Pereiti prie turinio

Sujungimas stulpelių lygmeniu

Sujungimas stulpelių lygmeniu yra pagrindinis merql pranašumas prieš naivų palyginimą eilučių lygmeniu. Kai abi pusės pakeičia tą pačią eilutę, merql lygina kiekvieną stulpelį atskirai, užuot paskelbęs konfliktu visą eilutę.

Eilučių lygmens sujungimo problema

Tarkime, posts lentelėje du žmonės redaguoja tą pačią eilutę:

Kodas
Base:    post #42  { title: "Hello",     content: "Body",    status: "draft"   }
Ours:    post #42  { title: "Hello",     content: "Body v2", status: "draft"   }
Theirs:  post #42  { title: "New Title", content: "Body",    status: "publish" }

Eilučių lygmens sujungimas nustato, kad abi pusės pakeitė eilutę, ir paskelbia konfliktą. Tačiau pakeitimai visiškai nesutampa. Mes redagavome content, o jie redagavo title ir status.

Kaip sujungimas stulpelių lygmeniu išsprendžia problemą

merql kiekvienam stulpeliui atskirai taiko tas pačias trijų krypčių sujungimo taisykles:

Kodas
title:   base="Hello", ours="Hello",  theirs="New Title"  -> accept theirs
content: base="Body",  ours="Body v2", theirs="Body"      -> accept ours
status:  base="draft", ours="draft",  theirs="publish"    -> accept theirs

Rezultatas: { title: "New Title", content: "Body v2", status: "publish" }. Sklandus sujungimas, be konflikto.

Kaip tai veikia

Kai ThreeWayMerge aptinka, kad abi pusės atnaujino tą pačią eilutę, jis perduoda darbą ColumnMerge::merge():

PHP
use Merql\Merge\ColumnMerge;

$result = ColumnMerge::merge(
    table: 'posts',
    rowKey: '42',
    base: ['title' => 'Hello', 'content' => 'Body', 'status' => 'draft'],
    ours: ['title' => 'Hello', 'content' => 'Body v2', 'status' => 'draft'],
    theirs: ['title' => 'New Title', 'content' => 'Body', 'status' => 'publish'],
);

// $result['values']    -> merged column values
// $result['conflicts'] -> list of Conflict objects (empty if clean)

Kiekvienam stulpeliui taikomos tos pačios taisyklės:

Bazė Mūsų pusė Jų pusė Rezultatas
A A A Palikti bazinę reikšmę (nepakeista)
A A B Priimti jų reikšmę
A B A Priimti mūsų reikšmę
A B B Priimti (abi pusės sutaria)
A B C Konfliktas (skirtingos reikšmės)

Kada vis dar kyla konfliktų

Konfliktas stulpelių lygmeniu kyla, kai abi pusės pakeičia tą patį stulpelį į skirtingas reikšmes:

Kodas
Base:    post #42  { title: "Hello" }
Ours:    post #42  { title: "Welcome" }
Theirs:  post #42  { title: "Greetings" }

Abi pusės pakeitė title į skirtingas reikšmes. Tai tikras konfliktas, kurį reikia išspręsti.

PHP
$result = ColumnMerge::merge(
    'posts', '42',
    ['title' => 'Hello'],
    ['title' => 'Welcome'],
    ['title' => 'Greetings'],
);

// $result['conflicts'] contains one Conflict:
//   table: "posts", column: "title"
//   oursValue: "Welcome", theirsValue: "Greetings", baseValue: "Hello"

Daliniai konfliktai

Vienoje eilutėje gali būti ir sklandžiai sujungtų pakeitimų, ir konfliktų. Jei vienas stulpelis sujungiamas sklandžiai, o kitame kyla konfliktas, eilutės MergeOperation yra sujungtos reikšmės sklandžiai sujungtuose stulpeliuose ir mūsų reikšmė (pagal numatytąją nuostatą) konfliktuojančiuose stulpeliuose. Apie konfliktą vis tiek pranešama atskirai.

Kodas
Base:    { title: "Hello", content: "Body",    status: "draft" }
Ours:    { title: "Welcome", content: "Body v2", status: "draft" }
Theirs:  { title: "Greetings", content: "Body",    status: "publish" }

Čia title konfliktuoja (abi pusės jį pakeitė skirtingai), content sujungiamas sklandžiai (pakeitė tik mūsų pusė), o status sujungiamas sklandžiai (pakeitė tik jų pusė). Operacijoje pateikiama:

PHP
// values: { title: "Welcome", content: "Body v2", status: "publish" }
// One conflict on the "title" column.

Reikšmių palyginimas

Stulpelių reikšmės po konvertavimo palyginamos kaip eilutės. NULL laikoma atskira reikšme:

  • NULL į NULL = nėra pakeitimo.
  • NULL į "hello" = atnaujinimas.
  • "hello" į NULL = atnaujinimas.
  • "1" į 1 = nėra pakeitimo (abi reikšmės konvertuojamos į eilutę "1").

Tai atitinka MerQL ryšio adapterio gavimo semantiką: visos duomenų bazės reikšmės grąžinamos kaip eilutės (arba NULL).

Sujungimas langelio lygmeniu

Kai sujungiant stulpelių lygmeniu vis tiek kyla konfliktas (abi pusės pakeitė tą patį stulpelį į skirtingas reikšmes), merql gali leistis vienu lygmeniu giliau ir atlikti sujungimą langelio lygmeniu. Tai taikoma TEXT stulpeliams (palyginamos eilutės po eilutės) ir JSON stulpeliams (palyginami raktai po rakto), taip išsprendžiant atvejus, kai abi pusės redagavo skirtingas to paties stulpelio reikšmės dalis.