Veerutaseme liitmine
Veerutaseme liitmine on merqli peamine eelis lihtsa reataseme võrdluse ees. Kui mõlemad pooled muudavad sama rida, võrdleb merql iga veergu eraldi, selle asemel et märkida kogu rida konfliktseks.
Reataseme liitmise probleem
Vaatleme tabelit posts, kus kaks inimest muudavad sama rida:
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" }
Reataseme liitmine tuvastab, et mõlemad pooled muutsid rida, ja kuulutab välja konflikti. Muudatused aga ei kattu üldse. Meie muutsime content, nemad muutsid title ja status.
Kuidas veerutaseme liitmine probleemi lahendab
merql rakendab igale veerule eraldi samu kolme osapoole liitmisreegleid:
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
Tulemus: { title: "New Title", content: "Body v2", status: "publish" }. Puhas liitmine, konflikti pole.
Kuidas see töötab
Kui ThreeWayMerge tuvastab, et mõlemad pooled uuendasid sama rida, delegeerib see töö objektile 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)
Iga veeru puhul kehtivad samad reeglid:
| Alus | Meie | Nende | Tulemus |
|---|---|---|---|
| A | A | A | Jäta alusväärtus alles (muudatusi pole) |
| A | A | B | Võta vastu nende väärtus |
| A | B | A | Võta vastu meie väärtus |
| A | B | B | Võta vastu (mõlemad nõustuvad) |
| A | B | C | Konflikt (erinevad väärtused) |
Millal konfliktid siiski tekivad
Veerutaseme konflikt tekib siis, kui mõlemad pooled muutsid sama veeru väärtuseks erineva väärtuse:
Base: post #42 { title: "Hello" }
Ours: post #42 { title: "Welcome" }
Theirs: post #42 { title: "Greetings" }
Mõlemad muutsid välja title, kuid eri väärtuseks. See on tegelik konflikt, mis vajab lahendamist.
$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"
Osalised konfliktid
Ühes reas võib olla nii puhtaid liitmisi kui ka konflikte. Kui üks veerg liidetakse puhtalt, kuid teises tekib konflikt, sisaldab rea MergeOperation puhtalt liidetud veergude väärtusi ja konfliktsete veergude puhul vaikimisi meie väärtust. Konfliktist teatatakse eraldi.
Base: { title: "Hello", content: "Body", status: "draft" }
Ours: { title: "Welcome", content: "Body v2", status: "draft" }
Theirs: { title: "Greetings", content: "Body", status: "publish" }
Siin on välja title konfliktne (mõlemad muutsid seda eri viisil), content liidetakse puhtalt (muutsime ainult meie) ja status liidetakse puhtalt (muutsid ainult nemad). Tehe sisaldab järgmist:
// values: { title: "Welcome", content: "Body v2", status: "publish" }
// One conflict on the "title" column.
Väärtuste võrdlus
Veeru väärtusi võrreldakse pärast teisendamist stringidena. NULL on eraldi väärtus:
NULLkuniNULL= muutusi pole.NULLkuni"hello"= uuendus."hello"kuniNULL= uuendus."1"kuni1= muutusi pole (mõlemad teisendatakse stringiks"1").
See vastab ühendusadapteri MerQL andmete laadimise semantikale: kõik andmebaasi väärtused tagastatakse stringidena (või väärtusena NULL).
Lahtritaseme liitmine
Kui veerutaseme liitmisel tekib endiselt konflikt (mõlemad pooled muutsid sama veeru eri väärtuseks), saab merql minna veel ühe taseme võrra sügavamale, kasutades lahtritaseme liitmist. See kehtib TEXT-veergude puhul (ridade kaupa diff) ja JSON veergude puhul (võtmete kaupa diff), lahendades olukorrad, kus pooled muutsid sama veeruväärtuse eri osi.