Firebird 3: software de 32 bits y de 64 bits

8 comentarios

Si nuestro Servidor es Firebird 3, debemos recordar lo siguiente:

  1. Si la aplicación que deseamos ejecutar fue compilada en 32 bits (nuestra propia aplicación, IBExpert, FlameRobin, etc.) entonces se requiere el archivo FBCLIENT.DLL de 32 bits, aún cuando el Servidor del Firebird 3 sea de 64 bits. Si es nuestra aplicación la que fue compilada en 32 bits entonces lo aconsejable es que el archivo FBCLIENT.DLL de 32 bits se encuentre en la misma carpeta en la cual se encuentra nuestro .EXE, así evitamos confusiones con otros archivos FBCLIENT.DLL que pudieran encontrarse en la misma computadora.
  2. Un Servidor Firebird 3 de 64 bits puede aceptar conexiones de un FBCLIENT.DLL de 32 bits o de 64 bits, indistintamente. Un Servidor Firebird 3 de 32 bits solamente puede aceptar conexiones de un FBCLIENT.DLL de 32 bits.
  3. La ODS (On Disk Structure) de una Base de Datos creada con Firebird 3 es exactamente la misma, sea que esa Base de Datos haya sido creada con la versión de 32 bits o con la versión de 64 bits.
  4. No se debe permitir la conexión a una Base de Datos con el Servidor de 32 bits y con el Servidor de 64 bits al mismo tiempo. O con el uno, o con el otro, pero no con ambos a la vez porque eso corromperá a la Base de Datos.

Artículos relacionados:

¿Qué es la versión de ODS?

Firebird 3: usando bases de datos anteriores

El índice del blog Firebird21

El foro del blog Firebird21

 

 

 

Solamente llamar a vistas y a stored procedures

4 comentarios

Una característica que siempre se ve en el código fuente de las aplicaciones bien escritas es que solamente llaman a vistas y a stored procedures.

Y a fuer de ser sinceros, tales aplicaciones son escasas, muy escasas.

Muchos programadores escriben en el código fuente de sus aplicaciones los comandos INSERT, UPDATE, DELETE, y SELECT a columnas de tablas.

Y eso está mal, muy mal.

¿Por qué?

Bueno, hay varios motivos. El autor de este blog varias veces ha evaluado aplicaciones y códigos fuentes escritos por otras personas y al finalizar la evaluación ha elevado un informe detallando lo bueno y lo malo que encontró. Y en el capítulo “Comunicación con la Base de Datos” estos son algunos problemas:

  1. El código fuente es desprolijo. Si alguien escribe los comandos mencionados más arriba en general lo hace de forma desordenada, calculando valores de variables, o realizando otras tareas no relacionadas, y eso además de no ser eficiente queda “feo”.
  2. No permite el trabajo en equipo. Cuando se trabaja en equipo lo ideal es modularizar al máximo para que cada función o cada rutina sea escrita una sola vez y utilizada por muchos programadores. De esa manera si hay algún error solamente puede estar en un lugar y será fácil encontrarlo y corregirlo. Pero si cada quien escribe los comandos en su propio código fuente entonces los errores pueden estar en muchos lugares y encontrarlos y corregirlos demorará mucho más tiempo. Y cualquier cambio a cualquiera de los códigos fuente puede introducir un nuevo error. Y esto inclusive puede ocurrir aunque se trate de un solo programador pero que tiene por ejemplo el INSERT a una sola tabla en dos o más programas.
  3. No hay un responsable de la Base de Datos. Cuando se trabaja en equipo una persona debe ser la encargada de verificar el correcto diseño y funcionamiento de la Base de Datos. Si cada programador escribe lo que se le ocurre en su propio código fuente, tales verificaciones serán imposibles de realizar y los errores posibles, muchísimos.
  4. No se puede verificar que el comando finalizará sin error hasta el momento de ser ejecutado. Por ejemplo, mirando un INSERT en el código fuente no se puede tener la seguridad de que esa fila será insertada o que ocurrirá una excepción de “table unknown”, “column unknown” o alguna otra.
  5. No se puede comprobar la eficiencia del comando. Este es el punto más importante. Los programas de administración gráfica, como el EMS SQL Manager, nos muestran la cantidad de filas leídas, la cantidad de filas extraídas, y en forma gráfica los índices usados. También podemos ver el PLAN utilizado. Así es fácil descubrir que no se está usando un índice cuando sí debería usarse, o que las filas leídas son demasiadas, o que se está usando el índice incorrecto, etc. Y es muy fácil y muy rápido cambiar la vista o el stored procedure con la intención de hacerlo más eficiente. Sin embargo, si escribimos los comandos dentro del código fuente de una aplicación es imposible saber si es eficiente o no lo es. Podemos “creer” que es eficiente y que usa los índices correctos, cuando en realidad no es así. Y hay además otro problema: aunque hoy una vista o un stored procedure sean muy eficientes, podrían dejar de serlo dentro de unos meses cuando las tablas tengan más filas o se hayan cambiado o borrado algunas filas. Escribiendo los comandos INSERT, UPDATE, DELETE, y SELECT a columnas de tablas dentro del código fuente de nuestras aplicaciones jamás podremos estar seguros de que son los más eficientes que podemos tener, en cambio si dichos comandos están dentro de una vista o dentro de un stored procedure sí que podremos tener esa seguridad.

VISTAS-STORED-1

Captura 1. Si haces clic en la imagen la verás más grande

VISTAS-STORED-2

Captura 2. Si haces clic en la imagen la verás más grande

Mirando la Captura 1. sabemos que la vista involucra a 3 tablas y que las 3 tablas usan índices (e inclusive sabemos los nombres de esos índices), y que la cantidad de filas parece estar correcta, sin embargo … ese SORT en la Captura 2. nos llama poderosamente la atención porque los SORT son muy lentos, ya que deben ordenar las filas de las tablas; ese ordenamiento se realiza en la memoria del Servidor (cuando tal cosa es posible) o en el disco duro (cuando no puede ordenarse en la memoria). En general, debemos evitar a los SORT como a la peste, porque indican que la tabla, la vista, el stored procedure seleccionable, o los resultados deberán ser ordenados, y eso puede demorar muchísimo tiempo en tablas grandes.

Si en lugar de escribir una vista, como en el ejemplo de arriba, hubiéramos escrito un SELECT en el código fuente de nuestro lenguaje de programación, ¡¡¡jamás nos habríamos percatado de ese SORT malévolo!!!. Y claro, cuando las tablas tuvieran muchas filas los usuarios se quejarían de la lentitud, pero mientras tanto les hicimos perder mucho tiempo innecesariamente porque nuestra consulta no estaba optimizada.

Conclusión:

Si quieres programar correctamente y eficientemente y profesionalmente, en el código fuente de tus aplicaciones solamente debes llamar a vistas y a stored procedures. Nunca, jamás, y por ningún motivo, ejecutar un INSERT, un UPDATE, un DELETE, o un SELECT a columnas de una tabla.

Los SELECT solamente a vistas.

Los INSERT, UPDATE, DELETE, y algunos SELECT, solamente dentro de un stored procedure.

Cuando se programan aplicaciones siempre se van encontrando errores y problemas aquí y allá. Para disminuir esa cantidad de errores y de problemas, y para optimizar las consultas y los procesamientos, siempre lo mejor es desde el código fuente de nuestras aplicaciones llamar a vistas y a stored procedures, y a nada más.

Artículos relacionados:

Optimizando las consultas

Optimizando las subconsultas

Optimizando los JOIN

Evitando que el optimizador … optimice

¿Por qué usar stored procedures?

Usando un stored procedure como una función

Escribiendo un stored procedure

Usando un PLAN

Algo más sobre PLAN

Entendiendo el contenido de un PLAN

El índice del blog Firebird21

El foro del blog Firebird21

Backups locales y backups remotos

Deja un comentario

El programa GBAK nos permite realizar backups locales y backups remotos.

  • En un backup local, la Base de Datos que está en el Servidor copiamos a nuestro disco duro local
  • En un backup remoto, la Base de Datos que está en el Servidor copiamos en el Servidor

NOTA: En todos los ejemplos de abajo el comando se ve en 3 líneas para que sea más fácil visualizarlo, pero debe escribirse en 1 sola línea.

Caso 1. Backup local

Ejemplo 1. El backup lo realiza el usuario SYSDBA o el creador de la Base de Datos

GBAK -backup -user NombreUsuario -password Contraseña 
\\SERVIDOR-PC\C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Ejemplo 2. El backup lo realiza un usuario que tiene el rol RDB$ADMIN

GBAK -backup -user NombreUsuario -password Contraseña -role RDB$ADMIN
\\SERVIDOR-PC\C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Ejemplo 3. El backup se hace mediante conexión por TCP/IP

GBAK -backup -user NombreUsuario -password Contraseña 
192.168.1.1:C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Si el usuario que quiere realizar el backup no es SYSDBA ni el creador de la Base de Datos entonces sí o sí debe tener el rol RDB$ADMIN y además deberá especificarlo para que el backup pueda realizarse con éxito.

La Base de Datos que se encuentra en la computadora cuyo nombre es SERVIDOR-PC o cuya dirección IP es 192.168.1.1 será copiada al disco duro local del usuario. Desde luego que estos son ejemplos, en tu caso tanto el nombre de la computadora o la dirección IP pueden ser distintos. El programa GBAK puede encontrarse en el disco duro local o en cualquier otra computadora. Si se encuentra en otra computadora debe estar en una carpeta compartida o no se lo podrá ejecutar.

Caso 2. Backup remoto

Ejemplo 4. Un backup remoto usando el nombre de la computadora

GBAK -backup -service \\SERVIDOR-PC\service_mgr -user NombreUsuario -password Contraseña 
C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Ejemplo 5. Un backup remoto usando la dirección IP de la computadora

GBAK -backup -service 192.168.1.1:service_mgr -user NombreUsuario -password Contraseña 
C:\SISTEMAS\BASESDATOS\MiBaseDatos.FDB 
C:\SISTEMAS\BACKUPS\MiBackup.FBK

Para que el backup remoto pueda realizarse se debe llamar al administrador de servicios o service manager de una computadora que tenga instalado al Servidor del Firebird.

Cuando se usa el service manager el backup termina más rápido, eso significa que los backups remotos son más rápidos que los backups locales.

Comentarios:

  1. El programa GBAK debe poder acceder a la Base de Datos. Para ello se puede usar la ubicación de la Base de Datos  (como en los ejemplos anteriores) o un alias que se haya especificado en el archivo ALIASES.CONF (que es lo recomendable)
  2. Como el programa GBAK copiará todo el contenido de la Base de Datos entonces solamente podrá finalizar con éxito si es ejecutado por el usuario SYSDBA, por el creador de la Base de Datos, o por un usuario que se conecte con el rol RDB$ADMIN. Eso es muy lógico, si un usuario tiene acceso restringido a una Base de Datos no se le puede permitir copiar todo el contenido de ella.
  3. La conexión a la Base de Datos puede realizarse mediante named-pipes (o sea, especificando el nombre de la computadora, como en el Ejemplo 1.) o mediante su dirección IP (como en el Ejemplo 3.)
  4. Si se quiere realizar un backup remoto entonces hay que usar la opción -service. Esta opción puede recibir un solo parámetro, el cual se llama service_mgr. El service_mgr solamente existe en las computadoras que tienen al Servidor del Firebird instalado. Por ese motivo, si la computadora desde donde se realiza el backup no tiene instalado al Servidor del Firebird hay que llamarlo al service_mgr desde una computadora que sí lo tenga instalado. Se lo puede llamar usando el nombre de la computadora (como en el Ejemplo 4.) o la dirección IP de la computadora (como en el Ejemplo 5.). Desde luego que si la computadora desde donde se ejecuta al programa GBAK tiene instalado al Servidor del Firebird entonces no será necesario escribir esos prefijos.
  5. Cuando se hace un backup remoto, la carpeta en donde se copiará el backup debe estar compartida. El programa GBAK es un programa más, para el Sistema Operativo no tiene algo de especial, es uno más del montón. Por lo tanto, para que pueda copiar el backup en una carpeta debe tener derecho de escritura en esa carpeta. Si la carpeta está en otra computadora, entonces debe estar compartida, sí o sí.
  6. Cuando se quiere realizar un backup hay que diferenciar dos cosas: 1) El programa GBAK debe poder conectarse a la Base de Datos, como si se tratara de un usuario humano más. Es por eso que debe especificarse el usuario, la contraseña, y quizás el rol. 2) El programa GBAK debe poder crear un archivo en una carpeta de un disco duro. Es por eso que debe tener permiso de escritura en esa carpeta.
  7. Cuando se realiza un backup remoto, hay que ver a la carpeta destino desde el punto de vista del Servidor. En los ejemplos 4. y 5. la carpeta C:\SISTEMAS\BACKUPS\ es una carpeta que se encuentra en la misma computadora donde se encuentra el Servidor. No es una carpeta local, es una carpeta remota, y se la ve como local, pero es local para el Servidor.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Usando Servidor y embedded en la misma aplicación (2)

Deja un comentario

En un artículo anterior ya habíamos visto las ventajas de usar Servidor y embedded en la misma aplicación. Ahora veremos otro caso donde tal aprovechamiento puede resultar muy útil.

Escenario:

En un supermercado grande hay 40 cajas, de las cuales por lo menos 15 están constantemente trabajando. Normalmente esas cajas están conectadas a una Base de Datos mediante Cliente/Servidor y si todo funciona bien entonces es lo correcto porque todas las operaciones se realizan con rapidez.

Cada vez que se realiza una venta, se registran los datos de esa venta en una de las cajas y se insertan filas a las tablas respectivas de la Base de Datos. Todo bien hasta allí.

Sin embargo, ¿qué sucedería si por alguna razón se interrumpe la conexión de una (o varias, o todas) caja/s con el Servidor?

Escribir con papel y lápiz los datos de las ventas porque la conexión con el Servidor se cortó no es una opción en un supermercado que tiene mucha clientela.

¿Y entonces, qué hacemos?

Solución:

La solución es que si la aplicación detecta que se ha interrumpido la conexión con el Servidor entonces guarde los datos de las siguientes ventas en una Base de Datos local a la cual se conectará mediante embedded.

Así, ninguna venta se perderá, las cajas seguirán trabajando normalmente, y al final del turno, al final del día, o cuando se restablezca la conexión, los datos de las ventas que se habían insertado en la Base de Datos local serán transferidos a la Base de Datos remota.

Conclusión:

Que se corte la conexión entre una computadora y la Base de Datos que se encuentra en el Servidor no es frecuente pero puede ocurrir. Nuestra aplicación debe ser lo suficientemente inteligente como para prever esa posibilidad y actuar en consecuencia, de tal manera que esa interrupción de la conexión no cause trastornos a los usuarios.

La gran mayoría de los usuarios quizás ni se entere de que en cierto momento se interrumpió la conexión de su computadora con el Servidor porque siguieron trabajando normalmente, como si tal interrupción nunca hubiera ocurrido. Para ellos, todo fue normal.

Sin embargo, nuestra aplicación sí detectó que se interrumpió la conexión y entonces en la computadora de ese usuario automáticamente empezó a utilizar una Base de Datos alternativa, o auxiliar.

Cuando la conexión se restableció, o al final del turno del cajero, o al final del día, o cuando se decidió, todo lo que estaba en la Base de Datos alternativa se copió a la Base de Datos normal, la que se encuentra en el Servidor.

De esta manera, ninguna venta se perdió, y tampoco ningún dato se perdió.

Artículos relacionados:

Usando Servidor y embedded en la misma aplicación

El índice del blog Firebird21

El foro del blog Firebird21

¿Es seguro usar Servidor y embedded al mismo tiempo?

Deja un comentario

Sí, … pero con algunas condiciones.

En ocasiones podrías querer conectarte usando Servidor (es decir: Classic, SuperClassic, o SuperServer) a una Base de Datos y en ocasiones podrías querer conectarte usando embedded. Entonces … ¿puedes hacer algo así?

Sí, pero no puedes realizar la conexión al mismo tiempo.

Veamos:

  1. Conectarse a la Base de Datos A con Servidor y a la Base de Datos A con embedded. NO PERMITIDO
  2. Conectarse a la Base de Datos A con embedded y a la Base de Datos A con Servidor. NO PERMITIDO
  3. Conectarse a la Base de Datos A con Servidor y a la Base de Datos B con embedded. PERMITIDO
  4. Conectarse a la Base de Datos A con embedded y a la Base de Datos A con embedded. NO PERMITIDO

La diferencia entre el caso 1. y el caso 2. está en quien se conectó primero a la Base de Datos A, pero sin importar quien lo haya hecho, la segunda conexión no es permitida.

Como habrás notado al mirar los casos anteriores, si te conectas por embedded, lo haces de forma exclusiva. Ninguna otra conexión a esa misma Base de Datos es permitida.

Resumiendo:

Se puede conectar usando Servidor y usando embedded en la misma computadora, pero la condición es que se haga a bases de datos distintas.

Artículos relacionados:

El índice del blog Firebird21

El foro del blog Firebird21

Acelerando los SORT

1 comentario

Ya sabemos que en ocasiones el Firebird necesita ordenar las filas creando archivos temporales, a esa operación se la llama SORT (ordenar, en inglés) y puede ser lenta en tablas grandes. Entonces ¿qué podemos hacer para acelerar los SORT?

  1. Pedirle que los realice en un disco rápido
  2. Pedirle que los realice en un disco RAM
  3. Asegurándonos que el espacio libre en el disco temporario sea más grande que la Base de Datos
  4. Creando los archivos temporales en un disco distinto al de la Base de Datos

Los discos tienen distintas velocidades de lectura/escritura (y distintos precios también, claro). Los más rápidos suelen ser los SSD (Solid State Disk), aunque el problema es que son más caros que los discos duros magnéticos y también tienen una menor vida útil (aunque esto último está cambiando mucho, ya que cada vez duran más tiempo).

Como los SORT requieren crear archivos temporales, y muchos de esos archivos temporales pueden llegar a ser inmensos entonces debemos buscar por todos los medios acelerar el proceso.

Usar un disco RAM es una muy buena alternativa, aunque por supuesto eso requiere que la computadora tenga mucha memoria disponible. Para saber como crear un disco RAM y que programa usar para ello, puedes leer este artículo:

Usando un disco RAM para aumentar la velocidad

 ¿Y cuánto espacio libre debe tener el disco dónde se realizarán los SORT?

Evidentemente, cuanto más, mejor. Como no podemos saber de antemano cuanto será el espacio libre que necesitará el Firebird en general se toma como parámetro el tamaño de la Base de Datos. Es casi seguro que siempre necesitará menos que eso.

Entonces, si nuestra Base de Datos tiene un tamaño de 2 Gb, con tener 2 Gb en el disco donde se crearán los archivos temporales será suficiente. Pero no olvides que las bases de datos siempre crecen entonces hay que prever más, en ese caso un disco (duro o RAM) con 4 Gb sería muy bueno.

¿Y cómo se especifica dónde se crearán los archivos temporales?

En la carpeta donde instalaste el Firebird encontrarás un archivo cuyo nombre es FIREBIRD.CONF, dentro de ese archivo hay una entrada llamada “TempDirectories”. Debes borrar el símbolo de numeral que está a la izquierda y escribir los nombres de las carpetas donde se crearán los archivos temporales. Si usarás más de una carpeta deberás separarlas con punto y coma, por ejemplo:

TempDirectories=G:\TEMP
TempDirectories=G:\TEMP;F:\FIREBIRDTEMPS

¿Qué significan esas entradas?

La primera, que todos los archivos temporales se crearán en la carpeta G:\TEMP

La segunda, que los archivos temporales se crearán en G:\TEMP y que si alguna vez no hay espacio suficiente entonces se los continuará creando en F:\FIREBIRDTEMPS

Es decir, la segunda carpeta solamente se usa si la primera carpeta se quedó sin espacio.

¿Cómo se deben especificar los nombres de las carpetas en TempDirectories?

Como el Firebird primero usará la primera carpeta, y si se queda sin espacio allí usará la segunda carpeta, entonces en primer lugar deberías escribir el nombre de la carpeta que se encuentra en el disco más rápido. Si tienes un disco RAM entonces esa primera carpeta evidentemente será la del disco RAM.

En el ejemplo de arriba si el disco G: es un disco RAM y el disco F: es un disco SSD, entonces estará perfecto, porque primero especificamos el disco más rápido.

Desde luego que puedes tener más de dos carpetas, aunque en este ejemplo se mostraron 2 carpetas tú podrías tener 3, 4, 5, las que necesites. Solamente recuerda que siempre los discos más rápidos deben ser escritos primero.

¿Por qué los discos donde se encuentran las bases de datos y los archivos temporales debe ser distinto?

Si una sola persona está usando la Base de Datos, no hay problema, porque o está creando archivos temporales o no los está creando. En ambos casos estará trabajando a la máxima velocidad posible. Pero lo normal es que a una Base de Datos estén conectadas varias personas al mismo tiempo, cada una de ellas realizando alguna operación y ahí sí el tema se complica y mucho.

¿Por qué se complica?

Tenemos dos posibilidades:

  1. Están en un disco duro magnético
  2. Están en un disco no magnético (por ejemplo, un disco SSD)

Si están en un disco duro magnético, entonces hay un cabezal que debe moverse. Ese es un movimiento mecánico y por lo tanto siempre será lento. Si un usuario hace un SORT el cabezal debe moverse a un sector del disco duro. Otro usuario hace un INSERT, el cabezal debe moverse a otro sector del disco duro. Otro usuario hace un INSERT a otra tabla y nuevamente el cabezal debe moverse. Si los usuarios están ejecutando las operaciones de INSERT, UPDATE, DELETE, SELECT, FETCH, entonces los sectores estarán contiguos o muy cerca unos de otros, porque todos ocurren dentro de la misma Base de Datos. Pero si un usuario está haciendo un SORT esos sectores estarán muy alejados de la Base de Datos y ese constante ir y venir del cabezal hará que tanto las operaciones en la Base de Datos como el SORT sean mucho más lentos de lo que deberían. Si has leído algo sobre el diseño de Sistemas Operativos recordarás que usan semáforos: le dan unos milisegundos a un proceso para que haga lo que quiere hacer, luego otros milisegundos a un segundo proceso, luego otros milisegundos a un tercer proceso, y así sucesivamente hasta regresar al primer proceso. Para los usuarios esto es transparente, creen que cada uno de sus procesos se está ejecutando simultáneamente con los demás procesos pero eso no es así (bueno, salvo que la computadora tenga varios procesadores, claro). De todas maneras, sea la computadora multi-procesador o no, el cabezal del disco duro tendrá un constante ir y venir entre los sectores usados en el SORT y los sectores usados para las otras operaciones. Eso es lento y siempre será lento, podrá aumentarse la velocidad con discos duros más veloces, pero siempre será lento.

Si están en un disco no magnético (por ejemplo, un disco SSD), entonces no hay un cabezal que se mueve, en realidad nada se mueve, pero los discos tienen una vida útil limitada que aunque va aumentando porque la tecnología mejora, siempre tiene un límite. Entonces, si además de realizar las operaciones normales (INSERT, UPDATE, DELETE, SELECT, FETCH) también le pedimos que use a ese mismo disco SSD para los SORT, los backups y los restores, la vida útil de nuestro disco SSD será mucho más corta de lo que debería ser.

Por lo tanto la conclusión es muy sencilla: la Base de Datos debe encontrarse en un disco y los archivos temporales en un disco distinto.

Ese disco debe ser físicamente distinto, no sirve que esté particionado. Si está particionado se trata del mismo disco aunque para el Sistema Operativo sean dos discos diferentes, la realidad es que sigue siendo un mismo disco físico, y eso es justamente lo que no queremos.

Artículos relacionados:

Entendiendo el contenido de un PLAN

Usando un disco RAM para aumentar la velocidad

El índice del blog Firebird21

El foro del blog Firebird21

 

Bases de datos shareware (2)

Deja un comentario

En este artículo ya habíamos visto las ventajas de tener una Base de Datos shareware, las dos formas usuales de hacerla, y los trucos que los usuarios tramposos podrían intentar:

https://firebird21.wordpress.com/2014/01/23/bases-de-datos-shareware/

Ahora explicaremos mejor el funcionamiento de esas dos formas.

Protección por fecha

Se le permite al usuario usar la aplicación hasta que llegue una cierta fecha, después ya no podrá usarla. Por ejemplo si instaló la aplicación el 24 de enero de 2014 podrá usarla hasta el 24 de febrero de 2014. Si quiere usarla después, entonces tendrá que pagar.

Aquí lo que debemos impedir es que si le cambia la fecha a la computadora la aplicación siga funcionando. Por ejemplo, el día 25 de febrero el usuario no puede usar la aplicación, le cambia la fecha a su computadora y le coloca 1 de febrero de 2014. A pesar de haber cambiado la fecha no debería poder usar la aplicación. Debemos detectar ese cambio y actuar en consecuencia.

¿Cómo protegemos por fecha?

Guardamos en una tabla de nuestra Base de Datos o en un archivo externo a ella, tres valores: la fecha inicial, la fecha final, y la fecha última.

La fecha inicial es el primer día que puede usar la aplicación. Por ejemplo el 24 de enero de 2014

La fecha final es el último día que puede usar la aplicación. Por ejemplo el 24 de febrero de 2014

La fecha última, cuando se instala la aplicación es igual a la fecha inicial. Después, cada vez que se ejecuta la aplicación se verifica si la fecha del Servidor es igual o posterior a la fecha última. Si es así, se actualiza la fecha última.

Entonces, si el 25 de febrero el usuario ejecuta la aplicación el valor de fecha última será 25 de febrero. Si le cambia la fecha a su computadora y le pone 1 de febrero, fecha última seguirá siendo 25 de febrero, porque el valor de fecha última jamás puede retroceder. El nuevo valor de fecha última solamente puede ser igual o posterior al valor anterior de fecha última.

En nuestra rutina de validación verificamos:

  1. Que la fecha de la computadora sea mayor o igual que fecha inicial y que también sea menor o igual a fecha final
  2. Que la fecha última sea mayor o igual que fecha inicial y que también sea menor o igual a fecha final

Podemos mejorar el algoritmo si en vez de guardar solamente la fecha guardamos la fecha y la hora. Inclusive lo mejoraríamos aún más si nos aseguramos que cada vez que se ejecuta la aplicación el tiempo aumente por lo menos en 5 minutos.

Primera ejecución del sistema: 24 de enero de 2014, 16:12

Segunda ejecución del sistema, como mínimo debería ser el 24 de enero de 2014 a las 16:17, ó sea 5 minutos después que la ejecución anterior. Fíjate que no importa cuando el usuario realmente ejecutó la aplicación, lo que nos aseguramos es que siempre haya un incremento de por lo menos 5 minutos. Si la segunda ejecución fue el 24 de enero a las 16:50, en fecha última tendremos guardado 24 de enero y 16:50, pero si la segunda ejecución fue el 24 de enero a las 16:13 en fecha última tendremos guardado 24 de enero y 16:17 porque siempre incrementamos como mínimo 5 minutos.

Por supuesto que no es obligatorio sumarle 5 minutos, podrías sumarle 10 minutos, 30 minutos, 60 minutos, los que te parezcan. La idea es que siempre que se ejecuta la aplicación la fecha y hora se incrementen, que jamás puedan mantenerse igual o retroceder.

De esta manera, tarde o temprano, haga el usuario lo que haga, se sobrepasará la fecha última y la aplicación dejará de funcionar.

Protección por cantidad de ejecuciones

Esto es mucho más fácil de programar que la protección por fechas. Simplemente guardamos en una tabla de nuestra Base de Datos o en un archivo externo la cantidad de veces que el usuario ejecutó nuestra aplicación. Cada vez que la ejecuta incrementamos esa cantidad en 1.

Cuando instala la aplicación, el contador es 0. La primera vez que la ejecuta, el contador es 1. La segunda vez el contador es 2. Y así sucesivamente. Cuando se llegue a la cantidad predeterminada (por ejemplo: 25), la aplicación dejará de funcionar.

Usando ambas protecciones

Para que nuestra aplicación esté más protegida lo mejor es protegerla con ambos métodos: fecha y cantidad.

Siguiendo con nuestro ejemplo, la aplicación dejará de funcionar el 25 de febrero de 2014 ó cuando haya sido ejecutada 25 veces, lo que ocurra primero.

Encriptando los valores

Evidentemente ninguna protección será efectiva si el usuario puede ver y cambiar las fechas o las cantidades de ejecución. Esos valores deben encontrarse encriptados (es decir, ilegibles para quienes no conozcan la clave) y cuanto más ocultos, mejor.

Un lugar donde tradicionalmente se guardan esos valores es en el Registro del Windows. Muy pocos usuarios conocen el Registro del Windows, menos aún han entrado a curiosearlo y muchos menos aún se atreven a cambiar algo por su propia cuenta.

Otro lugar es en la propia Base de Datos. Si tienes una tabla de un solo registro donde guardas la configuración o algo similar entonces puedes aprovechar y agregarle una columna a esa tabla. En esa nueva columna guardas (convenientemente encriptadas, por supuesto) la fecha inicial, la fecha final, la fecha última y la cantidad de ejecuciones.

Recuperando los valores

Así como has guardado las fechas y la cantidad de ejecuciones encriptadas, debes poder desencriptarlas para realizar las verificaciones y determinar si la aplicación puede seguir usándose o no.

Esto puedes realizarlo en dos lugares:

  1. En tu aplicación. Es decir en el programa que escribiste con Visual FoxPro, Visual Basic, C, C++, Delphi, Java, etc.
  2. En un trigger de tu Base de Datos. El usuario debe tener solamente la versión compilada de ese trigger, no debe tener el código fuente o de nada te servirán las protecciones.

Lo ideal y lo correcto por lo tanto es que verifiques que tu aplicación puede ejecutarse, en ambos lugares: en tu aplicación y en un trigger. De esa manera aunque el usuario llegara a descubrir y evitar la protección que se encuentra en un lugar aún le faltaría descubrir y evitar la protección que se encuentra en el otro. Y si debe trabajar más para conseguirlo es más probable que desista de su intención. Y entonces la protección habrá cumplido su misión.

En el siguiente artículo ya veremos como implementar lo expuesto hasta acá.

Artículos relacionados:

Bases de datos shareware

El índice del blog Firebird21

Older Entries