UNPKG

@nsilly/repository

Version:

NF Repository is a abstract layer of Sequelize Application, that make application more easy to understand and flexible to maintain.

516 lines (440 loc) 12.9 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.QueryBuilder = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _ = _interopRequireWildcard(require("lodash")); var _exceptions = require("@nsilly/exceptions"); var _sequelize = require("sequelize"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } 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() { for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } var mainModel = args[0]; var options = args[1] || {}; if (typeof args[0] === 'string') { if (this.models !== undefined && this.models[args[0]] !== undefined) { mainModel = this.models[args[0]]; } else { mainModel = args[0]; } } if (options.include !== undefined && typeof options.include === 'string' && this.models !== undefined && this.models[options.include] !== undefined) { options.include = this.models[options.include]; } var include = _objectSpread({}, options, {}, { model: mainModel }); 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 _this = 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[_this.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[_this.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[_this.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;