Μετάβαση στο περιεχόμενο

Δημιουργία SQL

Το SqlGenerator μετατρέπει ένα MergeResult σε παραμετροποιημένες εντολές SQL. Όλες οι τιμές μεταβιβάζονται ως παράμετροι και δεν ενσωματώνονται ποτέ στη συμβολοσειρά SQL.

PHP
use Merql\Apply\SqlGenerator;

$statements = SqlGenerator::generate($result);

foreach ($statements as $stmt) {
    echo $stmt['sql'] . "\n";
    // INSERT INTO `posts` (`id`, `title`, `status`) VALUES (?, ?, ?)
    print_r($stmt['params']);
    // [42, 'New Title', 'publish']
}

Χρησιμοποιήστε το generateGuarded() όταν ένα σχέδιο συγχώνευσης που έχει εξεταστεί πρέπει να εφαρμοστεί μόνο εφόσον οι ενεργές γραμμές εξακολουθούν να αντιστοιχούν σε ένα αναμενόμενο στιγμιότυπο.

PHP
use Merql\Apply\SqlGenerator;
use Merql\Snapshot\SnapshotStore;

$statements = SqlGenerator::generateGuarded(
    $selectedResult,
    SnapshotStore::load('theirs'),
);

Μορφή εντολής

Κάθε εντολή είναι ένας συσχετιστικός πίνακας με δύο κλειδιά:

PHP
[
    'sql'    => 'INSERT INTO `posts` (`id`, `title`) VALUES (?, ?)',
    'params' => [42, 'New Title'],
]

Τα αναγνωριστικά (ονόματα πινάκων και στηλών) παρατίθενται σύμφωνα με το στυλ παράθεσης του οδηγού της βάσης δεδομένων. Το MySQL χρησιμοποιεί backticks, ενώ το SQLite χρησιμοποιεί διπλά εισαγωγικά. Όταν δεν παρέχεται οδηγός, τα backticks χρησιμοποιούνται ως προεπιλογή.

Σειρά ενεργειών

Οι ενέργειες ομαδοποιούνται ανά τύπο και εκτελούνται με την εξής σειρά:

  1. INSERTs πρώτα -- οι νέες γραμμές πρέπει να υπάρχουν πριν τις αναφέρουν οι ενημερώσεις.
  2. UPDATEs δεύτερα.
  3. DELETEs τελευταία -- πρέπει να καταργηθούν οι αναφορές στις γραμμές πριν από τη διαγραφή τους.
PHP
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.

Σειρά ξένων κλειδιών

Όταν παρέχονται εξαρτήσεις ξένων κλειδιών, οι ενέργειες μέσα σε κάθε ομάδα ταξινομούνται τοπολογικά. Οι γονικοί πίνακες επεξεργάζονται πριν από τους θυγατρικούς στις εισαγωγές και τις ενημερώσεις. Οι θυγατρικοί πίνακες επεξεργάζονται πριν από τους γονικούς στις διαγραφές.

PHP
$fkDependencies = [
    'comments' => ['posts'],        // comments references posts
    'post_meta' => ['posts'],       // post_meta references posts
];

$statements = SqlGenerator::generate($result, fkDependencies: $fkDependencies);
// INSERTs: posts first, then comments and post_meta
// DELETEs: comments and post_meta first, then posts

Το ForeignKeyResolver εκτελεί τοπολογική ταξινόμηση στο γράφημα εξαρτήσεων. Οι κυκλικές εξαρτήσεις εντοπίζονται και διακόπτονται για να αποφευχθούν ατέρμονοι βρόχοι.

Αυτόματος εντοπισμός ξένων κλειδιών

Το Applier διαβάζει αυτόματα από τη βάση δεδομένων τις σχέσεις ξένων κλειδιών:

PHP
use Merql\Apply\Applier;

$applier = new Applier($connection);
$applied = $applier->apply($result);
// FK dependencies are read from the database via the driver.

Παραδείγματα δημιουργημένων SQL

INSERT

Sql
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES (?, ?, ?, ?)
-- params: [42, 'New Post', 'Body text', 'draft']

Περιλαμβάνονται όλες οι στήλες από τις τιμές της ενέργειας.

UPDATE

Sql
UPDATE `posts` SET `title` = ?, `status` = ? WHERE `id` = ?
-- params: ['New Title', 'publish', 42]

Οι στήλες ταυτότητας (πρωτεύον κλειδί) εξαιρούνται από τον όρο SET και χρησιμοποιούνται στον όρο WHERE. Οι τιμές του όρου WHERE προέρχονται από την αποκωδικοποίηση του κλειδιού της γραμμής.

DELETE

Sql
DELETE FROM `posts` WHERE `id` = ?
-- params: [42]

Στον όρο WHERE εμφανίζονται μόνο στήλες ταυτότητας.

Προστατευμένη UPDATE

Οι προστατευμένες ενημερώσεις περιλαμβάνουν τόσο όρους ταυτότητας όσο και όρους για την αναμενόμενη ενεργή γραμμή.

Sql
UPDATE `posts` SET `title` = ? WHERE `id` = ? AND `status` = ?
-- params: ['New Title', 42, 'draft']

Αν η γραμμή δεν έχει πλέον την αναμενόμενη status, η εντολή επηρεάζει μηδενικές γραμμές και η προστατευμένη εφαρμογή αναιρεί τη συναλλαγή.

Προστατευμένη INSERT

Οι προστατευμένες εισαγωγές χρησιμοποιούν το NOT EXISTS για να αποφύγουν την εισαγωγή σε ταυτότητα που εμφανίστηκε μετά τη δημιουργία του σχεδίου.

Sql
INSERT INTO `posts` (`id`, `title`) SELECT ?, ? WHERE NOT EXISTS (
  SELECT 1 FROM `posts` WHERE `id` = ?
)
-- params: [42, 'New Post', 42]

Χειρισμός NULL

Οι τιμές NULL μεταβιβάζονται ως PHP null στον πίνακα παραμέτρων. Η σύνδεση διαχειρίζεται τη δέσμευση:

PHP
$statements = SqlGenerator::generate($result);
// params might contain: [42, null, 'draft']
// The adapter binds null as SQL NULL

Στην έξοδο δοκιμαστικής εκτέλεσης, οι τιμές NULL εμφανίζονται ως η κυριολεκτική συμβολοσειρά NULL χωρίς εισαγωγικά.

Εντοπισμός στηλών ταυτότητας

Το SqlGenerator καθορίζει ποιες στήλες σχηματίζουν την ταυτότητα της γραμμής εξετάζοντας το TableSnapshot::identityColumns του βασικού στιγμιότυπου. Αυτές οι στήλες χρησιμοποιούνται στους όρους WHERE των εντολών UPDATE και DELETE και εξαιρούνται από τους όρους SET των UPDATE.

Αν δεν υπάρχει βασικό στιγμιότυπο, χρησιμοποιείται ως εφεδρική επιλογή η πρώτη στήλη του πίνακα τιμών. Αν ο πίνακας τιμών είναι κενός, θεωρείται το id.

Μεταβίβαση οδηγού

Για να ελέγξετε την παράθεση αναγνωριστικών, μεταβιβάστε ένα στιγμιότυπο Driver:

PHP
use Merql\Driver\SqliteDriver;

$statements = SqlGenerator::generate(
    $result,
    driver: new SqliteDriver(),
);
// Uses double-quote quoting: "posts", "title"