Johdanto
merql on puhdas PHP-kirjasto, joka tekee tietokannan tilalle kolmisuuntaisia yhdistämisiä. Se tallentaa tauluista tilannevedoksia, laskee niiden väliset muutossarjat, yhdistää kaksi muutosjoukkoa yhteiseen lähtötilaan nähden ja havaitsee ristiriidat saraketasolla. Käytössä on sama algoritmi kuin gitin lähdetiedostoissa, mutta sitä sovelletaan tietokannan riveihin ja sarakkeisiin tekstirivien sijaan.
Ei ulkoisia työkaluja. Tukee MySQL- ja SQLite-tietokantoja liitettävien yhteyssovittimien ja murreajurien kautta.
Pikaesimerkki
Yhdistämiseen tarvitaan kolme saman datan tilaa: lähtötila, josta molemmat kopiot aloittivat, sekä kaksi kopiota niiden itsenäisten muutosten jälkeen. Tässä testiympäristö kopioitiin tuotantotietokannasta, ja molempia on sittemmin muokattu.
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";
}
Kukin tilannevedos otetaan tietokannasta, jossa kyseinen tila on. Kaikkien kolmen ottaminen samasta tietokannasta peräkkäin ei kuvaa kahta erkaantunutta kopiota: theirs sisältäisi jo ours-muutokset, ja jokainen ours-puolen lisäämä rivi ilmoitettaisiin insert_insert-ristiriitana.
Tulos luettelee toiminnot, jotka muuttavat basen yhdistetyksi tilaksi, ja sisältää molempien puolten muutokset. Kukin toiminto on merkitty lähteellään (ours, theirs tai merged). Jos haluat kirjoittaa testiympäristön muutokset tuotantoon, käytä komentoa Suojattu käyttö ja sovella vain toimintoja, joita tuotantoympäristössä ei vielä ole.
Tai käytä CLI-ohjelmaa, joka yhdistää tietokantaan, joka on määritetty kullekin snapshot-arvolle kohteessa MERQL_DB_DSN:
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
Miksi merql
Useimmat tietokantatyökalut vertaavat tiloja rivitasolla: jos yksikin rivin sarake eroaa kahden version välillä, koko rivi merkitään ristiriidaksi. Näin syntyy vääriä ristiriitoja, kun kaksi henkilöä muokkaa saman rivin eri sarakkeita.
merql yhdistää muutokset saraketasolla. Jos toinen puoli muutti arvoa title ja toinen arvoa status, muutokset yhdistyvät ongelmitta ilman ristiriitaa. Ristiriita syntyy vain, kun molemmat puolet muuttavat saman sarakkeen eri arvoon.
TEXT- ja JSON-sarakkeissa merql voi yhdistää yhtä tasoa syvemmältä solutasolla. Tekstisarakkeen eri riveihin tai JSON-sarakkeen eri avaimiin tehdyt muutokset voidaan yhdistää ongelmitta samalla kolmen osapuolen algoritmilla. Solutason yhdistäminen on valinnainen: välitä CellMergeConfig kohteelle ThreeWayMerge. Merql-julkisivu ja CLI yhdistävät vain saraketasolla. Katso Solutason yhdistäminen.
Yhdistämismalli
Base (snapshot at fork time)
/ \
Ours (one copy's changes) Theirs (the other copy's changes)
\ /
--------- MERGE ----------
|
Merged result
+ conflicts (if any)
Kolme tilaa, kuten gitissä. Base on yhteinen edeltäjä. Ours ja theirs ovat kaksi kopiota niiden erkaantumisen jälkeen; kumpikin tallennetaan omasta tietokannastaan. Yhdistämissäännöt kohtelevat molempia puolia samalla tavalla. Nimet näkyvät kunkin toiminnon source-kentässä, ristiriitatyypeissä (update_delete tarkoittaa, että ours päivitti ja theirs poisti) sekä OursWins- ja TheirsWins-ratkaisukäytännöissä. Ilman yhteistä lähtötilaa et voi erottaa lisäystä muuttumattomasta.
Yhdistäminen ei itsessään kirjoita mitään. Sen toiminnot muuntavat basen yhdistetyksi tilaksi, joten Merql::apply() suorittaa ne kaikki ongelmitta vain tietokannassa, jossa on yhä base-tila. Jos haluat tuoda toisen puolen muutokset tietokantaan, jossa on jo toisen puolen muutokset, esimerkiksi siirtää testiympäristön muokkaukset tuotantoon, käytä vain puuttuvia toimintoja; katso Suojattu käyttö.
Vaatimukset
- PHP 8.2 tai uudempi.
ext-mbstringjaext-zlib, joita tekstierot tuottavapitmaster/pitmaster-riippuvuus edellyttää.- Käyttämääsi sovitinta vastaava tietokantalaajennus:
ext-pdosekäext-pdo_sqlitetaiext-pdo_mysql, taiext-mysqli. merqlincomposer.jsonainoastaan ehdottaaext-pdo- jaext-mysqli-laajennuksia, joten Composer ei tarkista niiden olemassaoloa. - MySQL- tai SQLite-tietokanta. Muut tietokantamoottorit tarvitsevat mukautetun ajurin.
Mitä se ei ole
merql ei ole tietokantakaavion siirtotyökalu. Se ei repliko tietokantoja eikä synkronoi niitä reaaliajassa. Se ratkaisee yhden rajatun ongelman: kun käytössä on kolme tietokannan tilaa, tuottaa neljännen, yhdistetyn tilan ja tunnistaa ristiriidat.
Dokumentaatio
- Aloitusopas -- asennus, ensimmäinen tilannevedos ja ensimmäinen yhdistäminen.
- CLI-ohjelman viite -- kattava viite komennolle
vendor/bin/merql. - PHP API-viite -- kattava API-dokumentaatio kaikista luokista.
- Yhdistämissuunnitelmat -- vakaat toimintotunnisteet, muutosryhmät ja valinnat.
- Suojattu käyttö -- valitut kirjoitukset ja aktiivisen rivin ennakkoehdot.
- Palautus -- palautuksen tukitiedostot ja poikkeamien tarkistukset.