De un tiempo a esta parte he hecho algunas modificaciones sobre alarife para poder formalizar todo lo posible el desarrollo de meorganizo.es y, de este modo, ganar en velocidad y productividad. Alarife es una pequeña librería de utilidades que creé para poder regenerar bases de datos automáticamente.
El “problema” que estaba teniendo con meorganizo.es es el que prácticamente todos tenemos a la hora de querer realizar pruebas en nuestro código:
Aparte se da otra circunstancia, y es que cuando libere una nueva versión de meorganizo.es y la ponga en producción prefiero haber probado 1000 veces los scripts de actualización del esquema de base de datos que sólo un par de ellas.
Para solucionar el problema de los tests de integración podría haber utilizado dbunit sobre hsqlbd, pero esto sólo me soluciona los problemas en un único escenario.
Lo que he hecho para solucionar los problemas de los 3 escenarios de golpe ha sido modificar alarife e integrarlo en mi desarrollo con grails. Las modificaciones de alarife en sí no son gran cosa:
He de decir que todo esto ha sido muy sencillo ya que desarrollé alarife usando TDD (desarrollo orientado a tests) y analizando estáticamente el código. De este modo he podido modificar un código que llevaba meses quieto de una manera muy rápida y, sobre todo, muy segura.
Pero esta entrada no va de alarife ni de meorganizo.es. En esta entrada quiero indicaros qué hay que hacer para integrar esta nueva versión de alarife en vuestros desarrollos con grails. Los pasos a seguir son los siguientes:
Podeis bajar la última versión de la librería pulsando aquí.

Para ello hay que editar el fichero BootStrap.groovy, que está en el directorio conf/, con un código similar al siguiente:
import com.raulexposito.alarife.DatabaseRegenerator
import com.raulexposito.alarife.enumeration.ApplicationMode
class BootStrap {
static final String DEVEL_FILE = "devel.properties"
static final String PRODUCTION_FILE = "production.properties"
def init = { servletContext ->
// IMPORTANTE: antes de generar el war de pre/producción hay que cambiar:
//
// 1) 'DEVEL_FILE' por 'PRODUCTION_FILE'
// 2) 'ApplicationMode.DEVELOPMENT' por 'ApplicationMode.PRODUCTION'
new DatabaseRegenerator(DEVEL_FILE, ApplicationMode.DEVELOPMENT)
}
def destroy = {
}
}
}
conf/Config.groovyEsto es opcional aunque recomendable
warn 'org.mortbay.log'
'com.raulexposito.alarife'
conf/DataSource.groovy.Estos datos de conexión son los que usaremos en los properties de alarife más adelante.

Crearemos los ficheros properties en src/java con los datos de conexión con las bases de datos. En este ejemplo he creado 3 puesto que usaré alarife para los 3 escenarios posibles:
A continuación muestro el contenido del properties de desarrollo (devel.properties), el cual tiene los datos del datasource que explicamos en el punto 4). Observad que el esquema es ‘azlo_devel’, que en mi caso es el esquema que uso para desarrollar:
# ---------------------------------------------------------------------------- #
# Configuration of the database connection #
# #
# IMPORTANT! the instance MUST be finished by '/' and be careful with the #
# lower and uppercase in 'schema', 'username' and 'password' #
# ---------------------------------------------------------------------------- #
instance = jdbc:mysql://localhost:3306/
driverClassName = com.mysql.jdbc.Driver
username = usuario
password = clave
schema = azlo_devel
# ---------------------------------------------------------------------------- #
# creation and destruction of the database once connected #
# #
# IMPORTANT! this commands are database dependant, so it MUST NOT BE hardcoded #
# IMPORTANT! the database name MUST BE uppercase (for instance: MYSQL) #
# ---------------------------------------------------------------------------- #
# MySQL
MYSQL.dropDatabase = drop database if exists `{0}`;
MYSQL.createDatabase = create database if not exists `{0}`;
MYSQL.changeDatabase = use `{0}`;
MYSQL.createVersionTable = create table `{0}`.`VERSION` (`version` VARCHAR(10) NOT NULL);
MYSQL.insertVersionTable = insert into `{0}`.`VERSION` (`version`) values ('{1}');
MYSQL.recoverVersionTable = select `version` FROM `{0}`.`VERSION`;
Hay que crearlos en src/java/scripts/mysql/ para cada escenario y versión. Por ejemplo, el fichero src/java/scripts/mysql/development/0.0.1/upgradeTables-0.0.1.sql actualiza el esquema a la versión 0.0.1 en desarrollo y tiene el siguiente código:
DROP TABLE IF EXISTS `task`; CREATE TABLE `task` ( `id` bigint(20) NOT NULL auto_increment, `version` bigint(20) NOT NULL, `name` varchar(255) NOT NULL, `state` varchar(255) NOT NULL, `tags` varchar(255) default NULL, `user_id` bigint(20) default NULL, PRIMARY KEY (`id`), KEY `FK363585F7634DFA` (`user_id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Y el fichero src/java/scripts/mysql/development/0.0.1/insertData-0.0.1.sql el siguiente:
INSERT INTO `task` VALUES (1,0,'sacar la basura','NEXT','basura',1), (2,0,'ir de compras','NEXT','compras',1); UPDATE `VERSION` SET version = '0.0.1';
Es importante destacar que al final de este script se almacena la versión del script que hemos lanzado en la tabla VERSION. Es decir, si hemos lanzado los scripts de la versión 1.2.3, almacenaremos en el campo version de la tabla VERSION el valor 1.2.3.
Si quisiéramos usarlo con nuestros tests de integración deberiamos implementar el método setUp() tal como sigue:
private static final String TESTING_FILE = "testing.properties";
void setUp () {
new DatabaseRegenerator(TESTING_FILE, ApplicationMode.TESTING)
}
Todo esto como ya digo es para formalizar y con ello acelerar vuestros desarrollos. A mi personalmente me resulta muy útil pero está claro que cada uno tiene sus manías y su manera de hacer las cosas.
Si tenéis alguna duda o alguna idea que darme por favor no dudéis en usar los comentarios.
2 respuestas a Cómo integrar alarife con grails
Miguel Ángel Grau
5 de Agosto de 2010 a las 19:19
Hola Raúl,
encuentro tu librería muy interesante y útil, pero no consigo integrarla con Grails siguiendo tus indicaciones. Después de crear manualmente la tabla versión, y poner el valor de versión a 0.0.0 en la tabla, consigo que intente ejecutar los scripts para la versión 0.0.1
El problema viene cuando intenta ejecutar la actualización de la tabla versión a 0.0.1, ya que, después de ejecutar el comando UPDATE VERSION SET version=’0.0.1′, y estar dentro de una transacción (imagino que abierta por Grails), cuando obtiene el valor de la tabla para actualizar la variable currentVersion, vuelve a obtener el valor 0.0.0, así que vuelve a ejecutar los scripts de la versión 0.0.1 y así se queda en un bucle infinito.
¿Podrías ayudarme?
Un saludo
Miguel Ángel
Raúl Expósito
5 de Agosto de 2010 a las 21:19
Muy buenas Miguel Ángel,
Mira, me emocionan tanto tu comentario como el saber que hay alguien que quiere usar algo que he creado
En cuanto pueda te mando un correo y lo vemos más despacio ¿va?. Seguramente me haya explicado mal en algún punto y por eso no te funcione.
Saludos