Sujungimo planai
MergeResult yra vykdomas sujungimo rezultatas. MergePlan yra šio rezultato
patikrinama forma. Naudokite jį, kai programai reikia parodyti, paruošti,
serializuoti arba pasirinktinai pritaikyti duomenų bazės pakeitimus prieš
įrašant juos į tikslinę duomenų bazę.
use Merql\Merql;
$plan = Merql::plan(
id: 'plan-2026-06-06',
base: 'base',
ours: 'ours',
theirs: 'theirs',
metadata: ['sandbox_id' => 'ow_123'],
);
Merql::plan() įkelia tris nurodytus momentinius vaizdus ir sujungia juos stulpelių
lygmeniu, kaip Merql::merge(). Norėdami suplanuoti sujungimą, kuriame TEXT ir
JSON stulpeliams naudojamas sujungimas langelio lygmeniu, patys sukurkite
rezultatą ir perduokite jį MergePlanBuilder:
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);
Plane pateikiama:
- jam sukurti naudotų momentinių vaizdų pavadinimai,
- operacijų, konfliktų, schemos neatitikimų, lentelių ir grupių suvestinė,
- stabilūs operacijų ID,
- stabilūs pakeitimų grupių ID,
- eilučių tapatybės stulpeliai ir tapatybės reikšmės,
- kiekvienos operacijos bazinės versijos, mūsų pusės, jų pusės ir rezultato eilučių reikšmės,
- pasirenkami pagrindinės programos metaduomenys,
- plano maiša,
- schemos versija.
Stabilūs ID
Tų pačių operacijos duomenų operacijų ID visada yra vienodi. Jie apskaičiuojami pagal lentelės pavadinimą, eilutės raktą, operacijos tipą, operacijos šaltinį, pakeistus stulpelius ir rezultato reikšmes.
Tų pačių grupės duomenų pakeitimų grupės ID visada yra vienodi. Numatytoji plano kūrimo priemonė kiekvienai operacijai sukuria atskirą operacijų grupę. Pagrindinės programos gali iš operacijų sąrašo kurti platesnes konkrečios srities grupes ir serializuoti jas tokiu pačiu DTO formatu.
foreach ($plan->changeGroups as $group) {
echo $group->id . ': ' . implode(', ', $group->operationIds);
}
Operacijos struktūra
Kiekvienoje MergePlanOperation pateikiama pakankamai konteksto peržiūrai ir atšaukimui.
$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
Pasirinkimai
Naudokite ChangeGroupSelection, kai UI paruošia grupes. Taikydami pakeitimus arba generuodami atšaukimo artefaktus, konvertuokite jį į OperationSelection.
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),
);
Pasirinktas rezultatas yra švarus MergeResult, kuriame yra tik pasirinktos
operacijos. Jį galima perduoti Merql::apply() arba Merql::applyGuarded().
Trūkstamų pakeitimų pasirinkimas tikslinėje bazėje
Plane pateikiamos abiejų pusių operacijos, nes sujungimo rezultatas paverčia bazinę
versiją sujungta būsena. Jei tikslinėje bazėje jau yra viena pusė, pasirinkite tik tas
operacijas, kurių joje dar nėra. Jei tikslinėje bazėje yra jų pusės pakeitimai, pavyzdžiui, į tiesioginę
duomenų bazę perkeliami smėliadėžės kopijoje atlikti pakeitimai, pasirinkite visas operacijas,
kurių šaltinis yra ours, taip pat merged atnaujinimus, kurie apima abiejų pusių stulpelių pakeitimus:
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),
);
Operacijos, kurių šaltinis yra theirs, ir merged ištrynimai (eilutės, kurias ištrynė abi pusės) tikslinėje bazėje jau yra.
Iš sujungimo su konfliktais sukurtame plane vis tiek pateikiama po operaciją kiekvienai
konfliktuojančiai eilutei, kurią atnaujino abi pusės. Rezultato reikšmėse konfliktuojančiam
stulpeliui saugoma mūsų reikšmė, o SelectedMergeResultFactory pateikia švarų rezultatą
bet kuriam pasirinkimui. Operacijos ir pakeitimų grupės conflictState net ir tokiu atveju šiuo metu
nurodo clean (#9), todėl, kaip nurodyta pirmiau, patys patikrinkite $plan->conflicts arba išspręskite konfliktus naudodami
ConflictResolver ir sukurkite planą iš išspręsto rezultato, naudodami
MergePlanBuilder. Kaip pritaikyti pasirinkimą su tiesioginės eilutės išankstinėmis sąlygomis, žr.
Apsaugotas taikymas.
Serializavimas
Sujungimo planai ir pasirinkimai turi stabilų JSON serializavimą. Išsaugokite serializuotą planą, jei vėlesniame taikymo etape reikia naudoti tiksliai peržiūrėtą operacijų rinkinį.
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),
);
Pseudonimais pavadinti momentiniai vaizdai
Sujungimo planuose naudojami kanoniniai lentelių pavadinimai. Jei skirtingose aplinkose fiziniai lentelių pavadinimai skiriasi, prieš planuodami išsaugokite jas tuo pačiu kanoniniu pavadinimu.
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',
]));
Momentinio vaizdo schemoje išsaugomas kanoninis lentelės pavadinimas, kartu išlaikant fizinės lentelės stulpelius, raktus, tapatybės stulpelius, eilučių raktus ir filtrus.