İçeriğe geç

Giriş

merql, veritabanı durumlarında üç yönlü birleştirmeler yapan saf bir PHP kitaplığıdır. Tabloların anlık görüntülerini alır, anlık görüntüler arasındaki değişiklik kümelerini hesaplar, ortak bir tabana göre iki değişiklik kümesini birleştirir ve sütun düzeyindeki çakışmaları algılar. git kaynak dosyalarında aynı algoritmayı kullanır; burada algoritma metin satırları yerine veritabanı satırları ve sütunlarına uygulanır.

Harici araç gerektirmez. Takılabilir bağlantı adaptörleri ve lehçe sürücüleri üzerinden MySQL ve SQLite destekler.

Hızlı örnek

Birleştirme için aynı verinin üç durumu gerekir: iki kopyanın başladığı base ve bağımsız olarak değiştirildikten sonraki iki kopya. Burada bir korumalı alan canlı veritabanından kopyalanmış ve o zamandan beri ikisi de düzenlenmiştir.

PHP
use Merql\Connection;
use Merql\Merql;

$live    = Connection::sqlite('/data/live.sqlite');
$sandbox = Connection::sqlite('/data/sandbox.sqlite');

// Base: live at the moment the sandbox was copied from it.
Merql::init($live);
Merql::snapshot('base');

// ... copy live.sqlite to sandbox.sqlite, then both databases change ...

// Ours: the sandbox with our edits. Theirs: live with its own changes.
Merql::init($sandbox);
Merql::snapshot('ours');
Merql::init($live);
Merql::snapshot('theirs');

$result = Merql::merge('base', 'ours', 'theirs');

if ($result->isClean()) {
    foreach ($result->operations() as $operation) {
        echo "{$operation->type} {$operation->table} #{$operation->rowKey} ({$operation->source})\n";
    }
} else {
    echo "Conflicts: {$result->conflictCount()}\n";
}

Her anlık görüntü, ilgili durumu barındıran veritabanından alınır. Üçünü de tek veritabanından art arda almak, birbirinden ayrışmış iki kopyayı tanımlamaz: theirs, ours'un değişikliklerini zaten içerir ve ours'un eklediği her satır insert_insert çakışması olarak bildirilir.

Sonuç, base durumunu birleştirilmiş duruma dönüştüren ve her iki taraftan gelen, kaynağıyla işaretlenmiş işlemleri listeler (ours, theirs veya merged). Korumalı alan değişikliklerini canlı veritabanına yazmak için, canlı veritabanında henüz bulunmayan işlemleri Korumalı Uygulama ile uygulayın.

Veya CLI üzerinden; bu araç, her snapshot için MERQL_DB_DSN içinde belirtilen veritabanına bağlanır:

Kabuk
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

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

merql'i neden kullanmalı

Durumları karşılaştıran çoğu veritabanı aracı satır düzeyinde çalışır: iki sürüm arasında bir satırdaki herhangi bir sütun farklıysa satırın tamamı çakışmalı olarak işaretlenir. İki kişi aynı satırın farklı sütunlarını düzenlediğinde bu, gerçekte olmayan çakışmalar üretir.

merql sütun düzeyinde birleştirme yapar. Bir taraf title sütununu, diğeri status sütununu değiştirdiyse değişiklikler çakışma olmadan sorunsuzca birleştirilir. Yalnızca her iki taraf da aynı sütunu farklı değerlere değiştirdiğinde çakışma bildirilir.

TEXT ve JSON sütunları için merql, hücre düzeyinde birleştirme yaparak bir seviye daha derine inebilir. Bir metin sütunundaki farklı satırlara veya JSON sütunundaki farklı anahtarlara yapılan iki düzenleme, aynı üç yönlü algoritmayla sorunsuzca birleştirilebilir. Hücre düzeyinde birleştirme isteğe bağlıdır: ThreeWayMerge öğesine bir CellMergeConfig iletin. Merql facade'ı ve CLI yalnızca sütun düzeyinde birleştirme yapar. Bkz. Hücre Düzeyinde Birleştirme.

Birleştirme modeli

Kod
         Base (snapshot at fork time)
        /                              \
   Ours (one copy's changes)            Theirs (the other copy's changes)
        \                              /
         --------- MERGE ----------
                     |
              Merged result
              + conflicts (if any)

git ile aynı üç durum. Base ortak üst öğedir. Ours ve theirs, ayrıldıktan sonraki iki kopyadır ve her biri kendi veritabanından alınır. Birleştirme kuralları her iki tarafı da aynı şekilde ele alır. Bu adlar her işlemin source alanında, çakışma türlerinde (update_delete, ours güncellendi ve theirs silindi anlamına gelir) ve OursWins ile TheirsWins çözümleme ilkelerinde kullanılır. Ortak bir temel olmadan "eklenen" ile "değiştirilmemiş" olanı ayırt edemezsiniz.

Birleştirme kendi başına hiçbir şey yazmaz. İşlemleri base'i birleştirilmiş duruma dönüştürür; bu nedenle Merql::apply() bunların tümünü sorunsuzca yalnızca hâlâ base'i tutan bir veritabanında çalıştırır. Bir tarafın değişikliklerini sandbox düzenlemelerini live ortama aktarmak gibi diğer tarafı zaten tutan bir veritabanına taşımak için yalnızca eksik işlemleri uygulayın; bkz. Korumalı Uygulama.

Gereksinimler

  • PHP 8.2 veya üzeri.
  • Metin farkını sağlayan pitmaster/pitmaster bağımlılığının gerektirdiği ext-mbstring ve ext-zlib.
  • Kullanılan adaptör için bir veritabanı uzantısı: ext-pdo_sqlite veya ext-pdo_mysql ile ext-pdo ya da ext-mysqli. merql'in composer.json yalnızca ext-pdo ve ext-mysqli önerir; bu nedenle Composer bunları denetlemez.
  • Bir MySQL veya SQLite veritabanı. Diğer motorlar için özel bir sürücü gerekir.

Ne değildir

merql bir şema geçiş aracı değildir. Veritabanlarını çoğaltmaz veya gerçek zamanlı olarak eşitlemez. Belirli bir sorunu çözer: üç veritabanı durumu verildiğinde, çakışmaları belirlenmiş dördüncü bir birleştirilmiş durum üretir.

Belgeler