sábado, julio 16, 2005

Crónica de una migración exitosa, Parte 1

Entre mas trabajo con Clipper.... mas me gusta xHarbour, y parece modo de mentira, de aproximadamente un año y medio a la fecha, he dejado de lado totalmente a Clipper y todo lo que he desarrollado lo he hecho a 32 bits.

En mi último reformateo de disco duro (procuro hacerlo cada año) realizado en Diciembre del 2004, instale todo lo básico, incluyendo xHarbour, Xailer, FiveWin, Borland C++, MultiEdit, AJMake y me olvidé totalmente de instalar las herramientas de 16 bits, a excepción del Workshop, Clipper y Blinker no se aparecieron por el disco duro hasta mediados de Marzo del 2005.

Con esto en mente, he tratado que todos mis clientes se muevan a 32 bits, que son plataformas sumamente estables, y es que además hoy en día es una labor de urgencia el mover los viejos programas de 16 a 32 bits, porque los 64 ya están a la vuelta de la esquina.

Como casi todo el mundo sabe, me liga un sentimiento afectivo y profesional con Sanrom's Software de México, de una forma u otra, soy algo así como el abuelo de la empresa, así que con esta confianza me puse a trabajar con Israel y Carolina para llevar a cabo la migración a 32 bits de sus 2 programas base: Grades y Cashier, sistemas de control escolar y de caja escolar respectivamente y 2 sistemas "satélites" Bancos y Módulo Web.

Si ya haz migrado tus aplicaciones, entonces sabrás que realmente no es una labor muy compleja, en si misma, casi todo pasa sin cambios, pero para su nueva versión de 32 bits, Isra y Caro querían darle una buena "lavada de cara" al sistema, no solo por fuera sino por dentro, entre los puntos que se querían atacar tenemos:

  • Cambio de la base de datos a tecnología Cliente/Servidor
  • Implementación de esquemas de seguridad para la base de datos
  • Refactorización del código para explotar al máximo los beneficios de xHarbour
  • Rediseño de la interfaz con el usuario para hacerla 100% "XP Look"
  • Implementación de rutinas para integración con Internet

Parte 1, Consiguiendo las herramientas.

Antes de atacar directamente la migración, fue necesario ver que cosas de la versión de 16 bits no pasarían a 32 bits, cuales pasarían con cambios y cuales permanecerían sin cambios.

Lo primero que se acordó fue revisar cuales eran todos lo componentes de terceros que se estaban usando y ver la manera de sustituirlos o de que en caso de contar con el código fuente de los mismos de recompilarlos, la lista fue de dar miedo:

  • TSBrowse, utilizado en casi un 80% del código y prácticamente para todo
  • TImage, para visualización de fotos de los alumnos
  • ChartFX, como generador de gráficas, en su versión de 16 bits, en formato VBX.
  • FileXLS, para exportar la información a Excel
  • TMultiPreview, para tener varias ventanas de vista previa abiertas al mismo tiempo
  • TSMTP, de Luis Krause para envío de correo electrónico
  • CanalFive Calendar, para captura de los datos tipo fecha.
  • INFOUNZ.DLL y WIZZIP.DLL para generación de archivos .ZIP de respaldo.

La parte mas compleja fue sin duda el TSBrowse, ya que a 32 bits, en su ultima versión (7.01) presenta varias fallas, y además había que tomar en cuenta que todo el sistema nuevo sería basado en Advantage Database Server, razón por la cual y después de probar sin éxito la nueva versión de TSBrowse, se decidió cambiar totalmente de browse, por el TWBrowse de Hernán.... mala idea.... mas del 80% del código del sistema son browses y todos basados en TSBrowse, la labor de cambiar todos los browses del sistema llevaría a tener que volver a escribir casi todo el código, con lo cual descartamos la idea, y nos arriesgamos en una misión suicida... tomar el código del TSBrowse, tal cual se tenía en la versión de 16 bits y compilarlo a 32 bits "a ver que pasa".... pues no pasó mucho...., bueno si, en realidad el código fuente pasó completo y funcionó a 32 bits, con algunas fallas sobre todo en el tema de manejo de "alias" cuando se trabaja en ventana MDI, pero gracias a la inestimable colaboración de Victor Tomás (www.listoelpollo.blogspot.com) que nos facilitó algunas modificaciones que él había hecho a esta clase, ahora funciona casi impecablemente a 32 bits (aún hay cosas que no nos gustan, pero nada que nos detenga o que impida funcionar al sistema).

Luego de librar el problema del TSBrowse atacamos el problema de la visualización de imágenes, en la versión de 16 bits se había venido utilizado la clase TImage de FiveWin, esta clase permite visualizar archivos con el formato BMP, JPG, GIF, TIFF, etc y está basada en las DLLs NVIEWLIB.DLL (32 bits) y NVIEWL16.DLL (16 bits), ambas gratuitas y que se incluyen con FiveWin. En estricta teoría, FiveWin de 16 bits puede hacer uso de las DLLs de 32 bits y esto es cierto bajo los Windows 9x (95, 98 y ME), sin embargo, bajo sistemas operativos TRUE-32 (NT, 2000 y XP) ¡ no se puede utilizar la DLL de 32 bits desde un programa de 16 !, así que para la version de 16 bits tuvimos que modificar la clase TImage para que siempre funcionara con la DLL de 16 bits, pero esto lleva un precio que pagar... la carga de las imagenes es muy lenta y eventualmente cuando se satura la memoria de la máquina, el programa invariablemente falla con un GPF. Por esta razón, a 32 bits decidimos cambiar totalmente de herramienta, y utilizamos la clase FreeImage de Enrico Maria Giordano. Esta clase está basada en un DLL OpenSource llamado precisamente FREEIMAGE.DLL, Enrico hizo un excelente trabajo escribiendo la clase y haciendo los wrappers para FiveWin Harbour que hacen uso de este DLL que es gratuita, 100% 32 bits y con una velocidad de carga muy muy rápida y lo mejor de todo, sin cambiar ni una linea del código fuente, porque la clase integra los mismos métodos y datas que la clase original de FiveWin. De la mano de lo anterior, se utilizó también la clase TZoomImage de Jaime Iruzun (www.codigoescrito.com), esta clase permite aumentar o disminuir la visualización de imagenes pero realiza esta operación sin deformación de la imagen.

Los reportes son parte importante de cualquier sistema, y la graficación y exportación de datos también, en la versión de 16 bits se utilizaba un VBX llamado ChartFX que se podía distribuir de manera gratuita, a 32 bits habia 2 opciones unicamente: la TGraph nativa de FiveWin, o bien utilizar ChartFX pero ahora en su modalidad ActiveX. Usar TGraph era una solución buena, pero llevaba implicito cambiar TODO el motor de graficación del sistema, aquí entró nuevamente a rescatarnos Victor Tomás con su clase TChartFX para 32 bits, adquirimos una copia de ella y también del ChartFX ActiveX. Este componente se maneja por OLE, por lo tanto se integra super bien con xHarbour, además tiene un montón de posibilidades y lo mejor de todo, a pesar que tuvimos que cambiar algunas cosas del código, se mantuvo mucha de la filosofia de programación para las gráficas.

La exportación de datos a Excel se realizaba por medio de la clase TFileXLS de Ramón Avendaño, desafortunadamente, no existen los códigos fuentes de dicha clase, solo se tiene la LIB para 16 bits y algunas compilaciones de la misma para versiones viejas de Harbour, la opción lógica era usar TExcelScript de Victor Tomás, pero esta clase te limita porque requiere que tengas instalado Excel en el equipo donde la vas a ejecutar. Ante este desolador paisaje, tuvimos que recurrir a un "truco sucio" para obtener el código fuente de TFileXLS, no quiero entrar en detalles de como lo hicimos, pero que se sepa unicamente que hay un Valkyrie involucrado.

La clase TMultiPreview no tuvo mucho problema, se cuenta con el código fuente y además se aprovechó para modificar el RPREVIEW.PRG para que la barra de botones de la ventana de vista previa se ajustara al estilo de la nueva interfaz.

El sistema cuenta con un sistema de "mail merge" que permite enviar correos electrónicos masivos a los padres de familia, para eso se utilizó inicialmente la clase TSMTP modificada por Luis Krause sobre la clase original de FiveWin, sin embargo, esta clase no maneja autenticación de usuarios en servidores que requieran clave de acceso y presenta algunos problemas cuando se quieren enviar archivos anexos, razón por la cual y debido a que además se integrarían otras funciones de internet, se hizo uso de la libreria FUNCKY, que integra un objeto SMTP para estos menesteres, además de otras cosas muy interesantes, la ventaja de usar esta libreria de funciones es que no requieres de tener una ventana abierta para enrutar los mensajes al WINSOCK, Funcky se hace cargo de eso directamente, además de que Funcky despacha los correos de una manera sumamente eficiente y super rápida.

CanalFive es el nombre de LOS COMPONENTES visuales que debes utilizar cuando quieres tener una aplicación que sea muy atractiva visualmente hablando, son componentes muy baratos y muy simples de implementar, escritos casi en su totalidad en FiveWin, el sistema de16 bits utilizaba C5 Calendar, para capturar campos fechas, y a pesar de contar con el código fuente de este componente, hubo un módulo en "C" que no se dejó compilar, por esta razón se decidió cambiar todos los gets que utilizaban este control por un control tipo DATEPICKER nativo de FiveWin Harbour, no hubo problema con la implementación salvo un pequeño detalle.... un DatePicker no permite dejar una fecha vacía, estamos estudiando varias soluciones que nos han sugerido, pero hasta ahora ninguna ha funcionado, seguiremos informando......

Finalmente, el sistema de respaldo/restauración de archivos se basaba en funciones que FiveWin traía incluidas y que estaban incluídas en 2 DLLs: WIZZIP.DLL para crear archivos .ZIP e INFOUNZ.DLL para desempacar archivos ZIP, sin embargo estos DLLs son de 16 bits y no son utilizables bajo 32 bits. Afortunadamente para nosotros, xHarbour incluye entre sus contribuciones la HBZIP, unas librerías que permiten manipular archivos .ZIP y que no requieren de ningun DLL externo.

Una vez conseguidas todas las herramientas, pasamos al cambio de tecnología de la base de datos, pero eso.... eso es otra historia.

sábado, julio 09, 2005

Cronica de una migración exitosa, Parte 2

Parte 2. La base de datos:

Cuando pretendes ganarte la vida vendiendo software, hay muchas cosas a tomar en cuenta en cuanto a diseños, estrategias de mercadeo, etc. Una de ellas es la base de datos. Pocos son los sistemas que veremos en el mercado cuyo fin no sea almacenar datos, de una forma u otra todos lo hacen.

Quizá te hayas encontrado muchas veces, cuando vas a vender un desarrollo, la pregunta típica de todo aquel que siente tener los conocimientos necesarios de informática por el simple hecho de trabajar todos los días con una computadora:

¿ En que está hecho ?
¿ Con qué base de datos trabaja ?

En realidad estas preguntas deberían ser las menos hechas, en mi opinión las preguntas correctas serían... ¿ hace realmente bien las cosas ?, ¿ es rápido y fácil de usar ?.

Todos hemos visto caras de "estás obsoleto" cuando le comentas a alguien que tu sistema está hecho en Clipper con archivos DBFs, inmediatamente todo el mundo te ve con cara de Parque Jurásico, por eso ahora, para evitarnos el mal trago, simplemente decimos: Esta hecho en Borland C++... ¡¡¡ y que me digan que no es cierto !!!, no va a faltar el listillo que va a preguntar... ¿ a ver el código fuente ?, no importa, muestrale el PCODE que genera xHarbour, seguramente la siguientes expresión será .... si si, ya se nota que está hecho en "C" ( si yo sé "C", ¿ quien contra mi ?).

El Software de Sanrom's va por la version 5.x, y la nueva versión de 32 bits será la 6, y en todas las versiones anteriores se habían utilizado archivos DBFs, con índices CDX, trabajando todo el software para red.

El cambio a 32 bits se quiso aprovechar para hacer un cambio también en el esquema de almacenamiento de datos, por muchas razones que iremos analizando mas adelante.

Desde la version 1.x de los sistemas Sanroms, Israel me había estado insistiendo en que su gran preocupación eran los archivos de datos, que el volúmen aumentaba en proporciones moustrosas cada mes, y por lo mismo se hacía mas lenta la ejecución del programa, lo cual está claro, en un colegio de 2,500 alumnos, donde cada alumno lleva un promedio de 10 materias, se generan mensualmente 25,000 registros de datos sólo para calificaciones, si multiplicamos eso por 10 meses de actividad docente al año, llegaremos a la conclusión de que se generan sobre 250 mil registros de datos en un período lectivo anual, y si a eso aunamos que hay que guardar históricos de por lo menos 5 años, tenemos que el archivo de calficaciones tendra algo así como 1'250,000 registros, el archivo de calificaciones genera tambien por lo menos 10 pagos anuales, multiplicados por 2,500 alumnos, esto nos da un total de 25,000 registros solo de pago de colegiatura normal, pero ademas hay otros tipos de pago como reposición de credencial, estacionamiento, actividades extraescolares, etc. asi que no solo son los 25,000 registros anuales de colegiaturas, son un poco mas.... y eso que no hemos contado todos los registros adicionales que se van generando con el uso del sistema como por ejemplo maestros, bitacoras, materias, horarios, etc. etc. etc.

Si a eso agregamos que nunca falta el usuario con iniciativa que le mete mano a los DBFs con Excel y luego se da el lujo de decirle a Excel que quiere guardar el archivo (ha sucedido más de una vez) y la corrupción de índices, que nunca debe faltar en un buen sistema... llegamos a la conclusión de que el almacenamiento de datos debía recibir una buena revisión.

Desde la version 4.x de los sistemas yo le había sugerido a Sanroms utilizar Advantage Database Server para garantizar la seguridad de la base de datos, y en ese entonces intentamos hacer la migración, sin embargo, tuvimos graves problemas con la clase TSBrowse a 16 bits y dado que el sistema está basado en un 80% en esa clase, desistimos en el intento.

La idea de utilizar ADS ya le venia dando la vuelta en la cabeza a la gente de Sanroms desde hace mucho tiempo, y así pues, para la versión de 32 bits se decidió que el código de esta nueva versión seria totalmente optimizado para utilizar ADS y se aprovecharía al maximo el RDD ADS con todas las funciones que tiene implementadas.


¿ Porqué ADS y no un SQL ?

La respuesta es sencilla, todos los datos actuales de los usuarios de los sistemas de Sanroms están guardados en DBFs, el camino lógico de migración hacia una herramienta mas "potente" con tecnología Cliente/Servidor, es ADS, desde el punto de vista de que no hay que hacer migración de datos, el usuario final seguirá trabajando con sus mismos datos y metodologías pero con un mejor manejo de sus tablas DBFs.

Otra razón para utilizar ADS, era que no había que hacer grandes cambios en el código fuente para el acceso a los datos, es decir, las operaciones actuales de lectura/escritura de los datos a las tablas permanecerían sin cambio, con lo cual habia un ahorro significativo en tiempo de programación, cambiar a un SQL hubiera significado volver a tener que escribir todas las rutinas de acceso a los datos y eso llevaría mucho, mucho, mucho tiempo adicional, porque tendríamos que rediseñar la base de datos primero y luego tendriamos que adaptar el programa a las nuevas estructuras de tablas (conozco empresas que llevan mas de un año intentando hacer funcionar un programa que usaba DBFs ahora con SQL y no terminan, y van como para otro añito mas o así).

Otra razón para utilizar ADS fue la portabilidad entre sistemas operativos de red, si hay una cosa en la que los colegios no gastan, es en tecnología, luego entonces no todos los colegios tienen servidores Windows NT, los hay que tienen Novell, otros que tienen Linux y otros menos agraciados, que trabajan con redes punto a punto con Windows 9x o XP, sin servidor dedicado. Si usábamos MySQL podíamos usarlo en Windows y en Linux pero no en Novell, si usábamos SQL Server podíamos usarlo en servidores Windows, pero no en Linux y tampoco en Novell, si usabamos Oracle, poíiamos utilizarlo en todos los servidores, pero el precio de la base de datos se disparaba hasta las nubes.... ¿ solución ?: Nuevamente ADS, es el único servidor de datos que tiene versiones para TODOS los sistemas operativos de red: Novell desde la versión 4.x, Windows NT/2000/2003 Server, Linux y hasta para redes punto a punto con Windows 9x.

Por otro lado ADS puede ser utilizado por cualquier lenguaje de programación, ya que soporta sentencias SQL para manipular las tablas, esto le permite a otros sistemas dentro del mismo colegio convivir e intercambiar datos con las tablas de los sistemas Sanroms.

El gran obstáculo en este punto, fue el precio del servidor de datos, que fue un problema relativo, los colegios pequeños, con pocos alumnos y por ende pocos usuarios, usarán el servidor local de ADS que es gratis y que puede manejar perfectamente hasta 5 usuarios simultáneos, claro, no tiene todas las grandes ventajas del servidor profesional, pero se puede trabajar con él muy bien y facilita la migración al servidor remoto (profesional) de una manera transparente en un futuro, si el colegio así lo decide. Los colegios mas grandes y con mayor número de usuarios (y con mas alumnos, por lógica) no tendrían ningún problema en adquirir servidores profesionales ADS, de hecho por lo menos 5 ya han pedido cotización.

Preparándose para ADS.

Mucha gente que ha utilizado el servidor local de ADS se queja de la lentitud del mismo, sin embargo no se dan cuenta de que para aprovechar todas las ventajas de ADS, hay que seguir algunas reglas básicas de uso.


Apertura de Archivos.

Por ejemplo, bajo ADS es necesario abrir TODAS las tablas de trabajo al principio del programa y no como en Clipper estamos acostumbrados, es decir, a abrir las tablas conforme las vamos necesitando y cerrándolas en el momento en que terminamos de usarlas, existen razones válidas para hacer esto, la mas común de todas es para evitar la corrupción de índices, entre menos tablas tenga abiertas, menos índices se pueden dañar, (lo cual es una reverenda tontería, cuando hay un índice dañado usualmente no regeneramos solo el índice dañado, regeneramos TODOS los índices de TODAS las tablas "por si las dudas", asi que... si de todas formas vamos a regenerar TODOS los índices en caso de daño, ¿ qué mas da que se dañe uno o todos ? ).

La segunda razón para esta serie de operaciones de Apertura/Cerrado de archivos DBFs, se debe a la limitación de los sistemas de 16 bits con respecto al número de archivos que se pueden abrir simultáneamente, los famosos FILES y BUFFERS de Clipper. Aunque en teoría Clipper puede abrir 255 archivos al mismo tiempo, esto no es del todo cierto, está limitado a una serie de parámetros en el CONFIG.SYS que determinan el número máximo de archivos que se pueden abrir y usalmente, a 16 bits, ese número está limitado por la memoria que la computadora.

A 32 bits no hay limitación en el número de archivos a abrir simultáneamente, así que la primer labor de programación para optimizar el código de Sanroms para usar ADS, fue eliminar TODOS los USE dentro del código del programa, y creánme, no fue una labor fácil porque había que revisar miles de líneas de código. También hubo que crear una rutina que abriera TODOS los archivos de datos junto con sus índices de una sola sentada, al arrancar el programa, sin embargo, el realizar estas operaciones llevó a mejorar el control de "alias" de las tablas porque permitió asignar "alias" fijos a los archivos abiertos, que nunca cambiarían durante toda la ejecución del programa. A nivel de arquitectura de ADS, este cambio optimizó enormemente el uso del servidor, ya que el servidor (local o remoto) solo recibe una petición de apertura por estacion de trabajo, esto le permite despachar los datos con mayor rapidez, ya que al tener abierto un archivo de datos en el servidor ADS, no es necesario volverlo a abrir por cada petición de la estación de trabajo, en cambio, si abrimos y cerramos continuamente archivos, estamos sobresaturando al servidor ADS de solicitudes de apertura y cerrado y por lógica reduciendo el rendimiento del mismo. En las pruebas realizadas en red, una vez realizada esta operación de optimización , tanto con el servidor local como remoto, se observó un comportamiento similiar en velocidad en el acceso a los datos.

Indices y Funciones definidas por el usuario.

Otro cambio necesario fue hacer una revisón a las llaves de los índices en busca de "FDUs" (Funciones Definidas por el Usuario), ADS no soporta que una llave del índice sea una función definida por el usuario, por ejemplo:

INDEX ON SumaNombre(appaterno,apmaterno,nombre) TAG NomCompleto

Esto no es una expresión válida para el motor de indexación de ADS ¿ porqué ?, pues porque la función SumaNombre() no es reconocida por ADS, recuerda que ADS es un programa EXTERNO a tu aplicación y no puede interactuar con ella, de tal forma que si el código fuente de la función SumaNombre() forma parte de tu archivo EXE en xHarbour, el servidor de ADS no tiene forma de "meterse" en tu archivo EXE para ver que operaciones realiza la función y ver que valor devuelve. Para solucionar este problema simplemente se agrega un campo nuevo al DBF, llamado por ejemplo NomCompleto, y al momento de hacer el REPLACE de los datos, se hace un llamado la función SumaNombre, así:

REPLACE NomCompleto WITH SumaNombre(appaterno, apmaterno, nombre)

Y luego, se genera un índice normal sobre ese campo:

INDEX ON NomCompleto TAG NomCompleto

De esta forma tenemos solucionado el problema (parcialmente), aún tenemos que ver que pasa con esos índices temporales que se generan con el fin de "filtrar" una base de datos.

AOFs, Filtros Optimizados Advantage.

Durante toda nuestra vida de Clipperos hemos aprendido que SET FILTER no es precisamente la mejor manera de filtrar los datos cuando se requiere solo un pequeño grupo de ellos dentro de una tabla y que la peor combinación que se puede hacer es mezclar un SET FILTER con un BROWSE, eso mas lento que el caballo del malo en una película de vaqueros.

Los índices CDX nos abrieron las puertas al maravilloso mundo de los SCOPES, un simple SET SCOPE TO y los filtros sobre las tablas se hacen a la velocidad del rayo, el precio a pagar.... agregar un índice al CDX sobre el campo que queremos filtrar, al parecer, hemos triunfado, peroooooooo......

¿ Que pasa si el criterio de filtrado no está dentro de un índice o bien esta en razón de una variable del programa ?, ¿creamos un índice "al vuelo" ?, no es mala idea, pero eso lleva tiempo.... ¿ que hacemos entonces ?.

Si fuesemos programadores de dBase III+ recurriríamos al SET FILTER sin importar cuanto tiempo se lleve el dichoso filtro, pero ADS nos regala una cosa llamada AOFs (Advantage Optimized Filters = Filtros Optimizados Advantage), característica incluída tanto en el servidor local como en el remoto.

Un AOF es un "filtro" que es realizado por el servidor ADS directamente, no por tu programa xHarbour. Un AOF se ejecuta con la misma velocidad que un query de SQL, y devuevle resultados de una manera muy rápida, la gracia de utilizar un AOF, consiste en saber crear el filtro.

Supongamos que tenemos el siguiente pedazo de código:

nEdad := 25
SET FILTER TO EmpEdad >= nEdad

Esto funcionaría en Clipper normal, pero no con ADS, ¿ porqué?, pues porque ADS no conoce el valor de la variable nEdad y por lo mismo no puede "resolver" el filtro de una manera adecuada, para utilizar un AOF, debemos de pasarle al servidor ADS la expresión "digerida", es decir con los valores que tiene que buscar, en forma textual, esto se hace creando una cadena de caracteres que contenga la expresión de filtro:

nEdad := 25
cFiltro := "EmpEdad >="+ALLTRIM(STR(nEdad))

Esto crea una cadena de caracteres con la expresión de filtro, para enviarsela al "motor" de AOFs, lo haremos mediante la función DBSETFILTER() como bloque de código y también como cadena de caracteres:

cBloque := "{"+cFiltro+"}"
DBSETFILTER(&cBloque,cFiltro)
DBGOTOP()


Esta simple operación realizará un AOF sobre la tabla DBF la velocidad de este tipo de filtro es IMPRESIONANTE, casi igual de rápido que un SCOPE.

Así pues, se revisó TODO el código para implementar AOFs en todas aquellas partes que se pudieran ver beneficiadas de su uso.


El divorcio del DBF.

Durante el proceso de optimización del código para ADS y viendo todas las bondades que iba arrojando la implementación dentro de los sistemas, nos asaltó la duda.... ¿ y si mejor utilizamos tablas ADT con índices ADI en vez de DBFs con índices CDX ?.

La idea no se quedó mucho tiempo en el aire, usando el ARC (Advantage Data Architech), una herramienta similar al DBU pero para ADS, exportamos todas las DBFs a archivos ADT y nos encontramos con varias sopresas:

La primera fue que la tabla ADT está mas optimizada que el DBF tradicional, es aproximadamente 10% mas pequeña que su similar DBF con el mismo número de registros.

La segunda fue que la tabla ADT funciona mas rápido que el DBF, es decir, que la recuperación de datos usando el servidor ADS sobre una tabla ADT con índices ADI es mas rápido que sobre un DBF con índices CDX.

La tercera fue que la tabla ADT no se puede abrir mas que con el ARC, ni Excel la puede abrir, con lo cual alejabamos de las ojos curiosos y de los usuarios con iniciativa los datos del sistema.

La cuarta fue muy impactante..... la estructura de la tabla ADT no es igual a la de la tabla DBF tradicional, por ejemplo, un campo que un DBF es un NUMERIC de 2 enteros con 0 decimales, en una tabla ADT es de tipo INTEGER, pero un campo que sea un NUMERIC de 10 enteros con 2 decimales en ADT es un campo tipo FLOAT, lo mas curioso de esto es que la función DBCREATE() de xHarbour, puede recibir una estructura de DBF como parametro, y la tabla ADT resultante tiene OTRA estructra distinta, de acuerdo al esquema de almacenamiento de las ADT, esto no tiene la menor importancia en la operación del programa porque de hecho no hay diferencia en el manejo de los campos, se leen y se escriben de la misma manera que un DBF, es mas, si un campo es, por ejemplo, de tipo FLOAT y se asigna a una variable como se hace normalmente, se trabaja como un NUMERIC común y corriente. A los sistemas Sanroms, esto le afectó porque cuenta con un "verificador" de estructuras, es decir, un modulo que verifica que la estructura de los archivos de datos sea la correcta para utilizar el sistema, pero esta rutina verificaba sobre estructuras DBF, no sobre ADT por lógica ese módulo SIEMPRE reportaba problemas con la base de datos, la solución fue simple, se cambió el programa para verificar las estructuras sobre los tipos válidos de ADT y asunto arreglado.

Otra cosa que se realizó fue la creación de un pequeño módulo externo que "migrara" los DBFs a tablas ADTs, este pequeño módulo migra todas las tablas del sistema en menos de 5 minutos de DBF a ADT, por la parte de los índices no hay el menor problema tampoco, estos se generan utilizando los comandos y funciones que se utilizan normalmente con índices CDX, es decir INDEX ON .... TAG .......

Lo bueno de cambiar a tablas ADT fue que mejoramos la velocidad de acceso a los datos, protegimos los datos de miradas curiosas y de herramientas que pueden manipular los archivos y lo mejor de todo: No tuvimos que mover nada del código que lee y escribe los datos a los archivos, osea que APPEND y REPLACE siguen funcionando.

Todo o nada, implementando transacciones.

Una de las cosas mas interesantes de ADS y mas útiles son las TRANSACCIONES, una transacción en terminos simples, son un grupo de operaciones sobre las tablas de la base de datos que se tienen que realizar TODAS hasta completarse, por ejemplo, en el caso de la elaboración de una factura, se tocan varias tablas, de unas se traen datos, por ejemplo de la de clientes, en otras se alteran valores de los campos, como por ejemplo en los inventarios y cuentas por pagar, en otras se agregan nuevos registros, como por ejemplo en la contabilidad, bueno todas esas operaciones que afectan las distintas tablas se conocen dentro de ADS como una TRANSACCION.

ADS tiene un control de transacciones que se implementa mediante 2 comados BEGIN TRANSACTION y COMMIT TRANSACTION, mediante estas 2 simples operaciones grantizamos que TODAS las operaciones que deban ser realizadas sobre una grupo de tablas se hagan totalmente hasta completarse, o que en caso de que "algo" falle tanto a nivel hardware, como software, no se realice ninguna de ellas, dejando todas las tablas en el último estado conocido, un esquema comun sería algo como esto:

BEGIN TRANSACTION
SELECT ....
APPEND BLANK
REPLACE....
REPLACE....
REPLACE....
.....
SELECT ....
IF DBSEEK .....
REPLACE....
REPLACE...
ELSE
APPEND BLANK
REPLACE .....
REPLACE ....
ENDIF
COMMIT TRANSACTION

En el esquema anterior y bajo el sistema de transacciones de ADS, TODAS las operaciones de añadir registros y modificar campos se realizaran desde la linea que dice BEGIN TRANSACTION hasta la línea que dice COMMIT TRANSACTION, si algo llegara a ocurrir entre dichas lineas, ya sea un problema de software (un error de sintaxis por ejemplo) o un problema de hardware (una falla en la corriente eléctrica por ejemplo), el servidor ADS DESHACE todo lo que tenga hecho, a esto se le llama un ROLLBACK TRANSACTION, y deja las bases de datos como estaban ANTES de hacer el BEGIN TRANSACTION, esto es fenomenal, porque ya nunca mas nos enfrentaremos a los problemas de bases de datos incompletas o con datos faltantes.

El motor de transacciones solo esta soportado en el servidor remoto ADS, el servidor local, aunque reconoce los comandos BEGIN TRANSACTION y COMMIT TRANSACTION, no ejecuta ninguna accion.

Encriptar o no encriptar.... esa es la cuestión.

Como parte del nuevo sistema de seguridad de ADS, decidimos encriptar las bases las bases de datos, ya que en el remoto caso de que alguien pudiera "robarse" los archivos de base de datos y llevarselos a otra computadora, no pueda ni siquiera leer la información.

El motor de encriptamiento de ADS utiliza un encriptamiento de 128 bits, que adicionalmente no genera el mismo código para la misma letra, digamos por ejempo que se tiene un valor "aaaaaa", ADS encripta la cadena y generaría algo como esto "5&$2q!", es decir, la misma letra no genera el mismo código encriptado, depende de la posición en que se encuentre dentro de la cadena de caracteres original. El sistema de encriptamiento codifica TODOS los tipos de campos, de tal forma que no importa que el campo sea numérico, lógico o cadena de caracteres, todos los datos están encriptados.

Adicionalmente ADS utiliza un algoritmo de encriptamiento de doble llave, donde el programador debe proporcionar un "password" previamente definido por el, este password se utilizará como "semilla" para encriptar la base de datos, la encriptación se realiza a nivel área de trabajo, con lo cual se pueden tener disitintos passwords para las distintas áreas de trabajo, de esta forma, aun en el caso de que alguien se robe los archivos, no le será posible visualizar la información , necesitaria 2 componentes: el motor de ADS y el password correcto.

La encriptación se realiza por medio del servidor ADS (local o remoto, esta características está incluida en ambos), mientras el archivo permanece encriptado en disco, es el servidor ADS quien hace el proceso de encriptado/desencriptado y envía a las estaciones de trabajo los datos desencriptados para su correcta visualización y los datos recibidos de las estaciones son encriptados por el mismo servidor para guardarlos en el archivo físico en disco.

La encriptación trajo un problema adicional, los comando COPY TO y APPEND FROM requieren que los datos sean desencriptados para poder exportarlos a nuevos archivos que puedan ser leidos.

Otras cosas a tomar en cuenta:

NULL no es lo mismo que vacío.... NULL es un valor que manejan muchas tablas SQL, un campo vacío en un archivo ADT no tiene un valor "vacío", sino que tiene un valor NULL, que es un valor neutro (como NIL) pero que a fin de cuentas es un "valor", esto nos complico un poco la vida al momento de hacer filtros o índices utilizando EMPTY(campo), sucede que los campos vacíos no respentan esta condición, porque en realidad no estan vacíos, tienen NULL, luego entonces la solución fue llenar estos campos vacíos con cadenas de caracteres vacías, o bien ceros en el caso de los campos numéricos.

¿ Cómo editar los datos ?.... Esa fue otra, con DBFs tenemos un gran número de editores para manejar los datos, el WinDBU, Prometeus, el mismo DBU de Clipper.... Con tablas ADT... ¿ que editor se utiliza ?, pues el mismo que provee ADS, el llamado ARC o Advantage Data Architech.

ARC permite hacer muchas de las labores de mantenimiento de los datos utilizando browses y los menús del programa, cosas mas complejas como reemplazos masivos, borrado de datos y otras similares no pueden realizarse directamente, pero ARC provee de un editor de instrucciones SQL que utilizando sentencias como SELECT, INSERT, UPDATE y DELETE te permite darle mantenimiento a los datos con facilidad, pero eso si, necesitas conocer un poco de SQL.

Si la tabla está encriptada, ARC te pedirá el password para poder abrir cualquier tabla ya sea desde el editor de datos o desde el editor de sentencias SQL, de esta manera, aún si alguien se roba los datos e incluso contando con el ARC, no podrá verlos, porque no tiene los passwords para las disintas tablas.

ARC te permite adicionalmente monitorear el servidor remoto (cuando se tiene instalado), crear "Diccionarios de datos" que son colecciones de tablas con niveles de seguridad a nivel usuario , tabla y registro, como en los SQL profesionales, que se utilizan para el acceso a los datos via internet.... je, olvide mencionarlo, los programas ADS pueden acceder a los datos via internet utilizando un componente incluido en el servidor remoto llamado AIS (Advantage Internet Server).

En realidad la explicación es mas extensa de lo que en realidad se trabajo, todo el proceso de cambio en el código y prueba de las bases de datos con los servidores remoto sy local llevo poco menos de 2 meses.

Una vez concluido con el cambio de formato de base de datos, pasamos a la parte de optimización del código para aprovechar las extensiones de xHarbour, como verás son cosas que el usuario no va a notar, pero que era necesario hacerlas para una migración exitosa a 32 bits.

viernes, julio 08, 2005

Crónica de una migración exitosa, Parte 3

Parte 3. Refactorizando el código.

Otra de las cosas que se hicieron para la migración a 32 bits de los sistemas Sanrom's, fue realizar un proceso de REFACTORIZACION del código fuente, otro proceso que el usuario final nunca ve, pero que internamente lleva mucho del trabajo para el programador.

La refactorización del código como lo explicó alguna vez José Luis Sánchez Navarro en su blog "Avemundi" es el proceso de revisar el código fuente no en búsqueda de bugs, sino en búsqueda de funciones o rutinas que se puedan optimizar, es decir, localizar aquellos puntos donde un FOR X... puede ser sustituido por un AEVAL, un grupo de instrucciones por un bloque de código, revisar que todas las variables estén bien definidas, quitar funciones obsoletas o que nunca se utilizaron, etc

Desde la primera versión de los sistemas Sanrom's, hace mas de 6 años, se habían ido acumulado pedazos de código que estaban ahí, sin hacer nada, y dado que los sistemas siempre están en constante cambio para adaptarlos a las necesidades y sugerencias de los clientes, mucho código realizado para probar tal o cual característica se queda como parte del fuente original aunque nunca se use.

Aprovechando que había que revisar todo el código fuente en busca de USE para adaptarlo al uso de ADS, se decidió además que la refactorización debería ser enfocada a utilizar al máximo las extensiones de xHarbour.

Así pues, con esto en mente, se procedió a hacer cambios en el código para utilizar las extensiones de xHB como WITH OBJECT, FOR EACH, SWITCH, variables GLOBAL, estas extensiones además de darle mayor estética al código fuente, repercutieron ampliamente en el desempeño del programa, se nota una velocidad bastante mayor por ejemplo en el acceso a arreglos en memoria.

Si quieres saber el porqué muchas extensiones de xHarbour mejoran el desempeño del programa, tienes que ver LA COSA DE NEGRO, jejeje y no es una invitación a ver algo sucio, se trata nada mas y nada menos que del blog de Walter Negro.

Walter Negro, como dice el amigo Julio Llinás, "enciende bajo el agua", y es que su conocimiento sobre la arquitectura interna de xHarbour y como explotarla al máximo es sorprendente, La Cosa de Negro es una referencia obligada para todos aquellos que deseen explotar al maximo las extensiones de xHarbour, ahí encontrarás el que y el por qué de muchas cosas que siempre te habias preguntado y que son respondidas por Walter de una manera simple de entender, sin entrar en demasiados tecnisismos.

Aprovechando todo lo que Walter explica en su blog, utilizamos la refactoriación del código original para al mismo tiempo optimizarlo para xHarbour, y creanme, ha valido la pena el esfuerzo, la aplicación se desempeña mucho mejor.

El factor tiempo.

A estas alturas del campeonato, te podrías estar preguntando.... ¿ y cuanto tiempo les llevó montar todo este circo para moverse a 32 bits ?, pues no mucho, si lo ponemos sobre la balanza, en realidad llevó solamente 6 meses, el dia 1 de Enero del 2005 dimos el banderazo de salida para el comienzo del desarrollo de las versiones 6 a 32 bits con tecnología cliente/servidor.

Los los nuevos productos fueron lanzados el 1 de Julio, exactamente 6 meses después de comenzar. ¿ qué.... 6 meses no es mucho tiempo ?, no si tomamos en cuenta que fueron 4 sistemas los que se movieron a 32 bits: Bancos, Control Escolar, Caja Escolar y el Módulo de consultas WEB, visto así el tiempo que se llevó el proceso de migración de cada sistema fue de 1.5 meses 6 semanas aproximadamente.


En el último artículo de esta serie, explicaré los ajustes que hicieron en la interfaz con el usuario, que también se trabajó a fondo para que el programa se "sintiera" como una aplicación nativa de Windows XP.

miércoles, julio 06, 2005

Crónica de una migración exitosa, Parte 4

Parte 4. La interfaz con el usuario.

Esta es la parte final de esta serie de artículos dedicados a como logramos migrar una aplicación de 16 a 32 bits, sin morirnos en el intento.

Esto de hacer software es como la construccion de un automovil, puedes tener el motor mas potente, el super equipo electronico, pero si tu carrocería es una porquería, pues apaga y vámonos, Ferrari y Lamborghini venden mas coches por sus espectaculares carrocerías que por sus no menos impresionantes motores.

Llegados a este punto, donde ya habíamos ajustado la base de datos, habíamos refactorizado el código y todo era exitoso y triunfador, llegó el momento de comenzar a trabajar con la carrocería, es decir la parte del programa que le da la cara al usuario.


Iconografía.

Como parte de la nueva cara de los sistemas Sanrom's se decidió cambiar todos los iconos de todos los sistemas por imagenes tipo XP, de tal forma que aún cuando el programa se ejecutara en Windows 98 se "sintiera" como si fuese XP.

Así pues decidimos utilizar la biblioteca de iconos de Icon Experience (www.iconexperience.com), realmente una buena cantidad de iconos por un precio muy accesible.



Parece modo de mentira, pero aunque tengas mas de 1,500 iconos, nunca encuentras todo lo que necesitas, así pues , se utilizaron tambien los famosísimos iconos de FOOOD, (www.foood.net) toda una tradición en cuanto a diseño de iconos buenos, bonitos y baratos.



Aún y con todos estos recursos visuales, hubo algunos iconos que se tuvieron que crear "al vuelo" combinando ambas colecciones y utilizando Photoshop.


Diseño de pantallas y temas XP.

El diseño de pantalla, aunque ustedes no lo crean, no se hace así porque sí, ni como queremos nostoros, hay mucha bibliografía sobre el diseño de interfaces, pero el manual de referencia OBLIGATORIO para desarrollar una buena aplicación Windows es:



DISEñO DE INTERFAZ DE USUARIO PARA APLICACIONES WINDOWS
Traducción de José Ángel Vallejo Pinto
Editorial McGraw-Hill
ISBN: 8448127684.



En este libro se encuentran explicados a detalle las directrices oficiales de Microsoft para que una aplicación pueda ser considerada "Compatible con Microsoft Windows", mucho del software que se vende por ahi, dice esta famosa leyenda, pero en realidad, estoy seguro que mas del 90% del software que pone esto, no lo es, y por una sencilla razón, existen ciertos "criterios" que Microsoft exige para certficiar una aplicación como Windows compatible, una cosa es que el programa diga que es compatible con Windows y otra muy muy muy distinta es que el Microsoft le haya extendido un certificado de compatibilidad.

Bueno, de esto trata este libro, explica lo que Microsoft te pediría en un momento dado, cuando que quisieses obtener un certificado de Compatible con Microsoft Windows.



  • ¿ Sabias por ejemplo que no debes combinar fonts de colores y de distintos tamaños dentro de una misma caja de dialogo ?,
  • ¿ Sabes que distancia en pixeles debe existir entre los botones, los gets y los says ?
  • ¿ Sabes que es un twip ?
  • ¿ Sabes porqué deben de existir siempre el botón de Aceptar y el botón de cancelar en todas las ventanas?
  • ¿ Sabías que todo lo que puedes hacer con el ratón se debe de poder hacer con el teclado unicamente ?
Estos, entre otros temas son los tratados en este libro que te ayudará a crear interfaces bien diseñadas y coherentes, tanto visual como funcionalmente.

Basados en este libro se rediseñaron las pantallas de los sistemas Sanroms, y para mejor apariencia XP, se incluyó el archivo THEMED.MANIFEST en el archivo de recursos para que el programa tomara el tema que tuviera en un momento dado el Windows XP, esta modificación no afecta si el programa se ejecuta en Windows 98:

Esta es una pantalla de la interfaz a 16 bits:



Esta es la misma pantalla a 32 bits, con los temas de Windows XP:



Se implementaron los Folders nativos del sistema (SysTabControl32), los meters, date pickers, etc:

Esta es una pantalla de los meters de 16 bits:


Y ahora así es como se ve a 32 bits:




Por otro lado, para hacernos sentir mas XP, se adquirió una licencia de Canal Five TaskBar, los Taskbar son paneles de exploración tipo explorer de Windows, que son ampliamente utilizados por XP. Como la interfaz de Sanroms está totalmente basada en Catálogos, decidimos que sería buena idea separar la barra de herramientas del sistema en general de la barra de herramientas utilizada por los catálogos, el resultado fue simplemente espectacular:

Este es el catálogo de alumnos en la interfaz de 16 bits, nota como existen 2 barras de botones, una para el sistema en general y otra para manipular directamente las funciones del catálogo:



Y ahora, la espectaular interfaz de 32 bits, esta aplicación tiene ahora iconografía de Windows XP, y la segunda barra de botones se ha sustituido por un VTaskBar de Canal Five, con paneles que se extienden y se comprimen según las opciones que se van necesitando, al gusto del usuario.


El sistema de gráficas estadísticas del sistema también cambió, anteriormente se trabajaba con la librería ChartFX en su modalidad control VBX, y esto funcionaba bien a 16 bits:


Sin embargo a 32 bits no funcionan los controles VBX de 26 por lo que se decidimos contactar con Vikthor Tomás (http://www.listoelpollo.blogspot.com) adquirir una copia de su clase ChartFX32 y obviamente también tuvimos que utilizar la versión completa de ChartFX de 32 bits (www.softwarefx.com), que es un control OCX, con ayuda de Vikthor, fue cuestión de días tener todas las gráficas funcionando de una buena vez ahora a 32 bits:



Integrando con Office:

No es necesario saber que todos los programas deben de tener un modulo de exportación a los productos de la suite Office de Microsoft.

Los productos de Sanroms exportan los datos a archivos XLS, directamente utilizando la clase FileXLS de Ramón Avendaño, pero también se necesitaban las capacidades de "combinar correspondencia", mediante la cual los usuarios pueden crear "plantillas" de documentos en Word, para despuués crear documentos personalizados.

Nuevamente con la ayuda de Vikthor se creó un módulo que, utilizando el OLE nativo de xHarbour, crea estos documentos personalizados a partir de una plantila e imprimiendolos dirctamente desde Word.


Integración con Internet:

En las versiones de 16 bits, la integración para internet solo consistía en poder enviar correos electrónicos utilizando la clase TSMPT de Luis Krause:



Para la versión de 32 bits, se decidió dejar que Funcky se hiciera cargo de esta tarea, porque además de ceñirse estrictamente al protocolo SMTP, permite también verificar que una cuenta de correo exista en un dominio, maneja servidores con autenticación y además puede enviar archivos anexos de cualquier tamaño y tipo, esta es la nueva pantalla del módulo de correo electrónico:



Finalmente... se modificó el modulo web para que fuera compatible con todos los cambios que se realizaron en el software:

http://www.sanroms.com/productos_modulo_web_calificaciones.html

http://www.sanroms.com/productos_modulo_web_edocta.html


            Al dia de hoy, todos los cambios están hechos, las primeras versiones ya se han comenzado a distribuir, y ahora solo esperamos que comiencen los reportes bugs para comenzar de nuevo el ciclo y claro, prepararnos para lo que venga.