# Mécanique de migration
Lors d'une mise à jour d'un module, il est parfois nécessaire d'utiliser des scripts pour effectuer des opérations de migrations ou des traitements spécifiques.
# Enregistrement d'un script de migration
Le lancement de ces scripts de migration est commandé dans le fichier info.xml
du module par l'utilisation d'une
directive <process command="./programs/RunMigrationScript.php>"/>
dans la section <post-upgrade>
.
- Exemple de déclaration type pour le lancement de scripts de migration :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<module xmlns="https://platform.anakeen.com/4/schemas/app/1.0" name="mon-module" vendor="Anakeen" version="1.0.2">
<post-install>
[...]
</post-install>
<post-upgrade>
<process command="./programs/RunMigrationScript.php --file=./vendor/Anakeen/Hub/Migration/resetHubConfigurationField.xml">
<label>Apply Migrate HubGenericConfiguration Rules</label>
</process>
[...]
</post-upgrade>
</module>
# Syntaxe d'un script de migration
Un script de migration Anakeen Platform est déterminé par trois éléments principaux qui représentent une
<migration:action>
: précondition/condition
, processus
et vérification
.
Ces éléments sont caractérisés par les balises <migration:condition>
, <migration:process>
et <migration:check>
respectivement.
- Exemple :
<?xml version="1.0" ?>
<migration:config xmlns:migration="https://platform.anakeen.com/4/schemas/migration/1.0">
<migration:action id="hubGenericConfiguration" label="Remove hge_component_libname field from HubGenericConfiguration">
<migration:condition logical-operator="and">
<migration:sql-assert-not-empty label="verify hge_component_libname field exists"><![CDATA[
select * from docattr where id='hge_component_libname';
]]></migration:sql-assert-not-empty>
<migration:sql-assert-not-empty label="verify hge_component_txtname field exists"><![CDATA[
select * from docattr where id='hge_component_txtname';
]]></migration:sql-assert-not-empty>
</migration:condition>
<migration:process>
<migration:sql-query label="Remove hge_component_libname field"><![CDATA[
delete from docattr where id='hge_component_libname';
]]></migration:sql-query>
</migration:process>
<migration:check>
<migration:sql-assert-empty label="verify hge_component_libname field has been removed"><![CDATA[
select * from docattr where id='hge_component_libname';
]]></migration:sql-assert-empty>
</migration:check>
</migration:action>
</migration:config>
# Déroulement du script de migration
Avant d'exécuter un script de migration, celui-ci va vérifier que toutes les conditions décrites dans la balise
<migration:condition>
soient bien respectées.
Une transaction est déposée sur la base de données.
Si celles-ci sont validées, alors le script passe à l'exécution du processus de migration (<migration:process>
).
Lorsque la migration est terminée, le script lance une vérification (<migration:check>
) des conditions de fin de
migration.
Si le test est positif la transaction est commitée,
sinon un rollback est fait.
# Validation des conditions
Il existe différents moyens de validation des conditions :
migration:sql-assert-false (LabelStringType)
Vérifie que la requête SQL retourne
faux
.migration:sql-assert-true (LabelStringType)
Vérifie que la requête SQL retourne
true
migration:sql-assert-not-empty (LabelStringType)
Vérifie que le retour de requête n'est pas vide.
migration:sql-assert-empty (LabelStringType)
Vérifie que le retour de requête est vide.
migration:php-assert-code-return-false (phpCodeType)
Vérifie que l'exécution du code PHP retourne
false
.migration:php-assert-code-return-true (phpCodeType)
Vérifie que l'exécution du code PHP retourne
true
.migration:php-assert-true (phpMethodType)
Vérifie que le retour de la méthode PHP est valué à
true
.migration:php-assert-false (phpMethodType)
Vérifie que le retour de la méthode PHP est valué à
false
.
# Processus de migration
Il existe différents processus de migration :
- migration:bash-code :
Script de commande CLI.
Attributs :- label (string) : Libellé du processus (obligatoire),
- stop-on-error (boolean) : Indique l'arrêt du processus en cas d'erreur.
Exemple : Rechargement des routes de configuration
<migration:bash-code label="Reload routes configuration"><![CDATA[
#!/bin/bash
./ank.php --system --reloadConfig
]]></migration:bash-code>
- migration:sql-queryType
Utilisation de requête SQL sur la base de données.
Attributs :- label (string) : Libellé du processus (obligatoire),
- stop-on-error (boolean) : Indique l'arrêt du processus en cas d'erreur.
Exemple : suppression du Smart Field hge_component_libname
<?xml version="1.0" ?>
<migration:config xmlns:migration="https://platform.anakeen.com/4/schemas/migration/1.0">
<migration:action id="hubGenericConfiguration" label="Remove hge_component_libname field from HubGenericConfiguration">
<migration:condition>
<migration:sql-assert-not-empty label="verify hge_component_libname field exists"><![CDATA[
select * from docattr where id='hge_component_libname';
]]></migration:sql-assert-not-empty>
</migration:condition>
<migration:process>
<migration:sql-query label="Remove hge_component_libname field"><![CDATA[
delete from docattr where id='hge_component_libname';
]]></migration:sql-query>
</migration:process>
<migration:check>
<migration:sql-assert-empty label="verify hge_component_libname field has been removed"><![CDATA[
select * from docattr where id='hge_component_libname';
]]></migration:sql-assert-empty>
</migration:check>
</migration:action>
</migration:config>
Avertissements
Si la vérification post processus n'est pas validée, alors la requête SQL est annulée.
- migration:php
Utilisation de méthodes PHP.
Attributs :- label (string) : Libellé du processus (obligatoire),
- stop-on-error (boolean) : Indique l'arrêt du processus en cas d'erreur,
- callable (callableType) : Méthode appelée durant l'exécution du processus (obligatoire).
Exemple :
<?xml version="1.0" ?>
<migration:config xmlns:migration="https://platform.anakeen.com/4/schemas/migration/1.0">
<migration:action id="hubGenericConfiguration" label="Remove hge_component_libname field from HubGenericConfiguration">
<migration:condition>
<migration:sql-assert-not-empty label="verify hge_component_libname field exists"><![CDATA[
select * from docattr where id='hge_component_libname';
]]></migration:sql-assert-not-empty>
</migration:condition>
<migration:process>
<migration:php label="Use MyMethod" callable="My\MyMethod::MyMethod()"/>
</migration:process>
<migration:check>
<migration:sql-assert-empty label="verify hge_component_libname field has been removed"><![CDATA[
select * from docattr where id='hge_component_libname';
]]></migration:sql-assert-empty>
</migration:check>
</migration:action>
</migration>
- migration:php-code
Utilisation d'instructions PHP.
Attributs :- load-context (boolean) : Indique le chargement du contexte,
- stop-on-error (boolean) : Indique l'arrêt du processus en cas d'erreur,
Exemple : Ajout d'un historique pour indiquer que le Smart Element a été migré
<?xml version="1.0" ?>
<migration:config xmlns:migration="https://platform.anakeen.com/4/schemas/migration/1.0">
<migration:action id="hubGenericConfiguration" label="Remove hge_component_libname field from HubGenericConfiguration">
<migration:condition>
<migration:sql-assert-not-empty label="verify bill_author_display field exists">
select * from docattr where id='bill_author_display';
</migration:sql-assert-not-empty>
</migration:condition>
<migration:process>
<migration:php-code><![CDATA[
<?php
use Anakeen\Search\SearchElements;
use Anakeen\Search\Filters\Contains;
use SmartStructure\Fields\Devbill as devbill;
$s = new SearchElements("DEVBILL");
$s->addFilter(new Contains(devbill::bill_author_display, "Jean"));
$res = $s->search()->getResults();
foreach ($res as $r) {
$r->addHistoryEntry("end of migration revision");
}
?>
]]></migration:php-code>
</migration:process>
<migration:check>
<migration:php-assert-code-return-true label="verify bill_author_display field exists"><![CDATA[
<?php
use Anakeen\Search\SearchElements;
use Anakeen\Search\Filters\Contains;
use SmartStructure\Fields\Devbill as devbill;
$s = new SearchElements("DEVBILL");
$s->addFilter(new Contains(devbill::bill_author_display, "Jean"));
$res = $s->search()->getResults();
foreach ($res as $r) {
$histo = $r->getHisto(false);
foreach ($histo as $h) {
if (strcmp($h["comment"], "end of migration revision") === 0) {
return true;
} else {
return false;
}
}
}
?>
]]></migration:php-assert-code-return-true>
</migration:check>
</migration:action>
</migration>