Artículos técnicos Grupo Danysoft: De Delphi a Interbase ida y vuelta [IV] Por Pablo I. Reyes – Equipo Grupo Danysoft septiembre de 2002 - (902) 123146 www.danysoft.com Este documento se ha realizado utilizando Doc-To-Help®, distribuido por : Danysoft Internacional Avda de España 17 28100 Alcobendas – Madrid Tfno. 902.123146 Fax. 902.123145 http://www.danysoft.com http://www.danyshop.com [email protected] © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com De Delphi a InterBase ida y vuelta Este artículo es el cuarto de una serie dedicados al uso de InterBase con Delphi. En realidad es el quinto ya que el tema del artículo anterior fue dividido en dos. Objetivo El objetivo de este artículo es desarrollar una aplicación de bases de datos cliente/servidor con Delphi utilizando InterBase y los componentes IBExpress. En este artículo utilizaré la base de datos employee.gdb incluida en la instalación de Delphi y disponible en el directorio “\Archivos de programa\Archivos comunes\Borland shared\Data”. Componentes IBExpress Los componentes IBExpress dialogan directamente con el cliente de InterBase y se encuentran en la página InterBase de la paleta de componentes. Están escritos enteramente en object pascal por lo que se compilan con nuestra aplicación y no requieren de componentes externos. Esto no sólo facilita el despliegue de las aplicaciones; también ofrece mejor rendimiento y permite acceder a todas las características de InterBase. Los componentes Free IBObjects son similares a los componentes IBExpress pero en ocasiones ofrecen mejor rendimiento. Os recomiendo que les echéis una mirada. Conectando... Nuestro primer paso será conectarnos a la base de datos aunque previamente deberéis olvidaros de la arena, el mar o la sierra y conectar nuevamente con el trabajo. ¡Por qué serán tan breves las vacaciones! Bien, volvamos a lo nuestro. Normalmente utilizo un DataModule por aplicación para los componentes de conexión. En el caso de los componentes IBExpress, los componentes requeridos para establecer una conexión con una base de datos son dos: IBDatabase e IBTransaction. Comenzaremos con una aplicación nueva a la que le agregaremos un DataModule que llamaremos DMConexion y contendrá un componente IBDatabase y un IBTransaction. A diferencia de los componentes basados en BDE, los componentes IBExpress proveen un componente para gestionar conexiones y otro para gestionar transacciones. Esto nos permite gestionar varias transacciones simultáneas en una misma conexión o gestionar una misma transacción en varias conexiones simultáneas. InterBase soporta el uso de transacciones de dos fases que involucren a más de una base de datos. Esto nos permite actualizar dos bases de datos en el contexto de la misma transacción y hacer los cambios permanentes sólo si los cambios a las dos bases de datos fueron exitosos. Para establecer una conexión el componente IBDatabase siempre necesita de un componente IBTransaction. Para ello vamos a indicarle al componente IBTransacction cual es el componente de conexión por defecto por medio de la propiedad DefaultDatabase. Luego vamos a indicarle al componente IBDatabase la base de datos a la que queremos conectarnos por medio de la propiedad DatabaseName. Como ya les dije, utilizaremos la base de datos employee.gdb disponible en “\Archivos © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com de programa\Archivos comunes\Borland shared\Data”. Vamos a verificar la conexión asignándole el valor True a la propiedad Connected. Si la propiedad LoginPrompt tiene el valor True, que es el valor por defecto, veremos la ventana de diálogo Login. Utilizaremos el usuario administrador de InterBase: SYSDBA, masterkey. Conjuntos de datos Los componentes IBExpress que nos permiten obtener conjuntos de datos son varios. Por un lado están los componentes equivalentes a los basados en BDE. Estos componentes están disponibles para facilitar la migración de aplicaciones BDE a IBExpress. Por otro lado están disponibles componentes específicos de IBExpress. Utilizaremos estos últimos componentes. IBDataSet En su forma más simple el componente IBDataSet es similar al componente Query. Podemos relacionarlo con un componente de conexión e indicar una sentencia SQL. Pero en su forma completa es algo así como un Query más un UpdateSQL. Vayamos por partes empezando por las más simples. Siguiendo las prácticas del buen programador, vamos a crear un nuevo DataModule, al que llamaremos DMDatos y le añadiremos un componente IBDataSet. Vamos a relacionarlo con nuestro componente de conexión por medio de la propiedad Database. Para ello es necesario agregar la unidad del DataModule de conexión a la cláusula uses del nuevo DataModule. Ahora vamos a proporcionarle una sentencia SQL por medio de la propiedad SelectSQL. La sentencia SQL es la siguiente: select * from country Código Fuente 1 - Sentencia SQL Select El componente IBDataSet provee un editor de sentencias SQL en el que es posible ver los nombres de las tablas disponibles y sus campos. Si bien no nos ofrece demasiadas facilidades para escribir las sentencias en sí al menos podemos ver los nombres de las tablas disponibles y sus campos, lo que no es poca cosa. © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com Ilustración 1 - Editor de sentencias SQL Ahora vamos a agregar al formulario principal de nuestra aplicación un DataSource, un DBGrid y un DBNavigator. También vamos a agregar la unidad del nuevo DataModule a su cláusula uses. Como ya habrán adivinado, vamos a utilizar el formulario principal para mostrar las datos del componente IBDataSet. Entonces, relacionar el DBGrid y el DBNavigator con el DataSource y el este último con el IBDataSet. El formulario principal debería verse algo así: Ilustración 2 - Formulario principal Por defecto, el conjunto de datos obtenido es de sólo lectura. Para que sea de lectura escritura debemos proveer las sentencias SQL para insertar, actualizar y eliminar registros. Para ello contamos con un asistente al que podemos acceder por medio del menú contextual seleccionando la opción “Dataset Editor...”. En el editor del IBDataSet debemos indicar los campos clave en la columna “Key Fields:” y hacer clic en el botón “Generate SQL”. Esto generará las sentencias SQL por nosotros, como lo muestra la siguiente imagen. Ilustración 3 - Editor de IBDataSet Ahora el IBDataSet es de lectura y escritura. El editor no sólo ha generado sentencias SQL para las propiedades DeleteSQL, InsertSQL y ModifySQL. También lo ha hecho © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com para la propiedad RefreshSQL cuya sentencia SQL es utilizada cada vez que se ejecuta el método refresh. Está funcionalidad nos permite habilitar el uso de “cache updates” con sólo cambiarle el valor a una propiedad. Por defecto, la propiedad CacheUpdates tiene el valor False. Si le asignamos el valor True las actualizaciones no serán aplicadas hasta que llamemos al método ApplyUpdates. Generadores Antes mencioné que una de las ventajas de los componentes IBExpress es que soportan todas las características de InterBase. Los generadores son un ejemplo de ello. La propiedad GeneratorField del componente IBDataSet permite asociar un generador de la base de datos con un campo del IBDataSet. El funcionamiento es bastante simple. Debemos indicar el nombre del generador, el campo que afecta, el incremento a aplicar y el momento en el cual obtener el nuevo valor. En este último caso las posibilidades son tres: • OnNewRecord: en este caso se obtendrá un nuevo valor inmediatamente después de insertar un nuevo registro (antes del evento OnNewRecord del IBDataSet). • OnPost: en este caso se obtendrá un nuevo valor inmediatamente antes de grabar los cambios (antes del evento OnBeforePost del IBDataSet). • OnServer: en este caso el valor es generado por el servidor y sólo se utiliza como un indicativo de que el usuario no debe proveer un valor para este campo. Ilustración 4 - Propiedad GeneratorField Alertadores de eventos Una de las características únicas de InterBase es la posibilidad de utilizar alertadores de eventos. Los alertadores de eventos permiten que las aplicaciones cliente se suscriban a eventos de la base de datos y sean notificadas cuando estos ocurran. Los eventos pueden ser generados en procedimientos almacenados y/o en disparadores mediante una sentencia como la siguiente: post_event "evento" Código Fuente 2 - Eventos © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com Vamos a crear un disparador que genere un evento y vamos a suscribirnos a ese evento para que nuestra aplicación sea notificada cada vez que dicho evento ocurra. IBSQL El componente IBSQL permite ejecutar sentencias SQL consumiendo la menor cantidad de recursos posibles. Vamos a utilizar este componente para crear un disparador desde nuestra aplicación. Añadir un componente IBSQL al DataModule DMDatos. Relacionarlo con el componente IBDatabase y asignarle la siguiente sentencia SQL a su propiedad SQL: create trigger ejemplo for country active after insert position 0 as begin post_event "danysoft"; end; Esta sentencia SQL se encarga de crear un disparador luego de insertar un registro en la tabla country. El disparador se encarga de generar un evento llamado “danysoft”. Añadir un botón al formulario principal con el siguiente código para su evento OnClick: procedure TForm1.Button1Click(Sender: TObject); begin DMDatos.IBSQL1.ExecQuery; end; Este código se encarga de ejecutar la sentencia SQL del componente IBSQL. IBEvents El componente IBEvents nos permite suscribirnos a eventos de una base de datos para ser notificados cada vez que el evento ocurra. Al recibir una notificación, el componente IBEvents genera el evento OnEventAlert. Por medio de la propiedad Events podemos indicar los eventos a los cuales queremos suscribirnos. En nuestro caso nos vamos a suscribir al evento “danysoft” que generamos en el disparador ejemplo creado hace un momento. Ilustración 5 - Editor de eventos © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com Cada vez que el evento sea generado mostraremos un mensaje con el nombre del mismo. Escribir el siguiente código para el evento OnEventAlerter: procedure TDMDatos.IBEvents1EventAlert(Sender: TObject; EventName: String; EventCount: Integer; var CancelAlerts: Boolean); begin ShowMessage('Notificación recibida: ' + EventName); end; Código Fuente 3 - Notificación de eventos EventName indica el nombre del evento notificado. EventCount indica la cantidad de notificaciones recibidas desde la última vez que el evento fue ejecutado. CancelAlerts permite cancelar la notificación de eventos de aquí en adelante. La notificación de eventos es ejecutada en un hilo secundario para proveer un mecanismo asincrónico verdadero. El componente IBEvents se encarga de sincronizar la ejecución del manejador del evento OnEventAlert por lo que no hay que escribir código adicional. Ahora sólo nos resta suscribirnos a los eventos. Añadir un botón al formulario principal y escribir el siguiente código para su evento OnClick: procedure TForm1.Button1Click(Sender: TObject); begin DMDatos.IBEvents1.RegisterEvents; end; Este código hace que el componente IBEvents se suscriba a los eventos que contiene. Si ejecutamos nuestra aplicación tal cual está no recibiremos ninguna notificación. Esto es porque en ningún momento hemos finalizado la transacción iniciada implícitamente por los componentes IBExpress por lo que hasta que no lo hagamos no recibiremos ninguna notificación. Vamos a finalizar la transacción explícitamente escribiendo una línea de código. Escribir el siguiente código para el evento AfterPost del component IBDataSet: procedure TDMDatos.IBDataSet1AfterPost(DataSet: TDataSet); begin IBDataSet1.Transaction.CommitRetaining; end; Este código hace que la transacción actual finalice exitosamente y que la misma sea retenida. Si no lo hiciéramos así el conjunto de datos se cerraría. Los componentes IBExpress necesitan una transacción abierta para mostrar un conjunto de datos. Ahora sí, si ejecutamos nuestra aplicación recibiremos la notificación al insertar un registro nuevo. Recuerden que el disparador debe existir y que es necesarios suscribirse a los eventos para ser notificados cuando estos ocurran. Componentes adicionales Además de los componentes mencionados, existen otros de gran utilidad. En la solapa InterBase se encuentran además los siguientes componentes: • IBDatabaseInfo: este componente permite obtener información de la base de datos. • IBSQLMonitor: este componente permite monitorear sentencias SQL de manera similar a la aplicación SQL Monitor para el BDE. Si utilizamos los © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com componente IBExpress debemos crear nuestro propio monitor de sentencias SQL utilizando este componente. • IBExtract: este componente permite extraer información de metadatos de la base de datos. Esta información la podemos utilizar, por ejemplo, para analizar la estructura de una tabla y determinar si es correcta. Además de la solapa InterBase también está disponible la solapa InterBase Admin que contiene componentes que permiten administrar desde nuestra aplicación un servidor InterBase. Tareas como realizar una copia de resguardo, administrar usuarios o configurar el servidor pueden ser llevadas a cabo muy fácilmente por medio de estos componentes. Sin embargo esto ya es tema de un futuro artículo. Resumen Hemos visto las tareas básicas para desarrollar una aplicación de bases de datos cliente / servidor con Delphi e InterBase utilizando los componente IBExpress. En lugar de explicar los componentes IBTable, IBQuery e IBStoredProc que son muy similares a sus equivalente basados en BDE, decidí explicar en detalle el componente IBDataSet. Luego vimos algunas características avanzadas de InterBase como los generadores y los alertadores de eventos y cómo podemos acceder fácilmente a ellas por medio de los componentes IBExpress. También vimos como crear un disparador desde nuestra aplicación por medio del componente IBSQL y que además de estos componentes existen muchos otros que permiten que una aplicación Delphi se integre mejor que ninguna con InterBase. Este artículo es el último de la serie dedica al uso de Delphi e InterBase tal y como fue concebida al principio. Sin embargo, debido al éxito obtenido continuaré escribiendo artículos avanzados sobre InterBase y los componentes IBExpress. Para más información Puede dejarnos cualquier consulta o comentario sobre el artículo, enviando un email a [email protected], estaremos encantados de atenderle. © 2002 Grupo Danysoft - +34.916 638683 – www.danysoft.com