UNPKG

json-sql-builder

Version:

SQLBuilder to translate JSON dataformat like mongo to SQL

142 lines (128 loc) 4.28 kB
'use strict'; const _ = require('lodash'); function whereClause(usedFor, where /*, outerQuery, identifier*/) { var result = '', conditions = []; if (_.isPlainObject(where)){ // $where: { // first_name: 'John', // last_name: 'Doe' // } _.forEach(where, (value, key) => { // check if there is a helper, maybe $or, $and ? if (key.startsWith('$')){ // $or: [...] var tmpQuery = {}; tmpQuery[key] = value; conditions.push(this.build(tmpQuery)); } else { if (_.isPlainObject(value)) { // last_name: { $eq: 'Doe' } conditions.push(this.build(value, key)); } else if (!_.isArray(value) && !_.isObject(value)){ // any primitive like: // first_name: 'John', id: 76534 conditions.push(this.quote(key) + ' = ' + this.addValue(value)); } else { // TODO: check if array is a possible value throw new Error ('Unknown value inside ' + usedFor + ' clause. The value must be either string or object.'); } } }); } else { throw new Error(usedFor + ' expression must be an object.'); } result += conditions.join(' AND '); if (result.startsWith('(')){ // remove the outer most parenthetes result = result.substring(1, result.length - 1); } return result; } module.exports.whereClause = whereClause; function aggregationHelper(sqlCommand, aggregation, outerQuery, identifier) { if (identifier){ // SUM(`salary`) AS `total_salary` return sqlCommand + '(' + this.quote(aggregation) + ') AS ' + this.quote(identifier); } else { // SUM(`salary`) return sqlCommand + '(' + this.quote(aggregation) + ')'; } } module.exports.aggregation = aggregationHelper; function comparisonHelper(condition, val, outerQuery, identifier) { if (identifier){ // val is an Object: mycolumn: { $eq: { $column: 'testcol'} } // should return `mycolumn` = `testcol` if (_.isPlainObject(val)){ return this.quote(identifier) + ' ' + condition + ' ' + this.build(val); } return this.quote(identifier) + ' ' + condition + ' ' + this.addValue(val); } else { return condition + ' ' + this.addValue(val); } } module.exports.comparison = comparisonHelper; function sortHelper(helperName, sort/*, outerQuery, identifier*/){ var results = []; if (_.isString(sort)){ // $sort: 'first_name' results.push(this.quote(sort)); } else if (_.isArray(sort)) { /* // Array of Strings $sort: ['last_name', 'first_name'], // Array of Objects $sort: [ { last_name : 'ASC' }, { first_name : 'DESC' } ]*/ _.forEach(sort, (column) => { // check the type of the column definition if (_.isString(column)){ // $sort: ['last_name', 'first_name'], results.push(this.quote(column)); } else if (_.isPlainObject(column)) { /*$sort: [ { last_name : 'ASC' }, { first_name : 'DESC' } ]*/ _.forEach(column, (value, key) => { var ascdesc = ''; if (_.isPlainObject(value)) ascdesc = this.build(value); if (_.isString(value) && value.toLowerCase() === 'asc') ascdesc = 'ASC'; if (_.isString(value) && value.toLowerCase() === 'desc') ascdesc = 'DESC'; if (_.isNumber(value) && value === 1) ascdesc = 'ASC'; if (_.isNumber(value) && value === -1) ascdesc = 'DESC'; results.push(this.quote(key) + ' ' + ascdesc); }); } else { throw new Error('The items of the ' + helperName + ' array should either be a string or an object.'); } }); } else if (_.isPlainObject(sort)) { /*$sort: { { last_name : 'ASC' }, { first_name : 'DESC' } }*/ _.forEach(sort, (value, column) => { var ascdesc = ''; if (_.isString(value)){ if (value.toLowerCase() === 'asc') ascdesc = ' ASC'; if (value.toLowerCase() === 'desc') ascdesc = ' DESC'; results.push(this.quote(column) + ascdesc); } else if (_.isNumber(value)){ if (value === 1) ascdesc = ' ASC'; if (value === -1) ascdesc = ' DESC'; results.push(this.quote(column) + ascdesc); } else if (_.isPlainObject(value)) { if (_.isPlainObject(value)) ascdesc = this.build(value); results.push(this.quote(column) + ' ' + ascdesc); } else { throw new Error('The properties of the ' + helperName + ' object should either be a string or an object.'); } }); } return results; } module.exports.sort = sortHelper;