
# Αναφορά CLI

Το merql περιλαμβάνει ένα CLI για τη λήψη στιγμιότυπων, τον υπολογισμό διαφορών και την εκτέλεση συγχωνεύσεων απευθείας από το τερματικό. Το Composer το εγκαθιστά ως `vendor/bin/merql`· σε ένα αντίγραφο του αποθετηρίου merql είναι το `bin/merql`.

Το `vendor/bin/merql` λειτουργεί και μετά την εγκατάσταση ως εξάρτηση, επειδή το merql 0.4.1. Οι παλαιότερες εκδόσεις αναζητούσαν το Composer autoloader μόνο στον δικό τους κατάλογο `vendor/` και αποτύγχαναν όταν το merql είχε εγκατασταθεί ως εξάρτηση.

## Γρήγορη εκκίνηση

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

Μια συγχώνευση τριών κατευθύνσεων απαιτεί να έχουν καταγραφεί οι δικές μας αλλαγές και οι αλλαγές της άλλης πλευράς από δύο βάσεις δεδομένων που αποκλίνουν από τη βάση. Κατευθύνετε το `MERQL_DB_DSN` στη σωστή βάση δεδομένων για κάθε στιγμιότυπο:

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

Η διαδοχική λήψη και των τριών στιγμιότυπων από την ίδια βάση δεδομένων δεν λειτουργεί για συγχώνευση: το στιγμιότυπο της άλλης πλευράς θα περιείχε ήδη τις δικές μας αλλαγές, οπότε κάθε γραμμή που εισαγάγαμε θα αναφερόταν ως διένεξη `insert_insert`.

## Μεταβλητές περιβάλλοντος

Το CLI διαβάζει τα στοιχεία σύνδεσης της βάσης δεδομένων από μεταβλητές περιβάλλοντος. Μπορείτε να συνδεθείτε είτε με μια συμβολοσειρά DSN του PDO είτε με μεμονωμένες παραμέτρους MySQL.

### Σύνδεση βάσει DSN

Χρησιμοποιήστε το `MERQL_DB_DSN` για συνδέσεις μέσω PDO. Αυτή είναι η προτεινόμενη προσέγγιση για το SQLite και για μη τυπικές διαμορφώσεις. Το DSN πρέπει να παραπέμπει σε βάση δεδομένων MySQL ή SQLite: το CLI δεν έχει τρόπο να καταχωρίσει οδηγό για άλλες μηχανές.

| Μεταβλητή | Περιγραφή | Παράδειγμα |
|---|---|---|
| `MERQL_DB_DSN` | Πλήρης συμβολοσειρά DSN του PDO | `sqlite:/path/to/db.sqlite` |
| `MERQL_DB_USER` | Όνομα χρήστη (προαιρετικό με DSN) | `root` |
| `MERQL_DB_PASS` | Κωδικός πρόσβασης (προαιρετικός με 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"
```

Χρησιμοποιήστε βάση δεδομένων SQLite αποθηκευμένη σε αρχείο. Κάθε εντολή CLI εκτελείται σε ξεχωριστή διεργασία, επομένως το `sqlite::memory:` ανοίγει πάντα μια νέα, κενή βάση δεδομένων και ένα στιγμιότυπό της δεν περιέχει πίνακες.

### Συντόμευση MySQL

Όταν δεν έχει οριστεί το `MERQL_DB_DSN`, το CLI χρησιμοποιεί ως εναλλακτική τις μεταβλητές που αφορούν ειδικά το MySQL.

| Μεταβλητή | Προεπιλογή | Περιγραφή |
|---|---|---|
| `MERQL_DB_NAME` | (απαιτείται) | Όνομα βάσης δεδομένων |
| `MERQL_DB_HOST` | `127.0.0.1` | Κεντρικός υπολογιστής MySQL |
| `MERQL_DB_PORT` | `3306` | Θύρα MySQL |
| `MERQL_DB_USER` | `root` | Όνομα χρήστη MySQL |
| `MERQL_DB_PASS` | (κενό) | Κωδικός πρόσβασης MySQL |
| `MERQL_DB_ADAPTER` | `pdo` | Ορίστε σε `mysqli` για χρήση του προσαρμογέα 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"
```

## Εντολές

### `merql snapshot <name>`

Καταγράψτε την τρέχουσα κατάσταση της βάσης δεδομένων που ορίζεται από τις μεταβλητές περιβάλλοντος και αποθηκεύστε την ως επώνυμο στιγμιότυπο. Αυτή είναι η μόνη εντολή που συνδέεται σε βάση δεδομένων.

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

Έξοδος:

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

Τα στιγμιότυπα αποθηκεύονται ως αρχεία JSON στο `.merql/snapshots/` κάτω από τον κατάλογο εργασίας (δείτε την ενότητα [Αποθήκευση στιγμιότυπων](#snapshot-storage)). Το όνομα πρέπει να περιέχει μόνο αλφαριθμητικούς χαρακτήρες, παύλες και κάτω παύλες.

Συνήθης ροή εργασίας: καταγράψτε ένα στιγμιότυπο πριν κάνετε αλλαγές και έπειτα ένα ακόμη μετά. Τα δύο στιγμιότυπα αποτελούν τη βάση για τη σύγκριση ή τη συγχώνευση.

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

Συγκρίνετε δύο επώνυμα στιγμιότυπα και εμφανίστε μια σύνοψη των διαφορών.

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

Έξοδος:

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

Και τα δύο στιγμιότυπα πρέπει να υπάρχουν ήδη (να έχουν καταγραφεί προηγουμένως με το `merql snapshot`). Η σύγκριση δεν απαιτεί σύνδεση με βάση δεδομένων, καθώς λειτουργεί με αποθηκευμένα αρχεία στιγμιότυπων.

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

Εκτελέστε συγχώνευση τριών επώνυμων στιγμιότυπων.

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

Έξοδος:

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

Και τα τρία στιγμιότυπα πρέπει να υπάρχουν ήδη. Η συγχώνευση δεν απαιτεί σύνδεση με βάση δεδομένων, καθώς λειτουργεί με αποθηκευμένα αρχεία στιγμιότυπων, και δεν γράφει ποτέ σε βάση δεδομένων: το CLI δεν διαθέτει εντολή εφαρμογής. Χρησιμοποιήστε τα PHP API για να εφαρμόσετε ένα αποτέλεσμα συγχώνευσης.

Το CLI συγχωνεύει σε επίπεδο στηλών. Δεν εφαρμόζει συγχώνευση σε επίπεδο κελιού σε στήλες TEXT ή JSON, επομένως δύο διαφορετικές αλλαγές στην ίδια στήλη οδηγούν πάντα σε διένεξη εδώ ([#7](https://github.com/inline0/merql/issues/7)). Χρησιμοποιήστε το `ThreeWayMerge` με ένα `CellMergeConfig` στο PHP για συγχώνευση σε επίπεδο κελιού.

#### `--dry-run`

Προσθέστε τη σημαία `--dry-run` για να δείτε σε προεπισκόπηση τις εντολές SQL που θα δημιουργούσε η συγχώνευση, χωρίς να εκτελέσετε τίποτα. Οι εντολές περιγράφουν πώς θα μετατραπεί η κατάσταση της βάσης στο συγχωνευμένο αποτέλεσμα, επομένως περιλαμβάνουν τις αλλαγές και των δύο πλευρών.

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

Έξοδος:

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

## Εντολές ανάπτυξης

Ένα αντίγραφο του αποθετηρίου merql περιλαμβάνει περισσότερα σενάρια στο `bin/` για τη σουίτα δοκιμών που βασίζεται σε oracle. Δεν αποτελούν μέρος του πακέτου Composer, οπότε μετά την εγκατάσταση ως εξάρτηση είναι διαθέσιμο μόνο το `vendor/bin/merql`. Εκτελέστε τα από τη ρίζα του αποθετηρίου μετά το `composer install`.

| Εντολή | Περιγραφή |
|---|---|
| `./bin/oracle <name>` | Υπολογίζει το αναμενόμενο αποτέλεσμα συγχώνευσης για ένα σενάριο |
| `./bin/actual <name>` | Εκτελεί το merql σε ένα σενάριο και καταγράφει την έξοδο |
| `./bin/compare <name>` | Συγκρίνει την έξοδο oracle με την πραγματική |
| `./bin/test-scenario <name>` | Πλήρης διαδικασία: προετοιμασία, oracle, πραγματικό αποτέλεσμα, σύγκριση |
| `./bin/test-regression` | Εκτελεί όλα τα σενάρια |
| `./bin/test-regression --category clean` | Εκτελεί μία κατηγορία: `clean`, `conflict`, `identity`, `types`, `scale` ή `edge` |
| `./bin/test-regression --fast` | Μόνο επιτυχία/αποτυχία, χωρίς αναφορές |
| `./bin/verify-compliance` | Πλήρης αναφορά συμμόρφωσης |
| `./bin/verify-all` | PHPStan + στυλ κώδικα + PHPUnit + έλεγχος παλινδρόμησης oracle |

Το `bin/test-regression` δέχεται επίσης το `--jobs`, αλλά προς το παρόν αγνοεί την τιμή και εκτελεί τα σενάρια το ένα μετά το άλλο ([#5](https://github.com/inline0/merql/issues/5)). Άγνωστο `--category` εμφανίζει το `No scenarios found` και τερματίζεται με επιτυχία.

Δείτε τη [Στρατηγική δοκιμών](https://merql.inline0.dev/el/docs/advanced/testing) για τη διάταξη των σεναρίων.

## Κατάσταση εξόδου

Τα `merql snapshot`, `diff` και `merge` τερματίζονται με κωδικό κατάστασης 1 όταν λείπει κάποιο όρισμα, όπως και το `snapshot` όταν δεν έχει διαμορφωθεί σύνδεση. Αν λείπει ένα στιγμιότυπο, η εντολή τερματίζεται με μη διαχειριζόμενο `SnapshotException` και μη μηδενικό κωδικό κατάστασης. Μια άγνωστη εντολή εμφανίζει το `Unknown command`, αλλά προς το παρόν τερματίζεται με κωδικό κατάστασης 0 ([#3](https://github.com/inline0/merql/issues/3)).

## Αποθήκευση στιγμιότυπων

Τα στιγμιότυπα αποθηκεύονται στο `.merql/snapshots/` σε σχέση με τον κατάλογο εργασίας. Κάθε στιγμιότυπο είναι ένα αρχείο JSON με όνομα `<name>.json`. Εκτελείτε κάθε εντολή από τον ίδιο κατάλογο, ώστε να εντοπίζει τα στιγμιότυπα των άλλων εντολών.

Το CLI δεν διαθέτει επιλογή ή μεταβλητή περιβάλλοντος για άλλη τοποθεσία ([#8](https://github.com/inline0/merql/issues/8)). Για να χρησιμοποιήσετε άλλη τοποθεσία, μεταβείτε σε διαφορετικό κατάλογο εργασίας πριν το εκτελέσετε. Στο PHP, ορίστε τον κατάλογο πριν από την καταγραφή ή τη φόρτωση στιγμιότυπων:

```php
use Merql\Snapshot\SnapshotStore;

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

Τα αρχεία στιγμιότυπων είναι φορητά. Μπορείτε να τα αντιγράψετε μεταξύ μηχανημάτων, να τα υποβάλετε σε σύστημα ελέγχου εκδόσεων ή να τα μοιραστείτε για συνεργατικό εντοπισμό σφαλμάτων. Ένα στιγμιότυπο που καταγράφηκε από το CLI μπορεί να φορτωθεί στο PHP με το `SnapshotStore::load()`, και αντίστροφα, αρκεί και τα δύο να χρησιμοποιούν τον ίδιο κατάλογο.
