15 de marzo de 2006

Registrando cambios a vistas locales

Título original: Logging Changes to Local Views
Autor: Nancy Folsom (http://www.pixeldustindustries.com)
Traducido por: Luis María Guayán


Durante la creación de un prototipo, e incluso durante el desarrollo, frecuentemente, y a veces inadvertidamente, hago retoques a las vistas locales. Esto puede suceder, por ejemplo, cuando me he olvidado de utilizar NVL(), o si necesito cambiar una expresión del filtro. Seguro, esto no debería suceder nunca, excepto después de que el diseño haya documentado el cambio de diseño, pero, bien, sucede. Si es un cambio cuidadoso, o un cambio de prueba que no fue quitado, puede ser diabólicamente difícil de encontrar lo que ha roto de repente una vista. De todas formas, lo analicé esta semana y pasé algunos minutos implementando un simple evento de la base de datos que registrará mis cambios en la vista -una tarea que vengo tratando de hacer desde antes de tratar de limpiar mi sótano-.

Mi enfoque es utilizar un PRG externo a los procedimientos almacenados de la DBC así pueda utilizar los mismos eventos para múltiples contenedores de bases de datos. Para este artículo, agregué un registro de entrada similar para las modificaciones de las tablas, aunque mi interés principal estaba en las vistas.

El siguiente código creará una tabla de registro de cambios y un contenedor de bases de datos, crea un PRG externo con los eventos dbc_AfterModifyView y dbc_AfterModifyTable de la base de datos, y finalmente habilita los eventos de la base de datos, para la base de datos que usted seleccionó. Como advierto en los comentarios, asegúrese de respaldar sus datos primero, lo ideal es ejecutar este código en un contenedor de bases de datos de ejemplo para estar seguro que usted entiende cómo trabaja.

* 2005.12.20 Nancy Folsom, Pixel Dust Industries
* Este programa crea un contenedor de base de datos y una tabla
* para registrar las modificaciones en las tablas y vistas
* * Se asume que se ejecuta en el directorio de desarrollo
* * ¡Cuidado! Como cualquier código que cambia datos, primero 
* * haga un respaldo de sus datos, y pruebe el código sobre algunos
* * datos de prueba antes de ejecutarlo sobre datos de producción
*
* Creamos el registro de modificaciones
*
If !File('ChangeLog.DBC')
  Create Database ChangeLog
Endif
Open Database ChangeLog
Set Database To ChangeLog
Create Table ChangeLogEvents (;
  IID I Autoinc, cObjectName C(254), ;
  cAction C(254), mValue M, tTimeStamp T)
Local lcDBC, lcLogFile, lcPRG
*
* Creamos los eventos PRG usando los comandos TEXT y StrToFile()
*
TEXT to lcPrg textmerge noshow
Procedure dbc_AfterModifyView(cViewName, lChanged)
  If lChanged
    * 
    * Almacenamos la definición SQL. 
    * Deberiamos guardar todos los valores DBGETPROP
    *
    Insert Into ChangeLog!ChangeLogEvents ( ;
      cAction, mValue, cObjectName, tTimeStamp) ;
      Values ( "AfterModifyView", ;
      DBGetProp(cViewName,"VIEW","SQL"), cViewName, DATETIME() )
    Return .T.
  Endif
Endproc
Procedure dbc_AfterModifyTable(cTableName, lChanged)
  If lChanged
    Local lni, lnj, laArray[1], lcStructure
    lcStructure = "Field structures" + Chr(13)
    * Por cada campo en la tabla ...
    For lni = 1 To Afields(laArray,cTableName)
      For lnj = 1 To Alen(laArray,2) - 1
        * ... capturamos la estructura del campo
        lcStructure = lcStructure + Transform(laArray[lni,lnj]) + ", "
          Next lnj
        lcStructure = lcStructure + Transform(laArray[lni,lnj]) + Chr(13)
      Next lni
      lcStructure = lcStructure + Chr(13) + "Indices" + Chr(13)
      * Por cada etiqueta de índice ...
      For lni = 1 To Ataginfo(laArray,cTableName)
        For lnj = 1 To Alen(laArray,2) - 1
          * ... capturamos el nombre de la etiqueta y la expresión
          lcStructure = lcStructure + laArray[lni,lnj] + ", "
        Next lnj
        lcStructure = lcStructure + laArray[lni,lnj] + Chr(13)
      Next lni
      Insert Into ChangeLog!ChangeLogEvents (;
        cAction, mValue, cObjectName, tTimeStamp) Values (;
        "AfterModifyTable", lcStructure, cTableName, DATETIME())
    Endif
    Return .T.
  Endproc
ENDTEXT
* Guardamos la cadena que hicimos con TEXT en un PRG.
lcLogFile = Putfile("Events file", "DataBaseEvents","PRG")
Strtofile(lcPRG, lcLogFile)
* Tomamos la DBC para habilitar los eventos
lcDBC = Getfile('DBC')
* Abrimos la DBC, ponemos los eventos y ponemos el archivo de eventos 
* al PRG creado arriba
Open Database (lcDBC)
lcDBC = Juststem(lcDBC)
DBSetProp(lcDBC,"Database", "DBCEvents",.T.)
DBSetProp(lcDBC,"Database","DBCEventFilename", lcLogFile)
* Ya está. Cada vez que una vista o tabla es modificada, la estructura
* será registrada en ChangeLogEvents (o el nombre que usted quiera).
Hay claramente muchas direcciones que esto puede tomar. Una de mis metas es identificar cambios específicos, con las fechas, como parte de mi sistema de documentación. Lo invito a que me contacte en nfolsomNOSPAM@NOSPAMpixeldustindustries.com con cualquier comentario, pregunta o crítica. Sus comentarios serán bienvenidos.

Observese que los eventos de la base de datos fueron agregados en Visual FoxPro 7.0. Usted puede leer más sobre ellos en http://msdn.microsoft.com/library/en-us/dv_foxhelp/html/neconDatabaseContainerEvents.asp.

Nancy Folsom

No hay comentarios. :

Publicar un comentario