Preskočiť na obsah

Plány zlúčenia

MergeResult je spustiteľný výstup zlúčenia. MergePlan je kontrolovateľná podoba tohto výstupu. Použite ho, keď aplikácia potrebuje pred zápisom do cieľovej databázy zobraziť, pripraviť, serializovať alebo selektívne použiť zmeny v databáze.

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() načíta tri pomenované snímky a zlúči ich na úrovni stĺpcov, podobne ako Merql::merge(). Ak chcete naplánovať zlúčenie, ktoré používa zlúčenie na úrovni buniek pre stĺpce TEXT a JSON, vytvorte výsledok sami a odovzdajte ho do 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 obsahuje:

  • názvy snímok použité pri jeho vytvorení,
  • súhrn operácií, konfliktov, nezhôd schémy, tabuliek a skupín,
  • stabilné ID operácií,
  • stabilné ID skupín zmien,
  • stĺpce identity riadkov a hodnoty identity,
  • hodnoty riadkov zo základnej verzie, našej strany, druhej strany a výsledku pre každú operáciu,
  • voliteľné metadáta hostiteľskej aplikácie,
  • hash plánu,
  • verziu schémy.

Stabilné ID

ID operácií sú deterministické pre rovnaký obsah operácie. Odvodzujú sa od názvu tabuľky, kľúča riadka, typu operácie, zdroja operácie, zmenených stĺpcov a výsledných hodnôt.

ID skupín zmien sú deterministické pre rovnaký obsah skupiny. Predvolený tvorca vytvorí jednu skupinu operácií pre každú operáciu. Hostiteľské aplikácie môžu zo zoznamu operácií vytvárať väčšie skupiny špecifické pre danú doménu a serializovať ich v rovnakej podobe DTO.

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

Štruktúra operácie

Každý MergePlanOperation obsahuje dostatok kontextu na kontrolu a vrátenie zmien.

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

Výbery

Použite ChangeGroupSelection, keď UI pripravuje skupiny. Pri použití alebo generovaní artefaktov na vrátenie zmien ho preveďte na OperationSelection.

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

Vybraný výsledok je čistý MergeResult, ktorý obsahuje iba vybrané operácie. Možno ho odovzdať do Merql::apply() alebo Merql::applyGuarded().

Výber toho, čo v cieľovej databáze chýba

Plán obsahuje operácie z oboch strán, pretože výsledok zlúčenia prevedie základnú verziu do zlúčeného stavu. Ak cieľ už obsahuje jednu stranu, vyberte iba operácie, ktoré v ňom ešte nie sú. Ak cieľ obsahuje ich stranu, napríklad živá databáza preberajúca úpravy zo sandboxovej kópie, ide o každú operáciu so zdrojom ours a tiež o aktualizácie merged, ktoré spájajú zmeny stĺpcov z oboch strán:

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

Operácie so zdrojom theirs a odstránenia merged (riadky odstránené na oboch stranách) už v tomto cieli sú.

Plán vytvorený zo zlúčenia s konfliktmi stále uvádza operáciu pre každý konfliktný riadok, ktorý aktualizovali obe strany. Jeho výsledné hodnoty obsahujú našu hodnotu v konfliktnom stĺpci a SelectedMergeResultFactory vracia čistý výsledok pre každý výber. Hodnota conflictState operácie aj skupiny zmien je však stále clean (č. 9), preto si sami skontrolujte $plan->conflicts, ako je uvedené vyššie, alebo vyriešte konflikty pomocou ConflictResolver a vytvorte plán z vyriešeného výsledku pomocou MergePlanBuilder. Informácie o zápise výberu s predbežnými podmienkami pre živé riadky nájdete v príručke Riadené použitie.

Serializácia

Plány zlúčenia a výbery majú stabilnú serializáciu JSON. Ak má neskorší krok použitia pracovať s presnou skontrolovanou množinou operácií, uložte serializovaný plán.

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

Snímky s aliasmi

Plány zlúčenia používajú kanonické názvy tabuliek. Ak sa fyzické názvy tabuliek v rôznych prostrediach líšia, pred plánovaním ich zaznamenajte pod rovnakým kanonickým názvom.

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

Schéma uložená v snímke používa kanonický názov tabuľky a zároveň zachováva stĺpce, kľúče, stĺpce identity, kľúče riadkov a filtre fyzickej tabuľky.