
# 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()`:

```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)
```

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.

```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"
```

## 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:

```php
// 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:

- `NULL` kuni `NULL` = muutusi pole.
- `NULL` kuni `"hello"` = uuendus.
- `"hello"` kuni `NULL` = uuendus.
- `"1"` kuni `1` = 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](https://merql.inline0.dev/et/docs/merge/cell-level). 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.
