Hoppa till innehåll

PHP API-referens

Fullständig referens för alla publika klasser och metoder i merql.

Merql (fasad)

Merql\Merql är den statiska startpunkten för vanliga åtgärder. Den kapslar in klasser på lägre nivå och hanterar automatiskt lagring av ögonblicksbilder.

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

Initiera fasaden med en databasanslutning. Måste anropas före snapshot(), apply() eller applyGuarded(); anropa den igen för att byta databas, till exempel för att ta ögonblicksbilder av ours och theirs från två olika kopior. Utan en $driver anropar den DriverFactory::create(), som ger ett undantag för andra motorer än MySQL och SQLite, om inte en drivrutin har registrerats. Skicka med en drivrutin för att åsidosätta automatisk identifiering, eller en uppsättning identitetsregler för att åsidosätta radidentiteten per tabell när ögonblicksbilden tas.

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

Fånga det aktuella databastillståndet och spara det på disk. Skicka med en array med tabellnamn för att ta ögonblicksbilder av specifika tabeller, eller utelämna den för att inkludera alla tabeller.

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

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

Läs in två namngivna ögonblicksbilder och beräkna ändringsuppsättningen mellan dem. Kräver inte init() eftersom den arbetar med sparade ögonblicksbilder.

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

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

Trevägssammanslagning av tre namngivna ögonblicksbilder. Returnerar ett resultat med konfliktfria åtgärder och eventuella konflikter. Sammanslagningen sker på kolumnnivå: fasaden skapar ThreeWayMerge utan en CellMergeConfig, så sammanslagning på cellnivå tillämpas inte. Använd ThreeWayMerge direkt för det.

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

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

Tvåvägssammanslagning: tillämpa ändringar på base. Motsvarar merge($base, $base, $changes). Ger alltid ett konfliktfritt resultat eftersom inga samtidiga ändringar finns. Endast på kolumnnivå, liksom merge().

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

apply(MergeResult $result): ApplyResult

Kör ett konfliktfritt sammanslagningsresultat mot databasen som skickats till init(). Kräver init(). Ger ConflictException om det finns olösta konflikter.

Varje åtgärd i resultatet körs, så hela resultatet från merge() kan tillämpas korrekt endast på en databas som fortfarande innehåller base-tillståndet. Om databasen redan innehåller en av sidorna tillämpar du de åtgärder som saknas där; se Skyddad tillämpning.

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

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

Bygg en sammanslagningsplan redo för UI utifrån tre namngivna ögonblicksbilder. Planen innehåller stabila åtgärds-ID:n, ID:n för ändringsgrupper, åtgärdskontext, konflikter, schemaavvikelser, en sammanfattning, metadata och en planhash. Sammanslagningen sker på kolumnnivå, som i merge(); skicka ett resultat som slagits samman på cellnivå till MergePlanBuilder::build() för sammanslagning på cellnivå.

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

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

Tillämpa ett konfliktfritt sammanslagningsresultat med optimistiska förvillkor för aktiva rader. Uppdateringar och borttagningar kräver att aktiva rader matchar $expectedLive; vid infogningar får målidentiteten inte redan finnas. $expectedLive är en ögonblicksbild av måldatabasen (theirs, när ours förs över till databasen som theirs hämtades från). Om en sats inte påverkar några rader återställs transaktionen.

PHP
use Merql\Snapshot\SnapshotStore;

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

reset(): void

Rensa de interna anslutnings- och Snapshotter-instanserna. Används främst i tester för att återställa tillståndet mellan körningar.


Anslutning

Merql\Connection bygger anslutningsadaptrar med lämpliga standardinställningar. PDO anslutningar använder undantag vid fel, associativt hämtningsläge, ingen emulering av förberedda satser och strängkonverterade hämtade värden. mysqli-adaptern normaliserar hämtade värden till samma format med sträng eller 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

Skapar en SQLite-anslutning. Aktiverar automatiskt främmande nycklar 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

Anslut med valfri PDO-DSN-sträng. merql levereras endast med drivrutiner för mysql och sqlite. Andra DSN:er öppnar en anslutning, men Merql::init(), Snapshotter och tillämparna ger Unsupported database driver om ingen drivrutin har registrerats med DriverFactory::register().

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

fromPdo(PDO $pdo): PdoDatabaseConnection

Omsluter en befintlig PDO-instans.

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

Omsluter en befintlig mysqli-instans.

Adapterkontrakt

Alla adaptrar implementerar 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() och scalar() godtar positionella list<scalar|null>- parametrar för platshållare av typen ?. query() returnerar list<array<string, scalar|null>>; värden normaliseras till samma format med sträng eller null i PDO- och mysqli-adaptrarna.


Snapshotter

Merql\Snapshot\Snapshotter fångar databastillståndet. Till skillnad från fasaden ger den dig full kontroll över filter och sparar inte automatiskt.

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

Drivrutinen identifieras automatiskt utifrån anslutningens identitet om den inte anges. Skicka med en IdentityRuleSet när tabellspecifik radidentitet ska åsidosätta schemats standardinställningar.

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

Fånga det aktuella tillståndet. Ange tabellnamn för att begränsa omfattningen. Skicka med filterobjekt för att utesluta tabeller, kolumner eller rader.

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

Fånga fysiska tabeller under kanoniska tabellnamn. Använd detta när samma logiska tabell har olika fysiska namn i olika miljöer.

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

Den resulterande ögonblicksbilden lagrar kanoniska tabellnamn samtidigt som fysiskt tabellschema, konfigurerade identitetskolumner, radnycklar och filter bevaras.

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

Bygg en ögonblicksbild från rådata utan databasanslutning. Användbart vid testning eller när data importeras från en annan källa.

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

Ögonblicksbild

Merql\Snapshot\Snapshot är ett skrivskyddat värdeobjekt som representerar ett fullständigt databastillstånd.

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 innehåller en tabells rader, fingeravtryck och schema.

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 är indata för 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 definierar kolumnerna som används för att skapa radnycklar.

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)

Lös standardregeln för identitet utifrån schemat: primärnyckel, första unika nyckel, därefter reservlösning med innehåll.

toArray(): array

Serialisera regeln som ['type' => string, 'columns' => list<string>].

fromArray(array $data): IdentityRule (statisk)

Återskapa en regel från serialiserade data.


IdentityRuleSet

Merql\Identity\IdentityRuleSet lagrar tabellspecifika åsidosättningar av identiteten.

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

Returnera en ny regeluppsättning med en tillagd åsidosättning för en tabell.

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

Returnera poster av typen IdentityConflict när flera rader ger samma nyckel för en regel.

toArray(): array

Serialisera tabellregler som en JSON-säker array.

fromArray(array $data): IdentityRuleSet (statisk)

Återskapa en regeluppsättning från serialiserade data.


SnapshotStore

Merql\Snapshot\SnapshotStore sparar och läser in ögonblicksbilder som filer av typen JSON.

setDirectory(string $directory): void

Ange lagringskatalogen. Standard är .merql/snapshots.

save(Snapshot $snapshot): void

Skriv en ögonblicksbild till disk.

load(string $name): Snapshot

Läs in en ögonblicksbild efter namn. Ger SnapshotException om den inte hittas.

exists(string $name): bool

Kontrollera om en ögonblicksbildsfil finns.

delete(string $name): void

Ta bort en ögonblicksbildsfil.


Differerare

Merql\Diff\Differ jämför två ögonblicksbilder och skapar en ändringsuppsättning.

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)

Jämför två värden genom att konvertera dem till strängar. NULL behandlas som ett eget värde: NULL === NULL är sant, NULL === '' är falskt.


Ändringsuppsättning

Merql\Diff\Changeset är en skrivskyddad samling åtgärder på radnivå.

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

Skrivskyddade värdeobjekt som representerar enskilda radändringar.

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 representerar en enskild kolumnändring i en raduppdatering.

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

ThreeWayMerge

Merql\Merge\ThreeWayMerge är den centrala sammanslagningsalgoritmen.

__construct(?CellMergeConfig $cellMergeConfig = null)

Skicka med en CellMergeConfig för att aktivera sammanslagning på cellnivå för kolumnerna TEXT och 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

Utför en trevägssammanslagning. Beräknar ändringsuppsättningar internt (base till ours, base till theirs) och slår samman dem.

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

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

Genväg för tvåvägssammanslagning. Motsvarar merge($base, $base, $changes).

schemaMismatches(): array

Returnerar SchemaException[] för alla schemaavvikelser som upptäcktes vid den senaste sammanslagningen (kolumner som lagts till eller tagits bort mellan ögonblicksbilder).


MergeResult

Merql\Merge\MergeResult är ett skrivskyddat värdeobjekt som innehåller resultatet av sammanslagningen.

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 är en serialiserbar granskningsmodell för en sammanslagning.

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>

Använd MergePlanSerializer::toJson() och ::fromJson() för stabila JSON-rundresor.

Urval

ChangeGroupSelection lagrar ID:n för grupper med förberedda ändringar. Konvertera det till en OperationSelection när du bygger valda sammanslagningsresultat eller återställningsplaner.

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 lagrar inversa åtgärder och förväntningar på avvikelser för en vald tillämpning.

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

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

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

Använd RollbackDrift innan återställningen tillämpas och sedan RollbackPlanApplier för att köra de inversa åtgärderna.


MergeOperation

Merql\Merge\MergeOperation är en enda löst åtgärd från sammanslagningen.

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

Typkonstanter:

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

Konflikt

Merql\Merge\Conflict representerar en olöst sammanslagningskonflikt.

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

Typ Betydelse
update_update Båda sidorna ändrade samma kolumn till olika värden
update_delete Vår sida uppdaterade en rad som deras sida tog bort
delete_update Vår sida tog bort en rad som deras sida uppdaterade
insert_insert Båda sidorna infogade en rad med samma primärnyckel

ConflictResolver

Merql\Merge\ConflictResolver tillämpar en lösningspolicy på alla konflikter i ett sammanslagningsresultat.

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

Returnerar en ny MergeResult med konflikter lösta enligt policyn.

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 är en enum med tre fall.

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 utför sammanslagningslogik per kolumn för en enskild rad. Används internt av ThreeWayMerge.

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

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

Tillämpare

Merql\Apply\Applier kör ett sammanslagningsresultat mot en databas.

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

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

Kör alla åtgärder i en enda transaktion. Återställer transaktionen vid fel och rapporterar felet i ApplyResult::errors() i stället för att kasta ett undantag. Kastar ConflictException om resultatet har olösta 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());
}

Sortering efter främmande nycklar hanteras automatiskt: infogningar sorteras efter beroenden och borttagningar i omvänd beroendeordning.


ApplyResult

Merql\Apply\ApplyResult är ett skrivskyddat värdeobjekt som returneras av tillämparen.

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

Efter en återställd tillämpning räknar rowsAffected() fortfarande med de satser som kördes före felet (#4). Kontrollera hasErrors() innan du litar på antalet.


DryRun

Merql\Apply\DryRun genererar människoläsbara SQL utan att köra något.

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

Returnerar en lista med SQL-strängar där värdena är infogade (endast för 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 genererar parameteriserade SQL-satser. Används internt av både Applier och DryRun.

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

Returnerar 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 konfigurerar sammanslagningsstrategier på cellnivå för specifika kolumner eller kolumntyper.

auto(): self (statisk)

Hjälpfabrik som tilldelar TextCellMerger till kolumner av typen TEXT/LONGTEXT och JsonCellMerger till kolumner av typen JSON.

PHP
use Merql\CellMerge\CellMergeConfig;

$config = CellMergeConfig::auto();

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

Tilldela en sammanslagare till en specifik kolumn. Använd table.column för fullständigt kvalificerade namn eller bara column för alla 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

Tilldela en sammanslagare till alla kolumner som matchar ett typmönster (skiftlägesokänslig delsträngsmatchning).

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

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

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

Slå upp sammanslagaren för en viss tabell, kolumn och typ. Prioritet: kvalificerat kolumnnamn, okvalificerat kolumnnamn, typmönster, standard (opak).


CellMerger (gränssnitt)

Merql\CellMerge\CellMerger är gränssnittet för sammanslagningsstrategier på cellnivå.

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

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

Tre inbyggda implementationer tillhandahålls.

TextCellMerger

Merql\CellMerge\TextCellMerger sammanfogar flerradig text med en trevägs diff rad för rad (samma algoritm som git använder för filinnehåll). Om båda sidorna redigerar olika rader blir sammanslagningen konfliktfri. Om båda sidorna redigerar samma rad på olika sätt rapporteras 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 sammanfogar JSON-värden genom att jämföra nycklar på toppnivå var för sig. Varje nyckel sammanfogas med trevägslogik. Nästlade objekt jämförs som opaka JSON-strängar (de sammanfogas inte 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 är standardalternativet. Det behandlar värden som opaka strängar och rapporterar alltid en konflikt när de skiljer sig åt.


CellMergeResult

Merql\CellMerge\CellMergeResult är returtypen för alla cellsammanslagare.

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 är en skrivskyddad representation av tabellstrukturen.

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>

Drivrutinssystem

merql använder ett drivrutinssystem med utbytbara drivrutiner för att abstrahera databasspecifika åtgärder. Drivrutiner identifieras automatiskt utifrån anslutningens drivrutinsidentitet.

Driver (gränssnitt)

Merql\Driver\Driver definierar kontraktet som alla databast drivrutiner implementerar.

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

Inbyggda implementationer: MysqlDriver och SqliteDriver.

DriverFactory

Merql\Driver\DriverFactory identifierar automatiskt drivrutinen från en anslutning.

PHP
use Merql\Driver\DriverFactory;

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

Registrera en anpassad drivrutin för andra databaser:

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

Filter

TableFilter

Merql\Filter\TableFilter inkluderar eller exkluderar tabeller med globmönster.

PHP
use Merql\Filter\TableFilter;

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

ColumnFilter

Merql\Filter\ColumnFilter tar bort specifika kolumner från ögonblicksbilder.

PHP
use Merql\Filter\ColumnFilter;

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

RowFilter

Merql\Filter\RowFilter filtrerar rader med en predikatfunktion.

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

Undantag

SnapshotException

Merql\Exceptions\SnapshotException kastas när en ögonblicksbild inte kan hittas eller har ett ogiltigt namn.

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

MergeException

Merql\Exceptions\MergeException kastas när en sammanslagning saknar en nödvändig ögonblicksbild.

PHP
MergeException::snapshotRequired('base');

ConflictException

Merql\Exceptions\ConflictException kastas när ett sammanslagningsresultat med olösta konflikter försöker tillämpas.

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

SchemaException

Merql\Exceptions\SchemaException kastas (eller samlas in) när scheman skiljer sig mellan ögonblicksbilder.

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

Schemainkonsekvenser stoppar inte sammanslagningen. De samlas in och är tillgängliga via $result->schemaMismatches() för granskning.