
# Sissejuhatus

merql on puhas PHP teek, mis ühendab andmebaasi kolme oleku muudatused. See salvestab tabelite hetktõmmised, arvutab nendevahelised muudatuste komplektid, ühendab kaks muudatuste komplekti ühise baasoleku põhjal ning tuvastab konfliktid veerutasemel. Sama algoritm, mida git kasutab lähtefailide puhul, rakendatuna ridadele ja veergudele, mitte ridadele tekstis.

Väliseid tööriistu pole vaja. Toetab MySQL ja SQLite-i vahetatavate ühendusadapterite ja dialektidraiverite kaudu.

## Kiire näide

Ühendamiseks on vaja samu andmeid kolmes olekus: baas, millest mõlemad koopiad alustasid, ning kaks koopiat pärast sõltumatuid muudatusi. Siin kopeeriti liivakast aktiivsest andmebaasist ja mõlemas on pärast seda muudatusi tehtud.

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

Iga hetktõmmis salvestatakse seda olekut sisaldavast andmebaasist. Kõigi kolme järjest salvestamine ühest andmebaasist ei kirjelda kahte lahknenud koopiat: theirs sisaldaks juba ours-i muudatusi ning iga ours-i lisatud rida märgitaks `insert_insert` konfliktiks.

Tulemus loetleb toimingud, mis viivad baasoleku mõlema poole muudatustega ühendatud olekusse; iga toiming on märgitud allikaga (`ours`, `theirs` või `merged`). Liivakasti muudatuste kirjutamiseks aktiivsesse andmebaasi rakendage toimingud, mida aktiivses andmebaasis veel pole, käsuga [kaitstud rakendamine](https://merql.inline0.dev/et/docs/apply/guarded).

Või käsuga CLI, mis loob ühenduse andmebaasiga, mille nimi on iga `snapshot` jaoks määratud väärtuses `MERQL_DB_DSN`:

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

## Miks merql

Enamik olekut võrdlevaid andmebaasitööriistu töötab rea tasemel: kui rea mis tahes veerg erineb kahe versiooni vahel, märgitakse konfliktiks terve rida. See tekitab valekonflikte, kui kaks inimest muudavad sama rea eri veerge.

merql ühendab veerutasemel. Kui üks pool muudab `title` ja teine `status`, ühendatakse muudatused puhtalt, ilma konfliktita. Konflikt tekib ainult siis, kui mõlemad pooled muudavad sama veeru väärtuse erinevaks.

TEXT- ja JSON-veergude puhul saab merql minna lahtritasemel ühendamisega sammu võrra sügavamale. Tekstiveeru eri ridade või JSON-veeru eri võtmete muudatused saab ühendada sama kolmeosalise algoritmiga. Lahtritasemel ühendamine on valikuline: edastage käsule `ThreeWayMerge` väärtus `CellMergeConfig`. `Merql`-fassaad ja CLI ühendavad ainult veerutasemel. Vt [lahtritasemel ühendamist](https://merql.inline0.dev/et/docs/merge/cell-level).

## Ühendamismudel

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

Kolm olekut nagu git-is. Base on ühine eelkäija. Ours ja theirs on kaks koopiat pärast lahknemist; kumbki salvestatakse oma andmebaasist. Ühendamisreeglid käsitlevad mõlemat poolt võrdselt. Nimed esinevad iga toimingu `source`-s, konfliktitüüpides (`update_delete` tähendab, et ours uuendas ja theirs kustutas) ning lahenduspoliitikates `OursWins` ja `TheirsWins`. Ühise baasita ei saa eristada "lisatud" ja "muutumata" olekut.

Ühendamine ei kirjuta ise midagi andmebaasi. Selle toimingud muudavad baasi ühendatud olekuks, seega käivitab `Merql::apply()` need kõik puhtalt ainult andmebaasis, milles on endiselt baasolek. Ühe poole muudatuste lisamiseks andmebaasi, kus on juba teise poole muudatused (näiteks liivakasti muudatuste kandmiseks aktiivsesse andmebaasi), rakendage ainult puuduvad toimingud; vt [kaitstud rakendamist](https://merql.inline0.dev/et/docs/apply/guarded).

## Nõuded

- PHP 8.2 või uuem.
- `ext-mbstring` ja `ext-zlib`, mida vajab teksti erinevusi pakkuv sõltuvus `pitmaster/pitmaster`.
- Kasutatava adapteri andmebaasilaiendus: `ext-pdo` koos `ext-pdo_sqlite` või `ext-pdo_mysql`-ga või `ext-mysqli`. merqli `composer.json` soovitab ainult pakette `ext-pdo` ja `ext-mysqli`, seega Composer neid ei kontrolli.
- MySQL või SQLite andmebaas. Muud mootorid vajavad kohandatud [draiverit](https://merql.inline0.dev/et/docs/apply/drivers).

## Mis see ei ole

merql ei ole skeemi migreerimise tööriist. See ei kopeeri andmebaase ega sünkrooni neid reaalajas. See lahendab ühe konkreetse probleemi: võtab kolm andmebaasi olekut ning loob neist neljanda ühendatud oleku, tuvastades konfliktid.

## Dokumentatsioon

- [Alustamine](https://merql.inline0.dev/et/docs/getting-started) -- paigaldamine, esimene hetktõmmis ja esimene ühendamine.
- [CLI viitejuhend](https://merql.inline0.dev/et/docs/cli) -- käsu `vendor/bin/merql` täielik viide.
- [PHP API viitejuhend](https://merql.inline0.dev/et/docs/api) -- kõigi klasside täielik API-dokumentatsioon.
- [Ühendamisplaanid](https://merql.inline0.dev/et/docs/merge/plans) -- stabiilsed toimingu-ID-d, muudatuste rühmad ja valikud.
- [Kaitstud rakendamine](https://merql.inline0.dev/et/docs/apply/guarded) -- valitud kirjutamised koos aktiivsete ridade eeltingimustega.
- [Tagasipööramine](https://merql.inline0.dev/et/docs/apply/rollback) -- tagasipööramise artefaktid ja lahknevuse kontrollid.
