Etiqueta

08 octubre 2014

Creación automática de tablas en el servidor

En algunos casos, puede tener sentido la ejecución de un proceso, que cree las tablas que falten en el servidor automáticamente tras iniciar la sesión con la base de datos, la intención sería, causar que las tablas necesarias para el correcto funcionamiento de la aplicación existan. Dicho proceso podría lanzarse cuando la aplicación es ejecutada por primera vez, cuando se entrega una nueva versión de la base de datos, cuando se cambie a un nuevo servidor de base de datos o a una base de datos diferente.

Puesto que estamos haciendo uso de clases "schema" durante el desarrollo de nuestra aplicación, es posible compararlas con las tablas correspondientes en el servidor, para saber si existen realmente y en caso necesario crearlas.

Partiendo de la base de que tenemos una variable "task" denominada "tSessObj" con una conexión válida a una base de datos. Crearemos un "statementobject" que más tarde utilizaremos para enviar las sentencias SQL necesarias a la base de datos, lo haremos sobre la variable local "lStatObj" (de tipo "Object" y sin subtipo).

Do tSessObj.$newstatement(#CT) Returns lStatObj

La variable "Object" "lStatObj" ahora dispone de los métodos y propiedades necesarios y que pueden ser localizados mediante el "Interface Manager" (opción disponible, mediante pulsar el botón derecho del ratón sobre la variable) si lo deseamos.

A continuación, utilizaríamos el código que mostramos más abajo para obtener las tablas alojadas en el servidor de base de datos, recogiéndolas sobre la variable de tipo lista "lDBTableList", tal como sigue:

Do lStatObj.$tables(kStatementServerTable)

Tenga en cuenta que sólo podrá ejecutar éste código mientras disponga de una instancia activa, es decir, mientras exista una conexión válida con la base de datos. Por lo que, si desea depurar el código, deberá marcar un punto de interrupción en el lugar que desee de la "Startup_Task", para cargar sobre la lista el resultado del método anterior, escriba:

Do lStatObj.$fetch(lDBTableList,kFetchAll)

El segundo paso será crear otra lista, que contenga las clases "schema" existentes en nuestra librería. Para ello usaremos también dos variables locales que la definirán, tal y como sigue:

Do lTablesForAppList.$define(lTableName,lSchemaClassName)
Do $schemas.$appendlist(lTablesForAppList,$ref.$servertablename,$ref.$name)

Ahora tendremos que ejecutar un bucle "For" que ira recorriendo la lista de clases "schema" y creando las nuevas tablas en el servidor según sea necesario:


For lTablesForAppList.$line from 1 to lTablesForAppList.$linecount() step 1
   Do lTablesForAppList.$loadcols()
   ; carga la línea actual en los campos correspondientes lTableName y lSchemaClassName
   Do lDBTableList.$search(lDBTableList.TableOrViewName=lTableName,kTrue,kFalse,kFalse,kFalse)
   If not(lDBTableList.$line) ;; cuando no existe la tabla
      Do lRow.$definefromsqlclass(lSchemaClassName)
      ; define una variable local de tipo "row" con el nombre del "schema" que se acaba de cargar
      Do lRow.$sessionobject.$assign(tSessObj) ;; ¡importante! hace que $createnames funcionen correctamente
      ; crea la nueva tabla en el servidor:
      Do lStatObj.$execdirect(con('CREATE TABLE ',lRow.$servertablenames(),'
(',lRow.$createnames(),') ')) Returns lStatus
      If not(lStatus)
         Breakpoint -> implementar aquí el controlador de errores
      End If
   End If
End For

Naturalmente este código deberá ejecutarse después de abrir la sesión con la base de datos sobre el método $construct de la "Startup_Task", cómo puede observar, se comprueba si existe la tabla en el servidor en correspondencia con lo definido en su clase "schema" y si no existe será automáticamente creada.

No hay comentarios: