diff --git a/README.md b/README.md index 5153dcd83d..498549123b 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ That's it! * Pagination * Sorting * Fields +* Group By +* Group By, Order By * Relations * Run dynamic queries @@ -135,6 +137,35 @@ eg: gets only customerNumber and checkNumber in response of each record ``` eg: gets all fields in table row but not checkNumber +## Group By + +``` +/api/offices/groupby?_fields=country +``` +eg: SELECT country,count(*) FROM offices GROUP BY country + +``` +/api/offices/groupby?_fields=country,city +``` +eg: SELECT country,city,count(*) FROM offices GROUP BY country,city + +## Group By, Order By + +``` +/api/offices/groupby?_fields=country,city&sort=city +``` +eg: SELECT country,city,count(*) FROM offices GROUP BY country,city ORDER BY city ASC + +``` +/api/offices/groupby?_fields=country,city&sort=city,country +``` +eg: SELECT country,city,count(*) FROM offices GROUP BY country,city ORDER BY city ASC, country ASC + +``` +/api/offices/groupby?_fields=country,city&sort=city,-country +``` +eg: SELECT country,city,count(*) FROM offices GROUP BY country,city ORDER BY city ASC, country DESC + ## Run dynamic queries Dynamic queries on a database can be run by POST method to URL localhost:3000/dynamic diff --git a/lib/xapi.js b/lib/xapi.js index 55c102f107..c17aa7e633 100644 --- a/lib/xapi.js +++ b/lib/xapi.js @@ -146,6 +146,11 @@ class Xapi { .get(this.asyncMiddleware(this.nestedList.bind(this))); break; + case 'groupby': + this.app.route(routes[i]['routeUrl']) + .get(this.asyncMiddleware(this.groupBy.bind(this))); + break; + } } } @@ -376,6 +381,27 @@ class Xapi { } + async groupBy(req, res) { + + let query = 'select ' + req.query._fields + ',count(*) as count from ?? group by ' + req.query._fields; + let params = []; + let tableName = req.app.locals._tableName; + + params.push(tableName); + + if (!req.query.sort) { + req.query._sort = {} + req.query._sort = '-count' + } + + query = query + this.mysql.getOrderByClause(req.query, tableName); + + var results = await this.mysql.exec(query, params); + + res.status(200).json(results); + + } + } diff --git a/lib/xsql.js b/lib/xsql.js index 34ae875cc9..05cf8b6d92 100644 --- a/lib/xsql.js +++ b/lib/xsql.js @@ -390,6 +390,7 @@ class Xsql { routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/describe', 'describe')) 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, 'post', apiPrefix, tableName, 'create')) routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName, 'list')) routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/:id', 'read')) diff --git a/tests/tests.js b/tests/tests.js index 7189d04b32..94bb7d3725 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -17,7 +17,7 @@ var mysqlPool = {} args['host'] = 'localhost' args['user'] = 'root' -args['password'] = '' +args['password'] = 'madurga' args['database'] = 'classicmodels' @@ -638,5 +638,67 @@ describe('xmysql : tests', function () { }); }); + it('GET /api/customers/groupby?_fields=city&_sort=city should PASS', function (done) { + + //post to an url with data + agent.get('/api/customers/groupby?_fields=city&_sort=city') //enter url + .expect(200)//200 for success 4xx for failure + .end(function (err, res) { + // Handle /api/v error + if (err) { + return done(err); + } + + //validate response + res.body[0]['city'].should.be.equals("NYC") + res.body.length.should.be.equals(95) + + return done(); + + }); + }); + + it('GET /api/offices/groupby?_fields=country should PASS', function (done) { + + //post to an url with data + agent.get('/api/offices/groupby?_fields=country') //enter url + .expect(200)//200 for success 4xx for failure + .end(function (err, res) { + // Handle /api/v error + if (err) { + return done(err); + } + + //validate response + res.body[0]['country'].should.be.equals("USA") + res.body.length.should.be.equals(5) + + return done(); + + }); + }); + + + it('GET /api/offices/groupby?_fields=country,city&sort=city,-country should PASS', function (done) { + + //post to an url with data + agent.get('/api/offices/groupby?_fields=country,city&sort=city,-country') //enter url + .expect(200)//200 for success 4xx for failure + .end(function (err, res) { + // Handle /api/v error + if (err) { + return done(err); + } + + //validate response + res.body[0]['country'].should.be.equals("Australia") + res.body[0]['city'].should.be.equals("Sydney") + res.body.length.should.be.equals(7) + + return done(); + + }); + }); + });