Načrti združevanja
MergeResult je izvedljivi izhod združitve. MergePlan je oblika tega izhoda, ki jo lahko pregledujete. Uporabite jo, kadar mora aplikacija prikazati, pripraviti, serializirati ali selektivno uveljaviti spremembe v podatkovni zbirki, preden jih zapiše v ciljno podatkovno zbirko.
use Merql\Merql;
$plan = Merql::plan(
id: 'plan-2026-06-06',
base: 'base',
ours: 'ours',
theirs: 'theirs',
metadata: ['sandbox_id' => 'ow_123'],
);
Merql::plan() naloži tri poimenovane posnetke in jih združi na ravni stolpcev, kot Merql::merge(). Če želite načrtovati združitev, ki uporablja združevanje na ravni celic za stolpca TEXT in JSON, rezultat ustvarite sami in ga posredujte v 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);
Načrt vsebuje:
- imena posnetkov, uporabljenih za njegovo izdelavo,
- povzetek operacij, konfliktov, neskladij shem, tabel in skupin,
- stabilne ID-je operacij,
- stabilne ID-je skupin sprememb,
- stolpce identitete vrstic in vrednosti identitete,
- vrednosti vrstic base, ours, theirs in result za vsako operacijo,
- neobvezne metapodatke gostiteljske aplikacije,
- zgoščeno vrednost načrta,
- različico sheme.
Stabilni ID-ji
ID-ji operacij so deterministični za enako vsebino operacije. Izhajajo iz imena tabele, ključa vrstice, vrste operacije, vira operacije, spremenjenih stolpcev in vrednosti rezultata.
ID-ji skupin sprememb so deterministični za enako vsebino skupine. Privzeti graditelj ustvari eno skupino operacij za vsako operacijo. Gostiteljske aplikacije lahko iz seznama operacij sestavijo večje domensko specifične skupine in jih še vedno serializirajo v enaki obliki DTO.
foreach ($plan->changeGroups as $group) {
echo $group->id . ': ' . implode(', ', $group->operationIds);
}
Oblika operacije
Vsak MergePlanOperation ohrani dovolj konteksta za pregled in povrnitev.
$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
Izbori
Uporabite ChangeGroupSelection, ko UI pripravi skupine. Pri uporabi ali ustvarjanju artefaktov za povrnitev ga pretvorite v 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),
);
Izbrani rezultat je čist MergeResult, ki vsebuje samo izbrane operacije. Posredujete ga lahko v Merql::apply() ali Merql::applyGuarded().
Izbira tega, kar cilju manjka
Načrt vsebuje operacije obeh strani, saj rezultat združitve pretvori base v združeno stanje. Če cilj že vsebuje eno stran, izberite samo operacije, ki jih še nima. Za cilj, ki vsebuje theirs, na primer za živo zbirko podatkov, ki prejema popravke iz peskovniške kopije, so to vse operacije z virom ours ter posodobitve merged, ki združujejo spremembe stolpcev z obeh strani:
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),
);
Operacije z virom theirs in brisanja merged (vrstice, ki sta jih izbrisali obe strani) so v tem cilju že prisotni.
Načrt, ustvarjen iz združitve s konflikti, še vedno navaja operacijo za vsako vrstico v konfliktu, ki sta jo posodobili obe strani. Njene vrednosti rezultata v stolpcu v konfliktu vsebujejo vrednost ours, SelectedMergeResultFactory pa vrne čist rezultat za vsak izbor. Vrednosti conflictState operacije in skupine sprememb so tudi takrat clean (#9), zato sami preverite $plan->conflicts, kot je opisano zgoraj, ali razrešite konflikte z ConflictResolver in ustvarite načrt iz razrešenega rezultata z MergePlanBuilder. Za zapis izbora s predpogoji za žive vrstice glejte Zaščitena uporaba.
Serializacija
Načrti združevanja in izbori imajo stabilno serializacijo JSON. Serializirani načrt shranite, kadar mora poznejši korak uporabe uporabiti točno pregledani nabor operacij.
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),
);
Vzdevki posnetkov
Načrti združevanja uporabljajo kanonična imena tabel. Če se fizična imena tabel med okolji razlikujejo, jih pred načrtovanjem zajemite pod istim kanoničnim imenom.
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',
]));
Shema, shranjena v posnetku, uporablja kanonično ime tabele, hkrati pa ohranja stolpce, ključe, stolpce identitete, ključe vrstic in filtre fizične tabele.