
# Úvod

merql je čistá knižnica PHP na trojstranné zlúčenie stavu databázy. Vytvára snímky tabuliek, počíta množiny zmien medzi snímkami, porovnáva dve množiny zmien so spoločným základom a zisťuje konflikty na úrovni stĺpcov. Používa rovnaký algoritmus ako git pri zdrojových súboroch, ale pracuje s riadkami a stĺpcami namiesto riadkov textu.

Bez externých nástrojov. Podporuje MySQL a SQLite prostredníctvom vymeniteľných adaptérov pripojenia a ovládačov dialektov.

## Rýchly príklad

Zlúčenie potrebuje tri stavy tých istých údajov: base, z ktorého vychádzali obe kópie, a dve kópie po ich nezávislých zmenách. V tomto príklade bola testovacia kópia vytvorená z produkčnej databázy a odvtedy sa obe upravovali.

```php
use Merql\Connection;
use Merql\Merql;

$live    = Connection::sqlite('/data/live.sqlite');
$sandbox = Connection::sqlite('/data/sandbox.sqlite');

// Base: live at the moment the sandbox was copied from it.
Merql::init($live);
Merql::snapshot('base');

// ... copy live.sqlite to sandbox.sqlite, then both databases change ...

// Ours: the sandbox with our edits. Theirs: live with its own changes.
Merql::init($sandbox);
Merql::snapshot('ours');
Merql::init($live);
Merql::snapshot('theirs');

$result = Merql::merge('base', 'ours', 'theirs');

if ($result->isClean()) {
    foreach ($result->operations() as $operation) {
        echo "{$operation->type} {$operation->table} #{$operation->rowKey} ({$operation->source})\n";
    }
} else {
    echo "Conflicts: {$result->conflictCount()}\n";
}
```

Každá snímka sa vytvorí z databázy, ktorá obsahuje príslušný stav. Vytvorenie všetkých troch snímok postupne z jednej databázy nepredstavuje dve rozvetvené kópie: theirs by už obsahoval zmeny ours a každý riadok vložený v ours by bol nahlásený ako konflikt `insert_insert`.

Výsledok obsahuje operácie, ktoré prevedú base na zlúčený stav, zozbierané z oboch strán a označené zdrojom (`ours`, `theirs` alebo `merged`). Ak chcete zapísať zmeny testovacieho prostredia do produkcie, použite [Kontrolované použitie](https://merql.inline0.dev/sk/docs/apply/guarded) iba pre operácie, ktoré v produkcii ešte chýbajú.

Alebo z CLI, ktorá sa pripája k databáze pomenovanej v `MERQL_DB_DSN` pre každý `snapshot`:

```bash
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot base
# ... copy live.sqlite to sandbox.sqlite, then both databases change ...
MERQL_DB_DSN="sqlite:/data/sandbox.sqlite" vendor/bin/merql snapshot ours
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot theirs

vendor/bin/merql merge base ours theirs --dry-run
```

## Prečo merql

Väčšina databázových nástrojov na porovnávanie stavov pracuje na úrovni riadkov: ak sa medzi dvoma verziami líši ktorýkoľvek stĺpec v riadku, celý riadok sa označí ako konflikt. To vedie k falošným konfliktom, keď dvaja ľudia upravia rôzne stĺpce toho istého riadka.

merql vykonáva zlúčenie na úrovni stĺpcov. Ak jedna strana zmenila `title` a druhá `status`, tieto zmeny sa zlúčia bez konfliktu. Konflikt sa nahlási iba vtedy, keď obe strany zmenia ten istý stĺpec na rôzne hodnoty.

Pri stĺpcoch TEXT a JSON môže merql zájsť o úroveň nižšie a zlúčiť obsah jednotlivých buniek. Dve úpravy rôznych riadkov textového stĺpca alebo rôznych kľúčov stĺpca JSON sa dajú zlúčiť rovnakým trojstranným algoritmom. Zlučovanie na úrovni buniek je voliteľné: odovzdajte `CellMergeConfig` do `ThreeWayMerge`. Fasáda `Merql` a príkaz CLI vykonávajú zlúčenie iba na úrovni stĺpcov. Pozrite si [Zlučovanie na úrovni buniek](https://merql.inline0.dev/sk/docs/merge/cell-level).

## Model zlúčenia

```
         Base (snapshot at fork time)
        /                              \
   Ours (one copy's changes)            Theirs (the other copy's changes)
        \                              /
         --------- MERGE ----------
                     |
              Merged result
              + conflicts (if any)
```

Tri stavy, rovnako ako v git. Base je spoločný predok. Ours a theirs sú dve kópie po rozvetvení, pričom každá sa zachytáva z vlastnej databázy. Pravidlá zlúčenia zaobchádzajú s oboma stranami rovnako. Ich názvy sa objavujú v `source` každej operácie, v typoch konfliktov (`update_delete` znamená, že ours aktualizovalo riadok a theirs ho odstránilo) a v pravidlách riešenia `OursWins` a `TheirsWins`. Bez spoločného základu nemožno rozlíšiť „pridané“ od „nezmenené“.

Zlúčenie samo nič nezapisuje. Jeho operácie transformujú base na zlúčený stav, preto ich `Merql::apply()` možno vykonať bez problémov iba v databáze, ktorá stále obsahuje base. Ak chcete preniesť zmeny jednej strany do databázy, ktorá už obsahuje zmeny druhej strany, napríklad presunúť úpravy testovacieho prostredia do produkcie, použite iba operácie, ktoré jej chýbajú; pozrite si [Kontrolované použitie](https://merql.inline0.dev/sk/docs/apply/guarded).

## Požiadavky

- PHP 8.2 alebo novší.
- `ext-mbstring` a `ext-zlib`, ktoré vyžaduje závislosť `pitmaster/pitmaster` poskytujúca rozdiely v texte.
- Rozšírenie databázy pre používaný adaptér: `ext-pdo` s `ext-pdo_sqlite` alebo `ext-pdo_mysql`, prípadne `ext-mysqli`. `composer.json` merql iba odporúča `ext-pdo` a `ext-mysqli`, preto ich Composer nekontroluje.
- Databáza MySQL alebo SQLite. Ostatné databázové systémy vyžadujú vlastný [ovládač](https://merql.inline0.dev/sk/docs/apply/drivers).

## Čo to nie je

merql nie je nástroj na migráciu schémy. nereplikuje databázy ani ich nesynchronizuje v reálnom čase. Rieši jeden konkrétny problém: z troch stavov databázy vytvorí štvrtý, zlúčený stav a identifikuje konflikty.

## Dokumentácia

- [Úvod](https://merql.inline0.dev/sk/docs/getting-started) -- inštalácia, prvá snímka, prvé zlúčenie.
- [CLI Referencia](https://merql.inline0.dev/sk/docs/cli) -- úplná referencia príkazu `vendor/bin/merql`.
- [PHP API Referencia](https://merql.inline0.dev/sk/docs/api) -- úplná dokumentácia API všetkých tried.
- [Plány zlúčenia](https://merql.inline0.dev/sk/docs/merge/plans) -- stabilné ID operácií, skupiny zmien a výbery.
- [Kontrolované použitie](https://merql.inline0.dev/sk/docs/apply/guarded) -- vybrané zápisy s podmienkami pre aktuálny stav riadka.
- [Vrátenie zmien](https://merql.inline0.dev/sk/docs/apply/rollback) -- artefakty na vrátenie zmien a kontroly odchýlok.
