Siirry sisältöön

SQL-luonti

SqlGenerator muuntaa MergeResult-tuloksen parametrisoiduiksi SQL-lausekkeiksi. Kaikki arvot sidotaan parametreiksi; niitä ei koskaan sijoiteta suoraan SQL-merkkijonoon.

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

Käytä toimintoa generateGuarded(), kun tarkistettu yhdistämissuunnitelma tulisi ottaa käyttöön vain, jos reaaliaikaiset rivit vastaavat edelleen odotettua tilannevedosta.

PHP
use Merql\Apply\SqlGenerator;
use Merql\Snapshot\SnapshotStore;

$statements = SqlGenerator::generateGuarded(
    $selectedResult,
    SnapshotStore::load('theirs'),
);

Lausekemuoto

Jokainen lauseke on assosiatiivinen taulukko, jossa on kaksi avainta:

PHP
[
    'sql'    => 'INSERT INTO `posts` (`id`, `title`) VALUES (?, ?)',
    'params' => [42, 'New Title'],
]

Tunnisteet (taulujen ja sarakkeiden nimet) lainataan tietokanta-ajurin tyylin mukaisesti. MySQL käyttää kenoviivoja, SQLite käyttää kaksoislainausmerkkejä. Jos ajuria ei anneta, oletuksena käytetään kenoviivoja.

Operaatioiden järjestys

Operaatiot ryhmitellään tyypin mukaan ja suoritetaan tässä järjestyksessä:

  1. INSERTit ensin -- uusien rivien on oltava olemassa, ennen kuin niihin voidaan viitata päivityksissä.
  2. UPDATEt toisena.
  3. DELETEt viimeisenä -- viittaukset riveihin on poistettava ennen niiden poistamista.
PHP
$statements = SqlGenerator::generate($result);
// All INSERTs, then all UPDATEs, then all DELETEs.

Viiteavainten mukainen järjestys

Kun viiteavainriippuvuudet annetaan, kunkin ryhmän operaatiot järjestetään topologisesti. Lisäyksissä ja päivityksissä ylätaulut käsitellään ennen alitauluja. Poistoissa alitaulut käsitellään ennen ylätauluja.

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 lajittelee riippuvuusverkon topologisesti. Kehämäiset riippuvuudet tunnistetaan ja puretaan loputtomien silmukoiden estämiseksi.

Viiteavainten automaattinen tunnistus

Applier lukee viiteavainsuhteet automaattisesti tietokannasta:

PHP
use Merql\Apply\Applier;

$applier = new Applier($connection);
$applied = $applier->apply($result);
// FK dependencies are read from the database via the driver.

Luotujen SQL-lausekkeiden esimerkkejä

INSERT

Sql
INSERT INTO `posts` (`id`, `title`, `content`, `status`) VALUES (?, ?, ?, ?)
-- params: [42, 'New Post', 'Body text', 'draft']

Kaikki operaation arvoissa olevat sarakkeet sisällytetään.

UPDATE

Sql
UPDATE `posts` SET `title` = ?, `status` = ? WHERE `id` = ?
-- params: ['New Title', 'publish', 42]

Identiteettisarakkeet (pääavain) jätetään pois SET-lausekkeesta ja niitä käytetään WHERE-lausekkeessa. WHERE-lausekkeen arvot saadaan purkamalla rivin avain.

DELETE

Sql
DELETE FROM `posts` WHERE `id` = ?
-- params: [42]

WHERE-lausekkeessa ovat vain identiteettisarakkeet.

Suojattu UPDATE

Suojatut päivitykset sisältävät sekä identiteettiä että odotettua reaaliaikaista riviä koskevat ehdot.

Sql
UPDATE `posts` SET `title` = ? WHERE `id` = ? AND `status` = ?
-- params: ['New Title', 42, 'draft']

Jos rivillä ei enää ole odotettua arvoa status, lauseke vaikuttaa nollaan riviin ja suojattu käyttöönotto peruu tapahtuman.

Suojattu INSERT

Suojatuissa lisäyksissä käytetään NOT EXISTS-toimintoa estämään lisäys identiteettiin, joka on tullut käyttöön suunnitelman luonnin jälkeen.

Sql
INSERT INTO `posts` (`id`, `title`) SELECT ?, ? WHERE NOT EXISTS (
  SELECT 1 FROM `posts` WHERE `id` = ?
)
-- params: [42, 'New Post', 42]

NULL-arvojen käsittely

NULL-arvot välitetään muodossa PHP null params-taulukossa. Yhteysadapteri huolehtii sidonnasta:

PHP
$statements = SqlGenerator::generate($result);
// params might contain: [42, null, 'draft']
// The adapter binds null as SQL NULL

Koeajon tulosteessa NULL-arvot näytetään merkkijonoliteraalina NULL ilman lainausmerkkejä.

Identiteettisarakkeiden tunnistus

SqlGenerator määrittää rivin identiteetin muodostavat sarakkeet pohjan tilannevedoksen TableSnapshot::identityColumns-arvon perusteella. Näitä sarakkeita käytetään UPDATE- ja DELETE-lausekkeiden WHERE-osissa, ja ne jätetään pois UPDATE-lauseiden SET-osista.

Jos pohjan tilannevedosta ei ole saatavilla, varasarake otetaan values-taulukon ensimmäisestä sarakkeesta. Jos values-taulukko on tyhjä, oletetaan id.

Ajurin välittäminen

Tunnisteiden lainausmerkkien hallintaan välitä Driver-instanssi:

PHP
use Merql\Driver\SqliteDriver;

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