Preskoči na vsebino

SQL Ustvarjanje

SqlGenerator pretvori MergeResult v parametrizirane stavke SQL. Vse vrednosti so vezane kot parametri in nikoli vstavljene v niz 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']
}

Uporabite generateGuarded(), kadar želite pregledani načrt združitve uporabiti samo, če se aktivne vrstice še vedno ujemajo s pričakovanim posnetkom.

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

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

Oblika stavka

Vsak stavek je asociativna tabela z dvema ključema:

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

Identifikatorji (imena tabel in stolpcev) so navedeni v narekovajih glede na slog gonilnika podatkovne zbirke. MySQL uporablja povratne narekovaje, SQLite pa dvojne narekovaje. Če gonilnik ni naveden, se privzeto uporabijo povratni narekovaji.

Vrstni red operacij

Operacije so razvrščene po vrsti in izvedene v tem vrstnem redu:

  1. Najprej INSERT – nove vrstice morajo obstajati, preden se lahko nanje sklicujejo posodobitve.
  2. Nato UPDATE.
  3. Nazadnje DELETE – pred brisanjem je treba odstraniti sklice na vrstice.
PHP
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.

Vrstni red tujih ključev

Če so podane odvisnosti tujih ključev, se operacije znotraj posamezne skupine topološko razvrstijo. Pri vstavljanju in posodabljanju se najprej obdelajo nadrejene tabele, nato podrejene. Pri brisanju se najprej obdelajo podrejene tabele, nato nadrejene.

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 izvede topološko razvrščanje grafa odvisnosti. Krožne odvisnosti zazna in prekine, da prepreči neskončne zanke.

Samodejno zaznavanje tujih ključev

Applier samodejno prebere povezave tujih ključev iz podatkovne zbirke:

PHP
use Merql\Apply\Applier;

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

Primeri ustvarjenih SQL

INSERT

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

Vključeni so vsi stolpci iz vrednosti operacije.

UPDATE

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

Identifikacijski stolpci (primarni ključ) so izključeni iz stavka SET in uporabljeni v stavku WHERE. Vrednosti stavka WHERE izhajajo iz dekodiranja ključa vrstice.

DELETE

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

V stavku WHERE so samo identifikacijski stolpci.

Zaščitena posodobitev UPDATE

Zaščitene posodobitve vključujejo pogoje za identiteto in pričakovano stanje aktivne vrstice.

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

Če vrstica nima več pričakovane vrednosti status, stavek ne vpliva na nobeno vrstico, zaščitena uporaba pa povrne transakcijo.

Zaščiteno vstavljanje INSERT

Zaščitena vstavljanja uporabljajo NOT EXISTS, da preprečijo vstavljanje v identiteto, ki se je pojavila po ustvarjanju načrta.

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

Obravnava NULL

Vrednosti NULL se v nizu parametrov posredujejo kot PHP null. Povezovalnik povezave poskrbi za vezavo:

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

V izpisu suhega zagona so vrednosti NULL prikazane kot dobesedni niz NULL brez narekovajev.

Zaznavanje identifikacijskih stolpcev

SqlGenerator določi, kateri stolpci sestavljajo identiteto vrstice, tako da pregleda TableSnapshot::identityColumns osnovnega posnetka. Ti stolpci se uporabijo v stavkih WHERE za UPDATE in DELETE ter izključijo iz stavkov SET za UPDATE.

Če osnovni posnetek ni na voljo, se kot nadomestna možnost uporabi prvi stolpec v nizu vrednosti. Če je niz vrednosti prazen, se predpostavi id.

Posredovanje gonilnika

Za nadzor zapisa identifikatorjev v narekovaje posredujte primerek Driver:

PHP
use Merql\Driver\SqliteDriver;

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