Barvna shema: Temna
Trenutno dejavna stran: start » sl » Dokumentacija » Razširitve DokuWikija (WvdS) » SQLite Data Studio » SQLite Data Studio: rutine

SQLite Data Studio: rutine

Nazaj: SQLite Data Studio


Rutina je poimenovana delovna enota SQL: manifest s parametri in obliko rezultata, poleg tega pa poizvedba sama ali klic izvorne procedure.

[Live]

Pojmi

Pojem Pomen
Rutina Poimenovana delovna enota SQL: manifest (.json) in ena ali več datotek SQL (.sql) ali klic izvorne procedure.
Nabor rutin Mapa z rutinami; te so glede na vrsto v podmapah Functions/ in Procedures/. Nabor default je mapa sql/ paketa; paketi, ki rutine uporabljajo, prijavijo svoje nabore (glejte referenco API). Naslavljanje: ime (privzeti nabor) ali nabor:ime.
Manifest JSON s parameters, returns in eno ali več implementations za posamezna zaledja.
Zaledje Vedenje, značilno za pogon (navajanje identifikatorjev, točke shranjevanja, lastInsertId, narečje izvornega klica), izbrano po gonilniku PDO povezave.

Hitri začetek

$routines = plugin_load('helper', 'wksqliteds');
 
// nad obstoječim PDO:
$affected = $routines->execute($pdo, 'close_inspection', ['id' => 123, 'user' => 'wolfgang']);
 
// nad poimenovano povezavo:
$rows = $routines->execute('reporting', 'reports:monthly', ['month' => '2026-07']);
 
// prek storitve wkcore:
$svc = ServiceHub::fromDokuWiki()->service('sql.routines');
$svc?->execute($pdo, 'close_inspection', ['id' => 123, 'user' => 'wolfgang']);

execute($connection, $routine, $params):

  • $connection: \PDO, objekt z metodo getPdo(), ime povezave ali null (uporabi se možnost default_connection).
  • $routine: „ime“ (privzeti nabor) ali „nabor:ime“; pripeta končnica .json se dopušča.
  • $params: ['ime' => vrednost, ...].
  • Rezultat po polju returns v manifestu, sicer se vrže RoutineException.

Manifest

Manifest je datoteka <ime>.json v podmapi svoje vrste, npr. sql/Functions/close_inspection.json. Datoteka SQL, ki jo navaja, je v isti podmapi.

Ploščati (ena izvedba – prvotna specifikacija, še vedno podprta):

{
  "name": "close_inspection",
  "type": "nonquery",
  "file": "close_inspection.sql",
  "transaction": true,
  "parameters": { "id": "integer", "user": "string" },
  "returns": "rows_affected"
}

Za več zaledij (izvedbe za posamezne gonilnike):

{
  "name": "close_inspection",
  "parameters": { "id": "integer", "user": "string" },
  "returns": "rows_affected",
  "implementations": {
    "default": { "type": "sql",       "file": "close_inspection.sql",       "transaction": true },
    "mysql":   { "type": "procedure", "call": "close_inspection",           "transaction": true },
    "pgsql":   { "type": "sql",       "file": "close_inspection.pgsql.sql", "transaction": true }
  }
}
Polje Vrednosti
name [A-Za-z0-9_-]+; se mora ujemati z imenom datoteke.
parameters preslikava ime → vrsta: integer, string, boolean, float. Pripona [] = seznam IN (polje → (?, ?, …)); pripona ? = dovoljen NULL.
returns rows_affected | insert_id | rows | row | scalar | none.
type sql (stavki iz datoteke) ali procedure (izvorni klic). Stare besede nonquery/query → sql; proc/call/function → procedure. Obliko rezultata določa returns, ne type.
file (sql) pot glede na podmapo vrste (Functions/ oz. Procedures/), končnica .sql, brez ..; datoteka mora biti v tej podmapi.
call (procedure) [A-Za-z_][A-Za-z0-9_.]*.
transaction bool (privzeto true).

Razreševanje: ključ za konkreten gonilnik ima prednost, sicer velja default.

Datoteke SQL

Datoteka type:sql sme vsebovati več stavkov; wksqliteds jih loči sam (pravila spodaj). Vsaka nadomestna oznaka :ime se prepiše v pozicijski ? in se veže (nikoli stakne) – enako za vsa zaledja, vključno z ODBC/Access. Stavek veže samo oznake, ki se v njem dejansko pojavijo (brez napake PDO HY093).

Pravila ločevanja: stavki se ločijo pri ; – vendar ne znotraj nizov ('…' z ubežnim zapisom ''), komentarjev (-- tudi za kodo v isti vrstici, /* … */) in identifikatorjev v narekovajih ("…", krativci, […]). Tudi ; znotraj bloka BEGIN … END ali CASE … END stavka ne loči: telo prožilca ali procedure ostane en stavek. Nezaključen blokovni komentar izvajanje prekine z RoutineException, namesto da bi pogoltnil preostanek datoteke.

Dinamični SQL

  • Seznami IN: parameter deklarirajte kot integer[]/string[] in podajte polje → (?, ?, …). Prazno polje → (NULL). V besedilu SQL stoji oznaka brez lastnih oklepajev (WHERE id IN :ids, ne IN (:ids) – sicer po razširitvi seznama nastane neveljavni IN ((?, ?))).
  • Dinamični identifikatorji / vdelani PHP: datoteka rutine sme vsebovati PHP; v obsegu sta $params in $ctx. $ctx->ident('stolpec') vrne preverjen identifikator v narekovajih, kot jih zahteva pogon (edina varna pot za dinamična imena tabel in stolpcev). Vrednosti vedno ostanejo oznake :ime.

Model groženj za vdelani PHP

Vdelani PHP teče s polnimi pravicami aplikacije (eval, kot pri wksnippet). Zato je zavarovan večkrat:

  • Potrebuje tako možnost paketa allowPhp kot globalno možnost $conf['phpok'] (dvojna vrata). Privzeto: izklopljeno. Če datoteka vsebuje PHP, vrata pa so zaprta, izvedba varno odpove (RoutineException).
  • Od 2. stopnje modela pravic (podrobnosti): tudi ko so odprta obe vrata v nastavitvah, sme datoteko SQL rutine s PHP shraniti (sama zmožnost design ne zadošča) ali jo interaktivno sprožiti v studiu (sama zmožnost use ne zadošča) samo pravi superuporabnik – ne glede na to, kaj sicer dovoljuje matrika zmožnosti. Razlog: brez te dodatne vezave bi uporabnik, ki ni superuporabnik, z dovoljenjem design lahko shranil kodo PHP, ki bi pozneje tekla s polnimi pravicami aplikacije (ko bi jo sprožil sam, superuporabnik ali storitev sql.routines). Pot prek storitve sql.routines (programski klicatelji, kot je wkblog) te dodatne vezave nima – zaupa že shranjeni datoteki rutine, natanko kot pred 2. stopnjo.

Prijava naborov rutin iz drugega paketa

// (a) z dogodkom
$controller->register_hook('WKSQLITEDS_REGISTER_ROUTINE_SETS', 'BEFORE', $this, 'sets');
public function sets(\dokuwiki\Extension\Event $event) {
    $event->data->register('reports', __DIR__ . '/sql');
}
 
// (b) programsko
plugin_load('helper', 'wksqliteds')->registerSet('reports', __DIR__ . '/sql');

Naslavljanje je nato reports:monthly. Celotna pogodba metod: referenca API. Dogodek iz časa pred preimenovanjem (WVDSDWMSQLITE_REGISTER_ROUTINE_SETS) se ne sproži več; prehodni most je bil odstranjen, ko so vsi znani paketi prešli na novo ime.

Nastavitve

Možnost Privzeto Pomen
allowPhp 0 dovoli vdelani PHP v rutinah (potreben je še globalni phpok; od 2. stopnje poleg tega strukturno vezan na superuporabnike).
default_connection '''' povezava, kadar execute() ne dobi nobene.
slow_ms 200 zabeleži rutine, ki trajajo dlje (ms); 0 = izklopljeno.

Varnost

  • CSRF: vsak zapis v skrbniškem delu prek checkSecurityToken().
  • Avtorizacija: izvedba prek spleta (vmesnik studia) sledi matriki zmožnosti; nobena spletna končna točka ne izvede rutine samo na podlagi vnosov iz zahteve brez preverjanja.
  • Prehod poti (CWE-22): imena so omejena na dovoljen nabor znakov; file je prek realpath zaprt v mapo nabora, končnica .sql.
  • Vrivanje SQL (CWE-89): vrednosti so vedno vezane; identifikatorji samo prek $ctx→ident(); SQL se nikoli ne sestavlja iz vrednosti.
  • Dostopni podatki: nikoli kot čisto besedilo v JSON in nikoli v sporočilih o napakah – podrobnosti: Povezave.
  • XSS (CWE-79): vsi izpisi v skrbniškem delu gredo skozi hsc().
  • Transakcije: transaction:true je atomaren (begin/commit oziroma SAVEPOINT pri gnezdenju), ob napaki povrnitev.

Opombe o zaledjih

Zaledje Gonilnik Identifikator Točke shranjevanja Klic procedure insert_id
SQLite sqlite „x“ da – (samo SQL) lastInsertId()
MySQL/MariaDB mysql `x` da CALL p(…) LAST_INSERT_ID()
PostgreSQL pgsql „x“ da SELECT * FROM p(…) lastval() – bolje RETURNING in returns:scalar
SQL Server sqlsrv [x] SAVE TRANSACTION EXEC p … SCOPE_IDENTITY()
MS Access odbc [x] jih ni (pridruži se zunanji transakciji, zabeleženo) {CALL p(…)} SELECT @@IDENTITY

MS Access potrebuje gonilnik ODBC ACE/Jet »Microsoft Access Driver (*.mdb, *.accdb)« in pdo_odbc (Windows).

Pogoste napake

Simptom: PDOException »HY093« pri manifestu z več stavki.

Vzrok: stavek veže oznako, ki je deklarirana v drugem stavku datoteke, v tem stavku pa se ne uporablja.

Rešitev: v praksi odpade – izvajalec v vsakem stavku veže samo oznake, ki se v njem dejansko pojavijo. Če se napaka vseeno pojavi, je navadno v imenu oznake tipkarska napaka (velike in male črke se morajo ujemati).


Simptom: filter IN s parametrom seznama vrne skladenjsko napako SQL.

Vzrok: oznaka ima v besedilu SQL lastne oklepaje (IN (:ids)); po samodejni razširitvi seznama nastane neveljavni IN ((?, ?)).

Rešitev: oklepaje v besedilu SQL izpustite – IN :ids (glejte razdelek »Dinamični SQL«).

Sorodne teme

  • Povezave – na katero povezavo se obrne execute()
  • Pravice – preverjanje zmožnosti pri izvedbi iz studia
  • Referenca API – celotna pogodba metod pomočnika
  • Recepti – recept »Ustvarjanje rutine«
sl/wiki/dwe/wksqliteds/routines.txt · Zadnja sprememba: uporabnika 0.0.0.0