SQL-spejl
SqlMirror flytter storh-samlinger til SQLite- eller MySQL-tabeller, så du kan
køre joins, sortere på tværs af tabeller, søge efter delstrenge og lave rapporter i SQL, mens
filerne forbliver kanoniske. Tænk på det som et sekundært indeks, der tilfældigvis er en database: spejlet er afledt, kan kasseres og kan genopbygges når som helst.
ext-pdo med driveren sqlite eller mysql kræves kun, når du bruger
funktionen; kernepakken forbliver uden afhængigheder.
Opsætning
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();
Begge motorer kan spejles: DocStore-samlinger og SegmentedLog-streams (kun aktive poster flyttes). Det er valgfrit at angive en Schema og
uafhængigt af lageret: erklærede felter af typen string/int/float/bool bliver typede, indekserede kolonner; alt andet kan fortsat forespørges i data-kolonnen JSON. Felter af typen mixed kan ikke markeres til indeksering.
Forbindelser
Konstruktøren accepterer et PDO-håndtag (driveren sqlite eller mysql, registreres
automatisk), et mysqli-håndtag eller enhver implementering af SqlMirrorConnection:
$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-stien fungerer med begge mysqli-fejlrapporteringsindstillinger, så et eksisterende
håndtag fra et værtsprogram (for eksempel WordPresss $wpdb->dbh) kan
genbruges direkte. Adfærden er identisk på tværs af drivere; fejl ved overførsel ruller
samlingens transaktion tilbage på dem alle.
Hver tabel får id (primærnøgle), hash (styrer trinvise overførsler), de
typede kolonner og data (hele posten i JSON).
Synkronisering
$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() sammenligner posternes hashes med spejlet og skriver hver samling i
én transaktion, så en afbrudt eller mislykket overførsel aldrig efterlader en delvist anvendt
batch. Uændrede poster koster én SELECT plus en gennemgang af posterne. En periodisk
push() (for eksempel fra et cron-interval) holder spejlet synkroniseret; kald
flush() med id'erne, du skrev under en forespørgsel, når læsere skal kunne
læse deres egne ændringer fra spejlet.
Forespørgsler
Lav forespørgsler mod spejlet med almindelig SQL. table() returnerer det spejlede tabelnavn:
$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'
);
Tilbageførsel til filer
pull() læser rækker fra spejlet og skriver dem til det registrerede lager i id-
rækkefølge. Det understøtter to forløb:
- Gendannelse: filerne er væk, men spejlet findes stadig. Registrer et nyt lager med samme samlingsnavn, og hent rækkerne tilbage.
- Klargøring: rækker, der indlæses i spejltabellen med eksterne værktøjer, bliver til storh-
poster. Rækkerne skal indeholde gyldige UUIDv7-id'er og et objekt i kolonnen
data; typede kolonner ignoreres ved hentning, fordidataer hele posten.
$restored = new Storh\DocStore($root, 'pages');
$mirror = new SqlMirror($pdo);
$mirror->collection($restored, 'pages');
$mirror->pull(); // ['written' => n, 'unchanged' => m]
Skrivninger fra hentede rækker går gennem lagerets normale funktioner, så skemavalidering og
unikke indekser gælder, og hver post skrives holdbart. pull() sletter aldrig
lokale poster, og poster, hvis data allerede svarer til spejlrækken, springes over. Efter klargøring af manuelt indsatte rækker skal du køre push() én gang: det omskriver
rækkerne i kanonisk form, så deres hashes stemmer overens.
Aftale og begrænsninger
- Filerne er kanoniske. Spejlet er skrivebeskyttet output; alt, der skrives til det
manuelt, overskrives eller slettes ved næste
push(). - Unikke kolonner i spejlet fungerer som et sikkerhedsnet, ikke som håndhævelse ved skrivning: en dublet, som filerne tillod, giver en mislykket (og fuldt tilbagerullet) overførsel. Brug unikke storh-indekser for at håndhæve unikhed ved skrivning.
- Spejlet kan være op til ét overførselsinterval bag filerne, bortset fra de id'er, du
udtrykkeligt
flush(). - Spejling tilføjer ikke transaktioner til storh. Atomiske skrivninger på tværs af flere poster kræver fortsat en rigtig database som autoritativt datasæt.
- Skemaændringer anvendes ved at slette og geninstallere spejlet:
uninstall(),install(),push().