
# CLI žinynas

merql pateikiama su CLI momentinėms kopijoms kurti, skirtumams apskaičiuoti ir sujungimams atlikti tiesiogiai terminale. Composer ją įdiegia kaip `vendor/bin/merql`; merql saugyklos darbinėje kopijoje tai yra `bin/merql`.

`vendor/bin/merql` veikia įdiegus priklausomybę, nes merql 0.4.1. Ankstesnėse versijose Composer autokrautuvo buvo ieškoma tik paties paketo `vendor/` kataloge, todėl merql nepavykdavo paleisti įdiegus jį kaip priklausomybę.

## Greita pradžia

```bash
# Capture a baseline from your database.
export MERQL_DB_DSN="sqlite:/path/to/db.sqlite"
vendor/bin/merql snapshot base

# Make some changes, then capture again.
vendor/bin/merql snapshot current

# See what changed.
vendor/bin/merql diff base current
```

Trijų krypčių sujungimui reikia mūsų ir jų momentinių kopijų iš dviejų duomenų bazių, kurios atsiskyrė nuo bazinės. Kiekvienai momentinei kopijai nurodykite `MERQL_DB_DSN` tinkamą duomenų bazę:

```bash
# Base: live before the sandbox was copied from it.
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

# Three-way merge with dry-run preview.
vendor/bin/merql merge base ours theirs --dry-run
```

Jei visas tris momentines kopijas iš eilės sukursite iš tos pačios duomenų bazės, sujungti nepavyks: jų kopijoje jau bus mūsų pakeitimai, todėl kiekviena mūsų įterpta eilutė bus nurodyta kaip `insert_insert` konfliktas.

## Aplinkos kintamieji

CLI nuskaito duomenų bazės ryšio informaciją iš aplinkos kintamųjų. Prisijungti galite naudodami PDO DSN eilutę arba atskirus MySQL parametrus.

### Ryšys naudojant DSN

Naudokite `MERQL_DB_DSN` PDO pagrįstiems ryšiams. Tai rekomenduojamas būdas SQLite ir nestandartinėms konfigūracijoms. DSN turi nurodyti MySQL arba SQLite duomenų bazę: CLI negali užregistruoti kitų duomenų bazių sistemų tvarkyklės.

| Kintamasis | Aprašymas | Pavyzdys |
|---|---|---|
| `MERQL_DB_DSN` | Visa PDO DSN eilutė | `sqlite:/path/to/db.sqlite` |
| `MERQL_DB_USER` | Naudotojo vardas (nebūtinas naudojant DSN) | `root` |
| `MERQL_DB_PASS` | Slaptažodis (nebūtinas naudojant DSN) | `secret` |

```bash
# SQLite file.
export MERQL_DB_DSN="sqlite:/var/data/myapp.sqlite"

# MySQL via DSN.
export MERQL_DB_DSN="mysql:host=127.0.0.1;dbname=mydb;charset=utf8mb4"
export MERQL_DB_USER="root"
export MERQL_DB_PASS="secret"
```

Naudokite failo pagrindu veikiančią SQLite duomenų bazę. Kiekviena CLI komanda vykdoma atskirame procese, todėl `sqlite::memory:` visada atidaro naują tuščią duomenų bazę, o jos momentinėje kopijoje nėra jokių lentelių.

### MySQL trumpinys

Jei `MERQL_DB_DSN` nenustatytas, CLI naudoja konkrečiai MySQL skirtus kintamuosius.

| Kintamasis | Numatytoji reikšmė | Aprašymas |
|---|---|---|
| `MERQL_DB_NAME` | (privaloma) | Duomenų bazės pavadinimas |
| `MERQL_DB_HOST` | `127.0.0.1` | MySQL pagrindinis kompiuteris |
| `MERQL_DB_PORT` | `3306` | MySQL prievadas |
| `MERQL_DB_USER` | `root` | MySQL naudotojo vardas |
| `MERQL_DB_PASS` | (tuščia) | MySQL slaptažodis |
| `MERQL_DB_ADAPTER` | `pdo` | Nustatykite į `mysqli`, kad naudotumėte mysqli adapterį |

```bash
export MERQL_DB_NAME="wordpress"
export MERQL_DB_HOST="127.0.0.1"
export MERQL_DB_PORT="3306"
export MERQL_DB_USER="root"
export MERQL_DB_PASS="password"
```

## Komandos

### `merql snapshot <name>`

Užfiksuokite esamą aplinkos kintamųjų nurodytos duomenų bazės būseną ir išsaugokite ją kaip pavadintą momentinę kopiją. Tai vienintelė komanda, kuri prisijungia prie duomenų bazės.

```bash
vendor/bin/merql snapshot baseline
```

Išvestis:

```
Snapshot 'baseline' saved
Tables: posts, comments, users, settings
```

Momentinės kopijos pagal numatytuosius nustatymus išsaugomos kaip JSON failai darbiniame kataloge, `.merql/snapshots/` (žr. [Momentinių kopijų saugykla](#snapshot-storage)). Pavadinime gali būti tik raidės, skaitmenys, brūkšneliai ir pabraukimo ženklai.

Įprasta darbo eiga: prieš atlikdami pakeitimus sukurkite momentinę kopiją, tada sukurkite kitą po pakeitimų. Šios dvi kopijos yra skirtumo arba sujungimo pagrindas.

### `merql diff <base> <current>`

Palyginkite dvi pavadintas momentines kopijas ir parodykite skirtumų santrauką.

```bash
vendor/bin/merql diff baseline current
```

Išvestis:

```
Changeset: baseline -> current
  Inserts: 3
  Updates: 7
  Deletes: 1
```

Abi momentinės kopijos jau turi būti sukurtos naudojant `merql snapshot`. Skirtumui apskaičiuoti nereikia ryšio su duomenų baze, nes naudojami išsaugoti momentinių kopijų failai.

### `merql merge <base> <ours> <theirs>`

Atlikite trijų pavadintų momentinių kopijų trijų krypčių sujungimą.

```bash
vendor/bin/merql merge base ours theirs
```

Išvestis:

```
Merge: base + ours + theirs
  Operations: 12
  Conflicts:  0
  Clean:      yes
```

Visos trys momentinės kopijos jau turi būti sukurtos. Sujungimui nereikia ryšio su duomenų baze, nes naudojami išsaugoti momentinių kopijų failai, ir duomenų bazė niekada nekeičiama: CLI neturi pritaikymo komandos. Sujungimo rezultatą pritaikykite naudodami PHP API.

CLI sujungia stulpelių lygmeniu. Jis nesujungia TEXT ar JSON stulpelių langelių lygmeniu, todėl du skirtingi to paties stulpelio pakeitimai visada laikomi konfliktu ([#7](https://github.com/inline0/merql/issues/7)). Jei norite sujungti langelių lygmeniu, naudokite `ThreeWayMerge` su `CellMergeConfig` sistemoje PHP.

#### `--dry-run`

Pridėkite vėliavėlę `--dry-run`, kad peržiūrėtumėte SQL sakinius, kuriuos sujungimas sugeneruotų, jų nevykdydami. Sakiniai aprašo, kaip bazinę būseną paversti sujungtu rezultatu, todėl juose pateikiami abiejų pusių pakeitimai.

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

Išvestis:

```
Merge: base + ours + theirs
  Operations: 3
  Conflicts:  0
  Clean:      yes

Dry run SQL:
  INSERT INTO `posts` (`id`, `title`, `status`) VALUES ('10', 'New Post', 'draft');
  UPDATE `posts` SET `title` = 'Updated Title' WHERE `id` = '5';
  DELETE FROM `comments` WHERE `id` = '3';
```

## Kūrimo komandos

merql saugyklos darbinėje kopijoje yra daugiau scenarijų, skirtų `bin/` oracle pagrįstam testų rinkiniui. Jie nėra įtraukti į Composer paketą, todėl įdiegus priklausomybę prieinama tik `vendor/bin/merql`. Vykdykite juos iš saugyklos šakninio katalogo po `composer install`.

| Komanda | Aprašymas |
|---|---|
| `./bin/oracle <name>` | Apskaičiuoti numatomą scenarijaus sujungimo rezultatą |
| `./bin/actual <name>` | Paleisti merql pagal scenarijų ir užfiksuoti išvestį |
| `./bin/compare <name>` | Palyginti oracle ir faktinę išvestį |
| `./bin/test-scenario <name>` | Visas procesas: paruošimas, oracle, faktinis rezultatas, palyginimas |
| `./bin/test-regression` | Vykdyti visus scenarijus |
| `./bin/test-regression --category clean` | Vykdyti vieną kategoriją: `clean`, `conflict`, `identity`, `types`, `scale` arba `edge` |
| `./bin/test-regression --fast` | Tik sėkmės arba nesėkmės rezultatas, be ataskaitų |
| `./bin/verify-compliance` | Išsami atitikties ataskaita |
| `./bin/verify-all` | PHPStan + kodo stilius + PHPUnit + oracle regresija |

`bin/test-regression` taip pat priima `--jobs`, tačiau šiuo metu reikšmę ignoruoja ir vykdo scenarijus vieną po kito ([#5](https://github.com/inline0/merql/issues/5)). Nežinomas `--category` išveda `No scenarios found` ir baigia darbą sėkmingai.

Scenarijų struktūrą žr. [Testavimo strategijoje](https://merql.inline0.dev/lt/docs/advanced/testing).

## Išėjimo kodas

`merql snapshot`, `diff` ir `merge` baigia darbą su 1 kodu, jei trūksta argumento, o `snapshot` taip pat, jei nesukonfigūruotas ryšys. Jei trūksta momentinės kopijos, komanda baigiama su neapdorota `SnapshotException` klaida ir nenu nuliniu kodu. Nežinoma komanda išveda `Unknown command`, bet šiuo metu baigia darbą su 0 kodu ([#3](https://github.com/inline0/merql/issues/3)).

## Momentinių kopijų saugykla

Momentinės kopijos saugomos `.merql/snapshots/` darbiniame kataloge. Kiekviena kopija yra vienas JSON failas pavadinimu `<name>.json`. Visas komandas vykdykite iš to paties katalogo, kad jos rastų viena kitos momentines kopijas.

CLI neturi parinkties ar aplinkos kintamojo kitai vietai nurodyti ([#8](https://github.com/inline0/merql/issues/8)). Norėdami naudoti kitą vietą, prieš paleisdami programą pereikite į kitą darbinį katalogą. PHP prieš kurdami arba įkeldami momentines kopijas nustatykite katalogą:

```php
use Merql\Snapshot\SnapshotStore;

SnapshotStore::setDirectory('/var/data/merql-snapshots');
```

Momentinių kopijų failai yra perkeliami. Galite juos kopijuoti į kitus kompiuterius, įtraukti į versijų valdymą ar bendrinti bendram derinimui. CLI sukurta momentinė kopija gali būti įkelta į PHP naudojant `SnapshotStore::load()` ir atvirkščiai, jei naudojamas tas pats katalogas.
