SQL-generering
SqlGenerator konverterer en MergeResult til parameteriserede SQL-sætninger. Alle værdier bindes som parametre og indsættes aldrig direkte i SQL-strengen.
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']
}
Brug generateGuarded(), når en gennemgået fletningsplan kun skal anvendes, hvis live-rækkerne stadig svarer til et forventet øjebliksbillede.
use Merql\Apply\SqlGenerator;
use Merql\Snapshot\SnapshotStore;
$statements = SqlGenerator::generateGuarded(
$selectedResult,
SnapshotStore::load('theirs'),
);
Sætningsformat
Hver sætning er et associativt array med to nøgler:
[
'sql' => 'INSERT INTO `posts` (`id`, `title`) VALUES (?, ?)',
'params' => [42, 'New Title'],
]
Identifikatorer (tabel- og kolonnenavne) citeres med databasens drivers citeringsstil. MySQL bruger backticks, SQLite bruger dobbelte anførselstegn. Hvis der ikke angives nogen driver, bruges backticks som standard.
Rækkefølge af handlinger
Handlinger grupperes efter type og udføres i denne rækkefølge:
- INSERTs først -- nye rækker skal eksistere, før opdateringer kan referere til dem.
- UPDATEs derefter.
- DELETEs til sidst -- referencer til rækker skal fjernes, før de slettes.
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.
Rækkefølge efter fremmednøgler
Når der angives afhængigheder mellem fremmednøgler, sorteres handlingerne i hver gruppe topologisk. Overordnede tabeller behandles før underordnede ved indsættelser og opdateringer. Underordnede tabeller behandles før overordnede ved sletninger.
$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 udfører en topologisk sortering af afhængighedsgrafen. Cirkulære afhængigheder registreres og brydes for at forhindre uendelige løkker.
Automatisk registrering af fremmednøgler
Applier henter automatisk relationer mellem fremmednøgler fra databasen:
use Merql\Apply\Applier;
$applier = new Applier($connection);
$applied = $applier->apply($result);
// FK dependencies are read from the database via the driver.
Eksempler på genereret SQL
INSERT
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES (?, ?, ?, ?)
-- params: [42, 'New Post', 'Body text', 'draft']
Alle kolonner fra handlingens værdier medtages.
UPDATE
UPDATE `posts` SET `title` = ?, `status` = ? WHERE `id` = ?
-- params: ['New Title', 'publish', 42]
Identitetskolonner (primærnøgle) udelades fra SET-delen og bruges i WHERE-delen. Værdierne i WHERE-delen kommer fra afkodning af rækkenøglen.
DELETE
DELETE FROM `posts` WHERE `id` = ?
-- params: [42]
Kun identitetskolonner indgår i WHERE-delen.
Beskyttet UPDATE
Beskyttede opdateringer indeholder både identitetsbetingelser og betingelser for den forventede live-række.
UPDATE `posts` SET `title` = ? WHERE `id` = ? AND `status` = ?
-- params: ['New Title', 42, 'draft']
Hvis rækken ikke længere har den forventede status, påvirker sætningen nul rækker, og beskyttet anvendelse ruller transaktionen tilbage.
Beskyttet INSERT
Beskyttede indsættelser bruger NOT EXISTS for at undgå at indsætte en identitet, der er dukket op, siden planen blev oprettet.
INSERT INTO `posts` (`id`, `title`) SELECT ?, ? WHERE NOT EXISTS (
SELECT 1 FROM `posts` WHERE `id` = ?
)
-- params: [42, 'New Post', 42]
Håndtering af NULL
NULL-værdier videregives som PHP null i params-arrayet. Forbindelsesadapteren håndterer bindingen:
$statements = SqlGenerator::generate($result);
// params might contain: [42, null, 'draft']
// The adapter binds null as SQL NULL
I output fra en prøvekørsel vises NULL-værdier som den bogstavelige streng NULL uden anførselstegn.
Registrering af identitetskolonner
SqlGenerator afgør, hvilke kolonner der udgør rækkeidentiteten, ved at se på TableSnapshot::identityColumns i grundøjebliksbilledet. Disse kolonner bruges i WHERE-betingelser for UPDATE- og DELETE-sætninger og udelades fra SET-betingelser i UPDATEs.
Hvis der ikke er et grundøjebliksbillede til rådighed, bruges den første kolonne i værdiarrayet som reserve. Hvis værdiarrayet er tomt, antages id.
Angivelse af en driver
Hvis du vil styre citeringen af identifikatorer, skal du angive en Driver-instans:
use Merql\Driver\SqliteDriver;
$statements = SqlGenerator::generate(
$result,
driver: new SqliteDriver(),
);
// Uses double-quote quoting: "posts", "title"