From b7b9cc31768ada5e5495e14285177de6a60b7807 Mon Sep 17 00:00:00 2001 From: oof1lab Date: Wed, 1 Nov 2017 20:26:27 +0000 Subject: [PATCH] feature : where clause - work in progress first cut, not getting invoked yet with apis however unit tests are testing the logic of new file. --- lib/util/whereClause.helper.js | 228 ++++++++++++++++++++++++++ lib/xapi.js | 2 +- tests/tests.js | 288 +++++++++++++++++++++++++++++++++ 3 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 lib/util/whereClause.helper.js diff --git a/lib/util/whereClause.helper.js b/lib/util/whereClause.helper.js new file mode 100644 index 0000000000..33cd7a8c63 --- /dev/null +++ b/lib/util/whereClause.helper.js @@ -0,0 +1,228 @@ +'use strict'; + +function replaceWhereParamsToQMarks(openParentheses, str) { + + let converted = '' + + if (openParentheses) { + for (var i = 0; i < str.length; ++i) { + if (str[i] === '(') { + converted += '(' + } else { + converted += '??' + break; + } + } + } else { + converted = '?' + for (var i = str.length - 1; i >= 0; --i) { + if (str[i] === ')') { + converted += ')' + } else { + break; + } + } + } + return converted; +} + +function getComparisonOperator(operator) { + + switch (operator) { + + case 'eq': + return '=' + break; + + case 'ne': + return '!=' + break; + + case 'lt': + return '<' + break; + + case 'lte': + return '<=' + break; + + case 'gt': + return '>' + break; + + case 'gte': + return '>=' + break; + + case 'like': + return ' like ' + break; + + case 'nlike': + return ' not like ' + break; + + // case 'in': + // return ' in ' + // break; + + default: + return null + break; + + } + +} + + +function getLogicalOperator(operator) { + + switch (operator) { + + case '+or': + return 'or' + break; + + case '+and': + return 'and' + break; + + case '+not': + return 'not' + break; + + case '+xor': + return 'xor' + break; + + default: + return null + break; + } + +} + + +exports.getWhereClause = function (whereInQueryParams, whereQuery, whereParams) { + + let grammarErr = 0; + let numOfConditions = whereInQueryParams.split(/\+or|\+and|\+not|\+xor/); + let logicalOperatorsInClause = whereInQueryParams.match(/(\+or|\+and|\+not|\+xor)/g) + + if (numOfConditions && logicalOperatorsInClause && numOfConditions.length !== logicalOperatorsInClause.length + 1) { + console.log('conditions and logical operators mismatch', numOfConditions.length, logicalOperatorsInClause.length); + return + } + + for (var i = 0; i < numOfConditions.length; ++i) { + + let variable = '' + let comparisonOperator = '' + let logicalOperator = '' + let variableValue = '' + let temp = '' + + // split on commas + var arr = numOfConditions[i].split(','); + + // consider first two splits only + var result = arr.splice(0, 2); + + // join to make only 3 array elements + result.push(arr.join(',')); + + // variable, operator, variablevalue + if (result.length !== 3) { + grammarErr = 1; + break; + } + + /**************** START : variable ****************/ + //console.log(result); + variable = result[0].match(/\(+(.*)/); + + console.log('variable',variable); + + if (!variable || variable.length !== 2) { + grammarErr = 1; + break; + } + + // get the variableName and push + whereParams.push(variable[1]) + + // then replace the variable name with ?? + temp = replaceWhereParamsToQMarks(true, result[0]) + if (!temp) { + grammarErr = 1; + break; + } + whereQuery += temp + + /**************** END : variable ****************/ + + + /**************** START : operator and value ****************/ + comparisonOperator = getComparisonOperator(result[1]) + if (!comparisonOperator) { + grammarErr = 1; + break; + } + whereQuery += comparisonOperator + + // get the variableValue and push + variableValue = result[2].match(/(.*?)\)/) + if (!variableValue || variableValue.length !== 2) { + grammarErr = 1; + break; + } + whereParams.push(variableValue[1]) + + // then replace the variableName with ? + temp = replaceWhereParamsToQMarks(false, result[2]) + if (!temp) { + grammarErr = 1; + break; + } + whereQuery += temp + + // only + if (numOfConditions.length !== -1 && i !== numOfConditions.length - 1) { + //console.log('finding logical operator for',logicalOperatorsInClause[i]); + logicalOperator = getLogicalOperator(logicalOperatorsInClause[i]) + + if (!logicalOperator) { + grammarErr = 1; + break; + } + + whereQuery += getLogicalOperator(logicalOperatorsInClause[i]) + } + /**************** END : operator ****************/ + + + } + + let obj = {} + + obj['query'] = '' + obj['params'] = [] + obj['err'] = grammarErr + + console.log(whereInQueryParams); + console.log(whereQuery); + console.log(whereParams); + console.log(grammarErr); + console.log('= = = = = = = = ='); + + if (!grammarErr) { + obj['query'] = whereQuery + obj['params'] = whereParams + } + + + + return obj + + +} diff --git a/lib/xapi.js b/lib/xapi.js index 4c5f04234b..251989e3f4 100644 --- a/lib/xapi.js +++ b/lib/xapi.js @@ -478,7 +478,7 @@ class Xapi { res.status(200).json(results); } else { - res.status(400).json({message:'Missing _fields in query params eg: /api/tableName/groupby?_fields=numericColumn1'}); + res.status(400).json({message: 'Missing _fields in query params eg: /api/tableName/groupby?_fields=numericColumn1'}); } } diff --git a/tests/tests.js b/tests/tests.js index f8a3fdbe75..e217695c22 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -4,6 +4,7 @@ var bodyParser = require('body-parser') var express = require('express') var mysql = require('mysql') var Xapi = require('../lib/xapi.js') +var whereClause = require('../lib/util/whereClause.helper.js') var should = require('should'); var request = require('supertest') @@ -748,4 +749,291 @@ describe('xmysql : tests', function () { }); + it('where clause unit ?_where=(abc,eq,1234) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,eq,1234)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(??=?)') + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + + it('where clause unit ?_where=(abc,ne,1234) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,ne,1234)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(??!=?)') + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + + it('where clause unit ?_where=(abc,lt,1234) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,lt,1234)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(???)') + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=(abc,gte,1234) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,gte,1234)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(??>=?)') + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + + it('where clause unit ?_where=(abc,like,1234) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,like,1234)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(?? like ?)') + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + + it('where clause unit ?_where=(abc,nlike,1234) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,nlike,1234)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(?? not like ?)') + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=abc,eq,1234) should FAIL', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('abc,eq,1234)',query,params) + + err.err.should.be.equal(1) + err.query.should.be.equal('') + err.params.length.should.be.equal(0) + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=(abc,eq,1234 should FAIL', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,eq,1234',query,params) + + err.err.should.be.equal(1) + err.query.should.be.equal('') + err.params.length.should.be.equal(0) + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=(abc,eq1234) should FAIL', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,eq1234)',query,params) + + err.err.should.be.equal(1) + err.query.should.be.equal('') + err.params.length.should.be.equal(0) + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=(abceq,1234) should FAIL', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abceq,1234)',query,params) + + err.err.should.be.equal(1) + err.query.should.be.equal('') + err.params.length.should.be.equal(0) + + done() + + //console.log(query,params,err); + + }); + + + it('where clause unit ?_where=(1,eq,1)(1,eq,2)+or should FAIL', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(1,eq,1)(1,eq,2)+or',query,params) + + err.err.should.be.equal(1) + err.query.should.be.equal('') + err.params.length.should.be.equal(0) + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=(1,eq,1)+or+or(1,eq,2)(1,eq,2) should FAIL', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(1,eq,1)+or+or(1,eq,2)(1,eq,2)',query,params) + + err.err.should.be.equal(1) + err.query.should.be.equal('') + err.params.length.should.be.equal(0) + + done() + + //console.log(query,params,err); + + }); + + it('where clause unit ?_where=(abc,eq,1)+or(b,eq,2) should PASS', function (done) { + + var query = '' + var params = [] + var err = whereClause.getWhereClause('(abc,eq,1)+or(b,eq,2)',query,params) + + err.err.should.be.equal(0) + err.query.should.be.equal('(??=?)or(??=?)') + err.params.length.should.be.equal(4) + err.params[0].should.be.equal('abc') + err.params[1].should.be.equal('1') + err.params[2].should.be.equal('b') + err.params[3].should.be.equal('2') + + // err.params[1].should.be.equal('1234') + + done() + + //console.log(query,params,err); + + }); + + + // it('where clause unit ?_where=((a,eq,1)+and(b,eq,2))+or(c,eq,3) should PASS', function (done) { + // + // var query = '' + // var params = [] + // var err = whereClause.getWhereClause('((a,eq,1)+and(b,eq,2))+or(c,eq,3)',query,params) + // + // err.err.should.be.equal(0) + // err.query.should.be.equal('((??=?)and(??=?))or(??=?)') + // err.params.length.should.be.equal(4) + // err.params[0].should.be.equal('abc') + // err.params[1].should.be.equal('1') + // err.params[2].should.be.equal('b') + // err.params[3].should.be.equal('2') + // + // err.params[1].should.be.equal('1234') + // + // done() + // + // //console.log(query,params,err); + // + // }); + + + + + + });