Bevezetés
A merql egy tiszta PHP-könyvtár, amely háromutas egyesítést végez az adatbázis állapotán. Pillanatképeket készít a táblákról, kiszámítja a pillanatképek közötti módosításkészleteket, egy közös alap alapján egyesíti a két módosításkészletet, és oszlopszinten észleli az ütközéseket. Ugyanazt az algoritmust alkalmazza sorokra és oszlopokra, amelyet a git a forrásfájlok sorain használ.
Nincsenek külső eszközök. A MySQL és a SQLite támogatása cserélhető kapcsolatadaptereken és dialektus-illesztőprogramokon keresztül történik.
Gyors példa
Az egyesítéshez ugyanazon adatok három állapota kell: az alap, amelyből mindkét példány kiindult, valamint a két példány a külön-külön végzett módosítások után. Ebben az esetben egy tesztkörnyezetet másoltak az éles adatbázisból, és azóta mindkettőt módosították.
use Merql\Connection;
use Merql\Merql;
$live = Connection::sqlite('/data/live.sqlite');
$sandbox = Connection::sqlite('/data/sandbox.sqlite');
// Base: live at the moment the sandbox was copied from it.
Merql::init($live);
Merql::snapshot('base');
// ... copy live.sqlite to sandbox.sqlite, then both databases change ...
// Ours: the sandbox with our edits. Theirs: live with its own changes.
Merql::init($sandbox);
Merql::snapshot('ours');
Merql::init($live);
Merql::snapshot('theirs');
$result = Merql::merge('base', 'ours', 'theirs');
if ($result->isClean()) {
foreach ($result->operations() as $operation) {
echo "{$operation->type} {$operation->table} #{$operation->rowKey} ({$operation->source})\n";
}
} else {
echo "Conflicts: {$result->conflictCount()}\n";
}
Minden pillanatképet abból az adatbázisból kell rögzíteni, amely az adott állapotot tartalmazza. Ha egymás után mindhármat ugyanabból az adatbázisból veszi, az nem két különvált példány állapotát írja le: a másik fél állapota már tartalmazná a saját módosításait, és minden általunk beszúrt sor insert_insert ütközésként jelenne meg.
Az eredmény felsorolja az alapállapotot az egyesített állapottá alakító műveleteket mindkét oldalról, és mindegyikhez hozzárendeli a forrását (ours, theirs vagy merged). Ha a tesztkörnyezet módosításait az éles adatbázisba szeretné átvinni, alkalmazza azokat a műveleteket, amelyek még hiányoznak az éles adatbázisból a Feltételes alkalmazás segítségével.
Vagy a CLI használatával, amely minden snapshot esetén a MERQL_DB_DSN által megadott adatbázishoz csatlakozik:
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot base
# ... copy live.sqlite to sandbox.sqlite, then both databases change ...
MERQL_DB_DSN="sqlite:/data/sandbox.sqlite" vendor/bin/merql snapshot ours
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot theirs
vendor/bin/merql merge base ours theirs --dry-run
Miért a merql
A legtöbb állapotot összehasonlító adatbázis-eszköz sorszinten működik: ha egy sor bármely oszlopa eltér a két verzió között, az egész sort ütközésként jelöli meg. Ez téves ütközéseket okoz, ha két ember ugyanazon sor különböző oszlopait szerkeszti.
A merql oszlopszinten végez egyesítést. Ha az egyik fél a title-t, a másik pedig a status-t módosította, a változások ütközés nélkül egyesíthetők. A rendszer csak akkor jelez ütközést, ha mindkét fél ugyanazt az oszlopot eltérő értékre módosítja.
A TEXT és JSON oszlopoknál a merql egy szinttel mélyebbre is mehet, és cellaszintű egyesítést végezhet. A szövegoszlop különböző sorait érintő két módosítás, illetve az JSON oszlop különböző kulcsait érintő két módosítás ugyanazzal a háromutas algoritmussal tisztán egyesíthető. A cellaszintű egyesítés választható: adjon át egy CellMergeConfig értéket a(z) ThreeWayMerge számára. A Merql homlokzat és a CLI csak oszlopszinten egyesít. Lásd: Cellaszintű egyesítés.
Az egyesítési modell
Base (snapshot at fork time)
/ \
Ours (one copy's changes) Theirs (the other copy's changes)
\ /
--------- MERGE ----------
|
Merged result
+ conflicts (if any)
Három állapot, akárcsak a gitben. A base a közös ős. Az ours és a theirs a szétválás után létrejött két másolat, mindegyiket a saját adatbázisa rögzíti. Az egyesítési szabályok egyformán kezelik mindkét oldalt. A nevek megjelennek az egyes műveletek source értékében, az ütközéstípusokban (az update_delete azt jelenti, hogy az ours frissített, a theirs pedig törölt), valamint a OursWins és TheirsWins feloldási szabályzatokban. Közös alap nélkül nem lehet megkülönböztetni a „hozzáadott” és a „változatlan” állapotot.
Az egyesítés önmagában nem ír semmit. Műveletei a base állapotot alakítják át az egyesített állapottá, ezért az Merql::apply() csak olyan adatbázison futtatja le mindegyiket ütközésmentesen, amely még a base állapotot tartalmazza. Ha az egyik oldal módosításait egy olyan adatbázisba szeretné átvinni, amely már a másik oldal állapotát tartalmazza, például a sandboxban végzett szerkesztéseket éles környezetbe emelné, csak a hiányzó műveleteket alkalmazza; lásd: Védett alkalmazás.
Követelmények
- PHP 8.2 vagy újabb.
ext-mbstringésext-zlib, amelyeket azpitmaster/pitmasterfüggőség igényel a szövegkülönbségek kiszámításához.- Az Ön által használt adapterhez szükséges adatbázis-bővítmény:
ext-pdoext-pdo_sqlitevagyext-pdo_mysqlhasználatával, illetveext-mysqli. A merqlcomposer.jsoncsak aext-pdoésext-mysqlihasználatát javasolja, ezért az Composer nem ellenőrzi, hogy ezek telepítve vannak-e. - MySQL vagy SQLite adatbázis. Más motorokhoz egyéni illesztőprogram szükséges.
Ami nem tartozik ide
A merql nem sémamigrációs eszköz. Nem replikál adatbázisokat és nem szinkronizálja őket valós időben. Egyetlen konkrét problémát old meg: három adatbázis-állapotból létrehoz egy negyedik, egyesített állapotot, és azonosítja az ütközéseket.
Dokumentáció
- Első lépések -- telepítés, első pillanatkép, első egyesítés.
- CLI referencia -- az
vendor/bin/merqlparancs teljes leírása. - PHP API referencia -- az összes osztály teljes API dokumentációja.
- Egyesítési tervek -- stabil műveletazonosítók, módosításcsoportok és kijelölések.
- Védett alkalmazás -- kijelölt írások az éles sorokra vonatkozó előfeltételekkel.
- Visszaállítás -- visszaállítási melléktermékek és eltérés-ellenőrzések.