SQL generavimas
SqlGenerator konvertuoja MergeResult į parametrizuotus SQL sakinius. Visos reikšmės perduodamos kaip parametrai ir niekada neįterpiamos į SQL eilutę.
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ą.
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:
[
'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:
- Pirmiausia vykdomi INSERT – naujos eilutės turi egzistuoti prieš nurodant jas atnaujinimuose.
- Antrieji vykdomi UPDATE.
- Galiausiai vykdomi DELETE – prieš ištrinant eilutes reikia pašalinti į jas nukreipiančias nuorodas.
$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.
$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:
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
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES (?, ?, ?, ?)
-- params: [42, 'New Post', 'Body text', 'draft']
Įtraukiami visi operacijos reikšmių stulpeliai.
UPDATE
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
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.
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.
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:
$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ų:
use Merql\Driver\SqliteDriver;
$statements = SqlGenerator::generate(
$result,
driver: new SqliteDriver(),
);
// Uses double-quote quoting: "posts", "title"