
# Sapludināšana kolonnu līmenī

Sapludināšana kolonnu līmenī ir merql galvenā priekšrocība salīdzinājumā ar vienkāršu rindu līmeņa salīdzināšanu. Ja abas puses maina vienu un to pašu rindu, merql salīdzina katru kolonnu atsevišķi, nevis atzīmē visu rindu kā konfliktu.

## Rindu līmeņa sapludināšanas problēma

Iedomājieties `posts` tabulu, kurā divi cilvēki rediģē vienu un to pašu rindu:

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

Rindu līmeņa sapludināšana konstatē, ka abas puses mainījušas rindu, un paziņo par konfliktu. Taču izmaiņas nemaz nepārklājas. Mēs rediģējām `content`, viņi — `title` un `status`.

## Kā to atrisina sapludināšana kolonnu līmenī

merql piemēro vienus un tos pašus trīsvirzienu sapludināšanas noteikumus katrai kolonnai atsevišķi:

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

Rezultāts: `{ title: "New Title", content: "Body v2", status: "publish" }`. Tīra sapludināšana bez konflikta.

## Kā tas darbojas

Kad `ThreeWayMerge` konstatē, ka abas puses atjauninājušas vienu un to pašu rindu, tas nodod darbu `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)
```

Katrai kolonnai piemēro vienus un tos pašus noteikumus:

| Bāze | Mūsu | Viņu | Rezultāts |
|---|---|---|---|
| A | A | A | Saglabāt bāzes vērtību (bez izmaiņām) |
| A | A | B | Pieņemt viņu vērtību |
| A | B | A | Pieņemt mūsu vērtību |
| A | B | B | Pieņemt (abas puses vienojas) |
| A | B | C | **Konflikts** (atšķirīgas vērtības) |

## Kad konflikti tomēr rodas

Konflikts kolonnu līmenī rodas, ja abas puses mainījušas vienu un to pašu kolonnu uz atšķirīgām vērtībām:

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

Abas puses mainīja `title` uz atšķirīgām vērtībām. Tas ir īsts konflikts, kas jāatrisina.

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

## Daļēji konflikti

Vienā rindā var būt gan tīras sapludināšanas, gan konflikti. Ja viena kolonna tiek sapludināta bez konfliktiem, bet citā rodas konflikts, rindas `MergeOperation` satur sapludinātās vērtības kolonnās bez konfliktiem un mūsu vērtību (pēc noklusējuma) konfliktējošajās kolonnās. Par konfliktu tiek ziņots atsevišķi.

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

Šeit `title` ir konflikts (abas puses to mainīja atšķirīgi), `content` saplūst bez konflikta (mainījām tikai mēs), bet `status` saplūst bez konflikta (mainīja tikai viņi). Darbība ietver:

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

## Vērtību salīdzināšana

Kolonnu vērtības pēc pārveidošanas tiek salīdzinātas kā virknes. `NULL` ir atšķirīga vērtība:

- `NULL` uz `NULL` = bez izmaiņām.
- `NULL` uz `"hello"` = atjauninājums.
- `"hello"` uz `NULL` = atjauninājums.
- `"1"` uz `1` = bez izmaiņām (abas vērtības pārveidotas par virkni `"1"`).

Tas atbilst MerQL savienojuma adaptera datu izgūšanas semantikai: visas datubāzes vērtības tiek atgrieztas kā virknes (vai NULL).

## Sapludināšana šūnu līmenī

Ja sapludināšana kolonnu līmenī joprojām rada konfliktu (abas puses mainījušas vienu un to pašu kolonnu uz atšķirīgām vērtībām), merql var iedziļināties vēl vienu līmeni — [šūnu līmeņa sapludināšanā](https://merql.inline0.dev/lv/docs/merge/cell-level). To piemēro TEXT kolonnām (rindu pa rindai diff) un JSON kolonnām (atslēgu pa atslēgai diff), atrisinot gadījumus, kuros abas puses rediģējušas dažādas viena un tā paša kolonnas vērtības daļas.
