Un poco de contexto

En mi trabajo se ofrece un punto de venta a tiendas pequeñas como incentivo para que adquieran los productos que ofrece mi empresa empleadora. Seguramente se estarán preguntando “Pero… ¿porqué usan SQLite para un punto de venta?”, la razón es que esta aplicación no se contempló como un sistema demasiado robusto, más bien buscaba cubrir una necesidad común de forma que fuera llamativo el consumir los productos que ofrece la empresa en la que trabajo.

Pero ya que este punto de venta se convirtió en un medio para hacer llegar anuncios o comunicados directamente a los clientes llegó al punto en que muy de ves en cuando la base de datos se bloqueaba, debido a que SQLite tiene la limitante de que solo soporta una conexión escribiendo en la base de datos. Además de que una de las nuevas funcionalidades que se requería agregar al punto de venta era que soportara múltiples usuarios, por lo que necesitábamos un nuevo motor de base de datos que soportara concurrencia.

Pero además ya existía una base de usuarios algo considerable, por lo que tener el soporte que implicaría cambiarlos a firebird podría requerir de mucho tiempo, así que tampoco era viable migrar a todos los usuarios a firebird, ya que la funcionalidad de múltiples usuarios de momento solo la usaría uno de nuestros clientes. Así que se necesitaba que el punto de venta trabajara con ambas bases de datos (pero solo una a la ves).

¿Porque Firebird 3?

Como dije antes, este punto de venta en realidad no era tan robusto, por lo que tener que agregar el instalador de MySQL que ocupa ~300MB no lo hacia el favorito.

Instalador de MySQL
Instalador de MySQL

Así que recordé que hay un punto de venta bastante grande y popular que utiliza Firebird… Microsip, así que revisé y Firebird tiene un tamaño bastante reducido de 12MB y así que se convirtió en la primera opción.

Instalador de Firebird
Instalador de Firebird

Descripción del Problema

Al revisar la clase que se encargaba de la persistencia de datos me topé con una clase de más de 6,500 lineas de código y al rededor de 140 funciones. Entonces analizando, la primera opción y la más “simple” seria copiar esta clase, cambiarle el nombre y comenzar a cambiar las consultas SQLite por consultas de Firebird.

POSDatabaseManager (Ejemplo)
POSDatabaseManager (Ejemplo)

Pero considerando que migrar de motor de base de datos no es algo que se deba tomar a la ligera (menos si tienes mas de 6,500 lineas de código y 140 funciones consultando datos). Decidí que además de crear una clase nueva con las consultas a Firebase, tenia que buscar la forma de que me fuera fácil cambiar de SQLite a Firebird.

Así que resumiendo, el problema al que nos enfrentamos a groso modo seria:

Implementar un mecanismo que nos permita que la aplicación pueda trabajar indistintamente tanto con SQLite como con Firebird.

¡Manos a la Obra!

Lo primero que vamos a hacer cambiar el nombre a la clase POSDatabaseManager a SQLiteDatabaseManager.

SQLiteDatabaseManager
SQLiteDatabaseManager

Luego crearemos una interfaz llamada IDatabaseManager que implementará SQLiteDatabaseManager y copiamos las firmas de las funciones de SQLiteManager a la interfaz. Quedando de la siguiente manera:

Implementando IDatabaseManager para SQLite
Implementando IDatabaseManager para SQLite

Bien ahora, lo que hay que hacer es cambiar todas las referencias de SQLiteManager en la aplicacion por referencias a IDatabaseManager, compilamos y no debería existir ningún error.

Todo esto no altera el funcionamiento de la aplicación y además ya tenemos todo preparado para comenzar la migración a Firebird. ¿Como lo haremos? pues fácil, crearemos la clase FirebirdDatabaseManager que también implementará la interfaz IDatabaseManager.

Implementando FirebirdDatabaseManager
Implementando FirebirdDatabaseManager

Ahora, solo resta implementar todas las funciones en la clase FirebirdDatabaseManager con sus respectivas consultas SQL para Firebird.

Bien, ahora, ¿como cambiamos de SQLite a Firebird o viceversa?, ¡Facil!, sería de la siguiente manera:

Con esto ya hemos terminado, ahora solo debemos recordar que cuando vayamos a usar el acceso a la base de datos SIEMPRE debemos utilizar referencias de la interfaz IDatabaseManager, de este modo a la aplicación le será indiferente si esta usando SQLite o Firebird.

Si se necesitara agregar alguna función nueva que acceda a la base de datos se debe declarar en IDatabaseManager de esta panera nos aseguramos de que se implemente tanto en SQLiteDatabaseManager como en FirebirdDatabaseManager.