Liigu sisu juurde

SQL genereerimine

SqlGenerator teisendab väärtuse MergeResult parameetriseeritud SQL-lauseteks. Kõik väärtused seotakse parameetritena ega paigutata kunagi SQL stringi sisse.

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']
}

Kasutage väärtust generateGuarded(), kui üle vaadatud liitmisplaani tohib rakendada ainult juhul, kui aktiivsed read vastavad endiselt eeldatud hetktõmmisele.

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

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

Lausete vorming

Iga lause on assotsiatiivne massiiv kahe võtmega:

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

Identifikaatorid (tabelite ja veergude nimed) pannakse jutumärkidesse andmebaasi draiveri vormingu järgi. MySQL kasutab tagurpidi ühekordseid jutumärke, SQLite topeltjutumärke. Kui draiverit pole määratud, kasutatakse vaikimisi tagurpidi ühekordseid jutumärke.

Operatsioonide järjestus

Operatsioonid rühmitatakse tüübi järgi ja käivitatakse järgmises järjestuses:

  1. Kõigepealt INSERTid – uued read peavad olemas olema enne, kui uuendused saavad neile viidata.
  2. Seejärel UPDATEid.
  3. Viimasena DELETEid – viited tuleb eemaldada enne ridade kustutamist.
PHP
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.

Võõrvõtmete järjestus

Kui võõrvõtmete sõltuvused on esitatud, järjestatakse iga rühma operatsioonid topoloogiliselt. Lisamiste ja uuenduste korral töödeldakse vanemtabeleid enne tütartabeleid. Kustutamiste korral töödeldakse tütartabeleid enne vanemtabeleid.

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 järjestab sõltuvusgraafi topoloogiliselt. Lõpmatute tsüklite vältimiseks tuvastatakse ringviited ja katkestatakse need.

Võõrvõtmete automaatne tuvastamine

Applier loeb võõrvõtmete seosed automaatselt andmebaasist:

PHP
use Merql\Apply\Applier;

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

Genereeritud SQL näited

INSERT

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

Kaasatakse kõik operatsiooni väärtuste hulgas olevad veerud.

UPDATE

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

Identiteediveerud (primaarvõti) jäetakse SET-klauslist välja ja neid kasutatakse WHERE-klauslis. WHERE-klausli väärtused saadakse reavõtme dekodeerimisel.

DELETE

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

WHERE-klauslis kasutatakse ainult identiteediveerge.

Piiratud UPDATE

Piiratud uuendused sisaldavad nii identiteediklausleid kui ka eeldatud aktiivse rea klausleid.

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

Kui real pole enam eeldatud status, ei mõjuta lause ühtegi rida ja piiratud rakendamine tühistab tehingu.

Piiratud INSERT

Piiratud lisamised kasutavad väärtust NOT EXISTS, et vältida sisestamist identiteediga, mis tekkis pärast plaani loomist.

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

NULL-i käsitlemine

NULL-väärtused edastatakse parameetrite massiivis väärtustena PHP null. Ühenduse adapter hoolitseb sidumise eest:

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

Proovikäigu väljundis kuvatakse NULL-väärtused jutumärkideta literaalstringina NULL.

Identiteediveergude tuvastamine

SqlGenerator määrab rea identiteedi moodustavad veerud baashetktõmmise TableSnapshot::identityColumns põhjal. Neid veerge kasutatakse UPDATE- ja DELETE-lausete WHERE-klauslites ning jäetakse UPDATE-lausete SET-klauslitest välja.

Kui baashetktõmmist pole saadaval, kasutatakse varuvariandina väärtuste massiivi esimest veergu. Kui väärtuste massiiv on tühi, eeldatakse id.

Draiveri edastamine

Identifikaatorite jutumärkidesse panemise juhtimiseks edastage Driver-i eksemplar:

PHP
use Merql\Driver\SqliteDriver;

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