| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- const sqlite3 = require('sqlite3');
- const CONFIG = require('./config.js');
- function DatabaseHelper() {
- this.db = null;
- this.models = [];
- }
- DatabaseHelper.prototype.init = function(allModels) {
- this.models = allModels;
- return new Promise((ok, ko) => {
- this.db = new sqlite3.Database(CONFIG.database, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE | sqlite3.OPEN_FULLMUTEX, async (err) => {
- if (err) {
- ko(err);
- return;
- }
- let types = this.models;
- for (let i =0; i < types.length; ++i) {
- let instance = new types[i]();
- await instance.createOrUpdateBase(this);
- }
- console.log("Database is ready");
- ok();
- });
- });
- }
- DatabaseHelper.prototype.runSql = function(sqlStatement, args, fetch) {
- console.info("DatabaseHelper::runSql ", sqlStatement, args);
- return new Promise((ok, ko) => {
- if (sqlStatement.indexOf('--') >= 0) {
- console.error("Rejecting SQL request containing comments");
- ko("SQL Comment Error");
- return;
- }
- try {
- let fnc = (fetch === false ? this.db.run : this.db.all);
- fnc.call(this.db, sqlStatement, args, function(err, data) {
- if (err) {
- console.error(err);
- ko(err);
- } else {
- ok(fetch !== false ? data : this.lastID);
- }
- });
- } catch (err) {
- console.error(err);
- ko(err);
- }
- });
- }
- DatabaseHelper.prototype.insertOne = async function(object) {
- let columns = [];
- let args = [];
- for (let [key, val] of Object.entries(object.describe())) {
- columns.push("`"+key+"`");
- args.push(val);
- }
- let request = "insert into `" +object.getTableName()
- +"` (" +columns.join(", ")
- +") VALUES (" +columns.map(i => "?").join(",")+")";
- let id = await this.runSql(request, args, false);
- if (object.id !== undefined)
- object.id = id;
- return id;
- }
- DatabaseHelper.prototype.insertMultipleSameTable = async function(arr) {
- let columns = [];
- let args = [];
- if (!arr || !arr.length)
- return;
- for (let [key, val] of Object.entries(arr[0].describe()))
- columns.push("`"+key+"`");
- let request = "insert into `" +arr[0].getTableName()
- +"` (" +columns.join(", ")
- +") VALUES ";
- let valuesArr = [];
- request += arr.map(i => ("(" +columns.map(i => "?").join(",")+")")).join(',');
- for (let i of arr)
- {
- for (let [key, val] of Object.entries(i.describe()))
- args.push(val);
- }
- await this.runSql(request, args, false);
- }
- DatabaseHelper.prototype.upsertOne = async function(obj) {
- let columns = [];
- let columnsVal = [];
- let args = [];
- let i =0;
- for (let [key, val] of Object.entries(obj.describe())) {
- columns.push("`"+key+"`");
- columnsVal.push("`"+key+"`=:"+(i++));
- args.push(val);
- }
- let request = "insert into `" +obj.getTableName()
- +"` (" +columns.join(", ")
- +") VALUES (" +columns.map((_, i) => `:${i}`).join(",")+")"
- +" ON CONFLICT DO UPDATE SET " +columnsVal.join(", ");
- await this.runSql(request, args, false);
- }
- DatabaseHelper.prototype.buildWhere = function(whereObj, columns, args) {
- columns = columns || [];
- args = args || [];
- if (!whereObj) {
- columns.push("1=1");
- } else {
- for (let [key, val] of Object.entries(whereObj)) {
- if (val === null) {
- columns.push("`"+key+"` is null");
- } else if (Array.isArray(val)) {
- columns.push("`"+key+"` in (" +val.map(i => "?").join(",") + ")");
- for (let i of val) args.push(i);
- } else {
- columns.push("`"+key+"`=?");
- args.push(val);
- }
- }
- }
- return {
- columns: columns,
- args: args
- };
- }
- DatabaseHelper.prototype.maxVersion = async function(instanceName) {
- let queryParts = [];
- for (let i of this.models)
- queryParts.push("select max(" +i.prototype.versionColumn.call(null) +") as v from " +i.prototype.getTableName.call(null) +" where instance=:0");
- let version = await this.runSql("select max(v) as v from (" +queryParts.join(" union ") +")", [ instanceName ], true);
- return (version?.[0]?.v) || 0;
- }
- DatabaseHelper.prototype.versionFetch = async function(objectPrototype, minVersion) {
- let query = "select * from `" +objectPrototype.prototype.getTableName.call(null) +"` where `" +objectPrototype.prototype.versionColumn.call(null)+"` > ? and instance=?";
- let result = [];
- for (let i of await this.runSql(query, [minVersion, CONFIG.instanceHostname], true))
- {
- let resultObj = new objectPrototype();
- resultObj.fromDb(i);
- result.push(resultObj);
- }
- return result;
- }
- DatabaseHelper.prototype.fetch = async function(objectPrototype, where, orderBy) {
- let result = await this.fetchRaw("*", objectPrototype.prototype.getTableName.call(null), where, orderBy);
- let resultArr = [];
- for (let i of result)
- {
- let resultObj = new objectPrototype();
- resultObj.fromDb(i);
- resultArr.push(resultObj);
- }
- return resultArr;
- }
- DatabaseHelper.prototype.fetchRaw = async function(columns, tableName, where, orderBy) {
- let whereArgs = this.buildWhere(where);
- let query = "select " + (Array.isArray(columns) ? columns.join(","): columns) +" from `" +tableName +"` where " +whereArgs.columns.join(" and ");
- if (orderBy)
- query += " ORDER BY " +Object.keys(orderBy || {}).map(i => "`"+i+"` " +(orderBy[i] === 'DESC' ? "DESC":"ASC")).join(",");
- return await this.runSql(query, whereArgs.args, true);
- }
- DatabaseHelper.prototype.findOne = async function(objectPrototype, where) {
- let whereArgs = this.buildWhere(where);
- let result = await this.runSql("select * from `" +objectPrototype.prototype.getTableName.call(null) +"` where " +whereArgs.columns.join(" and ") +" LIMIT 1", whereArgs.args, true);
- if (result && result.length)
- {
- let resultObj = new objectPrototype();
- resultObj.fromDb(result[0]);
- return resultObj;
- }
- return null;
- }
- DatabaseHelper.prototype.update = async function(where, object) {
- if (object.lastUpdated)
- object.lastUpdated = new Date();
- await this.rawUpdate(object, where, object.describe());
- }
- DatabaseHelper.prototype.rawUpdate = async function(model, where, values) {
- let columns = [];
- let args = [];
- for (let [key, val] of Object.entries(values)) {
- columns.push("`"+key+"`=?");
- args.push(val);
- }
- let whereArgs = this.buildWhere(where, [], args);
- let query = "update `" +(model.prototype?.getTableName ? model.prototype.getTableName() : model.getTableName())
- +"` set " +columns.join(", ")
- +" WHERE " +whereArgs.columns.join(" and ");
- await this.runSql(query, args, false);
- }
- module.exports.DatabaseHelper = new DatabaseHelper();
|