Preskoči na vsebino

Združevanje na ravni stolpcev

Združevanje na ravni stolpcev je glavna prednost merql pred preprosto primerjavo na ravni vrstic. Ko obe strani spremenita isto vrstico, merql primerja vsak stolpec posebej, namesto da bi celotno vrstico označil kot spor.

Težava pri združevanju na ravni vrstic

Oglejmo si tabelo posts, v kateri dve osebi urejata isto vrstico:

Koda
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" }

Združevanje na ravni vrstic zazna, da sta obe strani spremenili vrstico, in razglasi spor. Toda spremembe se sploh ne prekrivajo. Mi smo uredili content, oni pa title in status.

Kako združevanje na ravni stolpcev razreši težavo

merql za vsak stolpec posebej uporabi ista trosmerna pravila združevanja:

Koda
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

Rezultat: { title: "New Title", content: "Body v2", status: "publish" }. Čista združitev brez sporov.

Kako deluje

Ko ThreeWayMerge zazna, da sta obe strani posodobili isto vrstico, delo prepusti ColumnMerge::merge():

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)

Za vsak stolpec veljajo ista pravila:

Osnova Naši Njihovi Rezultat
A A A Ohranimo osnovo (brez sprememb)
A A B Sprejmemo njihovega
A B A Sprejmemo našega
A B B Sprejmemo (oba se strinjata)
A B C Spor (različni vrednosti)

Kdaj še vedno pride do sporov

Spor na ravni stolpca nastane, kadar obe strani spremenita isti stolpec na različni vrednosti:

Koda
Base:    post #42  { title: "Hello" }
Ours:    post #42  { title: "Welcome" }
Theirs:  post #42  { title: "Greetings" }

Obe strani sta spremenili title na različni vrednosti. To je dejanski spor, ki ga je treba razrešiti.

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"

Delni spori

V eni vrstici so lahko hkrati čisto združene vrednosti in spori. Če se en stolpec združi brez težav, pri drugem pa pride do spora, MergeOperation za vrstico vsebuje združene vrednosti čistih stolpcev in našo vrednost (privzeto) za stolpce s spori. Spor je še vedno naveden ločeno.

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

Tukaj je pri title prišlo do spora (obe strani sta ga različno spremenili), content je bil čisto združen (spremenila ga je samo naša stran), status pa prav tako (spremenila ga je samo njihova stran). Operacija vsebuje:

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

Primerjava vrednosti

Vrednosti stolpcev se po pretvorbi primerjajo kot nizi. NULL je ločena vrednost:

  • NULL do NULL = brez spremembe.
  • NULL do "hello" = posodobitev.
  • "hello" do NULL = posodobitev.
  • "1" do 1 = brez spremembe (oboje se pretvori v niz "1").

To ustreza semantiki pridobivanja podatkov adapterja povezave MerQL: vse vrednosti podatkovne zbirke so vrnjene kot nizi (ali NULL).

Združevanje na ravni celic

Če pri združevanju na ravni stolpcev še vedno pride do spora (obe strani sta isti stolpec spremenili na različni vrednosti), lahko merql združevanje poglobi na združevanje na ravni celic. To velja za stolpce TEXT (razlike po vrsticah) in JSON (razlike po ključih) ter razreši primere, ko sta obe strani spremenili različne dele vrednosti istega stolpca.