Referencia PHP API
Úplná referencia všetkých verejných tried a metód v merql.
Merql (fasáda)
Merql\Merql je statický vstupný bod pre bežné operácie. Obaľuje nízkoúrovňové triedy a automaticky spravuje uchovávanie snímok.
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
Inicializujte fasádu databázovým pripojením. Musí sa zavolať pred snapshot(), apply() alebo applyGuarded(); zavolajte ju znova na prepnutie databáz, napríklad pri vytváraní snímok ours a theirs z dvoch rôznych kópií. Bez $driver zavolá DriverFactory::create(), čo vyhodí výnimku pre iné enginy než MySQL a SQLite, ak nie je zaregistrovaný ovládač. Odovzdaním ovládača prepíšete automatické rozpoznanie; množinou pravidiel identity prepíšete identitu riadkov pre jednotlivé tabuľky počas zachytávania snímky.
snapshot(string $name, array $tables = []): Snapshot
Zachyťte aktuálny stav databázy a uložte ho na disk. Odovzdajte pole názvov tabuliek na vytvorenie snímok konkrétnych tabuliek alebo ho vynechajte pre všetky tabuľky.
$snapshot = Merql::snapshot('baseline');
$snapshot = Merql::snapshot('baseline', ['posts', 'users']);
diff(string $base, string $current): Changeset
Načítajte dve pomenované snímky a vypočítajte medzi nimi množinu zmien. init() nie je potrebný, pretože operácia pracuje s uloženými snímkami.
$changeset = Merql::diff('before', 'after');
merge(string $base, string $ours, string $theirs): MergeResult
Trojcestné zlúčenie troch pomenovaných snímok. Vráti výsledok s čistými operáciami a prípadnými konfliktmi. Zlučuje na úrovni stĺpcov: fasáda vytvorí ThreeWayMerge bez CellMergeConfig, takže zlúčenie na úrovni buniek sa nepoužije. Ak ho potrebujete, použite priamo ThreeWayMerge.
$result = Merql::merge('base', 'ours', 'theirs');
patch(string $base, string $changes): MergeResult
Dvojcestné zlúčenie: použije zmeny na základ. Ekvivalent merge($base, $base, $changes). Vždy vytvorí čistý výsledok, pretože neexistujú súbežné úpravy. Podobne ako merge() funguje iba na úrovni stĺpcov.
$result = Merql::patch('base', 'changes');
apply(MergeResult $result): ApplyResult
Vykoná čistý výsledok zlúčenia nad databázou odovzdanou do init(). Vyžaduje init(). Ak zostanú nevyriešené konflikty, vyhodí ConflictException.
Vykonajú sa všetky operácie vo výsledku, takže úplný výsledok merge() sa dá čisto použiť iba v databáze, ktorá stále obsahuje základný stav. V databáze, ktorá už obsahuje stav jednej strany, použite výber operácií, ktoré jej chýbajú; pozrite si Riadené použitie.
$applied = Merql::apply($result);
echo $applied->rowsAffected();
plan(string $id, string $base, string $ours, string $theirs, array $metadata = []): MergePlan
Vytvorte plán zlúčenia pripravený pre UI z troch pomenovaných snímok. Plán obsahuje stabilné
ID operácií, ID skupín zmien, kontext operácií, konflikty, nesúlady schém,
prehľad, metadáta a hash plánu. Zlúčenie prebieha na úrovni stĺpcov, rovnako ako
v merge(); na zlúčenie na úrovni buniek odovzdajte výsledok so zlúčenými bunkami do MergePlanBuilder::build().
$plan = Merql::plan('plan-1', 'base', 'ours', 'theirs', [
'source' => 'review-ui',
]);
applyGuarded(MergeResult $result, Snapshot $expectedLive): ApplyResult
Použite čistý výsledok zlúčenia s optimistickými podmienkami pre živé riadky. Aktualizácie a
odstránenia vyžadujú, aby sa aktuálne živé riadky zhodovali s $expectedLive; pri vkladaní sa vyžaduje, aby
cieľová identita ešte neexistovala. $expectedLive je snímka cieľovej databázy (theirs, keď sa ours povyšuje do databázy, z ktorej bola vytvorená snímka theirs). Akýkoľvek príkaz, ktorý ovplyvní nula riadkov, spôsobí vrátenie transakcie.
use Merql\Snapshot\SnapshotStore;
$applied = Merql::applyGuarded($selectedResult, SnapshotStore::load('theirs'));
reset(): void
Vymažte interné inštancie pripojenia a Snapshotter. Používa sa najmä v testoch na resetovanie stavu medzi spusteniami.
Pripojenie
Merql\Connection vytvára adaptéry pripojenia s vhodnými predvolenými nastaveniami. Pripojenia PDO používajú výnimky pri chybách, asociatívny režim načítavania, emulované pripravené príkazy sú vypnuté a načítané hodnoty sa prevádzajú na reťazce. Adaptér mysqli normalizuje načítané hodnoty do rovnakého formátu reťazca alebo 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
Vytvorí pripojenie SQLite. Automaticky zapne cudzie kľúče pomocou PRAGMA foreign_keys = ON.
$connection = Connection::sqlite('/var/data/app.sqlite');
$connection = Connection::sqlite(':memory:');
fromDsn(string $dsn, string $username = '', string $password = ''): PdoDatabaseConnection
Pripojte sa pomocou ľubovoľného reťazca DSN PDO. merql obsahuje ovládače iba pre mysql a sqlite; pri iných DSN sa pripojenie otvorí, ale Merql::init(), Snapshotter a aplikátory vyhodia Unsupported database driver, pokiaľ nie je ovládač zaregistrovaný pomocou DriverFactory::register().
$connection = Connection::fromDsn('mysql:host=localhost;dbname=app', 'root', 'pass');
fromPdo(PDO $pdo): PdoDatabaseConnection
Obaľte existujúcu inštanciu PDO.
fromMysqli(mysqli $mysqli, string $charset = 'utf8mb4'): MysqliDatabaseConnection
Obaľte existujúcu inštanciu mysqli.
Zmluva adaptéra
Všetky adaptéry implementujú 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() a scalar() prijímajú pozičné parametre list<scalar|null>
pre zástupné symboly ?. query() vracia
list<array<string, scalar|null>>; hodnoty sa normalizujú do rovnakého
formátu reťazca alebo null v adaptéroch PDO aj mysqli.
Snapshotter
Merql\Snapshot\Snapshotter zachytáva stav databázy. Na rozdiel od fasády vám poskytuje úplnú kontrolu nad filtrami a automaticky neukladá zmeny.
__construct(DatabaseConnection $connection, ?Driver $driver = null, ?IdentityRuleSet $identityRules = null)
Ak nie je zadaný, ovládač sa automaticky určí podľa identity pripojenia. Ak má identita riadka konkrétnej tabuľky prednosť pred predvolenými nastaveniami schémy, zadajte IdentityRuleSet.
capture(string $name, array $tables = [], array $filters = []): Snapshot
Zachyťte aktuálny stav. Rozsah obmedzíte zadaním názvov tabuliek. Ak chcete vylúčiť tabuľky, stĺpce alebo riadky, zadajte objekty filtrov.
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
Zachyťte fyzické tabuľky pod kanonickými názvami tabuliek. Túto možnosť použite, keď má tá istá logická tabuľka v rôznych prostrediach odlišné fyzické názvy.
$snapshot = $snapshotter->captureAliased('sandbox', [
'wp_onumia_abcd_posts' => 'wp_posts',
'wp_onumia_abcd_postmeta' => 'wp_postmeta',
]);
Výsledný snímok ukladá kanonické názvy tabuliek a zároveň zachováva fyzickú schému tabuliek, nakonfigurované stĺpce identity, kľúče riadkov a filtre.
fromData(string $name, array $tableData): Snapshot (statická)
Vytvorte snímok z nespracovaných údajov bez pripojenia k databáze. Hodí sa na testovanie alebo pri importovaní údajov z iného zdroja.
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']),
]);
Snímok
Merql\Snapshot\Snapshot je objekt hodnoty iba na čítanie, ktorý predstavuje úplný stav databázy.
$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 obsahuje riadky jednej tabuľky, ich odtlačky a schému.
$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 predstavuje vstupné údaje pre 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 určuje stĺpce použité na vytvorenie kľúčov riadkov.
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 (statická)
Určí predvolené pravidlo identity zo schémy: primárny kľúč, prvý jedinečný kľúč a potom náhradné riešenie založené na obsahu.
toArray(): array
Serializuje pravidlo ako ['type' => string, 'columns' => list<string>].
fromArray(array $data): IdentityRule (statická)
Obnoví pravidlo zo serializovaných údajov.
IdentityRuleSet
Merql\Identity\IdentityRuleSet uchováva prepísania identity pre konkrétne tabuľky.
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
Vráti novú množinu pravidiel s pridaným prepísaním pre jednu tabuľku.
conflictsFor(string $table, IdentityRule $rule, array $rows): array
Vráti položky IdentityConflict, keď podľa pravidla vytvoria viaceré riadky rovnaký kľúč.
toArray(): array
Serializuje pravidlá tabuliek do poľa bezpečného pre JSON.
fromArray(array $data): IdentityRuleSet (statická)
Obnoví množinu pravidiel zo serializovaných údajov.
SnapshotStore
Merql\Snapshot\SnapshotStore ukladá a načítava snímky ako súbory JSON.
setDirectory(string $directory): void
Nastaví adresár úložiska. Predvolená hodnota je .merql/snapshots.
save(Snapshot $snapshot): void
Zapíše snímok na disk.
load(string $name): Snapshot
Načíta snímok podľa názvu. Ak sa nenájde, vyvolá SnapshotException.
exists(string $name): bool
Skontroluje, či súbor snímku existuje.
delete(string $name): void
Odstráni súbor snímku.
Rozdiely
Merql\Diff\Differ porovná dva snímky a vytvorí množinu zmien.
diff(Snapshot $base, Snapshot $current): Changeset
use Merql\Diff\Differ;
$differ = new Differ();
$changeset = $differ->diff($baseSnapshot, $currentSnapshot);
valuesEqual(mixed $a, mixed $b): bool (statická)
Porovná dve hodnoty po prevedení na reťazec. NULL sa považuje za samostatnú hodnotu: NULL === NULL je pravda, NULL === '' je nepravda.
Množina zmien
Merql\Diff\Changeset je kolekcia operácií na úrovni riadkov iba na čítanie.
$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
Objekty hodnôt iba na čítanie, ktoré predstavujú jednotlivé zmeny riadkov.
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 predstavuje zmenu jedného stĺpca v rámci aktualizácie riadka.
$diff->column; // string
$diff->oldValue; // mixed
$diff->newValue; // mixed
ThreeWayMerge
Merql\Merge\ThreeWayMerge je hlavný algoritmus zlúčenia.
__construct(?CellMergeConfig $cellMergeConfig = null)
Ak chcete povoliť zlúčenie na úrovni buniek pre stĺpce TEXT a JSON, zadajte CellMergeConfig.
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
Vykoná trojcestné zlúčenie. Zmeny vypočíta interne (od základu po naše a od základu po ich) a zlúči ich.
$result = $merge->merge($baseSnapshot, $oursSnapshot, $theirsSnapshot);
patch(Snapshot $base, Snapshot $changes): MergeResult
Skratka na dvojcestné zlúčenie. Ekvivalent merge($base, $base, $changes).
schemaMismatches(): array
Vráti SchemaException[] pre všetky rozdiely v schéme zistené počas posledného zlúčenia (pridané alebo odstránené stĺpce medzi snímkami).
MergeResult
Merql\Merge\MergeResult je objekt hodnoty iba na čítanie, ktorý obsahuje výsledok zlúčenia.
$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 je serializovateľný model na kontrolu zlúčenia.
$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>
Použite MergePlanSerializer::toJson() a ::fromJson() na stabilné spiatočné prevody JSON.
Výbery
ChangeGroupSelection uchováva ID pripravených skupín zmien. Pri vytváraní výsledkov zlúčenia alebo plánov vrátenia vybraných zmien ho preveďte na OperationSelection.
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 uchováva opačné operácie a očakávania týkajúce sa odchýlok pre vybranú aplikáciu zmien.
use Merql\Rollback\RollbackPlanBuilder;
use Merql\Rollback\RollbackPlanSerializer;
$rollback = (new RollbackPlanBuilder())->build(
'rollback-1',
$plan,
$operationSelection,
$liveBeforeRows,
);
$json = RollbackPlanSerializer::toJson($rollback);
Pred vrátením zmien použite RollbackDrift a potom spustite opačné operácie pomocou RollbackPlanApplier.
MergeOperation
Merql\Merge\MergeOperation je jedna vyriešená operácia zo zlúčenia.
$op->type; // string: 'insert' | 'update' | 'delete'
$op->table; // string
$op->rowKey; // string
$op->values; // array<string, mixed>
$op->source; // string: 'ours' | 'theirs' | 'merged'
Typové konštanty:
MergeOperation::TYPE_INSERT; // 'insert'
MergeOperation::TYPE_UPDATE; // 'update'
MergeOperation::TYPE_DELETE; // 'delete'
Konflikt
Merql\Merge\Conflict predstavuje nevyriešený konflikt zlúčenia.
$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 konfliktov
| Typ | Význam |
|---|---|
update_update |
Obe strany zmenili ten istý stĺpec na odlišné hodnoty |
update_delete |
Naša strana aktualizovala riadok, ktorý ich strana odstránila |
delete_update |
Naša strana odstránila riadok, ktorý ich strana aktualizovala |
insert_insert |
Obe strany vložili riadok s rovnakým primárnym kľúčom |
ConflictResolver
Merql\Merge\ConflictResolver použije zásady riešenia na všetky konflikty vo výsledku zlúčenia.
resolve(MergeResult $result, ConflictPolicy $policy): MergeResult (statická)
Vráti nové MergeResult s konfliktmi vyriešenými podľa zásad.
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 je enum s podkladovým typom a tromi prípadmi.
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 vykonáva logiku zlúčenia po stĺpcoch pre jeden riadok. Interne ho používa ThreeWayMerge.
merge(string $table, string $rowKey, array $base, array $ours, array $theirs, ?CellMergeConfig $cellMergeConfig = null, array $columnTypes = []): array (statická)
Vráti ['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)
Aplikátor
Merql\Apply\Applier vykoná výsledok zlúčenia v databáze.
__construct(DatabaseConnection $connection, ?Driver $driver = null)
apply(MergeResult $result, ?Snapshot $base = null): ApplyResult
Všetky operácie vykoná v jednej transakcii. Pri akejkoľvek chybe transakciu vráti späť a chybu oznámi v ApplyResult::errors() namiesto jej vyvolania. Ak výsledok obsahuje nevyriešené konflikty, vyvolá ConflictException.
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());
}
Poradie cudzích kľúčov sa spracúva automaticky: vkladania sa zoradia podľa závislostí a odstraňovania v opačnom poradí závislostí.
ApplyResult
Merql\Apply\ApplyResult je objekt hodnoty iba na čítanie, ktorý vracia aplikátor.
$applied->rowsAffected(); // int
$applied->errors(); // list<string>
$applied->hasErrors(); // bool
Po vrátení aplikácie zmien späť rowsAffected() stále počíta príkazy spustené pred zlyhaním (#4). Skôr než tomuto počtu dôverujete, skontrolujte hasErrors().
DryRun
Merql\Apply\DryRun vytvára ľuďom čitateľné SQL bez vykonania čohokoľvek.
generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (statická)
Vráti zoznam reťazcov SQL so vloženými hodnotami (len na účely zobrazenia).
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 vytvára parametrizované príkazy SQL. Interne ich používajú Applier aj DryRun.
generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (statická)
Vráti 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 nastavuje stratégie zlúčenia na úrovni buniek pre konkrétne stĺpce alebo typy stĺpcov.
auto(): self (statická)
Továrenská metóda, ktorá priradí TextCellMerger stĺpcom TEXT/LONGTEXT a JsonCellMerger stĺpcom JSON.
use Merql\CellMerge\CellMergeConfig;
$config = CellMergeConfig::auto();
forColumn(string $column, CellMerger $merger): self
Priradí zlúčovač konkrétnemu stĺpcu. Pre kvalifikované názvy použite table.column alebo zadajte iba column pre všetky tabuľky.
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
Priradí zlúčovač všetkým stĺpcom zodpovedajúcim vzoru typu (zhoda podreťazca bez rozlišovania veľkosti písmen).
use Merql\CellMerge\CellMergeConfig;
use Merql\CellMerge\JsonCellMerger;
$config = (new CellMergeConfig())
->forType('json', new JsonCellMerger());
getMerger(string $table, string $column, string $columnType = ''): CellMerger
Vyhľadá zlúčovač pre danú tabuľku, stĺpec a typ. Priorita: kvalifikovaný názov stĺpca, nekvalifikovaný názov stĺpca, vzor typu, predvolená hodnota (nepriehľadná).
CellMerger (rozhranie)
Merql\CellMerge\CellMerger je rozhranie pre stratégie zlúčenia na úrovni buniek.
use Merql\CellMerge\CellMerger;
use Merql\CellMerge\CellMergeResult;
interface CellMerger
{
public function merge(mixed $base, mixed $ours, mixed $theirs): CellMergeResult;
}
K dispozícii sú tri vstavané implementácie.
TextCellMerger
Merql\CellMerge\TextCellMerger zlučuje viacriadkový text pomocou trojcestného porovnania po jednotlivých riadkoch (rovnaký algoritmus, aký git používa pre obsah súborov). Ak obe strany upravia rôzne riadky, zlúčenie prebehne bez konfliktu. Ak obe strany odlišne upravia ten istý riadok, nahlási 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 zlučuje hodnoty JSON nezávislým porovnávaním kľúčov najvyššej úrovne. Každý kľúč sa zlúči pomocou trojcestnej logiky. Vnorené objekty sa porovnávajú ako nepriehľadné reťazce JSON (nezlučujú sa rekurzívne).
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 je predvolená možnosť. S hodnotami zaobchádza ako s nepriehľadnými reťazcami a pri každom rozdiele vždy nahlási konflikt.
CellMergeResult
Merql\CellMerge\CellMergeResult je návratový typ všetkých zlúčovačov buniek.
$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 je reprezentácia štruktúry tabuľky iba na čítanie.
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>
Systém ovládačov
merql používa zásuvný systém ovládačov na abstrakciu operácií špecifických pre databázy. Ovládače sa automaticky určujú podľa identity ovládača pripojenia.
Driver (rozhranie)
Merql\Driver\Driver definuje zmluvu, ktorú implementujú všetky databázové ovládače.
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;
}
Vstavané implementácie: MysqlDriver a SqliteDriver.
DriverFactory
Merql\Driver\DriverFactory automaticky určí ovládač podľa pripojenia.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
Zaregistrovanie vlastného ovládača pre iné databázy:
DriverFactory::register('pgsql', MyPostgresDriver::class);
Filtre
TableFilter
Merql\Filter\TableFilter zahŕňa alebo vylučuje tabuľky pomocou vzorov glob.
use Merql\Filter\TableFilter;
$filter = TableFilter::exclude(['cache_*', 'sessions', 'temp_*']);
$filter = TableFilter::include(['posts', 'users', 'comments']);
ColumnFilter
Merql\Filter\ColumnFilter odstraňuje konkrétne stĺpce zo snímkov.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'created_at', 'modified_date']);
RowFilter
Merql\Filter\RowFilter filtruje riadky pomocou predikátovej funkcie.
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;
});
Výnimky
SnapshotException
Merql\Exceptions\SnapshotException sa vyvolá, keď sa snímok nenájde alebo má neplatný názov.
SnapshotException::notFound('baseline', '/path/to/baseline.json');
MergeException
Merql\Exceptions\MergeException sa vyvolá, keď pri zlúčení chýba požadovaný snímok.
MergeException::snapshotRequired('base');
ConflictException
Merql\Exceptions\ConflictException sa vyvolá pri pokuse použiť výsledok zlúčenia s nevyriešenými konfliktmi.
ConflictException::unresolved(3);
// Message: "Cannot apply merge with 3 unresolved conflict(s)"
SchemaException
Merql\Exceptions\SchemaException sa vyvolá (alebo zhromaždí), keď sa schémy medzi snímkami líšia.
SchemaException::mismatch('posts', 'column "tags" exists in current but not in base');
Rozdiely v schéme nezastavia zlúčenie. Zhromaždia sa a možno si ich prezrieť cez $result->schemaMismatches().