Pereiti prie turinio

SQL veidrodis

SqlMirror perkelia storh kolekcijas į SQLite arba MySQL lenteles, kad galėtumėte atlikti sujungimus, rikiavimą tarp lentelių, paiešką pagal poeilutes ir kurti ataskaitas naudodami SQL, o failai išlieka kanoninio formato. Tai tarsi antrinis indeksas, kuris kartu yra ir duomenų bazė: veidrodis gaunamas iš pirminių duomenų, jį galima išmesti ir bet kada atkurti. ext-pdo su sqlite arba mysql tvarkykle reikalingas tik naudojant veidrodį; pagrindinis paketas neturi priklausomybių.

Nustatymas

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();

Abu varikliai gali naudoti veidrodį: kolekcijos DocStore ir srautai SegmentedLog (perkeliami tik esami įrašai). Schema pateikti nebūtina ir tai nepriklauso nuo saugyklos: deklaruoti string/int/float/bool laukai tampa tipuotais, indeksuotais stulpeliais; visa kita galima užklausti per data JSON stulpelį. mixed laukų negalima pažymėti kaip indeksuojamų.

Ryšiai

Konstruktoriui galima perduoti PDO objektą (tvarkyklė sqlite arba mysql, aptinkama automatiškai), mysqli objektą arba bet kurią SqlMirrorConnection realizaciją:

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 būdas veikia esant bet kuriam mysqli klaidų pranešimo režimui, todėl galima pakartotinai naudoti esamą pagrindinės programos objektą, pavyzdžiui, WordPress $wpdb->dbh. Visos tvarkyklės veikia vienodai; nepavykus perkelti duomenų, visose grąžinama kolekcijos transakcija.

Kiekviena lentelė turi id (pirminį raktą), hash (naudojamas perkeliant tik pakeistus įrašus), tipuotus stulpelius ir data (visą įrašą JSON).

Sinchronizavimas

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() palygina įrašų maišas su veidrodžiu ir kiekvieną kolekciją įrašo per vieną transakciją, todėl dėl strigimo ar nesėkmingo perkėlimo nepaliekama iš dalies pritaikyta įrašų partija. Nepasikeitusiems įrašams reikia tik vieno SELECT ir visų įrašų peržiūros. Periodiškai paleiskite push() (pavyzdžiui, iš cron užduoties), kad veidrodis būtų sinchronizuotas; kai skaitytojams reikia, kad jų pakeitimai būtų iškart matomi veidrodyje, perduokite flush() užklausoje įrašytų įrašų ID.

Užklausos

Veidrodžio užklausoms naudokite paprastą SQL. table() grąžina veidrodinės lentelės pavadinimą:

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'
);

Duomenų grąžinimas į failus

pull() skaito veidrodžio eilutes ir įrašo jas į registruotą saugyklą pagal ID. Jis skirtas dviem atvejams:

  • Atkūrimas: failai prarasti, bet veidrodis išliko. Užregistruokite naują saugyklą tuo pačiu kolekcijos pavadinimu ir grąžinkite duomenis.
  • Pradinių duomenų įkėlimas: išoriniais įrankiais į veidrodžio lentelę įkeltos eilutės tampa storh įrašais. Eilutėse turi būti galiojantys UUIDv7 ID ir objektas stulpelyje data; tipuotų stulpelių reikšmės grąžinant ignoruojamos, nes data yra visas įrašas.
PHP
$restored = new Storh\DocStore($root, 'pages');
$mirror   = new SqlMirror($pdo);
$mirror->collection($restored, 'pages');
$mirror->pull();          // ['written' => n, 'unchanged' => m]

Grąžinami įrašai apdorojami įprastais saugyklos metodais, todėl taikomas schemos tikrinimas ir unikalūs indeksai, o kiekvienas įrašas išsaugomas patvariai. pull() niekada neištrina vietinių įrašų; įrašai, kurių duomenys jau sutampa su veidrodžio eilute, praleidžiami. Įkėlę eilutes rankiniu būdu, vieną kartą paleiskite push(): eilutės bus perrašytos kanoniniu formatu, kad jų maišos sutaptų.

Sąlygos ir apribojimai

  • Failai yra kanoninis šaltinis. Veidrodis yra tik skaitoma išvestis; viskas, kas į jį įrašoma rankiniu būdu, per kitą push() bus perrašyta arba ištrinta.
  • Unikalūs veidrodžio stulpeliai yra atsarginė apsauga, o ne įrašymo metu taikomas apribojimas: dublikatas, kurį leido failai, pasireiškia kaip nepavykęs (ir visiškai atšauktas) siuntimas. Įrašymo metu taikykite storh unikalius indeksus.
  • Veidrodis atsilieka nuo failų iki vieno siuntimo intervalo, išskyrus ID, kuriuos flush() aiškiai nurodote.
  • Veidrodinis atvaizdavimas neprideda transakcijų pačiam storh. Kelių įrašų atominis įrašymas tebėra tikros duomenų bazės, kaip sistemos įrašų šaltinio, užduotis.
  • Schemos pakeitimai pritaikomi ištrinant ir iš naujo įdiegiant veidrodį: uninstall(), install(), push().