PHP API uzziņu rokasgrāmata
Pilnīga uzziņu rokasgrāmata par visām merql publiskajām klasēm un metodēm.
Merql (fasāde)
Merql\Merql ir statiska ieejas vieta biežākajām darbībām. Tā apvieno zemāka līmeņa klases un automātiski pārvalda momentuzņēmumu saglabāšanu.
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
Inicializējiet fasādi ar datubāzes savienojumu. Tas jāizsauc pirms snapshot(), apply() vai applyGuarded(); izsauciet to vēlreiz, lai pārslēgtu datubāzes, piemēram, lai izveidotu mūsu un viņu puses momentuzņēmumus no divām dažādām kopijām. Ja nav $driver, tiek izsaukts DriverFactory::create(), kas rada kļūdu citiem dzinējiem, nevis MySQL un SQLite, ja vien nav reģistrēts draiveris. Nododiet draiveri, lai aizstātu automātisko noteikšanu, vai identitātes noteikumu kopu, lai momentuzņēmuma izveides laikā aizstātu rindu identitāti katrai tabulai.
snapshot(string $name, array $tables = []): Snapshot
Uzņemiet pašreizējā datubāzes stāvokļa momentuzņēmumu un saglabājiet to diskā. Nododiet tabulu nosaukumu masīvu, lai izveidotu momentuzņēmumus tikai konkrētām tabulām, vai izlaidiet to, lai iekļautu visas tabulas.
$snapshot = Merql::snapshot('baseline');
$snapshot = Merql::snapshot('baseline', ['posts', 'users']);
diff(string $base, string $current): Changeset
Ielādējiet divus nosauktus momentuzņēmumus un aprēķiniet izmaiņu kopu starp tiem. init() nav nepieciešams, jo darbība izmanto saglabātos momentuzņēmumus.
$changeset = Merql::diff('before', 'after');
merge(string $base, string $ours, string $theirs): MergeResult
Trīspusēja sapludināšana starp trim nosauktiem momentuzņēmumiem. Atgriež rezultātu ar konfliktus neradošām darbībām un visiem konfliktiem. Sapludināšana notiek kolonnu līmenī: fasāde izveido ThreeWayMerge bez CellMergeConfig, tāpēc šūnu līmeņa sapludināšana netiek veikta. Šūnu līmeņa sapludināšanai izmantojiet tieši ThreeWayMerge.
$result = Merql::merge('base', 'ours', 'theirs');
patch(string $base, string $changes): MergeResult
Divpusēja sapludināšana: piemērot izmaiņas bāzei. Līdzvērtīga merge($base, $base, $changes). Vienmēr iegūst tīru rezultātu, jo vienlaicīgu labojumu nav. Notiek tikai kolonnu līmenī, tāpat kā merge().
$result = Merql::patch('base', 'changes');
apply(MergeResult $result): ApplyResult
Izpildiet tīras sapludināšanas rezultātu datubāzē, kas nodota funkcijai init(). Nepieciešams init(). Ja joprojām ir neatrisināti konflikti, rodas ConflictException.
Tiek izpildīta katra rezultāta darbība, tāpēc viss merge() rezultāts tiek piemērots bez konfliktiem tikai datubāzei, kurā joprojām ir bāzes stāvoklis. Datubāzei, kurā jau ir vienas puses stāvoklis, piemērojiet trūkstošo darbību atlasi; skatiet Guarded Apply.
$applied = Merql::apply($result);
echo $applied->rowsAffected();
plan(string $id, string $base, string $ours, string $theirs, array $metadata = []): MergePlan
Izveidojiet sapludināšanas plānu, kas gatavs UI, no trim nosauktiem momentuzņēmumiem. Plānā ir stabili darbību ID, izmaiņu grupu ID, darbību konteksts, konflikti, shēmas neatbilstības, kopsavilkums, metadati un plāna jaucējvērtība. Sapludināšana notiek kolonnu līmenī, tāpat kā merge(); šūnu līmeņa sapludināšanai nododiet šūnu līmenī sapludinātu rezultātu funkcijai MergePlanBuilder::build().
$plan = Merql::plan('plan-1', 'base', 'ours', 'theirs', [
'source' => 'review-ui',
]);
applyGuarded(MergeResult $result, Snapshot $expectedLive): ApplyResult
Piemērojiet tīras sapludināšanas rezultātu, izmantojot optimistiskus priekšnosacījumus par aktuālajām rindām. Lai atjauninātu vai dzēstu, pašreizējām rindām jāsakrīt ar $expectedLive; lai ievietotu, mērķa identitāte nedrīkst jau pastāvēt. $expectedLive ir mērķa datubāzes momentuzņēmums (viņu puses momentuzņēmums, kad mūsu puses izmaiņas tiek pārnestas uz datubāzi, no kuras tika izveidots viņu puses momentuzņēmums). Ja kāds priekšraksts neietekmē nevienu rindu, transakcija tiek atcelta.
use Merql\Snapshot\SnapshotStore;
$applied = Merql::applyGuarded($selectedResult, SnapshotStore::load('theirs'));
reset(): void
Notīriet iekšējos savienojuma un Snapshotter eksemplārus. Galvenokārt izmanto testos, lai atiestatītu stāvokli starp palaišanas reizēm.
Savienojums
Merql\Connection izveido savienojuma adapterus ar pārdomātiem noklusējuma iestatījumiem. PDO savienojumos kļūdas gadījumā tiek izmantoti izņēmumi, asociatīvais datu izgūšanas režīms, tiek atspējota emulēta sagatavošana un izgūtās vērtības tiek pārveidotas virknēs. mysqli adapteris normalizē izgūtās vērtības tā, lai tās būtu virknes vai 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
Izveido SQLite savienojumu. Automātiski iespējo ārējās atslēgas, izmantojot PRAGMA foreign_keys = ON.
$connection = Connection::sqlite('/var/data/app.sqlite');
$connection = Connection::sqlite(':memory:');
fromDsn(string $dsn, string $username = '', string $password = ''): PdoDatabaseConnection
Izveidojiet savienojumu, izmantojot jebkuru PDO DSN virkni. merql ietver draiverus tikai mysql un sqlite; ar citiem DSN savienojums tiek izveidots, bet Merql::init(), Snapshotter un applieri rada Unsupported database driver, ja vien draiveris nav reģistrēts ar DriverFactory::register().
$connection = Connection::fromDsn('mysql:host=localhost;dbname=app', 'root', 'pass');
fromPdo(PDO $pdo): PdoDatabaseConnection
Aptiniet esošu PDO instanci.
fromMysqli(mysqli $mysqli, string $charset = 'utf8mb4'): MysqliDatabaseConnection
Aptiniet esošu mysqli instanci.
Adaptera līgums
Visi adapteri implementē 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() un scalar() pieņem pozicionālus list<scalar|null> parametrus vietturiem ?. query() atgriež list<array<string, scalar|null>>; gan PDO, gan mysqli adapteros vērtības tiek normalizētas vienādā formā — virkne vai null.
Snapshotter
Merql\Snapshot\Snapshotter uzņem datubāzes stāvokļa momentuzņēmumu. Atšķirībā no fasādes, tas sniedz pilnīgu kontroli pār filtriem un neveic automātisku saglabāšanu.
__construct(DatabaseConnection $connection, ?Driver $driver = null, ?IdentityRuleSet $identityRules = null)
Ja draiveris nav norādīts, tas tiek automātiski noteikts pēc savienojuma identitātes. Nododiet IdentityRuleSet, ja tabulu līmeņa rindu identitātei jāaizstāj shēmas noklusējuma iestatījumi.
capture(string $name, array $tables = [], array $filters = []): Snapshot
Uzņemiet pašreizējā stāvokļa momentuzņēmumu. Norādiet tabulu nosaukumus, lai ierobežotu tvērumu. Norādiet filtru objektus, lai izslēgtu tabulas, kolonnas vai rindas.
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
Uzņemiet fizisko tabulu momentuzņēmumu, izmantojot kanoniskos tabulu nosaukumus. Izmantojiet to, ja vienai loģiskai tabulai dažādās vidēs ir dažādi fiziskie nosaukumi.
$snapshot = $snapshotter->captureAliased('sandbox', [
'wp_onumia_abcd_posts' => 'wp_posts',
'wp_onumia_abcd_postmeta' => 'wp_postmeta',
]);
Iegūtajā momentuzņēmumā tiek saglabāti kanoniskie tabulu nosaukumi, vienlaikus saglabājot fizisko tabulu shēmu, konfigurētās identitātes kolonnas, rindu atslēgas un filtrus.
fromData(string $name, array $tableData): Snapshot (statisks)
Izveidojiet momentuzņēmumu no neapstrādātiem datiem bez datubāzes savienojuma. Noder testēšanai vai datu importēšanai no cita avota.
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']),
]);
Momentuzņēmums
Merql\Snapshot\Snapshot ir tikai lasāms vērtību objekts, kas attēlo pilnu datubāzes stāvokli.
$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 glabā vienas tabulas rindas, kontrolsummas un shē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 ir ievaddati funkcijai 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 nosaka kolonnas, ko izmanto rindu atslēgu izveidei.
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 (statisks)
Nosakiet noklusējuma identitātes noteikumu no shēmas: primārā atslēga, pirmā unikālā atslēga un pēc tam satura rezerves variants.
toArray(): array
Serializējiet noteikumu kā ['type' => string, 'columns' => list<string>].
fromArray(array $data): IdentityRule (statisks)
Izveidojiet noteikumu no serializētiem datiem.
IdentityRuleSet
Merql\Identity\IdentityRuleSet glabā tabulu līmeņa identitātes aizstājējus.
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
Atgrieziet jaunu noteikumu kopu, kurai pievienots vienas tabulas aizstājējs.
conflictsFor(string $table, IdentityRule $rule, array $rows): array
Atgrieziet IdentityConflict ierakstus, ja vairāku rindu atslēga atbilst vienam noteikumam.
toArray(): array
Serializējiet tabulu noteikumus JSON drošā masīvā.
fromArray(array $data): IdentityRuleSet (statisks)
Izveidojiet noteikumu kopu no serializētiem datiem.
SnapshotStore
Merql\Snapshot\SnapshotStore saglabā un ielādē momentuzņēmumus kā JSON failus.
setDirectory(string $directory): void
Iestatiet krātuves direktoriju. Noklusējums ir .merql/snapshots.
save(Snapshot $snapshot): void
Ierakstiet momentuzņēmumu diskā.
load(string $name): Snapshot
Ielādējiet momentuzņēmumu pēc nosaukuma. Ja tas nav atrasts, rodas SnapshotException.
exists(string $name): bool
Pārbaudiet, vai pastāv momentuzņēmuma fails.
delete(string $name): void
Noņemiet momentuzņēmuma failu.
Izmaiņu noteicējs
Merql\Diff\Differ salīdzina divus momentuzņēmumus un izveido izmaiņu kopu.
diff(Snapshot $base, Snapshot $current): Changeset
use Merql\Diff\Differ;
$differ = new Differ();
$changeset = $differ->diff($baseSnapshot, $currentSnapshot);
valuesEqual(mixed $a, mixed $b): bool (statisks)
Salīdziniet divas vērtības, pārvēršot tās virknēs. NULL tiek uzskatīts par atsevišķu vērtību: NULL === NULL ir patiess, NULL === '' ir aplams.
Izmaiņu kopa
Merql\Diff\Changeset ir tikai lasāma rindu līmeņa darbību kolekcija.
$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
Tikai lasāmi vērtību objekti, kas attēlo atsevišķas rindu izmaiņas.
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 attēlo vienas kolonnas izmaiņu rindas atjauninājumā.
$diff->column; // string
$diff->oldValue; // mixed
$diff->newValue; // mixed
ThreeWayMerge
Merql\Merge\ThreeWayMerge ir galvenais sapludināšanas algoritms.
__construct(?CellMergeConfig $cellMergeConfig = null)
Nododiet CellMergeConfig, lai iespējotu šūnu līmeņa sapludināšanu TEXT un JSON kolonnām.
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
Veiciet trīspusēju sapludināšanu. Aprēķina izmaiņu kopas iekšēji (no bāzes līdz mūsu pusei, no bāzes līdz viņu pusei) un tās sapludina.
$result = $merge->merge($baseSnapshot, $oursSnapshot, $theirsSnapshot);
patch(Snapshot $base, Snapshot $changes): MergeResult
Divpusējas sapludināšanas saīsinājums. Līdzvērtīgs merge($base, $base, $changes).
schemaMismatches(): array
Atgriež SchemaException[] par visām shēmas atšķirībām, kas konstatētas pēdējās sapludināšanas laikā (kolonnas, kas pievienotas vai noņemtas starp momentuzņēmumiem).
MergeResult
Merql\Merge\MergeResult ir tikai lasāms vērtību objekts, kurā iekļauts sapludināšanas rezultāts.
$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 ir serializējams sapludināšanas pārskatīšanas modelis.
$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>
Izmantojiet MergePlanSerializer::toJson() un ::fromJson(), lai nodrošinātu stabilu JSON turp un atpakaļ pārveidi.
Atlases
ChangeGroupSelection glabā iestudēto izmaiņu grupu ID. Pārvērtiet to par OperationSelection, veidojot atlasītos sapludināšanas rezultātus vai atgriešanas plānus.
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 glabā apgrieztās darbības un novirzes sagaidāmās vērtības atlasītai piemērošanai.
use Merql\Rollback\RollbackPlanBuilder;
use Merql\Rollback\RollbackPlanSerializer;
$rollback = (new RollbackPlanBuilder())->build(
'rollback-1',
$plan,
$operationSelection,
$liveBeforeRows,
);
$json = RollbackPlanSerializer::toJson($rollback);
Pirms atgriešanas piemērošanas izmantojiet RollbackDrift, pēc tam RollbackPlanApplier, lai izpildītu apgrieztās darbības.
MergeOperation
Merql\Merge\MergeOperation ir viena atrisināta darbība no sapludināšanas.
$op->type; // string: 'insert' | 'update' | 'delete'
$op->table; // string
$op->rowKey; // string
$op->values; // array<string, mixed>
$op->source; // string: 'ours' | 'theirs' | 'merged'
Tipu konstantes:
MergeOperation::TYPE_INSERT; // 'insert'
MergeOperation::TYPE_UPDATE; // 'update'
MergeOperation::TYPE_DELETE; // 'delete'
Konflikts
Merql\Merge\Conflict attēlo neatrisinātu sapludināšanas konfliktu.
$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
Konfliktu veidi
| Veids | Nozīme |
|---|---|
update_update |
Abas puses mainīja vienu un to pašu kolonnu uz dažādām vērtībām |
update_delete |
Mūsu puse atjaunināja rindu, ko viņu puse dzēsa |
delete_update |
Mūsu puse dzēsa rindu, ko viņu puse atjaunināja |
insert_insert |
Abas puses ievietoja rindu ar vienu un to pašu primāro atslēgu |
ConflictResolver
Merql\Merge\ConflictResolver visiem sapludināšanas rezultāta konfliktiem piemēro atrisināšanas politiku.
resolve(MergeResult $result, ConflictPolicy $policy): MergeResult (statisks)
Atgriež jaunu MergeResult, kurā konflikti ir atrisināti saskaņā ar politiku.
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 ir backed enum ar trim variantiem.
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 veic vienas rindas kolonnu līmeņa sapludināšanu. Iekšēji to izmanto ThreeWayMerge.
merge(string $table, string $rowKey, array $base, array $ours, array $theirs, ?CellMergeConfig $cellMergeConfig = null, array $columnTypes = []): array (statisks)
Atgriež ['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)
Applier
Merql\Apply\Applier izpilda sapludināšanas rezultātu datubāzē.
__construct(DatabaseConnection $connection, ?Driver $driver = null)
apply(MergeResult $result, ?Snapshot $base = null): ApplyResult
Izpilda visas darbības vienā transakcijā. Ja rodas kļūda, transakciju atceļ un par to ziņo laukā ApplyResult::errors(), nevis rada izņēmumu. Ja rezultātā ir neatrisināti konflikti, rodas 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());
}
Ārējo atslēgu secība tiek apstrādāta automātiski: ievietošanas darbības tiek sakārtotas atkarību secībā, bet dzēšanas darbības — apgrieztā atkarību secībā.
ApplyResult
Merql\Apply\ApplyResult ir tikai lasāms vērtību objekts, ko atgriež applier.
$applied->rowsAffected(); // int
$applied->errors(); // list<string>
$applied->hasErrors(); // bool
Pēc atceltas piemērošanas rowsAffected() joprojām uzskaita priekšrakstus, kas tika izpildīti pirms kļūmes (#4). Pirms paļaušanās uz šo skaitu pārbaudiet hasErrors().
DryRun
Merql\Apply\DryRun ģenerē cilvēkam lasāmus SQL, neko neizpildot.
generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (statisks)
Atgriež SQL virkņu sarakstu ar ievietotām vērtībām (tikai attēlošanai).
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 ģenerē parametrizētus SQL priekšrakstus. Iekšēji tos izmanto gan Applier, gan DryRun.
generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (statisks)
Atgriež 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 konfigurē šūnu līmeņa sapludināšanas stratēģijas noteiktām kolonnām vai kolonnu tipiem.
auto(): self (statisks)
Ērta izveides funkcija, kas piešķir TextCellMerger TEXT/LONGTEXT kolonnām un JsonCellMerger kolonnām JSON.
use Merql\CellMerge\CellMergeConfig;
$config = CellMergeConfig::auto();
forColumn(string $column, CellMerger $merger): self
Piešķiriet sapludinātāju konkrētai kolonnai. Izmantojiet table.column, lai norādītu pilnībā kvalificētus nosaukumus, vai tikai column visām tabulām.
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
Piešķiriet sapludinātāju visām kolonnām, kas atbilst tipa paraugam (reģistrnejutīga apakšvirknes atbilstība).
use Merql\CellMerge\CellMergeConfig;
use Merql\CellMerge\JsonCellMerger;
$config = (new CellMergeConfig())
->forType('json', new JsonCellMerger());
getMerger(string $table, string $column, string $columnType = ''): CellMerger
Atrodiet sapludinātāju norādītajai tabulai, kolonnai un tipam. Prioritāte: kvalificēts kolonnas nosaukums, nekvalificēts kolonnas nosaukums, tipa paraugs, noklusējums (opaque).
CellMerger (interfeiss)
Merql\CellMerge\CellMerger ir interfeiss šūnu līmeņa sapludināšanas stratēģijām.
use Merql\CellMerge\CellMerger;
use Merql\CellMerge\CellMergeResult;
interface CellMerger
{
public function merge(mixed $base, mixed $ours, mixed $theirs): CellMergeResult;
}
Ir pieejamas trīs iebūvētas implementācijas.
TextCellMerger
Merql\CellMerge\TextCellMerger sapludina vairākas teksta rindas, izmantojot trīspusēju rindu pa rindai atšķirību salīdzināšanu (to pašu algoritmu, ko git izmanto failu saturam). Ja abas puses rediģē dažādas rindas, sapludināšana notiek bez konfliktiem. Ja abas puses atšķirīgi rediģē vienu un to pašu rindu, tiek ziņots par konfliktu.
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 apvieno JSON vērtības, neatkarīgi salīdzinot augšējā līmeņa atslēgas. Katra atslēga tiek apvienota, izmantojot trīsvirzienu loģiku. Iekļautie objekti tiek salīdzināti kā necaurskatāmas JSON virknes (tie netiek apvienoti rekursīvi).
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 ir noklusējuma izvēle. Tā uztver vērtības kā necaurskatāmas virknes un vienmēr ziņo par konfliktu, ja tās atšķiras.
CellMergeResult
Merql\CellMerge\CellMergeResult ir visu šūnu apvienotāju atgriežamais tips.
$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 ir tikai lasāms tabulas struktūras attēlojums.
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>
Draiveru sistēma
merql izmanto paplašināmu draiveru sistēmu, lai abstrahētu datubāzēm specifiskās darbības. Draiveri tiek automātiski noteikti pēc savienojuma draivera identifikatora.
Draiveris (saskarne)
Merql\Driver\Driver definē līgumu, ko īsteno visi datubāzu draiveri.
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;
}
Iebūvētās realizācijas: MysqlDriver un SqliteDriver.
DriverFactory
Merql\Driver\DriverFactory automātiski nosaka draiveri pēc savienojuma.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
Reģistrējiet pielāgotu draiveri citām datubāzēm:
DriverFactory::register('pgsql', MyPostgresDriver::class);
Filtri
TableFilter
Merql\Filter\TableFilter iekļauj vai izslēdz tabulas, izmantojot glob modeļus.
use Merql\Filter\TableFilter;
$filter = TableFilter::exclude(['cache_*', 'sessions', 'temp_*']);
$filter = TableFilter::include(['posts', 'users', 'comments']);
ColumnFilter
Merql\Filter\ColumnFilter noņem noteiktas kolonnas no momentuzņēmumiem.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'created_at', 'modified_date']);
RowFilter
Merql\Filter\RowFilter filtrē rindas, izmantojot predikāta funkciju.
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;
});
Izņēmumi
SnapshotException
Merql\Exceptions\SnapshotException tiek izmests, ja momentuzņēmumu nevar atrast vai tā nosaukums nav derīgs.
SnapshotException::notFound('baseline', '/path/to/baseline.json');
MergeException
Merql\Exceptions\MergeException tiek izmests, ja apvienošanai trūkst nepieciešamā momentuzņēmuma.
MergeException::snapshotRequired('base');
ConflictException
Merql\Exceptions\ConflictException tiek izmests, mēģinot lietot apvienošanas rezultātu, kurā ir neatrisināti konflikti.
ConflictException::unresolved(3);
// Message: "Cannot apply merge with 3 unresolved conflict(s)"
SchemaException
Merql\Exceptions\SchemaException tiek izmests (vai apkopots), ja momentuzņēmumu shēmas atšķiras.
SchemaException::mismatch('posts', 'column "tags" exists in current but not in base');
Shēmu neatbilstības neaptur apvienošanu. Tās tiek apkopotas un apskatei ir pieejamas, izmantojot $result->schemaMismatches().