Fletning på kolonneniveau
Fletning på kolonneniveau er merqls største fordel frem for en naiv sammenligning på rækkeniveau. Når begge sider ændrer den samme række, sammenligner merql hver kolonne for sig i stedet for at markere hele rækken som en konflikt.
Problemet med fletning på rækkeniveau
Forestil dig en tabel af typen posts, hvor to personer redigerer den samme række:
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" }
En fletning på rækkeniveau registrerer, at begge sider har ændret rækken, og erklærer en konflikt. Men ændringerne overlapper slet ikke. Vores ændrede content, mens deres ændrede title og status.
Sådan løser fletning på kolonneniveau problemet
merql anvender de samme trevejsfletteregler på hver enkelt kolonne:
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
Resultat: { title: "New Title", content: "Body v2", status: "publish" }. Konfliktfri fletning.
Sådan fungerer det
Når ThreeWayMerge registrerer, at begge sider har opdateret den samme række, overlader den arbejdet til 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)
De samme regler gælder for hver kolonne:
| Base | Vores | Deres | Resultat |
|---|---|---|---|
| A | A | A | Behold base (ingen ændring) |
| A | A | B | Brug deres |
| A | B | A | Brug vores |
| A | B | B | Brug værdien (begge er enige) |
| A | B | C | Konflikt (forskellige værdier) |
Hvornår opstår der stadig konflikter
Der opstår en konflikt på kolonneniveau, når begge sider har ændret den samme kolonne til forskellige værdier:
Base: post #42 { title: "Hello" }
Ours: post #42 { title: "Welcome" }
Theirs: post #42 { title: "Greetings" }
Begge ændrede title til forskellige værdier. Det er en reel konflikt, der kræver en løsning.
$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"
Delvise konflikter
En enkelt række kan indeholde både konfliktfri fletninger og konflikter. Hvis én kolonne flettes uden konflikt, men en anden giver en konflikt, indeholder rækkens MergeOperation de flettede værdier for konfliktfri kolonner og vores værdi som standard for kolonner med konflikter. Konflikten rapporteres stadig separat.
Base: { title: "Hello", content: "Body", status: "draft" }
Ours: { title: "Welcome", content: "Body v2", status: "draft" }
Theirs: { title: "Greetings", content: "Body", status: "publish" }
Her giver title en konflikt (begge ændrede den forskelligt), content flettes uden konflikt (kun vores side ændrede den), og status flettes uden konflikt (kun deres side ændrede den). Handlingen indeholder:
// values: { title: "Welcome", content: "Body v2", status: "publish" }
// One conflict on the "title" column.
Værdisammenligning
Kolonneværdier sammenlignes som strenge efter konvertering. NULL er en særskilt værdi:
NULLtilNULL= ingen ændring.NULLtil"hello"= opdatering."hello"tilNULL= opdatering."1"til1= ingen ændring (begge konverteres til strengen"1").
Dette svarer til MerQL-forbindelsesadapterens hentningssemantik: alle databaseværdier returneres som strenge (eller NULL).
Fletning på celleniveau
Hvis fletning på kolonneniveau stadig giver en konflikt (begge sider har ændret den samme kolonne til forskellige værdier), kan merql gå et niveau dybere med fletning på celleniveau. Det gælder TEXT-kolonner (linjevis difference) og JSON-kolonner (nøglevis difference) og løser tilfælde, hvor begge sider har redigeret forskellige dele af den samme kolonneværdi.