Przejdź do treści

PHP API Dokumentacja referencyjna

Pełna dokumentacja wszystkich publicznych klas i metod w merql.

Merql (fasada)

Merql\Merql to statyczny punkt wejścia do typowych operacji. Opakowuje klasy niższego poziomu i automatycznie zarządza trwałym zapisem migawek.

PHP
use Merql\Connection;
use Merql\Identity\IdentityRule;
use Merql\Identity\IdentityRuleSet;
use Merql\Merql;

$connection = Connection::sqlite(':memory:');
Merql::init($connection, identityRules: new IdentityRuleSet([
    'options' => IdentityRule::natural(['option_name']),
]));

init(DatabaseConnection $connection, ?Driver $driver = null, ?IdentityRuleSet $identityRules = null): void

Zainicjuj fasadę, przekazując połączenie z bazą danych. Należy wywołać tę metodę przed snapshot(), apply() lub applyGuarded(); wywołaj ją ponownie, aby przełączyć bazy danych, na przykład w celu utworzenia migawek naszej i ich strony z dwóch różnych kopii. Bez $driver metoda wywołuje DriverFactory::create(), które zgłasza wyjątek dla silników innych niż MySQL i SQLite, chyba że zarejestrowano sterownik. Przekaż sterownik, aby zastąpić automatyczne wykrywanie, albo zestaw reguł tożsamości, aby zastąpić tożsamość wierszy dla poszczególnych tabel podczas przechwytywania migawki.

snapshot(string $name, array $tables = []): Snapshot

Przechwyć bieżący stan bazy danych i zapisz go na dysku. Przekaż tablicę nazw tabel, aby utworzyć migawki wybranych tabel, albo pomiń ten argument, aby uwzględnić wszystkie tabele.

PHP
$snapshot = Merql::snapshot('baseline');
$snapshot = Merql::snapshot('baseline', ['posts', 'users']);

diff(string $base, string $current): Changeset

Wczytaj dwie nazwane migawki i oblicz między nimi zestaw zmian. Nie wymaga init(), ponieważ korzysta z zapisanych migawek.

PHP
$changeset = Merql::diff('before', 'after');

merge(string $base, string $ours, string $theirs): MergeResult

Scal trzy nazwane migawki. Zwraca wynik zawierający czyste operacje i ewentualne konflikty. Scala na poziomie kolumn: fasada tworzy ThreeWayMerge bez CellMergeConfig, więc scalanie na poziomie komórek nie jest stosowane. W tym celu użyj bezpośrednio ThreeWayMerge.

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

patch(string $base, string $changes): MergeResult

Scalanie dwukierunkowe: zastosuj zmiany do bazy. Równoważne merge($base, $base, $changes). Zawsze daje czysty wynik, ponieważ nie ma równoczesnych edycji. Tylko na poziomie kolumn, podobnie jak merge().

PHP
$result = Merql::patch('base', 'changes');

apply(MergeResult $result): ApplyResult

Wykonaj czysty wynik scalania na bazie danych przekazanej do init(). Wymaga init(). Zgłasza ConflictException, jeśli pozostają nierozwiązane konflikty.

Wykonywana jest każda operacja z wyniku, więc pełny wynik merge() można zastosować bez konfliktów tylko do bazy danych, która nadal zawiera stan bazowy. Jeśli baza zawiera już stan jednej ze stron, zastosuj wybrane operacje, których jej brakuje; zobacz Guarded Apply.

PHP
$applied = Merql::apply($result);
echo $applied->rowsAffected();

plan(string $id, string $base, string $ours, string $theirs, array $metadata = []): MergePlan

Utwórz plan scalania gotowy do UI na podstawie trzech nazwanych migawek. Plan obejmuje stabilne identyfikatory operacji, identyfikatory grup zmian, kontekst operacji, konflikty, niezgodności schematów, podsumowanie, metadane i skrót planu. Scalanie odbywa się na poziomie kolumn, jak w merge(); przekaż wynik scalony na poziomie komórek do MergePlanBuilder::build(), aby scalić na poziomie komórek.

PHP
$plan = Merql::plan('plan-1', 'base', 'ours', 'theirs', [
    'source' => 'review-ui',
]);

applyGuarded(MergeResult $result, Snapshot $expectedLive): ApplyResult

Zastosuj czysty wynik scalania z optymistycznymi warunkami wstępnymi dla aktywnych wierszy. Aktualizacje i usunięcia wymagają, aby bieżące aktywne wiersze odpowiadały $expectedLive; w przypadku wstawień wymagane jest, aby docelowa tożsamość jeszcze nie istniała. $expectedLive to migawka docelowej bazy danych (ich strony, gdy przenosimy naszą stronę do bazy, z której utworzono ich migawkę). Każda instrukcja, która zmieni zero wierszy, powoduje wycofanie transakcji.

PHP
use Merql\Snapshot\SnapshotStore;

$applied = Merql::applyGuarded($selectedResult, SnapshotStore::load('theirs'));

reset(): void

Wyczyść wewnętrzne instancje połączenia i modułu Snapshotter. Służy głównie do resetowania stanu między uruchomieniami testów.


Połączenie

Merql\Connection tworzy adaptery połączeń z rozsądnymi ustawieniami domyślnymi. Połączenia PDO zgłaszają wyjątki w razie błędu, używają asocjacyjnego trybu pobierania, wyłączają emulowane przygotowywanie zapytań i zwracają pobrane wartości jako ciągi znaków. Adapter mysqli normalizuje pobrane wartości do takiej samej postaci ciągu znaków lub null.

mysql(string $host, string $database, string $username, string $password = '', int $port = 3306, string $charset = 'utf8mb4'): PdoDatabaseConnection

PHP
use Merql\Connection;

$connection = Connection::mysql('127.0.0.1', 'my_app', 'root', 'secret');

mysqli(string $host, string $database, string $username, string $password = '', int $port = 3306, string $charset = 'utf8mb4'): MysqliDatabaseConnection

PHP
$connection = Connection::mysqli('127.0.0.1', 'my_app', 'root', 'secret');

sqlite(string $path = ':memory:'): PdoDatabaseConnection

Tworzy połączenie SQLite. Automatycznie włącza klucze obce za pomocą PRAGMA foreign_keys = ON.

PHP
$connection = Connection::sqlite('/var/data/app.sqlite');
$connection = Connection::sqlite(':memory:');

fromDsn(string $dsn, string $username = '', string $password = ''): PdoDatabaseConnection

Nawiąż połączenie, używając dowolnego ciągu DSN PDO. merql zawiera sterowniki tylko dla mysql i sqlite; inne DSN nawiązują połączenie, ale Merql::init(), Snapshotter i moduły stosujące zmiany zgłaszają Unsupported database driver, chyba że sterownik został zarejestrowany przez DriverFactory::register().

PHP
$connection = Connection::fromDsn('mysql:host=localhost;dbname=app', 'root', 'pass');

fromPdo(PDO $pdo): PdoDatabaseConnection

Opakuj istniejącą instancję PDO.

fromMysqli(mysqli $mysqli, string $charset = 'utf8mb4'): MysqliDatabaseConnection

Opakuj istniejącą instancję mysqli.

Kontrakt adaptera

Wszystkie adaptery implementują Merql\Database\DatabaseConnection:

PHP
interface DatabaseConnection
{
    public function driverName(): string;
    public function execute(string $sql, array $params = []): int;
    public function query(string $sql, array $params = []): array;
    public function scalar(string $sql, array $params = []): ?string;
    public function beginTransaction(): void;
    public function commit(): void;
    public function rollBack(): void;
    public function lastInsertId(): string;
}

execute(), query() i scalar() przyjmują pozycyjne parametry list<scalar|null> dla symboli zastępczych ?. query() zwraca list<array<string, scalar|null>>; wartości są normalizowane do takiej samej postaci ciągu znaków lub null przez adaptery PDO i mysqli.


Snapshotter

Merql\Snapshot\Snapshotter przechwytuje stan bazy danych. W przeciwieństwie do fasady daje pełną kontrolę nad filtrami i nie zapisuje danych automatycznie.

__construct(DatabaseConnection $connection, ?Driver $driver = null, ?IdentityRuleSet $identityRules = null)

Jeśli nie podano sterownika, jest on automatycznie wykrywany na podstawie tożsamości połączenia. Przekaż IdentityRuleSet, gdy tożsamość wierszy dla poszczególnych tabel ma zastępować domyślne ustawienia schematu.

capture(string $name, array $tables = [], array $filters = []): Snapshot

Przechwyć bieżący stan. Podaj nazwy tabel, aby ograniczyć zakres. Przekaż obiekty filtrów, aby wykluczyć tabele, kolumny lub wiersze.

PHP
use Merql\Snapshot\Snapshotter;
use Merql\Filter\TableFilter;
use Merql\Filter\ColumnFilter;
use Merql\Filter\RowFilter;
use Merql\Identity\IdentityRule;
use Merql\Identity\IdentityRuleSet;

$snapshotter = new Snapshotter(
    $connection,
    identityRules: new IdentityRuleSet([
        'wp_options' => IdentityRule::natural(['option_name']),
    ]),
);

// All tables.
$snapshot = $snapshotter->capture('full');

// Specific tables with filters.
$snapshot = $snapshotter->capture('filtered', ['posts', 'users'], [
    TableFilter::exclude(['cache_*', 'sessions']),
    ColumnFilter::ignore(['updated_at', 'created_at']),
    RowFilter::create(fn(string $table, array $row) => $row['status'] !== 'trash'),
]);

captureAliased(string $name, array $physicalToCanonicalTableMap, array $filters = []): Snapshot

Przechwytuj tabele fizyczne pod kanonicznymi nazwami tabel. Użyj tego, gdy ta sama tabela logiczna ma różne nazwy fizyczne w poszczególnych środowiskach.

PHP
$snapshot = $snapshotter->captureAliased('sandbox', [
    'wp_onumia_abcd_posts' => 'wp_posts',
    'wp_onumia_abcd_postmeta' => 'wp_postmeta',
]);

Wynikowa migawka przechowuje kanoniczne nazwy tabel, zachowując schemat fizycznej tabeli, skonfigurowane kolumny tożsamości, klucze wierszy i filtry.

fromData(string $name, array $tableData): Snapshot (statyczna)

Utwórz migawkę z surowych danych bez połączenia z bazą danych. Przydatne do testów lub importowania danych z innego źródła.

PHP
use Merql\Snapshot\Snapshotter;
use Merql\Snapshot\TableSnapshotData;
use Merql\Schema\TableSchema;

$schema = new TableSchema('posts', ['id' => 'int', 'title' => 'varchar'], ['id']);

$snapshot = Snapshotter::fromData('test', [
    'posts' => new TableSnapshotData($schema, [
        ['id' => '1', 'title' => 'Hello'],
        ['id' => '2', 'title' => 'World'],
    ], ['id']),
]);

Migawka

Merql\Snapshot\Snapshot to obiekt wartości tylko do odczytu, reprezentujący kompletny stan bazy danych.

PHP
$snapshot->name;                    // string: snapshot identifier
$snapshot->tables;                  // array<string, TableSnapshot>
$snapshot->tableNames();            // list<string>
$snapshot->hasTable('posts');       // bool
$snapshot->getTable('posts');       // ?TableSnapshot

TableSnapshot

Merql\Snapshot\TableSnapshot zawiera wiersze, odciski palców i schemat jednej tabeli.

PHP
$table = $snapshot->getTable('posts');

$table->schema;                    // TableSchema
$table->identityColumns;           // list<string>: columns used for row identity
$table->fingerprints;              // array<string, string>: row key to hash
$table->rows;                      // array<string, array<string, mixed>>

$table->rowKeys();                 // list<string>
$table->rowCount();                // int
$table->hasRow('42');              // bool
$table->getRow('42');              // ?array<string, mixed>
$table->getFingerprint('42');      // ?string

TableSnapshotData

Merql\Snapshot\TableSnapshotData to dane wejściowe dla Snapshotter::fromData().

PHP
use Merql\Snapshot\TableSnapshotData;
use Merql\Schema\TableSchema;

$data = new TableSnapshotData(
    schema: new TableSchema('posts', ['id' => 'int', 'title' => 'varchar'], ['id']),
    rows: [
        ['id' => '1', 'title' => 'First Post'],
    ],
    identityColumns: ['id'],
);

IdentityRule

Merql\Identity\IdentityRule określa kolumny używane do budowania kluczy wierszy.

PHP
use Merql\Identity\IdentityRule;

$primary = IdentityRule::primary(['id']);
$natural = IdentityRule::natural(['option_name']);
$composite = IdentityRule::composite(['object_id', 'term_taxonomy_id']);
$content = IdentityRule::content(['name', 'value']);

$key = $natural->key(['option_name' => 'siteurl']);
// "siteurl"

forSchema(TableSchema $schema): IdentityRule (statyczna)

Rozpoznaj domyślną regułę tożsamości ze schematu: klucz główny, pierwszy klucz unikatowy, a następnie zapasowo zawartość.

toArray(): array

Serializuj regułę jako ['type' => string, 'columns' => list<string>].

fromArray(array $data): IdentityRule (statyczna)

Odtwórz regułę z zserializowanych danych.


IdentityRuleSet

Merql\Identity\IdentityRuleSet przechowuje zastąpienia tożsamości dla poszczególnych tabel.

PHP
use Merql\Identity\IdentityRule;
use Merql\Identity\IdentityRuleSet;

$rules = new IdentityRuleSet([
    'wp_options' => IdentityRule::natural(['option_name']),
]);

$rule = $rules->ruleFor($schema);

with(string $table, IdentityRule $rule): IdentityRuleSet

Zwróć nowy zestaw reguł z dodanym zastąpieniem dla jednej tabeli.

conflictsFor(string $table, IdentityRule $rule, array $rows): array

Zwraca wpisy IdentityConflict, gdy wiele wierszy dla danej reguły daje ten sam klucz.

toArray(): array

Serializuj reguły tabel jako tablicę bezpieczną dla JSON.

fromArray(array $data): IdentityRuleSet (statyczna)

Odtwórz zestaw reguł z zserializowanych danych.


SnapshotStore

Merql\Snapshot\SnapshotStore zapisuje i wczytuje migawki jako pliki JSON.

setDirectory(string $directory): void

Ustaw katalog przechowywania. Domyślnie jest to .merql/snapshots.

save(Snapshot $snapshot): void

Zapisz migawkę na dysku.

load(string $name): Snapshot

Wczytaj migawkę według nazwy. Zgłasza SnapshotException, jeśli nie znaleziono pliku.

exists(string $name): bool

Sprawdź, czy plik migawki istnieje.

delete(string $name): void

Usuń plik migawki.


Differ

Merql\Diff\Differ porównuje dwie migawki i tworzy zestaw zmian.

diff(Snapshot $base, Snapshot $current): Changeset

PHP
use Merql\Diff\Differ;

$differ = new Differ();
$changeset = $differ->diff($baseSnapshot, $currentSnapshot);

valuesEqual(mixed $a, mixed $b): bool (statyczna)

Porównaj dwie wartości po konwersji do ciągu znaków. NULL jest traktowane jako odrębna wartość: NULL === NULL to prawda, NULL === '' to fałsz.


Zestaw zmian

Merql\Diff\Changeset to kolekcja operacji na poziomie wierszy, tylko do odczytu.

PHP
$changeset->inserts();             // list<RowInsert>
$changeset->updates();             // list<RowUpdate>
$changeset->deletes();             // list<RowDelete>
$changeset->isEmpty();             // bool
$changeset->count();               // int: total operations
$changeset->forTable('posts');     // Changeset: filtered to one table

RowInsert, RowUpdate, RowDelete

Obiekty wartości tylko do odczytu reprezentujące pojedyncze zmiany wierszy.

RowInsert

PHP
$insert->table;                    // string
$insert->rowKey;                   // string
$insert->values;                   // array<string, mixed>

RowUpdate

PHP
$update->table;                    // string
$update->rowKey;                   // string
$update->columnDiffs;              // list<ColumnDiff>
$update->fullRow;                  // array<string, mixed>: complete current row
$update->columnDiffMap();          // array<string, ColumnDiff>: keyed by column name

RowDelete

PHP
$delete->table;                    // string
$delete->rowKey;                   // string
$delete->oldValues;                // array<string, mixed>: values before deletion

ColumnDiff

Merql\Diff\ColumnDiff reprezentuje pojedynczą zmianę kolumny w ramach aktualizacji wiersza.

PHP
$diff->column;                     // string
$diff->oldValue;                   // mixed
$diff->newValue;                   // mixed

ThreeWayMerge

Merql\Merge\ThreeWayMerge to główny algorytm scalania.

__construct(?CellMergeConfig $cellMergeConfig = null)

Przekaż CellMergeConfig, aby włączyć scalanie na poziomie komórek dla kolumn TEXT i JSON.

PHP
use Merql\Merge\ThreeWayMerge;
use Merql\CellMerge\CellMergeConfig;

// Default: column-level merge only.
$merge = new ThreeWayMerge();

// With cell-level merge for TEXT and JSON columns.
$merge = new ThreeWayMerge(CellMergeConfig::auto());

merge(Snapshot $base, Snapshot $ours, Snapshot $theirs): MergeResult

Wykonaj scalanie trójstronne. Wewnętrznie oblicza zestawy zmian (od stanu bazowego do naszej strony i od stanu bazowego do ich strony), a następnie je scala.

PHP
$result = $merge->merge($baseSnapshot, $oursSnapshot, $theirsSnapshot);

patch(Snapshot $base, Snapshot $changes): MergeResult

Skrót do scalania dwukierunkowego. Równoważne merge($base, $base, $changes).

schemaMismatches(): array

Zwraca SchemaException[] dla wszelkich różnic schematu wykrytych podczas ostatniego scalania (kolumn dodanych lub usuniętych między migawkami).


MergeResult

Merql\Merge\MergeResult to obiekt wartości tylko do odczytu zawierający wynik scalania.

PHP
$result->isClean();                // bool: no conflicts
$result->operations();             // list<MergeOperation>
$result->conflicts();              // list<Conflict>
$result->operationCount();         // int
$result->conflictCount();          // int
$result->baseSnapshot();           // ?Snapshot
$result->schemaMismatches();       // list<SchemaException>
$result->hasSchemaMismatches();    // bool

MergePlan

Merql\Plan\MergePlan to serializowalny model przeglądu scalania.

PHP
$plan->id;                        // string
$plan->baseSnapshot;              // string
$plan->oursSnapshot;              // string
$plan->theirsSnapshot;            // string
$plan->summary;                   // MergePlanSummary
$plan->changeGroups;              // list<MergePlanChangeGroup>
$plan->operations;                // list<MergePlanOperation>
$plan->conflicts;                 // list<MergePlanConflict>
$plan->schemaMismatches;          // list<string>
$plan->hash;                      // string
$plan->metadata;                  // array<string, mixed>

Użyj MergePlanSerializer::toJson() i ::fromJson(), aby zapewnić stabilną obsługę konwersji JSON w obie strony.

Wybory

ChangeGroupSelection przechowuje identyfikatory przygotowanych grup zmian. Przekształć go w OperationSelection podczas tworzenia wybranych wyników scalania lub planów wycofania.

PHP
use Merql\Plan\ChangeGroupSelection;
use Merql\Plan\SelectedMergeResultFactory;

$selection = ChangeGroupSelection::fromIds([$groupId]);
$operationSelection = $selection->toOperationSelection($plan);

$selected = (new SelectedMergeResultFactory())
    ->fromOperationSelection($plan, $operationSelection);

RollbackPlan

Merql\Rollback\RollbackPlan przechowuje operacje odwrotne i oczekiwania dotyczące rozbieżności przy wybranym zastosowaniu zmian.

PHP
use Merql\Rollback\RollbackPlanBuilder;
use Merql\Rollback\RollbackPlanSerializer;

$rollback = (new RollbackPlanBuilder())->build(
    'rollback-1',
    $plan,
    $operationSelection,
    $liveBeforeRows,
);

$json = RollbackPlanSerializer::toJson($rollback);

Użyj RollbackDrift przed zastosowaniem wycofania, a następnie RollbackPlanApplier, aby uruchomić operacje odwrotne.


MergeOperation

Merql\Merge\MergeOperation to pojedyncza, rozstrzygnięta operacja scalania.

PHP
$op->type;                         // string: 'insert' | 'update' | 'delete'
$op->table;                        // string
$op->rowKey;                       // string
$op->values;                       // array<string, mixed>
$op->source;                       // string: 'ours' | 'theirs' | 'merged'

Stałe typów:

PHP
MergeOperation::TYPE_INSERT;       // 'insert'
MergeOperation::TYPE_UPDATE;       // 'update'
MergeOperation::TYPE_DELETE;       // 'delete'

Konflikt

Merql\Merge\Conflict reprezentuje nierozwiązany konflikt scalania.

PHP
$conflict->table();                // string
$conflict->rowKey();               // string
$conflict->type();                 // string: 'update_update' | 'update_delete' | 'delete_update' | 'insert_insert'
$conflict->column();               // ?string (null for structural conflicts)
$conflict->oursValue();            // mixed
$conflict->theirsValue();          // mixed
$conflict->baseValue();            // mixed
$conflict->primaryKey(['id']);     // array<string, string>: decoded from rowKey

Typy konfliktów

Typ Znaczenie
update_update Obie strony zmieniły tę samą kolumnę na różne wartości
update_delete Nasza strona zaktualizowała wiersz, który ich strona usunęła
delete_update Nasza strona usunęła wiersz, który ich strona zaktualizowała
insert_insert Obie strony wstawiły wiersz z tym samym kluczem głównym

ConflictResolver

Merql\Merge\ConflictResolver stosuje zasady rozstrzygania do wszystkich konfliktów w wyniku scalania.

resolve(MergeResult $result, ConflictPolicy $policy): MergeResult (statyczna)

Zwraca nowy obiekt MergeResult z konfliktami rozwiązanymi zgodnie z przyjętą zasadą.

PHP
use Merql\Merge\ConflictResolver;
use Merql\Merge\ConflictPolicy;

// Accept all "theirs" values when conflicts arise.
$resolved = ConflictResolver::resolve($result, ConflictPolicy::TheirsWins);

// Accept all "ours" values.
$resolved = ConflictResolver::resolve($result, ConflictPolicy::OursWins);

// Return unchanged (for manual inspection).
$resolved = ConflictResolver::resolve($result, ConflictPolicy::Manual);

ConflictPolicy

Merql\Merge\ConflictPolicy to wyliczenie bazowe z trzema przypadkami.

PHP
use Merql\Merge\ConflictPolicy;

ConflictPolicy::OursWins;          // Resolve all conflicts in favor of "ours"
ConflictPolicy::TheirsWins;        // Resolve all conflicts in favor of "theirs"
ConflictPolicy::Manual;            // Leave conflicts unresolved for manual handling

ColumnMerge

Merql\Merge\ColumnMerge wykonuje logikę scalania dla poszczególnych kolumn w jednym wierszu. Jest wewnętrznie używany przez ThreeWayMerge.

merge(string $table, string $rowKey, array $base, array $ours, array $theirs, ?CellMergeConfig $cellMergeConfig = null, array $columnTypes = []): array (statyczna)

Zwraca ['values' => array, 'conflicts' => list<Conflict>].

PHP
use Merql\Merge\ColumnMerge;

$result = ColumnMerge::merge(
    'posts',
    '42',
    ['title' => 'Hello', 'status' => 'draft'],     // base
    ['title' => 'Hello', 'status' => 'published'],  // ours
    ['title' => 'New Title', 'status' => 'draft'],   // theirs
);

// $result['values'] = ['title' => 'New Title', 'status' => 'published']
// $result['conflicts'] = [] (clean merge)

Applier

Merql\Apply\Applier wykonuje wynik scalania na bazie danych.

__construct(DatabaseConnection $connection, ?Driver $driver = null)

apply(MergeResult $result, ?Snapshot $base = null): ApplyResult

Wykonuje wszystkie operacje w ramach jednej transakcji. W razie błędu wycofuje transakcję i zgłasza go w ApplyResult::errors() zamiast rzucać wyjątek. Zgłasza ConflictException, jeśli wynik zawiera nierozwiązane konflikty.

PHP
use Merql\Apply\Applier;

$applier = new Applier($connection);
$applied = $applier->apply($result);

echo "Rows affected: {$applied->rowsAffected()}\n";
if ($applied->hasErrors()) {
    print_r($applied->errors());
}

Kolejność kluczy obcych jest obsługiwana automatycznie: wstawienia są sortowane według zależności, a usunięcia w odwrotnej kolejności zależności.


ApplyResult

Merql\Apply\ApplyResult to obiekt wartości tylko do odczytu zwracany przez moduł stosujący zmiany.

PHP
$applied->rowsAffected();         // int
$applied->errors();               // list<string>
$applied->hasErrors();            // bool

Po wycofaniu zastosowania zmian rowsAffected() nadal zlicza instrukcje wykonane przed błędem (#4). Przed uznaniem tej liczby za wiarygodną sprawdź hasErrors().


DryRun

Merql\Apply\DryRun generuje czytelne dla człowieka instrukcje SQL bez wykonywania czegokolwiek.

generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (statyczna)

Zwraca listę ciągów SQL z wstawionymi wartościami (wyłącznie do wyświetlania).

PHP
use Merql\Apply\DryRun;

$statements = DryRun::generate($result);

foreach ($statements as $sql) {
    echo "{$sql};\n";
}

// Output:
// INSERT INTO `posts` (`id`, `title`) VALUES ('10', 'New Post');
// UPDATE `posts` SET `title` = 'Updated' WHERE `id` = '5';
// DELETE FROM `comments` WHERE `id` = '3';

SqlGenerator

Merql\Apply\SqlGenerator generuje parametryzowane instrukcje SQL. Jest wewnętrznie używany zarówno przez Applier, jak i DryRun.

generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (statyczna)

Zwraca list<array{sql: string, params: list<scalar|null>}>.

PHP
use Merql\Apply\SqlGenerator;

$statements = SqlGenerator::generate($result);

foreach ($statements as $stmt) {
    $connection->execute($stmt['sql'], $stmt['params']);
}

CellMergeConfig

Merql\CellMerge\CellMergeConfig konfiguruje strategie scalania komórek dla określonych kolumn lub typów kolumn.

auto(): self (statyczna)

Fabryka ułatwiająca przypisanie TextCellMerger do kolumn TEXT/LONGTEXT oraz JsonCellMerger do kolumn JSON.

PHP
use Merql\CellMerge\CellMergeConfig;

$config = CellMergeConfig::auto();

forColumn(string $column, CellMerger $merger): self

Przypisz moduł scalający do konkretnej kolumny. Użyj table.column dla nazw kwalifikowanych albo samego column dla wszystkich tabel.

PHP
use Merql\CellMerge\CellMergeConfig;
use Merql\CellMerge\TextCellMerger;

$config = (new CellMergeConfig())
    ->forColumn('posts.content', new TextCellMerger())
    ->forColumn('description', new TextCellMerger());

forType(string $typePattern, CellMerger $merger): self

Przypisz mechanizm scalania do wszystkich kolumn pasujących do wzorca typu (dopasowanie podciągu bez rozróżniania wielkości liter).

PHP
use Merql\CellMerge\CellMergeConfig;
use Merql\CellMerge\JsonCellMerger;

$config = (new CellMergeConfig())
    ->forType('json', new JsonCellMerger());

getMerger(string $table, string $column, string $columnType = ''): CellMerger

Znajdź mechanizm scalania dla podanej tabeli, kolumny i typu. Priorytet: kwalifikowana nazwa kolumny, niekwalifikowana nazwa kolumny, wzorzec typu, wartość domyślna (nieprzezroczysta).


CellMerger (interfejs)

Merql\CellMerge\CellMerger to interfejs strategii scalania na poziomie komórek.

PHP
use Merql\CellMerge\CellMerger;
use Merql\CellMerge\CellMergeResult;

interface CellMerger
{
    public function merge(mixed $base, mixed $ours, mixed $theirs): CellMergeResult;
}

Dostępne są trzy wbudowane implementacje.

TextCellMerger

Merql\CellMerge\TextCellMerger scala tekst wielowierszowy za pomocą trójstronnego porównania wiersz po wierszu (tego samego algorytmu, którego git używa do zawartości plików). Gdy obie strony edytują różne wiersze, scalanie przebiega bez konfliktów. Gdy obie strony różnie edytują ten sam wiersz, zgłaszany jest konflikt.

PHP
use Merql\CellMerge\TextCellMerger;

$merger = new TextCellMerger();
$result = $merger->merge(
    "line 1\nline 2\nline 3",
    "line 1\nline 2 modified\nline 3",
    "line 1\nline 2\nline 3 modified",
);
// $result->clean === true
// $result->value === "line 1\nline 2 modified\nline 3 modified"

JsonCellMerger

Merql\CellMerge\JsonCellMerger scala wartości JSON, porównując niezależnie klucze najwyższego poziomu. Każdy klucz jest scalany z użyciem logiki trójstronnej. Zagnieżdżone obiekty są porównywane jako nieprzezroczyste ciągi JSON (bez rekurencyjnego scalania).

PHP
use Merql\CellMerge\JsonCellMerger;

$merger = new JsonCellMerger();
$result = $merger->merge(
    '{"a": 1, "b": 2}',
    '{"a": 10, "b": 2}',        // changed "a"
    '{"a": 1, "b": 20}',         // changed "b"
);
// $result->clean === true
// $result->value === '{"a":10,"b":20}'

OpaqueCellMerger

Merql\CellMerge\OpaqueCellMerger jest wartością domyślną. Traktuje wartości jako nieprzezroczyste ciągi i zawsze zgłasza konflikt, gdy się różnią.


CellMergeResult

Merql\CellMerge\CellMergeResult to typ zwracany przez wszystkie mechanizmy scalania komórek.

PHP
$result->clean;                    // bool: true if merge succeeded
$result->value;                    // mixed: merged value (or ours on conflict)
$result->conflicts;                // int: number of conflicts

// Factory methods.
CellMergeResult::resolved($value);           // clean merge
CellMergeResult::conflict($oursValue, $n);   // conflict with count

TableSchema

Merql\Schema\TableSchema to reprezentacja struktury tabeli tylko do odczytu.

PHP
use Merql\Schema\TableSchema;

$schema = new TableSchema(
    name: 'posts',
    columns: ['id' => 'int', 'title' => 'varchar(255)', 'content' => 'text'],
    primaryKey: ['id'],
    uniqueKeys: [['slug']],
);

$schema->name;                     // string
$schema->columns;                  // array<string, string>: name to type
$schema->primaryKey;               // list<string>
$schema->uniqueKeys;               // list<list<string>>
$schema->hasPrimaryKey();          // bool
$schema->hasUniqueKeys();          // bool
$schema->columnNames();            // list<string>

System sterowników

merql używa rozszerzalnego systemu sterowników do abstrakcji operacji specyficznych dla baz danych. Sterowniki są wykrywane automatycznie na podstawie tożsamości sterownika połączenia.

Driver (interfejs)

Merql\Driver\Driver określa kontrakt, który implementują wszystkie sterowniki baz danych.

PHP
interface Driver
{
    public function quoteIdentifier(string $name): string;
    public function listTables(DatabaseConnection $connection): array;
    public function readSchema(DatabaseConnection $connection, string $table): TableSchema;
    public function readForeignKeys(DatabaseConnection $connection): array;
    public function selectAll(string $table): string;
}

Wbudowane implementacje: MysqlDriver i SqliteDriver.

DriverFactory

Merql\Driver\DriverFactory automatycznie wykrywa sterownik na podstawie połączenia.

PHP
use Merql\Driver\DriverFactory;

$driver = DriverFactory::create($connection);

Zarejestruj niestandardowy sterownik dla innych baz danych:

PHP
DriverFactory::register('pgsql', MyPostgresDriver::class);

Filtry

TableFilter

Merql\Filter\TableFilter uwzględnia tabele lub je wyklucza za pomocą wzorców glob.

PHP
use Merql\Filter\TableFilter;

$filter = TableFilter::exclude(['cache_*', 'sessions', 'temp_*']);
$filter = TableFilter::include(['posts', 'users', 'comments']);

ColumnFilter

Merql\Filter\ColumnFilter usuwa określone kolumny ze zrzutów.

PHP
use Merql\Filter\ColumnFilter;

$filter = ColumnFilter::ignore(['updated_at', 'created_at', 'modified_date']);

RowFilter

Merql\Filter\RowFilter filtruje wiersze za pomocą funkcji predykatu.

PHP
use Merql\Filter\RowFilter;

$filter = RowFilter::create(function (string $table, array $row): bool {
    // Exclude trashed posts.
    if ($table === 'posts' && ($row['status'] ?? '') === 'trash') {
        return false;
    }
    return true;
});

Wyjątki

SnapshotException

Merql\Exceptions\SnapshotException jest zgłaszany, gdy nie można znaleźć zrzutu lub ma on nieprawidłową nazwę.

PHP
SnapshotException::notFound('baseline', '/path/to/baseline.json');

MergeException

Merql\Exceptions\MergeException jest zgłaszany, gdy do scalania brakuje wymaganego zrzutu.

PHP
MergeException::snapshotRequired('base');

ConflictException

Merql\Exceptions\ConflictException jest zgłaszany przy próbie zastosowania wyniku scalania z nierozwiązanymi konfliktami.

PHP
ConflictException::unresolved(3);
// Message: "Cannot apply merge with 3 unresolved conflict(s)"

SchemaException

Merql\Exceptions\SchemaException jest zgłaszany (lub gromadzony), gdy schematy różnią się między zrzutami.

PHP
SchemaException::mismatch('posts', 'column "tags" exists in current but not in base');

Niezgodności schematów nie zatrzymują scalania. Są gromadzone i dostępne do wglądu za pomocą $result->schemaMismatches().