Skip to content

Instantly share code, notes, and snippets.

@rosd89
Last active August 9, 2019 06:28
Show Gist options
  • Save rosd89/2007c19238c5023c519a70c00c178334 to your computer and use it in GitHub Desktop.
Save rosd89/2007c19238c5023c519a70c00c178334 to your computer and use it in GitHub Desktop.
const moment = require('moment-timezone');
const {mongo} = require('../mongodb');
const DEFAULT_VALUES = {
NOW: new Date()
};
const MongoQueryParser = class {
constructor({params, values}) {
Object.assign(this, {
_parser: new (require('sql-where-parser'))(),
params,
values,
comparators: {
'>': '$gt',
'>=': '$gte',
'<': '$lt',
'<=': '$lte'
}
})
}
parse(condition) {
return this._parser.parse(condition, (operator, operands) => {
switch (operator) {
case 'AND':
return {'$and': operands};
case 'OR':
return {'$or': operands};
case 'NOT':
return {'$ne': operands};
}
const [k,] = operands
const name = operands[1].replace('$', '');
const value = this.values[name];
let param = this.params[name];
if (param === undefined) {
const defaultValue = DEFAULT_VALUES[value.default];
if (defaultValue) {
return this._replaceOperator(operator, operands, defaultValue);
}
if (!value.required) {
throw new Error(`${k} is not required`);
}
}
switch (value.type) {
case 'DATETIME':
case 'DATE':
param = moment(param).tz('Asia/Seoul').toDate();
break;
case 'NUMBER':
param = +param;
break;
case 'STRING':
break;
default:
throw new Error(`${k} is not type`);
}
return this._replaceOperator(operator, operands, param);
});
}
_replaceOperator(operator, operands, param) {
switch (operator) {
case '=':
return {[operands[0]]: param};
case '>':
case '>=':
case '<':
case '<=':
return {[operands[0]]: {[this.comparators[operator]]: param}}
}
}
};
const toMongoGroup = data => Object.entries(data).reduce((p, [k, v]) => {
if (v.startsWith('$')) {
p[k] = v;
return p;
}
const [fn, str] = v.split('(');
const [cx,] = str.split(')');
p[k] = {};
p[k][`$${fn}`] = cx;
return p;
}, {});
@rosd89
Copy link
Author

rosd89 commented Aug 9, 2019

const params = {
    v1: '2019-06-28',
    v2: '2019-07-01'
  };
[
            {
              $match: new MongoQueryParser({params, values: report.values}).parse(report.condition)
            },
            {
              $group: {
                _id: toMongoGroup(report.groups),
                ...toMongoGroup(report.fields)
              }
            }
          ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment