Ugrás a tartalomhoz

Oszlopszintű egyesítés

Az oszlopszintű egyesítés a merql legfőbb előnye a naiv, soronkénti összehasonlítással szemben. Ha mindkét oldal módosítja ugyanazt a sort, a merql az egész sor ütközésként való megjelölése helyett külön-külön hasonlítja össze az oszlopokat.

A soronkénti egyesítés problémája

Tegyük fel, hogy egy posts táblában két ember ugyanazt a sort szerkeszti:

Kód
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" }

A soronkénti egyesítés észleli, hogy mindkét oldal módosította a sort, és ütközést állapít meg. A módosítások azonban egyáltalán nem fedik egymást. Az ours a(z) content értékét, a theirs pedig a(z) title és status értékét módosította.

Az ütközés feloldása oszlopszintű egyesítéssel

A merql ugyanazokat a háromutas egyesítési szabályokat alkalmazza minden egyes oszlopra:

Kód
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

Eredmény: { title: "New Title", content: "Body v2", status: "publish" }. Ütközésmentes, tiszta egyesítés.

Működés

Amikor a(z) ThreeWayMerge észleli, hogy mindkét oldal módosította ugyanazt a sort, átadja a feladatot a(z) ColumnMerge::merge() számára:

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)

Minden oszlopra ugyanazok a szabályok érvényesek:

Base Ours Theirs Eredmény
A A A Az alap megtartása (nincs változás)
A A B A theirs elfogadása
A B A Az ours elfogadása
A B B Elfogadás (mindkét oldal egyetért)
A B C Ütközés (eltérő értékek)

Mikor fordul elő továbbra is ütközés

Oszlopszintű ütközés akkor fordul elő, ha mindkét oldal ugyanazt az oszlopot módosítja, de eltérő értékre:

Kód
Base:    post #42  { title: "Hello" }
Ours:    post #42  { title: "Welcome" }
Theirs:  post #42  { title: "Greetings" }

Mindkét oldal módosította a(z) title értékét, de eltérő eredményre. Ez valódi ütközés, amely feloldást igényel.

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"

Részleges ütközések

Egy soron belül lehetnek tisztán egyesíthető értékek és ütközések is. Ha az egyik oszlop tisztán egyesül, a másik pedig ütközik, a sorhoz tartozó MergeOperation a tisztán egyesíthető oszlopok egyesített értékeit, az ütköző oszlopoknál pedig alapértelmezés szerint az ours értékét tartalmazza. Az ütközést ettől függetlenül külön jelzi.

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

Itt a(z) title ütközik (mindkét oldal eltérően módosította), a(z) content tisztán egyesül (csak az ours módosította), a(z) status pedig tisztán egyesül (csak a theirs módosította). A művelet tartalmazza:

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

Értékek összehasonlítása

Az oszlopértékeket konvertálás után karakterláncként hasonlítja össze. A NULL különálló értéknek számít:

  • NULL és NULL között = nincs változás.
  • NULL és "hello" között = módosítás.
  • "hello" és NULL között = módosítás.
  • "1" és 1 között = nincs változás (mindkettő a(z) "1" karakterlánccá alakul).

Ez megfelel a(z) MerQL kapcsolatadapter adatlekérési szemantikájának: az adatbázis értékei karakterláncként (vagy NULL-ként) érkeznek vissza.

Cellaszintű egyesítés

Ha az oszlopszintű egyesítés továbbra is ütközést eredményez (mindkét oldal ugyanazt az oszlopot módosította eltérő értékre), a merql egy szinttel mélyebbre is mehet a cellaszintű egyesítéssel. Ez a TEXT oszlopokra (soronkénti különbségvizsgálat) és az JSON oszlopokra (kulcsonkénti különbségvizsgálat) vonatkozik, és azokat az eseteket oldja meg, amikor mindkét oldal ugyanazon oszlopérték különböző részeit szerkesztette.