Referință pentru CLI
merql include un CLI pentru capturarea instantaneelor, calcularea diferențelor și executarea îmbinărilor direct din terminal. Composer îl instalează ca vendor/bin/merql; într-o copie locală a depozitului merql, acesta este bin/merql.
vendor/bin/merql funcționează după instalarea ca dependență, deoarece merql 0.4.1. Versiunile anterioare căutau autoloaderul Composer doar în directorul vendor/ propriu al pachetului și eșuau când merql era instalat ca dependență.
Pornire rapidă
# 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
O îmbinare în trei direcții necesită instantanee ale versiunilor noastre și ale celorlalți, capturate din două baze de date care au evoluat separat pornind de la baza comună. Indicați baza de date potrivită pentru fiecare instantaneu folosind MERQL_DB_DSN:
# 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
Capturarea pe rând a tuturor celor trei instantanee din aceeași bază de date nu funcționează pentru o îmbinare: versiunea celorlalți ar conține deja modificările noastre, astfel că fiecare rând inserat de noi ar fi raportat drept conflict insert_insert.
Variabile de mediu
CLI citește detaliile conexiunii la baza de date din variabilele de mediu. Vă puteți conecta folosind fie un șir DSN PDO, fie parametri MySQL individuali.
Conexiune bazată pe DSN
Folosiți MERQL_DB_DSN pentru conexiunile bazate pe PDO. Aceasta este abordarea recomandată
pentru SQLite și pentru configurațiile nestandard. DSN-ul trebuie să indice o bază de date MySQL
sau SQLite: CLI nu poate înregistra un driver pentru alte motoare.
| Variabilă | Descriere | Exemplu |
|---|---|---|
MERQL_DB_DSN |
Șir DSN PDO complet | sqlite:/path/to/db.sqlite |
MERQL_DB_USER |
Nume de utilizator (opțional cu DSN) | root |
MERQL_DB_PASS |
Parolă (opțională cu DSN) | secret |
# 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"
Folosiți o bază de date SQLite bazată pe fișier. Fiecare comandă CLI rulează
într-un proces propriu, așadar sqlite::memory: deschide întotdeauna o bază de date nouă și goală, iar instantaneul acesteia
nu conține tabele.
Forma prescurtată MySQL
Când MERQL_DB_DSN nu este setat, CLI folosește ca alternativă variabilele specifice MySQL.
| Variabilă | Valoare implicită | Descriere |
|---|---|---|
MERQL_DB_NAME |
(obligatoriu) | Numele bazei de date |
MERQL_DB_HOST |
127.0.0.1 |
Gazda MySQL |
MERQL_DB_PORT |
3306 |
Portul MySQL |
MERQL_DB_USER |
root |
Numele de utilizator MySQL |
MERQL_DB_PASS |
(gol) | Parola MySQL |
MERQL_DB_ADAPTER |
pdo |
Setați la mysqli pentru a folosi adaptorul mysqli |
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"
Comenzi
merql snapshot <name>
Capturați starea curentă a bazei de date indicate de variabilele de mediu și salvați-o ca instantaneu cu nume. Aceasta este singura comandă care se conectează la o bază de date.
vendor/bin/merql snapshot baseline
Rezultat:
Snapshot 'baseline' saved
Tables: posts, comments, users, settings
Instantaneele sunt salvate ca fișiere JSON în .merql/snapshots/, sub directorul de lucru (consultați Stocarea instantaneelor). Numele poate conține doar caractere alfanumerice, cratime și liniuțe de subliniere.
Flux de lucru obișnuit: capturați un instantaneu înainte de a face modificări, apoi capturați altul după. Cele două instantanee stau la baza unei comparații sau îmbinări.
merql diff <base> <current>
Comparați două instantanee cu nume și afișați un rezumat al diferențelor.
vendor/bin/merql diff baseline current
Rezultat:
Changeset: baseline -> current
Inserts: 3
Updates: 7
Deletes: 1
Ambele instantanee trebuie să existe deja (capturate anterior cu merql snapshot). Comparația nu necesită o conexiune la baza de date, deoarece operează pe fișierele de instantaneu salvate.
merql merge <base> <ours> <theirs>
Efectuați o îmbinare în trei direcții a trei instantanee cu nume.
vendor/bin/merql merge base ours theirs
Rezultat:
Merge: base + ours + theirs
Operations: 12
Conflicts: 0
Clean: yes
Toate cele trei instantanee trebuie să existe deja. Îmbinarea nu necesită o conexiune la baza de date, deoarece operează pe fișierele de instantaneu salvate, și nu scrie niciodată într-o bază de date: CLI nu are nicio comandă de aplicare. Folosiți PHP API pentru a aplica rezultatul îmbinării.
CLI face îmbinarea la nivel de coloană. Nu aplică îmbinarea la nivel de celulă pentru coloanele TEXT sau JSON, așadar două editări diferite ale aceleiași coloane sunt întotdeauna un conflict aici (#7). Pentru îmbinare la nivel de celulă, folosiți ThreeWayMerge cu un CellMergeConfig în PHP.
--dry-run
Adăugați opțiunea --dry-run pentru a previzualiza instrucțiunile SQL pe care le-ar genera îmbinarea, fără a executa nimic. Instrucțiunile descriu cum să transformați starea de bază în rezultatul îmbinat, așadar includ modificările ambelor părți.
vendor/bin/merql merge base ours theirs --dry-run
Rezultat:
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';
Comenzi de dezvoltare
O copie locală a depozitului merql include mai multe scripturi în bin/ pentru suita sa de teste bazată pe oracle. Acestea nu fac parte din pachetul Composer, așadar instalarea ca dependență include doar vendor/bin/merql. Rulați-le din rădăcina depozitului după composer install.
| Comandă | Descriere |
|---|---|
./bin/oracle <name> |
Calculează rezultatul de îmbinare așteptat pentru un scenariu |
./bin/actual <name> |
Rulează merql pentru un scenariu și capturează rezultatul |
./bin/compare <name> |
Compară rezultatul oracle cu cel efectiv |
./bin/test-scenario <name> |
Flux complet: configurare, oracle, rezultat efectiv, comparare |
./bin/test-regression |
Rulează toate scenariile |
./bin/test-regression --category clean |
Rulează o categorie: clean, conflict, identity, types, scale sau edge |
./bin/test-regression --fast |
Doar reușită/eșec, fără rapoarte |
./bin/verify-compliance |
Raport complet de conformitate |
./bin/verify-all |
PHPStan + stilul codului + PHPUnit + regresie oracle |
bin/test-regression acceptă și --jobs, dar momentan ignoră valoarea și rulează scenariile unul după altul (#5). O valoare --category necunoscută afișează No scenarios found și se încheie cu succes.
Consultați Strategia de testare pentru structura scenariilor.
Cod de ieșire
merql snapshot, diff și merge se încheie cu codul 1 când lipsește un argument, iar snapshot se încheie la fel și când nu este configurată nicio conexiune. Dacă lipsește un instantaneu, comanda se încheie cu o excepție SnapshotException neprinsă și un cod de ieșire diferit de zero. O comandă necunoscută afișează Unknown command, dar momentan se încheie cu codul 0 (#3).
Stocarea instantaneelor
Instantaneele sunt stocate în .merql/snapshots/ relativ la directorul de lucru. Fiecare instantaneu este un singur fișier JSON cu numele <name>.json. Rulați toate comenzile din același director pentru ca acestea să găsească instantaneele celorlalte comenzi.
CLI nu are nicio opțiune sau variabilă de mediu pentru o altă locație (#8). Pentru a folosi altă locație, schimbați directorul de lucru înainte de a-l rula. În PHP, setați directorul înainte de a captura sau încărca instantanee:
use Merql\Snapshot\SnapshotStore;
SnapshotStore::setDirectory('/var/data/merql-snapshots');
Fișierele de instantaneu sunt portabile. Le puteți copia între mașini, include în sistemul de control al versiunilor sau partaja pentru depanare colaborativă. Un instantaneu capturat de CLI poate fi încărcat în PHP cu SnapshotStore::load() și invers, atât timp cât ambele folosesc același director.