Una vista rápida a Unidac (Universal Data Access Components)

 

Buen camino a todos.

devart_logoHoy vamos a dar una vista rápida a la librería de componentes Unidac (Universal Data Access Components), que son, como muchos ya conocéis,  una colección o biblioteca de componentes para distintos entornos de desarrollo, entre ellos, nuestros Delphi y C++ Builder, pero que también añaden Lazarus (y Free Pascal) entre sus destinos, y que nos proveen de acceso a multiples bases de datos, de una forma unificada (y sencilla). Con vuestro permiso, me voy a permitir una pequeña parada para conocerlos con unas líneas de código y compartir con vosotros esas primeras impresiones, gracias a la deferencia que tuvieron con el blog de Delphi Básico para que pudiera probarlos en esta entrada.

Vaya por delante, y es algo que los amigos y compañeros de la comunidad, con los que he podido compartir ideas conocen, nunca he sido demasiado partidario de usar componentes adicionales en el entorno de desarrollo, fuera de los que ya se incluyen al comprarlo, por lo que intento ceñirme a los existentes, en la medida que me sea posible. Quizás sí muy al principio, en aquellos años en los que daba los primeros pasos en el IDE de Delphi y celebraba cualquier componente nuevo, figuradamente con un brindis; pero el paso del tiempo y la experiencia, y algunos batacazos, creo que me enseñaron que no se debe alocadamente introducir componentes que puedan, bien no tener continuidad, por causas ajenas a nosotros, bien por otras causas que sí puedan depender directamente de nosotros, como pueda ser el costo económico de mantenerlos, habida cuenta que las sucesivas renovaciones del mismo entorno de desarrollo, nos obligan a renovar las versiones de estas librerías. Fijaros que matizo «alocadamente». La alternativa, mantener inalterada una configuración sobre un proyecto determinado, suele ser una soga al cuello que mas tarde o temprano acaba asfixiando, por lo que lo ideal es que éste pueda evolucionar al mismo tiempo que se producen cambios en el IDE.

Pero nunca existen normas rígidas e inalterables. Por ello, siempre hay momentos en los que puede hacerse necesario valorar seriamente introducir determinada librería. Y una de las areas que pueden justificarlos, bajo mi humilde criterio, es la que hace referencia a las conexiones de datos, que dan muchos quebraderos de cabeza, en todos los ordenes. Y por supuesto, también durante el propio desarrollo. Sin ir mas lejos, me viene a la cabeza la compra del driver de devExpress para MySQL, que hice junto a un compañero y amigo con el que compartía varios proyectos, hace algunos años y precisamente a Devart, en un momento de transición de la versión 4 a la 5 de MySQL, ante los problemas continuos del driver genérico de dbExpress que incluía el IDE para esta base de datos (funcionaba bien con la version 4 pero recuerdo que era imposible trabajar de forma continuada tras actualizar la versión de MySQL), de forma que dicha compra, para nosotros fue algo rentable y aseguró la continuidad de aquel proyecto. Se justificaba en aquel momento ampliamente, y consideramos entonces que valió la pena el dinero gastado.

Mi eterna curiosidad de alguna forma, me ha llevado estos semanas anteriores a evaluar y explorar el producto, para tener una idea de qué nos ofrece ahora, tras ver varios enlaces añadidos en el foro de Delphi Solidario. Lo que pueda comentar es mi opinión subjetiva, fruto de esa actividad.

¿Cómo se nos ofrece Unidac?

Devart, la compañía que desarrolla Unidac no es un recién llegado sino una compañía con solera, fundada en el 97, con muchos años de desarrollo a sus espaldas en el mundo de las herramientas y acceso a bases de datos. Existe en su portafolio una infinidad de productos que abarcan distintas tecnologías y realmente no tiene demasiado sentido citarlos aquí porque son muchos. Entre ese abanico de productos, herramientas y utilidades de gestión de datos, proveedores de datos ADO .Net, componentes VCL/FMX que unifican el acceso a las distintas bases de datos, como Oracle, SQL Server, MySQL, etc , incluyendo drivers para dbExpress, ODBC drivers y distintas utilidades, como editores de código, monitores, etc…

En el siguiente enlace podéis acceder al detalle de sus productos.

Entre todos estos componentes, drivers  y herramientas, yo he querido probar en esta ocasión Unidac, que se distribuye en tres ediciones, Express, Standard y Profesional, pudiendo incluir ésta última edición el código fuente  (lo cual encarece lógicamente el precio). Supongo que en ocasiones se hará imprescindible tenerlo aunque nunca fue mi caso.

A la hora de optar por este producto, tenemos varias opciones:

Devart nos ofrece Unidac Express de forma gratuita y se incluye el motor y los componentes básicos que son comunes a todas las ediciones. En este caso, con la version Express no se incluye ninguno de los componentes que habitualmente llamamos Proveedores de Datos (Providers) y que son los que nos ayudan a conectar con los distintos motores de datos, pero la adquisición e instalación de los respectivos productos  ODAC, SDAC, MyDAC, IBDAC, PgDAC, y LiteDAC permitirían el acceso individual a Oracle, SQL Server, MySQL, InterBase (Firebird), PostgreSQL, y SQLite. Con independencia de que sí se suministra el componente, TMemVirtual,

schema-unidac

La versión estándar, por el contrario, sí incluye todos los proveedores de datos, pero a diferencia de la version profesional, no permitiría el desarrollo móvil para Android o IOS.

Y finalmente, la version profesional, incluye todas las posibilidades, incluyendo el desarrollo de aplicaciones móviles, cifrado de datos y componentes adicionales.

El detalle completo de características de cada edición, lo podéis encontrar en el siguiente enlace:

http://www.devart.com/unidac/editions.html

Y los precios, oscilan desde los 197.97 Euros de la versión Estándar, los 296.98 Euros de la version profesional y finalmente, los 445.50 Euros de la version profesional que incluye el código fuente. Precios sin iva, para una licencia individual. Estas cifras os pueden dar una idea del coste de esta adquisición.

En todo caso, existe la posibilidad de descargar una version trial funcional por 60 días, lo cual puede dar la oportunidad de que hagáis alguna prueba para evaluar el producto y valorar si en algún momento os puede ser de utilidad.

Unidac 6.0 Trial para Rad Studio XE7, (47.37 Mb)

Primeras impresiones…

Me gustaría empezar diciendo que Unidac es un de producto de calidad, profesional, una de las alternativas serias a FireDac, este último incluido desde hace algo menos de dos años en nuestro IDE. Haciendo un poco de historia, el 5 de Febrero de 2013, Embarcadero publicaba en el area de notas de prensa, la adquisición de AnyDac de DA-Soft, Embarcadero Technologies Acquires High Performance Enterprise Database Connectivity Technology for Developers,  que era junto a UniDac de Devart, en esas fechas, dos de los productos que competían por un mismo hueco en ese mercado. Quizás esta adquisición, rompió -en mi opinión- un cierto equilibrio que existía hasta ese momento ya que no era nada infrecuente encontrar, explorando en las distintas redes y webs conocidas, entradas y consultas de foros que contrastaban ambos productos y empresas: UniDac versus AnyDac. Todos los comentarios que pude leer entonces dejaban en un lugar muy alto la calidad de ambos, a todos los niveles, inclusive soporte técnico.

Para aquellos que usan alternativamente en sus desarrollos Lazarus y Delphi, pueden encontrar un motivo mas para considerarlo de su interés. Los precios además son asequibles (con independencia de que a nadie nos guste tener costes adicionales). No soy quien para juzgar una u  otra razón, pero entiendo que es bueno que existan alternativas y que los distintos fabricantes aspiren a encontrar un lugar de excelencia en el mercado, que los diferencie. Y en mi opinión, Devart encontró ese hueco.

Las primeras impresiones que recibes tras la instalación de UniDac son excelentes, muy buenas. Tras finalizar dicha instalación, encontramos 2 nuevas categorías en la paleta de componentes, que son respectivamente:  Unidac y Unidac Providers que concentran la casi totalidad de componentes instalados.

paleta_unidac

paleta_unidac_providers

 Adicionalmente se instalaran también los componentes TVirtualTable, que representa un dataset en memoria sin conexión a datos, y TCRBatchMove, que permite mover registros entre distintos datasets usándose principalmente para copias o borrados sedata_accesslectivos.

Estos dos componentes, podrás encontrarlos en la pestaña Data Access.

Esta disposición, donde todos los componentes quedan bien localizados y fácilmente accesibles, particularmente me resulta agradable en cuanto a su usabilidad, reforzada -y de esto no me queda duda-, por una buena documentación que acompaña al producto, que es posible ser descargada en formato PDF, de igual forma que es consultada on line o integrada en la ayuda del mismo entorno de desarrollo, invocada en el contexto. Es uno de los aspectos que me ha sorprendido muy gratamente, ya que la documentación, además, se acompaña con algunas demos muy útiles, que permiten tener mucho mas clara la mecánica de trabajo en esa primera toma de contacto que siempre es vital. Existe una pagina donde se enumeran todos los ejemplos que se incluyen, Demos, pero además, podéis descargar un versión ya compilada lista para el uso, Demo Compilada.

demo_compilada

La peculiaridad de esta demo es que puede ser explorada, ejecutando los métodos disponibles por la interfaz y simultáneamente, acceder al código fuente. Basta conectar, como origen de datos una base de datos de entre las disponibles por los drivers de conexión y creará un conjunto reducido de tablas acompañadas de registros, para que se puedan probar la funcionalidad de cada área.

Pssss… Un comentario al margen de esto: Observad como se construye la estructura de herencia en los formularios de la demo. Va muy en la línea de algunos de los artículos que hemos compartido y que hablaban de la modularidad.  

Estos son los principales componentes, no visuales, ubicados en la paleta de Unidac.

UniConnection TUniConnection Representa la conexión al motor de datos, un interfaz común a los distintas bases de datos (sql server, mysql, interbase, firebird, etc…). El acceso se produce tras fijar los parámetros de conexión principales como el usuario, el password, la ubicación del servicio, etc…y establecer el proveedor de datos deseado, provider, entre los existentes en la paleta UnidacProviders, seleccionado en una de las propiedades ProviderName del componente. Este escenario,  mantener un interfaz común, aventaja en productividad al contexto en el que el desarrollador aborda desde bibliotecas distintas el acceso a multiples bases de datos.
TUniEncryptor TUniEncryptor Enlazado a la componentes que representan el dataset, como UniQuery o UniTable, cifrar y descifrar determinados campos del mismo.
UniTransaction TUniTransaction Representa la Transacción y permite el control de las operaciones, inclusive transacciones distribuidas, que sean admitidas por algunos proveedores de datos.
UniQuery TUniQuery Básicamente lo usamos para obtener conjuntos de datos a través de una consulta SQL, que involucren a una o varias tablas.
UniTable TUniTable Semejante al anterior, salvo que implica a una única tabla de la que debemos indicar únicamente el nombre.
UniStoredProc TUniStoredProc Su principal misión es ejecutar procedimientos almacenados.
UniSQL TUniSQL Ejecutan sentencias de SQL, aunque no devuelven datasets. Pueden ejecutar procedimientos almacenados.
UniScript TUniScript Principalmente se hacen necesarios para ejecutar sentencias sql que requieren procesos mas complejos o mayor control.
UniMetaData TUniMetaData Permite recibir metadata.
UniUpdateSQL TUniUpdateSQL Este componente, sobrescribe las operaciones de actualización y se liga a los componentes que representan al dataset.
UniDataSource TUniDataSource Provee un interface común para conectar data-aware controls, que interactúan con el usuario, con los componentes de datos. Descienden jerárquicamente del TDataSource.
UniLoader TUniLoader Ayuda en la carga rápida de datos.
UniDump TUniDump Operaciones de respaldo o restauración de datos.
UniMonitor TUniSQLMonitor Interfaz para monitorear y hacer un seguimiento de la ejecución de las sentencias sql en tiempo real.
UniConnectionDialog TUniConnectDialog Asociados a la conexión, permite crear un dialogo personalizado de los parámetros de acceso. Es el típico dialogo que se abre previo a la conexión si se establece ésta en LoginPrompt a True. Sorprendentemente, preestablece la posibilidad de establecer el idioma entre los disponibles.
UniAlerter TUniAlerter Se usa para recibir y enviar eventos.

 La paleta UnidacProviders, contendrá los proveedores de datos. En este caso, en la imagen aparecen todos pero es posible que optemos por comprar la solución especifica por lo que en ese caso, solo aparecerían los adquiridos. En cualquier caso, la biblioteca de componentes básica establece ese interfaz común a los distintos motores de datos o plataformas.

Podéis consultar el alcance de compatibilidad de los distintos proveedores para las versiones de dichos motores/plataformas en el siguiente enlace:

Tabla de compatibilidad

 Cosas que nos ayudan…

Si disponer de una buena documentación es importante, no lo es menos que se integren en los propios componentes pequeñas utilidades y expertos que nos ayuden. Los que habitualmente denominamos editores  personalizados.

El que primero vais a descubrir, abre el dialogo de conexión en el componente TUniConnection.

editor_conexion

 

Os ayudará en la tarea de configuración de la conexión con algunos detalles que se agradecen, como el descubrimiento automático de los distintos servicios que encuentra el provider, una vez seleccionado, o la lista desplegable de las distintas bases de datos, asociadas al servidor elegido. Por supuesto, se puede probar la conexión y ver que funciona todo correcto. Si es así, lucirá un circulo de color verde a modo de semáforo.

También en esta area de pestañas se podrán configurar las opciones avanzadas, las macros a nivel de conexión, el mapeo de los tipos de datos personalizados también a nivel de conexión. Y finalmente, un par de pestañas informativas. Quizás no os suene eso de Macros o lo del Mapeo de Tipos porque no era algo habitual pero estas bibliotecas ya lo contemplan y es algo demandado y necesario en algunos contextos. Los Macros permiten hacer sustituciones de nombres asociados a objetos propios de las bases de datos, como por ejemplo el nombre de las tablas, y que sean sustituidos usando un alias o nombre asignado por nosotros, en función de que tipo de servidor sea conectado, permitiendo salvar diferencias de cada motor y unificar las invocaciones. Si os queda duda, podéis acceder a la ayuda asociada, ver macros. Y respecto al concepto de Mapeo de Tipos, hace referencia a la personalización de los tipos asociados a los campos descubiertos por el dataset, que genéricamente hace una equivalencia con los del motor de datos. Por poner un ejemplo, es posible que de un tipo Numeric(4,0) se infiera un campo de tipo decimal cuando realmente va a contener un tipo entero. Esto es personalizar o mapear el tipo, de forma que damos a conocer como debe considerarlo. Igualmente si os queda alguna duda, podéis consultar la ayuda que es bastante clara en cuanto al concepto y a cómo llevarlo a la práctica: Mapeo de Tipos.productividad

Otra muestra de productividad destacable, podría ser el editor auxiliar que acompaña a los componentes que representan el DataSet.

Podemos poner como ejemplo el componente TUniTable, que es uno de los mas sencillos pues representa a una única tabla. Además del editor especializado, podemos acceder a un editor de datos que nos permitiría ver in situ su contenido real. Ese editor especializado además, nos permite preparar como se visualizan los datos, el orden, los filtros, condiciones y opciones avanzadas, además del mapeo a nivel de tabla, que también es posible.

La imagen inferior os muestra estos aspectos.

editor_dataset

Llegados a esta punto, y puestos a comentar algo sobre el editor personalizado de los querys de Unidac (TUniQuery)  me gustaría introducir un pequeño script para generar unas cuantas tablas para hacer unas pruebas. En esta caso utilizaremos un motor de SQL Server que he habilitado exclusivamente para la entrada. Se ubicaría en un servidor compartido en Internet.

Consta de 4 tablas, 1 vista y 1 procedimiento almacenado. Igualmente, una vez creadas éstas, doy unos valores de muestra.

Os copio el script.

CREATE DATABASE [TestUnidac]
COLLATE Modern_Spanish_CI_AS
GO

USE [TestUnidac]
GO

SET NOCOUNT ON
GO

--
-- Definition for table Empleados : 
--

CREATE TABLE [dbo].[Empleados] (
  [IDEmpleado] int NOT NULL,
  [Nombre] varchar(50) COLLATE Modern_Spanish_CI_AS NOT NULL,
  [Apellido1] varchar(50) COLLATE Modern_Spanish_CI_AS NULL,
  [Apellido2] varchar(50) COLLATE Modern_Spanish_CI_AS NULL,
  [Tarjeta] varchar(10) COLLATE Modern_Spanish_CI_AS NOT NULL,
  [Password] varchar(4) COLLATE Modern_Spanish_CI_AS CONSTRAINT [DF_Empleados_Password] DEFAULT 1234 NOT NULL,
  [IDEmpresa] int NOT NULL,
  [FechaAlta] datetime CONSTRAINT [DF_Empleados_FechaAlta] DEFAULT getdate() NULL,
  [UltimoRegistro] datetime NULL,
  CONSTRAINT [PK_Empleados] PRIMARY KEY CLUSTERED ([IDEmpleado]),
  CONSTRAINT [FK_Empleados_Empresas] FOREIGN KEY ([IDEmpresa]) 
  REFERENCES [dbo].[Empresas] ([IDEmpresa]) 
  ON UPDATE NO ACTION
  ON DELETE NO ACTION
)
ON [PRIMARY]
GO

--
-- Definition for table Empresas : 
--

CREATE TABLE [dbo].[Empresas] (
  [IDEmpresa] int NOT NULL,
  [Nombre] varchar(50) COLLATE Modern_Spanish_CI_AS NULL,
  CONSTRAINT [PK_Empresas] PRIMARY KEY CLUSTERED ([IDEmpresa])
)
ON [PRIMARY]
GO

--
-- Definition for table RegistrosHorarios : 
--

CREATE TABLE [dbo].[RegistrosHorarios] (
  [IDRegistro] bigint IDENTITY(1, 1) NOT NULL,
  [IDEmpleado] int NOT NULL,
  [FechaRegistro] datetime NOT NULL,
  [ES] char(1) COLLATE Modern_Spanish_CI_AS NULL,
  CONSTRAINT [PK_RegistrosHorarios] PRIMARY KEY CLUSTERED ([IDRegistro]),
  CONSTRAINT [FK_RegistrosHorarios_Empleados] FOREIGN KEY ([IDEmpleado]) 
  REFERENCES [dbo].[Empleados] ([IDEmpleado]) 
  ON UPDATE NO ACTION
  ON DELETE NO ACTION
)
ON [PRIMARY]
GO

--
-- Definition for table TiposDeRegistro : 
--

CREATE TABLE [dbo].[TiposDeRegistro] (
  [IDTipo] int NULL,
  [Descripcion] varchar(50) COLLATE Modern_Spanish_CI_AS NULL
)
ON [PRIMARY]
GO

--
-- Definition for view VistaRegistrosHorarios : 
--
GO
CREATE VIEW [dbo].[VistaRegistrosHorarios]
AS
SELECT        dbo.RegistrosHorarios.IDRegistro, dbo.RegistrosHorarios.IDEmpleado, dbo.Empleados.Nombre + ' ' + dbo.Empleados.Apellido1 + ' ' + dbo.Empleados.Apellido2 AS NombreEmpleado, dbo.Empleados.IDEmpresa, 
                         dbo.RegistrosHorarios.FechaRegistro
FROM            dbo.Empleados INNER JOIN
                         dbo.RegistrosHorarios ON dbo.Empleados.IDEmpleado = dbo.RegistrosHorarios.IDEmpleado
GO

--
-- Definition for stored procedure RegistraMovimiento : 
--
GO
CREATE PROCEDURE [dbo].[RegistraMovimiento]
@IDEmpleado int,
@HoraRegistro datetime,
@IDTipo int,
@IDMovimiento int out
AS
BEGIN
  Set @IDMovimiento = -1;
  
  if (@IDEmpleado > 0)
  begin
    Insert into RegistrosHorarios(IDEmpleado, FechaRegistro, ES) 
    Values (@IDEmpleado, @HoraRegistro, @IDTipo);
    
    Set @IDMovimiento = @@Identity;
  end; 

END
GO

Cuando me planteé escribir esta entrada, buscaba un ejemplo sencillo para que se pudiera ver algún detalle en la práctica, por lo que recordé una vieja entrada que me podía venir fantástica para  retomarla y reusar su código, por su sencillez. Me estoy refiriendo a la entrada Modulo de Control de Presencia, escrita en Septiembre del 2010.

imagen

Era ideal porque involucraba pocas tablas u objetos en el servidor. Una tabla de empleados, otra que guardase los picajes horarios y poco mas. Nos servirá al final de la entrada, para probar que la conexión de sql server se establece en Android, por ejemplo.

Como veis, aquel articulo describía un imaginario reloj que registraba el acceso al centro laboral, las salidas del mismo, o las incidencias, para el control horario. Figuradamente se ejecutaba con el soporte de un monitor táctil y su funcionamiento era muy sencillo: iniciada la operación de registro, el empleado se identificaba con un código numérico de cuatro cifras. Inmediatamente introducía su código, y marcaba el tipo de registro, momento en el que finalizaba la operación. Quizás, había un punto original en todo aquel proceso, y era que no guardaba en una base de datos al uso, sino que previo a ese supuesto envío final al servidor, toda la información quedaba almacenada localmente en un fichero de texto plano hasta su proceso posterior. Cada registro de los empleados, implicaba la creación de una instancia de la clase TMovimiento, que finalmente quedaban almacenadas en dicho fichero de forma que podían ser recreadas nuevamente para su manipulación.

Pero no nos adelantemos, ya que estábamos compartiendo las impresiones de estos editores personalizados. Este es que utilizamos para editar el contenido y configuración del componente TUniQuery:

EditorQuery1

La principal propiedad que da sentido a este componente es la lista de cadenas, SQL, que es donde decidimos que sentencia sql vamos a ejecutar.  Aunque, la primera impresión, si observáis el marco rojo que he resaltado en la imagen inferior, aparecen múltiples  campos de propiedades muy similares, adicionales, que os pueden confundir.

query

¡No debería preocuparos! El editor de código personalizado de TUniQuery es capaz de generar y rellenar todas esas líneas mediante un generador incluido, en el que tan solo debéis indicar que campos debe considerar la clave primaria y cuales van a ser actualizables.

Esto es lo que yo hubiera podido poner.

EditorQuery3

Hecho esto, y tras pulsar el botón GenerateSQL, el editor nos mostrará la segunda pestaña, con todo el código escrito automáticamente para cada situación o evento: al insertar, al borrar, al actualizar, etc…

EditorQuery4

Igualmente, el mismo editor contiene un generador para procedimientos almacenados. El que se visualiza en la siguiente imagen:

generador_procedures

Si seleccionamos un procedimiento (yo utilice el creado en las tablas citadas) y pulsamos generar, se provocarán dos acciones distintas. Por un lado, se generarían los estamentos sql asociados al procedimiento, ya que el podría esconder su ejecución el retorno de un cursor editable, (vemos en esa misma imagen, en la parte inferior el área de Query rellena de forma automática). Y en  segundo lugar, si el procedimiento esta parametrizado, igualmente se capturan éstos, y se rellenan los datos asociados a los parámetros. Esto lo podéis ver en la siguiente imagen.

parameters

Esto va de cosas reseñables…, ¿no?

Efectivamente.

Hay detalles que me han gustado de la documentación y que podrían pasar inadvertidos. De hecho, me es imposible señalar con detalle todos los aspectos que resaltaría porque a medida que voy escribiendo al vuelo estas líneas me doy cuenta de que van quedando cosas en el tintero.

Por ejemplo, no he dicho que estos datasets son bidireccionales. Es decir, vas a poder conectarlos de forma directa para navegar a través de una rejilla de datos.

Permiten además lo que se suele llamar CachedUpdates, que va a guardar localmente los cambios y enviarlos a la orden de un ApplyUpdates, estrategia a la que la mayoría de nosotros estamos ya acostumbrados. Contempla también, aspectos que hacen referencia a las claves primarias incrementales y en la documentación se cita cómo actuar en distintos casos, para obtenerlas tras la consulta sql (suponemos una inserción que es el caso mas típico).

Y a todo esto, le sumas el control que nos dan las transacciones, que van a permitir hacer uso de las mismas bien de forma implícita como explicita (inclusive transacciones distribuidas).

Otro punto mas que no he citado: la encriptación de determinados campos. También es posible.

Pues volviendo al tema que abría este apartado, decía que me había gustado la documentación en un detalle que podía pasar inadvertido, y me refería concretamente a que se abordan temas relacionados de alguna forma con algunos puntos citados, como son la existencia de redes inestables, que precisan que configuremos correctamente algunos parámetros de conexión o trabajo. El que se hagan mas o menos llamadas al servidor, se abran o cierren conexiones, se use o no cachedupdates, pueden hacer que el servidor consuma valiosos recursos o que por el contrario sea capaz de responder a la cadena de llamadas de un ambiente de producción. Estos aspectos, se abordan en la ayuda y se recomiendan algunos detalles que aunque puedan a simple vista de sentido común, se nos pueden llegar a escapar.

Así que en ese sentido me parece importante destacarlo.

¿Y por donde empiezo si no tengo ni idea…?

Vamos a crear un proyecto nuevo con la plataforma firemonkey. Podemos usar un formulario en blanco, vacío, ya que solo queremos ver esos primeros pasos en la práctica.

Hay una pagina en la documentación que habla expresamente de esto: Lo básico.

Lo vamos a hacer nosotros con un par de rejillas en ese formulario que hemos creado. ¡Dadme un minuto!

Pienso que es un buen momento para ir dando por concluida la entrada. Tenemos tiempo por delante para investigar en detalles específicos que nos interesen. No obstante, como comentaba anteriormente, modifiqué el código de la entrada de ese reloj para poder probar y experimentar.

En fin… Me parecía correcto incluirlo en la entrada, aun cuando no estuviera testado ni probado rigurosamente. Realmente no tuve tiempo para probarlo en iphone.

Se corresponde la unidad Reloj.pas con la existente en dicha entrada, pero algunos cambios sí fueron necesarios, para adaptarlos al nuevo supuesto: ya que en este caso, el reloj no era de propósito general. El usuario se serviría de su móvil para identificarse al entrar al puesto de trabajo.

El ejemplo del reloj…

MiReloj

En el video inferior, se puede ver ambas aplicaciones en ejecución en un móvil Android (a través del monitor del mac).

 Entre los cambios que tuve que hacer, fueron referentes a la ventana modal que luce en la aplicación original, para identificar y validar al usuario, pidiendo primero la clave de tarjeta y posteriormente el password. En este caso no tenia sentido mostrar una ventana adicional por lo que el interfaz de usuario cambió para solicitar solo el password y leer los datos del usuario de un fichero de inicialización.

Por tal razón, al pulsar el supuesto usuario el botón SendData, se mostraba la pestaña asociada al teclado de la contraseña, y el botón de envío de dicho teclado, acaba ejecutando el código de envío de los registros.

Este es el código, que se apoya en un procedimiento almacenado que devuelve la clave primaria del registro insertado, si tiene éxito.


procedure THeaderFooterForm.acOkEnvioExecute(Sender: TObject);
var
  fList: TList;
  i: Integer;
  iCount: Integer;
begin
  iCount:= 0;
  if Assigned(FEmpleado) then
  begin
      //comprobamos el password del empleado
      if not FEmpleado.AutentificarEmpleado(fValor) then
      begin
        TEmpleado.ReleaseInstance;
        Raise Exception.Create('Error de autentificacion');
      end;

      fList:= TList.Create;
      try
        fList.AddRange(FEmpleado.GetRegistrosHorarios);
        for i:= 0 to FList.Count-1 do
        begin
          if FEmpleado.Id_Empleado = FList[i].IDEmpleado then
          begin
            spRegistrarMovimiento.Params.ParamByName('IDEmpleado').Value:= FList[i].IDEmpleado;
            spRegistrarMovimiento.Params.ParamByName('HoraRegistro').Value:= FList[i].Hora;
            spRegistrarMovimiento.Params.ParamByName('IDTipo').Value:= FList[i].IDTipo;
            spRegistrarMovimiento.ExecProc;
            if spRegistrarMovimiento.Params.ParamByName('IDMovimiento').AsInteger > 0 then
            begin
              FEmpleado.MarcarEnviado(FList[i].Index);
              Inc(iCount);
            end;
          end;
        end;
      finally
        fList.Free;
      end;
      TEmpleado.DeleteMovimientos;
  end;
  TEmpleado.ReleaseInstance;

  case iCount of
    0:labAnotacionEmpleado.Text:= 'No existen registros que enviar...';
    1:labAnotacionEmpleado.Text:= 'Enviado 1 registro...';
    else
      labAnotacionEmpleado.Text:= 'Enviados ' + iCount.ToString + ' registros...';
  end;
end;

 También hago la anotación que ese botón con el título «Save», quedó alojado en ese punto para evaluar que se grababan bien en el fichero de movimientos las instancias. Es una parte que no pude cerrar por falta de tiempo. Imagino que lo suprimiré.

Respecto a la otra aplicación que ha acabado con el nombre «Explorador», no tiene apenas código ni mucho que reseñar. Muestra los registros que se han ido introduciendo para cada empleado desde la aplicación anterior.

Explorador

Os incluyo el código por si queréis darle un vistazo: Descargar

Es un buen momento para cerrar esta entrada y despedirnos por hoy, en una noche tan especial para los cristianos.

Buen camino y Dios os bendiga.

4 respuestas a “Una vista rápida a Unidac (Universal Data Access Components)

Add yours

  1. Estimado muy buena entrada, he utilizado los componente de DevART hace varios años ODAC, UniDAC y dotConnect for SQL, este último teniendo algunas limitantes, que en si son producto de .NET y no de la librería…

    Saludos,

    André

    Me gusta

Deja un comentario

Blog de WordPress.com.

Subir ↑

Marina Casado

Escritora y Doctora en Literatura Española. Periodista cultural. Madrid, España

Sigo aqui

Mi rincon del cuadrilatero, ahi donde al creer que me he rendido, aun sigo peleando.

Recetas y consejos nutricionales

Indicadas para personas con diabetes, recomendadas para todos.

¡Buen camino!

ANÉCDOTAS Y REFLEXIONES SOBRE UN VIAJE A SANTIAGO…

https://lfgonzalez.visiblogs.com/

Algunas reflexiones y comentarios sobre Delphi

It's All About Code!

A blog about Delphi, C++ Builder and related technologies...

The Podcast at Delphi.org

The Podcast about the Delphi programming language, tools, news and community.

Blog de Carlos G

Algunas reflexiones y comentarios sobre Delphi

The Road to Delphi

Delphi - Free Pascal - Oxygene

La web de Seoane

Algunas reflexiones y comentarios sobre Delphi

El blog de cadetill

Cosas de programación....... y de la vida

Delphi-losophy

A Lover of Delphic Wisdom

Delphi en Movimiento

Algunas reflexiones y comentarios sobre Delphi

marcocantu.blog

Algunas reflexiones y comentarios sobre Delphi

Press F9

Algunas reflexiones y comentarios sobre Delphi

El blog de jachguate

Un blog sobre tecnología y la vida en general