انتقل إلى المحتوى

مرجع CLI

يأتي merql مع CLI لالتقاط اللقطات وحساب الفروق وتشغيل عمليات الدمج مباشرةً من الطرفية. يثبّته Composer بالاسم vendor/bin/merql؛ أما في نسخة من مستودع merql فيكون bin/merql.

يعمل vendor/bin/merql من تثبيت التبعية منذ merql 0.4.1. أما الإصدارات الأقدم فكانت تبحث عن محمّل Composer التلقائي في مجلد vendor/ الخاص بالحزمة فقط، وتفشل عند تثبيت merql كتبعية.

البدء السريع

سطر الأوامر
# 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

يتطلب الدمج ثلاثي الاتجاهات التقاط ours وtheirs من قاعدتي بيانات تفرعتا عن base. وجّه 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

لا يصلح أخذ اللقطات الثلاث جميعها من قاعدة البيانات نفسها واحدة تلو الأخرى كعملية دمج: إذ ستحتوي theirs عندئذ على تغييرات ours بالفعل، وسيُبلغ عن كل صف أدرجته ours بوصفه تعارض insert_insert.

متغيرات البيئة

يقرأ CLI تفاصيل اتصال قاعدة البيانات من متغيرات البيئة. ويمكنك الاتصال باستخدام سلسلة PDO DSN أو معلمات MySQL منفردة.

الاتصال باستخدام DSN

استخدم MERQL_DB_DSN للاتصالات المعتمدة على PDO. وهذا هو النهج الموصى به لـ SQLite والإعدادات غير القياسية. يجب أن يشير DSN إلى قاعدة بيانات MySQL أو SQLite: فلا توجد طريقة لدى CLI لتسجيل برنامج تشغيل لمحركات أخرى.

المتغير الوصف المثال
MERQL_DB_DSN سلسلة PDO DSN كاملة sqlite:/path/to/db.sqlite
MERQL_DB_USER اسم المستخدم (اختياري مع DSN) root
MERQL_DB_PASS كلمة المرور (اختيارية مع 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"

استخدم قاعدة بيانات 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
سطر الأوامر
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>

التقط الحالة الحالية لقاعدة البيانات التي تحددها متغيرات البيئة، واحفظها كلقطة مسماة. هذا هو الأمر الوحيد الذي يتصل بقاعدة بيانات.

سطر الأوامر
vendor/bin/merql snapshot baseline

المخرجات:

الكود
Snapshot 'baseline' saved
Tables: posts, comments, users, settings

تُحفظ اللقطات كملفات JSON في .merql/snapshots/ ضمن مجلد العمل (راجع تخزين اللقطات). يجب أن يتكون الاسم من أحرف وأرقام وشرطات وشرطات سفلية فقط.

سير العمل المعتاد: التقط لقطة قبل إجراء التغييرات، ثم التقط أخرى بعدها. وتشكل اللقطتان أساسًا لحساب الفروق أو الدمج.

merql diff <base> <current>

قارن بين لقطتين مسمّاتين واعرض ملخصًا للاختلافات.

سطر الأوامر
vendor/bin/merql diff baseline current

المخرجات:

الكود
Changeset: baseline -> current
  Inserts: 3
  Updates: 7
  Deletes: 1

يجب أن تكون كلتا اللقطتين موجودتين مسبقًا (وقد التُقطتا باستخدام merql snapshot). ولا يتطلب حساب الفروق اتصالًا بقاعدة بيانات، إذ يعمل على ملفات اللقطات المحفوظة.

merql merge <base> <ours> <theirs>

نفّذ دمجًا ثلاثي الاتجاهات لثلاث لقطات مسمّاة.

سطر الأوامر
vendor/bin/merql merge base ours theirs

المخرجات:

الكود
Merge: base + ours + theirs
  Operations: 12
  Conflicts:  0
  Clean:      yes

يجب أن تكون اللقطات الثلاث كلها موجودة مسبقًا. ولا يتطلب الدمج اتصالًا بقاعدة بيانات، إذ يعمل على ملفات اللقطات المحفوظة، كما أنه لا يكتب مطلقًا إلى قاعدة بيانات: فلا يتضمن CLI أمر تطبيق. استخدم PHP ‏API لتطبيق نتيجة دمج.

ينفّذ CLI الدمج على مستوى الأعمدة. ولا يدمج الخلايا داخل أعمدة TEXT أو JSON، لذا تُعد أي تعديلات مختلفة على العمود نفسه تعارضًا دائمًا هنا (#7). استخدم ThreeWayMerge مع CellMergeConfig في PHP لدمج الخلايا.

--dry-run

أضف العلامة --dry-run لمعاينة عبارات SQL التي سينشئها الدمج، من دون تنفيذ أي شيء. وتوضح العبارات كيفية تحويل حالة الأساس إلى النتيجة المدمجة، لذا تشمل تغييرات كلا الجانبين.

سطر الأوامر
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/ لمجموعة اختبار تعتمد على المحكّم المرجعي. وهي غير مضمنة في حزمة Composer، لذا لا يتوفر في تثبيت التبعية سوى vendor/bin/merql. شغّلها من جذر المستودع بعد composer install.

الأمر الوصف
./bin/oracle <name> احسب نتيجة الدمج المتوقعة لسيناريو
./bin/actual <name> شغّل merql على سيناريو والتقط المخرجات
./bin/compare <name> قارن مخرجات المحكّم بالمخرجات الفعلية
./bin/test-scenario <name> المسار الكامل: الإعداد، والمحكّم، والتنفيذ الفعلي، والمقارنة
./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 + اختبار تراجع المحكّم المرجعي

يقبل bin/test-regression أيضًا --jobs، لكنه يتجاهل القيمة حاليًا وينفذ السيناريوهات واحدًا تلو الآخر (#5). تؤدي --category غير المعروفة إلى طباعة No scenarios found والخروج بنجاح.

راجع استراتيجية الاختبار للاطلاع على تخطيط السيناريوهات.

حالة الخروج

يخرج كل من merql snapshot وdiff وmerge بالحالة 1 عند غياب وسيطة، وكذلك snapshot عند عدم إعداد اتصال. ينهي غياب لقطة الحالة الأمر باستثناء SnapshotException غير معالج وحالة خروج غير صفرية. يطبع الأمر غير المعروف Unknown command لكنه يخرج حاليًا بالحالة 0 (#3).

تخزين لقطات الحالة

تُخزَّن لقطات الحالة في .merql/snapshots/ نسبةً إلى دليل العمل. كل لقطة هي ملف JSON واحد باسم <name>.json. شغّل جميع الأوامر من الدليل نفسه لكي يعثر كل أمر على لقطات الأوامر الأخرى.

لا يتضمن CLI خيارًا أو متغير بيئة لتحديد موقع آخر (#8). لاستخدام موقع آخر، انتقل إلى دليل عمل مختلف قبل تشغيله. في PHP، حدّد الدليل قبل التقاط لقطات الحالة أو تحميلها:

PHP
use Merql\Snapshot\SnapshotStore;

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

ملفات لقطات الحالة قابلة للنقل. يمكنك نسخها بين الأجهزة، أو إيداعها في نظام للتحكم بالإصدارات، أو مشاركتها لتصحيح الأخطاء بالتعاون. يمكن تحميل لقطة التقطها CLI في PHP باستخدام SnapshotStore::load()، والعكس صحيح، ما دام الاثنان يستخدمان الدليل نفسه.