
# Bevezetés

A merql egy tiszta PHP-könyvtár, amely háromutas egyesítést végez az adatbázis állapotán. Pillanatképeket készít a táblákról, kiszámítja a pillanatképek közötti módosításkészleteket, egy közös alap alapján egyesíti a két módosításkészletet, és oszlopszinten észleli az ütközéseket. Ugyanazt az algoritmust alkalmazza sorokra és oszlopokra, amelyet a git a forrásfájlok sorain használ.

Nincsenek külső eszközök. A MySQL és a SQLite támogatása cserélhető kapcsolatadaptereken és dialektus-illesztőprogramokon keresztül történik.

## Gyors példa

Az egyesítéshez ugyanazon adatok három állapota kell: az alap, amelyből mindkét példány kiindult, valamint a két példány a külön-külön végzett módosítások után. Ebben az esetben egy tesztkörnyezetet másoltak az éles adatbázisból, és azóta mindkettőt módosították.

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

Minden pillanatképet abból az adatbázisból kell rögzíteni, amely az adott állapotot tartalmazza. Ha egymás után mindhármat ugyanabból az adatbázisból veszi, az nem két különvált példány állapotát írja le: a másik fél állapota már tartalmazná a saját módosításait, és minden általunk beszúrt sor `insert_insert` ütközésként jelenne meg.

Az eredmény felsorolja az alapállapotot az egyesített állapottá alakító műveleteket mindkét oldalról, és mindegyikhez hozzárendeli a forrását (`ours`, `theirs` vagy `merged`). Ha a tesztkörnyezet módosításait az éles adatbázisba szeretné átvinni, alkalmazza azokat a műveleteket, amelyek még hiányoznak az éles adatbázisból a [Feltételes alkalmazás](https://merql.inline0.dev/hu/docs/apply/guarded) segítségével.

Vagy a CLI használatával, amely minden `snapshot` esetén a `MERQL_DB_DSN` által megadott adatbázishoz csatlakozik:

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

## Miért a merql

A legtöbb állapotot összehasonlító adatbázis-eszköz sorszinten működik: ha egy sor bármely oszlopa eltér a két verzió között, az egész sort ütközésként jelöli meg. Ez téves ütközéseket okoz, ha két ember ugyanazon sor különböző oszlopait szerkeszti.

A merql oszlopszinten végez egyesítést. Ha az egyik fél a `title`-t, a másik pedig a `status`-t módosította, a változások ütközés nélkül egyesíthetők. A rendszer csak akkor jelez ütközést, ha mindkét fél ugyanazt az oszlopot eltérő értékre módosítja.

A TEXT és JSON oszlopoknál a merql egy szinttel mélyebbre is mehet, és cellaszintű egyesítést végezhet. A szövegoszlop különböző sorait érintő két módosítás, illetve az JSON oszlop különböző kulcsait érintő két módosítás ugyanazzal a háromutas algoritmussal tisztán egyesíthető. A cellaszintű egyesítés választható: adjon át egy `CellMergeConfig` értéket a(z) `ThreeWayMerge` számára. A `Merql` homlokzat és a CLI csak oszlopszinten egyesít. Lásd: [Cellaszintű egyesítés](https://merql.inline0.dev/hu/docs/merge/cell-level).

## Az egyesítési modell

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

Három állapot, akárcsak a gitben. A base a közös ős. Az ours és a theirs a szétválás után létrejött két másolat, mindegyiket a saját adatbázisa rögzíti. Az egyesítési szabályok egyformán kezelik mindkét oldalt. A nevek megjelennek az egyes műveletek `source` értékében, az ütközéstípusokban (az `update_delete` azt jelenti, hogy az ours frissített, a theirs pedig törölt), valamint a `OursWins` és `TheirsWins` feloldási szabályzatokban. Közös alap nélkül nem lehet megkülönböztetni a „hozzáadott” és a „változatlan” állapotot.

Az egyesítés önmagában nem ír semmit. Műveletei a base állapotot alakítják át az egyesített állapottá, ezért az `Merql::apply()` csak olyan adatbázison futtatja le mindegyiket ütközésmentesen, amely még a base állapotot tartalmazza. Ha az egyik oldal módosításait egy olyan adatbázisba szeretné átvinni, amely már a másik oldal állapotát tartalmazza, például a sandboxban végzett szerkesztéseket éles környezetbe emelné, csak a hiányzó műveleteket alkalmazza; lásd: [Védett alkalmazás](https://merql.inline0.dev/hu/docs/apply/guarded).

## Követelmények

- PHP 8.2 vagy újabb.
- `ext-mbstring` és `ext-zlib`, amelyeket az `pitmaster/pitmaster` függőség igényel a szövegkülönbségek kiszámításához.
- Az Ön által használt adapterhez szükséges adatbázis-bővítmény: `ext-pdo` `ext-pdo_sqlite` vagy `ext-pdo_mysql` használatával, illetve `ext-mysqli`. A merql `composer.json` csak a `ext-pdo` és `ext-mysqli` használatát javasolja, ezért az Composer nem ellenőrzi, hogy ezek telepítve vannak-e.
- MySQL vagy SQLite adatbázis. Más motorokhoz egyéni [illesztőprogram](https://merql.inline0.dev/hu/docs/apply/drivers) szükséges.

## Ami nem tartozik ide

A merql nem sémamigrációs eszköz. Nem replikál adatbázisokat és nem szinkronizálja őket valós időben. Egyetlen konkrét problémát old meg: három adatbázis-állapotból létrehoz egy negyedik, egyesített állapotot, és azonosítja az ütközéseket.

## Dokumentáció

- [Első lépések](https://merql.inline0.dev/hu/docs/getting-started) -- telepítés, első pillanatkép, első egyesítés.
- [CLI referencia](https://merql.inline0.dev/hu/docs/cli) -- az `vendor/bin/merql` parancs teljes leírása.
- [PHP API referencia](https://merql.inline0.dev/hu/docs/api) -- az összes osztály teljes API dokumentációja.
- [Egyesítési tervek](https://merql.inline0.dev/hu/docs/merge/plans) -- stabil műveletazonosítók, módosításcsoportok és kijelölések.
- [Védett alkalmazás](https://merql.inline0.dev/hu/docs/apply/guarded) -- kijelölt írások az éles sorokra vonatkozó előfeltételekkel.
- [Visszaállítás](https://merql.inline0.dev/hu/docs/apply/rollback) -- visszaállítási melléktermékek és eltérés-ellenőrzések.
