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ę:
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:
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():
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:
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.
$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.
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:
// 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.