Browse Source

Features : adding findOne api v0.2.0

pull/13/head
oof1lab 7 years ago
parent
commit
a5410c0137
  1. 23
      README.md
  2. 6
      index.js
  3. 2
      lib/util/cmd.helper.js
  4. 54
      lib/xapi.js
  5. 1
      lib/xsql.js
  6. 2
      package.json
  7. 25
      tests/tests.js

23
README.md

@ -79,8 +79,9 @@ Root URL (localhost:3000/) returns all REST API urls for each table in schema.
* POST      /api/tableName
* GET       /api/tableName/:id
* PUT       /api/tableName/:id
* GET       /api/tableName/findOne
* GET       /api/tableName/count
* GET       /api/tableName/exists
* GET       /api/tableName/:id/exists
* GET       /api/tableName/groupby
* GET       /api/tableName/aggregate
* GET       /api/parentTable/:id/childTable
@ -208,6 +209,26 @@ eg: filter of rows using _where is available for relational route URLs too.
/api/offices/1/employees?_where=(jobTitle,eq,Sales%20Rep)
```
## FindOne
```
/api/tableName/findOne?_where=(id,eq,1)
```
Works similar to list but only returns top/one result. Used in conjunction with _where
## Count
```
/api/tableName/count
```
Returns number of rows in table
## Exists
```
/api/tableName/1/exists
```
Returns true or false depending on whether record exists
## Group By, Having (as query params)

6
index.js

@ -31,7 +31,9 @@ let mysqlPool = mysql.createPool(sqlConfig);
/**************** START : setup Xapi ****************/
console.log('');
console.log(' REST APIs at the speed of thought.. ');
console.log('');
console.log('');
console.log(' Generating REST APIs at the speed of your thought.. ');
console.log('');
let t = process.hrtime();
@ -43,7 +45,7 @@ moreApis.init((err, results) => {
var t1 = process.hrtime(t);
var t2 = t1[0]+t1[1]/1000000000
console.log(' ');
console.log(" Xmysql took : %d seconds",dataHelp.round(t2,1));
console.log(' ');
console.log(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ');

2
lib/util/cmd.helper.js

@ -11,7 +11,7 @@ program.on('--help', () => {
})
program
.version('0.1.9')
.version('0.2.0')
.option('-h, --host <n>', 'hostname')
.option('-d, --database <n>', 'database schema name')
.option('-u, --user <n>', 'username of database / root by default')

54
lib/xapi.js

@ -135,6 +135,11 @@ class Xapi {
.get(this.asyncMiddleware(this.list.bind(this)));
break;
case 'findOne':
this.app.route(routes[i]['routeUrl'])
.get(this.asyncMiddleware(this.findOne.bind(this)));
break;
case 'create':
this.app.route(routes[i]['routeUrl'])
.post(this.asyncMiddleware(this.create.bind(this)));
@ -211,12 +216,11 @@ class Xapi {
console.log(' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ');
console.log(' ');
console.log(' Database : %s',this.config.database);
console.log(' Number of resources : %s',stat.tables);
console.log(' Database : %s', this.config.database);
console.log(' Number of resources : %s', stat.tables);
console.log(' ');
console.log(' REST APIs Generated : %s'.green.bold,stat.apis );
console.log(' REST APIs Generated : %s'.green.bold, stat.apis);
console.log(' ');
return stat
}
@ -233,7 +237,16 @@ class Xapi {
}
prepareListQuery(req, res, queryParamsObj, nested = false) {
/**
*
* @param req
* @param res
* @param queryParamsObj : {query, params}
* @param listType : 0:list, 1:nested, 2:findOne
*
* Updates query, params for query of type listType
*/
prepareListQuery(req, res, queryParamsObj, listType = 0) {
queryParamsObj.query = 'select ';
queryParamsObj.params = [];
@ -248,7 +261,7 @@ class Xapi {
/**************** add tableName ****************/
queryParamsObj.query += ' from ?? ';
if (nested) {
if (listType === 1) {
req.app.locals._tableName = req.app.locals._childTable;
@ -289,8 +302,12 @@ class Xapi {
this.mysql.getOrderByClause(req.query, req.app.locals._tableName, queryParamsObj);
/**************** add limit clause ****************/
queryParamsObj.query += ' limit ?,? '
queryParamsObj.params = queryParamsObj.params.concat(this.mysql.getLimitClause(req.query));
if (listType === 2) {
queryParamsObj.query += ' limit 1 '
} else {
queryParamsObj.query += ' limit ?,? '
queryParamsObj.params = queryParamsObj.params.concat(this.mysql.getLimitClause(req.query));
}
//console.log(queryParamsObj.query, queryParamsObj.params);
@ -302,7 +319,7 @@ class Xapi {
queryParamsObj.query = ''
queryParamsObj.params = []
this.prepareListQuery(req, res, queryParamsObj, false);
this.prepareListQuery(req, res, queryParamsObj, 0);
let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params);
res.status(200).json(results);
@ -315,7 +332,20 @@ class Xapi {
queryParamsObj.query = '';
queryParamsObj.params = [];
this.prepareListQuery(req, res, queryParamsObj, true)
this.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.prepareListQuery(req, res, queryParamsObj, 2);
let results = await this.mysql.exec(queryParamsObj.query, queryParamsObj.params);
res.status(200).json(results);
@ -488,13 +518,13 @@ class Xapi {
queryParamsObj.params = [];
/**************** add columns and group by columns ****************/
this.mysql.getColumnsForSelectStmt(req.app.locals._tableName,req.query,queryParamsObj)
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)
this.mysql.getColumnsForSelectStmt(req.app.locals._tableName, req.query, queryParamsObj)
if (!req.query._sort) {
req.query._sort = {}

1
lib/xsql.js

@ -457,6 +457,7 @@ class Xsql {
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/count', 'count'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/groupby', 'groupby'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/aggregate', 'aggregate'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/findOne', 'findOne'))
routes.push(this.prepareRoute(internal, 'post', apiPrefix, tableName, 'create'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName, 'list'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/:id', 'read'))

2
package.json

@ -1,6 +1,6 @@
{
"name": "xmysql",
"version": "0.1.9",
"version": "0.2.0",
"description": "One command to generate REST APIs for any MySql database",
"main": "index.js",
"scripts": {

25
tests/tests.js

@ -332,6 +332,30 @@ describe('xmysql : tests', function () {
});
it('GET /api/customers/findOne?_where=(customerNumber,eq,119) should PASS', function (done) {
//http get an url
agent.get('/api/customers/findOne?_where=(customerNumber,eq,119)') // api url
.expect(200) // 2xx for success and 4xx for failure
.end(function (err, res) {
// Handle /api/offices/1/employees error
if (err) {
return done(err);
}
// tate is an invalid column but still it should query right number of columns
res.body.length.should.be.equal(1)
res.body[0]['customerNumber'].should.be.equal(119)
return done();
});
});
it('GET /api/offices?_fields=-territory,-addressLine2,-state,-tate should PASS', function (done) {
//http get an url
@ -1299,6 +1323,7 @@ describe('xmysql : tests', function () {
//
// it('GET http://localhost:3000/api/customers/groupby?_fields=city,country&_having=(customerNumber,lt,110) should PASS', function (done) {
//

Loading…
Cancel
Save