From ed9c9f754b66d09776a9edd1959940673926cd8d Mon Sep 17 00:00:00 2001 From: oof1lab Date: Sat, 25 Nov 2017 19:03:24 +0530 Subject: [PATCH] Refactor : separate class for controller --- lib/xapi.js | 604 +++------------------------------------------------ lib/xctrl.js | 566 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 595 insertions(+), 575 deletions(-) create mode 100644 lib/xctrl.js diff --git a/lib/xapi.js b/lib/xapi.js index 5e1f595e9e..8f5133b067 100644 --- a/lib/xapi.js +++ b/lib/xapi.js @@ -1,6 +1,7 @@ 'use strict'; var Xsql = require('./xsql.js'); +var Xctrl = require('./xctrl.js'); var multer = require('multer'); var path = require('path'); @@ -13,6 +14,7 @@ class Xapi { this.config = args; this.mysql = new Xsql(args, mysqlPool) this.app = app; + this.ctrls = []; /**************** START : multer ****************/ this.storage = multer.diskStorage({ @@ -135,6 +137,10 @@ class Xapi { // iterate over each resource for (var j = 0; j < resources.length; ++j) { + + let resourceCtrl = new Xctrl(this.app, this.mysql) + this.ctrls.push(resourceCtrl); + let routes = resources[j]['routes']; stat.apis += resources[j]['routes'].length @@ -146,67 +152,67 @@ class Xapi { case 'list': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.list.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.list.bind(resourceCtrl))); break; case 'findOne': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.findOne.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.findOne.bind(resourceCtrl))); break; case 'create': this.app.route(routes[i]['routeUrl']) - .post(this.asyncMiddleware(this.create.bind(this))); + .post(this.asyncMiddleware(resourceCtrl.create.bind(resourceCtrl))); break; case 'read': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.read.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.read.bind(resourceCtrl))); break; case 'bulkInsert': this.app.route(routes[i]['routeUrl']) - .post(this.asyncMiddleware(this.bulkInsert.bind(this))); + .post(this.asyncMiddleware(resourceCtrl.bulkInsert.bind(resourceCtrl))); break; case 'bulkRead': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.bulkRead.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.bulkRead.bind(resourceCtrl))); break; case 'bulkDelete': this.app.route(routes[i]['routeUrl']) - .delete(this.asyncMiddleware(this.bulkDelete.bind(this))); + .delete(this.asyncMiddleware(resourceCtrl.bulkDelete.bind(resourceCtrl))); break; case 'patch': this.app.route(routes[i]['routeUrl']) - .patch(this.asyncMiddleware(this.patch.bind(this))); + .patch(this.asyncMiddleware(resourceCtrl.patch.bind(resourceCtrl))); break; case 'update': this.app.route(routes[i]['routeUrl']) - .put(this.asyncMiddleware(this.update.bind(this))); + .put(this.asyncMiddleware(resourceCtrl.update.bind(resourceCtrl))); break; case 'delete': this.app.route(routes[i]['routeUrl']) - .delete(this.asyncMiddleware(this.delete.bind(this))); + .delete(this.asyncMiddleware(resourceCtrl.delete.bind(resourceCtrl))); break; case 'exists': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.exists.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.exists.bind(resourceCtrl))); break; case 'count': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.count.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.count.bind(resourceCtrl))); break; case 'distinct': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.distinct.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.distinct.bind(resourceCtrl))); break; case 'describe': @@ -216,32 +222,32 @@ class Xapi { case 'relational': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.nestedList.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.nestedList.bind(resourceCtrl))); break; case 'groupby': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.groupBy.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.groupBy.bind(resourceCtrl))); break; case 'ugroupby': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.ugroupby.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.ugroupby.bind(resourceCtrl))); break; case 'chart': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.chart.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.chart.bind(resourceCtrl))); break; case 'autoChart': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.autoChart.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.autoChart.bind(resourceCtrl))); break; case 'aggregate': this.app.route(routes[i]['routeUrl']) - .get(this.asyncMiddleware(this.aggregate.bind(this))); + .get(this.asyncMiddleware(resourceCtrl.aggregate.bind(resourceCtrl))); break; } @@ -274,37 +280,11 @@ class Xapi { console.log(' '); console.log(' REST APIs Generated : %s'.green.bold, stat.apis); console.log(' '); - return stat - } - - async create(req, res) { - - let query = 'INSERT INTO ?? SET ?'; - let params = []; - - params.push(req.app.locals._tableName); - params.push(req.body); - - var results = await this.mysql.exec(query, params); - res.status(200).json(results); - } - - - async list(req, res) { - - let queryParamsObj = {} - queryParamsObj.query = '' - queryParamsObj.params = [] - - this.mysql.prepareListQuery(req, res, queryParamsObj, 0); - - let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - res.status(200).json(results); + return stat } - async xjoin(req, res) { let obj = {} @@ -319,252 +299,16 @@ class Xapi { let results = await this.mysql.exec(obj.query, obj.params) res.status(200).json(results) - //http://localhost:3000/api/xjoin?_join=pl.productlines,j,pr.products,j,ord.orderdetails&on1=(pl.productline,eq,pr.products)&on2=(pr.productcode,eq,ord.productcode) - - } - - - async nestedList(req, res) { - - let queryParamsObj = {} - queryParamsObj.query = ''; - queryParamsObj.params = []; - - this.mysql.prepareListQuery(req, res, queryParamsObj, 1) - - let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - res.status(200).json(results); - - } - - async findOne(req, res) { - - let queryParamsObj = {} - queryParamsObj.query = '' - queryParamsObj.params = [] - - this.mysql.prepareListQuery(req, res, queryParamsObj, 2); - - let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - res.status(200).json(results); - - } - - async read(req, res) { - - let query = 'select * from ?? where '; - let params = []; - - params.push(req.app.locals._tableName); - - let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, - req.params.id.split('___')); - - - if (!clause) { - return res.status(400).send({ - error: "Table is made of composite primary keys - all keys were not in input" - }); - } - - query += clause; - query += ' LIMIT 1' - - let results = await this.mysql.exec(query, params); - res.status(200).json(results); - - - } - - async exists(req, res) { - - let query = 'select * from ?? where '; - let params = []; - - params.push(req.app.locals._tableName); - - let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, - req.params.id.split('___')); - - if (!clause) { - return res.status(400).send({ - error: "Table is made of composite primary keys - all keys were not in input" - }) - } - - query += clause; - query += ' LIMIT 1' - - let results = await this.mysql.exec(query, params); - res.status(200).json(results); - - - } - - - async update(req, res) { - - let query = 'REPLACE INTO ?? SET ?'; - let params = []; - - params.push(req.app.locals._tableName); - params.push(req.body); - - var results = await this.mysql.exec(query, params); - res.status(200).json(results); - - } - - async patch(req, res) { - - let query = 'UPDATE ?? SET '; - let keys = Object.keys(req.body); - - // SET clause - let updateKeys = ''; - for (let i = 0; i < keys.length; ++i) { - updateKeys += keys[i] + ' = ? ' - if (i !== keys.length - 1) - updateKeys += ', ' - } - - // where clause - query += updateKeys + ' where ' - let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, - req.params.id.split('___')); - - if (!clause) { - return res.status(400).send({ - error: "Table is made of composite primary keys - all keys were not in input" - }) - } - - query += clause; - - // params - let params = []; - params.push(req.app.locals._tableName); - params = params.concat(Object.values(req.body)); - - let results = await this.mysql.exec(query, params); - res.status(200).json(results); - - } - async delete(req, res) { - - let query = 'DELETE FROM ?? WHERE '; - let params = []; - - params.push(req.app.locals._tableName); - - let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, - req.params.id.split('___')); - - if (!clause) { - return res.status(400).send({ - error: "Table is made of composite primary keys - all keys were not in input" - }); - } + async tableDescribe(req, res) { - query += clause; + let query = 'describe ??'; + let params = [req.app.locals._tableName]; let results = await this.mysql.exec(query, params); res.status(200).json(results); - - } - - async bulkInsert(req, res) { - - let queryParamsObj = {} - queryParamsObj.query = '' - queryParamsObj.params = [] - let results = [] - - //console.log(req.app.locals._tableName, req.body); - - this.mysql.getBulkInsertStatement(req.app.locals._tableName, req.body, queryParamsObj) - - results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - res.status(200).json(results); - - } - - async bulkDelete(req, res) { - - let query = 'delete from ?? where ?? in '; - let params = []; - - params.push(req.app.locals._tableName); - params.push(this.mysql.getPrimaryKeyName(req.app.locals._tableName)); - - query += '(' - - if (req.query && req.query._ids) { - let ids = req.query._ids.split(',') - for (var i = 0; i < ids.length; ++i) { - if (i) { - query += ',' - } - query += '?' - params.push(ids[i]) - } - } - - query += ')' - - //console.log(query, params); - - var results = await this.mysql.exec(query, params); - res.status(200).json(results); - - } - - async bulkRead(req, res) { - - let queryParamsObj = {} - queryParamsObj.query = '' - queryParamsObj.params = [] - - this.mysql.prepareListQuery(req, res, queryParamsObj, 3); - - //console.log(queryParamsObj.query, queryParamsObj.params); - - let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - res.status(200).json(results); - - } - - - async count(req, res) { - - let queryParams = {} - - queryParams.query = 'select count(1) as no_of_rows from ?? '; - queryParams.params = []; - - queryParams.params.push(req.app.locals._tableName); - - this.mysql.getWhereClause(req.query._where, req.app.locals._tableName, queryParams, ' where ') - - let results = await this.mysql.exec(queryParams.query, queryParams.params); - res.status(200).json(results); - - } - - async distinct(req, res) { - - let queryParamsObj = {} - queryParamsObj.query = '' - queryParamsObj.params = [] - - this.mysql.prepareListQuery(req, res, queryParamsObj, 4); - - let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - res.status(200).json(results); - } async tables(req, res) { @@ -582,7 +326,6 @@ class Xapi { res.status(200).json(results) } - async runQuery(req, res) { let query = req.body.query; @@ -594,295 +337,6 @@ class Xapi { } - async tableDescribe(req, res) { - - let query = 'describe ??'; - let params = [req.app.locals._tableName]; - - let results = await this.mysql.exec(query, params); - res.status(200).json(results); - - } - - async groupBy(req, res) { - - if (req.query && req.query._fields) { - - let queryParamsObj = {} - queryParamsObj.query = 'select '; - queryParamsObj.params = []; - - /**************** add columns and group by columns ****************/ - this.mysql.getColumnsForSelectStmt(req.app.locals._tableName, req.query, queryParamsObj) - - queryParamsObj.query += ',count(*) as _count from ?? group by '; - let tableName = req.app.locals._tableName; - queryParamsObj.params.push(tableName); - - this.mysql.getColumnsForSelectStmt(req.app.locals._tableName, req.query, queryParamsObj) - - if (!req.query._sort) { - req.query._sort = {} - req.query._sort = '-_count' - } - - /**************** add having clause ****************/ - this.mysql.getHavingClause(req.query._having, req.app.locals._tableName, queryParamsObj, ' having '); - - /**************** add orderby clause ****************/ - this.mysql.getOrderByClause(req.query, tableName, queryParamsObj); - - //console.log(queryParamsObj.query, queryParamsObj.params); - var results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - - res.status(200).json(results); - - } else { - res.status(400).json({message: 'Missing _fields query params eg: /api/tableName/groupby?_fields=column1'}) - } - - } - - async ugroupby(req, res) { - - if (req.query && req.query._fields) { - - let queryParamsObj = {} - queryParamsObj.query = ''; - queryParamsObj.params = []; - let uGrpByResults = {} - - /**************** add fields with count(*) *****************/ - let fields = req.query._fields.split(',') - - for (var i = 0; i < fields.length; ++i) { - - uGrpByResults[fields[i]] = [] - - if (i) { - queryParamsObj.query += ' UNION ' - } - queryParamsObj.query += ' SELECT IFNULL(CONCAT(?,?,??),?) as ugroupby, count(*) as _count from ?? GROUP BY ?? ' - queryParamsObj.params.push(fields[i]) - queryParamsObj.params.push('~') - queryParamsObj.params.push(fields[i]) - queryParamsObj.params.push(fields[i] + '~') - queryParamsObj.params.push(req.app.locals._tableName) - queryParamsObj.params.push(fields[i]) - } - - //console.log(queryParamsObj.query, queryParamsObj.params); - var results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); - - for (var i = 0; i < results.length; ++i) { - - let grpByColName = results[i]['ugroupby'].split('~')[0] - let grpByColValue = results[i]['ugroupby'].split('~')[1] - - let obj = {} - obj[grpByColValue] = results[i]['_count']; - - uGrpByResults[grpByColName].push(obj) - - } - - res.status(200).json(uGrpByResults); - - } else { - res.status(400).json({message: 'Missing _fields query params eg: /api/tableName/ugroupby?_fields=column1,column2'}) - } - } - - - async aggregate(req, res) { - - - if (req.query && req.query._fields) { - let tableName = req.app.locals._tableName; - let query = 'select ' - let params = [] - let fields = req.query._fields.split(','); - - for (var i = 0; i < fields.length; ++i) { - if (i) { - query = query + ',' - } - query = query + ' min(??) as ?,max(??) as ?,avg(??) as ?,sum(??) as ?,stddev(??) as ?,variance(??) as ? ' - params.push(fields[i]); - params.push('min_of_' + fields[i]); - params.push(fields[i]); - params.push('max_of_' + fields[i]); - params.push(fields[i]); - params.push('avg_of_' + fields[i]); - params.push(fields[i]); - params.push('sum_of_' + fields[i]); - params.push(fields[i]); - params.push('stddev_of_' + fields[i]); - params.push(fields[i]); - params.push('variance_of_' + fields[i]); - } - - query = query + ' from ??' - params.push(tableName) - - var results = await this.mysql.exec(query, params); - - res.status(200).json(results); - } else { - res.status(400).json({message: 'Missing _fields in query params eg: /api/tableName/aggregate?_fields=numericColumn1'}); - } - - } - - - async chart(req, res) { - - let query = '' - let params = [] - let obj = {} - - - if (req.query) { - - let isRange = false - if (req.query.range) { - isRange = true - } - - if (req.query && req.query.min && req.query.max && req.query.step) { - - //console.log(req.params.min, req.params.max, req.params.step); - - obj = this.mysql.getChartQueryAndParamsFromMinMaxStep(req.app.locals._tableName, - req.query._fields, - parseInt(req.query.min), - parseInt(req.query.max), - parseInt(req.query.step), - isRange) - - - } else if (req.query && req.query.steparray && req.query.steparray.length > 1) { - - obj = this.mysql.getChartQueryAndParamsFromStepArray(req.app.locals._tableName, - req.query._fields, - (req.query.steparray.split(',')).map(Number), - isRange) - - - } else if (req.query && req.query.steppair && req.query.steppair.length > 1) { - - obj = this.mysql.getChartQueryAndParamsFromStepPair(req.app.locals._tableName, - req.query._fields, - (req.query.steppair.split(',')).map(Number), - false) - - - } else { - - query = 'select min(??) as min,max(??) as max,stddev(??) as stddev,avg(??) as avg from ??'; - params = []; - - params.push(req.query._fields); - params.push(req.query._fields); - params.push(req.query._fields); - params.push(req.query._fields); - params.push(req.app.locals._tableName); - - let _this = this; - - let results = await - _this.mysql.exec(query, params); - - //console.log(results, results['max'], req.params); - - obj = _this.mysql.getChartQueryAndParamsFromMinMaxStddev(req.app.locals._tableName, - req.query._fields, - results[0]['min'], - results[0]['max'], - results[0]['stddev'], - isRange - ) - - } - - this.mysql.getWhereClause(req.query._where, req.app.locals._tableName, obj, ' where ') - - let results = await - this.mysql.exec(obj.query, obj.params); - - res.status(200).json(results); - - } else { - res.status(400).json({message: 'Missing _fields in query params eg: /api/tableName/chart?_fields=numericColumn1'}); - } - - - } - - - async autoChart(req, res) { - - let query = 'describe ??' - let params = [req.app.locals._tableName] - let obj = {} - let results = [] - - let isRange = false - if (req.query.range) { - isRange = true - } - - - let describeResults = await this.mysql.exec(query, params) - - //console.log(describeResults); - - for (var i = 0; i < describeResults.length; ++i) { - - //console.log('is this numeric column', describeResults[i]['Type']); - - if (describeResults[i]['Key'] !== 'PRI' && this.mysql.isTypeOfColumnNumber(describeResults[i]['Type'])) { - - query = 'select min(??) as min,max(??) as max,stddev(??) as stddev,avg(??) as avg from ??'; - params = []; - - params.push(describeResults[i]['Field']); - params.push(describeResults[i]['Field']); - params.push(describeResults[i]['Field']); - params.push(describeResults[i]['Field']); - params.push(req.app.locals._tableName); - - let _this = this; - - let minMaxResults = await _this.mysql.exec(query, params); - - //console.log(minMaxResults, minMaxResults['max'], req.params); - - query = '' - params = [] - - obj = _this.mysql.getChartQueryAndParamsFromMinMaxStddev(req.app.locals._tableName, - describeResults[i]['Field'], - minMaxResults[0]['min'], - minMaxResults[0]['max'], - minMaxResults[0]['stddev'], - isRange - ) - - let r = await this.mysql.exec(obj.query, obj.params); - - let resultObj = {} - resultObj['column'] = describeResults[i]['Field'] - resultObj['chart'] = r - - results.push(resultObj); - - } - } - - res.status(200).json(results); - } - /**************** START : files related ****************/ downloadFile(req, res) { diff --git a/lib/xctrl.js b/lib/xctrl.js new file mode 100644 index 0000000000..6b81ab741a --- /dev/null +++ b/lib/xctrl.js @@ -0,0 +1,566 @@ +//define class +class xctrl { + + constructor(app,mysql) { + + this.app = app; + this.mysql = mysql; + + } + + async create(req, res) { + + let query = 'INSERT INTO ?? SET ?'; + let params = []; + + params.push(req.app.locals._tableName); + params.push(req.body); + + var results = await this.mysql.exec(query, params); + res.status(200).json(results); + + } + + + async list(req, res) { + + let queryParamsObj = {} + queryParamsObj.query = '' + queryParamsObj.params = [] + + this.mysql.prepareListQuery(req, res, queryParamsObj, 0); + + let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + res.status(200).json(results); + + } + + + async nestedList(req, res) { + + let queryParamsObj = {} + queryParamsObj.query = ''; + queryParamsObj.params = []; + + this.mysql.prepareListQuery(req, res, queryParamsObj, 1) + + let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + res.status(200).json(results); + + } + + async findOne(req, res) { + + let queryParamsObj = {} + queryParamsObj.query = '' + queryParamsObj.params = [] + + this.mysql.prepareListQuery(req, res, queryParamsObj, 2); + + let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + res.status(200).json(results); + + } + + async read(req, res) { + + let query = 'select * from ?? where '; + let params = []; + + params.push(req.app.locals._tableName); + + let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, + req.params.id.split('___')); + + + if (!clause) { + return res.status(400).send({ + error: "Table is made of composite primary keys - all keys were not in input" + }); + } + + query += clause; + query += ' LIMIT 1' + + let results = await this.mysql.exec(query, params); + res.status(200).json(results); + + + } + + async exists(req, res) { + + let query = 'select * from ?? where '; + let params = []; + + params.push(req.app.locals._tableName); + + let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, + req.params.id.split('___')); + + if (!clause) { + return res.status(400).send({ + error: "Table is made of composite primary keys - all keys were not in input" + }) + } + + query += clause; + query += ' LIMIT 1' + + let results = await this.mysql.exec(query, params); + res.status(200).json(results); + + + } + + + async update(req, res) { + + let query = 'REPLACE INTO ?? SET ?'; + let params = []; + + params.push(req.app.locals._tableName); + params.push(req.body); + + var results = await this.mysql.exec(query, params); + res.status(200).json(results); + + } + + async patch(req, res) { + + let query = 'UPDATE ?? SET '; + let keys = Object.keys(req.body); + + // SET clause + let updateKeys = ''; + for (let i = 0; i < keys.length; ++i) { + updateKeys += keys[i] + ' = ? ' + if (i !== keys.length - 1) + updateKeys += ', ' + } + + // where clause + query += updateKeys + ' where ' + let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, + req.params.id.split('___')); + + if (!clause) { + return res.status(400).send({ + error: "Table is made of composite primary keys - all keys were not in input" + }) + } + + query += clause; + + // params + let params = []; + params.push(req.app.locals._tableName); + params = params.concat(Object.values(req.body)); + + let results = await this.mysql.exec(query, params); + res.status(200).json(results); + + + } + + async delete(req, res) { + + let query = 'DELETE FROM ?? WHERE '; + let params = []; + + params.push(req.app.locals._tableName); + + let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, + req.params.id.split('___')); + + if (!clause) { + return res.status(400).send({ + error: "Table is made of composite primary keys - all keys were not in input" + }); + } + + query += clause; + + let results = await this.mysql.exec(query, params); + res.status(200).json(results); + + + } + + async bulkInsert(req, res) { + + let queryParamsObj = {} + queryParamsObj.query = '' + queryParamsObj.params = [] + let results = [] + + //console.log(req.app.locals._tableName, req.body); + + this.mysql.getBulkInsertStatement(req.app.locals._tableName, req.body, queryParamsObj) + + results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + res.status(200).json(results); + + } + + async bulkDelete(req, res) { + + let query = 'delete from ?? where ?? in '; + let params = []; + + params.push(req.app.locals._tableName); + params.push(this.mysql.getPrimaryKeyName(req.app.locals._tableName)); + + query += '(' + + if (req.query && req.query._ids) { + let ids = req.query._ids.split(',') + for (var i = 0; i < ids.length; ++i) { + if (i) { + query += ',' + } + query += '?' + params.push(ids[i]) + } + } + + query += ')' + + //console.log(query, params); + + var results = await this.mysql.exec(query, params); + res.status(200).json(results); + + } + + async bulkRead(req, res) { + + let queryParamsObj = {} + queryParamsObj.query = '' + queryParamsObj.params = [] + + this.mysql.prepareListQuery(req, res, queryParamsObj, 3); + + //console.log(queryParamsObj.query, queryParamsObj.params); + + let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + res.status(200).json(results); + + } + + + async count(req, res) { + + let queryParams = {} + + queryParams.query = 'select count(1) as no_of_rows from ?? '; + queryParams.params = []; + + queryParams.params.push(req.app.locals._tableName); + + this.mysql.getWhereClause(req.query._where, req.app.locals._tableName, queryParams, ' where ') + + let results = await this.mysql.exec(queryParams.query, queryParams.params); + res.status(200).json(results); + + } + + async distinct(req, res) { + + let queryParamsObj = {} + queryParamsObj.query = '' + queryParamsObj.params = [] + + this.mysql.prepareListQuery(req, res, queryParamsObj, 4); + + let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + res.status(200).json(results); + + } + + + async groupBy(req, res) { + + if (req.query && req.query._fields) { + + let queryParamsObj = {} + queryParamsObj.query = 'select '; + queryParamsObj.params = []; + + /**************** add columns and group by columns ****************/ + this.mysql.getColumnsForSelectStmt(req.app.locals._tableName, req.query, queryParamsObj) + + queryParamsObj.query += ',count(*) as _count from ?? group by '; + let tableName = req.app.locals._tableName; + queryParamsObj.params.push(tableName); + + this.mysql.getColumnsForSelectStmt(req.app.locals._tableName, req.query, queryParamsObj) + + if (!req.query._sort) { + req.query._sort = {} + req.query._sort = '-_count' + } + + /**************** add having clause ****************/ + this.mysql.getHavingClause(req.query._having, req.app.locals._tableName, queryParamsObj, ' having '); + + /**************** add orderby clause ****************/ + this.mysql.getOrderByClause(req.query, tableName, queryParamsObj); + + //console.log(queryParamsObj.query, queryParamsObj.params); + var results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + + res.status(200).json(results); + + } else { + res.status(400).json({message: 'Missing _fields query params eg: /api/tableName/groupby?_fields=column1'}) + } + + } + + async ugroupby(req, res) { + + if (req.query && req.query._fields) { + + let queryParamsObj = {} + queryParamsObj.query = ''; + queryParamsObj.params = []; + let uGrpByResults = {} + + /**************** add fields with count(*) *****************/ + let fields = req.query._fields.split(',') + + for (var i = 0; i < fields.length; ++i) { + + uGrpByResults[fields[i]] = [] + + if (i) { + queryParamsObj.query += ' UNION ' + } + queryParamsObj.query += ' SELECT IFNULL(CONCAT(?,?,??),?) as ugroupby, count(*) as _count from ?? GROUP BY ?? ' + queryParamsObj.params.push(fields[i]) + queryParamsObj.params.push('~') + queryParamsObj.params.push(fields[i]) + queryParamsObj.params.push(fields[i] + '~') + queryParamsObj.params.push(req.app.locals._tableName) + queryParamsObj.params.push(fields[i]) + } + + //console.log(queryParamsObj.query, queryParamsObj.params); + var results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params); + + for (var i = 0; i < results.length; ++i) { + + let grpByColName = results[i]['ugroupby'].split('~')[0] + let grpByColValue = results[i]['ugroupby'].split('~')[1] + + let obj = {} + obj[grpByColValue] = results[i]['_count']; + + uGrpByResults[grpByColName].push(obj) + + } + + res.status(200).json(uGrpByResults); + + } else { + res.status(400).json({message: 'Missing _fields query params eg: /api/tableName/ugroupby?_fields=column1,column2'}) + } + } + + + async aggregate(req, res) { + + + if (req.query && req.query._fields) { + let tableName = req.app.locals._tableName; + let query = 'select ' + let params = [] + let fields = req.query._fields.split(','); + + for (var i = 0; i < fields.length; ++i) { + if (i) { + query = query + ',' + } + query = query + ' min(??) as ?,max(??) as ?,avg(??) as ?,sum(??) as ?,stddev(??) as ?,variance(??) as ? ' + params.push(fields[i]); + params.push('min_of_' + fields[i]); + params.push(fields[i]); + params.push('max_of_' + fields[i]); + params.push(fields[i]); + params.push('avg_of_' + fields[i]); + params.push(fields[i]); + params.push('sum_of_' + fields[i]); + params.push(fields[i]); + params.push('stddev_of_' + fields[i]); + params.push(fields[i]); + params.push('variance_of_' + fields[i]); + } + + query = query + ' from ??' + params.push(tableName) + + var results = await this.mysql.exec(query, params); + + res.status(200).json(results); + } else { + res.status(400).json({message: 'Missing _fields in query params eg: /api/tableName/aggregate?_fields=numericColumn1'}); + } + + } + + + async chart(req, res) { + + let query = '' + let params = [] + let obj = {} + + + if (req.query) { + + let isRange = false + if (req.query.range) { + isRange = true + } + + if (req.query && req.query.min && req.query.max && req.query.step) { + + //console.log(req.params.min, req.params.max, req.params.step); + + obj = this.mysql.getChartQueryAndParamsFromMinMaxStep(req.app.locals._tableName, + req.query._fields, + parseInt(req.query.min), + parseInt(req.query.max), + parseInt(req.query.step), + isRange) + + + } else if (req.query && req.query.steparray && req.query.steparray.length > 1) { + + obj = this.mysql.getChartQueryAndParamsFromStepArray(req.app.locals._tableName, + req.query._fields, + (req.query.steparray.split(',')).map(Number), + isRange) + + + } else if (req.query && req.query.steppair && req.query.steppair.length > 1) { + + obj = this.mysql.getChartQueryAndParamsFromStepPair(req.app.locals._tableName, + req.query._fields, + (req.query.steppair.split(',')).map(Number), + false) + + + } else { + + query = 'select min(??) as min,max(??) as max,stddev(??) as stddev,avg(??) as avg from ??'; + params = []; + + params.push(req.query._fields); + params.push(req.query._fields); + params.push(req.query._fields); + params.push(req.query._fields); + params.push(req.app.locals._tableName); + + let _this = this; + + let results = await + _this.mysql.exec(query, params); + + //console.log(results, results['max'], req.params); + + obj = _this.mysql.getChartQueryAndParamsFromMinMaxStddev(req.app.locals._tableName, + req.query._fields, + results[0]['min'], + results[0]['max'], + results[0]['stddev'], + isRange + ) + + } + + this.mysql.getWhereClause(req.query._where, req.app.locals._tableName, obj, ' where ') + + let results = await + this.mysql.exec(obj.query, obj.params); + + res.status(200).json(results); + + } else { + res.status(400).json({message: 'Missing _fields in query params eg: /api/tableName/chart?_fields=numericColumn1'}); + } + + + } + + + async autoChart(req, res) { + + let query = 'describe ??' + let params = [req.app.locals._tableName] + let obj = {} + let results = [] + + let isRange = false + if (req.query.range) { + isRange = true + } + + + let describeResults = await this.mysql.exec(query, params) + + //console.log(describeResults); + + for (var i = 0; i < describeResults.length; ++i) { + + //console.log('is this numeric column', describeResults[i]['Type']); + + if (describeResults[i]['Key'] !== 'PRI' && this.mysql.isTypeOfColumnNumber(describeResults[i]['Type'])) { + + query = 'select min(??) as min,max(??) as max,stddev(??) as stddev,avg(??) as avg from ??'; + params = []; + + params.push(describeResults[i]['Field']); + params.push(describeResults[i]['Field']); + params.push(describeResults[i]['Field']); + params.push(describeResults[i]['Field']); + params.push(req.app.locals._tableName); + + let _this = this; + + let minMaxResults = await _this.mysql.exec(query, params); + + //console.log(minMaxResults, minMaxResults['max'], req.params); + + query = '' + params = [] + + obj = _this.mysql.getChartQueryAndParamsFromMinMaxStddev(req.app.locals._tableName, + describeResults[i]['Field'], + minMaxResults[0]['min'], + minMaxResults[0]['max'], + minMaxResults[0]['stddev'], + isRange + ) + + let r = await this.mysql.exec(obj.query, obj.params); + + let resultObj = {} + resultObj['column'] = describeResults[i]['Field'] + resultObj['chart'] = r + + results.push(resultObj); + + } + } + + res.status(200).json(results); + } + + +} + +//expose class +module.exports = xctrl; \ No newline at end of file