Αναφορά PHP API
Πλήρης αναφορά για όλες τις δημόσιες κλάσεις και μεθόδους του merql.
Merql (πρόσοψη)
Το Merql\Merql είναι το στατικό σημείο εισόδου για συνήθεις λειτουργίες. Περιτυλίγει τις κλάσεις χαμηλότερου επιπέδου και διαχειρίζεται αυτόματα τη διατήρηση στιγμιότυπων.
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
Αρχικοποιήστε την πρόσοψη με μια σύνδεση βάσης δεδομένων. Πρέπει να κληθεί πριν από τα
snapshot(), apply() ή applyGuarded()· καλέστε την ξανά για εναλλαγή βάσεων δεδομένων,
για παράδειγμα για να δημιουργήσετε στιγμιότυπα των ours και theirs από δύο διαφορετικά αντίγραφα. Χωρίς $driver, καλεί το DriverFactory::create(), το οποίο προκαλεί εξαίρεση για μηχανές εκτός από MySQL και SQLite, εκτός αν έχει καταχωριστεί πρόγραμμα οδήγησης. Περάστε ένα πρόγραμμα οδήγησης για να παρακάμψετε τον αυτόματο εντοπισμό ή ένα σύνολο κανόνων ταυτοποίησης για να παρακάμψετε την ταυτότητα γραμμών ανά πίνακα κατά τη λήψη στιγμιότυπου.
snapshot(string $name, array $tables = []): Snapshot
Καταγράψτε την τρέχουσα κατάσταση της βάσης δεδομένων και αποθηκεύστε την στον δίσκο. Περάστε έναν πίνακα ονομάτων για να δημιουργήσετε στιγμιότυπο συγκεκριμένων πινάκων ή παραλείψτε τον για όλους τους πίνακες.
$snapshot = Merql::snapshot('baseline');
$snapshot = Merql::snapshot('baseline', ['posts', 'users']);
diff(string $base, string $current): Changeset
Φορτώστε δύο στιγμιότυπα με όνομα και υπολογίστε το σύνολο αλλαγών μεταξύ τους. Δεν απαιτείται το init(), καθώς λειτουργεί με αποθηκευμένα στιγμιότυπα.
$changeset = Merql::diff('before', 'after');
merge(string $base, string $ours, string $theirs): MergeResult
Συγχώνευση τριών στιγμιότυπων τριών κατευθύνσεων. Επιστρέφει αποτέλεσμα με καθαρές λειτουργίες και τυχόν διενέξεις. Συγχωνεύει σε επίπεδο στηλών: η πρόσοψη δημιουργεί το ThreeWayMerge χωρίς CellMergeConfig, επομένως δεν εφαρμόζεται συγχώνευση σε επίπεδο κελιού. Χρησιμοποιήστε απευθείας το ThreeWayMerge γι' αυτό.
$result = Merql::merge('base', 'ours', 'theirs');
patch(string $base, string $changes): MergeResult
Συγχώνευση δύο κατευθύνσεων: εφαρμογή αλλαγών στο base. Ισοδυναμεί με το merge($base, $base, $changes). Παράγει πάντα καθαρό αποτέλεσμα, καθώς δεν υπάρχουν ταυτόχρονες επεξεργασίες. Μόνο σε επίπεδο στηλών, όπως το merge().
$result = Merql::patch('base', 'changes');
apply(MergeResult $result): ApplyResult
Εκτελέστε ένα καθαρό αποτέλεσμα συγχώνευσης στη βάση δεδομένων που περάστηκε στο init(). Απαιτείται το init(). Προκαλεί εξαίρεση ConflictException αν παραμένουν ανεπίλυτες διενέξεις.
Εκτελείται κάθε λειτουργία του αποτελέσματος, επομένως ολόκληρο το αποτέλεσμα του merge() εφαρμόζεται ομαλά μόνο σε βάση δεδομένων που εξακολουθεί να έχει την κατάσταση base. Για βάση δεδομένων που έχει ήδη την κατάσταση μιας πλευράς, εφαρμόστε επιλεγμένες λειτουργίες που της λείπουν· δείτε την ενότητα Guarded Apply.
$applied = Merql::apply($result);
echo $applied->rowsAffected();
plan(string $id, string $base, string $ours, string $theirs, array $metadata = []): MergePlan
Δημιουργήστε σχέδιο συγχώνευσης έτοιμο για UI από τρία στιγμιότυπα με όνομα. Το σχέδιο περιλαμβάνει σταθερά ID λειτουργιών, ID ομάδων αλλαγών, περιβάλλον λειτουργιών, διενέξεις, ασυμφωνίες σχήματος, σύνοψη, μεταδεδομένα και κατακερματισμό σχεδίου. Η συγχώνευση γίνεται σε επίπεδο στηλών, όπως στο merge()· περάστε αποτέλεσμα συγχώνευσης κελιών στο MergePlanBuilder::build() για συγχώνευση σε επίπεδο κελιού.
$plan = Merql::plan('plan-1', 'base', 'ours', 'theirs', [
'source' => 'review-ui',
]);
applyGuarded(MergeResult $result, Snapshot $expectedLive): ApplyResult
Εφαρμόστε ένα καθαρό αποτέλεσμα συγχώνευσης με αισιόδοξες προϋποθέσεις στις ζωντανές γραμμές. Οι ενημερώσεις και οι διαγραφές απαιτούν οι τρέχουσες ζωντανές γραμμές να αντιστοιχούν στο $expectedLive· για τις εισαγωγές απαιτείται να μην υπάρχει ήδη η ταυτότητα-στόχος. Το $expectedLive είναι στιγμιότυπο της βάσης δεδομένων-στόχου (theirs, όταν προωθείτε το ours στη βάση από την οποία λήφθηκε το theirs). Κάθε εντολή που επηρεάζει μηδέν γραμμές προκαλεί rollback της συναλλαγής.
use Merql\Snapshot\SnapshotStore;
$applied = Merql::applyGuarded($selectedResult, SnapshotStore::load('theirs'));
reset(): void
Καθαρίστε τις εσωτερικές συνδέσεις και τις παρουσίες Snapshotter. Χρησιμοποιείται κυρίως στις δοκιμές για επαναφορά της κατάστασης μεταξύ εκτελέσεων.
Σύνδεση
Το Merql\Connection δημιουργεί προσαρμογείς σύνδεσης με κατάλληλες προεπιλογές. Οι συνδέσεις PDO χρησιμοποιούν εξαιρέσεις σε περίπτωση σφάλματος, συσχετισμένη λειτουργία ανάκτησης, απενεργοποιημένες προσομοιωμένες προετοιμασμένες εντολές και ανακτημένες τιμές ως συμβολοσειρές. Ο προσαρμογέας mysqli κανονικοποιεί τις ανακτημένες τιμές στην ίδια μορφή συμβολοσειράς ή 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
Δημιουργεί σύνδεση SQLite. Ενεργοποιεί αυτόματα τα ξένα κλειδιά μέσω του PRAGMA foreign_keys = ON.
$connection = Connection::sqlite('/var/data/app.sqlite');
$connection = Connection::sqlite(':memory:');
fromDsn(string $dsn, string $username = '', string $password = ''): PdoDatabaseConnection
Συνδεθείτε με οποιαδήποτε συμβολοσειρά DSN του PDO. Το merql παρέχει προγράμματα οδήγησης μόνο για τα mysql και sqlite· με άλλα DSN η σύνδεση ανοίγει, αλλά τα Merql::init(), Snapshotter και οι appliers προκαλούν Unsupported database driver, εκτός αν καταχωριστεί πρόγραμμα οδήγησης με το DriverFactory::register().
$connection = Connection::fromDsn('mysql:host=localhost;dbname=app', 'root', 'pass');
fromPdo(PDO $pdo): PdoDatabaseConnection
Περιτυλίξτε μια υπάρχουσα παρουσία PDO.
fromMysqli(mysqli $mysqli, string $charset = 'utf8mb4'): MysqliDatabaseConnection
Περιτυλίξτε μια υπάρχουσα παρουσία mysqli.
Σύμβαση προσαρμογέα
Όλοι οι προσαρμογείς υλοποιούν το 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() και scalar() δέχονται παραμέτρους list<scalar|null> κατά θέση για placeholders ?. Το query() επιστρέφει list<array<string, scalar|null>>· οι τιμές κανονικοποιούνται στην ίδια μορφή συμβολοσειράς ή null στους προσαρμογείς PDO και mysqli.
Εργαλείο λήψης στιγμιότυπων
Το Merql\Snapshot\Snapshotter καταγράφει την κατάσταση της βάσης δεδομένων. Σε αντίθεση με την πρόσοψη, σας δίνει πλήρη έλεγχο στα φίλτρα και δεν αποθηκεύει αυτόματα.
__construct(DatabaseConnection $connection, ?Driver $driver = null, ?IdentityRuleSet $identityRules = null)
Το πρόγραμμα οδήγησης εντοπίζεται αυτόματα από την ταυτότητα σύνδεσης, αν δεν δοθεί. Περάστε ένα
IdentityRuleSet όταν η ταυτότητα γραμμών ανά πίνακα πρέπει να παρακάμπτει τις προεπιλογές του σχήματος.
capture(string $name, array $tables = [], array $filters = []): Snapshot
Καταγράψτε την τρέχουσα κατάσταση. Περάστε ονόματα πινάκων για περιορισμό του πεδίου εφαρμογής. Περάστε αντικείμενα φίλτρων για να εξαιρέσετε πίνακες, στήλες ή γραμμές.
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
Καταγράψτε φυσικούς πίνακες με κανονικά ονόματα πινάκων. Χρησιμοποιήστε το όταν ο ίδιος λογικός πίνακας έχει διαφορετικά φυσικά ονόματα σε διαφορετικά περιβάλλοντα.
$snapshot = $snapshotter->captureAliased('sandbox', [
'wp_onumia_abcd_posts' => 'wp_posts',
'wp_onumia_abcd_postmeta' => 'wp_postmeta',
]);
Το στιγμιότυπο που προκύπτει αποθηκεύει τα κανονικά ονόματα πινάκων, διατηρώντας παράλληλα το σχήμα φυσικών πινάκων, τις διαμορφωμένες στήλες ταυτοποίησης, τα κλειδιά γραμμών και τα φίλτρα.
fromData(string $name, array $tableData): Snapshot (στατικό)
Δημιουργήστε ένα στιγμιότυπο από ακατέργαστα δεδομένα χωρίς σύνδεση σε βάση δεδομένων. Χρήσιμο για δοκιμές ή για εισαγωγή δεδομένων από άλλη πηγή.
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']),
]);
Στιγμιότυπο
Το Merql\Snapshot\Snapshot είναι ένα αντικείμενο τιμής μόνο για ανάγνωση που αναπαριστά μια πλήρη κατάσταση βάσης δεδομένων.
$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 περιέχει τις γραμμές, τα αποτυπώματα και το σχήμα ενός πίνακα.
$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 είναι δεδομένα εισόδου για το 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 ορίζει τις στήλες που χρησιμοποιούνται για τη δημιουργία κλειδιών γραμμών.
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 (στατικό)
Επιλύει τον προεπιλεγμένο κανόνα ταυτότητας από το σχήμα: πρωτεύον κλειδί, πρώτο μοναδικό κλειδί, έπειτα εναλλακτική βάσει περιεχομένου.
toArray(): array
Σειριοποιεί τον κανόνα ως ['type' => string, 'columns' => list<string>].
fromArray(array $data): IdentityRule (στατικό)
Δημιουργεί έναν κανόνα από σειριοποιημένα δεδομένα.
IdentityRuleSet
Το Merql\Identity\IdentityRuleSet αποθηκεύει παρακάμψεις ταυτότητας ανά πίνακα.
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
Επιστρέφει ένα νέο σύνολο κανόνων με μια παράκαμψη για έναν πίνακα.
conflictsFor(string $table, IdentityRule $rule, array $rows): array
Επιστρέφει τις εγγραφές IdentityConflict όταν πολλές γραμμές παράγουν το ίδιο κλειδί για έναν
κανόνα.
toArray(): array
Σειριοποιεί τους κανόνες πινάκων ως πίνακα ασφαλή για JSON.
fromArray(array $data): IdentityRuleSet (στατικό)
Δημιουργεί ένα σύνολο κανόνων από σειριοποιημένα δεδομένα.
SnapshotStore
Το Merql\Snapshot\SnapshotStore αποθηκεύει και φορτώνει στιγμιότυπα ως αρχεία JSON.
setDirectory(string $directory): void
Ορίζει τον κατάλογο αποθήκευσης. Η προεπιλογή είναι .merql/snapshots.
save(Snapshot $snapshot): void
Εγγράφει ένα στιγμιότυπο στον δίσκο.
load(string $name): Snapshot
Φορτώνει ένα στιγμιότυπο με βάση το όνομά του. Αν δεν βρεθεί, προκαλείται το SnapshotException.
exists(string $name): bool
Ελέγχει αν υπάρχει αρχείο στιγμιότυπου.
delete(string $name): void
Αφαιρεί ένα αρχείο στιγμιότυπου.
Διαφορές
Το Merql\Diff\Differ συγκρίνει δύο στιγμιότυπα και παράγει ένα σύνολο αλλαγών.
diff(Snapshot $base, Snapshot $current): Changeset
use Merql\Diff\Differ;
$differ = new Differ();
$changeset = $differ->diff($baseSnapshot, $currentSnapshot);
valuesEqual(mixed $a, mixed $b): bool (στατικό)
Συγκρίνει δύο τιμές μετατρέποντάς τες σε συμβολοσειρές. Το NULL αντιμετωπίζεται ως διακριτή τιμή: το NULL === NULL είναι true, το NULL === '' είναι false.
Σύνολο αλλαγών
Το Merql\Diff\Changeset είναι μια συλλογή λειτουργιών ανά γραμμή, μόνο για ανάγνωση.
$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
Αντικείμενα τιμής μόνο για ανάγνωση που αναπαριστούν μεμονωμένες αλλαγές γραμμών.
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 αναπαριστά μία αλλαγή στήλης σε μια ενημέρωση γραμμής.
$diff->column; // string
$diff->oldValue; // mixed
$diff->newValue; // mixed
ThreeWayMerge
Το Merql\Merge\ThreeWayMerge είναι ο βασικός αλγόριθμος συγχώνευσης.
__construct(?CellMergeConfig $cellMergeConfig = null)
Περάστε ένα CellMergeConfig για να ενεργοποιήσετε τη συγχώνευση σε επίπεδο κελιού για στήλες TEXT και 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
Εκτελεί μια συγχώνευση τριών κατευθύνσεων. Υπολογίζει εσωτερικά τα σύνολα αλλαγών (από τη βάση σε εμάς, από τη βάση σε εκείνους) και τα συγχωνεύει.
$result = $merge->merge($baseSnapshot, $oursSnapshot, $theirsSnapshot);
patch(Snapshot $base, Snapshot $changes): MergeResult
Συντόμευση για συγχώνευση δύο κατευθύνσεων. Ισοδυναμεί με merge($base, $base, $changes).
schemaMismatches(): array
Επιστρέφει το SchemaException[] για τυχόν διαφορές σχήματος που εντοπίστηκαν στην τελευταία συγχώνευση (στήλες που προστέθηκαν ή αφαιρέθηκαν μεταξύ στιγμιότυπων).
MergeResult
Το Merql\Merge\MergeResult είναι ένα αντικείμενο τιμής μόνο για ανάγνωση που περιέχει το αποτέλεσμα της συγχώνευσης.
$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 είναι ένα μοντέλο ελέγχου συγχώνευσης που μπορεί να σειριοποιηθεί.
$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>
Χρησιμοποιήστε τα MergePlanSerializer::toJson() και ::fromJson() για σταθερούς κύκλους JSON
μετατροπής.
Επιλογές
Το ChangeGroupSelection αποθηκεύει αναγνωριστικά ομάδων αλλαγών που έχουν τεθεί σε στάδιο προετοιμασίας. Μετατρέψτε το σε ένα
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 αποθηκεύει αντίστροφες λειτουργίες και προσδοκίες απόκλισης
για μια επιλεγμένη εφαρμογή.
use Merql\Rollback\RollbackPlanBuilder;
use Merql\Rollback\RollbackPlanSerializer;
$rollback = (new RollbackPlanBuilder())->build(
'rollback-1',
$plan,
$operationSelection,
$liveBeforeRows,
);
$json = RollbackPlanSerializer::toJson($rollback);
Χρησιμοποιήστε το RollbackDrift πριν από την εφαρμογή επαναφοράς και έπειτα το RollbackPlanApplier για να εκτελέσετε
τις αντίστροφες λειτουργίες.
MergeOperation
Το Merql\Merge\MergeOperation είναι μία επιλυμένη λειτουργία από τη συγχώνευση.
$op->type; // string: 'insert' | 'update' | 'delete'
$op->table; // string
$op->rowKey; // string
$op->values; // array<string, mixed>
$op->source; // string: 'ours' | 'theirs' | 'merged'
Σταθερές τύπων:
MergeOperation::TYPE_INSERT; // 'insert'
MergeOperation::TYPE_UPDATE; // 'update'
MergeOperation::TYPE_DELETE; // 'delete'
Σύγκρουση
Το Merql\Merge\Conflict αναπαριστά μια ανεπίλυτη σύγκρουση συγχώνευσης.
$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
Τύποι συγκρούσεων
| Τύπος | Σημασία |
|---|---|
update_update |
Και οι δύο πλευρές άλλαξαν την ίδια στήλη σε διαφορετικές τιμές |
update_delete |
Εμείς ενημερώσαμε μια γραμμή που εκείνοι διέγραψαν |
delete_update |
Εμείς διαγράψαμε μια γραμμή που εκείνοι ενημέρωσαν |
insert_insert |
Και οι δύο πλευρές εισήγαγαν μια γραμμή με το ίδιο πρωτεύον κλειδί |
ConflictResolver
Το Merql\Merge\ConflictResolver εφαρμόζει μια πολιτική επίλυσης σε όλες τις συγκρούσεις ενός αποτελέσματος συγχώνευσης.
resolve(MergeResult $result, ConflictPolicy $policy): MergeResult (στατικό)
Επιστρέφει ένα νέο MergeResult με τις συγκρούσεις επιλυμένες σύμφωνα με την πολιτική.
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 είναι απαριθμημένος τύπος με τρεις περιπτώσεις.
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 εκτελεί λογική συγχώνευσης ανά στήλη για μία γραμμή. Χρησιμοποιείται εσωτερικά από το ThreeWayMerge.
merge(string $table, string $rowKey, array $base, array $ours, array $theirs, ?CellMergeConfig $cellMergeConfig = null, array $columnTypes = []): array (στατικό)
Επιστρέφει το ['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)
Εφαρμογή
Το Merql\Apply\Applier εκτελεί ένα αποτέλεσμα συγχώνευσης σε μια βάση δεδομένων.
__construct(DatabaseConnection $connection, ?Driver $driver = null)
apply(MergeResult $result, ?Snapshot $base = null): ApplyResult
Εκτελεί όλες τις λειτουργίες σε μία συναλλαγή. Σε οποιοδήποτε σφάλμα, κάνει επαναφορά και το αναφέρει στο ApplyResult::errors() αντί να προκαλέσει εξαίρεση. Προκαλεί το 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());
}
Η σειρά των ξένων κλειδιών διεκπεραιώνεται αυτόματα: οι εισαγωγές ταξινομούνται κατά σειρά εξάρτησης και οι διαγραφές με αντίστροφη σειρά εξάρτησης.
ApplyResult
Το Merql\Apply\ApplyResult είναι ένα αντικείμενο τιμής μόνο για ανάγνωση που επιστρέφεται από το εργαλείο εφαρμογής.
$applied->rowsAffected(); // int
$applied->errors(); // list<string>
$applied->hasErrors(); // bool
Μετά από μια εφαρμογή που έγινε επαναφορά, το rowsAffected() εξακολουθεί να μετρά τις εντολές που εκτελέστηκαν πριν από την αποτυχία (#4). Ελέγξτε το hasErrors() πριν βασιστείτε στον αριθμό.
DryRun
Το Merql\Apply\DryRun δημιουργεί αναγνώσιμες από τον άνθρωπο εντολές SQL χωρίς να εκτελεί τίποτα.
generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (στατικό)
Επιστρέφει μια λίστα συμβολοσειρών SQL με ενσωματωμένες τιμές (μόνο για εμφάνιση).
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 δημιουργεί παραμετροποιημένες εντολές SQL. Χρησιμοποιείται εσωτερικά τόσο από το Applier όσο και από το DryRun.
generate(MergeResult $result, ?Snapshot $base = null, array $fkDependencies = [], ?Driver $driver = null): array (στατικό)
Επιστρέφει το 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 διαμορφώνει στρατηγικές συγχώνευσης σε επίπεδο κελιού για συγκεκριμένες στήλες ή τύπους στηλών.
auto(): self (στατικό)
Εργοστασιακή μέθοδος ευκολίας που αντιστοιχίζει το TextCellMerger σε στήλες TEXT/LONGTEXT και το JsonCellMerger σε στήλες JSON.
use Merql\CellMerge\CellMergeConfig;
$config = CellMergeConfig::auto();
forColumn(string $column, CellMerger $merger): self
Αντιστοιχίστε έναν συγχωνευτή σε μια συγκεκριμένη στήλη. Χρησιμοποιήστε το table.column για πλήρως προσδιορισμένα ονόματα ή μόνο το column για όλους τους πίνακες.
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
Αντιστοιχίζει έναν συγχωνευτή σε όλες τις στήλες που ταιριάζουν με ένα μοτίβο τύπου (αντιστοίχιση υποσυμβολοσειράς χωρίς διάκριση πεζών-κεφαλαίων).
use Merql\CellMerge\CellMergeConfig;
use Merql\CellMerge\JsonCellMerger;
$config = (new CellMergeConfig())
->forType('json', new JsonCellMerger());
getMerger(string $table, string $column, string $columnType = ''): CellMerger
Αναζητά τον συγχωνευτή για έναν συγκεκριμένο πίνακα, στήλη και τύπο. Προτεραιότητα: πλήρως προσδιορισμένο όνομα στήλης, μη προσδιορισμένο όνομα στήλης, μοτίβο τύπου, προεπιλογή (αδιαφανής).
CellMerger (διεπαφή)
Το Merql\CellMerge\CellMerger είναι η διεπαφή για στρατηγικές συγχώνευσης σε επίπεδο κελιού.
use Merql\CellMerge\CellMerger;
use Merql\CellMerge\CellMergeResult;
interface CellMerger
{
public function merge(mixed $base, mixed $ours, mixed $theirs): CellMergeResult;
}
Παρέχονται τρεις ενσωματωμένες υλοποιήσεις.
TextCellMerger
Το Merql\CellMerge\TextCellMerger συγχωνεύει κείμενο πολλών γραμμών χρησιμοποιώντας σύγκριση διαφορών γραμμή προς γραμμή τριών κατευθύνσεων (τον ίδιο αλγόριθμο που χρησιμοποιεί το git για το περιεχόμενο αρχείων). Όταν οι δύο πλευρές επεξεργάζονται διαφορετικές γραμμές, η συγχώνευση γίνεται χωρίς σύγκρουση. Όταν και οι δύο πλευρές επεξεργάζονται διαφορετικά την ίδια γραμμή, αναφέρει σύγκρουση.
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 συγχωνεύει τιμές JSON συγκρίνοντας ανεξάρτητα τα κλειδιά ανώτατου επιπέδου. Κάθε κλειδί συγχωνεύεται με λογική τριών κατευθύνσεων. Τα ένθετα αντικείμενα συγκρίνονται ως αδιαφανείς συμβολοσειρές JSON (δεν συγχωνεύονται αναδρομικά).
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 είναι η προεπιλογή. Αντιμετωπίζει τις τιμές ως αδιαφανείς συμβολοσειρές και αναφέρει πάντα σύγκρουση όταν διαφέρουν.
CellMergeResult
Το Merql\CellMerge\CellMergeResult είναι ο τύπος επιστροφής όλων των συγχωνευτών κελιών.
$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 είναι μια αναπαράσταση της δομής πίνακα μόνο για ανάγνωση.
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>
Σύστημα οδηγών
Το merql χρησιμοποιεί ένα σύστημα οδηγών με δυνατότητα προσθήκης εναλλακτικών, για την αφαίρεση των λειτουργιών που εξαρτώνται από τη βάση δεδομένων. Οι οδηγοί εντοπίζονται αυτόματα με βάση την ταυτότητα του οδηγού σύνδεσης.
Driver (διεπαφή)
Το Merql\Driver\Driver ορίζει τη σύμβαση που υλοποιούν όλοι οι οδηγοί βάσεων δεδομένων.
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;
}
Ενσωματωμένες υλοποιήσεις: MysqlDriver και SqliteDriver.
DriverFactory
Το Merql\Driver\DriverFactory εντοπίζει αυτόματα τον οδηγό από μια σύνδεση.
use Merql\Driver\DriverFactory;
$driver = DriverFactory::create($connection);
Καταχωρίστε έναν προσαρμοσμένο οδηγό για άλλες βάσεις δεδομένων:
DriverFactory::register('pgsql', MyPostgresDriver::class);
Φίλτρα
TableFilter
Το Merql\Filter\TableFilter συμπεριλαμβάνει ή εξαιρεί πίνακες χρησιμοποιώντας μοτίβα glob.
use Merql\Filter\TableFilter;
$filter = TableFilter::exclude(['cache_*', 'sessions', 'temp_*']);
$filter = TableFilter::include(['posts', 'users', 'comments']);
ColumnFilter
Το Merql\Filter\ColumnFilter αφαιρεί συγκεκριμένες στήλες από τα στιγμιότυπα.
use Merql\Filter\ColumnFilter;
$filter = ColumnFilter::ignore(['updated_at', 'created_at', 'modified_date']);
RowFilter
Το Merql\Filter\RowFilter φιλτράρει γραμμές με μια συνάρτηση κατηγόρημα.
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;
});
Εξαιρέσεις
SnapshotException
Το Merql\Exceptions\SnapshotException προκαλείται όταν δεν μπορεί να βρεθεί ένα στιγμιότυπο ή το όνομά του δεν είναι έγκυρο.
SnapshotException::notFound('baseline', '/path/to/baseline.json');
MergeException
Το Merql\Exceptions\MergeException προκαλείται όταν λείπει ένα απαιτούμενο στιγμιότυπο για συγχώνευση.
MergeException::snapshotRequired('base');
ConflictException
Το Merql\Exceptions\ConflictException προκαλείται κατά την προσπάθεια εφαρμογής ενός αποτελέσματος συγχώνευσης με ανεπίλυτες συγκρούσεις.
ConflictException::unresolved(3);
// Message: "Cannot apply merge with 3 unresolved conflict(s)"
SchemaException
Το Merql\Exceptions\SchemaException προκαλείται (ή συλλέγεται) όταν διαφέρουν τα σχήματα μεταξύ στιγμιότυπων.
SchemaException::mismatch('posts', 'column "tags" exists in current but not in base');
Οι ασυμφωνίες σχήματος δεν διακόπτουν τη συγχώνευση. Συλλέγονται και είναι διαθέσιμες για επιθεώρηση μέσω του $result->schemaMismatches().