Liitmisplaanid
MergeResult on liitmise käivitatav väljund. MergePlan on selle väljundi kontrollitav vorm. Kasutage seda siis, kui rakendus peab enne muudatuste sihtandmebaasi kirjutamist neid kuvama, ette valmistama, serialiseerima või valikuliselt rakendama.
use Merql\Merql;
$plan = Merql::plan(
id: 'plan-2026-06-06',
base: 'base',
ours: 'ours',
theirs: 'theirs',
metadata: ['sandbox_id' => 'ow_123'],
);
Merql::plan() laadib kolm nimega hetktõmmist ja liidab need veerutasemel, nagu Merql::merge(). Lahtritaseme liitmist TEXT- ja JSON-veergude jaoks kasutava plaani koostamiseks looge tulemus ise ja edastage see objektile 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);
Plaan sisaldab järgmist:
- selle koostamiseks kasutatud hetktõmmiste nimed,
- tehete, konfliktide, skeemierinevuste, tabelite ja rühmade kokkuvõte,
- stabiilsed tehte-ID-d,
- stabiilsed muudatuste rühma ID-d,
- rea identiteediveerud ja identiteediväärtused,
- iga tehte rea alus-, meie, nende ja tulemusväärtused,
- hostrakenduse valikulised metaandmed,
- plaani räsi,
- skeemi versioon.
Stabiilsed ID-d
Tehte ID-d on sama tehte sisu korral deterministlikud. Need tuletatakse tabeli nimest, reavõtmest, tehte tüübist, tehte allikast, muudetud veergudest ja tulemusväärtustest.
Muudatuste rühma ID-d on sama rühma sisu korral deterministlikud. Vaikimisi koostaja loob iga tehte jaoks eraldi tehte rühma. Hostrakendused saavad tehete loendist koostada suuremaid valdkonnapõhiseid rühmi ja serialiseerida need sama DTO-kujuga.
foreach ($plan->changeGroups as $group) {
echo $group->id . ': ' . implode(', ', $group->operationIds);
}
Tehte kuju
Iga MergePlanOperation sisaldab ülevaatuseks ja tagasipööramiseks piisavalt konteksti.
$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
Valikud
Kasutage ChangeGroupSelection, kui UI valmistab rühmad ette. Rakendamisel või tagasipööramise artefaktide loomisel teisendage see objektiks 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),
);
Valitud tulemus on puhas MergeResult, mis sisaldab ainult valitud tehteid. Selle saab edastada objektile Merql::apply() või Merql::applyGuarded().
Sihtandmebaasist puuduvate muudatuste valimine
Plaan sisaldab mõlema poole tehteid, sest liitmise tulemus muudab aluse liidetud olekuks. Kui sihtandmebaas sisaldab juba ühe poole muudatusi, valige ainult need tehted, mida seal veel pole. Kui sihtandmebaas sisaldab nende muudatusi, näiteks kui aktiivne andmebaas saab liivakastikoopia muudatused, hõlmab see kõiki tehteid, mille allikas on ours, ning ka tehteid merged, mis ühendavad mõlema poole veerumuudatused:
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),
);
Selle sihtandmebaasi olemasolevate muudatuste hulka kuuluvad need, mille allikas on theirs, ning tehted merged (read, mille mõlemad pooled kustutasid).
Konfliktidega liitmisest koostatud plaan loetleb endiselt iga konfliktse rea kohta tehte, kui mõlemad pooled seda uuendasid. Selle tulemusväärtused sisaldavad konfliktse veeru puhul meie väärtust ja SelectedMergeResultFactory tagastab iga valiku korral puhta tulemuse. Tehte ja muudatuste rühma conflictState on praegu ka sellisel juhul clean (#9), seega kontrollige ise ülaltoodud viisil $plan->conflicts või lahendage konfliktid ConflictResolver abil ja koostage plaan lahendatud tulemusest, kasutades MergePlanBuilder. Vaadake jaotist Kaitstud rakendamine, kus kirjeldatakse valiku kirjutamist koos aktiivse rea eeltingimustega.
Järjestamine
Liitmisplaanide ja valikute serialiseerimine JSON on stabiilne. Salvestage serialiseeritud plaan, kui hilisem rakendamine peab kasutama täpselt üle vaadatud tehete kogumit.
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),
);
Teise nimega hetktõmmised
Liitmisplaanid kasutavad kanoonilisi tabelinimesid. Kui füüsilised tabelinimed on keskkondades erinevad, jäädvustage tabelid enne plaani koostamist sama kanoonilise nime all.
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',
]));
Hetktõmmises salvestatud skeem kasutab kanoonilist tabelinime, säilitades samal ajal füüsilise tabeli veerud, võtmed, identiteediveerud, reavõtmed ja filtrid.