
# Įvadas

merql yra grynoji PHP biblioteka, atliekanti trijų krypčių duomenų bazės būsenos sujungimus. Ji sukuria lentelių momentines kopijas, apskaičiuoja pakeitimų rinkinius tarp jų, sujungia du pakeitimų rinkinius pagal bendrą bazę ir aptinka konfliktus stulpelių lygmeniu. Naudojamas tas pats algoritmas kaip git šaltinio failams, tik eilutėms ir stulpeliams, o ne kodo eilutėms.

Nereikia išorinių įrankių. Palaikomi MySQL ir SQLite naudojant prijungiamus ryšio adapterius ir dialektų tvarkykles.

## Trumpas pavyzdys

Sujungimui reikia trijų tų pačių duomenų būsenų: bazinės, nuo kurios pradėjo abi kopijos, ir dviejų kopijų po nepriklausomų pakeitimų. Šiuo atveju bandomoji aplinka nukopijuota iš veikiančios duomenų bazės, o nuo tada pakeistos abi.

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

Kiekviena momentinė kopija sukuriama iš duomenų bazės, kurioje yra atitinkama būsena. Jei visas tris iš eilės sukursite iš vienos duomenų bazės, jos neatspindės dviejų atsiskyrusių kopijų: jų kopijoje jau bus mūsų pakeitimų, o kiekviena mūsų įterpta eilutė bus nurodyta kaip `insert_insert` konfliktas.

Rezultate išvardytos operacijos, kuriomis bazinė būsena paverčiama sujungta būsena; įtraukti abiejų pusių pakeitimai, o kiekviena operacija pažymėta jos šaltiniu (`ours`, `theirs` arba `merged`). Norėdami perkelti bandomosios aplinkos pakeitimus į veikiančią aplinką, naudokite [Apsaugotą pritaikymą](https://merql.inline0.dev/lt/docs/apply/guarded) ir pritaikykite operacijas, kurių dar nėra veikiančioje aplinkoje.

Arba iš CLI, kuri prisijungia prie duomenų bazės, nurodytos `MERQL_DB_DSN` kiekvienai `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
```

## Kodėl merql

Dauguma būseną lyginančių duomenų bazių įrankių veikia eilučių lygmeniu: jei bet kuris eilutės stulpelis skiriasi tarp dviejų versijų, visa eilutė pažymima kaip konfliktas. Dėl to klaidingai nurodomi konfliktai, kai du žmonės keičia skirtingus tos pačios eilutės stulpelius.

merql sujungia stulpelių lygmeniu. Jei viena pusė pakeitė `title`, o kita – `status`, pakeitimai sklandžiai sujungiami be konflikto. Konfliktas kyla tik tada, kai abi pusės pakeičia tą patį stulpelį į skirtingas reikšmes.

TEXT ir JSON stulpeliuose merql gali sujungti vienu lygmeniu giliau – langelių lygmeniu. Du skirtingų teksto stulpelio eilučių arba skirtingų JSON stulpelio raktų pakeitimai gali būti sklandžiai sujungti tuo pačiu trijų krypčių algoritmu. Langelių lygmens sujungimas pasirenkamas: perduokite `CellMergeConfig` į `ThreeWayMerge`. `Merql` fasadas ir CLI sujungia tik stulpelių lygmeniu. Žr. [Sujungimas langelių lygmeniu](https://merql.inline0.dev/lt/docs/merge/cell-level).

## Sujungimo modelis

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

Trys būsenos, kaip ir git. Bazinė yra bendras protėvis. Mūsų ir jų kopijos yra dvi atsiskyrusios kopijos, kiekviena užfiksuota iš jai skirtos duomenų bazės. Sujungimo taisyklės abi puses traktuoja vienodai. Pavadinimai pateikiami kiekvienos operacijos `source`, konfliktų tipuose (`update_delete` reiškia, kad mes atnaujinome, o jie ištrynė) ir `OursWins` bei `TheirsWins` sprendimo strategijose. Neturint bendros bazės neįmanoma atskirti „pridėta“ nuo „nepakeista“.

Pats sujungimas nieko neįrašo. Jo operacijos bazinę būseną paverčia sujungta būsena, todėl `Merql::apply()` visas jas sėkmingai vykdo tik duomenų bazėje, kurioje tebėra bazinė būsena. Norėdami perkelti vienos pusės pakeitimus į duomenų bazę, kurioje jau yra kitos pusės pakeitimų, pavyzdžiui, perkelti bandomosios aplinkos pakeitimus į veikiančią aplinką, pritaikykite tik trūkstamas operacijas; žr. [Apsaugotas pritaikymas](https://merql.inline0.dev/lt/docs/apply/guarded).

## Reikalavimai

- PHP 8.2 arba naujesnė versija.
- `ext-mbstring` ir `ext-zlib`, reikalingi `pitmaster/pitmaster` priklausomybei, kuri pateikia teksto skirtumų skaičiavimo funkciją.
- Duomenų bazės plėtinys jūsų naudojamam adapteriui: `ext-pdo` su `ext-pdo_sqlite` arba `ext-pdo_mysql`, arba `ext-mysqli`. merql `composer.json` tik rekomenduoja įdiegti `ext-pdo` ir `ext-mysqli`, todėl Composer jų netikrina.
- MySQL arba SQLite duomenų bazė. Kitoms sistemoms reikia pasirinktinės [tvarkyklės](https://merql.inline0.dev/lt/docs/apply/drivers).

## Kas tai nėra

merql nėra schemos migravimo įrankis. Jis neatkuria duomenų bazių ir nesinchronizuoja jų realiuoju laiku. Jis sprendžia vieną konkrečią problemą: turint tris duomenų bazės būsenas, sukuria ketvirtą sujungtą būseną ir nurodo konfliktus.

## Dokumentacija

- [Pradžia](https://merql.inline0.dev/lt/docs/getting-started) -- diegimas, pirmasis momentinis vaizdas, pirmasis sujungimas.
- [CLI Nuoroda](https://merql.inline0.dev/lt/docs/cli) -- išsami `vendor/bin/merql` komandos nuoroda.
- [PHP API nuoroda](https://merql.inline0.dev/lt/docs/api) -- išsami API dokumentacija apie visas klases.
- [Sujungimo planai](https://merql.inline0.dev/lt/docs/merge/plans) -- stabilūs operacijų ID, pakeitimų grupės ir pasirinkimai.
- [Apsaugotas taikymas](https://merql.inline0.dev/lt/docs/apply/guarded) -- pasirinktų pakeitimų įrašymas su tiesioginės eilutės išankstinėmis sąlygomis.
- [Atšaukimas](https://merql.inline0.dev/lt/docs/apply/rollback) -- atšaukimo artefaktai ir nukrypimų patikros.
