Liigu sisu juurde

SQL peegel

SqlMirror saadab storh kogud SQLite või MySQL tabelitesse, et saaksid SQL-is teha liitmisi, järjestada andmeid tabeliteüleselt, otsida alamstringe ja koostada aruandeid, samal ajal kui failid jäävad kanooniliseks allikaks. Mõtle sellest kui teisesest indeksist, mis on ühtlasi andmebaas: peegel on tuletatud, ära visatav ja igal ajal taastatav. ext-pdo koos draiveriga sqlite või mysql on vajalik ainult siis, kui seda kasutad; põhipaketil sõltuvusi pole.

Seadistamine

PHP
use Storh\DocStore;
use Storh\Schema;
use Storh\SqlMirror;

$schema = Schema::collection('pages')
    ->string('slug')->unique()
    ->string('kind')->index()
    ->int('publishedAt')->range();

$pages  = new DocStore($root, 'pages', schema: $schema);
$events = new Storh\SegmentedLog($root, 'events');

$mirror = new SqlMirror(new PDO('sqlite:' . $root . '/mirror.db'), 'app_');
$mirror->collection($pages, 'pages', $schema);
$mirror->collection($events, 'events');

$mirror->install();
$mirror->push();

Mõlemat mootorit saab peegeldada: DocStore kogusid ja SegmentedLog vooge (saadetakse ainult aktiivsed kirjed). Schema edastamine on valikuline ega sõltu andmehoidlast: deklareeritud väljad string/int/float/bool muutuvad tüübistatud, indekseeritud veergudeks; kõik muu jääb päringu jaoks veergu data JSON. Välju mixed ei saa märgistada indekseeritavaks.

Ühendused

Konstruktor võtab vastu PDO käepideme (sqlite või mysql draiver, tuvastatakse automaatselt), mysqli käepideme või mis tahes SqlMirrorConnection teostuse:

PHP
$mirror = new SqlMirror(new PDO('sqlite:' . $root . '/mirror.db'));
$mirror = new SqlMirror(new PDO('mysql:host=127.0.0.1;dbname=app;charset=utf8mb4', $user, $password));
$mirror = new SqlMirror(new mysqli('127.0.0.1', $user, $password, 'app'), 'wp_storh_');

mysqli tee töötab mõlema mysqli veateavituse režiimiga, nii et hostrakenduse olemasolevat käepidet (näiteks WordPress $wpdb->dbh oma) saab muutmata kujul uuesti kasutada. Käitumine on kõigi draiverite puhul sama; saatmise tõrgete korral pööratakse kõigi puhul kogu kollektsiooni tehing tagasi.

Igale tabelile lisatakse id (primaarvõti), hash (juhib järkjärgulist saatmist), tüübistatud veerud ja data (kirje täielik JSON).

Sünkroonimine

PHP
$mirror->push();                    // reconcile: insert, update, delete as needed
$mirror->push('pages');             // reconcile a single collection
$mirror->flush('pages', $ids);      // push or remove just these ids
$mirror->pull();                    // write mirror rows back into the store
$mirror->verify();                  // report missing, stale, and orphaned rows
$mirror->rebuild();                 // clear all rows and push from scratch
$mirror->uninstall();               // drop the mirror tables

push() võrdleb kirjete räside erinevusi peegliga ja kirjutab iga kogu ühe tehinguna, nii et kokku jooksnud või nurjunud saatmine ei jäta kunagi poolikut paketti. Muutmata kirjete töötlemiseks piisab ühest SELECT-ist ja kirjete läbikäimisest. Korrapärane push() (näiteks cron käivituse ajal) hoiab peegli ajakohasena; kui lugejad peavad päringu käigus kirjutatud kirjete muudatusi kohe peeglis nägema, kutsu flush() ja anna kaasa nende kirjete ID-d.

Päringud

Päringu tegemiseks kasuta peeglis tavalist SQL-i. table() tagastab peegeldatud tabeli nime:

PHP
$pdo->query(
    'SELECT p.slug, COUNT(*) AS sales
     FROM ' . $mirror->table('purchases') . ' o
     INNER JOIN ' . $mirror->table('products') . ' p ON p.id = o.product_id
     GROUP BY p.slug
     ORDER BY sales DESC'
);

Andmete failidesse tagasitoomine

pull() loeb peegli ridu ja kirjutab need registreeritud andmehoidlasse ID-de järjekorras. See katab kaks kasutusjuhtu:

  • Taastamine: failid on kadunud, kuid peegel on alles. Registreeri sama kogu nime all uus andmehoidla ja too andmed tagasi.
  • Algandmetega täitmine: väliste tööriistade abil peeglitabelisse laaditud ridadest saavad storh kirjed. Ridadel peavad olema kehtivad UUIDv7 ID-d ja veerus data peab olema objekt; tüübistatud veerge tagasitoomisel eiratakse, sest data sisaldab kogu kirjet.
PHP
$restored = new Storh\DocStore($root, 'pages');
$mirror   = new SqlMirror($pdo);
$mirror->collection($restored, 'pages');
$mirror->pull();          // ['written' => n, 'unchanged' => m]

Tagasitoomisel kasutatakse andmehoidla tavapärast töövoogu, seega rakenduvad skeemi valideerimine ja unikaalsed indeksid ning iga kirje kirjutatakse püsivalt kettale. pull() ei kustuta kohalikke kirjeid ja kirjed, mille andmed kattuvad peeglireaga, jäetakse vahele. Pärast käsitsi lisatud ridade algandmetena laadimist käivita push() üks kord: see kirjutab need read kanoonilisel kujul ümber, et nende räsid saaksid sünkroonitud.

Tingimused ja piirangud

  • Kanoonilised andmed asuvad failides. Peegel on kirjutuskaitstud väljund; käsitsi sinna kirjutatu kirjutatakse järgmise push() ajal üle või kustutatakse.
  • Peegli unikaalsed veerud on kaitsemeede, mitte kirjutusaegne kontroll: kui failid lubasid duplikaadi, nurjub selle saatmine ja kogu tehing pööratakse tagasi. Kirjutamise ajal kontrollimiseks kasuta storh unikaalseid indekseid.
  • Peegel võib failidest maha jääda kuni ühe saatmisintervalli võrra, välja arvatud nende ID-de puhul, mille saadad selgesõnaliselt käsuga flush().
  • Peegeldamine ei lisa tehinguid otse storh-le. Mitme kirje aatomkirjutused tuleb endiselt teha päris andmebaasis, mis on süsteemi tõeallikas.
  • Skeemi muudatused rakendatakse peegli kustutamise ja uuesti paigaldamisega: uninstall(), install(), push().