let mysql = require('mysql'); let config = require("./configuration"); class Database { constructor() { this.pool = mysql.createPool({ connectionLimit: 50, connectTimeout: 5000, acquireTimeout: 5000, host: config.sqlDatabase.host, user: config.sqlDatabase.user, password: config.sqlDatabase.password, database: config.sqlDatabase.database, multipleStatements: true, }); /* this.pool.on('connection', function(connection) { }); */ } get q() { return new SimpleQuery(this); } static instance() { if (!Database.INSTANCE) Database.INSTANCE = new Database(); return Database.INSTANCE; } con(cb) { return this.pool.getConnection(cb); } query(sql, values, cb) { this.pool.query(sql, values, (e, d) => cb(e, d)); } } class SelectElement { constructor(row, asName) { this.row = row; this.asName = asName; } get name() { return this.asName || this.row; } } class SimpleQuery { constructor(db) { this.db = db; this.selects = []; this.table = null; this.filters = []; this.orders = []; this.limitVal = null; } static compileArray(arr, first, separator, comp) { let res = ""; if (arr.length <= 0) return res; for (let i = 0; i < arr.length; i++) { if (i < 1) res += first; else res += separator; res += comp(arr[i]); } return res; } select(row, asName) { if (Array.isArray(row)) { if (!Array.isArray(asName)) asName = []; for (let i = 0; i < row.length; i++) this.select(row[i], asName[i]); } else { this.selects.push(new SelectElement(row, asName)); } return this; } from(tab) { this.table = tab; return this; } filter(row, val) { this.filters.push({row: row, val: val}); return this; } order(row, desc) { this.orders.push({row: row, desc: !!desc}); return this; } limit(limit) { this.limitVal = limit; return this; } reqSel(minVal) { if (this.selects.length < minVal) throw "Missing selectors"; return this; } get(cb) { let sel = this.selects[0].name; this.first(function (e, d) { if (d) cb(e, d[sel]); else cb(e, d); }); } first(cb) { this.limit(1).all(function (e, d) { if (d) cb(e, d[0]); else cb(e, d); }); } list(cb) { let value = this.selects[0].name; this.all(function (e, d) { if (d) cb(e, d.map(e => e[value])); else cb(e, d); }); } array(cb) { let index = this.selects[0].name; let value = this.selects[1].name; this.reqSel(2).all(function (e, d) { if (d) { let res = []; d.forEach(e => res[e[index]] = e[value]); cb(e, res); } else { cb(e, d); } }); } index(cb) { let index = this.selects[0].name; this.reqSel(1).all((e, d) => { if (d) { let res = []; d.forEach(e => res[e[index]] = e); cb(e, res); } else { cb(e, d); } }); } all(cb) { if (this.selects.length < 1) this.select("*"); if (!this.table) throw "Missing Table Name"; let values = []; let query = SimpleQuery.compileArray(this.selects, "SELECT ", ",", function (o) { if (o.asName) { return o.row + " AS " + o.asName; } return o.row; }) + " FROM " + this.table + SimpleQuery.compileArray(this.filters, " WHERE", " AND", function (o) { values.push(o.val); return " " + o.row + " = ?"; }) + SimpleQuery.compileArray(this.orders, " ORDER BY ", ",", function (o) { if (o.desc) return o.row + " DESC"; else return o.row + " ASC"; }); if (this.limitVal) query += " LIMIT " + this.limitVal; this.db.query(query, values, cb); } } module.exports = Database;