Generovanie SQL
SqlGenerator prevádza MergeResult na parametrizované príkazy SQL. Všetky hodnoty sa odovzdávajú ako parametre a nikdy sa nevkladajú priamo do reťazca SQL.
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() použite vtedy, keď sa má skontrolovaný plán zlúčenia použiť iba v prípade, že sa aktuálne riadky stále zhodujú s očakávanou snímkou.
use Merql\Apply\SqlGenerator;
use Merql\Snapshot\SnapshotStore;
$statements = SqlGenerator::generateGuarded(
$selectedResult,
SnapshotStore::load('theirs'),
);
Formát príkazu
Každý príkaz je asociatívne pole s dvoma kľúčmi:
[
'sql' => 'INSERT INTO `posts` (`id`, `title`) VALUES (?, ?)',
'params' => [42, 'New Title'],
]
Identifikátory (názvy tabuliek a stĺpcov) sa uzatvárajú do úvodzoviek podľa pravidiel ovládača databázy. MySQL používa spätné apostrofy, SQLite používa dvojité úvodzovky. Ak ovládač nie je zadaný, predvolene sa používajú spätné apostrofy.
Poradie operácií
Operácie sa zoskupia podľa typu a vykonajú v tomto poradí:
- Najprv INSERTs – nové riadky musia existovať predtým, než sa na ne budú odkazovať aktualizácie.
- Potom UPDATEs.
- Nakoniec DELETEs – pred odstránením treba zrušiť odkazy na riadky.
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.
Poradie cudzích kľúčov
Ak sú zadané závislosti cudzích kľúčov, operácie v každej skupine sa zoradia topologicky. Pri vkladaní a aktualizáciách sa najprv spracujú nadradené tabuľky a potom podriadené tabuľky. Pri odstraňovaní sa najprv spracujú podriadené tabuľky a potom nadradené tabuľky.
$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 vykoná topologické triedenie grafu závislostí. Kruhové závislosti sa zistia a prerušia, aby sa zabránilo nekonečným slučkám.
Automatické zisťovanie cudzích kľúčov
Applier automaticky načíta vzťahy cudzích kľúčov z databázy:
use Merql\Apply\Applier;
$applier = new Applier($connection);
$applied = $applier->apply($result);
// FK dependencies are read from the database via the driver.
Príklady generovaných SQL
INSERT
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES (?, ?, ?, ?)
-- params: [42, 'New Post', 'Body text', 'draft']
Zahrnú sa všetky stĺpce z hodnôt operácie.
UPDATE
UPDATE `posts` SET `title` = ?, `status` = ? WHERE `id` = ?
-- params: ['New Title', 'publish', 42]
Stĺpce identity (primárny kľúč) sa vynechajú z klauzuly SET a použijú sa v klauzule WHERE. Hodnoty klauzuly WHERE sa získajú dekódovaním kľúča riadka.
DELETE
DELETE FROM `posts` WHERE `id` = ?
-- params: [42]
V klauzule WHERE sa nachádzajú iba stĺpce identity.
Chránený UPDATE
Chránené aktualizácie obsahujú klauzuly identity aj klauzuly očakávaného aktuálneho riadka.
UPDATE `posts` SET `title` = ? WHERE `id` = ? AND `status` = ?
-- params: ['New Title', 42, 'draft']
Ak riadok už nemá očakávaný status, príkaz ovplyvní nula riadkov a chránené použitie vráti transakciu späť.
Chránený INSERT
Chránené vkladania používajú NOT EXISTS, aby zabránili vloženiu identity, ktorá sa objavila po vytvorení plánu.
INSERT INTO `posts` (`id`, `title`) SELECT ?, ? WHERE NOT EXISTS (
SELECT 1 FROM `posts` WHERE `id` = ?
)
-- params: [42, 'New Post', 42]
Spracovanie NULL
Hodnoty NULL sa v poli parametrov odovzdávajú ako PHP null. Ovládač pripojenia sa postará o naviazanie:
$statements = SqlGenerator::generate($result);
// params might contain: [42, null, 'draft']
// The adapter binds null as SQL NULL
Vo výstupe skúšobného spustenia sa hodnoty NULL zobrazujú ako doslovný reťazec NULL bez úvodzoviek.
Zisťovanie stĺpca identity
SqlGenerator určí, ktoré stĺpce tvoria identitu riadka, podľa TableSnapshot::identityColumns základnej snímky. Tieto stĺpce sa použijú v klauzulách WHERE príkazov UPDATE a DELETE a vynechajú sa z klauzúl SET príkazov UPDATE.
Ak základná snímka nie je k dispozícii, ako záložný stĺpec sa použije prvý stĺpec v poli hodnôt. Ak je pole hodnôt prázdne, predpokladá sa id.
Odovzdanie ovládača
Ak chcete určiť spôsob uzatvárania identifikátorov do úvodzoviek, odovzdajte inštanciu Driver:
use Merql\Driver\SqliteDriver;
$statements = SqlGenerator::generate(
$result,
driver: new SqliteDriver(),
);
// Uses double-quote quoting: "posts", "title"