Browse Source

Feature : adding 'range' option to Chart API npm v0.3.1

pull/13/head
oof1lab 7 years ago
parent
commit
bf95f02c75
  1. 55
      README.md
  2. 2
      lib/util/cmd.helper.js
  3. 4
      lib/util/data.helper.js
  4. 20
      lib/xapi.js
  5. 31
      lib/xsql.js
  6. 2
      package.json
  7. 68
      tests/tests.js

55
README.md

@ -73,7 +73,7 @@ Powered by popular node packages : ([express](https://github.com/expressjs/expre
* Group By, Having (as query params) :fire::fire:
* Group By, Having (as a separate API) :fire::fire:
* Multiple group by in one API :fire::fire:
* Chart API for numeric column :fire::fire:
* Chart API for numeric column :fire::fire::fire::fire::fire::fire:
* Supports views
* Prototyping (features available when using local MySql server only)
* Run dynamic queries :fire::fire::fire:
@ -431,11 +431,11 @@ response body
## Chart
[:arrow_heading_up:](#api-overview)
:fire::fire: **[ HOTNESS ALERT ]**
:fire::fire::fire::fire::fire::fire: **[ HOTNESS ALERT ]**
Chart API returns distribution of a numeric column in a table
It comes in three flavours
It comes in **SIX** powerful flavours
1. Chart : With min, max, step in query params :fire::fire:
[:arrow_heading_up:](#api-overview)
@ -550,6 +550,55 @@ Response
```
4. Chart : With min, max, step in query params :fire::fire:
[:arrow_heading_up:](#api-overview)
This API returns the number of rows where amount is between (0,25000), (0,50000) ... (0,maxValue)
Number of records for amount is calculated everytime from min value to extended Range instead of incremental steps
```
/api/payments/chart?_fields=amount&min=0&max=131000&step=25000&range=1
Response
[
{
"amount": "0 to 25000",
"_count": 107
},
{
"amount": "0 to 50000",
"_count": 231
},
{
"amount": "0 to 75000",
"_count": 261
},
{
"amount": "0 to 100000",
"_count": 268
},
{
"amount": "0 to 125000",
"_count": 273
}
]
```
5. Range can be specified to other variations of chart operation #2 and #3 like below
```
/api/payments/chart?_fields=amount&steparray=0,10000,20000,70000,140000
```
6.
```
/api/payments/chart?_fields=amount&range=1
```
Please Note:
_fields in Chart API can only take numeric column as its argument.

2
lib/util/cmd.helper.js

@ -11,7 +11,7 @@ program.on('--help', () => {
})
program
.version('0.3.0')
.version('0.3.1')
.option('-h, --host <n>', 'hostname / localhost by default')
.option('-u, --user <n>', 'username of database / root by default')
.option('-p, --password <n>', 'password of database / empty by default')

4
lib/util/data.helper.js

@ -66,7 +66,7 @@ exports.numberGetFixed = (number) => {
return parseInt(number.toFixed())
}
exports.getRangeSimple = function (min, max, step) {
exports.getStepArraySimple = function (min, max, step) {
var arr = []
for (var i = min; i <= max; i = i + step) {
@ -77,7 +77,7 @@ exports.getRangeSimple = function (min, max, step) {
};
exports.getRange = (min, max, stddev) => {
exports.getStepArray = (min, max, stddev) => {
// console.log(' = = = = = = = ');
//console.log('original numbers', min, max, stddev);

20
lib/xapi.js

@ -772,7 +772,16 @@ class Xapi {
let params = []
let obj = {}
if (req.query && req.query._fields) {
if (req.query) {
let isRange = false
if (req.query.range) {
isRange = true
}
if (req.query && req.query.min && req.query.max && req.query.step) {
@ -782,14 +791,16 @@ class Xapi {
req.query._fields,
parseInt(req.query.min),
parseInt(req.query.max),
parseInt(req.query.step))
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))
(req.query.steparray.split(',')).map(Number),
isRange)
} else {
@ -814,7 +825,8 @@ class Xapi {
req.query._fields,
results[0]['min'],
results[0]['max'],
results[0]['stddev']
results[0]['stddev'],
isRange
)
}

31
lib/xsql.js

@ -592,16 +592,16 @@ class Xsql {
}
getChartQueryAndParamsFromStepArray(tableName, columnName, stepArray) {
getChartQueryAndParamsFromStepArray(tableName, columnName, stepArray, isRange = false) {
let obj = {}
obj.query = ''
obj.params = []
if (stepArray.length && stepArray.length >= 2) {
//console.log('getChartQueryAndParamsFromStepArray',isRange);
let params = [tableName, columnName, stepArray[0], stepArray[1]]
if (stepArray.length && stepArray.length >= 2) {
for (let i = 0; i < stepArray.length - 1; i = i + 1) {
@ -610,16 +610,27 @@ class Xsql {
obj.query = obj.query + ' union '
}
if (i) {
if (i && isRange === false) {
stepArray[i] = stepArray[i] + 1
}
if (isRange === false) {
obj.params.push((stepArray[i]) + ' to ' + stepArray[i + 1])
} else {
obj.params.push((stepArray[0]) + ' to ' + stepArray[i + 1])
}
obj.params.push(columnName)
obj.params.push(tableName)
obj.params.push(columnName)
if (isRange === false) {
obj.params.push(stepArray[i])
obj.params.push(stepArray[i + 1])
} else {
obj.params.push(stepArray[0])
obj.params.push(stepArray[i + 1])
}
}
@ -632,13 +643,13 @@ class Xsql {
}
getChartQueryAndParamsFromMinMaxStddev(tableName, columnName, min, max, stddev) {
getChartQueryAndParamsFromMinMaxStddev(tableName, columnName, min, max, stddev, isRange = false) {
let stepArray = dataHelp.getRange(min, max, stddev)
let stepArray = dataHelp.getStepArray(min, max, stddev)
//console.log('steparray', stepArray);
let obj = this.getChartQueryAndParamsFromStepArray(tableName, columnName, stepArray)
let obj = this.getChartQueryAndParamsFromStepArray(tableName, columnName, stepArray, isRange)
//console.log('steparray', obj);
@ -646,13 +657,13 @@ class Xsql {
}
getChartQueryAndParamsFromMinMaxStep(tableName, columnName, min, max, step) {
getChartQueryAndParamsFromMinMaxStep(tableName, columnName, min, max, step, isRange = false) {
let stepArray = dataHelp.getRangeSimple(min, max, step)
let stepArray = dataHelp.getStepArraySimple(min, max, step)
//console.log('steparray', stepArray);
let obj = this.getChartQueryAndParamsFromStepArray(tableName, columnName, stepArray)
let obj = this.getChartQueryAndParamsFromStepArray(tableName, columnName, stepArray, isRange)
//console.log('steparray', obj);

2
package.json

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

68
tests/tests.js

@ -783,7 +783,8 @@ describe('xmysql : tests', function () {
});
});
// something weird going on
// SOMETHING WEIRD HERE
// test in travis show 7 but on local machine result has 6 elements
// it('GET /api/productlines?_where=(htmlDescription,is,null) should PASS', function (done) {
//
// //post to an url with data
@ -1203,6 +1204,28 @@ describe('xmysql : tests', function () {
});
})
it('GET /api/payments/chart?_fields=amount&min=0&max=131000&step=25000&range=1 should PASS', function (done) {
//post to an url with data
agent.get('/api/payments/chart?_fields=amount&min=0&max=131000&step=25000&range=1') //enter url
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
res.body.length.should.be.equals(5)
res.body[4]['_count'].should.be.equals(273)
res.body[1]['_count'].should.be.equals(231)
res.body[0]['_count'].should.be.equals(107)
return done();
});
})
it('GET /api/payments/chart?_fields=amount&steparray=0,50000,100000,140000 should PASS', function (done) {
//post to an url with data
@ -1224,6 +1247,47 @@ describe('xmysql : tests', function () {
});
})
it('GET /api/payments/chart?_fields=amount&steparray=0,50000,100000,140000&range=1 should PASS', function (done) {
//post to an url with data
agent.get('/api/payments/chart?_fields=amount&steparray=0,50000,100000,140000&range=1') //enter url
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
res.body.length.should.be.equals(3)
res.body[0]['_count'].should.be.equals(231)
res.body[1]['_count'].should.be.equals(268)
res.body[2]['_count'].should.be.equals(273)
return done();
});
})
it('GET /api/payments/chart?_fields=amount&range=1 should PASS', function (done) {
//post to an url with data
agent.get('/api/payments/chart?_fields=amount&range=1') //enter url
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
res.body.length.should.be.equals(7)
res.body[0]['_count'].should.be.equals(45)
res.body[6]['_count'].should.be.equals(273)
return done();
});
})
it('GET /api/offices/1/employees?_groupby=jobTitle&_having=(_count,gt,1) should PASS', function (done) {
//post to an url with data
@ -1823,8 +1887,6 @@ describe('xmysql : tests', function () {
var err = whereClause.getConditionClause('(a,is,null)~and(b,is,true)~and(c,is,false)')
//console.log(err.params[1],err);
err.err.should.be.equal(0)
err.query.should.be.equal('(?? is ?)and(?? is ?)and(?? is ?)')
//err.params[1].should.be.equal(null)

Loading…
Cancel
Save