Gå til indhold

PHP API-referencemateriale

Komplet reference til alle offentlige klasser og metoder i merql.

Merql (facade)

Merql\Merql er det statiske indgangspunkt til almindelige handlinger. Det indkapsler klasserne på lavere niveau og håndterer automatisk lagring af snapshots.

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

Initialisér facaden med en databaseforbindelse. Skal kaldes før snapshot(), apply() eller applyGuarded(); kald den igen for at skifte database, for eksempel for at tage snapshots af ours og theirs fra to forskellige kopier. Uden en $driver kalder den DriverFactory::create(), som kaster en undtagelse for andre databasemotorer end MySQL og SQLite, medmindre en driver er registreret. Angiv en driver for at tilsidesætte automatisk registrering eller et sæt identitetsregler for at tilsidesætte rækkeidentiteten pr. tabel under optagelse af snapshots.

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

Optag den aktuelle databasetilstand, og gem den på disk. Angiv en liste over tabelnavne for kun at tage snapshots af bestemte tabeller, eller udelad den for at tage snapshots af alle tabeller.

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

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

Indlæs to navngivne snapshots, og beregn ændringssættet mellem dem. Kræver ikke init(), da det arbejder ud fra gemte snapshots.

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

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

Trevejssammenfletning af tre navngivne snapshots. Returnerer et resultat med konfliktfrie handlinger og eventuelle konflikter. Sammenfletter på kolonneniveau: facaden opretter ThreeWayMerge uden en CellMergeConfig, så sammenfletning på celleniveau ikke anvendes. Brug ThreeWayMerge direkte til det.

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

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

Tovejssammenfletning: anvend ændringer på grundlaget. Svarer til merge($base, $base, $changes). Giver altid et konfliktfrit resultat, da der ikke er samtidige redigeringer. Kun på kolonneniveau, ligesom merge().

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

apply(MergeResult $result): ApplyResult

Udfør et konfliktfrit sammenfletningsresultat på databasen, der blev sendt til init(). Kræver init(). Kaster ConflictException, hvis der stadig er uløste konflikter.

Hver handling i resultatet udføres, så hele resultatet af merge() kan kun anvendes konfliktfrit på en database, der stadig har grundlagstilstanden. Hvis databasen allerede har tilstanden fra den ene side, skal du anvende et udvalg af de handlinger, den mangler; se Beskyttet anvendelse.

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

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

Byg en sammenfletningsplan klar til UI ud fra tre navngivne snapshots. Planen indeholder stabile handlings-ID'er, ID'er for ændringsgrupper, handlingskontekst, konflikter, skemaforskelle, et resumé, metadata og en planhash. Sammenfletningen sker på kolonneniveau som i merge(); send et cellesammenflettet resultat til MergePlanBuilder::build() for sammenfletning på celleniveau.

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

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

Anvend et konfliktfrit sammenfletningsresultat med optimistiske forudsætninger for live-rækker. Opdateringer og sletninger kræver, at de aktuelle live-rækker svarer til $expectedLive; ved indsættelser må target-identiteten ikke allerede findes. $expectedLive er et snapshot af databasen som mål (theirs, når ours overføres til den database, som theirs blev taget fra). Hvis en kommando ikke påvirker nogen rækker, rulles transaktionen tilbage.

PHP
use Merql\Snapshot\SnapshotStore;

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

reset(): void

Ryd de interne forbindelses- og Snapshotter-instanser. Bruges primært i test til at nulstille tilstanden mellem kørsler.


Forbindelse

Merql\Connection opretter forbindelsesadaptere med fornuftige standardindstillinger. PDO-forbindelser bruger undtagelser ved fejl, associativ hentetilstand, ingen emulerede forberedte sætninger og hentede værdier som strenge. mysqli-adapteren normaliserer hentede værdier til samme streng-eller-null-format.

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

Opretter en SQLite-forbindelse. Aktiverer automatisk fremmednøgler via PRAGMA foreign_keys = ON.

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

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

Opret forbindelse med en vilkårlig PDO DSN-streng. merql leveres kun med drivere til mysql og sqlite; andre DSN'er opretter en forbindelse, men Merql::init(), Snapshotter og applikatorerne kaster Unsupported database driver, medmindre en driver er registreret med DriverFactory::register().

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

fromPdo(PDO $pdo): PdoDatabaseConnection

Ombryd en eksisterende PDO-instans.

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

Ombryd en eksisterende mysqli-instans.

Adapterkontrakt

Alle adaptere implementerer 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() og scalar() accepterer positionelle list<scalar|null> parametre for pladsholdere af typen ?. query() returnerer list<array<string, scalar|null>>; værdier normaliseres til samme streng-eller-null-format på tværs af PDO- og mysqli-adaptere.


Snapshotter

Merql\Snapshot\Snapshotter optager databasetilstanden. I modsætning til facaden giver den dig fuld kontrol over filtre og gemmer ikke automatisk.

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

Driveren registreres automatisk ud fra forbindelsens identitet, hvis den ikke angives. Angiv et IdentityRuleSet, når tabelspecifik rækkeidentitet skal tilsidesætte skemaets standardindstillinger.

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

Optag den aktuelle tilstand. Angiv tabelnavne for at begrænse omfanget. Angiv filterobjekter for at udelukke tabeller, kolonner eller rækker.

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

Optag fysiske tabeller under kanoniske tabelnavne. Brug dette, når den samme logiske tabel har forskellige fysiske navne på tværs af miljøer.

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

Det resulterende snapshot gemmer kanoniske tabelnavne, samtidig med at det bevarer det fysiske tabelskema, konfigurerede identitetskolonner, rækkenøgler og filtre.

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

Byg et snapshot ud fra rådata uden en databaseforbindelse. Nyttigt til test eller ved import af data fra en anden kilde.

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']),
]);

Snapshot

Merql\Snapshot\Snapshot er et skrivebeskyttet værdiobjekt, der repræsenterer en fuldstændig databasetilstand.

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 indeholder én tabels rækker, fingeraftryk og skema.

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 er inputdata til 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 definerer de kolonner, der bruges til at opbygge rækkenøgler.

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 (statisk)

Find standardidentitetsreglen ud fra skemaet: primærnøgle, første unikke nøgle, derefter fallback til indhold.

toArray(): array

Serialisér reglen som ['type' => string, 'columns' => list<string>].

fromArray(array $data): IdentityRule (statisk)

Opret en regel ud fra serialiserede data.


IdentityRuleSet

Merql\Identity\IdentityRuleSet gemmer tabelspecifikke tilsidesættelser af identitet.

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

Returner et nyt regelsæt med én tilføjet tabeltilsidesættelse.

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

Returner IdentityConflict-poster, når flere rækker giver samme nøgle for en regel.

toArray(): array

Serialisér tabelregler som et JSON-sikkert array.

fromArray(array $data): IdentityRuleSet (statisk)

Opret et regelsæt ud fra serialiserede data.


SnapshotStore

Merql\Snapshot\SnapshotStore gemmer og indlæser snapshots som JSON-filer.

setDirectory(string $directory): void

Angiv lagermappen. Standard er .merql/snapshots.

save(Snapshot $snapshot): void

Skriv et snapshot til disk.

load(string $name): Snapshot

Indlæs et snapshot efter navn. Kaster SnapshotException, hvis det ikke findes.

exists(string $name): bool

Kontrollér, om en snapshotfil findes.

delete(string $name): void

Fjern en snapshotfil.


Differ

Merql\Diff\Differ sammenligner to snapshots og opretter et ændringssæt.

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 (statisk)

Sammenlign to værdier ved at tvinge dem til strenge. NULL behandles som en særskilt værdi: NULL === NULL er sand, NULL === '' er falsk.


Ændringssæt

Merql\Diff\Changeset er en skrivebeskyttet samling af handlinger på rækkeniveau.

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

Skrivebeskyttede værdiobjekter, der repræsenterer ændringer af enkelte rækker.

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 repræsenterer en enkelt kolonneændring i en rækkeopdatering.

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

ThreeWayMerge

Merql\Merge\ThreeWayMerge er den centrale sammenfletningsalgoritme.

__construct(?CellMergeConfig $cellMergeConfig = null)

Angiv en CellMergeConfig for at aktivere sammenfletning på celleniveau for TEXT- og JSON-kolonner.

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

Udfør en trevejssammenfletning. Beregner ændringssæt internt (fra base til ours og fra base til theirs) og sammenfletter dem.

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

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

Genvej til tovejssammenfletning. Svarer til merge($base, $base, $changes).

schemaMismatches(): array

Returnerer SchemaException[] for alle skemaforskelle, der blev registreret under den seneste sammenfletning (kolonner tilføjet eller fjernet mellem snapshots).


MergeResult

Merql\Merge\MergeResult er et skrivebeskyttet værdiobjekt, der indeholder resultatet af sammenfletningen.

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 er en serialiserbar reviewmodel for en sammenfletning.

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>

Brug MergePlanSerializer::toJson() og ::fromJson() til stabile JSON-ture.

Udvalg

ChangeGroupSelection gemmer trinvist tilføjede ID'er for ændringsgrupper. Konvertér den til en OperationSelection, når du opbygger udvalgte sammenfletningsresultater eller tilbagerulningsplaner.

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 gemmer inverse handlinger og forventninger til afvigelser for en udvalgt anvendelse.

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

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

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

Brug RollbackDrift før rollback, og brug derefter RollbackPlanApplier til at køre de inverse operationer.


MergeOperation

Merql\Merge\MergeOperation er en enkelt afklaret operation fra sammenfletningen.

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

Typekonstanter:

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

Konflikt

Merql\Merge\Conflict repræsenterer en uafklaret sammenfletningskonflikt.

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

Konflikttyper

Type Betydning
update_update Begge sider ændrede den samme kolonne til forskellige værdier
update_delete Vores side opdaterede en række, som deres side slettede
delete_update Vores side slettede en række, som deres side opdaterede
insert_insert Begge sider indsatte en række med samme primærnøgle

ConflictResolver

Merql\Merge\ConflictResolver anvender en løsningspolitik på alle konflikter i resultatet af en sammenfletning.

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

Returnerer en ny MergeResult med konflikter løst i henhold til politikken.

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 er en backed enum med tre cases.

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 udfører sammenfletningslogik pr. kolonne for en enkelt række. Bruges internt af ThreeWayMerge.

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

Returnerer ['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)

Udfører

Merql\Apply\Applier udfører et sammenfletningsresultat på en database.

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

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

Udfører alle operationer i en enkelt transaktion. Ruller tilbage ved enhver fejl og rapporterer den i ApplyResult::errors() i stedet for at kaste den. Kaster ConflictException, hvis resultatet indeholder uafklarede konflikter.

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());
}

Fremmednøglerækkefølgen håndteres automatisk: Indsættelser sorteres efter afhængigheder, og sletninger sorteres i omvendt afhængighedsrækkefølge.


ApplyResult

Merql\Apply\ApplyResult er et skrivebeskyttet værdiobjekt, som returneres af udføreren.

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

Efter en tilbagerullet anvendelse tæller rowsAffected() stadig de sætninger, der blev kørt før fejlen (#4). Kontrollér hasErrors(), før du stoler på tallet.


DryRun

Merql\Apply\DryRun genererer menneskeligt læsbare SQL uden at udføre noget.

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

Returnerer en liste med SQL-strenge, hvor værdierne er indsat (kun til visning).

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 genererer parametriserede SQL-sætninger. Bruges internt af både Applier og DryRun.

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

Returnerer 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 konfigurerer sammenfletningsstrategier på celleniveau for bestemte kolonner eller kolonnetyper.

auto(): self (statisk)

Praktisk factory, der tildeler TextCellMerger til TEXT/LONGTEXT-kolonner og JsonCellMerger til JSON-kolonner.

PHP
use Merql\CellMerge\CellMergeConfig;

$config = CellMergeConfig::auto();

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

Tildel en sammenfletter til en bestemt kolonne. Brug table.column til kvalificerede navne eller blot column til alle tabeller.

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

Tildel en sammenfletter til alle kolonner, der matcher et typemønster (uafhængigt af store og små bogstaver, delstrengsmatch).

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

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

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

Find sammenfletteren for en given tabel, kolonne og type. Prioritet: kvalificeret kolonnenavn, ukvalificeret kolonnenavn, typemønster, standard (opaque).


CellMerger (grænseflade)

Merql\CellMerge\CellMerger er grænsefladen for sammenfletningsstrategier på celleniveau.

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

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

Der findes tre indbyggede implementeringer.

TextCellMerger

Merql\CellMerge\TextCellMerger sammenfletter tekst med flere linjer ved hjælp af en trevejssammenligning linje for linje (samme algoritme, som git bruger til filindhold). Når begge sider redigerer forskellige linjer, lykkes sammenfletningen uden konflikter. Når begge sider redigerer den samme linje forskelligt, rapporteres en 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 sammenfletter JSON-værdier ved at sammenligne nøgler på øverste niveau uafhængigt. Hver nøgle sammenflettes med trevejslogik. Indlejrede objekter sammenlignes som opaque JSON-strenge (de sammenflettes ikke rekursivt).

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 er standarden. Den behandler værdier som opaque strenge og rapporterer altid en konflikt, når de er forskellige.


CellMergeResult

Merql\CellMerge\CellMergeResult er returtypen for alle celle-sammenflettere.

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 er en skrivebeskyttet repræsentation af tabelstrukturen.

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>

Driversystem

merql bruger et system med udskiftelige drivere til at abstrahere databasespecifikke operationer. Drivere registreres automatisk ud fra forbindelsens driveridentitet.

Driver (grænseflade)

Merql\Driver\Driver definerer den kontrakt, som alle databasedrivere implementerer.

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;
}

Indbyggede implementeringer: MysqlDriver og SqliteDriver.

DriverFactory

Merql\Driver\DriverFactory registrerer automatisk driveren ud fra en forbindelse.

PHP
use Merql\Driver\DriverFactory;

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

Registrer en tilpasset driver til andre databaser:

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

Filtre

TableFilter

Merql\Filter\TableFilter inkluderer eller udelukker tabeller ved hjælp af globmønstre.

PHP
use Merql\Filter\TableFilter;

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

ColumnFilter

Merql\Filter\ColumnFilter fjerner bestemte kolonner fra snapshots.

PHP
use Merql\Filter\ColumnFilter;

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

RowFilter

Merql\Filter\RowFilter filtrerer rækker ved hjælp af en prædikatfunktion.

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;
});

Undtagelser

SnapshotException

Merql\Exceptions\SnapshotException kastes, når et snapshot ikke kan findes eller har et ugyldigt navn.

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

MergeException

Merql\Exceptions\MergeException kastes, når et påkrævet snapshot mangler til en sammenfletning.

PHP
MergeException::snapshotRequired('base');

ConflictException

Merql\Exceptions\ConflictException kastes, når der forsøges at anvende et sammenfletningsresultat med uafklarede konflikter.

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

SchemaException

Merql\Exceptions\SchemaException kastes (eller indsamles), når skemaerne er forskellige mellem snapshots.

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

Skemaforskelle stopper ikke sammenfletningen. De indsamles og kan ses via $result->schemaMismatches().