Last active
August 9, 2019 06:28
-
-
Save rosd89/2007c19238c5023c519a70c00c178334 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | |
| }, {}); |
Author
rosd89
commented
Aug 9, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment