From c764c4f402b0011de32f02a9cf657a625e50b773 Mon Sep 17 00:00:00 2001
From: MrFry
Date: Tue, 7 Apr 2020 14:09:34 +0200
Subject: [PATCH] Exit cleanup functions, authentication polish, db polish
---
middlewares/auth.middleware.js | 26 +++--
middlewares/reqlogger.middleware.js | 17 ++-
modules/api/api.js | 138 +++++++++++++++++++++-
modules/api/apiDBStruct.json | 93 ++++++++++++---
modules/api/views/man.ejs | 172 ----------------------------
modules/dataEditor/dataEditor.js | 1 -
server.js | 46 +++++++-
utils/classes.js | 1 -
utils/dbSetup.js | 18 ++-
utils/dbtools.js | 31 +++--
10 files changed, 314 insertions(+), 229 deletions(-)
delete mode 100755 modules/api/views/man.ejs
diff --git a/middlewares/auth.middleware.js b/middlewares/auth.middleware.js
index 700b267..6e42c98 100644
--- a/middlewares/auth.middleware.js
+++ b/middlewares/auth.middleware.js
@@ -1,13 +1,8 @@
const logger = require('../utils/logger.js')
const dbtools = require('../utils/dbtools.js')
-const exceptions = [
- 'favicon',
- '/login'
-]
-
module.exports = function (options) {
- const { authDB, jsonResponse } = options
+ const { authDB, jsonResponse, exceptions } = options
const renderLogin = (res) => {
if (jsonResponse) {
@@ -54,7 +49,7 @@ module.exports = function (options) {
logger.DebugLog(`ID #${user.id}: ${req.url}`, 'auth', 1)
- // TODO: add stat to acesses table
+ UpdateAccess(authDB, user, ip, sessionID)
dbtools.Update(authDB, 'sessions', {
lastAccess: new Date().toString()
@@ -73,10 +68,25 @@ module.exports = function (options) {
}
}
+function UpdateAccess (db, user, ip, sessionID) {
+ const accesses = dbtools.Select(db, 'accesses', {
+ userId: user.id,
+ ip: ip
+ })
+
+ if (accesses.length === 0) {
+ dbtools.Insert(db, 'accesses', {
+ userID: user.id,
+ ip: ip,
+ sessionID: sessionID,
+ date: new Date().toString()
+ })
+ }
+}
+
function GetUserBySessionID (db, sessionID, req) {
logger.DebugLog(`Getting user from db`, 'auth', 2)
- // TODO: check same ip?
const session = dbtools.Select(db, 'sessions', {
id: sessionID
})[0]
diff --git a/middlewares/reqlogger.middleware.js b/middlewares/reqlogger.middleware.js
index 609dbed..e016140 100644
--- a/middlewares/reqlogger.middleware.js
+++ b/middlewares/reqlogger.middleware.js
@@ -1,9 +1,8 @@
const logger = require('../utils/logger.js')
-// TODO: use this middleware in all modules
-
module.exports = function (options) {
const loggableKeywords = options ? options.loggableKeywords : undefined
+ const loggableModules = options ? options.loggableModules : undefined
return function (req, res, next) {
res.on('finish', function () {
@@ -13,15 +12,15 @@ module.exports = function (options) {
const ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress
const hostname = req.hostname.replace('www.', '').split('.')[0]
- // TODO: merge req.url and req.hostname checking
- // TODO: regexp includes checking
- let toLog = loggableKeywords && loggableKeywords.some((x) => {
+
+ // fixme: regexp includes checking
+ const hasLoggableKeyword = loggableKeywords && loggableKeywords.some((x) => {
return req.url.includes(x)
})
-
- if (hostname.includes('dataeditor')) {
- toLog = true
- }
+ const hasLoggableModule = loggableModules && loggableModules.some((x) => {
+ return hostname.includes(x)
+ })
+ const toLog = hasLoggableModule || hasLoggableKeyword
logger.LogReq(req, true, res.statusCode)
if (toLog) { logger.LogReq(req) }
diff --git a/modules/api/api.js b/modules/api/api.js
index e4e0789..21b72cf 100644
--- a/modules/api/api.js
+++ b/modules/api/api.js
@@ -46,6 +46,8 @@ const dataEditsLog = 'stats/dataEdits'
const dailyDataCountFile = 'stats/dailyDataCount'
const usersDBPath = 'data/dbs/users.db'
+const maxVeteranPwGetCount = 5
+
if (!utils.FileExists(usersDBPath)) {
throw new Error('No user DB exists yet! please run utils/dbSetup.js first!')
}
@@ -67,7 +69,12 @@ app.set('views', [
])
app.use(auth({
authDB: authDB,
- jsonResponse: true
+ jsonResponse: true,
+ exceptions: [
+ 'favicon',
+ '/login',
+ '/getveteranpw'
+ ]
}))
app.use(express.static('public'))
app.use(busboy({
@@ -106,6 +113,118 @@ Load()
// -------------------------------------------------------------
+app.post('/getpw', function (req, res) {
+ logger.LogReq(req)
+
+ const requestingUser = req.session.user
+
+ if (requestingUser.avaiblePWRequests <= 0) {
+ res.json({
+ result: 'error',
+ msg: 'Too many passwords requested or cant request password yet, try later'
+ })
+ logger.Log(`User #${requestingUser.id} requested too much passwords`, logger.GetColor('cyan'))
+ return
+ }
+
+ dbtools.Update(authDB, 'users', {
+ avaiblePWRequests: requestingUser.avaiblePWRequests - 1,
+ pwRequestCount: requestingUser.pwRequestCount + 1
+ }, {
+ id: requestingUser.id
+ })
+
+ const pw = uuidv4()
+ const insertRes = dbtools.Insert(authDB, 'users', {
+ pw: pw,
+ created: new Date().toString()
+ })
+
+ logger.Log(`User #${requestingUser.id} creted new user #${insertRes.lastInsertRowid}`, logger.GetColor('cyan'))
+
+ console.log(requestingUser)
+
+ res.json({
+ result: 'success',
+ pw: pw,
+ remaining: requestingUser.avaiblePWRequests - 1
+ })
+})
+
+app.post('/getveteranpw', function (req, res) {
+ logger.LogReq(req)
+ const ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress
+
+ const tries = dbtools.Select(authDB, 'veteranPWRequests', {
+ ip: ip
+ })[0]
+
+ if (tries) {
+ if (tries.count > maxVeteranPwGetCount) {
+ res.json({
+ result: 'error',
+ msg: 'Too many tries'
+ })
+ logger.Log(`Too many veteran PW requests from ${ip}!`, logger.GetColor('cyan'))
+ return
+ } else {
+ dbtools.Update(authDB, 'veteranPWRequests', {
+ count: tries.count + 1,
+ lastDate: new Date().toString()
+ }, {
+ id: tries.id
+ })
+ }
+ } else {
+ dbtools.Insert(authDB, 'veteranPWRequests', {
+ ip: ip,
+ lastDate: new Date().toString()
+ })
+ }
+
+ const oldUserID = req.body.cid
+ if (!oldUserID) {
+ res.json({
+ result: 'error',
+ msg: 'No CID recieved'
+ })
+ logger.Log(`No client ID recieved`, logger.GetColor('cyan'))
+ return
+ }
+
+ const user = dbtools.Select(authDB, 'users', {
+ oldCID: oldUserID
+ })[0]
+
+ if (user) {
+ if (user.pwGotFromCID === 0) {
+ logger.Log(`Sent password to veteran user #${user.id}`, logger.GetColor('cyan'))
+ dbtools.Update(authDB, 'users', {
+ pwGotFromCID: 1
+ }, {
+ id: user.id
+ })
+
+ res.json({
+ result: 'success',
+ pw: user.pw
+ })
+ } else {
+ logger.Log(`Veteran user #${user.id} already requested password`, logger.GetColor('cyan'))
+ res.json({
+ result: 'error',
+ msg: 'Password already requested once'
+ })
+ }
+ } else {
+ logger.Log(`Invalid password request with CID: ${oldUserID}`, logger.GetColor('cyan'))
+ res.json({
+ result: 'error',
+ msg: 'no such CID'
+ })
+ }
+})
+
app.post('/login', (req, res) => {
logger.LogReq(req)
const pw = req.body.pw
@@ -430,15 +549,26 @@ app.post('*', function (req, res) {
res.status(404).render('404')
})
-exports.app = app
-exports.dailyAction = () => {
+function ExportDailyDataCount () {
utils.AppendToFile(JSON.stringify({
date: new Date(),
subjectCount: data.Subjects.length,
questionCOunt: data.Subjects.reduce((acc, subj) => {
return acc + subj.Questions.length
- }, 0)
+ }, 0),
+ userCount: dbtools.TableInfo(authDB, 'users').dataCount
}), dailyDataCountFile)
}
+exports.app = app
+exports.cleanup = () => {
+ logger.Log('Closing Auth DB')
+ authDB.close()
+}
+exports.dailyAction = () => {
+ ExportDailyDataCount()
+
+ // TODO: selectAll from users, check if date is more than x, and increment every y
+}
+
logger.Log('API module started', logger.GetColor('yellow'))
diff --git a/modules/api/apiDBStruct.json b/modules/api/apiDBStruct.json
index d810509..1a10e8a 100644
--- a/modules/api/apiDBStruct.json
+++ b/modules/api/apiDBStruct.json
@@ -12,7 +12,8 @@
"unique": true
},
"oldCID": {
- "type": "text"
+ "type": "text",
+ "unique": true
},
"lastIP": {
"type": "text"
@@ -24,24 +25,42 @@
"type": "number",
"defaultZero": true
},
+ "created": {
+ "type": "text",
+ "notNull": true
+ },
"lastLogin": {
"type": "text"
},
"lastAccess": {
"type": "text"
+ },
+ "avaiblePWRequests": {
+ "type": "number",
+ "defaultZero": true
+ },
+ "pwRequestCount": {
+ "type": "number",
+ "defaultZero": true
+ },
+ "pwGotFromCID": {
+ "type": "number",
+ "defaultZero": true
}
}
},
"sessions": {
- "foreignKey": {
- "keysFrom": [
- "userID"
- ],
- "table": "users",
- "keysTo": [
- "id"
- ]
- },
+ "foreignKey": [
+ {
+ "keysFrom": [
+ "userID"
+ ],
+ "table": "users",
+ "keysTo": [
+ "id"
+ ]
+ }
+ ],
"tableStruct": {
"id": {
"type": "text",
@@ -65,18 +84,60 @@
}
}
},
- "acesses": {
+ "accesses": {
+ "foreignKey": [
+ {
+ "keysFrom": [
+ "userID"
+ ],
+ "table": "users",
+ "keysTo": [
+ "id"
+ ]
+ }
+ ],
"tableStruct": {
- "accessId": {
- "type": "number",
+ "accessID": {
+ "type": "integer",
"primary": true,
+ "autoIncrement": true
+ },
+ "userID": {
+ "type": "number",
"notNull": true
},
- "userId": {
- "type": "number"
+ "ip": {
+ "type": "text",
+ "notNull": true
+ },
+ "date": {
+ "type": "text",
+ "notNull": true
+ },
+ "sessionID": {
+ "type": "text",
+ "notNull": true
+ }
+ }
+ },
+ "veteranPWRequests": {
+ "tableStruct": {
+ "id": {
+ "type": "integer",
+ "primary": true,
+ "autoIncrement": true
},
"ip": {
- "type": "text"
+ "type": "text",
+ "notNull": true
+ },
+ "count": {
+ "type": "number",
+ "defaultZero": true
+ },
+ "lastDate": {
+ "type": "text",
+ "notNull": true
}
}
}
diff --git a/modules/api/views/man.ejs b/modules/api/views/man.ejs
deleted file mode 100755
index db1a489..0000000
--- a/modules/api/views/man.ejs
+++ /dev/null
@@ -1,172 +0,0 @@
-
- Moodle/Elearnig/KMOOC manual
-
-
- Ez a userscript Moodle/Elearnig/KMOOC tesztek megoldása során segítséget jelenít meg.
-
-
-A válasz ablakban jobb felül lévő százalék jelzi, hogy mekkora eséllyel jó a megoldás. Ez
-sokszor jó viszonyítás, de semmi sem biztos! Bármikor előfordulhat, hogy nem jó a
-megjelenített válasz! Ezért csak saját felelősségedre használd! Sok kikerülhetetlen
-hibalehetőség van, amit egyszerű nem lehet scriptben lekezelni (Pl rosszul megadott kérdés
-tanár részéről). Kézzel is lehet keresni a elmentett kérdések között. Ezért mindig
-legyen egy letöltött verziód a kérdésekről, mert nem 100% hogy mindég elérhető a szerver!
-Továbbá ha a moodle oldalán a DOM megváltozik, a script nem fog működni! Ez nem annyira
-gyakori, de bármikor megtörténhet! Érdemes nem kikapcsolni a tampermonkey-ban a userscript
-frissítést. Ez nem windows update, itt tényleg hibajavítások jönnek ki. Hiba, észrevétel
-esetén : Script Feedback (ezt
-gyakran még aznap megnézem.)
-
-
-Továbbá ez a userscript HTTP requestekket küldhet egy szerver felé, ahova az összes megoldott
-tesztjeid kérdéseit és (helyes)válaszait feltölti! Ezzel garantálja, hogy neked, és mindenki
-másnak a legfrissebb adatok állnak rendelkezésre.
-
-
- Tartalomjegyzék
-
-
-
- -
- Használat - Ez szuper fontos, elsőnek olvasd el
-
- -
- Eddigi teszt kérdések - Itt elérhető az eddigi összes ismert teszt
- kérdés-válaszai
-
- -
- Gyakran előforduló kérdések - Ha itt nincs kérdésed, akkor itt tedd fel!
-
- -
- Adat egyszerűsítés - Ha túl sok egyforma kérdésed van ;)
-
- -
- Other stuff
-
-
-
- Használat
-
-
-
-
- Először is tölts le egy userscript futtató kiegészítőt a böngésződhöz. Én Tampermonkeyt használok, és ezzel van tesztelve a
- userscript is, ezért ez ajánlott. Más is működhet (violentmonkey, etc), de az nem garantált.
- Majd a weboldalról egy kattintással elvileg
- le tudod tölteni a scriptet, és elvileg kész is. Script majd udvariasan megkéri, hogy
- hagy beszélgessen a szerverrel, mert mással nem tud.
-
- Teszt közben még több dolog történhet:
-
-
- - Nem jó kérdésre ad választ a script: Ilyenkor az van, hogy nincs meg a
- kérdés, vagy több hasonló kérdés/válasz van. Ilyenkor a jobbra/balra gombbal
- váltogathatsz azok a kérdés/válasz combók közül, amit talált a script
-
- - Több teszt kérdés van egy oldalon: Fel le gombbal váltogathatsz a kérdések között.
- Ilyenkor is működik az előbb említett funkció. Az indexek, amit kiír a bal felső sarokban:
- aktuális kérdés száma / aktuális találat száma.
-
- - Nem jelenik meg semmi, vagy nem működik a script: Megesik az ilyesmi. Ha
- a webszerver még elérhető akkor ott meg bírod nézni a kérdéseket, és ott lehet
- keresgélni Ctrl + F -el Ha az sincs, akkor lehet hogy jól jön ha van egy
- lementett kérdés gyűjteményed.
-
-
- Egyéb funkciók:
-
- -
- Ha esetleg videókat nézel, akkor spaceval lehet play/pausolni, és jobbra/balra
- gombbal ugrani a videóban.
-
- -
- Ha bármikor nem kell a script, akkor a menü gomb alatt bekapcsolhatod a passzív
- módot, ami nem piszkálja a szervert. Vagy kikapcsolhatod magát a scriptet
- tampermonkey-ban. Ha bármiért is el akarod tüntetni a következő oldalig az éppen
- megjelenő script ablakot, akkor középső egér gombbal kattintva rajta ezt
- megteheted.
-
-
-
- Ha 2.0 előttről jöttél, és rettenetesen össze vagy zavarodva:
-
- 2.0 előtt a script az egész adatbázist leszedte, beolvasta, és onnan keresett. Ez a
- keresés most szerver oldalon van megvalósítva, és a script csak a kérdést, hozzá tartózó
- egyéb infót (pl kép nevek) és a tárgy nevét küldi el szervernek. Ezután az visszaküldi a
- helyes válaszokat.
-
- |
-
-
- |
-
-
- Eddigi teszt kérdések:
-
-
-Eddigi összes kérdés
-Továbbá ez még arra jó, hogy ha valamiért bugos a script, akkor itt tudsz ctrl-f el nézegetni,
-vagy ha lemented az összes kérdést, akkor még akkor is biztonságban vagy, ha netán leáll a
-szerver, vagy elmegy a neted. Bár úgy nehezen moodlezel, de mind1
-
-
- Gyakran előforduló kérdések
-
-
-
- -
- 1. Olyan helyeken fut le a script, ahol nem kellene, vagy zavar
- Tampermonkey bővitmény ikon -> click -> scriptet kapcsold ki. Csak ne felejtsd
- visszakapcsolni ;) Meg passzív módot is bekapcsolhatod a menü gomb alatt.
-
-
- -
- 2. Túl nagy a kérdést és a választ megjelenítő ablak, nem tudok a válaszra kattintani
- Zommolj ki egy kicsit, vagy kapcsold ki addig a scriptet. Továbbá középső
- egérgombra kattintva rá el bírod tüntetni az ablakot, amíg újra nem töltöd az oldalt,
- vagy másikra ugrasz.
-
-
- -
- 4. Mi ez a ... ?
-
-
-
- -
- 5.
-
-
-
-
- -
- Egyéb:
- észrevétel
-
-
-
Jogosultságok:
-GM_openInTab: help megnyitása új lapon, GM_xmlhttpRequest: online adatbázishoz. GM_info: a
-scriptről információ, a verzióváltozás érzékeléséhez. GM_getValue/ GM_setValue: oldal
-bezárásakor megmaradó változók kezelése. Előző verzió tárolására, ugyanúgy verzióváltozás
-érzékeléséhez, néhány beállítás, illetve hogy melyik tárgyakból keressen kérdéseket. Ezek
-függvények, és a sciptben néhol meg vannak hívva, keresd meg.
- Elküldött adatok online módban: Minden teszt végén az összes kérdés, és rá a moodle szerint
-helyesnek vélt válaszok. Fogadott adatok: az összes eddig ismert moodle kérdés
-
-
-
-
-
diff --git a/modules/dataEditor/dataEditor.js b/modules/dataEditor/dataEditor.js
index 36e1422..a3adc7a 100644
--- a/modules/dataEditor/dataEditor.js
+++ b/modules/dataEditor/dataEditor.js
@@ -71,7 +71,6 @@ AddHtmlRoutes(utils.ReadDir('modules/dataEditor/public'))
// --------------------------------------------------------------
app.get('/', function (req, res) {
- // TODO: log this, regexp $/^
res.end('hai')
logger.LogReq(req)
})
diff --git a/server.js b/server.js
index fdcffe3..9f1a06c 100755
--- a/server.js
+++ b/server.js
@@ -52,12 +52,40 @@ try {
console.log(e)
}
+// Setting up exits
+// process.on('exit', () => exit('exit'))
+// process.on('exit', () => exit('exit'))
+process.on('SIGINT', () => exit('SIGINT'))
+process.on('SIGINT', () => exit('SIGINT'))
+process.on('SIGTERM', () => exit('SIGTERM'))
+process.on('SIGTERM', () => exit('SIGTERM'))
+
+function exit (reason) {
+ logger.Log(`Exiting, reason: ${reason}`)
+ Object.keys(modules).forEach((k, i) => {
+ const x = modules[k]
+ if (x.cleanup) {
+ try {
+ x.cleanup()
+ } catch (e) {
+ logger.Log(`Error in ${k} cleanup! Details in STDERR`, logger.GetColor('redbg'))
+ console.err(e)
+ }
+ }
+ })
+ process.exit()
+}
+
const app = express()
app.use(cors())
-app.use(reqlogger([
- 'stable.user.js', // TODO
- 'dataeditor'
-]))
+app.use(reqlogger({
+ loggableKeywords: [
+ 'stable.user.js'
+ ],
+ loggableModules: [
+ 'dataeditor'
+ ]
+}))
Object.keys(modules).forEach(function (k, i) {
let x = modules[k]
@@ -65,11 +93,12 @@ Object.keys(modules).forEach(function (k, i) {
let mod = require(x.path)
if (mod.setup) {
mod.setup({
- url: 'http://' + x.urls[0] // TODO http https or neither
+ url: 'https://' + x.urls[0]
})
}
x.app = mod.app
x.dailyAction = mod.dailyAction
+ x.cleanup = mod.cleanup
x.urls.forEach((url) => {
app.use(vhost(url, x.app))
})
@@ -127,7 +156,12 @@ function setLogTimer () {
Object.keys(modules).forEach((k, i) => {
const x = modules[k]
if (x.dailyAction) {
- x.dailyAction()
+ try {
+ x.dailyAction()
+ } catch (e) {
+ logger.Log(`Error in ${k} daily action! Details in STDERR`, logger.GetColor('redbg'))
+ console.err(e)
+ }
}
})
diff --git a/utils/classes.js b/utils/classes.js
index 5006f63..d173010 100755
--- a/utils/classes.js
+++ b/utils/classes.js
@@ -270,7 +270,6 @@ class Question {
return SUtils.CompareString(this.A, qObj.A)
}
- // TODO: return q / a / data match for debuging
Compare (q2, data) {
assert(q2)
let qObj
diff --git a/utils/dbSetup.js b/utils/dbSetup.js
index ae86647..54bf143 100644
--- a/utils/dbSetup.js
+++ b/utils/dbSetup.js
@@ -11,9 +11,22 @@ let authDB
console.clear()
CreateDB()
+// authDB.backup(usersDBPath)
+// .then(() => {
+// logger.Log('backup complete!')
+// })
+// .catch((err) => {
+// logger.Log('backup failed!', logger.GetColor('redbg'))
+// console.log(err)
+// })
+
+authDB.close()
+
function CreateDB () {
const dbStruct = utils.ReadJSON(dbStructPath)
+ // authDB = dbtools.GetDB(':memory:')
authDB = dbtools.GetDB(usersDBPath)
+ authDB.pragma('synchronous = OFF')
Object.keys(dbStruct).forEach((tableName) => {
const tableData = dbStruct[tableName]
@@ -24,11 +37,14 @@ function CreateDB () {
const uids = utils.ReadFile('../dbUsers/keys').split('\n')
uids.forEach((cid, i) => {
+ if (!cid) { return }
logger.Log(`[ ${i} / ${uids.length} ]`)
try {
dbtools.Insert(authDB, 'users', {
pw: uuidv4(),
- oldCID: cid
+ oldCID: cid,
+ avaiblePWRequests: 4,
+ created: new Date().toString()
})
} catch (e) {
logger.Log('Error during inserting', logger.GetColor('redbg'))
diff --git a/utils/dbtools.js b/utils/dbtools.js
index 30b6365..fcabba6 100644
--- a/utils/dbtools.js
+++ b/utils/dbtools.js
@@ -21,8 +21,8 @@ const utils = require('../utils/utils.js')
const debugLog = process.env.NS_SQL_DEBUG_LOG
// { asd: 'asd', basd: 4 } => asd = 'asd', basd = 4
-function GetSqlQuerry (conditions) {
- return Object.keys(conditions).reduce((acc, key) => {
+function GetSqlQuerry (conditions, type) {
+ const res = Object.keys(conditions).reduce((acc, key) => {
const item = conditions[key]
if (typeof item === 'string') {
acc.push(`${key} = '${conditions[key]}'`)
@@ -30,14 +30,21 @@ function GetSqlQuerry (conditions) {
acc.push(`${key} = ${conditions[key]}`)
}
return acc
- }, []).join(', ')
+ }, [])
+ if (type === 'where') {
+ return res.join(' AND ')
+ } else {
+ return res.join(', ')
+ }
}
// -------------------------------------------------------------------------
function GetDB (path) {
utils.CreatePath(path)
- return new Sqlite(path)
+ const res = new Sqlite(path)
+ res.pragma('synchronous = OFF')
+ return res
}
function DebugLog (msg) {
@@ -87,7 +94,7 @@ function TableInfo (db, table) {
function Update (db, table, newData, conditions) {
try {
- const s = `UPDATE ${table} SET ${GetSqlQuerry(newData)} WHERE ${GetSqlQuerry(conditions)}`
+ const s = `UPDATE ${table} SET ${GetSqlQuerry(newData, 'set')} WHERE ${GetSqlQuerry(conditions, 'where')}`
DebugLog(s)
const stmt = db.prepare(s)
@@ -99,7 +106,7 @@ function Update (db, table, newData, conditions) {
function Delete (db, table, conditions) {
try {
- const s = `DELETE FROM ${table} WHERE ${GetSqlQuerry(conditions)}`
+ const s = `DELETE FROM ${table} WHERE ${GetSqlQuerry(conditions, 'where')}`
DebugLog(s)
const stmt = db.prepare(s)
@@ -137,14 +144,16 @@ function CreateTable (db, name, columns, foreignKeys) {
return acc
}, []).join(', ')
- let fKeys = ''
+ let fKeys = []
if (foreignKeys) {
- const { keysFrom, table, keysTo } = foreignKeys
- fKeys = `, FOREIGN KEY(${keysFrom.join(', ')}) REFERENCES ${table}(${keysTo.join(', ')})`
+ foreignKeys.forEach((f) => {
+ const { keysFrom, table, keysTo } = f
+ fKeys.push(`, FOREIGN KEY(${keysFrom.join(', ')}) REFERENCES ${table}(${keysTo.join(', ')})`)
+ })
}
// IF NOT EXISTS
- const s = `CREATE TABLE ${name}(${cols}${fKeys})`
+ const s = `CREATE TABLE ${name}(${cols}${fKeys.join(', ')})`
DebugLog(s)
const stmt = db.prepare(s)
@@ -168,7 +177,7 @@ function SelectAll (db, from) {
function Select (db, from, conditions) {
try {
- const s = `SELECT * from ${from} WHERE ${GetSqlQuerry(conditions)}`
+ const s = `SELECT * from ${from} WHERE ${GetSqlQuerry(conditions, 'where')}`
DebugLog(s)
const stmt = db.prepare(s)