Merql
Unione di database a tre vie PHP pura, con risoluzione dei conflitti a livello di colonna. Semantica di unione in stile Git per tabelle MySQL e SQLite.
composer require merql/merqlUltima versione 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']);Nella pratica
Un’unione legge tre snapshot salvati e restituisce le operazioni da scrivere e i conflitti da risolvere.
Unire tre snapshot
Acquisite lo snapshot di base prima che le due copie si separino, poi acquisite uno snapshot per ciascun lato, per esempio un database live e una copia sandbox. ThreeWayMerge confronta entrambi i lati con la base e unisce i due changeset.
Nella scheda dei risultati, noi abbiamo modificato content e gli altri hanno modificato title e status della stessa riga, quindi l’unione mantiene tutte e tre le modifiche senza conflitti.
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" }Unione a tre vie
Base, nostri, loro. Un’unione a tre vie in stile git su righe e colonne con chiavi anziché su righe di testo. Rileva inserimenti, aggiornamenti ed eliminazioni tra due rami.
Risoluzione a livello di colonna
Quando entrambi i lati modificano la stessa riga, merql confronta le colonne una per una. Segnala un conflitto solo se la stessa colonna cambia con valori diversi.
Unione delle celle su richiesta
Passate una CellMergeConfig a ThreeWayMerge: le colonne TEXT vengono unite riga per riga con il diff di Myers, le colonne JSON chiave per chiave. La facade Merql e CLI non attivano questa funzione.
Più database
Adattatori di connessione e driver di dialetto collegabili, con MySQL e SQLite integrati.
Rilevamento dei conflitti
Aggiornamento contro aggiornamento, aggiornamento contro eliminazione, eliminazione contro aggiornamento e inserimento contro inserimento: ciascun conflitto viene segnalato con tabella e riga. I conflitti tra aggiornamenti indicano anche la colonna.
Generazione di SQL
Istruzioni INSERT, UPDATE e DELETE parametrizzate con ordinamento basato sulle FK. Anteprima di prova o applicazione in una transazione.
CLI
Acquisizione di snapshot, diff e unione dalla riga di comando. Supporta MySQL e SQLite tramite variabili d’ambiente.
Testato
32 scenari di regressione con risultati attesi scritti a mano (composer test:oracle). La CI esegue i test unitari e di integrazione di 231 e il livello 10 di PHPStan.
Perché Merql
Gli snapshot sono file
Ogni snapshot è un file JSON che potete copiare tra computer o inserire nel controllo di versione. Diff e unione leggono questi file, quindi funzionano senza una connessione al database.
Esaminate prima di scrivere
Un piano di unione assegna un ID stabile a ogni operazione e gruppo di modifiche e conserva le righe di base, nostre, altrui e del risultato. Selezionate i gruppi desiderati e applicate solo quelli.
I piani obsoleti vengono bloccati
L’applicazione protetta scrive solo nelle righe che corrispondono ancora allo snapshot esaminato. Se un’istruzione non modifica alcuna riga, la transazione viene annullata e il risultato include l’errore.
Rollback con verifica delle differenze
Create un piano di rollback dalle righe live subito prima della scrittura e salvatelo come JSON. Prima di annullare le modifiche, la verifica delle differenze confronta le impronte delle righe e restituisce le operazioni le cui righe sono cambiate nel frattempo.
A confronto con
Merql unisce i dati delle righe provenienti da tre snapshot. Questi strumenti gestiscono il versionamento, la sincronizzazione o la migrazione dei database, attività affini.
| Strumento | Ideale per | Differenze rispetto a Merql |
|---|---|---|
| Dolt | Ideale perDolt è un database SQL che puoi duplicare, clonare, ramificare, unire, inviare e scaricare come un repository Git. Ti connetti come a qualsiasi database MySQL e tiene traccia della provenienza di ogni cella. | Differenze rispetto a MerqlMerql mantiene il database MySQL o SQLite che già utilizzi. Salva le tabelle in file snapshot JSON e ne unisce tre, lasciando a te la scelta dello snapshot di base. |
| pt-table-sync | Ideale perpt-table-sync individua e corregge le differenze tra tabelle MySQL, in una direzione o in entrambe tra server. Quando sincronizza una replica, applica le modifiche alla sorgente di replica. | Differenze rispetto a MerqlNella sincronizzazione bidirezionale, pt-table-sync sceglie la riga vincente in base a una colonna di conflitto e ne copia i valori. Merql confronta entrambi i lati con una base comune, unisce le modifiche apportate a colonne diverse della stessa riga e segnala come conflitti le modifiche incompatibili da risolvere. |
| sqldiff | Ideale persqldiff confronta due database SQLite e stampa uno script SQL che trasforma il primo nel secondo. Può anche scrivere un changeset binario per l'estensione di sessione SQLite o riepilogare le righe modificate per tabella. | Differenze rispetto a MerqlUn diff a due vie non può stabilire se un lato ha aggiunto una riga o l'altro l'ha eliminata. Merql aggiunge uno snapshot di base per determinarlo, unisce due serie di modifiche e funziona anche con MySQL. |
| Doctrine Migrations | Ideale perDoctrine Migrations tiene traccia delle versioni dello schema del database, così le modifiche allo schema possono essere esaminate e testate prima della distribuzione in produzione. | Differenze rispetto a MerqlMerql non è uno strumento di migrazione dello schema. Unisce i dati delle righe e segnala le colonne aggiunte o rimosse tra gli snapshot, lasciando a te il compito di modificare lo schema. |
Domande e risposte
Risposte brevi dalla documentazione di Merql.
MySQL e SQLite, tramite gli adattatori PDO o mysqli. Per un altro motore, scrivi una classe che implementi l'interfaccia Driver e registrala con DriverFactory::register().
No. Non migra gli schemi, non replica i database e non li sincronizza in tempo reale. A partire da tre stati del database, produce un quarto stato unificato e identifica i conflitti.
Quando entrambi i lati modificano la stessa colonna della stessa riga assegnandole valori diversi, quando un lato aggiorna una riga eliminata dall'altro oppure quando entrambi inseriscono una riga con la stessa chiave. Le modifiche a colonne diverse della stessa riga vengono unite senza problemi.
No. Leggono i file snapshot salvati, quindi solo la creazione di uno snapshot e l'applicazione di un risultato richiedono una connessione al database.
Sì. Crea un piano di unione, seleziona i gruppi di modifiche tramite i relativi ID e trasforma la selezione in un risultato pulito per Merql::apply() o Merql::applyGuarded().
Solo se lo abiliti creando ThreeWayMerge con un CellMergeConfig, ad esempio CellMergeConfig::auto(). Merql::merge(), Merql::plan() e CLI trattano ogni valore di colonna come un blocco unico.
Segui la guida, dal primo snapshot fino ai piani di unione, all'applicazione protetta e al rollback.