UNPKG

@reflaunt/nsilly-sequelize

Version:

Reflaunt Nsilly sequelize is a abstract layer of Sequelize Application, that make application more easy to understand and flexible to maintain.

585 lines (497 loc) 13.4 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); exports.__esModule = true; exports.QueryBuilder = void 0; var _ = _interopRequireWildcard(require("lodash")); var _exceptions = require("@nsilly/exceptions"); var _sequelize = require("sequelize"); var QueryBuilder = /*#__PURE__*/function () { function QueryBuilder() { this.wheres = []; this.scopeQueries = []; this.scopes = []; this.offset = 0; this.limit = undefined; this.orders = []; this.group = undefined; this.includes = []; this.attributes = []; } var _proto = QueryBuilder.prototype; _proto.setModels = function setModels(models) { this.models = models; } /** * Add a basic WHERE clause to the query. * * @param string column * @param mixed operator * @param mixed value * * @return this */ ; _proto.where = function where() { var type = _sequelize.Op.and; var column; var operation = '='; var value; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } if (args.length === 2) { var _ref = [args[0], args[1]]; column = _ref[0]; value = _ref[1]; } else if (args.length === 3) { column = args[0]; operation = args[1]; value = args[2]; } else if (args.length === 1) { // means raw query var _ref2 = [args[0], null, null]; column = _ref2[0]; operation = _ref2[1]; value = _ref2[2]; } else { throw new _exceptions.Exception('where function expect two or three parameters', 1000); } this.wheres.push({ column: column, operation: operation, value: value, type: type }); return this; } /** * Add a basic WHERE clause to the query. * * @param string column * @param mixed operator * @param mixed value * * @return this */ ; _proto.scopeQuery = function scopeQuery(query, type) { if (type === void 0) { type = _sequelize.Op.and; } this.scopeQueries.push({ query: query, type: type }); return this; } /** * Add a basic OR WHERE clause to the query. * * @param string column * @param mixed operator * @param mixed value * * @return this */ ; _proto.orWhere = function orWhere() { var type = _sequelize.Op.or; var column; var operation = '='; var value; for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (args.length === 2) { var _ref3 = [args[0], args[1]]; column = _ref3[0]; value = _ref3[1]; } else if (args.length === 3) { column = args[0]; operation = args[1]; value = args[2]; } else if (args.length === 1) { var _ref4 = [args[0], null, null]; column = _ref4[0]; operation = _ref4[1]; value = _ref4[2]; } else { throw new _exceptions.Exception('orWhere function expect one, two or three parameters', 1000); } this.wheres.push({ column: column, operation: operation, value: value, type: type }); return this; } /** * Add an "WHERE IN" clause to the query. * * @param string column * @param array value * * @return this */ ; _proto.whereIn = function whereIn(column, value) { var operation = _sequelize.Op["in"]; var type = _sequelize.Op.and; this.wheres.push({ column: column, operation: operation, value: value, type: type }); return this; } /** * Add an "OR WHERE IN" clause to the query. * * @param string column * @param array value * * @return this */ ; _proto.orWhereIn = function orWhereIn(column, value) { var operation = _sequelize.Op["in"]; var type = _sequelize.Op.or; this.wheres.push({ column: column, operation: operation, value: value, type: type }); return this; } /** * Add an "WHERE NOT IN" clause to the query. * * @param string column * @param array value * * @return this */ ; _proto.whereNotIn = function whereNotIn(column, value) { var operation = _sequelize.Op.notIn; var type = _sequelize.Op.and; this.wheres.push({ column: column, operation: operation, value: value, type: type }); return this; } /** * Add a basic where clause with relation to the query. * * @param string relation * @param callable callable * * @return this */ ; _proto.whereHas = function whereHas(relation, builder, options) { options = options || {}; var model; if (this.models !== undefined && this.models[relation] !== undefined) { model = this.models[relation]; } else { model = relation; } this.includes.push(Object.assign({ model: model, where: builder.buildWhereQuery() }, options)); return this; } /** * include another table that has many to many relationship with it * * @param string relation * @param callable builder * * @return this */ ; _proto.includeThroughWhere = function includeThroughWhere(relation, builder) { if (this.models !== undefined && this.models[relation] !== undefined) { this.includes.push({ model: this.models[relation], through: { where: builder.buildWhereQuery() } }); } else { this.includes.push({ model: relation, through: { where: builder.buildWhereQuery() } }); } return this; } /** * Alias to set the "offset" value of the query. * * @param int value * * @return this */ ; _proto.skip = function skip(offset) { this.offset = _.isUndefined(offset) ? 1 : parseInt(offset); } /** * Alias to set the "limit" value of the query. * * @param int value * * @return this */ ; _proto.take = function take(limit) { this.limit = _.isUndefined(limit) ? undefined : parseInt(limit); } /** * Add an "order by" clause to the query. * * @param string column * @param string direction * * @return this */ ; _proto.orderBy = function orderBy() { var model; var field; var direction = 'ASC'; for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } if (args.length === 2) { field = args[0]; direction = args[1]; this.orders.push([field, direction]); } if (args.length === 3) { model = args[0]; field = args[1]; direction = args[2]; this.orders.push([model, field, direction]); } if (args.length === 1) { field = args[0]; this.orders.push(field); } } /** * Add an "GROUP BY" clause to the query. * * @param string column * * @return this */ ; _proto.groupBy = function groupBy(column) { this.group = column; } /** * Begin querying a model with eager loading. * * @param array|string $relations * * @return this */ ; _proto["with"] = function _with() { var _this = this; for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } if (_.isArray(args[0])) { args = args[0]; } var mainModel = args[0]; if (typeof args[0] === 'string') { if (this.models !== undefined && this.models[args[0]] !== undefined) { mainModel = this.models[args[0]]; } else { mainModel = args[0]; } } var include = { model: mainModel }; var arr = []; var arrayInclude = []; var obj = {}; for (var i = 1; i < args.length; i++) { if (args[i]) { arr.push(args[i].split(':')); } } _.forEach(arr, function (item) { switch (item[0]) { case 'as': obj[item[0]] = item[1]; Object.assign(include, obj); break; case 'attributes': obj[item[0]] = []; for (var j = 1; j < item.length; j++) { obj[item[0]].push(item[j]); } Object.assign(include, obj); break; case 'include': var model = item[1]; if (typeof item[1] === 'string') { if (_this.models !== undefined && _this.models[item[1]] !== undefined) { model = _this.models[item[1]]; } else { model = item[1]; } } var includeObj = { model: model }; if (item[2] === 'as') { Object.assign(includeObj, { as: item[3] }); } arrayInclude.push(includeObj); break; default: break; } }); arrayInclude = _.reverse(arrayInclude); for (var _i = 0; _i < arrayInclude.length - 1; _i++) { Object.assign(arrayInclude[_i + 1], { include: arrayInclude[_i] }); } if (!_.isNil(arrayInclude[arrayInclude.length - 1])) { Object.assign(include, { include: arrayInclude[arrayInclude.length - 1] }); } _.forEach(this.includes, function (value) { if (value['model'] === include['model'] && include['include']) { Object.assign(value, include); include = {}; } }); if (!_.isEmpty(include)) { this.includes.push(include); } } /** * Add scope to the query * * @param string scope * * @return this */ ; _proto.withScope = function withScope(scope) { this.scopes.push(scope); } /** * Set the columns to be selected. * * @param array|mixed $columns * * @return this */ ; _proto.select = function select(columns) { this.attributes = columns; return this; }; _proto.resolveOperation = function resolveOperation(operation) { switch (operation) { case '=': return _sequelize.Op.eq; case '>': return _sequelize.Op.gt; case '<': return _sequelize.Op.lt; case '>=': return _sequelize.Op.gte; case '<=': return _sequelize.Op.lte; case '<>': case '!=': return _sequelize.Op.ne; case 'like': case 'LIKE': return _sequelize.Op.like; case 'notLike': case 'NOTLIKE': return _sequelize.Op.notLike; default: return operation; } }; _proto.buildWhereQuery = function buildWhereQuery() { var _this2 = this; var query = {}; var group = _.groupBy(this.wheres, 'type'); if (this.wheres.length === 0 && this.scopeQueries.length === 0) { return query; } if (!_.isUndefined(group[_sequelize.Op.or]) && group[_sequelize.Op.or].length > 0) { var _query; query = (_query = {}, _query[_sequelize.Op.or] = [], _query); if (!_.isUndefined(group[_sequelize.Op.and]) && group[_sequelize.Op.and].length > 0) { var _query$Op$or$push; var andQuery = {}; _.forEach(group[_sequelize.Op.and], function (item) { var _andQuery$item$column; andQuery[item.column] = (_andQuery$item$column = {}, _andQuery$item$column[_this2.resolveOperation(item.operation)] = item.value, _andQuery$item$column); }); query[_sequelize.Op.or].push((_query$Op$or$push = {}, _query$Op$or$push[_sequelize.Op.and] = andQuery, _query$Op$or$push)); } _.forEach(group[_sequelize.Op.or], function (item) { if (item.operation === null && item.value == null) { query[_sequelize.Op.or].push(item.column); } else { var _item$column, _query$Op$or$push2; query[_sequelize.Op.or].push((_query$Op$or$push2 = {}, _query$Op$or$push2[item.column] = (_item$column = {}, _item$column[_this2.resolveOperation(item.operation)] = item.value, _item$column), _query$Op$or$push2)); } }); } else { var _query2; query = (_query2 = {}, _query2[_sequelize.Op.and] = [], _query2); _.forEach(group[_sequelize.Op.and], function (item) { if (item.operation === null && item.value == null) { query[_sequelize.Op.and].push(item.column); } else { var _item$column2, _query$Op$and$push; query[_sequelize.Op.and].push((_query$Op$and$push = {}, _query$Op$and$push[item.column] = (_item$column2 = {}, _item$column2[_this2.resolveOperation(item.operation)] = item.value, _item$column2), _query$Op$and$push)); } }); } if (_.isArray(this.scopeQueries) && this.scopeQueries.length > 0) { _.forEach(this.scopeQueries, function (item) { if (query[item.type] !== undefined && _.isArray(query[item.type])) { var _query$item$type$push; query[item.type].push((_query$item$type$push = {}, _query$item$type$push[item.type] = item.query.buildWhereQuery(), _query$item$type$push)); } else { query[item.type] = item.query.buildWhereQuery(); } }); } return query; }; return QueryBuilder; }(); exports.QueryBuilder = QueryBuilder;