Hoppa till innehåll

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.

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

Använd generateGuarded() när en granskad sammanfogningsplan bara ska tillämpas om de aktiva raderna fortfarande motsvarar en förväntad snapshot.

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

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

  1. INSERTs först -- nya rader måste finnas innan uppdateringar kan referera till dem.
  2. UPDATEs därefter.
  3. DELETEs sist -- referenser till rader måste tas bort innan raderna raderas.
PHP
$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.

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

PHP
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

Sql
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

Sql
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

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

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

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

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

PHP
use Merql\Driver\SqliteDriver;

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