TC$mC$ ei ole lainkaan liian iso kakku, vaan pC$invastoin: tC$mC$ on
suorastaan oppikirjaesimerkki modulaarisesta arkkitehtuurista. Erottamalla
tietokantamoottori (O-Base) ja sen kyselykieli/rajapinta (SQL Middleware)
toisistaan, teet juuri sen, mitC$ suuret datamoottorit kuten Presto, Trino tai
Apache Drill tekevC$t.
Suunnitellaan molemmat osiot!
---
### 1. O-Base Supervisor: Nimettyjen tietokantojen hallinta
Jotta voimme luoda, listata ja poistaa tietokantoja siten, ettC$ jokainen saa
*oman* Node.js-prosessinsa ja hakemistonsa, tarvitsemme uuden, erittC$in
kevyen orkestrointipalvelimen. Kutsutaan tC$tC$ nimellC$ **Supervisor**.
**Arkkitehtuuri:**
* **Supervisor (Portti 3000):** Ottaa vastaan hallintakutsut. Se pitC$C$
kirjaa kC$ynnissC$ olevista tietokannoista ja niille varatuista porteista.
* **Worker-prosessit (Portit 3001, 3002...):** Kun luot tietokannan "crm",
Supervisor luo hakemiston `./databases/crm` ja kC$ynnistC$C$ taustalle `node
server.js crm 3001` (jossa `server.js` on aiemmin tekemC$mme Fastify-palvelin
pienin muutoksin).
**Supervisor API (KC$site):**
* `POST /db` (body: `{"name": "crm"}`) -> Luo hakemiston, varaa vapaan portin,
tekee `child_process.spawn()` ja palauttaa `{"status": "running", "port":
3001}`.
* `GET /db` -> Palauttaa listan (esim. hakemiston listaus ja mitkC$ prosessit
ovat elossa).
* `DELETE /db/:name` -> LC$hettC$C$ SIGTERM-signaalin kyseiselle
worker-prosessille ja arkistoi/poistaa `./databases/:name` -hakemiston.
TC$mC$ eristC$C$ tietokannat tC$ydellisesti toisistaan RAM-muistissa ja
estC$C$ yhden tietokannan kaatumisen tai raskaan kompaktion vaikuttamasta
toisiin.
---
### 2. SQL Middleware & OpenAPI (MariaDB-kloonin mahdollistaminen)
TC$mC$ on visiossasi se kaikkein herkullisin osa. Voisiko toinen AI
(SQL-adapteri-dev-chat) rakentaa CLI-tyC6kalun ja SQL-kC$C$ntC$jC$n, jos
annamme sille vain OpenAPI-speksin? **KyllC$ voi.**
TekoC$lymallit ovat erinomaisia kC$C$ntC$mC$C$n kielioppeja (SQL AST -> REST
HTTP).
Jotta tC$mC$ onnistuu, meidC$n O-Base API:n `openapi.json` tC$ytyy tarjota
kolme "siltaa" SQL-maailman ja O-Basen RAM-maailman vC$lille:
#### Silta 1: Skeeman tunnistus (`SHOW TABLES` ja `DESCRIBE`)
Koska O-Base on "schemaless", meidC$n on tarjottava reitti, joka palauttaa
kokoelmien nimet ja niiden olemassa olevat avaimet, jotta SQL-client osaa
nC$yttC$C$ ne tauluina ja sarakkeina.
* **O-Base API:** `GET /api/_meta/collections`
* **SQL Client tekee:** Muuttaa tC$mC$n `SHOW TABLES` -tulosteeksi.
#### Silta 2: Suodatus ja Kyselyt (`SELECT ... WHERE`)
MeidC$n on laajennettava O-Basen `GET /api/:collection` -reittiC$
ymmC$rtC$mC$C$n yksinkertaisia query-parametreja.
* **SQL:** `SELECT nimi, status FROM asiakkaat WHERE status = 'aktiivinen'
LIMIT 10`
* **SQL Client kC$C$ntC$C$:** Tekee HTTP-pyynnC6n O-Baselle: `GET
/api/asiakkaat?status=aktiivinen&_limit=10`
* **SQL Client tekee:** Vastaanottaa JSONin O-Baselta, poimii vain `nimi` ja
`status` kentC$t muistissa (projektiot), ja tulostaa ne nC$tisti
MariaDB-tyylisenC$ ASCII-taulukkona.
#### Silta 3: In-Memory JOINit (Vaativa SQL)
EntC$ jos kC$yttC$jC$ tekee: `SELECT * FROM laskut LEFT JOIN asiakkaat ON
laskut.asiakas_id = asiakkaat.id`?
* O-Base *ei* osaa JOINia, koska se rikkoisi sen minimalistisen rakenteen.
* **Ratkaisu:** SQL Client hakee molemmat (`GET /api/laskut` ja `GET
/api/asiakkaat`) RAM-muistiinsa, suorittaa Hash-JOINin asiakkaan puolella
(middleware) ja palauttaa tuloksen. TC$mC$ on standarditapa hajautetuissa
tietokannoissa.
#### Silta 4: DML (`INSERT`, `UPDATE`, `DELETE`)
* **SQL:** `INSERT INTO asiakkaat (id, nimi) VALUES ('crm_008', 'Matti')`
* **SQL Client kC$C$ntC$C$:** `PUT /api/asiakkaat/crm_008` (body: `{"nimi":
"Matti"}`)
### OpenAPI-speksin rooli
Jotta toinen dev-chat osaa rakentaa tC$mC$n, riittC$C$ ettC$ generoimme sille
tarkan `openapi.json` tiedoston, joka kuvaa:
1. Reitit (GET, PUT, PATCH, DELETE, /api/sync)
2. Tuetut URL Query-parametrit hakuihin (esim. millC$ syntaksilla etsitC$C$n
`?_limit=10` tai `?kentta=arvo`).
3. AST-MD:n ja JSONin sisC$llC6nneuvottelun (`Accept` ja `Content-Type`
headerit).
MC$C$rittelet SQL-dev-chatille vain tavoitteen: *"TC$ssC$ on O-Base REST API:n
openapi.json. Kirjoita Node.js CLI-tyC6kalu, joka ottaa vastaan standardia
SQL-kieltC$, kC$C$ntC$C$ sen nC$iksi REST-kutsuiksi, formatoi tulokset
MariaDB-tyyliseksi ASCII-taulukoksi, ja tarjoaa interaktiivisen REPL-kehotteen
(esim. `obase-sql> `)."*