Generering av SQL
SqlGenerator omvandlar en MergeResult till parametriserade SQL-satser. Alla värden binds som parametrar och infogas aldrig i strängen för 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']
}
Använd generateGuarded() när en granskad sammanfogningsplan bara ska tillämpas om de aktiva raderna fortfarande motsvarar en förväntad snapshot.
use Merql\Apply\SqlGenerator;
use Merql\Snapshot\SnapshotStore;
$statements = SqlGenerator::generateGuarded(
$selectedResult,
SnapshotStore::load('theirs'),
);
Satsformat
Varje sats är en associativ array med två nycklar:
[
'sql' => 'INSERT INTO `posts` (`id`, `title`) VALUES (?, ?)',
'params' => [42, 'New Title'],
]
Identifierare (tabell- och kolumnnamn) citeras med databasdrivrutinens citeringsstil. MySQL använder backticks och SQLite använder dubbla citattecken. Om ingen drivrutin anges används backticks som standard.
Åtgärdernas ordning
Åtgärder grupperas efter typ och körs i följande ordning:
- INSERTs först -- nya rader måste finnas innan uppdateringar kan referera till dem.
- UPDATEs därefter.
- DELETEs sist -- referenser till rader måste tas bort innan raderna raderas.
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.
Ordning för främmande nycklar
När beroenden mellan främmande nycklar anges sorteras åtgärderna inom varje grupp topologiskt. Överordnade tabeller behandlas före underordnade tabeller vid infogningar och uppdateringar. Underordnade tabeller behandlas före överordnade tabeller vid raderingar.
$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 utför en topologisk sortering av beroendegrafen. Cirkulära beroenden upptäcks och bryts för att förhindra oändliga loopar.
Automatisk identifiering av främmande nycklar
Applier läser automatiskt relationer mellan främmande nycklar från databasen:
use Merql\Apply\Applier;
$applier = new Applier($connection);
$applied = $applier->apply($result);
// FK dependencies are read from the database via the driver.
Exempel på genererade SQL
INSERT
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES (?, ?, ?, ?)
-- params: [42, 'New Post', 'Body text', 'draft']
Alla kolumner från åtgärdens värden inkluderas.
UPDATE
UPDATE `posts` SET `title` = ?, `status` = ? WHERE `id` = ?
-- params: ['New Title', 'publish', 42]
Identitetskolumner (primärnyckel) utesluts från SET-satsen och används i WHERE-satsen. Värdena i WHERE-satsen hämtas genom att avkoda radnyckeln.
DELETE
DELETE FROM `posts` WHERE `id` = ?
-- params: [42]
Endast identitetskolumner förekommer i WHERE-satsen.
Skyddad UPDATE
Skyddade uppdateringar innehåller både identitetsvillkor och villkor för förväntade aktiva rader.
UPDATE `posts` SET `title` = ? WHERE `id` = ? AND `status` = ?
-- params: ['New Title', 42, 'draft']
Om raden inte längre har förväntad status påverkar satsen noll rader och den skyddade tillämpningen återställer transaktionen.
Skyddad INSERT
Skyddade infogningar använder NOT EXISTS för att undvika att infoga en identitet som har tillkommit sedan planen skapades.
INSERT INTO `posts` (`id`, `title`) SELECT ?, ? WHERE NOT EXISTS (
SELECT 1 FROM `posts` WHERE `id` = ?
)
-- params: [42, 'New Post', 42]
Hantering av NULL
NULL-värden skickas som PHP null i params-arrayen. Anslutningsadaptern hanterar bindningen:
$statements = SqlGenerator::generate($result);
// params might contain: [42, null, 'draft']
// The adapter binds null as SQL NULL
I utdata från en torrkörning återges NULL-värden som den bokstavliga strängen NULL utan citattecken.
Identifiering av identitetskolumner
SqlGenerator avgör vilka kolumner som utgör radens identitet genom att granska TableSnapshot::identityColumns i bassnapshoten. Dessa kolumner används i WHERE-satser för UPDATE- och DELETE-satser och utesluts från SET-satser i UPDATE-satser.
Om ingen bassnapshot är tillgänglig används den första kolumnen i värdearrayen som reserv. Om värdearrayen är tom antas id.
Ange en drivrutin
Om du vill styra citeringen av identifierare skickar du en instans av Driver:
use Merql\Driver\SqliteDriver;
$statements = SqlGenerator::generate(
$result,
driver: new SqliteDriver(),
);
// Uses double-quote quoting: "posts", "title"