¿Todas las DBF abiertas o no?

¿Todas las DBF abiertas o no?

Postby rolando » Sun Feb 24, 2008 12:32 pm

Buen día,

Quiero consultar a los que saben más (la única manera de aprender),

En Clipper DOS, hacía un menú principal desde el que llamaba a distintos menúes que trabajaban con distintas .DBF, como seguridad, abría las .DBF a medida que se necesitaban y las cerraba cuando volvía al menú principal.

Todo esto, con la idea de prevenir corrupción en las .DBF si hubiese un corte de energía.

Esta misma forma de trabajo la utilizo también en FWH pero me está resultando incómoda porque a veces queda abierto un dialog conteniendo get's que modifican la .DBF al cerrarse y, como la DBF ya fue cerrada al salir del submenú, estos datos no pueden ser cargados en dicha DBF.

Todo lo antedicho es para la siguiente consulta: ¿Sigue siendo crítico tener una DBF abierta en caso de corte de energía?.

Gracias.

Rolando :D
User avatar
rolando
 
Posts: 593
Joined: Sat May 12, 2007 11:47 am
Location: San Nicolás - BA - ARGENTINA

Postby Armando » Sun Feb 24, 2008 2:31 pm

Rolando:

Creo que una sana costumbre es abrir solo las DBF que uses en cada PRG y cerrarlas al salir del mismo PRG, al menos mientras no uses otro motor para manejar las DBFs.

Lo que no entiendo es por qué al salir del sub menú cierras las DBFs.

Saludos
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Armando
 
Posts: 3076
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México

Postby Alfredo Arteaga » Sun Feb 24, 2008 4:53 pm

Sí, sigue siendo crítico. La estructura y manejo de DBFs no ha cambiado.

Desde Clipper con DOS he trabajado unas rutinas que han mejorado con el tiempo y ahora tambien me sirven para manejar tablas SQL.

Acostumbro a abrir todas las tablas de control una sola vez, entre ellas las que me sirven para controlar parámetros, procesos, actividades, permisos, usuarios, mensajes, etc. estas tablas se encuentran en la carpeta principal y en el caso de SQL forman una base de datos.

Los tablas de trabajo pueden encontrarse en otras carpetas o para el caso de SQL formar otra base de datos, estas tablas las abro y cierro de acuerdo a las necesidades, normalmente son abiertas al ingresar al programa o paso que las requiera y cerradas al finalizar.

La misma tabla puede ser abierta n veces sin problema, talvez el secreto esté en el uso y manejo del ALIAS.

He aquí el código:

Code: Select all  Expand view
STATIC aDbfs:={}

/*
   cAlias:=Open_Dbf("MiTabla")
   ...
   (cAlias)->(DbAppend())
   (cAlias)->DatoN:=cData
   (cAlias)->(DBCommit())
   (cAlias)->(DbUnlock())
   ...
   Close_Dbf("MiTabla",cAlias)
*/

// --- Apertura y cierre de tablas DBF, SQL (totalmente MDI)

FUNCTION Open_Dbf(cDbf,lDat,lShr)
   LOCAL cDriver:=DbSetDriver()
   LOCAL nI, nD, cAlias, oDbf
   LOCAL cFile, cRut
   DEFAULT lDat:=.T.
   DEFAULT lShr:=.T.
   CursorWait()
   IF cDriver="DBFCDX"
      cRut:=IF(lDat,cPatD,cPath)
   ELSE
      IF lDat
         SR_SetActiveConnection(nData)
      ELSE
         SR_SetActiveConnection(nMain)
      ENDIF
   ENDIF
   IF Select(cDbf)>0
      DBSelectArea(cDbf)
      nD:=AScan(aDbfs,{|aAt| aAt[1]==cDbf})
      IF nD>0
         aDbfs[nD,2]++
      ENDIF
      cAlias:=New_Alias(cDbf,nD)
      cFile :=IF(cDriver="DBFCDX",cRut+Upper(cDbf),cDbf+".DBF")
      DbUseArea(.T.,cDriver,cFile,cAlias,lShr,.F.)
      IF !Empty(OrdName(1))
         (cAlias)->(DbSetIndex(cFile))
         (cAlias)->(OrdSetFocus(1))
      ENDIF
   ELSE
      nD:=AScan(aDbfs,{|aAt| aAt[1]==cDbf})
      IF nD=0
         AAdd(aDbfs,{cDbf,1})
         nD:=AScan(aDbfs,{|aAt| aAt[1]==cDbf})
      ELSE
         aDbfs[nD,2]++
      ENDIF
      cAlias:=New_Alias(cDbf,nD)
      cFile :=IF(cDriver="DBFCDX",cRut+Upper(cDbf),cDbf+".DBF")
      DbUseArea(.T.,cDriver,cFile,cAlias,lShr,.F.)
      IF !Empty(OrdName(1))
         (cAlias)->(DbSetIndex(cFile))
         (cAlias)->(OrdSetFocus(1))
      ENDIF
   ENDIF
   CursorArrow()
RETURN (cAlias)

STAT FUNC New_Alias(cDbf,nD)
   LOCAL cAlias, cX, nX:=0
   IF Select(cDbf)=0
      RETURN (cDbf)
   ENDIF
   cX:=LTrim(Str(aDbfs[nD,2]-1))
   cAlias:=cDbf+cX
   DO WHILE Select(cAlias)>0
      nX:=Val(cX)+1
      cX:=LTrim(Str(nX))
      cAlias:=cDbf+cX
   ENDDO
RETURN (cAlias)

FUNCTION Close_Dbf(cDbf,cAlias,lEnd)
   LOCAL nD
   DEFAULT lEnd:=.F.
   DEFAULT cAlias:=cDbf
   CursorWait()
   cDbf:=Upper(cDbf)
   IF Select(cDbf)>0
      nD:=AScan(aDbfs,{|aAt| aAt[1]==cDbf})
      IF nD>0
         IF lEnd
            IF Select(cAlias)>0
               (cAlias)->(DbCloseArea())
            ENDIF
            IF Select(cDbf)>0
               Close(cDbf)
            ENDIF
            aDbfs[nD,2]:=0
         ELSE
            IF aDbfs[nD,2]>0
               aDbfs[nD,2]--
               IF Select(cAlias)>0
                  (cAlias)->(DbCloseArea())
               ENDIF
            ENDIF
         ENDIF
      ENDIF
   ELSE
      nD:=AScan(aDbfs,{|aAt| aAt[1]==cDbf})
      IF nD>0
         aDbfs[nD,2]:=0
      ENDIF
   ENDIF
   CursorArrow()
RETURN (NIL)

FUNCTION Verif_Close()    // Verifica si quedan tablas abiertas, útil durante el desarrollo
   LOCAL nD
   FOR nD=1 TO Len(aDbfs)
      IF aDbfs[nD,2]>0
         MsgInfo("Falto por cerrar "+aDbfs[nD,1]+Tran(aDbfs[nD,2],"999"))
      ENDIF
   NEXT nD
RETURN (NIL)
User avatar
Alfredo Arteaga
 
Posts: 326
Joined: Sun Oct 09, 2005 5:22 pm
Location: Mexico

Postby Andrés González » Tue Feb 26, 2008 8:13 am

La verdad es que es una buena pregunta y ultimamente le estoy dando muchas vueltas al tema. Principalmente debido a que ya tengo un sistema funcionando en el que voy abriendo bases de datos en cascada dejando las anteriores abiertas, todo ello mediante ficheros externos donde defino el lugar, los indices y las relaciones de las bases de datos. Esto lo he resuelto mediante el uso de un array que me controla como va creciendo la cascada y en todo momento se que tengo abierto. Pero unicamente tengo abierto una ventana con su browse de base de dato y las opciones alta, baja, ... que se pueden hacer dependiendo de los derechos. A medida que voy saliendo de la ultima ventana vuelvo abrir la anterior que tengo almacenada en el array (ademas de posicionarla en el registro que estaba antes de haber pasado a la siguiente) y cierro completamente las dbf que empleaba. Esto lleva mucho consumo de memoria si se pretende hacer de este modo, debido a que el único metodo que he encontrado es parar el flujo de cada una con el Syswait(), en alguna ocasion el word arrancado con la clase tWord me falla y se queda colgado, pero no se si achacarlo al consumo de memoria. Haciendolo de este modo cuando mi programa esta arrancado el indicador de rendimiento del administrador de tareas esta siempre sobre el 90%. Hace tiempo hice la consulta y Antonio me respondio que la mejor manera era quitar el syswait() pero no he encontrado un entorno que me posibilite hacer lo que hago. Descubri un sistema en avemundi que hacia algo similar que era el FDSI, pero por una rotura de disco este entorno lo perdi y ha sido eliminado de la página.

Bien si alguien se quiere mojar seguro que mas de unos estaremos interesados en el tema.

Saludos.
Saludos

Andrés González desde Mallorca
User avatar
Andrés González
 
Posts: 627
Joined: Thu Jan 19, 2006 10:45 am
Location: Mallorca

Postby horacio » Tue Feb 26, 2008 11:02 am

Yo siempre abro las tablas cuando arranca la aplicación y las mantengo así hasta que esta se cierra. He leido en varios post que el problema de trabajar con dbf en red es la colisión de los archivos índices y por esta situación se corrompen. Y esto puede pasar independientemente si trabajo abriendo y cerrando las bbdd o que estén todas abiertas. En estos casos tendría que volver a generar el índice corrupto y como tengo una rutina que genera índices para todas las bbdd no tiene mucho sentido abrir de a una base. Creo, también que esta forma de trabajar ( abriendo y cerrando las BBDD ) es una herencia de dbase ya que la cantidad de áreas de trabajo que podíamos abrir era limitada.
horacio
 
Posts: 1358
Joined: Wed Jun 21, 2006 12:39 am
Location: Capital Federal Argentina

Postby pymsoft » Tue Feb 26, 2008 1:12 pm

Yo abro todas las bases de datos cuando entro a la aplicación, y la primera vez controlo la estructura de cada uno de los archivos.
Uso un timer, que si no tengo ninguna ventana abierta, (controla cada 90 segundos) me cierra todas las bases de datos, y en el caso que abra una ventana para mostrar datos llamo a una funcion que me abre todas las bases de datos "AbrirTodaslasDBFs()", que en el caso que el archivo esté abierto, lo selecciona y basta.
A mi me funciona desde hace años... Aunque de repente, la solución justa hubiera sido utilizar la clase tDatabase y abrir los archivos cuando fueran necesarios o sea, cuando se abre cada ventana y dialogo, y seguramente me hubiera evitado de comprobar y salvar el orden, puntero, etc. cada vez que uso un archivo en ventanas diferentes...

Saludos
Pedro Gonzalez
User avatar
pymsoft
 
Posts: 383
Joined: Tue Oct 11, 2005 1:01 pm
Location: Savona - Italia

Re: ¿Todas las DBF abiertas o no?

Postby FiveWiDi » Tue Feb 26, 2008 1:35 pm

La solución que yo aplico es muy parecida a la de Pedro (pimsoft).

Al entrar en la aplicación abro todas las DBF, compruebo su estructura e índices, declaro objetos oTDbf (del estilo de TDataBase) que añado a una array que arrastro en toda la aplicación, y finalmente cierro los DBF conservando los oTdbf.

Cuando abro una ventana, clono los oTdbf necesarios y abro la DBF correspondiente; cuando salgo de la ventana el VALID hace el trabajo de realizar un oTDbfClonado:End().

Si no hay ventana, no hay DBF abiertas, me puedo ir a comer, a cenar, al cine, al lavabo y QueSeJoda el riesgo.
Hay muchos usarios Murphy en los lavabos, en el cine, comiendo o cenando.

Saludos
Carlos G.
FiveWiDi
 
Posts: 1078
Joined: Mon Oct 10, 2005 2:38 pm


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 55 guests