
# CLI uzziņu rokasgrāmata

merql ietver CLI momentuzņēmumu izveidei, atšķirību aprēķināšanai un apvienošanai tieši terminālī. Composer to instalē kā `vendor/bin/merql`; merql repozitorija izrakstā tā ir `bin/merql`.

`vendor/bin/merql` darbojas pēc atkarību instalēšanas, jo merql 0.4.1. Iepriekšējās versijas meklēja Composer autoloader tikai pakotnes `vendor/` direktorijā un nedarbojās, ja merql bija instalēts kā atkarība.

## Ātrais sākums

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

Trīspusējai apvienošanai nepieciešams, lai ours un theirs būtu iegūti no divām datubāzēm, kas atšķīrušās no base. Norādiet `MERQL_DB_DSN` pareizo datubāzi katram momentuzņēmumam:

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

Visu trīs momentuzņēmumu secīga izveide no vienas un tās pašas datubāzes neder apvienošanai: theirs jau ietvertu ours izmaiņas, tāpēc katra ours ievietotā rinda tiktu uzrādīta kā `insert_insert` konflikts.

## Vides mainīgie

CLI nolasa datubāzes savienojuma informāciju no vides mainīgajiem. Varat
izveidot savienojumu, izmantojot PDO DSN virkni vai atsevišķus MySQL parametrus.

### Savienojums, izmantojot DSN

PDO savienojumiem izmantojiet `MERQL_DB_DSN`. Šī ir ieteicamā pieeja
SQLite un nestandarta konfigurācijām. DSN jānorāda uz MySQL
vai SQLite datubāzi: CLI nevar reģistrēt draiveri citām sistēmām.

| Mainīgais | Apraksts | Piemērs |
|---|---|---|
| `MERQL_DB_DSN` | Pilna PDO DSN virkne | `sqlite:/path/to/db.sqlite` |
| `MERQL_DB_USER` | Lietotājvārds (neobligāts, ja norādīts DSN) | `root` |
| `MERQL_DB_PASS` | Parole (neobligāta, ja norādīts 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"
```

Izmantojiet failā glabātu SQLite datubāzi. Katra CLI komanda darbojas savā procesā, tāpēc
`sqlite::memory:` vienmēr atver jaunu, tukšu datubāzi, un tās momentuzņēmumā
nav nevienas tabulas.

### MySQL saīsinājums

Ja `MERQL_DB_DSN` nav iestatīts, CLI izmanto MySQL specifiskos mainīgos.

| Mainīgais | Noklusējums | Apraksts |
|---|---|---|
| `MERQL_DB_NAME` | (obligāts) | Datubāzes nosaukums |
| `MERQL_DB_HOST` | `127.0.0.1` | MySQL resursdators |
| `MERQL_DB_PORT` | `3306` | MySQL ports |
| `MERQL_DB_USER` | `root` | MySQL lietotājvārds |
| `MERQL_DB_PASS` | (tukšs) | MySQL parole |
| `MERQL_DB_ADAPTER` | `pdo` | Iestatiet uz `mysqli`, lai izmantotu mysqli adapteri |

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

## Komandas

### `merql snapshot <name>`

Iegūstiet vides mainīgajos norādītās datubāzes pašreizējo stāvokli un saglabājiet to kā nosauktu momentuzņēmumu. Šī ir vienīgā komanda, kas izveido savienojumu ar datubāzi.

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

Izvade:

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

Momentuzņēmumi pēc noklusējuma tiek saglabāti kā JSON faili darba direktorijā esošajā `.merql/snapshots/` (skatiet [Momentuzņēmumu glabāšana](#snapshot-storage)). Nosaukumā drīkst būt tikai burtciparu rakstzīmes, defises un pasvītrojumi.

Tipiska darbplūsma: izveidojiet momentuzņēmumu pirms izmaiņu veikšanas un pēc tam vēl vienu. Šie divi momentuzņēmumi ir pamatā atšķirību aprēķinam vai apvienošanai.

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

Salīdziniet divus nosauktus momentuzņēmumus un parādiet atšķirību kopsavilkumu.

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

Izvade:

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

Abiem momentuzņēmumiem jau jābūt izveidotiem ar `merql snapshot`. Atšķirību aprēķinam nav nepieciešams savienojums ar datubāzi, jo tas darbojas ar saglabātajiem momentuzņēmumu failiem.

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

Veiciet trīs nosauktu momentuzņēmumu trīspusēju apvienošanu.

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

Izvade:

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

Visiem trim momentuzņēmumiem jau jābūt izveidotiem. Apvienošanai nav nepieciešams savienojums ar datubāzi, jo tā darbojas ar saglabātajiem momentuzņēmumu failiem, un tā nekad neraksta datubāzē: CLI nav lietojuma komandas. Izmantojiet PHP API, lai lietotu apvienošanas rezultātu.

CLI apvienošanas veic kolonnu līmenī. Tā neveic šūnu līmeņa apvienošanu TEXT vai JSON kolonnās, tāpēc divas atšķirīgas vienas kolonnas izmaiņas vienmēr ir konflikts ([#7](https://github.com/inline0/merql/issues/7)). Šūnu līmeņa apvienošanai izmantojiet `ThreeWayMerge` kopā ar `CellMergeConfig` iekš PHP.

#### `--dry-run`

Pievienojiet karodziņu `--dry-run`, lai priekšskatītu apvienošanas ģenerētos SQL priekšrakstus, neko neizpildot. Priekšraksti apraksta, kā bāzes stāvokli pārveidot par apvienoto rezultātu, tāpēc tie ietver abu pušu izmaiņas.

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

Izvade:

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

## Izstrādes komandas

merql repozitorija izrakstā ir vairāk skriptu `bin/` direktorijā tā uz oracle balstītajai testu kopai. Tie nav iekļauti Composer pakotnē, tāpēc pēc atkarību instalēšanas pieejams tikai `vendor/bin/merql`. Palaidiet tos no repozitorija saknes pēc `composer install`.

| Komanda | Apraksts |
|---|---|
| `./bin/oracle <name>` | Aprēķināt sagaidāmo apvienošanas rezultātu scenārijam |
| `./bin/actual <name>` | Palaist merql scenārijā un iegūt izvadi |
| `./bin/compare <name>` | Salīdzināt oracle un faktisko izvadi |
| `./bin/test-scenario <name>` | Pilns process: iestatīšana, oracle, faktiskā izvade, salīdzināšana |
| `./bin/test-regression` | Palaist visus scenārijus |
| `./bin/test-regression --category clean` | Palaist vienu kategoriju: `clean`, `conflict`, `identity`, `types`, `scale` vai `edge` |
| `./bin/test-regression --fast` | Tikai sekmju un kļūmju rezultāti, bez pārskatiem |
| `./bin/verify-compliance` | Pilns atbilstības pārskats |
| `./bin/verify-all` | PHPStan + koda stils + PHPUnit + oracle regresija |

`bin/test-regression` pieņem arī `--jobs`, taču pašlaik ignorē vērtību un palaiž scenārijus vienu pēc otra ([#5](https://github.com/inline0/merql/issues/5)). Nezināma `--category` gadījumā tiek parādīts `No scenarios found`, un komanda beidzas veiksmīgi.

Scenāriju izkārtojumu skatiet sadaļā [Testēšanas stratēģija](https://merql.inline0.dev/lv/docs/advanced/testing).

## Beigu statuss

`merql snapshot`, `diff` un `merge` beidzas ar statusu 1, ja trūkst argumenta, bet `snapshot` arī tad, ja nav konfigurēts savienojums. Ja trūkst momentuzņēmuma, komanda beidzas ar neapstrādātu `SnapshotException` un statusu, kas nav nulle. Nezināmas komandas gadījumā tiek parādīts `Unknown command`, taču pašlaik tā beidzas ar statusu 0 ([#3](https://github.com/inline0/merql/issues/3)).

## Momentuzņēmumu glabāšana

Momentuzņēmumi tiek glabāti `.merql/snapshots/`, kas norādīts attiecībā pret darba direktoriju. Katrs momentuzņēmums ir viens JSON fails ar nosaukumu `<name>.json`. Palaidiet visas komandas no viena direktorija, lai tās atrastu citu komandu momentuzņēmumus.

CLI nav opcijas vai vides mainīgā citas atrašanās vietas norādīšanai ([#8](https://github.com/inline0/merql/issues/8)). Lai izmantotu citu vietu, pirms palaišanas pārejiet uz citu darba direktoriju. PHP iestatiet direktoriju pirms momentuzņēmumu izveides vai ielādes:

```php
use Merql\Snapshot\SnapshotStore;

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

Momentuzņēmumu faili ir pārnesami. Varat tos kopēt starp datoriem, iekļaut versiju vadības sistēmā vai koplietot kopīgai atkļūdošanai. Momentuzņēmumu, ko izveidojis CLI, var ielādēt PHP, izmantojot `SnapshotStore::load()`, un otrādi, ja vien abos gadījumos tiek izmantots viens un tas pats direktorijs.
