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.
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.
$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.
$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.
$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().
$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.
$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å.
$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.
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
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
$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.
$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().
$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:
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.
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.
$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.
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.
$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.
$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().
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.
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.
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
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å.
$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
$insert->table; // string
$insert->rowKey; // string
$insert->values; // array<string, mixed>
RowUpdate
$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
$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.
$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.
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.
$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.
$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.
$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.
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.
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.
$op->type; // string: 'insert' | 'update' | 'delete'
$op->table; // string
$op->rowKey; // string
$op->values; // array<string, mixed>
$op->source; // string: 'ours' | 'theirs' | 'merged'
Typkonstanter:
MergeOperation::TYPE_INSERT; // 'insert'
MergeOperation::TYPE_UPDATE; // 'update'
MergeOperation::TYPE_DELETE; // 'delete'
Konflikt
Merql\Merge\Conflict representerar en olöst sammanslagningskonflikt.
$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.
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.
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>].
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.
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.
$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).
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>}>.
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.
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.
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).
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å.
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.
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).
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.
$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.
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.
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.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
Registrera en anpassad drivrutin för andra databaser:
DriverFactory::register('pgsql', MyPostgresDriver::class);
Filter
TableFilter
Merql\Filter\TableFilter inkluderar eller exkluderar tabeller med globmönster.
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.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'created_at', 'modified_date']);
RowFilter
Merql\Filter\RowFilter filtrerar rader med en predikatfunktion.
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.
SnapshotException::notFound('baseline', '/path/to/baseline.json');
MergeException
Merql\Exceptions\MergeException kastas när en sammanslagning saknar en nödvändig ögonblicksbild.
MergeException::snapshotRequired('base');
ConflictException
Merql\Exceptions\ConflictException kastas när ett sammanslagningsresultat med olösta konflikter försöker tillämpas.
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.
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.