vendredi 25 mai 2012

Versioner sa base avec LiquiBase

LiquiBase est un sytème de gestion de version permettant de gérer les changements à appliquer à une base de données. Il est écrit en Java et fonctionne avec des SGBDs hétérogènes tels qu'Oracle, MySQL et PostgreSQL.
Ce système propose un grand nombre de fonctions pour effectuer certains tâches comme supprimer une table, ajouter un index, une colonne, une contrainte ... Il est possible d'ajouter des tests et traitements en fonction des résultats obtenus, d'inclure des fichiers externes, d'ajouter des actions qui seront faites à chaque exécution etc...
Voici un exemple de fichier de changement qu'il est possible d'utiliser :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">

<changeSet id="1" author="steve" runAlways="true">
<preConditions onFail="HALT"
onFailMessage="You're trying to apply changes on database qal or prd !!">
<sqlCheck expectedResult="1"> SELECT substring(database(),11) NOT IN ('qal','prd')  </sqlCheck>
</preConditions>
</changeSet>
<changeSet id="2" author="cyril">
<comment>Whole bd1_data_tst database regenerated </comment>
<sql>SET sql_mode=''</sql>
<sqlFile path="schema/bd1-schema.tmp-fix-drop-tables.sql" />
<sqlFile path="schema/bd1_struct_v41.sql" />
<sqlFile path="schema/bd1_data_v41.sql" />
<sql>SELECT sleep(1)</sql>
<sqlFile path="schema/bd1-schema.v41-v42.sql" />
<sql>SELECT sleep(1)</sql>
<sqlFile path="schema/bd1-schema.v42-v43.sql" />
<sql>SELECT sleep(1)</sql>
<sqlFile path="schema/bd1-schema.v43-v44.sql" />
<sqlFile path="routinesTriggersEvents/pre-util.sql" />
<sqlFile path="routinesTriggersEvents/util-debug.sql"
splitStatements="false" />
<sqlFile path="routinesTriggersEvents/pre-companySearch.sql" />
<sqlFile path="routinesTriggersEvents/companyDictionarySearchWithSoundexInTempTable.sql"
splitStatements="false" />
<sqlFile path="routinesTriggersEvents/companyDictionarySoundexSearchWithWhereClause.sql"
splitStatements="false" />
<sqlFile path="routinesTriggersEvents/validatedCompanyDictionarySearchWithSoundex.sql"
splitStatements="false" />
<sqlFile path="routinesTriggersEvents/pre-triggers.sql" />
<sql>
DROP procedure IF EXISTS clean_all_tables_from_current_db;
</sql>
<sqlFile path="routinesTriggersEvents/clean-test-tables.sql"
splitStatements="false" />
<sql>
TRUNCATE tx10;
</sql>
</changeSet>

<include file="./bd1-changelog.xml"
relativeToChangelogFile="true" />

</databaseChangeLog>

Dans ce fichier de changement, on peut voir qu'il y a 2 changements à appliquer (changeSet id="X") dont un qui sera appliqué à chaque fois (runAlways="true") , et que le premier changement effectue un test qui sera fatal à l'application des changements suivants s'il échoue (onFail="HALT").
On remarque aussi que chaque changement est associé à un utilisateur bien défini (author="cyril"). En plus des deux changements présents dans le fichier, les changements inclus dans le fichier ./bd1-changeog.xml seront aussi appliqués, ce qui permet par exemple d'observer un certain découpage et de ne pas avoir un fichier de changement qui pèse plusieurs Mo.


Concernant l'utilisation, il existe un plugin Maven afin de pouvoir piloter le système. Il est aussi possible d'écrire une petite application en Java pour appliquer un fichier de changement ou utiliser une commande en ligne si vous ne disposez pas de Maven.

Aucun commentaire: