Preskočiť na obsah

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.

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

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.

PHP
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:

PHP
[
    '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í:

  1. Najprv INSERTs – nové riadky musia existovať predtým, než sa na ne budú odkazovať aktualizácie.
  2. Potom UPDATEs.
  3. Nakoniec DELETEs – pred odstránením treba zrušiť odkazy na riadky.
PHP
$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.

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 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:

PHP
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

Sql
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

Sql
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

Sql
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.

Sql
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.

Sql
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:

PHP
$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:

PHP
use Merql\Driver\SqliteDriver;

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