Yhdistämissuunnitelmat
MergeResult on yhdistämisen suoritettava tulos. MergePlan on tämän tuloksen tarkasteltava muoto. Käytä sitä, kun sovelluksen pitää näyttää, vaiheistaa, sarjoittaa tai ottaa valikoidusti käyttöön tietokantamuutoksia ennen niiden kirjoittamista kohdetietokantaan.
use Merql\Merql;
$plan = Merql::plan(
id: 'plan-2026-06-06',
base: 'base',
ours: 'ours',
theirs: 'theirs',
metadata: ['sandbox_id' => 'ow_123'],
);
Merql::plan() lataa kolme nimettyä tilannevedosta ja yhdistää ne saraketasolla, kuten Merql::merge(). Jos haluat suunnitella yhdistämisen, jossa TEXT- ja JSON-sarakkeille käytetään solutason yhdistämistä, rakenna tulos itse ja välitä se MergePlanBuilder-toiminnolle:
use Merql\CellMerge\CellMergeConfig;
use Merql\Merge\ThreeWayMerge;
use Merql\Plan\MergePlanBuilder;
use Merql\Snapshot\SnapshotStore;
$base = SnapshotStore::load('base');
$ours = SnapshotStore::load('ours');
$theirs = SnapshotStore::load('theirs');
$result = (new ThreeWayMerge(CellMergeConfig::auto()))->merge($base, $ours, $theirs);
$plan = (new MergePlanBuilder())->build('plan-2026-06-06', $base, $ours, $theirs, $result);
Suunnitelma sisältää:
- sen rakentamiseen käytettyjen tilannevedosten nimet,
- toimintojen, ristiriitojen, skeemapoikkeamien, taulujen ja ryhmien yhteenvedon,
- vakaat toimintotunnisteet,
- vakaat muutosryhmien tunnisteet,
- rivien identiteettisarakkeet ja identiteettiarvot,
- kunkin toiminnon perus-, meidän-, heidän- ja tulosrivin arvot,
- valinnaiset isäntäsovelluksen metatiedot,
- suunnitelman hajautusarvon,
- skeemaversion.
Vakaat tunnisteet
Toimintojen tunnisteet ovat deterministisiä, kun toiminnon sisältö on sama. Ne johdetaan taulun nimestä, rivin avaimesta, toiminnon tyypistä, toiminnon lähteestä, muuttuneista sarakkeista ja tuloksen arvoista.
Muutosryhmien tunnisteet ovat deterministisiä, kun ryhmän sisältö on sama. Oletusrakentaja luo yhden toimintoryhmän kutakin toimintoa kohti. Isäntäsovellukset voivat muodostaa toimintoluettelosta suurempia toimialakohtaisia ryhmiä ja sarjoittaa ne silti samalla DTO-rakenteella.
foreach ($plan->changeGroups as $group) {
echo $group->id . ': ' . implode(', ', $group->operationIds);
}
Toiminnon rakenne
Jokainen MergePlanOperation sisältää riittävästi tietoa tarkastelua ja palautusta varten.
$operation = $plan->operations[0];
$operation->id; // stable operation ID
$operation->type; // insert, update, delete
$operation->table; // canonical table name
$operation->rowKey; // encoded identity key
$operation->identityColumns; // columns used for identity
$operation->identityValues; // decoded identity values
$operation->source; // ours, theirs, or merged
$operation->baseRow; // row in base snapshot, or null
$operation->oursRow; // row in ours snapshot, or null
$operation->theirsRow; // row in theirs snapshot, or null
$operation->resultValues; // values the merge would write
$operation->changedColumns; // changed result columns
Valinnat
Käytä ChangeGroupSelection-rakennetta, kun UI vaiheistaa ryhmät. Muunna se OperationSelection-muotoon muutoksia käyttöönotettaessa tai palautustiedostoja luotaessa.
use Merql\Plan\ChangeGroupSelection;
use Merql\Plan\SelectedMergeResultFactory;
use Merql\Snapshot\SnapshotStore;
$selection = ChangeGroupSelection::fromIds([
$plan->changeGroups[0]->id,
]);
$operationSelection = $selection->toOperationSelection($plan);
$selectedResult = (new SelectedMergeResultFactory())->fromOperationSelection(
$plan,
$operationSelection,
SnapshotStore::load($plan->baseSnapshot),
);
Valittu tulos on puhdas MergeResult, joka sisältää vain valitut toiminnot. Sen voi välittää Merql::apply()- tai Merql::applyGuarded()-toiminnolle.
Sen valitseminen, mitä kohteesta puuttuu
Suunnitelma sisältää molempien puolten toiminnot, koska yhdistämistulos muuttaa peruskannan yhdistetyksi tilaksi. Kun kohteessa on jo toinen puoli, valitse vain toiminnot, joita kohteesta vielä puuttuu. Jos kohteessa on heidän puolensa, esimerkiksi jos käytössä oleva tietokanta saa hiekkalaatikkokopion muokkaukset, valitse kaikki lähteen ours toiminnot sekä merged-päivitykset, joissa yhdistyvät molempien puolten sarakemuutokset:
use Merql\Plan\OperationSelection;
use Merql\Plan\SelectedMergeResultFactory;
use Merql\Snapshot\SnapshotStore;
// Rows with an unresolved conflict stay out of the selection.
$conflicted = [];
foreach ($plan->conflicts as $conflict) {
$conflicted[$conflict->table . "\0" . $conflict->rowKey] = true;
}
$ids = [];
foreach ($plan->operations as $operation) {
$missing = $operation->source === 'ours'
|| ($operation->source === 'merged' && $operation->type === 'update');
if ($missing && !isset($conflicted[$operation->table . "\0" . $operation->rowKey])) {
$ids[] = $operation->id;
}
}
$selected = (new SelectedMergeResultFactory())->fromOperationSelection(
$plan,
OperationSelection::fromIds($ids),
SnapshotStore::load($plan->baseSnapshot),
);
Lähteen theirs toiminnot ja merged-poistot (rivit, jotka molemmat puolet poistivat) ovat jo kyseisessä kohteessa.
Ristiriitoja sisältävän yhdistämisen suunnitelmassa on edelleen toiminto jokaiselle ristiriitaiselle riville, jota molemmat puolet päivittivät. Sen tulosarvoissa on meidän arvomme ristiriitaisessa sarakkeessa, ja SelectedMergeResultFactory palauttaa puhtaan tuloksen kaikille valinnoille. Toiminnon ja muutosryhmän conflictState on tällä hetkellä clean myös tällöin (#9), joten tarkista $plan->conflicts itse yllä kuvatulla tavalla tai ratkaise ristiriidat ConflictResolver-toiminnolla ja rakenna suunnitelma ratkaistusta tuloksesta käyttäen MergePlanBuilder-toimintoa. Katso ohjeesta Suojattu käyttöönotto, miten valinta kirjoitetaan tietokantaan käytössä olevan rivin ennakkoehdoilla.
Sarjallistaminen
Yhdistämissuunnitelmien ja valintojen JSON-sarjoitus on vakaa. Tallenna sarjoitettu suunnitelma, jos myöhempi käyttöönottovaihe tarvitsee täsmälleen saman tarkistetun toimintojoukon.
use Merql\Plan\ChangeGroupSelection;
use Merql\Plan\MergePlanSerializer;
$json = MergePlanSerializer::toJson($plan);
$restored = MergePlanSerializer::fromJson($json);
$selectionJson = json_encode($selection->toArray(), JSON_THROW_ON_ERROR);
$selection = ChangeGroupSelection::fromArray(
json_decode($selectionJson, true, flags: JSON_THROW_ON_ERROR),
);
Aliaksetut tilannevedokset
Yhdistämissuunnitelmissa käytetään kanonisia taulujen nimiä. Jos fyysisten taulujen nimet eroavat ympäristöjen välillä, ota tilannevedokset ennen suunnittelua samalla kanonisella nimellä.
use Merql\Snapshot\SnapshotStore;
use Merql\Snapshot\Snapshotter;
$snapshotter = new Snapshotter($connection);
SnapshotStore::save($snapshotter->captureAliased('live', [
'wp_posts' => 'wp_posts',
]));
SnapshotStore::save($snapshotter->captureAliased('sandbox', [
'wp_onumia_abc_posts' => 'wp_posts',
]));
Tilannevedokseen tallennettu skeema käyttää kanonista taulun nimeä ja säilyttää fyysisen taulun sarakkeet, avaimet, identiteettisarakkeet, riviavaimet ja suodattimet.