Saraketason yhdistäminen
Saraketason yhdistäminen on merqlin tärkein etu verrattuna yksinkertaiseen rivitason vertailuun. Kun molemmat puolet muuttavat samaa riviä, merql vertaa kutakin saraketta erikseen eikä merkitse koko riviä ristiriidaksi.
Rivitason yhdistämisen ongelma
Tarkastellaan posts-taulua, jossa kaksi henkilöä muokkaa samaa riviä:
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" }
Rivitason yhdistäminen havaitsee, että molemmat puolet muuttivat riviä, ja ilmoittaa ristiriidan. Muutokset eivät kuitenkaan mene päällekkäin. Ours muokkasi kohdetta content, theirs kohteita title ja status.
Näin saraketason yhdistäminen ratkaisee ongelman
merql soveltaa samoja kolmen osapuolen yhdistämissääntöjä kuhunkin sarakkeeseen erikseen:
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
Tulos: { title: "New Title", content: "Body v2", status: "publish" }. Yhdistäminen onnistui ilman ristiriitaa.
Näin se toimii
Kun ThreeWayMerge havaitsee, että molemmat puolet päivittivät saman rivin, se siirtää tehtävän kohteelle 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)
Kuhunkin sarakkeeseen sovelletaan samoja sääntöjä:
| Lähtötila | Ours | Theirs | Tulos |
|---|---|---|---|
| A | A | A | Säilytä lähtötila (ei muutosta) |
| A | A | B | Hyväksy theirs |
| A | B | A | Hyväksy ours |
| A | B | B | Hyväksy (molemmat samaa mieltä) |
| A | B | C | Ristiriita (eri arvot) |
Milloin ristiriitoja silti syntyy
Saraketason ristiriita syntyy, kun molemmat puolet muuttavat saman sarakkeen eri arvoiksi:
Base: post #42 { title: "Hello" }
Ours: post #42 { title: "Welcome" }
Theirs: post #42 { title: "Greetings" }
Molemmat muuttivat sarakkeen title eri arvoksi. Kyseessä on todellinen ristiriita, joka vaatii ratkaisun.
$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"
Osittaiset ristiriidat
Yhdellä rivillä voi olla sekä puhtaita yhdistämisiä että ristiriitoja. Jos yksi sarake yhdistyy puhtaasti mutta toisessa on ristiriita, rivin MergeOperation sisältää puhtaasti yhdistettyjen sarakkeiden arvot ja ristiriitaisten sarakkeiden arvona meidän arvomme (oletuksena). Ristiriita ilmoitetaan silti erikseen.
Base: { title: "Hello", content: "Body", status: "draft" }
Ours: { title: "Welcome", content: "Body v2", status: "draft" }
Theirs: { title: "Greetings", content: "Body", status: "publish" }
Tässä title aiheuttaa ristiriidan (molemmat muuttivat sitä eri tavalla), content yhdistyy puhtaasti (vain meidän puolemme muuttui) ja status yhdistyy puhtaasti (vain heidän puolensa muuttui). Toiminto sisältää:
// values: { title: "Welcome", content: "Body v2", status: "publish" }
// One conflict on the "title" column.
Arvojen vertailu
Sarakkeiden arvoja verrataan merkkijonoina tyyppimuunnoksen jälkeen. NULL on eri arvo:
NULL–NULL= ei muutosta.NULL–"hello"= päivitys."hello"–NULL= päivitys."1"–1= ei muutosta (molemmat muunnetaan merkkijonoksi"1").
Tämä vastaa MerQL-yhteyssovittimen noutosemantiikkaa: kaikki tietokanta-arvot palautetaan merkkijonoina (tai NULL-arvona).
Solutason yhdistäminen
Jos saraketason yhdistäminen tuottaa silti ristiriidan (molemmat puolet muuttivat saman sarakkeen eri arvoon), merql voi mennä vielä yhden tason syvemmälle solutason yhdistämisellä. Tätä sovelletaan TEXT-sarakkeisiin (rivikohtainen diff) ja JSON-sarakkeisiin (avainkohtainen diff), jolloin ratkaistaan tapaukset, joissa molemmat puolet muokkasivat saman sarakearvon eri osia.