Arkkitehtuuri:
Node.js, kC$ytC$ readline moduulia REPL:lle.
KC$ytC$ fetch (Node 18+) tai axios HTTP-pyyntC6ihin.
SQL-parser: voidaan kC$yttC$C$ yksinkertaista itse kirjoitettua parseria
(regex-pohjainen) tai kirjastoa kuten node-sql-parser. Mutta riippuvuuksien
vC$lttC$miseksi ehkC$ kirjoitetaan yksinkertainen parseri, joka tunnistaa
SELECT, INSERT, UPDATE, DELETE ja jC$sentC$C$ perusasiat.
Parserin tulee palauttaa rakenne: { type: 'SELECT', table, columns, where,
limit } jne.
Sitten kC$C$ntC$jC$ muuntaa tC$mC$n REST-pyynnC6ksi.
HTTP-client suorittaa pyynnC6n ja palauttaa JSON-vastauksen.
Taulukonmuodostaja ottaa JSON-taulukon/objektin ja tulostaa ASCII-taulukon.
REPL-silmukka: odottaa kC$yttC$jC$n syC6tettC$, suorittaa komennon, tulostaa
tuloksen, toistaa.
LisC$ksi: -h ja -p parametrit host ja port. Oletus localhost:3001.
Toteutetaan koodi yhteen tiedostoon tai moduuleihin. Ehdotan yksinkertaista
rakennetta:
src/index.js (pC$C$ohjelma, CLI-parametrit, REPL)
src/parser.js (SQL-parseri)
src/translator.js (SQL -> REST)
src/httpClient.js (HTTP-pyynnC6t)
src/tableFormatter.js (ASCII-taulukko)
Koska kC$yttC$jC$ pyytC$C$ suunnittelua ja koodia, annetaan koko koodi tC$ssC$
vastauksessa.
Kirjoitetaan parseri:
Regex SELECT: /^SELECT\s+(.+?)\s+FROM\s+(\w+)(?:\s+WHERE\s+(.+?))?(?:\s+LIMIT\s
+(\d+))?;?$/i
Tarkemmin: columns voi olla * tai pilkulla erotettu lista.
WHERE-lause: yksinkertainen, esim. col = 'value' AND col2 = 123. Voidaan jakaa
AND:lla, sitten jokainen ehto: avain = arvo. Arvo voi olla lainausmerkeissC$
tai numero. Tuki vain = operaattorille.
INSERT: /^INSERT\s+INTO\s+(\w+)\s
(
[
)
]
+
)
([
)
]+)\sVALUES\s*
(
[
)
]
+
)
([
)
]+);?$/i
UPDATE: /^UPDATE\s+(\w+)\s+SET\s+(.+?)\s+WHERE\s+(.+?);?$/i
DELETE: /^DELETE\s+FROM\s+(\w+)\s+WHERE\s+(.+?);?$/i
Parserin tulee palauttaa objekti, jossa on tyyppi ja tiedot.
Translator:
SELECT -> GET /api/{table}?queryparams, ja asiakaspuolella suodatetaan
sarakkeet ja jC$rjestys, limit.
INSERT -> PUT /api/{table}/{id}, body ilman id:tC$.
UPDATE -> PATCH /api/{table}/{id}, body SET-kentC$t.
DELETE -> DELETE /api/{table}/{id}.
Erityisesti WHERE id = 'xxx' voidaan muuntaa suoraan REST-polun id:ksi, mutta
muuten query-parametriksi.
Taulukonmuodostaja:
SyC6te voi olla objekti (yksittC$inen) tai taulukko objekteja tai objekti,
jonka arvot ovat objekteja (kuten GET /api/asiakkaat palauttaa: { "007":
{...}, "003": {...} }). TC$mC$ on tC$rkeC$C$: REST vastaa objektilla, jossa
avaimet ovat id:itC$ ja arvot itse objektit. MeidC$n tulee tunnistaa tC$mC$
rakenne ja muuntaa se listaksi objekteja, joihin lisC$tC$C$n id-kenttC$ (tai
kC$ytetC$C$n avainta id:nC$). Esim. vastaus { "007":{"nimi":"James
Bond","status":"secret"}, "003":{"nimi":"James Pond","type":"unknown"} }
tulisi nC$yttC$C$ taulukkona, jossa on sarake "id" (tai "_id") ja sitten
objektin kentC$t. Asiakaspuolella voidaan lisC$tC$ id-sarake.
Jos vastaus on lista (esim. _meta/collections), sekin voidaan formatoida.
ASCII-taulukko: laske sarakkeiden leveydet, tulosta reunat.
REPL:
KC$ytC$ readline.createInterface.
Kysymys "obase-sql> ".
Kun kC$yttC$jC$ syC6ttC$C$ komennon, suorita ja tulosta.
Tuki komennoille: exit, quit, help.
VirheenkC$sittely.
HTTP-client:
KC$ytC$ fetch, mutta tarkista virheet.
Perusosoite: http://{host}:{port}
KC$ytetC$C$n Node.js:n sisC$C$nrakennettua fetch (Node 18+). Jos vanhempi, voi
kC$yttC$C$ axios, mutta oletetaan moderni Node.
Annetaan koodit. SelitetC$C$n myC6s asennus ja kC$yttC6.
Kirjoitetaan koodi selkeC$sti kommentoituna.
Vastauksessa annetaan ensin arkkitehtuurikuvaus, sitten koodi.