UNPKG

mongo-aql

Version:

A mongo-like interface for aql generation

161 lines (136 loc) 3.6 kB
var queryTypes = require('./query-types'); var queryHelpers = require('./query-helpers'); var utils = require('./utils'); module.exports = function(collection, json, alias, valuePrefix) { var query; alias = alias || 'c'; valuePrefix = valuePrefix || 'v'; global.valuePrefix = valuePrefix; if (typeof collection !== 'string' || !collection || !collection.length) { throw new Error('collection empty or not a string.') } if (typeof json === undefined || !json) { throw new Error('json empty.') } if (typeof json === undefined || !json) { throw new Error('json empty.') } if (Object.prototype.toString.call(json) !== "[object Object]") { throw new Error('input not a valid object.') } // create a clone of the object which we can then modify // and thus leave the original object intact json = Object.assign({}, json); if (typeof json === 'string') { try { json = JSON.parse(json); } catch (err) { throw new Error(err); return err; } } if (!json) { return ''; } // todo: separate these into functions if (json.$text) { query = { type: 'text', table: collection, alias }; // grab certain keywords that need to be in their separate objects for (var key in json.$text) { if (key === '$search') { query['text-search'] = json.$text[key]; delete json.$text[key]; } else if (key === '$field') { query['text-field'] = json.$text[key]; delete json.$text[key]; } else if (key === '$limit') { query['text-limit'] = json.$text[key]; delete json.$text[key]; } } delete json.$text; for (var key in json) { if (key === '$orderby') { query['order'] = json[key]; delete json[key]; } } // the rest belongs to "where" query.where = json; } else { query = { type: 'select', table: collection, alias, valuePrefix, return: true }; // grab certain keywords that need to be in their separate objects for (var key in json) { if (key === '$orderby') { query['order'] = json[key]; delete json[key]; } else if (key === '$limit') { if (typeof json['$skip'] !== 'undefined') { query['limit'] = [ json['$skip'], json[key] ]; delete json['$skip']; } else { query['limit'] = json[key]; } delete json[key]; } else if (key.substring(0, 1) === '@') { query.embed = query.embed || []; query.embed.push({ key: key.substring(1), collection: json[key] }); delete json[key]; } } // the rest belongs to "where" query.where = json; } return build(query); } /** * Main AQL Building function * @param {Object} query * @param {Array} values * @return {String} */ function build(query, values) { if (!query.type){ query.type = 'expression'; } else if (!queryTypes.has(query.type)){ query.function = query.type; query.type = 'function'; } var type = queryTypes.get(query.type), variables = type.match(/\{[\w-]+\}/g); values = values || {}; query.__defaultTable = query.table; query.columns = ['*']; for (var i = 0, l = variables.length, key; i < l; ++i){ // If there exists a builder function and input in the options // corresponding to the query helper name, then run that // helper function with the value of the query->helper_key type = type.replace( variables[i], queryHelpers.has(key = variables[i].substring(1, variables[i].length - 1)) && query[key] ? queryHelpers.get(key).fn(query[key], values, query) : '' ); } var result = { query : type.trim().replace(/\s+/g, " "), values : values }; // console.log(result); return result; };