Browse Source

Fix#24 : Xjoin column names to have aliases derived from tablName-alias and columnName.

pull/27/head
o1lab 6 years ago
parent
commit
5a9b6f4a5f
  1. 18
      README.md
  2. 9
      lib/xapi.js
  3. 129
      lib/xsql.js
  4. 22
      tests/tests.js

18
README.md

@ -726,7 +726,7 @@ Sql join query:
```sql ```sql
SELECT * SELECT pl.field1, pr.field2
FROM productlines as pl FROM productlines as pl
JOIN products as pr JOIN products as pr
ON pl.productline = pr.productline ON pl.productline = pr.productline
@ -735,14 +735,14 @@ FROM productlines as pl
Equivalent xjoin query API: Equivalent xjoin query API:
``` ```
/api/xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline) /api/xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl.field1,pr.field2
``` ```
#### Multiple tables join #### Multiple tables join
Sql join query: Sql join query:
```sql ```sql
SELECT * SELECT pl.field1, pr.field2, ord.field3
FROM productlines as pl FROM productlines as pl
JOIN products as pr JOIN products as pr
ON pl.productline = pr.productline ON pl.productline = pr.productline
@ -753,7 +753,7 @@ FROM productlines as pl
Equivalent xjoin query API: Equivalent xjoin query API:
``` ```
/api/xjoin?_join=pl.productlines,_j,pr.products,_j,ord.orderDetails&_on1=(pl.productline,eq,pr.productline)&_on2=(pr.productcode,eq,ord.productcode) /api/xjoin?_join=pl.productlines,_j,pr.products,_j,ord.orderDetails&_on1=(pl.productline,eq,pr.productline)&_on2=(pr.productcode,eq,ord.productcode)&_fields=&_fields=pl.field1,pr.field2,ord.field3
``` ```
@ -774,6 +774,16 @@ Example to use : _fields, _where, _p, _size in query params
/api/xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl.productline,pr.productName&_size=2&_where=(productName,like,1972~) /api/xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl.productline,pr.productName&_size=2&_where=(productName,like,1972~)
``` ```
Response:
```
[{"pl_productline":"Classic Cars","pr_productName":"1972 Alfa Romeo GTA"}]
```
Please note :
Xjoin response has aliases for fields like below aliasTableName + '_' + columnName.
eg: pl.productline in _fields query params - returns as pl_productline in response.
## Run dynamic queries ## Run dynamic queries
[:arrow_heading_up:](#api-overview) [:arrow_heading_up:](#api-overview)

9
lib/xapi.js

@ -304,9 +304,12 @@ class Xapi {
this.mysql.prepareJoinQuery(req, res, obj) this.mysql.prepareJoinQuery(req, res, obj)
//console.log(obj); //console.log(obj);
if(obj.query.length){
let results = await this.mysql.exec(obj.query, obj.params) let results = await this.mysql.exec(obj.query, obj.params)
res.status(200).json(results) res.status(200).json(results)
} else {
res.status(400).json({err: 'Invalid Xjoin request'});
}
} }

129
lib/xsql.js

@ -139,6 +139,7 @@ class Xsql {
} }
} }
} }
/**************** END : Cache functions ****************/ /**************** END : Cache functions ****************/
@ -249,7 +250,7 @@ class Xsql {
/**************** START : prepare value object in prepared statement ****************/ /**************** START : prepare value object in prepared statement ****************/
// iterate over sent object array // iterate over sent object array
let arrOfArr = [] let arrOfArr = []
for (var i = 0; i < objectArray.length; ++i) { for (var i = 0; i < objectArray.length; ++i) {
let arrValues = [] let arrValues = []
@ -670,7 +671,7 @@ class Xsql {
//select ? as ??, count(*) as _count from ?? where ?? between ? and ? //select ? as ??, count(*) as _count from ?? where ?? between ? and ?
if (stepArray.length && stepArray.length >= 2 && stepArray.length%2 === 0) { if (stepArray.length && stepArray.length >= 2 && stepArray.length % 2 === 0) {
for (let i = 0; i < stepArray.length && stepArray.length >= 2; i = i + 2) { for (let i = 0; i < stepArray.length && stepArray.length >= 2; i = i + 2) {
@ -954,93 +955,109 @@ class Xsql {
queryParamsObj.query = 'SELECT ' queryParamsObj.query = 'SELECT '
queryParamsObj.grammarErr = 0; queryParamsObj.grammarErr = 0;
/**************** START : get fields ****************/ while (1) {
if (req.query._fields) {
let fields = req.query._fields.split(',') /**************** START : get fields ****************/
if (req.query._fields) {
// from _fields to - ??, ??, ?? [col1,col2,col3] let fields = req.query._fields.split(',')
for (var i = 0; i < fields.length; ++i) {
if (i) { // from _fields to - ??, ??, ?? [col1,col2,col3]
queryParamsObj.query += ',' for (var i = 0; i < fields.length && (!queryParamsObj.grammarErr); ++i) {
if (i) {
queryParamsObj.query += ','
}
queryParamsObj.query += ' ?? '
queryParamsObj.params.push(fields[i])
let aliases = fields[i].split('.');
if (aliases.length === 2) {
queryParamsObj.query += 'as ' + aliases[0] + '_' + aliases[1];
//console.log(queryParamsObj.query);
} else {
queryParamsObj.grammarErr = 1;
}
} }
queryParamsObj.query += ' ?? ' } else {
queryParamsObj.params.push(fields[i]) queryParamsObj.grammarErr = 1;
} }
} else { queryParamsObj.query += ' from '
queryParamsObj.query += ' * ' if(queryParamsObj.grammarErr){
break;
}
} /**************** END : get fields ****************/
queryParamsObj.query += ' from '
/**************** END : get fields ****************/
/**************** START : get join + on ****************/
let joinTables = req.query._join.split(',')
if (joinTables.length < 3) {
//console.log('grammar error ', joinTables.length);
queryParamsObj.grammarErr = 1;
break;
}
/**************** START : get join + on ****************/ //console.log('jointables.length', joinTables);
let joinTables = req.query._join.split(',')
if (joinTables.length < 3) {
//console.log('grammar error ', joinTables.length);
queryParamsObj.grammarErr = 1;
}
//console.log('jointables.length', joinTables); let onCondnCount = 0;
let onCondnCount = 0; for (let i = 0; i < joinTables.length - 1 && queryParamsObj.grammarErr === 0; i = i + 2) {
for (let i = 0; i < joinTables.length - 1 && queryParamsObj.grammarErr === 0; i = i + 2) { onCondnCount++;
onCondnCount++; this._joinTableNames(i, joinTables, i, queryParamsObj)
this._joinTableNames(i, joinTables, i, queryParamsObj) if (queryParamsObj.grammarErr) {
console.log('failed at _joinTableNames', queryParamsObj);
break;
}
if (queryParamsObj.grammarErr) { //console.log('after join tables', queryParamsObj);
console.log('failed at _joinTableNames', queryParamsObj);
break;
}
//console.log('after join tables', queryParamsObj); let onCondn = '_on' + (onCondnCount)
let onCondnObj = {}
if (onCondn in req.query) {
//console.log(onCondn, req.query[onCondn]);
onCondnObj = whereHelp.getConditionClause(req.query[onCondn], ' on ')
//console.log('onCondnObj', onCondnObj);
queryParamsObj.query += ' on ' + onCondnObj.query
queryParamsObj.params = queryParamsObj.params.concat(onCondnObj.params)
} else {
queryParamsObj.grammarErr = 1;
//console.log('No on condition: ', onCondn);
break;
}
let onCondn = '_on' + (onCondnCount) if (i === 0) {
let onCondnObj = {} i = i + 1
if (onCondn in req.query) { }
//console.log(onCondn, req.query[onCondn]);
onCondnObj = whereHelp.getConditionClause(req.query[onCondn], ' on ')
//console.log('onCondnObj', onCondnObj);
queryParamsObj.query += ' on ' + onCondnObj.query
queryParamsObj.params = queryParamsObj.params.concat(onCondnObj.params)
} else {
queryParamsObj.grammarErr = 1;
//console.log('No on condition: ', onCondn);
break;
} }
/**************** END : get join + on ****************/
//console.log('- - - - - - -'); if(queryParamsObj.grammarErr){
if (i === 0) { break;
i = i + 1 } else {
this.getWhereClause(req.query._where, ' ignore ', queryParamsObj, ' where ');
this._getGrpByHavingOrderBy(req, 'ignore', queryParamsObj, 5)
//console.log('after where',queryParamsObj);
} }
//console.log('index after loop', i);
break;
} }
/**************** END : get join + on ****************/
if (queryParamsObj.grammarErr) { if (queryParamsObj.grammarErr) {
queryParamsObj.query = '' queryParamsObj.query = ''
queryParamsObj.params = [] queryParamsObj.params = []
} }
this.getWhereClause(req.query._where, ' ignore ', queryParamsObj, ' where ');
//console.log('after where',queryParamsObj);
this._getGrpByHavingOrderBy(req, 'ignore', queryParamsObj, 5)
return queryParamsObj; return queryParamsObj;
} }
} }

22
tests/tests.js

@ -1599,7 +1599,7 @@ describe('xmysql : tests', function () {
//post to an url with data //post to an url with data
agent.get(apiPrefix + 'xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)') //enter url agent.get(apiPrefix + 'xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)') //enter url
.expect(200)//200 for success 4xx for failure .expect(400)//200 for success 4xx for failure
.end(function (err, res) { .end(function (err, res) {
// Handle /api/v error // Handle /api/v error
@ -1607,8 +1607,6 @@ describe('xmysql : tests', function () {
return done(err); return done(err);
} }
//validate response
Object.keys(res.body[0]).length.should.be.equals(12)
return done(); return done();
}); });
@ -1636,6 +1634,24 @@ describe('xmysql : tests', function () {
}); });
}); });
it('GET ' + apiPrefix + 'xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl_productline,pr.productName should PASS', function (done) {
//post to an url with data
agent.get(apiPrefix + 'xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl_productline,pr.productName') //enter url
.expect(400)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
return done();
});
});
it('GET ' + apiPrefix + 'xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl.productline,pr.productName&_size=2 should PASS', function (done) { it('GET ' + apiPrefix + 'xjoin?_join=pl.productlines,_j,pr.products&_on1=(pl.productline,eq,pr.productline)&_fields=pl.productline,pr.productName&_size=2 should PASS', function (done) {
//post to an url with data //post to an url with data

Loading…
Cancel
Save