
# Referencia CLI

merql obsahuje CLI na zachytávanie snímok, výpočet rozdielov a spúšťanie zlúčení priamo z terminálu. Composer ho nainštaluje ako `vendor/bin/merql`; v lokálnej kópii úložiska merql je dostupný ako `bin/merql`.

`vendor/bin/merql` funguje aj po inštalácii ako závislosť, pretože merql 0.4.1. Staršie vydania hľadali zavádzač Composer iba v adresári `vendor/` samotného balíka a pri inštalácii merql ako závislosti zlyhali.

## Rýchly začiatok

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

Trojstranné zlúčenie vyžaduje, aby sa naše zmeny a zmeny druhej strany zachytili z dvoch databáz, ktoré sa vyvíjali oddelene od základného stavu. Pre každú snímku nastavte `MERQL_DB_DSN` na správnu databázu:

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

Zachytenie všetkých troch snímok z tej istej databázy postupne nefunguje ako zlúčenie: zmeny druhej strany by už obsahovali naše zmeny, takže každý riadok, ktorý sme vložili, by sa označil ako konflikt `insert_insert`.

## Premenné prostredia

CLI načítava údaje o pripojení k databáze z premenných prostredia. Pripojiť sa môžete pomocou reťazca DSN pre PDO alebo samostatných parametrov MySQL.

### Pripojenie pomocou DSN

Pre pripojenia založené na PDO použite `MERQL_DB_DSN`. Tento odporúčaný spôsob je vhodný pre SQLite aj neštandardné konfigurácie. DSN musí smerovať na databázu MySQL alebo SQLite: CLI nedokáže zaregistrovať ovládač pre iné databázové systémy.

| Premenná | Opis | Príklad |
|---|---|---|
| `MERQL_DB_DSN` | Úplný reťazec DSN pre PDO | `sqlite:/path/to/db.sqlite` |
| `MERQL_DB_USER` | Používateľské meno (pri DSN nepovinné) | `root` |
| `MERQL_DB_PASS` | Heslo (pri DSN nepovinné) | `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"
```

Použite databázu SQLite uloženú v súbore. Každý príkaz CLI sa spúšťa v samostatnom procese, takže `sqlite::memory:` vždy otvorí novú, prázdnu databázu a jej snímka neobsahuje žiadne tabuľky.

### Skrátený zápis MySQL

Ak nie je nastavená premenná `MERQL_DB_DSN`, CLI použije ako náhradné premenné špecifické pre MySQL.

| Premenná | Predvolená hodnota | Opis |
|---|---|---|
| `MERQL_DB_NAME` | (povinné) | Názov databázy |
| `MERQL_DB_HOST` | `127.0.0.1` | Hostiteľ MySQL |
| `MERQL_DB_PORT` | `3306` | Port MySQL |
| `MERQL_DB_USER` | `root` | Používateľské meno MySQL |
| `MERQL_DB_PASS` | (prázdne) | Heslo MySQL |
| `MERQL_DB_ADAPTER` | `pdo` | Nastavením na `mysqli` použijete ovládač mysqli |

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

## Príkazy

### `merql snapshot <name>`

Zachytí aktuálny stav databázy určenej premennými prostredia a uloží ho ako pomenovanú snímku. Toto je jediný príkaz, ktorý sa pripája k databáze.

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

Výstup:

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

Snímky sa ukladajú ako súbory JSON v adresári `.merql/snapshots/` v pracovnom adresári (pozrite si [Ukladanie snímok](#snapshot-storage)). Názov môže obsahovať iba alfanumerické znaky, pomlčky a podčiarkovníky.

Bežný postup: pred vykonaním zmien zachyťte snímku a potom zachyťte ďalšiu. Tieto dve snímky tvoria základ na porovnanie alebo zlúčenie.

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

Porovná dve pomenované snímky a zobrazí súhrn rozdielov.

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

Výstup:

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

Obe snímky už musia existovať (musia byť predtým zachytené pomocou `merql snapshot`). Porovnanie nevyžaduje pripojenie k databáze, pretože pracuje s uloženými súbormi snímok.

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

Vykoná trojstranné zlúčenie troch pomenovaných snímok.

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

Výstup:

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

Všetky tri snímky už musia existovať. Zlúčenie nevyžaduje pripojenie k databáze, pretože pracuje s uloženými súbormi snímok, a do databázy nikdy nezapisuje: CLI nemá príkaz na použitie zmien. Na použitie výsledku zlúčenia použite PHP API.

CLI zlučuje na úrovni stĺpcov. Nepoužíva zlúčenie na úrovni buniek pre stĺpce TEXT ani JSON, takže dve rôzne úpravy toho istého stĺpca vždy predstavujú konflikt ([#7](https://github.com/inline0/merql/issues/7)). Na zlúčenie na úrovni buniek použite `ThreeWayMerge` s `CellMergeConfig` v PHP.

#### `--dry-run`

Pridajte príznak `--dry-run` a zobrazte náhľad príkazov SQL, ktoré by zlúčenie vytvorilo, bez ich vykonania. Príkazy opisujú, ako zmeniť základný stav na zlúčený výsledok, a preto zahŕňajú zmeny oboch strán.

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

Výstup:

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

## Príkazy na vývoj

Lokálna kópia úložiska merql obsahuje ďalšie skripty v `bin/` pre testovaciu súpravu riadenú referenčnými výsledkami. Nie sú súčasťou balíka Composer, takže po inštalácii závislosti máte k dispozícii iba `vendor/bin/merql`. Spúšťajte ich z koreňového adresára úložiska po `composer install`.

| Príkaz | Opis |
|---|---|
| `./bin/oracle <name>` | Vypočíta očakávaný výsledok zlúčenia pre scenár |
| `./bin/actual <name>` | Spustí merql pre scenár a zachytí výstup |
| `./bin/compare <name>` | Porovná referenčný a skutočný výstup |
| `./bin/test-scenario <name>` | Celý proces: príprava, referenčný výsledok, skutočný výsledok, porovnanie |
| `./bin/test-regression` | Spustí všetky scenáre |
| `./bin/test-regression --category clean` | Spustí jednu kategóriu: `clean`, `conflict`, `identity`, `types`, `scale` alebo `edge` |
| `./bin/test-regression --fast` | Iba výsledok úspech/neúspech, bez správ |
| `./bin/verify-compliance` | Úplná správa o zhode |
| `./bin/verify-all` | PHPStan + štýl kódu + PHPUnit + regresné testy referenčných výsledkov |

`bin/test-regression` prijíma aj `--jobs`, no momentálne ignoruje jeho hodnotu a spúšťa scenáre postupne ([#5](https://github.com/inline0/merql/issues/5)). Neznámy `--category` vypíše `No scenarios found` a skončí úspešne.

Rozloženie scenárov nájdete v [Stratégii testovania](https://merql.inline0.dev/sk/docs/advanced/testing).

## Ukončovací stav

`merql snapshot`, `diff` a `merge` skončia so stavom 1, ak chýba argument; `snapshot` skončí rovnako aj vtedy, ak nie je nakonfigurované pripojenie. Pri chýbajúcej snímke sa príkaz skončí s nezachytenou výnimkou `SnapshotException` a nenulovým stavom. Neznámy príkaz vypíše `Unknown command`, no momentálne skončí so stavom 0 ([#3](https://github.com/inline0/merql/issues/3)).

## Ukladanie snímok

Snímky sa ukladajú do `.merql/snapshots/` vzhľadom na pracovný adresár. Každá snímka je jeden súbor JSON s názvom `<name>.json`. Všetky príkazy spúšťajte z toho istého adresára, aby našli snímky vytvorené ostatnými príkazmi.

CLI nemá možnosť ani premennú prostredia na určenie iného umiestnenia ([#8](https://github.com/inline0/merql/issues/8)). Ak chcete použiť iné umiestnenie, pred spustením zmeňte pracovný adresár. V PHP nastavte adresár pred zachytením alebo načítaním snímok:

```php
use Merql\Snapshot\SnapshotStore;

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

Súbory snímok možno prenášať. Môžete ich kopírovať medzi počítačmi, pridať do systému správy verzií alebo zdieľať pri spoločnom ladení. Snímku zachytenú pomocou CLI možno načítať v PHP pomocou `SnapshotStore::load()` a naopak, ak oba nástroje používajú ten istý adresár.
