مرجع 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، حدّد الدليل قبل التقاط لقطات الحالة أو تحميلها:
use Merql\Snapshot\SnapshotStore;
SnapshotStore::setDirectory('/var/data/merql-snapshots');
ملفات لقطات الحالة قابلة للنقل. يمكنك نسخها بين الأجهزة، أو إيداعها في نظام للتحكم بالإصدارات، أو مشاركتها لتصحيح الأخطاء بالتعاون. يمكن تحميل لقطة التقطها CLI في PHP باستخدام SnapshotStore::load()، والعكس صحيح، ما دام الاثنان يستخدمان الدليل نفسه.