|
|
@ -18,6 +18,7 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
this.mysql.init((err, results) => { |
|
|
|
this.mysql.init((err, results) => { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.app.use(this.urlMiddleware) |
|
|
|
this.setupRoutes() |
|
|
|
this.setupRoutes() |
|
|
|
this.app.use(this.errorMiddleware) |
|
|
|
this.app.use(this.errorMiddleware) |
|
|
|
cbk(err, results) |
|
|
|
cbk(err, results) |
|
|
@ -26,9 +27,27 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
urlMiddleware(req, res, next) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let justUrl = req.originalUrl.split('?')[0] |
|
|
|
|
|
|
|
let pathSplit = justUrl.split('/') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pathSplit.length >= 2 && pathSplit[1] === 'api') { |
|
|
|
|
|
|
|
if (pathSplit.length >= 5) { |
|
|
|
|
|
|
|
req.app.locals._parentTable = pathSplit[2] |
|
|
|
|
|
|
|
req.app.locals._childTable = pathSplit[4] |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
req.app.locals._tableName = pathSplit[2] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
next(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
errorMiddleware(err, req, res, next) { |
|
|
|
errorMiddleware(err, req, res, next) { |
|
|
|
|
|
|
|
|
|
|
|
if(err && err.code) |
|
|
|
if (err && err.code) |
|
|
|
res.status(400).json({error: err}); |
|
|
|
res.status(400).json({error: err}); |
|
|
|
else |
|
|
|
else |
|
|
|
res.status(500).json({error: 'Internal server error : ' + err.message}); |
|
|
|
res.status(500).json({error: 'Internal server error : ' + err.message}); |
|
|
@ -47,10 +66,8 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
root(req, res) { |
|
|
|
root(req, res) { |
|
|
|
|
|
|
|
|
|
|
|
//res.sendFile(path + "index.html")
|
|
|
|
|
|
|
|
let v = []; |
|
|
|
let v = []; |
|
|
|
|
|
|
|
v = this.mysql.getSchemaRoutes(false, req.protocol + '://' + req.get('host') + '/api/'); |
|
|
|
v = this.mysql.getSchemaRoutes(req.protocol + '://' + req.get('host') + '/api/'); |
|
|
|
|
|
|
|
v = v.concat(this.mysql.globalRoutesPrint(req.protocol + '://' + req.get('host') + '/api/')) |
|
|
|
v = v.concat(this.mysql.globalRoutesPrint(req.protocol + '://' + req.get('host') + '/api/')) |
|
|
|
|
|
|
|
|
|
|
|
res.json(v) |
|
|
|
res.json(v) |
|
|
@ -59,36 +76,96 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
setupRoutes() { |
|
|
|
setupRoutes() { |
|
|
|
|
|
|
|
|
|
|
|
this.app.get('/', this.asyncMiddleware(this.root.bind(this))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************** START : tables apis ****************/ |
|
|
|
this.app.get('/', this.asyncMiddleware(this.root.bind(this))) |
|
|
|
this.app.route('/api/tables') |
|
|
|
this.app.route('/api/tables') |
|
|
|
.get(this.asyncMiddleware(this.tables.bind(this))); |
|
|
|
.get(this.asyncMiddleware(this.tables.bind(this))); |
|
|
|
|
|
|
|
|
|
|
|
this.app.route('/api/:tableName/describe') |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.tableDescribe.bind(this))); |
|
|
|
|
|
|
|
/**************** END : tables apis ****************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let resources = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resources = this.mysql.getSchemaRoutes(true, '/api/'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (var j = 0; j < resources.length; ++j) { |
|
|
|
|
|
|
|
|
|
|
|
/**************** START : basic apis ****************/ |
|
|
|
let routes = resources[j]['routes']; |
|
|
|
this.app.route('/api/:tableName/count') |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.count.bind(this))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.app.route('/api/:tableName') |
|
|
|
for (var i = 0; i < routes.length; ++i) { |
|
|
|
.get(this.asyncMiddleware(this.list.bind(this))) |
|
|
|
|
|
|
|
.post(this.asyncMiddleware(this.create.bind(this))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.app.route('/api/:tableName/:id') |
|
|
|
switch (routes[i]['routeType']) { |
|
|
|
.get(this.asyncMiddleware(this.read.bind(this))) |
|
|
|
|
|
|
|
.put(this.asyncMiddleware(this.update.bind(this))) |
|
|
|
case 'list': |
|
|
|
.delete(this.asyncMiddleware(this.delete.bind(this))); |
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.list.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'create': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.post(this.asyncMiddleware(this.create.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'read': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.read.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'update': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.put(this.asyncMiddleware(this.update.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'delete': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.delete(this.asyncMiddleware(this.delete.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'exists': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.exists.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'count': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.count.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'describe': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.tableDescribe.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'relational': |
|
|
|
|
|
|
|
this.app.route(routes[i]['routeUrl']) |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.nestedList.bind(this))); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.app.route('/api/:tableName/:id/exists') |
|
|
|
|
|
|
|
.get(this.asyncMiddleware(this.exists.bind(this))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.app.route('/api/:parentTable/:id/:childTable') |
|
|
|
// this.app.route('/api/:tableName/describe')
|
|
|
|
.get(this.asyncMiddleware(this.nestedList.bind(this))); |
|
|
|
// .get(this.asyncMiddleware(this.tableDescribe.bind(this)));
|
|
|
|
/**************** END : basic apis ****************/ |
|
|
|
//
|
|
|
|
|
|
|
|
// /**************** START : basic apis ****************/
|
|
|
|
|
|
|
|
// this.app.route('/api/:tableName/count')
|
|
|
|
|
|
|
|
// .get(this.asyncMiddleware(this.count.bind(this)));
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// this.app.route('/api/:tableName')
|
|
|
|
|
|
|
|
// .get(this.asyncMiddleware(this.list.bind(this)))
|
|
|
|
|
|
|
|
// .post(this.asyncMiddleware(this.create.bind(this)));
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// this.app.route('/api/:tableName/:id')
|
|
|
|
|
|
|
|
// .get(this.asyncMiddleware(this.read.bind(this)))
|
|
|
|
|
|
|
|
// .put(this.asyncMiddleware(this.update.bind(this)))
|
|
|
|
|
|
|
|
// .delete(this.asyncMiddleware(this.delete.bind(this)));
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// this.app.route('/api/:tableName/:id/exists')
|
|
|
|
|
|
|
|
// .get(this.asyncMiddleware(this.exists.bind(this)));
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// this.app.route('/api/:parentTable/:id/:childTable')
|
|
|
|
|
|
|
|
// .get(this.asyncMiddleware(this.nestedList.bind(this)));
|
|
|
|
|
|
|
|
// /**************** END : basic apis ****************/
|
|
|
|
|
|
|
|
|
|
|
|
if (this.sqlConfig.dynamic === 1) { |
|
|
|
if (this.sqlConfig.dynamic === 1) { |
|
|
|
|
|
|
|
|
|
|
@ -104,7 +181,7 @@ class Xapi { |
|
|
|
let query = 'INSERT INTO ?? SET ?'; |
|
|
|
let query = 'INSERT INTO ?? SET ?'; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
|
|
|
|
|
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
params.push(req.body); |
|
|
|
params.push(req.body); |
|
|
|
|
|
|
|
|
|
|
|
var results = await this.mysql.exec(query, params); |
|
|
|
var results = await this.mysql.exec(query, params); |
|
|
@ -114,12 +191,12 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
async list(req, res) { |
|
|
|
async list(req, res) { |
|
|
|
|
|
|
|
|
|
|
|
let cols = this.mysql.getColumnsForSelectStmt(req.params.tableName, req.query); |
|
|
|
let cols = this.mysql.getColumnsForSelectStmt(req.app.locals._tableName, req.query); |
|
|
|
let query = 'select ' + cols + ' from ?? '; |
|
|
|
let query = 'select ' + cols + ' from ?? '; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
|
|
|
|
|
|
|
|
query = query + this.mysql.getOrderByClause(req.query, req.params.tableName); |
|
|
|
query = query + this.mysql.getOrderByClause(req.query, req.app.locals._tableName); |
|
|
|
|
|
|
|
|
|
|
|
query = query + ' limit ?,? ' |
|
|
|
query = query + ' limit ?,? ' |
|
|
|
params = params.concat(this.mysql.getLimitClause(req.query)); |
|
|
|
params = params.concat(this.mysql.getLimitClause(req.query)); |
|
|
@ -131,15 +208,15 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
async nestedList(req, res) { |
|
|
|
async nestedList(req, res) { |
|
|
|
|
|
|
|
|
|
|
|
let cols = this.mysql.getColumnsForSelectStmt(req.params.childTable, req.query); |
|
|
|
let cols = this.mysql.getColumnsForSelectStmt(req.app.locals._childTable, req.query); |
|
|
|
let query = 'select ' + cols + ' from ?? where '; |
|
|
|
let query = 'select ' + cols + ' from ?? where '; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
|
|
|
|
|
|
|
|
params.push(req.params.childTable); |
|
|
|
params.push(req.app.locals._childTable); |
|
|
|
|
|
|
|
|
|
|
|
let whereClause = this.mysql.getForeignKeyWhereClause(req.params.parentTable, |
|
|
|
let whereClause = this.mysql.getForeignKeyWhereClause(req.app.locals._parentTable, |
|
|
|
req.params.id, |
|
|
|
req.params.id, |
|
|
|
req.params.childTable); |
|
|
|
req.app.locals._childTable); |
|
|
|
|
|
|
|
|
|
|
|
if (!whereClause) { |
|
|
|
if (!whereClause) { |
|
|
|
return res.status(400).send({ |
|
|
|
return res.status(400).send({ |
|
|
@ -149,7 +226,7 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
query += whereClause; |
|
|
|
query += whereClause; |
|
|
|
|
|
|
|
|
|
|
|
query = query + this.mysql.getOrderByClause(req.query, req.params.parentTable); |
|
|
|
query = query + this.mysql.getOrderByClause(req.query, req.app.locals._parentTable); |
|
|
|
|
|
|
|
|
|
|
|
query = query + ' limit ?,? ' |
|
|
|
query = query + ' limit ?,? ' |
|
|
|
params = params.concat(this.mysql.getLimitClause(req.query)); |
|
|
|
params = params.concat(this.mysql.getLimitClause(req.query)); |
|
|
@ -164,9 +241,9 @@ class Xapi { |
|
|
|
let query = 'select * from ?? where '; |
|
|
|
let query = 'select * from ?? where '; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
|
|
|
|
|
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
|
|
|
|
|
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, |
|
|
|
req.params.id.split('___')); |
|
|
|
req.params.id.split('___')); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -190,9 +267,9 @@ class Xapi { |
|
|
|
let query = 'select * from ?? where '; |
|
|
|
let query = 'select * from ?? where '; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
|
|
|
|
|
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
|
|
|
|
|
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, |
|
|
|
req.params.id.split('___')); |
|
|
|
req.params.id.split('___')); |
|
|
|
|
|
|
|
|
|
|
|
if (!clause) { |
|
|
|
if (!clause) { |
|
|
@ -225,7 +302,7 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
// where clause
|
|
|
|
// where clause
|
|
|
|
query += updateKeys + ' where ' |
|
|
|
query += updateKeys + ' where ' |
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, |
|
|
|
req.params.id.split('___')); |
|
|
|
req.params.id.split('___')); |
|
|
|
|
|
|
|
|
|
|
|
if (!clause) { |
|
|
|
if (!clause) { |
|
|
@ -238,7 +315,7 @@ class Xapi { |
|
|
|
|
|
|
|
|
|
|
|
// params
|
|
|
|
// params
|
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
params = params.concat(Object.values(req.body)); |
|
|
|
params = params.concat(Object.values(req.body)); |
|
|
|
|
|
|
|
|
|
|
|
let results = await this.mysql.exec(query, params); |
|
|
|
let results = await this.mysql.exec(query, params); |
|
|
@ -252,9 +329,9 @@ class Xapi { |
|
|
|
let query = 'DELETE FROM ?? WHERE '; |
|
|
|
let query = 'DELETE FROM ?? WHERE '; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
|
|
|
|
|
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
|
|
|
|
|
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.params.tableName, |
|
|
|
let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName, |
|
|
|
req.params.id.split('___')); |
|
|
|
req.params.id.split('___')); |
|
|
|
|
|
|
|
|
|
|
|
if (!clause) { |
|
|
|
if (!clause) { |
|
|
@ -276,7 +353,7 @@ class Xapi { |
|
|
|
let query = 'select count(1) as no_of_rows from ??'; |
|
|
|
let query = 'select count(1) as no_of_rows from ??'; |
|
|
|
let params = []; |
|
|
|
let params = []; |
|
|
|
|
|
|
|
|
|
|
|
params.push(req.params.tableName); |
|
|
|
params.push(req.app.locals._tableName); |
|
|
|
|
|
|
|
|
|
|
|
let results = await this.mysql.exec(query, params); |
|
|
|
let results = await this.mysql.exec(query, params); |
|
|
|
res.status(200).json(results); |
|
|
|
res.status(200).json(results); |
|
|
@ -308,7 +385,7 @@ class Xapi { |
|
|
|
async tableDescribe(req, res) { |
|
|
|
async tableDescribe(req, res) { |
|
|
|
|
|
|
|
|
|
|
|
let query = 'describe ??'; |
|
|
|
let query = 'describe ??'; |
|
|
|
let params = [req.params.tableName]; |
|
|
|
let params = [req.app.locals._tableName]; |
|
|
|
|
|
|
|
|
|
|
|
let results = await this.mysql.exec(query, params); |
|
|
|
let results = await this.mysql.exec(query, params); |
|
|
|
res.status(200).json(results); |
|
|
|
res.status(200).json(results); |
|
|
|