
# CLI referencia

A merql tartalmaz egy CLI eszközt, amellyel pillanatképek készíthetők, különbségek számíthatók és egyesítések futtathatók közvetlenül a terminálból. A Composer a `vendor/bin/merql` néven telepíti; a merql-tároló egy példányában ez a következő: `bin/merql`.

A `vendor/bin/merql` függőségként telepített csomag esetén is működik, mivel a merql a 0.4.1. A korábbi kiadások csak a csomag saját `vendor/` könyvtárában keresték a Composer automatikus betöltőjét, ezért a merql függőségként történő telepítésekor nem működtek.

## Gyors kezdés

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

A háromutas egyesítéshez az ours és a theirs pillanatképét két olyan adatbázisból kell készíteni, amelyek eltértek az alaptól. Minden pillanatképhez a megfelelő adatbázist adja meg a `MERQL_DB_DSN` számára:

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

Nem működik egyesítésként, ha mindhárom pillanatképet ugyanabból az adatbázisból készíti egymás után: a theirs már tartalmazná az ours módosításait, ezért minden, az ours által beszúrt sort `insert_insert` ütközésként jelezne a rendszer.

## Környezeti változók

A CLI a környezeti változókból olvassa be az adatbázis-kapcsolat adatait. PDO DSN-karakterlánccal vagy különálló MySQL paraméterekkel is csatlakozhat.

### DSN-alapú kapcsolat

PDO-alapú kapcsolatokhoz használja a `MERQL_DB_DSN`-t. Ez az ajánlott megoldás SQLite esetén és nem szabványos konfigurációkhoz. A DSN-nek MySQL vagy SQLite adatbázisra kell mutatnia: a CLI nem tud illesztőprogramot regisztrálni más adatbázismotorokhoz.

| Változó | Leírás | Példa |
|---|---|---|
| `MERQL_DB_DSN` | Teljes PDO DSN-karakterlánc | `sqlite:/path/to/db.sqlite` |
| `MERQL_DB_USER` | Felhasználónév (DSN mellett nem kötelező) | `root` |
| `MERQL_DB_PASS` | Jelszó (DSN mellett nem kötelező) | `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"
```

Fájlon alapuló SQLite-adatbázist használ. Minden CLI parancs külön folyamatban fut, ezért a `sqlite::memory:` mindig új, üres adatbázist nyit meg, és az erről készült pillanatkép nem tartalmaz táblákat.

### MySQL-rövidítés

Ha a `MERQL_DB_DSN` nincs beállítva, a CLI az adatbázis-specifikus változókra vált: MySQL.

| Változó | Alapértelmezett érték | Leírás |
|---|---|---|
| `MERQL_DB_NAME` | (kötelező) | Adatbázis neve |
| `MERQL_DB_HOST` | `127.0.0.1` | MySQL állomás |
| `MERQL_DB_PORT` | `3306` | MySQL port |
| `MERQL_DB_USER` | `root` | MySQL felhasználónév |
| `MERQL_DB_PASS` | (üres) | MySQL jelszó |
| `MERQL_DB_ADAPTER` | `pdo` | Állítsa `mysqli` értékre a mysqli-adapter használatához |

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

## Parancsok

### `merql snapshot <name>`

Rögzítse a környezeti változók által megadott adatbázis aktuális állapotát, és mentse el névvel ellátott pillanatképként. Ez az egyetlen parancs, amely adatbázishoz csatlakozik.

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

Kimenet:

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

A pillanatképek alapértelmezés szerint `.merql/snapshots/` alatt, a munkakönyvtárban lévő JSON fájlokként maradnak meg (lásd: [Pillanatkép-tárolás](#snapshot-storage)). A név csak betűket, számokat, kötőjeleket és aláhúzásjeleket tartalmazhat.

Jellemző munkafolyamat: készítsen pillanatképet a módosítások előtt, majd egy másikat utánuk. A két pillanatkép szolgál az összehasonlítás vagy az egyesítés alapjául.

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

Hasonlítson össze két elnevezett pillanatképet, és jelenítse meg az eltérések összefoglalását.

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

Kimenet:

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

Mindkét pillanatképnek már léteznie kell (korábban a `merql snapshot` paranccsal kellett rögzíteni). Az összehasonlításhoz nem kell adatbázis-kapcsolat, mivel mentett pillanatképfájlokon dolgozik.

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

Végezzen háromutas egyesítést három elnevezett pillanatképen.

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

Kimenet:

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

Mindhárom pillanatképnek már léteznie kell. Az egyesítéshez nem kell adatbázis-kapcsolat, mivel mentett pillanatképfájlokon dolgozik, és soha nem ír adatbázisba: a CLI nem rendelkezik alkalmazási paranccsal. Az egyesítés eredményének alkalmazásához használja a PHP API parancsot.

A CLI oszlopszinten végez egyesítést. Nem egyesíti cellaszinten a TEXT vagy JSON oszlopokat, ezért ugyanazon oszlop két különböző módosítása mindig ütközésnek számít ([#7](https://github.com/inline0/merql/issues/7)). Cellaszintű egyesítéshez használja a `ThreeWayMerge`-t egy `CellMergeConfig`-val a PHP-ben.

#### `--dry-run`

Adja hozzá a `--dry-run` jelzőt az egyesítés által előállított SQL utasítások előnézetéhez, végrehajtás nélkül. Az utasítások azt írják le, hogyan alakul át az alapállapot az egyesített eredménnyé, ezért mindkét oldal módosításait tartalmazzák.

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

Kimenet:

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

## Fejlesztési parancsok

A merql-tárház egy munkapéldányában több parancsfájl található a `bin/` könyvtárban az oracle-alapú tesztcsomaghoz. Ezek nem részei a Composer csomagnak, ezért a függőségek telepítése után csak a `vendor/bin/merql` érhető el. Futtassa őket a tárház gyökérkönyvtárából, az `composer install` után.

| Parancs | Leírás |
|---|---|
| `./bin/oracle <name>` | Az elvárt egyesítési eredmény kiszámítása egy forgatókönyvhöz |
| `./bin/actual <name>` | A merql futtatása egy forgatókönyvön és a kimenet rögzítése |
| `./bin/compare <name>` | Az oracle-kimenet és a tényleges kimenet összehasonlítása |
| `./bin/test-scenario <name>` | Teljes folyamat: beállítás, oracle, tényleges kimenet, összehasonlítás |
| `./bin/test-regression` | Az összes forgatókönyv futtatása |
| `./bin/test-regression --category clean` | Egy kategória futtatása: `clean`, `conflict`, `identity`, `types`, `scale` vagy `edge` |
| `./bin/test-regression --fast` | Csak sikeres vagy sikertelen állapot, jelentések nélkül |
| `./bin/verify-compliance` | Teljes megfelelőségi jelentés |
| `./bin/verify-all` | PHPStan + kódstílus + PHPUnit + oracle-regresszió |

A `bin/test-regression` a `--jobs` értéket is elfogadja, de jelenleg figyelmen kívül hagyja, és egymás után futtatja a forgatókönyveket ([#5](https://github.com/inline0/merql/issues/5)). Ismeretlen `--category` esetén kiírja a `No scenarios found` értéket, majd sikeresen kilép.

A forgatókönyvek felépítéséről lásd a [Tesztelési stratégiát](https://merql.inline0.dev/hu/docs/advanced/testing).

## Kilépési állapot

A `merql snapshot`, a `diff` és a `merge` hiányzó argumentum esetén 1-es állapotkóddal lép ki; a `snapshot` akkor is, ha nincs beállítva kapcsolat. Hiányzó pillanatkép esetén a parancs el nem kapott `SnapshotException` kivétellel és nem nulla állapotkóddal ér véget. Ismeretlen parancs esetén kiírja a `Unknown command` értéket, de jelenleg 0-s állapotkóddal lép ki ([#3](https://github.com/inline0/merql/issues/3)).

## Pillanatkép-tárolás

A pillanatképek a munkakönyvtárhoz képest a `.merql/snapshots/` helyen tárolódnak. Minden pillanatkép egyetlen JSON fájl, neve `<name>.json`. Minden parancsot ugyanabból a könyvtárból futtasson, hogy megtalálják egymás pillanatképeit.

A CLI nem kínál kapcsolót vagy környezeti változót másik hely megadására ([#8](https://github.com/inline0/merql/issues/8)). Másik hely használatához váltson másik munkakönyvtárra a futtatás előtt. PHP esetén a pillanatképek rögzítése vagy betöltése előtt állítsa be a könyvtárat:

```php
use Merql\Snapshot\SnapshotStore;

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

A pillanatképfájlok hordozhatók. Másolja át őket gépek között, véglegesítse verziókezelőben, vagy ossza meg őket közös hibakereséshez. A CLI által rögzített pillanatkép betölthető a PHP programban a `SnapshotStore::load()` használatával, és fordítva, ha mindkettő ugyanazt a könyvtárat használja.
