Pereiti prie turinio

SQL generavimas

SqlGenerator konvertuoja MergeResult į parametrizuotus SQL sakinius. Visos reikšmės perduodamos kaip parametrai ir niekada neįterpiamos į SQL eilutę.

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

Naudokite generateGuarded(), kai peržiūrėtas sujungimo planas turėtų būti pritaikytas tik tuo atveju, jei tiesioginės eilutės vis dar atitinka numatytą momentinę kopiją.

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

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

Sakinio formatas

Kiekvienas sakinys yra asociatyvusis masyvas su dviem raktais:

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

Identifikatoriai (lentelių ir stulpelių pavadinimai) cituojami naudojant duomenų bazės tvarkyklės kabučių stilių. MySQL naudoja atvirkštines kabutes, o SQLite – dvigubas kabutes. Jei tvarkyklė nepateikta, pagal numatytąją nuostatą naudojamos atvirkštinės kabutės.

Operacijų tvarka

Operacijos grupuojamos pagal tipą ir vykdomos tokia tvarka:

  1. Pirmiausia vykdomi INSERT – naujos eilutės turi egzistuoti prieš nurodant jas atnaujinimuose.
  2. Antrieji vykdomi UPDATE.
  3. Galiausiai vykdomi DELETE – prieš ištrinant eilutes reikia pašalinti į jas nukreipiančias nuorodas.
PHP
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.

Svetimųjų raktų tvarka

Kai pateikiamos svetimųjų raktų priklausomybės, kiekvienos grupės operacijos rikiuojamos topologiškai. Įterpiant ir atnaujinant pirmiausia apdorojamos pirminės lentelės, tada antrinės. Trinant pirmiausia apdorojamos antrinės lentelės, tada pirminės.

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 atlieka priklausomybių grafo topologinį rikiavimą. Ciklinės priklausomybės aptinkamos ir nutraukiamos, kad būtų išvengta begalinių ciklų.

Automatinis svetimųjų raktų aptikimas

Applier automatiškai nuskaito svetimųjų raktų ryšius iš duomenų bazės:

PHP
use Merql\Apply\Applier;

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

Sugeneruotų SQL pavyzdžiai

INSERT

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

Įtraukiami visi operacijos reikšmių stulpeliai.

UPDATE

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

Tapatybės stulpeliai (pirminis raktas) neįtraukiami į SET sąlygą ir naudojami WHERE sąlygoje. WHERE sąlygos reikšmės gaunamos iššifravus eilutės raktą.

DELETE

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

WHERE sąlygoje pateikiami tik tapatybės stulpeliai.

Apsaugotas UPDATE

Apsaugoti atnaujinimai apima ir tapatybės sąlygas, ir numatytos tiesioginės eilutės sąlygas.

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

Jei eilutės status nebeatitinka numatytų, sakinys paveikia nulį eilučių ir apsaugotas pritaikymas atšaukia transakciją.

Apsaugotas INSERT

Apsaugotuose įterpimuose naudojama NOT EXISTS, kad nebūtų įterpta eilutė su tapatybe, kuri atsirado po plano sudarymo.

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

NULL reikšmių tvarkymas

NULL reikšmės parametrų masyve perduodamos kaip PHP null. Susiejimą atlieka ryšio adapteris:

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

Bandomojo vykdymo išvestyje NULL reikšmės pateikiamos kaip pažodinė eilutė NULL be kabučių.

Tapatybės stulpelio aptikimas

SqlGenerator nustato, kurie stulpeliai sudaro eilutės tapatybę, nagrinėdama bazinės momentinės kopijos TableSnapshot::identityColumns. Šie stulpeliai naudojami UPDATE ir DELETE sakinių WHERE sąlygose, o UPDATE sakinių SET sąlygos iš jų neįtraukiamos.

Jei bazinė momentinė kopija nepasiekiama, kaip atsarginis variantas naudojamas pirmasis reikšmių masyvo stulpelis. Jei reikšmių masyvas tuščias, daroma prielaida, kad tai id.

Tvarkyklės perdavimas

Norėdami valdyti identifikatorių kabučių naudojimą, perduokite Driver egzempliorių:

PHP
use Merql\Driver\SqliteDriver;

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