Merql
Fusion de bases de données à trois voies pure en PHP, avec résolution des conflits au niveau des colonnes. Sémantique de fusion de type Git appliquée aux tables MySQL et SQLite.
composer require merql/merqlDernière version v0.4.1 MIT PHP 8.2+
use Merql\Merql;
Merql::init($connection);
// Snapshot all tables.
$snapshot = Merql::snapshot('baseline');
// Snapshot specific tables.
$snapshot = Merql::snapshot('baseline', ['posts', 'comments', 'users']);En pratique
Une fusion lit trois instantanés enregistrés et renvoie les opérations à écrire ainsi que les conflits à résoudre.
Fusionner trois instantanés
Créez l’instantané de base avant que les deux copies ne divergent, puis un instantané de chaque côté, par exemple d’une base en production et d’une copie de test. ThreeWayMerge compare les deux côtés à la base et fusionne leurs ensembles de modifications.
Dans l’onglet des résultats, notre côté a modifié content, tandis que leur côté a modifié title et status de la même ligne ; la fusion conserve donc les trois modifications sans conflit.
use Merql\Merge\ThreeWayMerge;
$merge = new ThreeWayMerge();
$result = $merge->merge($base, $ours, $theirs);
echo $result->operationCount(); // resolved operations
echo $result->conflictCount(); // unresolved conflictsBase: { title: "Hello", content: "Body", status: "draft" }
Ours: { title: "Hello", content: "Body v2", status: "draft" }
Theirs: { title: "New Title", content: "Body", status: "publish" }
Result: { title: "New Title", content: "Body v2", status: "publish" }Fusion à trois voies
Base, les nôtres, les leurs. Une fusion à trois voies de type git sur des lignes et colonnes à clés plutôt que sur des lignes de texte. Détecte les insertions, mises à jour et suppressions entre deux branches.
Résolution au niveau des colonnes
Lorsque les deux côtés modifient la même ligne, merql compare les colonnes une à une. Un conflit survient uniquement si la même colonne reçoit des valeurs différentes.
Fusion des cellules sur option
Transmettez une CellMergeConfig à ThreeWayMerge pour fusionner les colonnes TEXT ligne par ligne avec l’algorithme Myers diff, et les colonnes JSON clé par clé. La façade Merql et le CLI ne l’activent pas.
Plusieurs bases de données
Adaptateurs de connexion et pilotes de dialecte enfichables, avec MySQL et SQLite intégrés.
Détection des conflits
Modification contre modification, modification contre suppression, suppression contre modification et insertion contre insertion : chaque conflit est signalé avec la table et la ligne. Les conflits entre deux modifications indiquent aussi la colonne concernée.
Génération SQL
Instructions INSERT, UPDATE et DELETE paramétrées, avec un ordre qui tient compte des clés étrangères. Prévisualisation à blanc ou application dans une transaction.
CLI
Création d’instantanés, comparaison et fusion depuis la ligne de commande. Prend en charge MySQL et SQLite via des variables d’environnement.
Testé
32 scénarios de régression avec des résultats attendus rédigés à la main (composer test:oracle). La CI exécute des tests unitaires et d’intégration 231 et le niveau 10 de PHPStan.
Pourquoi Merql
Les instantanés sont des fichiers
Chaque instantané est un fichier JSON que vous pouvez copier entre machines ou valider dans le contrôle de version. Les comparaisons et fusions lisent ces fichiers et fonctionnent donc sans connexion à une base de données.
Vérifiez avant d’écrire
Un plan de fusion attribue un ID stable à chaque opération et groupe de modifications, et conserve les lignes de base, de notre côté, de leur côté et du résultat. Sélectionnez les groupes voulus et appliquez-les seuls.
Les plans obsolètes sont bloqués
L’application protégée écrit uniquement dans les lignes qui correspondent toujours à l’instantané que vous avez examiné. Si une instruction ne modifie aucune ligne, la transaction est annulée et le résultat contient l’erreur.
Annulation avec vérification de dérive
Créez un plan d’annulation à partir des lignes en production juste avant l’écriture et enregistrez-le au format JSON. Avant l’annulation, la vérification de dérive compare les empreintes des lignes et renvoie les opérations dont les lignes ont changé depuis.
Comparaison avec
Merql fusionne les données de lignes à partir de trois instantanés. Ces outils gèrent le versionnement, la synchronisation ou la migration des bases de données, des tâches connexes.
| Outil | Idéal pour | Différence avec Merql |
|---|---|---|
| Dolt | Idéal pourDolt est une base de données SQL que vous pouvez dupliquer, cloner, brancher, fusionner, envoyer et récupérer comme un dépôt Git. Vous vous y connectez comme à n’importe quelle base de données MySQL, et elle suit la provenance de chaque cellule. | Différence avec MerqlMerql conserve la base de données MySQL ou SQLite que vous utilisez déjà. Il enregistre les tables dans des fichiers d’instantané JSON et en fusionne trois, la base étant choisie par vos soins. |
| pt-table-sync | Idéal pourpt-table-sync détecte et corrige les différences entre des tables MySQL, dans un sens ou dans les deux sens entre serveurs. Lorsqu’il synchronise une réplique, il applique les modifications à la source de réplication. | Différence avec MerqlLors d’une synchronisation bidirectionnelle, pt-table-sync choisit la ligne gagnante selon une colonne de conflit et en copie les valeurs. Merql compare les deux côtés à une base commune, fusionne les modifications apportées à différentes colonnes d’une même ligne et signale les changements incompatibles comme des conflits à résoudre. |
| sqldiff | Idéal poursqldiff compare deux bases de données SQLite et affiche un script SQL qui transforme la première en seconde. Il peut aussi écrire un ensemble de modifications binaire pour l’extension de session SQLite ou résumer les lignes modifiées par table. | Différence avec MerqlUne comparaison à deux voies ne permet pas de savoir si un côté a ajouté une ligne ou si l’autre l’a supprimée. Merql ajoute un instantané de base pour trancher, fusionne deux ensembles de modifications et fonctionne aussi avec MySQL. |
| Doctrine Migrations | Idéal pourDoctrine Migrations versionne le schéma de votre base de données, afin que les modifications de schéma puissent être examinées et testées avant leur déploiement en production. | Différence avec MerqlMerql n’est pas un outil de migration de schéma. Il fusionne les données des lignes et signale les colonnes ajoutées ou supprimées entre les instantanés ; la modification du schéma vous revient. |
Questions et réponses
Réponses courtes issues de la documentation de Merql.
MySQL et SQLite, via les adaptateurs PDO ou mysqli. Pour un autre moteur, écrivez une classe qui implémente l’interface Driver et enregistrez-la avec DriverFactory::register().
Non. Il ne migre pas les schémas, ne réplique pas les bases de données et ne les synchronise pas en temps réel. À partir de trois états de base de données, il produit un quatrième état fusionné et identifie les conflits.
Lorsqu’un même côté modifie la même colonne d’une même ligne avec des valeurs différentes, lorsqu’un côté modifie une ligne supprimée par l’autre ou lorsque les deux côtés insèrent une ligne ayant la même clé. Les modifications apportées à des colonnes différentes d’une même ligne sont fusionnées sans conflit.
Non. Elles lisent des fichiers d’instantané enregistrés ; seule la création d’un instantané et l’application d’un résultat se connectent à la base de données.
Oui. Créez un plan de fusion, sélectionnez des groupes de modifications par ID et transformez la sélection en un résultat sans conflit pour Merql::apply() ou Merql::applyGuarded().
Uniquement si vous l’activez en construisant ThreeWayMerge avec une CellMergeConfig, par exemple CellMergeConfig::auto(). Merql::merge(), Merql::plan() et le CLI traitent chaque valeur de colonne dans son ensemble.
Suivez le guide, de votre premier instantané aux plans de fusion, à l’application protégée et à l’annulation.