Pāriet uz saturu

Sapludināšanas plāni

MergeResult ir izpildāmais sapludināšanas rezultāts. MergePlan ir šī rezultāta pārskatāmā forma. Izmantojiet to, ja lietotnei pirms izmaiņu ierakstīšanas mērķa datubāzē ir jāparāda, jāiestudē, jāserializē vai selektīvi jāpiemēro datubāzes izmaiņas.

PHP
use Merql\Merql;

$plan = Merql::plan(
    id: 'plan-2026-06-06',
    base: 'base',
    ours: 'ours',
    theirs: 'theirs',
    metadata: ['sandbox_id' => 'ow_123'],
);

Merql::plan() ielādē trīs nosauktos momentuzņēmumus un sapludina tos kolonnu līmenī, tāpat kā Merql::merge(). Lai plānotu sapludināšanu, kurā TEXT un JSON kolonnām izmantota šūnu līmeņa sapludināšana, izveidojiet rezultātu paši un nododiet to MergePlanBuilder:

PHP
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);

Plānā ir:

  • tā izveidei izmantoto momentuzņēmumu nosaukumi,
  • darbību, konfliktu, shēmas neatbilstību, tabulu un grupu kopsavilkums,
  • stabili darbību ID,
  • stabili izmaiņu grupu ID,
  • rindu identitātes kolonnas un identitātes vērtības,
  • katras darbības bāzes, mūsu, viņu un rezultāta rindu vērtības,
  • neobligāti resurslietotnes metadati,
  • plāna jaucējvērtība,
  • shēmas versija.

Stabili ID

Darbību ID vienam un tam pašam darbības saturam ir deterministiski. Tos atvasina no tabulas nosaukuma, rindas atslēgas, darbības veida, darbības avota, mainītajām kolonnām un rezultāta vērtībām.

Izmaiņu grupu ID vienam un tam pašam grupas saturam ir deterministiski. Pēc noklusējuma plāna veidotājs katrai darbībai izveido atsevišķu darbību grupu. Resurslietotnes var izveidot lielākas, konkrētajai jomai pielāgotas grupas no darbību saraksta un serializēt tās tādā pašā DTO formā.

PHP
foreach ($plan->changeGroups as $group) {
    echo $group->id . ': ' . implode(', ', $group->operationIds);
}

Darbības struktūra

Katrs MergePlanOperation ietver pietiekami daudz konteksta pārskatīšanai un atcelšanai.

PHP
$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

Atlases

Izmantojiet ChangeGroupSelection, ja UI iestudē grupas. Pārveidojiet to par OperationSelection, kad lietojat izmaiņas vai ģenerējat atcelšanas artefaktus.

PHP
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),
);

Atlasītais rezultāts ir tīrs MergeResult, kurā ir tikai atlasītās darbības. To var nodot Merql::apply() vai Merql::applyGuarded().

Atlase tam, kā trūkst mērķa datubāzē

Plānā ir abu pušu darbības, jo sapludināšanas rezultāts pārveido bāzi sapludinātajā stāvoklī. Ja mērķa datubāzē jau ir viena puse, atlasiet tikai tās darbības, kuru tur vēl nav. Mērķim, kurā ir viņu versija, piemēram, reāllaika datubāzei, kurā jāsaņem smilškastes kopijas labojumi, tās ir visas darbības ar avotu ours, kā arī merged atjauninājumi, kuros apvienotas abu pušu kolonnu izmaiņas:

PHP
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),
);

Darbības ar avotu theirs un merged dzēšanas (rindas, ko izdzēsušas abas puses) jau ir iekļautas šajā mērķa datubāzē.

Plānā, kas izveidots no sapludināšanas ar konfliktiem, joprojām ir norādīta darbība katrai konfliktējošajai rindai, ko atjauninājušas abas puses. Tās rezultāta vērtībās konfliktējošajā kolonnā ir mūsu vērtība, un SelectedMergeResultFactory atgriež tīru rezultātu jebkurai atlasei. Darbības un izmaiņu grupas conflictState arī šādā gadījumā pašlaik ir clean (#9), tāpēc pārbaudiet $plan->conflicts paši, kā aprakstīts iepriekš, vai atrisiniet konfliktus ar ConflictResolver un izveidojiet plānu no atrisinātā rezultāta, izmantojot MergePlanBuilder. Skatiet Droša lietošana, lai lietotu atlasi ar reāllaika rindu priekšnosacījumiem.

Serializēšana

Sapludināšanas plāniem un atlasēm ir stabila JSON serializācija. Saglabājiet serializēto plānu, ja vēlākā izmaiņu lietošanas solī jāizmanto tieši tas pats pārskatītais darbību kopums.

PHP
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),
);

Nosaukumu aizstājvārdi momentuzņēmumiem

Sapludināšanas plānos tiek izmantoti kanoniskie tabulu nosaukumi. Ja fizisko tabulu nosaukumi dažādās vidēs atšķiras, pirms plānošanas saglabājiet tās ar vienādu kanonisko nosaukumu.

PHP
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',
]));

Momentuzņēmumā saglabātajā shēmā tiek izmantots kanoniskais tabulas nosaukums, vienlaikus saglabājot fiziskās tabulas kolonnas, atslēgas, identitātes kolonnas, rindu atslēgas un filtrus.