diff --git a/lib/pawsqlite-node-adapter.js b/lib/pawsqlite-node-adapter.js index 6a81996..80efd90 100644 --- a/lib/pawsqlite-node-adapter.js +++ b/lib/pawsqlite-node-adapter.js @@ -2,6 +2,93 @@ /******/ "use strict"; /******/ var __webpack_modules__ = ({ +/***/ "./src/database_wrapper.mjs": +/*!**********************************!*\ + !*** ./src/database_wrapper.mjs ***! + \**********************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "DatabaseWrapper": () => (/* binding */ DatabaseWrapper) +/* harmony export */ }); +/* harmony import */ var _node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_adapter_error.mjs */ "./src/node_adapter_error.mjs"); +/* harmony import */ var _query_wrapper_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./query_wrapper.mjs */ "./src/query_wrapper.mjs"); +/* harmony import */ var _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./response_wrapper.mjs */ "./src/response_wrapper.mjs"); +/* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); + + + + + + +class DatabaseWrapper { + constructor(db) { + this.db = db; + } + + close() { + return new Promise((resolve, reject) => { + this.db.close((err) => { + if (err) { + reject(_node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.NodeAdapterError.from(err)); + return; + } + resolve(); + }); + }); + } + + sql(sql, ...args) { + const query = new _query_wrapper_mjs__WEBPACK_IMPORTED_MODULE_1__.QueryWrapper(sql); + + if (query.isAnyOf("INSERT", "UPDATE", "DELETE")) { + return this.executeRun(query, ...args); + } else { + return this.executeAll(query, ...args); + } + } + + executeRun(query, ...args) { + return new Promise((resolve, reject) => { + (0,_log_mjs__WEBPACK_IMPORTED_MODULE_3__.log)(query.sql); + this.db.run(query.sql, ...args, function (err) { + if (err) { + reject(_node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.NodeAdapterError.from(err)); + return; + } + + const result = {}; + + if (query.isAnyOf("INSERT")) { + result.insertId = this.lastID; + } + + if (query.isAnyOf("UPDATE", "DELETE")) { + result.rowsAffected = this.changes; + } + + resolve(_response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__.ResponseWrapper.success(result)); + }); + }); + } + + executeAll(query, ...args) { + return new Promise((resolve, reject) => { + (0,_log_mjs__WEBPACK_IMPORTED_MODULE_3__.log)(query.sql); + this.db.all(query.sql, ...args, function (err, rows) { + if (err) { + reject(_node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.NodeAdapterError.from(err)); + return; + } + resolve(_response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__.ResponseWrapper.success({rows})); + }); + }); + } +} + +/***/ }), + /***/ "./src/log.mjs": /*!*********************!*\ !*** ./src/log.mjs ***! @@ -50,6 +137,63 @@ class NodeAdapterError extends Error { } } +/***/ }), + +/***/ "./src/query_wrapper.mjs": +/*!*******************************!*\ + !*** ./src/query_wrapper.mjs ***! + \*******************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "QueryWrapper": () => (/* binding */ QueryWrapper) +/* harmony export */ }); +class QueryWrapper { + constructor(sql) { + this.sql = sql.trim(); + this.operation = sql.replace(/[^a-z].*/i, "").toUpperCase(); + } + + isAnyOf(...operations) { + for (const op of operations) { + if(op.toUpperCase() === this.operation) { + return true; + } + } + return false; + } +} + +/***/ }), + +/***/ "./src/response_wrapper.mjs": +/*!**********************************!*\ + !*** ./src/response_wrapper.mjs ***! + \**********************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ResponseWrapper": () => (/* binding */ ResponseWrapper) +/* harmony export */ }); +const ResponseWrapper = { + success: (obj = {}) => ({ + success: true, + ...obj + }) +}; + +/***/ }), + +/***/ "sqlite3": +/*!**************************!*\ + !*** external "sqlite3" ***! + \**************************/ +/***/ ((module) => { + +module.exports = require("sqlite3");; + /***/ }) /******/ }); @@ -117,8 +261,15 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); -/* harmony import */ var _node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_adapter_error.mjs */ "./src/node_adapter_error.mjs"); -/* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); +/* harmony import */ var sqlite3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sqlite3 */ "sqlite3"); +/* harmony import */ var _node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./node_adapter_error.mjs */ "./src/node_adapter_error.mjs"); +/* harmony import */ var _database_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./database_wrapper.mjs */ "./src/database_wrapper.mjs"); +/* harmony import */ var _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./response_wrapper.mjs */ "./src/response_wrapper.mjs"); +/* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); + + + + @@ -127,37 +278,44 @@ const databases = new Map(); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: "PawSQLiteNodeAdapter", open: async (dbName) => { - // const version = "1.0"; - - // if (!databases.has(dbName)) { - // databases.set(dbName, new DatabaseWrapper(dbName, version)); - // } + if (!databases.has(dbName)) { + const db = new _database_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__.DatabaseWrapper( + new sqlite3__WEBPACK_IMPORTED_MODULE_0__.Database(dbName) + ); + databases.set(dbName, db); + } - // return ResponseWrapper.success({ version }); + return _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_3__.ResponseWrapper.success(); }, close: async (dbName) => { - // databases.delete(dbName); - // return ResponseWrapper.success(); + const db = databases.get(dbName); + if (!db) { + throw new _node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_1__.NodeAdapterError("Database not open"); + } + + await db.close(); + + databases.delete(dbName); + return _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_3__.ResponseWrapper.success(); }, sql: async (dbName, sql, ...args) => { - // log(sql); + const db = databases.get(dbName); + if (!db) { + throw new _node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_1__.NodeAdapterError("Database not open"); + } - // const db = databases.get(dbName); - // if (!db) { - // throw new NodeAdapterError("Database not open"); - // } + const result = await db.sql(sql, ...args); - // const result = await db.sql(sql, ...args); - // return ResponseWrapper.success(result); + return _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_3__.ResponseWrapper.success(result); }, delete: async (dbName) => { - // throw new NodeAdapterError("Delete not implemented"); + throw new _node_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_1__.NodeAdapterError("Delete not implemented"); }, - debug: _log_mjs__WEBPACK_IMPORTED_MODULE_1__.enableDebug + debug: _log_mjs__WEBPACK_IMPORTED_MODULE_4__.enableDebug }); })(); diff --git a/lib/pawsqlite-node-adapter.js.map b/lib/pawsqlite-node-adapter.js.map index b0dbcd5..a3b7690 100644 --- a/lib/pawsqlite-node-adapter.js.map +++ b/lib/pawsqlite-node-adapter.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://pawsqlite-node-adapter/./src/log.mjs","webpack://pawsqlite-node-adapter/./src/node_adapter_error.mjs","webpack://pawsqlite-node-adapter/webpack/bootstrap","webpack://pawsqlite-node-adapter/webpack/runtime/define property getters","webpack://pawsqlite-node-adapter/webpack/runtime/hasOwnProperty shorthand","webpack://pawsqlite-node-adapter/webpack/runtime/make namespace object","webpack://pawsqlite-node-adapter/./src/node_adapter.mjs"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;;AAEO;AACP;AACA;AACA,G;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA,C;;;;;;;;;;;;;;ACbO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,C;;;;;;UCRA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCrBA;WACA;WACA;WACA;WACA,wCAAwC,yCAAyC;WACjF;WACA;WACA,E;;;;;WCPA,wF;;;;;WCAA;WACA;WACA;WACA,sDAAsD,kBAAkB;WACxE;WACA,+CAA+C,cAAc;WAC7D,E;;;;;;;;;;;;;;;;ACN4D;AACf;;AAE7C;;AAEA,iEAAe;AACf;AACA;AACA;;AAEA;AACA;AACA;;AAEA,uCAAuC,UAAU;AACjD,GAAG;;AAEH;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;;AAEH,SAAS,iDAAW;AACpB,CAAC,EAAC","file":"pawsqlite-node-adapter.js","sourcesContent":["let DEBUG = false;\n\nexport function log(...args) {\n if (DEBUG) {\n console.log(...args);\n } \n}\n\nexport function enableDebug(active) {\n DEBUG = !!active;\n log(\"PawSQLite-WebSQL-Adapter: debugging \" + (\n DEBUG ? \"enabled\" : \"disabled\")\n );\n}","export class NodeAdapterError extends Error {\n static from(e) {\n let message = \"\";\n if (e && e.message) {\n message = e.message;\n }\n return new NodeAdapterError(message);\n }\n}","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { NodeAdapterError } from \"./node_adapter_error.mjs\";\nimport { enableDebug, log } from \"./log.mjs\";\n\nconst databases = new Map();\n\nexport default {\n name: \"PawSQLiteNodeAdapter\",\n open: async (dbName) => {\n // const version = \"1.0\";\n\n // if (!databases.has(dbName)) {\n // databases.set(dbName, new DatabaseWrapper(dbName, version));\n // }\n\n // return ResponseWrapper.success({ version });\n },\n\n close: async (dbName) => {\n // databases.delete(dbName);\n // return ResponseWrapper.success();\n },\n\n sql: async (dbName, sql, ...args) => {\n // log(sql);\n\n // const db = databases.get(dbName);\n // if (!db) {\n // throw new NodeAdapterError(\"Database not open\");\n // }\n\n // const result = await db.sql(sql, ...args);\n // return ResponseWrapper.success(result);\n },\n\n delete: async (dbName) => {\n // throw new NodeAdapterError(\"Delete not implemented\");\n },\n\n debug: enableDebug\n};\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://pawsqlite-node-adapter/./src/database_wrapper.mjs","webpack://pawsqlite-node-adapter/./src/log.mjs","webpack://pawsqlite-node-adapter/./src/node_adapter_error.mjs","webpack://pawsqlite-node-adapter/./src/query_wrapper.mjs","webpack://pawsqlite-node-adapter/./src/response_wrapper.mjs","webpack://pawsqlite-node-adapter/external \"sqlite3\"","webpack://pawsqlite-node-adapter/webpack/bootstrap","webpack://pawsqlite-node-adapter/webpack/runtime/define property getters","webpack://pawsqlite-node-adapter/webpack/runtime/hasOwnProperty shorthand","webpack://pawsqlite-node-adapter/webpack/runtime/make namespace object","webpack://pawsqlite-node-adapter/./src/node_adapter.mjs"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAA4D;AACT;AACM;AACZ;;;AAGtC;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,0EAAqB;AACtC;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;;AAEA;AACA,sBAAsB,4DAAY;;AAElC;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA,MAAM,6CAAG;AACT;AACA;AACA,iBAAiB,0EAAqB;AACtC;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,gBAAgB,0EAAuB;AACvC,OAAO;AACP,KAAK;AACL;;AAEA;AACA;AACA,MAAM,6CAAG;AACT;AACA;AACA,iBAAiB,0EAAqB;AACtC;AACA;AACA,gBAAgB,0EAAuB,EAAE,KAAK;AAC9C,OAAO;AACP,KAAK;AACL;AACA,C;;;;;;;;;;;;;;;ACrEA;;AAEO;AACP;AACA;AACA,G;AACA;;AAEO;AACP;AACA;AACA;AACA;AACA,C;;;;;;;;;;;;;;ACbO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,C;;;;;;;;;;;;;;ACRO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,C;;;;;;;;;;;;;;ACdO;AACP,oBAAoB;AACpB;AACA;AACA,GAAG;AACH,E;;;;;;;;;;ACLA,qC;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCrBA;WACA;WACA;WACA;WACA,wCAAwC,yCAAyC;WACjF;WACA;WACA,E;;;;;WCPA,wF;;;;;WCAA;WACA;WACA;WACA,sDAAsD,kBAAkB;WACxE;WACA,+CAA+C,cAAc;WAC7D,E;;;;;;;;;;;;;;;;;;;ACNmC;;AAEyB;AACH;AACA;AACZ;;AAE7C;;AAEA,iEAAe;AACf;AACA;AACA;AACA,qBAAqB,kEAAe;AACpC,YAAY,6CAAgB;AAC5B;AACA;AACA;;AAEA,WAAW,0EAAuB;AAClC,GAAG;;AAEH;AACA;AACA;AACA,gBAAgB,qEAAgB;AAChC;;AAEA;;AAEA;AACA,WAAW,0EAAuB;AAClC,GAAG;;AAEH;AACA;AACA;AACA,gBAAgB,qEAAgB;AAChC;;AAEA;;AAEA,WAAW,0EAAuB;AAClC,GAAG;;AAEH;AACA,cAAc,qEAAgB;AAC9B,GAAG;;AAEH,SAAS,iDAAW;AACpB,CAAC,EAAC","file":"pawsqlite-node-adapter.js","sourcesContent":["import { NodeAdapterError } from \"./node_adapter_error.mjs\";\nimport { QueryWrapper } from \"./query_wrapper.mjs\";\nimport { ResponseWrapper } from \"./response_wrapper.mjs\";\nimport { enableDebug, log } from \"./log.mjs\";\n\n\nexport class DatabaseWrapper {\n constructor(db) {\n this.db = db;\n }\n\n close() {\n return new Promise((resolve, reject) => {\n this.db.close((err) => {\n if (err) {\n reject(NodeAdapterError.from(err));\n return;\n }\n resolve();\n });\n });\n }\n\n sql(sql, ...args) {\n const query = new QueryWrapper(sql);\n\n if (query.isAnyOf(\"INSERT\", \"UPDATE\", \"DELETE\")) {\n return this.executeRun(query, ...args);\n } else {\n return this.executeAll(query, ...args);\n }\n }\n\n executeRun(query, ...args) {\n return new Promise((resolve, reject) => {\n log(query.sql);\n this.db.run(query.sql, ...args, function (err) {\n if (err) {\n reject(NodeAdapterError.from(err));\n return;\n }\n\n const result = {};\n\n if (query.isAnyOf(\"INSERT\")) {\n result.insertId = this.lastID;\n }\n\n if (query.isAnyOf(\"UPDATE\", \"DELETE\")) {\n result.rowsAffected = this.changes;\n }\n\n resolve(ResponseWrapper.success(result));\n });\n });\n }\n\n executeAll(query, ...args) {\n return new Promise((resolve, reject) => {\n log(query.sql);\n this.db.all(query.sql, ...args, function (err, rows) {\n if (err) {\n reject(NodeAdapterError.from(err));\n return;\n }\n resolve(ResponseWrapper.success({rows}));\n });\n });\n }\n}","let DEBUG = false;\n\nexport function log(...args) {\n if (DEBUG) {\n console.log(...args);\n } \n}\n\nexport function enableDebug(active) {\n DEBUG = !!active;\n log(\"PawSQLite-WebSQL-Adapter: debugging \" + (\n DEBUG ? \"enabled\" : \"disabled\")\n );\n}","export class NodeAdapterError extends Error {\n static from(e) {\n let message = \"\";\n if (e && e.message) {\n message = e.message;\n }\n return new NodeAdapterError(message);\n }\n}","export class QueryWrapper {\n constructor(sql) {\n this.sql = sql.trim();\n this.operation = sql.replace(/[^a-z].*/i, \"\").toUpperCase();\n }\n\n isAnyOf(...operations) {\n for (const op of operations) {\n if(op.toUpperCase() === this.operation) {\n return true;\n }\n }\n return false;\n }\n}","export const ResponseWrapper = {\n success: (obj = {}) => ({\n success: true,\n ...obj\n })\n};","module.exports = require(\"sqlite3\");;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tif(__webpack_module_cache__[moduleId]) {\n\t\treturn __webpack_module_cache__[moduleId].exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import * as sqlite3 from \"sqlite3\";\n\nimport { NodeAdapterError } from \"./node_adapter_error.mjs\";\nimport { DatabaseWrapper } from \"./database_wrapper.mjs\";\nimport { ResponseWrapper } from \"./response_wrapper.mjs\";\nimport { enableDebug, log } from \"./log.mjs\";\n\nconst databases = new Map();\n\nexport default {\n name: \"PawSQLiteNodeAdapter\",\n open: async (dbName) => {\n if (!databases.has(dbName)) {\n const db = new DatabaseWrapper(\n new sqlite3.Database(dbName)\n );\n databases.set(dbName, db);\n }\n\n return ResponseWrapper.success();\n },\n\n close: async (dbName) => {\n const db = databases.get(dbName);\n if (!db) {\n throw new NodeAdapterError(\"Database not open\");\n }\n\n await db.close();\n\n databases.delete(dbName);\n return ResponseWrapper.success();\n },\n\n sql: async (dbName, sql, ...args) => {\n const db = databases.get(dbName);\n if (!db) {\n throw new NodeAdapterError(\"Database not open\");\n }\n\n const result = await db.sql(sql, ...args);\n\n return ResponseWrapper.success(result);\n },\n\n delete: async (dbName) => {\n throw new NodeAdapterError(\"Delete not implemented\");\n },\n\n debug: enableDebug\n};\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/database_wrapper.mjs b/src/database_wrapper.mjs new file mode 100644 index 0000000..6bb39ad --- /dev/null +++ b/src/database_wrapper.mjs @@ -0,0 +1,70 @@ +import { NodeAdapterError } from "./node_adapter_error.mjs"; +import { QueryWrapper } from "./query_wrapper.mjs"; +import { ResponseWrapper } from "./response_wrapper.mjs"; +import { enableDebug, log } from "./log.mjs"; + + +export class DatabaseWrapper { + constructor(db) { + this.db = db; + } + + close() { + return new Promise((resolve, reject) => { + this.db.close((err) => { + if (err) { + reject(NodeAdapterError.from(err)); + return; + } + resolve(); + }); + }); + } + + sql(sql, ...args) { + const query = new QueryWrapper(sql); + + if (query.isAnyOf("INSERT", "UPDATE", "DELETE")) { + return this.executeRun(query, ...args); + } else { + return this.executeAll(query, ...args); + } + } + + executeRun(query, ...args) { + return new Promise((resolve, reject) => { + log(query.sql); + this.db.run(query.sql, ...args, function (err) { + if (err) { + reject(NodeAdapterError.from(err)); + return; + } + + const result = {}; + + if (query.isAnyOf("INSERT")) { + result.insertId = this.lastID; + } + + if (query.isAnyOf("UPDATE", "DELETE")) { + result.rowsAffected = this.changes; + } + + resolve(ResponseWrapper.success(result)); + }); + }); + } + + executeAll(query, ...args) { + return new Promise((resolve, reject) => { + log(query.sql); + this.db.all(query.sql, ...args, function (err, rows) { + if (err) { + reject(NodeAdapterError.from(err)); + return; + } + resolve(ResponseWrapper.success({rows})); + }); + }); + } +} \ No newline at end of file diff --git a/src/node_adapter.mjs b/src/node_adapter.mjs index bd855e9..72ef41e 100644 --- a/src/node_adapter.mjs +++ b/src/node_adapter.mjs @@ -1,4 +1,8 @@ +import * as sqlite3 from "sqlite3"; + import { NodeAdapterError } from "./node_adapter_error.mjs"; +import { DatabaseWrapper } from "./database_wrapper.mjs"; +import { ResponseWrapper } from "./response_wrapper.mjs"; import { enableDebug, log } from "./log.mjs"; const databases = new Map(); @@ -6,34 +10,41 @@ const databases = new Map(); export default { name: "PawSQLiteNodeAdapter", open: async (dbName) => { - // const version = "1.0"; - - // if (!databases.has(dbName)) { - // databases.set(dbName, new DatabaseWrapper(dbName, version)); - // } - - // return ResponseWrapper.success({ version }); + if (!databases.has(dbName)) { + const db = new DatabaseWrapper( + new sqlite3.Database(dbName) + ); + databases.set(dbName, db); + } + + return ResponseWrapper.success(); }, close: async (dbName) => { - // databases.delete(dbName); - // return ResponseWrapper.success(); + const db = databases.get(dbName); + if (!db) { + throw new NodeAdapterError("Database not open"); + } + + await db.close(); + + databases.delete(dbName); + return ResponseWrapper.success(); }, sql: async (dbName, sql, ...args) => { - // log(sql); + const db = databases.get(dbName); + if (!db) { + throw new NodeAdapterError("Database not open"); + } - // const db = databases.get(dbName); - // if (!db) { - // throw new NodeAdapterError("Database not open"); - // } + const result = await db.sql(sql, ...args); - // const result = await db.sql(sql, ...args); - // return ResponseWrapper.success(result); + return ResponseWrapper.success(result); }, delete: async (dbName) => { - // throw new NodeAdapterError("Delete not implemented"); + throw new NodeAdapterError("Delete not implemented"); }, debug: enableDebug diff --git a/src/query_wrapper.mjs b/src/query_wrapper.mjs new file mode 100644 index 0000000..c13e900 --- /dev/null +++ b/src/query_wrapper.mjs @@ -0,0 +1,15 @@ +export class QueryWrapper { + constructor(sql) { + this.sql = sql.trim(); + this.operation = sql.replace(/[^a-z].*/i, "").toUpperCase(); + } + + isAnyOf(...operations) { + for (const op of operations) { + if(op.toUpperCase() === this.operation) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/src/response_wrapper.mjs b/src/response_wrapper.mjs new file mode 100644 index 0000000..c6f9eab --- /dev/null +++ b/src/response_wrapper.mjs @@ -0,0 +1,6 @@ +export const ResponseWrapper = { + success: (obj = {}) => ({ + success: true, + ...obj + }) +}; \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 4e3ac69..db2609e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,6 +6,9 @@ var config = { mode: 'development', entry: __dirname + '/src/node_adapter.mjs', devtool: 'source-map', + externals: { + sqlite3: 'sqlite3' + }, output: { path: __dirname + '/lib', filename: outputFile,