UNPKG

@stoqey/sofa

Version:
415 lines 15.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildIndexExpr = exports.buildWhereClauseExpr = exports.verifyWhereObjectKey = exports.buildWhereExpr = exports.buildSelectExpr = exports.buildSelectArrayExpr = exports.selectBuilder = void 0; var dictionary_1 = require("./dictionary"); var exceptions_1 = require("../exceptions"); var utils_1 = require("../utils"); // select expressions functions /** * Build a SELECT N1QL query from user-specified parameters. * {@link https://docs.couchbase.com/server/6.5/n1ql/n1ql-language-reference/select-syntax.html} * @param collection Collection name * @param select SELECT Clause param * @param letExpr LET Clause param * @param where WHERE Clause param * @param orderBy ORDER BY Clause param * @param limit LIMIT Clause param * @param offset OFFSET Clause param * @param useExpr USE Clause param * * @return N1QL SELECT Query * */ var selectBuilder = function (collection, select, letExpr, where, orderBy, limit, offset, useExpr, groupByExpr, lettingExpr, havingExpr, plainJoinExpr) { try { var expr = ''; if (typeof select === 'string') { expr = select; } if (Array.isArray(select)) { expr = (0, exports.buildSelectArrayExpr)(select); } var _collection = collection.indexOf(' ') !== -1 ? ("`" + collection).replace(' ', '` ') : collection.indexOf('`') !== -1 ? collection : "`" + collection + "`"; return "SELECT " + expr + " FROM " + _collection + (plainJoinExpr ? " " + plainJoinExpr + " " : '') + _buildUseKeysExpr(useExpr) + _buildLetExpr(letExpr) + (0, exports.buildWhereExpr)(where) + _buildGroupByExpr(groupByExpr, lettingExpr, havingExpr) + _buildOrderByExpr(orderBy) + _buildLimitExpr(limit) + _buildOffsetExpr(offset); } catch (exception) { if (exception instanceof exceptions_1.WhereClauseException) { throw exception; } throw new exceptions_1.SelectClauseException(); } }; exports.selectBuilder = selectBuilder; /** * @ignore * */ var _buildAS = function (c) { return c.hasOwnProperty('as') ? " AS " + c['as'] : ''; }; /** * @ignore * */ var _buildField = function (clause) { if (clause.hasOwnProperty('name')) { return "" + (0, utils_1.escapeReservedWords)(clause['name']) + _buildAS(clause); } return "" + (0, utils_1.escapeReservedWords)(clause); }; /** * Create N1QL queries from select array params * @param clause SELECT Clause param * * @return N1QL SELECT Query * */ var buildSelectArrayExpr = function (clause) { return "" + clause.map(function (c) { return (0, exports.buildSelectExpr)('', c); }).join(','); }; exports.buildSelectArrayExpr = buildSelectArrayExpr; /** * Recursive function to create N1QL queries. * @param n1ql N1QL Query String * @param clause SELECT Clause param * * @return N1QL SELECT Query * */ var buildSelectExpr = function (n1ql, clause) { try { if (clause.hasOwnProperty('$field')) { return _buildField(clause['$field']); } var key = Object.keys(clause)[0]; if (dictionary_1.ReturnResultDict.hasOwnProperty(key)) { return dictionary_1.ReturnResultDict[key] + " " + (0, exports.buildSelectExpr)(n1ql, clause[key]); } if (dictionary_1.ResultExprDict.hasOwnProperty(key)) { return dictionary_1.ResultExprDict[key] + " " + (0, exports.buildSelectExpr)(n1ql, clause[key]); } if (dictionary_1.AggDict.hasOwnProperty(key)) { // todo check if have AS expr inside of Agg function. return dictionary_1.AggDict[key] + "(" + _buildAggDictExpr(clause, key) + (0, exports.buildSelectExpr)(n1ql, clause[key]) + ")" + _buildAS(clause[key]); } throw new exceptions_1.SelectClauseException(); } catch (_a) { throw new exceptions_1.SelectClauseException(); } }; exports.buildSelectExpr = buildSelectExpr; /** * @ignore * */ var _buildAggDictExpr = function (clause, key) { if (dictionary_1.AggDict.hasOwnProperty(key)) { if (clause[key].hasOwnProperty('ro')) { return dictionary_1.ReturnResultDict[clause[key]['ro']] + " "; } } return ''; }; /** * @ignore * */ var _buildLetExpr = function (letExpr, clause) { return Array.isArray(letExpr) ? " " + (clause ? clause : 'LET') + " " + letExpr .map(function (value) { return (0, utils_1.escapeReservedWords)(value.key) + "=" + value.value; }) .join(',') : ''; }; /** * @ignore * */ var _buildOrderByExpr = function (orderExpr) { return !!orderExpr ? " ORDER BY " + Object.keys(orderExpr) .map(function (value) { return (0, utils_1.escapeReservedWords)(value) + " " + orderExpr[value]; }) .join(',') : ''; }; /** * @ignore * */ var _buildLimitExpr = function (limit) { return Number.isInteger(limit) ? " LIMIT " + limit : ''; }; /** * @ignore * */ var _buildOffsetExpr = function (offset) { return Number.isInteger(offset) ? " OFFSET " + offset : ''; }; /** * @ignore * */ var _buildUseKeysExpr = function (useKeys) { return Array.isArray(useKeys) ? " USE KEYS " + stringifyValues(useKeys) : ''; }; // end select expression functions //group by expression functions /** *@ignore */ var _buildGroupByExpr = function (groupByExpr, lettingExpr, havingExpr) { try { if ((lettingExpr || havingExpr) && !groupByExpr) { throw new exceptions_1.QueryGroupByParamsException(); } if (!groupByExpr) { return ''; } return " " + _buildGroupBy(groupByExpr) + _buildLetExpr(lettingExpr, 'LETTING') + (0, exports.buildWhereExpr)(havingExpr, 'HAVING'); } catch (_a) { throw new exceptions_1.QueryGroupByParamsException(); } }; /** *@ignore */ var _buildGroupBy = function (groupByExpr) { return "GROUP BY " + groupByExpr .map(function (value) { return "" + (0, utils_1.escapeReservedWords)(value.expr) + (value.as ? " AS " + value.as : ''); }) .join(','); }; //end group by expression functions // where expression functions /** * Create WHERE N1QL Expressions. * {@link https://docs.couchbase.com/server/6.5/n1ql/n1ql-language-reference/where.html} * @param clause WHERE Clause param * @return N1QL WHERE Expression * */ var buildWhereExpr = function (expr, clause) { return expr ? " " + (clause ? clause : 'WHERE') + " " + (0, exports.buildWhereClauseExpr)('', expr) : ''; }; exports.buildWhereExpr = buildWhereExpr; /** * @ignore * **/ var verifyWhereObjectKey = function (clause) { var exist = false; for (var key in clause) { if (['$and', '$or', '$not', '$any', '$$every', '$in', '$within'].includes(key)) { exist = true; break; } } return exist; }; exports.verifyWhereObjectKey = verifyWhereObjectKey; /** * Recursive function to create WHERE N1QL Expressions. * @param n1ql N1QL Query String * @param clause WHERE Clause param * * @return N1QL WHERE Expression * */ var buildWhereClauseExpr = function (n1ql, clause) { try { if (!(0, exports.verifyWhereObjectKey)(clause)) { return _buildFieldClauseExpr(clause); } return Object.keys(clause) .map(function (key) { var _a; if (dictionary_1.CollectionSelectOperatorDict[key]) { return "" + _buildWhereCollectionExpr(key, clause[key]); } if (dictionary_1.CollectionInWithinOperatorDict[key]) { return "" + _buildCollectionInWithinOperator(key, clause[key]); } if (Array.isArray(clause[key])) { var prefix = key === '$not' ? dictionary_1.LogicalOperatorDict[key] + " " : ''; var joinOp = key === '$not' ? " AND " : " " + dictionary_1.LogicalOperatorDict[key] + " "; return prefix + "(" + clause[key] .map(function (value) { return (0, exports.buildWhereClauseExpr)(n1ql, value); }) .join(joinOp) + ")"; } else { return "" + (0, exports.buildWhereClauseExpr)(n1ql, (_a = {}, _a[key] = clause[key], _a)); } }) .join(' AND '); } catch (exception) { if (exception instanceof exceptions_1.WhereClauseException) { throw exception; } throw new exceptions_1.WhereClauseException(); } }; exports.buildWhereClauseExpr = buildWhereClauseExpr; /** * @ignore * */ var _buildFieldClauseExpr = function (field) { try { var expr = Object.keys(field).map(function (value) { if (typeof field[value] === 'object' && !Array.isArray(field[value])) { return "" + _buildComparisionClauseExpr(value, field[value]); } if (!value.includes('$')) { if (typeof field[value] === 'string') { return (0, utils_1.escapeReservedWords)(value) + "=" + stringifyValues(field[value]); } if (typeof field[value] === 'number' || typeof field[value] === 'boolean' || Array.isArray(field[value])) { return (0, utils_1.escapeReservedWords)(value) + "=" + stringifyValues(field[value]); } } throw new exceptions_1.QueryOperatorNotFoundException(value); }); return expr.join(' AND '); } catch (exception) { if (exception instanceof exceptions_1.WhereClauseException) { throw exception; } throw new exceptions_1.WhereClauseException(); } }; /** * @ignore * */ var _buildComparisionClauseExpr = function (fieldName, comparison) { try { var expr = Object.keys(comparison) .map(function (value) { if (!!comparison[value]) { if (dictionary_1.ComparisonEmptyOperatorDict.hasOwnProperty(value)) { return (0, utils_1.escapeReservedWords)(fieldName) + " " + dictionary_1.ComparisonEmptyOperatorDict[value]; } if (dictionary_1.ComparisonSingleOperatorDict.hasOwnProperty(value)) { return "" + (0, utils_1.escapeReservedWords)(fieldName) + dictionary_1.ComparisonSingleOperatorDict[value] + stringifyValues(comparison[value]); } if (dictionary_1.ComparisonSingleStringOperatorDict.hasOwnProperty(value)) { return (0, utils_1.escapeReservedWords)(fieldName) + " " + dictionary_1.ComparisonSingleStringOperatorDict[value] + " " + stringifyValues(comparison[value]); } if (dictionary_1.ComparisonMultipleOperatorDict.hasOwnProperty(value) && Array.isArray(comparison[value])) { return (0, utils_1.escapeReservedWords)(fieldName) + " " + dictionary_1.ComparisonMultipleOperatorDict[value] + " " + comparison[value].map(function (v) { return stringifyValues(v); }).join(' AND '); } } throw new exceptions_1.QueryOperatorNotFoundException(value); }) .join(" AND "); return Object.keys(comparison).length > 1 ? "(" + expr + ")" : expr; } catch (exception) { if (exception instanceof exceptions_1.WhereClauseException) { throw exception; } throw new exceptions_1.WhereClauseException(); } }; /** * @ignore * */ var _buildCollectionInWithinOperator = function (op, expr, excludeOperator) { if (!op || !expr.target_expr || !expr.search_expr) { throw new exceptions_1.InWithinOperatorExceptions(); } return "" + expr.search_expr + (!excludeOperator && expr.$not ? ' NOT ' : ' ') + dictionary_1.CollectionInWithinOperatorDict[op] + " " + (excludeOperator ? expr.target_expr : stringifyValues(expr.target_expr)); }; var stringifyValues = function (value) { return JSON.stringify(value).replace(/\\/gi, ''); }; /** * @ignore * */ var _buildCollectionInWithIn = function (collection) { var op = collection.$in ? '$in' : collection.$within ? '$within' : undefined; if (!op) { throw new Error('The Collection Operator needs to have the following clauses declared (IN | WITHIN) and SATISFIES.'); } return "" + _buildCollectionInWithinOperator(op, collection[op], true); }; /** * @ignore * */ var _buildWhereCollectionExpr = function (op, expr) { return dictionary_1.CollectionSelectOperatorDict[op] + " " + expr.$expr .map(function (value) { return _buildCollectionInWithIn(value); }) .join(',') + " " + dictionary_1.CollectionSatisfiesOperatorDict['$satisfies'] + " " + (0, exports.buildWhereClauseExpr)('', expr.$satisfied) + " END"; }; // end where expression functions // index expression functions /** * Build a INDEX N1QL query from user-specified parameters. * {@link https://docs.couchbase.com/server/6.5/n1ql/n1ql-language-reference/createindex.html} * @param collection Collection name * @param type INDEX clause types can be 'CREATE' | 'BUILD' | 'DROP' | 'CREATE PRIMARY' * @param on ON Clause param * @param where WHERE Clause param * @param usingGSI use a Global Secondary Index(GSI). * @param withExpr WITH Clause param * * @return N1QL INDEX Query * */ var buildIndexExpr = function (collection, type, name, on, where, usingGSI, withExpr) { if (['BUILD', 'CREATE', 'CREATE PRIMARY'].includes(type) && on) { return type + " INDEX `" + name + "` ON `" + collection + "`(" + buildOnExpr(on) + ")" + (0, exports.buildWhereExpr)(where) + " " + (usingGSI ? 'USING GSI' : '') + " " + buildWithExpr(withExpr); } else { return type + " INDEX `" + collection + "`.`" + name + "`" + (usingGSI ? ' USING GSI' : ''); } }; exports.buildIndexExpr = buildIndexExpr; /** * @ignore * */ var buildOnExpr = function (on) { return on .map(function (value) { return "" + (0, utils_1.escapeReservedWords)(value.name) + buildOnSortExpr(value); }) .join(','); }; /** * @ignore * */ var buildOnSortExpr = function (onExpr) { if (onExpr && onExpr.hasOwnProperty('sort')) { return "[\"" + onExpr.sort + "\"]"; } return ''; }; /** * @ignore * */ var buildWithExpr = function (withExpr) { if (withExpr) { var resultExpr = Object.keys(withExpr) .map(function (value) { switch (value) { case 'nodes': return buildWithNodesExpr(withExpr[value]); case 'defer_build': case 'num_replica': return "\"" + value + "\": " + withExpr[value]; default: throw new Error('The WITH clause has an incorrect syntax'); } }) .join(','); return !!resultExpr ? "WITH {" + resultExpr + "}" : ''; } return ''; }; /** * @ignore * */ var buildWithNodesExpr = function (withNodesExpr) { if (withNodesExpr) { return "\"nodes\": " + stringifyValues(withNodesExpr); } }; // end index expression functions //# sourceMappingURL=builders.js.map