objection
Advanced tools
Comparing version 0.5.0-rc.1 to 0.5.0-rc.2
'use strict'; | ||
var _dec, _dec2, _desc, _value, _class, _class2, _temp; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -22,6 +20,2 @@ value: true | ||
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); | ||
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
@@ -39,6 +33,2 @@ | ||
var _get2 = require('babel-runtime/helpers/get'); | ||
var _get3 = _interopRequireDefault(_get2); | ||
var _inherits2 = require('babel-runtime/helpers/inherits'); | ||
@@ -48,2 +38,4 @@ | ||
var _dec, _dec2, _dec3, _desc, _value, _class, _class2, _temp; | ||
var _lodash = require('lodash'); | ||
@@ -69,2 +61,6 @@ | ||
var _hiddenDataGetterSetter = require('../utils/decorators/hiddenDataGetterSetter'); | ||
var _hiddenDataGetterSetter2 = _interopRequireDefault(_hiddenDataGetterSetter); | ||
var _ValidationError = require('../ValidationError'); | ||
@@ -90,18 +86,34 @@ | ||
var _HasOneRelation = require('../relations/HasOneRelation'); | ||
var _HasOneRelation = require('../relations/hasOne/HasOneRelation'); | ||
var _HasOneRelation2 = _interopRequireDefault(_HasOneRelation); | ||
var _HasManyRelation = require('../relations/HasManyRelation'); | ||
var _HasManyRelation = require('../relations/hasMany/HasManyRelation'); | ||
var _HasManyRelation2 = _interopRequireDefault(_HasManyRelation); | ||
var _BelongsToOneRelation = require('../relations/BelongsToOneRelation'); | ||
var _ManyToManyRelation = require('../relations/manyToMany/ManyToManyRelation'); | ||
var _ManyToManyRelation2 = _interopRequireDefault(_ManyToManyRelation); | ||
var _BelongsToOneRelation = require('../relations/belongsToOne/BelongsToOneRelation'); | ||
var _BelongsToOneRelation2 = _interopRequireDefault(_BelongsToOneRelation); | ||
var _ManyToManyRelation = require('../relations/ManyToManyRelation'); | ||
var _InstanceFindOperation = require('../queryBuilder/operations/InstanceFindOperation'); | ||
var _ManyToManyRelation2 = _interopRequireDefault(_ManyToManyRelation); | ||
var _InstanceFindOperation2 = _interopRequireDefault(_InstanceFindOperation); | ||
var _InstanceInsertOperation = require('../queryBuilder/operations/InstanceInsertOperation'); | ||
var _InstanceInsertOperation2 = _interopRequireDefault(_InstanceInsertOperation); | ||
var _InstanceUpdateOperation = require('../queryBuilder/operations/InstanceUpdateOperation'); | ||
var _InstanceUpdateOperation2 = _interopRequireDefault(_InstanceUpdateOperation); | ||
var _InstanceDeleteOperation = require('../queryBuilder/operations/InstanceDeleteOperation'); | ||
var _InstanceDeleteOperation2 = _interopRequireDefault(_InstanceDeleteOperation); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -138,3 +150,3 @@ | ||
var Model = (_dec = (0, _deprecated2.default)({ removedIn: '0.7.0', useInstead: 'BelongsToOneRelation' }), _dec2 = (0, _deprecated2.default)({ removedIn: '0.7.0', useInstead: 'HasManyRelation' }), (_class = (_temp = _class2 = function (_ModelBase) { | ||
var Model = (_dec = (0, _deprecated2.default)({ removedIn: '0.7.0', useInstead: 'BelongsToOneRelation' }), _dec2 = (0, _deprecated2.default)({ removedIn: '0.7.0', useInstead: 'HasManyRelation' }), _dec3 = (0, _hiddenDataGetterSetter2.default)('relations'), (_class = (_temp = _class2 = function (_ModelBase) { | ||
(0, _inherits3.default)(Model, _ModelBase); | ||
@@ -144,536 +156,506 @@ | ||
(0, _classCallCheck3.default)(this, Model); | ||
return (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(Model).apply(this, arguments)); | ||
return (0, _possibleConstructorReturn3.default)(this, _ModelBase.apply(this, arguments)); | ||
} | ||
(0, _createClass3.default)(Model, [{ | ||
key: '$id', | ||
/** | ||
* @param {string|number|Array.<string|number>=} id | ||
* @returns {string|number|Array.<string|number>} | ||
*/ | ||
/** | ||
* @param {string|number|Array.<string|number>=} id | ||
* @returns {string|number|Array.<string|number>} | ||
*/ | ||
value: function $id() { | ||
if (arguments.length > 0) { | ||
return setId(this, arguments[0]); | ||
} else { | ||
return getId(this); | ||
} | ||
Model.prototype.$id = function $id(id) { | ||
if (arguments.length > 0) { | ||
return setId(this, arguments[0]); | ||
} else { | ||
return getId(this); | ||
} | ||
}; | ||
/** | ||
* @returns {knex} | ||
*/ | ||
/** | ||
* @returns {knex} | ||
*/ | ||
}, { | ||
key: '$knex', | ||
value: function $knex() { | ||
return this.constructor.knex(); | ||
} | ||
/** | ||
* @returns {knex} | ||
*/ | ||
Model.prototype.$knex = function $knex() { | ||
return this.constructor.knex(); | ||
}; | ||
}, { | ||
key: '$transaction', | ||
value: function $transaction() { | ||
return this.constructor.transaction(); | ||
} | ||
/** | ||
* @returns {knex} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: '$query', | ||
value: function $query() { | ||
var _this2 = this; | ||
Model.prototype.$transaction = function $transaction() { | ||
return this.constructor.transaction(); | ||
}; | ||
var ModelClass = this.constructor; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
return ModelClass.QueryBuilder.forClass(ModelClass).findImpl(function (builder) { | ||
builder.first(); | ||
builder.onBuild(function (builder) { | ||
builder.whereComposite(ModelClass.getFullIdColumn(), _this2.$id()); | ||
}); | ||
}).insertImpl(function (insertion, builder) { | ||
insertion.setData(_this2); | ||
builder.onBuild(function (builder) { | ||
builder.$$insert(insertion); | ||
}); | ||
}).updateImpl(function (update, builder) { | ||
if (!update.model()) { | ||
update.setData(_this2); | ||
} | ||
builder.onBuild(function (builder) { | ||
builder.$$update(update).whereComposite(ModelClass.getFullIdColumn(), _this2.$id()); | ||
}); | ||
}).patchImpl(function (patch, builder) { | ||
if (!patch.model()) { | ||
patch.setData(_this2); | ||
} | ||
Model.prototype.$query = function $query() { | ||
var _this2 = this; | ||
builder.onBuild(function (builder) { | ||
builder.$$update(patch).whereComposite(ModelClass.getFullIdColumn(), _this2.$id()); | ||
}); | ||
}).deleteImpl(function (builder) { | ||
builder.onBuild(function (builder) { | ||
builder.$$delete().whereComposite(ModelClass.getFullIdColumn(), _this2.$id()); | ||
}); | ||
}).relateImpl(function () { | ||
throw new Error('`relate` makes no sense in this context'); | ||
}).unrelateImpl(function () { | ||
throw new Error('`unrelate` makes no sense in this context'); | ||
}); | ||
} | ||
var ModelClass = this.constructor; | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
return ModelClass.QueryBuilder.forClass(ModelClass).findOperationFactory(function (builder) { | ||
return new _InstanceFindOperation2.default(builder, 'find', { instance: _this2 }); | ||
}).insertOperationFactory(function (builder) { | ||
return new _InstanceInsertOperation2.default(builder, 'insert', { instance: _this2 }); | ||
}).updateOperationFactory(function (builder) { | ||
return new _InstanceUpdateOperation2.default(builder, 'update', { instance: _this2 }); | ||
}).patchOperationFactory(function (builder) { | ||
return new _InstanceUpdateOperation2.default(builder, 'patch', { instance: _this2, modelOptions: { patch: true } }); | ||
}).deleteOperationFactory(function (builder) { | ||
return new _InstanceDeleteOperation2.default(builder, 'delete', { instance: _this2 }); | ||
}).relateOperationFactory(function () { | ||
throw new Error('`relate` makes no sense in this context'); | ||
}).unrelateOperationFactory(function () { | ||
throw new Error('`unrelate` makes no sense in this context'); | ||
}); | ||
}; | ||
}, { | ||
key: '$relatedQuery', | ||
value: function $relatedQuery(relationName) { | ||
var _this3 = this; | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
var relation = this.constructor.getRelation(relationName); | ||
var ModelClass = relation.relatedModelClass; | ||
return ModelClass.RelatedQueryBuilder.forClass(ModelClass).findImpl(function (builder) { | ||
relation.find(builder, [_this3]); | ||
}).insertImpl(function (insert, builder) { | ||
relation.insert(builder, _this3, insert); | ||
}).updateImpl(function (update, builder) { | ||
relation.update(builder, _this3, update); | ||
}).patchImpl(function (patch, builder) { | ||
relation.patch(builder, _this3, patch); | ||
}).deleteImpl(function (builder) { | ||
relation.delete(builder, _this3); | ||
}).relateImpl(function (ids, builder) { | ||
relation.relate(builder, _this3, ids); | ||
}).unrelateImpl(function (builder) { | ||
relation.unrelate(builder, _this3); | ||
}); | ||
} | ||
Model.prototype.$relatedQuery = function $relatedQuery(relationName) { | ||
var _this3 = this; | ||
/** | ||
* @param {string|RelationExpression} relationExpression | ||
* @param {Object.<string, function(QueryBuilder)>=} filters | ||
* @returns {Promise} | ||
*/ | ||
var relation = this.constructor.getRelation(relationName); | ||
var ModelClass = relation.relatedModelClass; | ||
}, { | ||
key: '$loadRelated', | ||
value: function $loadRelated(relationExpression, filters) { | ||
return this.constructor.loadRelated(this, relationExpression, filters); | ||
} | ||
return ModelClass.RelatedQueryBuilder.forClass(ModelClass).findOperationFactory(function (builder) { | ||
return relation.find(builder, [_this3]); | ||
}).insertOperationFactory(function (builder) { | ||
return relation.insert(builder, _this3); | ||
}).updateOperationFactory(function (builder) { | ||
return relation.update(builder, _this3); | ||
}).patchOperationFactory(function (builder) { | ||
return relation.patch(builder, _this3); | ||
}).deleteOperationFactory(function (builder) { | ||
return relation.delete(builder, _this3); | ||
}).relateOperationFactory(function (builder) { | ||
return relation.relate(builder, _this3); | ||
}).unrelateOperationFactory(function (builder) { | ||
return relation.unrelate(builder, _this3); | ||
}); | ||
}; | ||
/** | ||
* @param {Constructor.<Model>=} filterConstructor | ||
* @param {function(Model)} callback | ||
* @return {Model} | ||
*/ | ||
/** | ||
* @param {string|RelationExpression} relationExpression | ||
* @param {Object.<string, function(QueryBuilder)>=} filters | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: '$traverse', | ||
value: function $traverse(filterConstructor, callback) { | ||
if (_lodash2.default.isUndefined(callback)) { | ||
callback = filterConstructor; | ||
filterConstructor = null; | ||
} | ||
this.constructor.traverse(filterConstructor, this, callback); | ||
return this; | ||
Model.prototype.$loadRelated = function $loadRelated(relationExpression, filters) { | ||
return this.constructor.loadRelated(this, relationExpression, filters); | ||
}; | ||
/** | ||
* @param {Constructor.<Model>=} filterConstructor | ||
* @param {function(Model)} callback | ||
* @return {Model} | ||
*/ | ||
Model.prototype.$traverse = function $traverse(filterConstructor, callback) { | ||
if (_lodash2.default.isUndefined(callback)) { | ||
callback = filterConstructor; | ||
filterConstructor = null; | ||
} | ||
}, { | ||
key: '$parseDatabaseJson', | ||
value: function $parseDatabaseJson(json) { | ||
var ModelClass = this.constructor; | ||
var jsonAttr = ModelClass.$$getJsonAttributes(); | ||
if (jsonAttr.length) { | ||
for (var i = 0, l = jsonAttr.length; i < l; ++i) { | ||
var attr = jsonAttr[i]; | ||
var value = json[attr]; | ||
this.constructor.traverse(filterConstructor, this, callback); | ||
return this; | ||
}; | ||
if (_lodash2.default.isString(value)) { | ||
json[attr] = JSON.parse(value); | ||
} | ||
Model.prototype.$parseDatabaseJson = function $parseDatabaseJson(json) { | ||
var ModelClass = this.constructor; | ||
var jsonAttr = ModelClass.$$getJsonAttributes(); | ||
if (jsonAttr.length) { | ||
for (var i = 0, l = jsonAttr.length; i < l; ++i) { | ||
var attr = jsonAttr[i]; | ||
var value = json[attr]; | ||
if (_lodash2.default.isString(value)) { | ||
json[attr] = JSON.parse(value); | ||
} | ||
} | ||
return json; | ||
} | ||
}, { | ||
key: '$formatDatabaseJson', | ||
value: function $formatDatabaseJson(json) { | ||
var ModelClass = this.constructor; | ||
var jsonAttr = ModelClass.$$getJsonAttributes(); | ||
if (jsonAttr.length) { | ||
for (var i = 0, l = jsonAttr.length; i < l; ++i) { | ||
var attr = jsonAttr[i]; | ||
var value = json[attr]; | ||
return json; | ||
}; | ||
if (_lodash2.default.isObject(value)) { | ||
json[attr] = (0, _stringify2.default)(value); | ||
} | ||
Model.prototype.$formatDatabaseJson = function $formatDatabaseJson(json) { | ||
var ModelClass = this.constructor; | ||
var jsonAttr = ModelClass.$$getJsonAttributes(); | ||
if (jsonAttr.length) { | ||
for (var i = 0, l = jsonAttr.length; i < l; ++i) { | ||
var attr = jsonAttr[i]; | ||
var value = json[attr]; | ||
if (_lodash2.default.isObject(value)) { | ||
json[attr] = (0, _stringify2.default)(value); | ||
} | ||
} | ||
} | ||
return json; | ||
return json; | ||
}; | ||
Model.prototype.$setJson = function $setJson(json, options) { | ||
_ModelBase.prototype.$setJson.call(this, json, options); | ||
if (!_lodash2.default.isObject(json)) { | ||
return; | ||
} | ||
}, { | ||
key: '$setJson', | ||
value: function $setJson(json, options) { | ||
(0, _get3.default)((0, _getPrototypeOf2.default)(Model.prototype), '$setJson', this).call(this, json, options); | ||
if (!_lodash2.default.isObject(json)) { | ||
return; | ||
} | ||
var relations = this.constructor.getRelations(); | ||
// Parse relations into Model instances. | ||
for (var relationName in relations) { | ||
if (_lodash2.default.has(json, relationName)) { | ||
var relationJson = json[relationName]; | ||
var relation = relations[relationName]; | ||
var relations = this.constructor.getRelations(); | ||
// Parse relations into Model instances. | ||
for (var relationName in relations) { | ||
if (_lodash2.default.has(json, relationName)) { | ||
var relationJson = json[relationName]; | ||
var relation = relations[relationName]; | ||
if (_lodash2.default.isArray(relationJson)) { | ||
this[relationName] = relation.relatedModelClass.ensureModelArray(relationJson, options); | ||
} else if (relationJson) { | ||
this[relationName] = relation.relatedModelClass.ensureModel(relationJson, options); | ||
} else { | ||
this[relationName] = null; | ||
} | ||
if (_lodash2.default.isArray(relationJson)) { | ||
this[relationName] = relation.relatedModelClass.ensureModelArray(relationJson, options); | ||
} else if (relationJson) { | ||
this[relationName] = relation.relatedModelClass.ensureModel(relationJson, options); | ||
} else { | ||
this[relationName] = null; | ||
} | ||
} | ||
} | ||
}; | ||
/** | ||
* @param {boolean=} shallow | ||
*/ | ||
/** | ||
* @param {boolean=} shallow | ||
*/ | ||
}, { | ||
key: '$toJson', | ||
value: function $toJson(shallow) { | ||
if (shallow) { | ||
return this.$$toJson(false, this.constructor.getRelations(), null); | ||
} else { | ||
return this.$$toJson(false, null, null); | ||
} | ||
Model.prototype.$toJson = function $toJson(shallow) { | ||
if (shallow) { | ||
return this.$$toJson(false, this.constructor.getRelations(), null); | ||
} else { | ||
return this.$$toJson(false, null, null); | ||
} | ||
}; | ||
/** | ||
* @override | ||
*/ | ||
/** | ||
* @override | ||
*/ | ||
}, { | ||
key: '$toDatabaseJson', | ||
value: function $toDatabaseJson() { | ||
var jsonSchema = this.constructor.jsonSchema; | ||
var pick = jsonSchema && jsonSchema.properties; | ||
var omit = undefined; | ||
if (!pick) { | ||
omit = this.constructor.getRelations(); | ||
} | ||
Model.prototype.$toDatabaseJson = function $toDatabaseJson() { | ||
var jsonSchema = this.constructor.jsonSchema; | ||
var pick = jsonSchema && jsonSchema.properties; | ||
var omit = void 0; | ||
return this.$$toJson(true, omit, pick); | ||
if (!pick) { | ||
omit = this.constructor.getRelations(); | ||
} | ||
/** | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
return this.$$toJson(true, omit, pick); | ||
}; | ||
}, { | ||
key: '$beforeInsert', | ||
value: function $beforeInsert(queryContext) {} | ||
/** | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
/** | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
}, { | ||
key: '$afterInsert', | ||
value: function $afterInsert(queryContext) {} | ||
Model.prototype.$beforeInsert = function $beforeInsert(queryContext) {}; | ||
/** | ||
* @param {ModelOptions} opt | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
/** | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
}, { | ||
key: '$beforeUpdate', | ||
value: function $beforeUpdate(opt, queryContext) {} | ||
/** | ||
* @param {ModelOptions} opt | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
Model.prototype.$afterInsert = function $afterInsert(queryContext) {}; | ||
}, { | ||
key: '$afterUpdate', | ||
value: function $afterUpdate(opt, queryContext) {} | ||
/** | ||
* @param {ModelOptions} opt | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}], [{ | ||
key: 'query', | ||
value: function query() { | ||
var ModelClass = this; | ||
Model.prototype.$beforeUpdate = function $beforeUpdate(opt, queryContext) {}; | ||
return ModelClass.QueryBuilder.forClass(ModelClass).relateImpl(function () { | ||
throw new Error('`relate` makes no sense in this context'); | ||
}).unrelateImpl(function () { | ||
throw new Error('`unrelate` makes no sense in this context'); | ||
}); | ||
} | ||
/** | ||
* @param {ModelOptions} opt | ||
* @param {Object} queryContext | ||
* @returns {Promise|*} | ||
*/ | ||
/** | ||
* @param {knex=} knex | ||
* @returns {knex} | ||
*/ | ||
}, { | ||
key: 'knex', | ||
value: function knex(_knex) { | ||
if (arguments.length) { | ||
this.$$knex = _knex; | ||
} else { | ||
var modelClass = this; | ||
Model.prototype.$afterUpdate = function $afterUpdate(opt, queryContext) {}; | ||
while (modelClass && !modelClass.$$knex) { | ||
var proto = modelClass.prototype.__proto__; | ||
modelClass = proto && proto.constructor; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
return modelClass && modelClass.$$knex; | ||
Model.query = function query() { | ||
var ModelClass = this; | ||
return ModelClass.QueryBuilder.forClass(ModelClass).relateOperationFactory(function () { | ||
throw new Error('`relate` makes no sense in this context'); | ||
}).unrelateOperationFactory(function () { | ||
throw new Error('`unrelate` makes no sense in this context'); | ||
}); | ||
}; | ||
/** | ||
* @param {knex=} knex | ||
* @returns {knex} | ||
*/ | ||
Model.knex = function knex(_knex) { | ||
if (arguments.length) { | ||
this.$$knex = _knex; | ||
} else { | ||
var modelClass = this; | ||
while (modelClass && !modelClass.$$knex) { | ||
var proto = modelClass.prototype.__proto__; | ||
modelClass = proto && proto.constructor; | ||
} | ||
return modelClass && modelClass.$$knex; | ||
} | ||
}; | ||
/** | ||
* @returns {knex} | ||
*/ | ||
/** | ||
* @returns {knex} | ||
*/ | ||
}, { | ||
key: 'transaction', | ||
value: function transaction() { | ||
return this.knex(); | ||
} | ||
/** | ||
* @return {Raw} | ||
*/ | ||
Model.transaction = function transaction() { | ||
return this.knex(); | ||
}; | ||
}, { | ||
key: 'raw', | ||
value: function raw() { | ||
var knex = this.knex(); | ||
return knex.raw.apply(knex, arguments); | ||
} | ||
/** | ||
* @return {Raw} | ||
*/ | ||
/** | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: 'fn', | ||
value: function fn() { | ||
var knex = this.knex(); | ||
return knex.fn; | ||
} | ||
Model.raw = function raw() { | ||
var knex = this.knex(); | ||
return knex.raw.apply(knex, arguments); | ||
}; | ||
/** | ||
* @return {Formatter} | ||
*/ | ||
/** | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: 'formatter', | ||
value: function formatter() { | ||
return this.knex().client.formatter(); | ||
} | ||
/** | ||
* @returns {knex.QueryBuilder} | ||
*/ | ||
Model.fn = function fn() { | ||
var knex = this.knex(); | ||
return knex.fn; | ||
}; | ||
}, { | ||
key: 'knexQuery', | ||
value: function knexQuery() { | ||
return this.knex().table(this.tableName); | ||
} | ||
/** | ||
* @return {Formatter} | ||
*/ | ||
/** | ||
* @param {knex} knex | ||
* @returns {Constructor.<Model>} | ||
*/ | ||
}, { | ||
key: 'bindKnex', | ||
value: function bindKnex(knex) { | ||
var ModelClass = this; | ||
Model.formatter = function formatter() { | ||
return this.knex().client.formatter(); | ||
}; | ||
if (!knex.$$objection) { | ||
knex.$$objection = {}; | ||
knex.$$objection.id = _lodash2.default.uniqueId(); | ||
knex.$$objection.boundModels = (0, _create2.default)(null); | ||
} | ||
/** | ||
* @returns {knex.QueryBuilder} | ||
*/ | ||
// Check if this model class has already been bound to the given knex. | ||
if (knex.$$objection.boundModels[ModelClass.tableName]) { | ||
return knex.$$objection.boundModels[ModelClass.tableName]; | ||
} | ||
// Create a new subclass of this class. | ||
var BoundModelClass = (0, _inheritModel2.default)(ModelClass); | ||
Model.knexQuery = function knexQuery() { | ||
return this.knex().table(this.tableName); | ||
}; | ||
BoundModelClass.knex(knex); | ||
knex.$$objection.boundModels[ModelClass.tableName] = BoundModelClass; | ||
/** | ||
* @param {knex} knex | ||
* @returns {Constructor.<Model>} | ||
*/ | ||
BoundModelClass.$$relations = _lodash2.default.reduce(ModelClass.getRelations(), function (relations, relation, relationName) { | ||
relations[relationName] = relation.bindKnex(knex); | ||
return relations; | ||
}, (0, _create2.default)(null)); | ||
return BoundModelClass; | ||
Model.bindKnex = function bindKnex(knex) { | ||
var ModelClass = this; | ||
if (!knex.$$objection) { | ||
knex.$$objection = {}; | ||
knex.$$objection.id = _lodash2.default.uniqueId(); | ||
knex.$$objection.boundModels = (0, _create2.default)(null); | ||
} | ||
/** | ||
* @param {knex} trx | ||
* @returns {Constructor.<Model>} | ||
*/ | ||
}, { | ||
key: 'bindTransaction', | ||
value: function bindTransaction(trx) { | ||
return this.bindKnex(trx); | ||
// Check if this model class has already been bound to the given knex. | ||
if (knex.$$objection.boundModels[ModelClass.tableName]) { | ||
return knex.$$objection.boundModels[ModelClass.tableName]; | ||
} | ||
/** | ||
* @param {Model|Object} model | ||
* @param {ModelOptions=} options | ||
* @returns {Model} | ||
*/ | ||
// Create a new subclass of this class. | ||
var BoundModelClass = (0, _inheritModel2.default)(ModelClass); | ||
}, { | ||
key: 'ensureModel', | ||
value: function ensureModel(model, options) { | ||
var ModelClass = this; | ||
BoundModelClass.knex(knex); | ||
knex.$$objection.boundModels[ModelClass.tableName] = BoundModelClass; | ||
if (!model) { | ||
return null; | ||
} | ||
// Bind all relations also. | ||
BoundModelClass.relations(_lodash2.default.reduce(ModelClass.getRelations(), function (relations, relation, relationName) { | ||
relations[relationName] = relation.bindKnex(knex); | ||
return relations; | ||
}, (0, _create2.default)(null))); | ||
if (model instanceof ModelClass) { | ||
return model; | ||
} else if (model instanceof Model) { | ||
throw new Error('model is already an instance of another Model'); | ||
} else { | ||
return ModelClass.fromJson(model, options); | ||
} | ||
return BoundModelClass; | ||
}; | ||
/** | ||
* @param {knex} trx | ||
* @returns {Constructor.<Model>} | ||
*/ | ||
Model.bindTransaction = function bindTransaction(trx) { | ||
return this.bindKnex(trx); | ||
}; | ||
/** | ||
* @param {Model|Object} model | ||
* @param {ModelOptions=} options | ||
* @returns {Model} | ||
*/ | ||
Model.ensureModel = function ensureModel(model, options) { | ||
var ModelClass = this; | ||
if (!model) { | ||
return null; | ||
} | ||
/** | ||
* @param {Array.<Model|Object>} input | ||
* @param {ModelOptions=} options | ||
* @returns {Array.<Model>} | ||
*/ | ||
if (model instanceof ModelClass) { | ||
return model; | ||
} else if (model instanceof Model) { | ||
throw new Error('model is already an instance of another Model'); | ||
} else { | ||
return ModelClass.fromJson(model, options); | ||
} | ||
}; | ||
}, { | ||
key: 'ensureModelArray', | ||
value: function ensureModelArray(input, options) { | ||
var ModelClass = this; | ||
/** | ||
* @param {Array.<Model|Object>} input | ||
* @param {ModelOptions=} options | ||
* @returns {Array.<Model>} | ||
*/ | ||
if (!input) { | ||
return []; | ||
} | ||
if (_lodash2.default.isArray(input)) { | ||
var models = new Array(input.length); | ||
Model.ensureModelArray = function ensureModelArray(input, options) { | ||
var ModelClass = this; | ||
for (var i = 0, l = input.length; i < l; ++i) { | ||
models[i] = ModelClass.ensureModel(input[i], options); | ||
} | ||
if (!input) { | ||
return []; | ||
} | ||
return models; | ||
} else { | ||
return [ModelClass.ensureModel(input, options)]; | ||
if (_lodash2.default.isArray(input)) { | ||
var models = new Array(input.length); | ||
for (var i = 0, l = input.length; i < l; ++i) { | ||
models[i] = ModelClass.ensureModel(input[i], options); | ||
} | ||
return models; | ||
} else { | ||
return [ModelClass.ensureModel(input, options)]; | ||
} | ||
}; | ||
/** | ||
* @returns {number} | ||
*/ | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
}, { | ||
key: 'getIdPropertyArray', | ||
value: function getIdPropertyArray() { | ||
var ModelClass = this; | ||
if (_lodash2.default.isArray(ModelClass.idColumn)) { | ||
return _lodash2.default.map(ModelClass.idColumn, function (col) { | ||
return idColumnToIdProperty(ModelClass, col); | ||
}); | ||
} else { | ||
return [idColumnToIdProperty(ModelClass, ModelClass.idColumn)]; | ||
} | ||
Model.getIdColumnArray = function getIdColumnArray() { | ||
var ModelClass = this; | ||
if (_lodash2.default.isArray(ModelClass.idColumn)) { | ||
return ModelClass.idColumn; | ||
} else { | ||
return [ModelClass.idColumn]; | ||
} | ||
}; | ||
/** | ||
* @returns {string|Array.<string>} | ||
*/ | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
}, { | ||
key: 'getIdProperty', | ||
value: function getIdProperty() { | ||
var ModelClass = this; | ||
if (_lodash2.default.isArray(ModelClass.idColumn)) { | ||
return _lodash2.default.map(ModelClass.idColumn, function (col) { | ||
return idColumnToIdProperty(ModelClass, col); | ||
}); | ||
} else { | ||
return idColumnToIdProperty(ModelClass, ModelClass.idColumn); | ||
} | ||
Model.getIdPropertyArray = function getIdPropertyArray() { | ||
var ModelClass = this; | ||
return _lodash2.default.map(ModelClass.getIdColumnArray(), function (col) { | ||
return idColumnToIdProperty(ModelClass, col); | ||
}); | ||
}; | ||
/** | ||
* @returns {string|Array.<string>} | ||
*/ | ||
Model.getIdProperty = function getIdProperty() { | ||
var ModelClass = this; | ||
if (_lodash2.default.isArray(ModelClass.idColumn)) { | ||
return _lodash2.default.map(ModelClass.idColumn, function (col) { | ||
return idColumnToIdProperty(ModelClass, col); | ||
}); | ||
} else { | ||
return idColumnToIdProperty(ModelClass, ModelClass.idColumn); | ||
} | ||
}; | ||
/** | ||
* @returns {string|Array.<string>} | ||
*/ | ||
/** | ||
* @returns {string|Array.<string>} | ||
*/ | ||
}, { | ||
key: 'getFullIdColumn', | ||
value: function getFullIdColumn() { | ||
var _this4 = this; | ||
if (_lodash2.default.isArray(this.idColumn)) { | ||
return _lodash2.default.map(this.idColumn, function (col) { | ||
return _this4.tableName + '.' + col; | ||
}); | ||
} else { | ||
return this.tableName + '.' + this.idColumn; | ||
} | ||
Model.getFullIdColumn = function getFullIdColumn() { | ||
var _this4 = this; | ||
if (_lodash2.default.isArray(this.idColumn)) { | ||
return _lodash2.default.map(this.idColumn, function (col) { | ||
return _this4.tableName + '.' + col; | ||
}); | ||
} else { | ||
return this.tableName + '.' + this.idColumn; | ||
} | ||
}; | ||
/** | ||
* @return {Object.<string, Relation>} | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: 'getRelations', | ||
value: function getRelations() { | ||
var ModelClass = this; | ||
if (!this.$$relations) { | ||
// Lazy-load the relations to prevent require loops. | ||
this.$$relations = _lodash2.default.reduce(this.relationMappings, function (relations, mapping, relationName) { | ||
Model.relations = function relations(_relations) {}; | ||
/** | ||
* @return {Object.<string, Relation>} | ||
*/ | ||
Model.getRelations = function getRelations() { | ||
var _this5 = this; | ||
var relations = this.relations(); | ||
if (!relations) { | ||
(function () { | ||
var ModelClass = _this5; | ||
relations = _lodash2.default.reduce(_this5.relationMappings, function (relations, mapping, relationName) { | ||
relations[relationName] = new mapping.relation(relationName, ModelClass); | ||
@@ -683,113 +665,113 @@ relations[relationName].setMapping(mapping); | ||
}, (0, _create2.default)(null)); | ||
} | ||
return this.$$relations; | ||
_this5.relations(relations); | ||
})(); | ||
} | ||
/** | ||
* @return {Relation} | ||
*/ | ||
return relations; | ||
}; | ||
}, { | ||
key: 'getRelation', | ||
value: function getRelation(name) { | ||
var relation = this.getRelations()[name]; | ||
/** | ||
* @return {Relation} | ||
*/ | ||
if (!relation) { | ||
throw new Error("model class '" + this.name + "' doesn't have relation '" + name + "'"); | ||
} | ||
return relation; | ||
Model.getRelation = function getRelation(name) { | ||
var relation = this.getRelations()[name]; | ||
if (!relation) { | ||
throw new Error("model class '" + this.name + "' doesn't have relation '" + name + "'"); | ||
} | ||
/** | ||
* @param {Array.<Model|Object>} $models | ||
* @param {string|RelationExpression} expression | ||
* @param {Object.<string, function(QueryBuilder)>=} filters | ||
* @returns {Promise} | ||
*/ | ||
return relation; | ||
}; | ||
}, { | ||
key: 'loadRelated', | ||
value: function loadRelated($models, expression, filters) { | ||
if (!(expression instanceof _RelationExpression2.default)) { | ||
expression = _RelationExpression2.default.parse(expression); | ||
} | ||
/** | ||
* @param {Array.<Model|Object>} $models | ||
* @param {string|RelationExpression} expression | ||
* @param {Object.<string, function(QueryBuilder)>=} filters | ||
* @returns {Promise} | ||
*/ | ||
return new _EagerFetcher2.default({ | ||
modelClass: this, | ||
models: this.ensureModelArray($models), | ||
eager: expression, | ||
filters: filters | ||
}).fetch().then(function (models) { | ||
return _lodash2.default.isArray($models) ? models : models[0]; | ||
}); | ||
Model.loadRelated = function loadRelated($models, expression, filters) { | ||
if (!(expression instanceof _RelationExpression2.default)) { | ||
expression = _RelationExpression2.default.parse(expression); | ||
} | ||
/** | ||
* @param {Constructor.<Model>=} filterConstructor | ||
* @param {Model|Array.<Model>} models | ||
* @param {function(Model, Model, string)} traverser | ||
* @return {Model} | ||
*/ | ||
return new _EagerFetcher2.default({ | ||
modelClass: this, | ||
models: this.ensureModelArray($models), | ||
eager: expression, | ||
filters: filters | ||
}).fetch().then(function (models) { | ||
return _lodash2.default.isArray($models) ? models : models[0]; | ||
}); | ||
}; | ||
}, { | ||
key: 'traverse', | ||
value: function traverse(filterConstructor, models, traverser) { | ||
filterConstructor = filterConstructor || null; | ||
/** | ||
* @param {Constructor.<Model>=} filterConstructor | ||
* @param {Model|Array.<Model>} models | ||
* @param {function(Model, Model, string)} traverser | ||
* @return {Model} | ||
*/ | ||
if (_lodash2.default.isUndefined(traverser)) { | ||
traverser = models; | ||
models = filterConstructor; | ||
filterConstructor = null; | ||
} | ||
if (!_lodash2.default.isFunction(traverser)) { | ||
throw new Error('traverser must be a function'); | ||
} | ||
Model.traverse = function traverse(filterConstructor, models, traverser) { | ||
filterConstructor = filterConstructor || null; | ||
_traverse(models, null, null, filterConstructor, traverser); | ||
return this; | ||
if (_lodash2.default.isUndefined(traverser)) { | ||
traverser = models; | ||
models = filterConstructor; | ||
filterConstructor = null; | ||
} | ||
/** | ||
* @protected | ||
* @returns {Array.<string>} | ||
*/ | ||
if (!_lodash2.default.isFunction(traverser)) { | ||
throw new Error('traverser must be a function'); | ||
} | ||
}, { | ||
key: '$$getJsonAttributes', | ||
value: function $$getJsonAttributes() { | ||
var _this5 = this; | ||
_traverse(models, null, null, filterConstructor, traverser); | ||
return this; | ||
}; | ||
// If the jsonAttributes property is not set, try to create it based | ||
// on the jsonSchema. All properties that are objects or arrays must | ||
// be converted to JSON. | ||
if (!this.jsonAttributes && this.jsonSchema) { | ||
this.jsonAttributes = []; | ||
/** | ||
* @protected | ||
* @returns {Array.<string>} | ||
*/ | ||
_lodash2.default.each(this.jsonSchema.properties, function (prop, propName) { | ||
var types = _lodash2.default.compact(ensureArray(prop.type)); | ||
if (types.length === 0 && _lodash2.default.isArray(prop.anyOf)) { | ||
types = _lodash2.default.flattenDeep(_lodash2.default.pluck(prop.anyOf, 'type')); | ||
} | ||
Model.$$getJsonAttributes = function $$getJsonAttributes() { | ||
var _this6 = this; | ||
if (types.length === 0 && _lodash2.default.isArray(prop.oneOf)) { | ||
types = _lodash2.default.flattenDeep(_lodash2.default.pluck(prop.oneOf, 'type')); | ||
} | ||
// If the jsonAttributes property is not set, try to create it based | ||
// on the jsonSchema. All properties that are objects or arrays must | ||
// be converted to JSON. | ||
if (!this.jsonAttributes && this.jsonSchema) { | ||
this.jsonAttributes = []; | ||
if (_lodash2.default.contains(types, 'object') || _lodash2.default.contains(types, 'array')) { | ||
_this5.jsonAttributes.push(propName); | ||
} | ||
}); | ||
} | ||
_lodash2.default.each(this.jsonSchema.properties, function (prop, propName) { | ||
var types = _lodash2.default.compact(ensureArray(prop.type)); | ||
if (!_lodash2.default.isArray(this.jsonAttributes)) { | ||
this.jsonAttributes = []; | ||
} | ||
if (types.length === 0 && _lodash2.default.isArray(prop.anyOf)) { | ||
types = _lodash2.default.flattenDeep(_lodash2.default.map(prop.anyOf, 'type')); | ||
} | ||
return this.jsonAttributes; | ||
if (types.length === 0 && _lodash2.default.isArray(prop.oneOf)) { | ||
types = _lodash2.default.flattenDeep(_lodash2.default.map(prop.oneOf, 'type')); | ||
} | ||
if (_lodash2.default.includes(types, 'object') || _lodash2.default.includes(types, 'array')) { | ||
_this6.jsonAttributes.push(propName); | ||
} | ||
}); | ||
} | ||
}, { | ||
if (!_lodash2.default.isArray(this.jsonAttributes)) { | ||
this.jsonAttributes = []; | ||
} | ||
return this.jsonAttributes; | ||
}; | ||
(0, _createClass3.default)(Model, null, [{ | ||
key: 'OneToOneRelation', | ||
@@ -809,2 +791,3 @@ get: function get() { | ||
/** | ||
@@ -814,2 +797,3 @@ * @type {string|Array.<string>} | ||
/** | ||
@@ -819,2 +803,3 @@ * @type {string} | ||
/** | ||
@@ -824,2 +809,3 @@ * @type {string} | ||
/** | ||
@@ -829,2 +815,3 @@ * @type {RegExp} | ||
/** | ||
@@ -834,2 +821,3 @@ * @type {Array.<string>} | ||
/** | ||
@@ -839,5 +827,2 @@ * @type {Object.<string, RelationMapping>} | ||
/** | ||
* @private | ||
*/ | ||
@@ -850,5 +835,6 @@ /** | ||
return Model; | ||
}(_ModelBase3.default), _class2.QueryBuilder = _QueryBuilder2.default, _class2.RelatedQueryBuilder = _QueryBuilder2.default, _class2.HasOneRelation = _HasOneRelation2.default, _class2.BelongsToOneRelation = _BelongsToOneRelation2.default, _class2.HasManyRelation = _HasManyRelation2.default, _class2.ManyToManyRelation = _ManyToManyRelation2.default, _class2.tableName = null, _class2.idColumn = 'id', _class2.uidProp = '#id', _class2.uidRefProp = '#ref', _class2.propRefRegex = /#ref{([^\.]+)\.([^}]+)}/g, _class2.jsonAttributes = null, _class2.relationMappings = null, _class2.$$knex = null, _class2.$$relations = null, _temp), (_applyDecoratedDescriptor(_class, 'OneToOneRelation', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class, 'OneToOneRelation'), _class), _applyDecoratedDescriptor(_class, 'OneToManyRelation', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class, 'OneToManyRelation'), _class), _applyDecoratedDescriptor(_class, 'getIdPropertyArray', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdPropertyArray'), _class), _applyDecoratedDescriptor(_class, 'getIdProperty', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdProperty'), _class), _applyDecoratedDescriptor(_class, 'getFullIdColumn', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getFullIdColumn'), _class)), _class)); | ||
}(_ModelBase3.default), _class2.QueryBuilder = _QueryBuilder2.default, _class2.RelatedQueryBuilder = _QueryBuilder2.default, _class2.HasOneRelation = _HasOneRelation2.default, _class2.HasManyRelation = _HasManyRelation2.default, _class2.ManyToManyRelation = _ManyToManyRelation2.default, _class2.BelongsToOneRelation = _BelongsToOneRelation2.default, _class2.tableName = null, _class2.idColumn = 'id', _class2.uidProp = '#id', _class2.uidRefProp = '#ref', _class2.propRefRegex = /#ref{([^\.]+)\.([^}]+)}/g, _class2.jsonAttributes = null, _class2.relationMappings = null, _class2.$$knex = null, _temp), (_applyDecoratedDescriptor(_class, 'OneToOneRelation', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class, 'OneToOneRelation'), _class), _applyDecoratedDescriptor(_class, 'OneToManyRelation', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class, 'OneToManyRelation'), _class), _applyDecoratedDescriptor(_class, 'getIdColumnArray', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdColumnArray'), _class), _applyDecoratedDescriptor(_class, 'getIdPropertyArray', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdPropertyArray'), _class), _applyDecoratedDescriptor(_class, 'getIdProperty', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdProperty'), _class), _applyDecoratedDescriptor(_class, 'getFullIdColumn', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getFullIdColumn'), _class), _applyDecoratedDescriptor(_class, 'relations', [_dec3], (0, _getOwnPropertyDescriptor2.default)(_class, 'relations'), _class)), _class)); | ||
exports.default = Model; | ||
function ensureArray(obj) { | ||
@@ -855,0 +841,0 @@ if (_lodash2.default.isArray(obj)) { |
'use strict'; | ||
var _dec, _dec2, _dec3, _desc, _value, _class, _class2, _temp; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -18,6 +16,4 @@ value: true | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _dec, _dec2, _dec3, _desc, _value, _class, _class2, _temp; | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _lodash = require('lodash'); | ||
@@ -96,441 +92,415 @@ | ||
(0, _createClass3.default)(ModelBase, [{ | ||
key: '$beforeValidate', | ||
/** | ||
* @param {Object} jsonSchema | ||
* @param {Object} json | ||
* @param {ModelOptions=} options | ||
* @return {Object} | ||
*/ | ||
/** | ||
* @param {Object} jsonSchema | ||
* @param {Object} json | ||
* @param {ModelOptions=} options | ||
* @return {Object} | ||
*/ | ||
value: function $beforeValidate(jsonSchema, json, options) { | ||
/* istanbul ignore next */ | ||
return jsonSchema; | ||
} | ||
ModelBase.prototype.$beforeValidate = function $beforeValidate(jsonSchema, json, options) { | ||
/* istanbul ignore next */ | ||
return jsonSchema; | ||
}; | ||
/** | ||
* @throws {ValidationError} | ||
* @param {Object=} json | ||
* @param {ModelOptions=} options | ||
* @return {Object} | ||
*/ | ||
/** | ||
* @throws {ValidationError} | ||
* @param {Object=} json | ||
* @param {ModelOptions=} options | ||
* @return {Object} | ||
*/ | ||
/** | ||
* @type {Object} | ||
*/ | ||
}, { | ||
key: '$validate', | ||
value: function $validate() { | ||
var json = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0]; | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
/** | ||
* @type {Object} | ||
*/ | ||
var ModelClass = this.constructor; | ||
var jsonSchema = ModelClass.jsonSchema; | ||
if (!jsonSchema || options.skipValidation) { | ||
return json; | ||
} | ||
ModelBase.prototype.$validate = function $validate() { | ||
var json = arguments.length <= 0 || arguments[0] === undefined ? this : arguments[0]; | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
// No need to call $beforeValidate (and clone the jsonSchema) if $beforeValidate has not been overwritten. | ||
if (this.$beforeValidate !== ModelBase.prototype.$beforeValidate) { | ||
jsonSchema = _lodash2.default.cloneDeep(jsonSchema); | ||
jsonSchema = this.$beforeValidate(jsonSchema, json, options); | ||
} | ||
var ModelClass = this.constructor; | ||
var jsonSchema = ModelClass.jsonSchema; | ||
var report = tryValidate(jsonSchema, json, options); | ||
var validationError = parseValidationError(report); | ||
if (!jsonSchema || options.skipValidation) { | ||
return json; | ||
} | ||
if (validationError) { | ||
throw validationError; | ||
} | ||
// No need to call $beforeValidate (and clone the jsonSchema) if $beforeValidate has not been overwritten. | ||
if (this.$beforeValidate !== ModelBase.prototype.$beforeValidate) { | ||
jsonSchema = _lodash2.default.cloneDeep(jsonSchema); | ||
jsonSchema = this.$beforeValidate(jsonSchema, json, options); | ||
} | ||
this.$afterValidate(json, options); | ||
return json; | ||
var report = tryValidate(jsonSchema, json, options); | ||
var validationError = parseValidationError(report); | ||
if (validationError) { | ||
throw validationError; | ||
} | ||
/** | ||
* @param {Object=} json | ||
* @param {ModelOptions=} options | ||
*/ | ||
this.$afterValidate(json, options); | ||
return json; | ||
}; | ||
}, { | ||
key: '$afterValidate', | ||
value: function $afterValidate(json, options) {} | ||
// Do nothing by default. | ||
/** | ||
* @param {Object=} json | ||
* @param {ModelOptions=} options | ||
*/ | ||
/** | ||
* @param {Object} json | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: '$parseDatabaseJson', | ||
value: function $parseDatabaseJson(json) { | ||
return json; | ||
} | ||
ModelBase.prototype.$afterValidate = function $afterValidate(json, options) {} | ||
// Do nothing by default. | ||
/** | ||
* @param {Object} json | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: '$formatDatabaseJson', | ||
value: function $formatDatabaseJson(json) { | ||
return json; | ||
} | ||
/** | ||
* @param {Object} json | ||
* @return {Object} | ||
*/ | ||
; | ||
/** | ||
* @param {Object} json | ||
* @param {ModelOptions=} options | ||
* @return {Object} | ||
*/ | ||
ModelBase.prototype.$parseDatabaseJson = function $parseDatabaseJson(json) { | ||
return json; | ||
}; | ||
}, { | ||
key: '$parseJson', | ||
value: function $parseJson(json, options) { | ||
return json; | ||
} | ||
/** | ||
* @param {Object} json | ||
* @return {Object} | ||
*/ | ||
/** | ||
* @param {Object} json | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: '$formatJson', | ||
value: function $formatJson(json) { | ||
return json; | ||
} | ||
ModelBase.prototype.$formatDatabaseJson = function $formatDatabaseJson(json) { | ||
return json; | ||
}; | ||
/** | ||
* @return {Object} | ||
*/ | ||
/** | ||
* @param {Object} json | ||
* @param {ModelOptions=} options | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: '$toDatabaseJson', | ||
value: function $toDatabaseJson() { | ||
return this.$$toJson(true, null, null); | ||
} | ||
/** | ||
* @return {Object} | ||
*/ | ||
ModelBase.prototype.$parseJson = function $parseJson(json, options) { | ||
return json; | ||
}; | ||
}, { | ||
key: '$toJson', | ||
value: function $toJson() { | ||
return this.$$toJson(false, null, null); | ||
} | ||
}, { | ||
key: 'toJSON', | ||
value: function toJSON() { | ||
return this.$toJson(); | ||
} | ||
/** | ||
* @param {Object} json | ||
* @return {Object} | ||
*/ | ||
/** | ||
* @param {Object} json | ||
* @param {ModelOptions=} options | ||
* @returns {ModelBase} | ||
* @throws ValidationError | ||
*/ | ||
}, { | ||
key: '$setJson', | ||
value: function $setJson(json) { | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
ModelBase.prototype.$formatJson = function $formatJson(json) { | ||
return json; | ||
}; | ||
json = json || {}; | ||
/** | ||
* @return {Object} | ||
*/ | ||
if (!_lodash2.default.isObject(json) || _lodash2.default.isString(json) || _lodash2.default.isNumber(json) || _lodash2.default.isDate(json) || _lodash2.default.isArray(json) || _lodash2.default.isFunction(json) || _lodash2.default.isTypedArray(json) || _lodash2.default.isRegExp(json)) { | ||
throw new Error('You should only pass objects to $setJson method. ' + '$setJson method was given an invalid value ' + json); | ||
} | ||
ModelBase.prototype.$toDatabaseJson = function $toDatabaseJson() { | ||
return this.$$toJson(true, null, null); | ||
}; | ||
if (!options.patch) { | ||
json = mergeWithDefaults(this.constructor.jsonSchema, json); | ||
} | ||
/** | ||
* @return {Object} | ||
*/ | ||
// If the json contains query properties like, knex Raw queries or knex/objection query | ||
// builders, we need to split those off into a separate object. This object will be | ||
// joined back in the $toDatabaseJson method. | ||
var split = (0, _splitQueryProps2.default)(this.constructor, json); | ||
if (split.query) { | ||
// Stash the query properties for later use in $toDatabaseJson method. | ||
this.$stashedQueryProps(split.query); | ||
} | ||
ModelBase.prototype.$toJson = function $toJson() { | ||
return this.$$toJson(false, null, null); | ||
}; | ||
split.json = this.$parseJson(split.json, options); | ||
split.json = this.$validate(split.json, options); | ||
ModelBase.prototype.toJSON = function toJSON() { | ||
return this.$toJson(); | ||
}; | ||
return this.$set(split.json); | ||
} | ||
/** | ||
* @param {Object} json | ||
* @param {ModelOptions=} options | ||
* @returns {ModelBase} | ||
* @throws ValidationError | ||
*/ | ||
/** | ||
* @param {Object} json | ||
* @returns {ModelBase} | ||
*/ | ||
}, { | ||
key: '$setDatabaseJson', | ||
value: function $setDatabaseJson() { | ||
var json = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
ModelBase.prototype.$setJson = function $setJson(json) { | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
json = this.$parseDatabaseJson(json); | ||
json = json || {}; | ||
for (var key in json) { | ||
this[key] = json[key]; | ||
} | ||
if (!_lodash2.default.isObject(json) || _lodash2.default.isString(json) || _lodash2.default.isNumber(json) || _lodash2.default.isDate(json) || _lodash2.default.isArray(json) || _lodash2.default.isFunction(json) || _lodash2.default.isTypedArray(json) || _lodash2.default.isRegExp(json)) { | ||
return this; | ||
throw new Error('You should only pass objects to $setJson method. ' + '$setJson method was given an invalid value ' + json); | ||
} | ||
/** | ||
* @param {Object} obj | ||
* @returns {ModelBase} | ||
*/ | ||
if (!options.patch) { | ||
json = mergeWithDefaults(this.constructor.jsonSchema, json); | ||
} | ||
}, { | ||
key: '$set', | ||
value: function $set(obj) { | ||
var self = this; | ||
// If the json contains query properties like, knex Raw queries or knex/objection query | ||
// builders, we need to split those off into a separate object. This object will be | ||
// joined back in the $toDatabaseJson method. | ||
var split = (0, _splitQueryProps2.default)(this.constructor, json); | ||
_lodash2.default.each(obj, function (value, key) { | ||
if (key.charAt(0) !== '$' && !_lodash2.default.isFunction(value)) { | ||
self[key] = value; | ||
} | ||
}); | ||
return this; | ||
if (split.query) { | ||
// Stash the query properties for later use in $toDatabaseJson method. | ||
this.$stashedQueryProps(split.query); | ||
} | ||
/** | ||
* @param {Array.<string>=} keys | ||
* @returns {Array.<string>} | ||
*/ | ||
split.json = this.$parseJson(split.json, options); | ||
split.json = this.$validate(split.json, options); | ||
}, { | ||
key: '$omitFromJson', | ||
value: function $omitFromJson(keys) {} | ||
return this.$set(split.json); | ||
}; | ||
/** | ||
* @param {Array.<string>=} keys | ||
* @returns {Array.<string>} | ||
*/ | ||
/** | ||
* @param {Object} json | ||
* @returns {ModelBase} | ||
*/ | ||
}, { | ||
key: '$omitFromDatabaseJson', | ||
value: function $omitFromDatabaseJson(keys) {} | ||
/** | ||
* @param {Object=} queryProps | ||
* @returns {Object} | ||
*/ | ||
ModelBase.prototype.$setDatabaseJson = function $setDatabaseJson() { | ||
var json = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
}, { | ||
key: '$stashedQueryProps', | ||
value: function $stashedQueryProps(queryProps) {} | ||
json = this.$parseDatabaseJson(json); | ||
/** | ||
* @param {string|Array.<string>|Object.<string, boolean>} keys | ||
* @returns {ModelBase} | ||
*/ | ||
for (var key in json) { | ||
this[key] = json[key]; | ||
} | ||
}, { | ||
key: '$omit', | ||
value: function $omit() { | ||
if (arguments.length === 1 && _lodash2.default.isObject(arguments[0])) { | ||
var keys = arguments[0]; | ||
return this; | ||
}; | ||
if (_lodash2.default.isArray(keys)) { | ||
omitArray(this, keys); | ||
} else { | ||
omitObject(this, keys); | ||
} | ||
} else { | ||
omitArray(this, _lodash2.default.toArray(arguments)); | ||
/** | ||
* @param {Object} obj | ||
* @returns {ModelBase} | ||
*/ | ||
ModelBase.prototype.$set = function $set(obj) { | ||
var self = this; | ||
_lodash2.default.each(obj, function (value, key) { | ||
if (key.charAt(0) !== '$' && !_lodash2.default.isFunction(value)) { | ||
self[key] = value; | ||
} | ||
}); | ||
return this; | ||
} | ||
return this; | ||
}; | ||
/** | ||
* @param {string|Array.<string>|Object.<string, boolean>} keys | ||
* @returns {ModelBase} `this` for chaining. | ||
*/ | ||
/** | ||
* @param {Array.<string>=} keys | ||
* @returns {Array.<string>} | ||
*/ | ||
}, { | ||
key: '$pick', | ||
value: function $pick() { | ||
if (arguments.length === 1 && _lodash2.default.isObject(arguments[0])) { | ||
var keys = arguments[0]; | ||
if (_lodash2.default.isArray(keys)) { | ||
pickArray(this, keys); | ||
} else { | ||
pickObject(this, keys); | ||
} | ||
ModelBase.prototype.$omitFromJson = function $omitFromJson(keys) {}; | ||
/** | ||
* @param {Array.<string>=} keys | ||
* @returns {Array.<string>} | ||
*/ | ||
ModelBase.prototype.$omitFromDatabaseJson = function $omitFromDatabaseJson(keys) {}; | ||
/** | ||
* @param {Object=} queryProps | ||
* @returns {Object} | ||
*/ | ||
ModelBase.prototype.$stashedQueryProps = function $stashedQueryProps(queryProps) {}; | ||
/** | ||
* @param {string|Array.<string>|Object.<string, boolean>} keys | ||
* @returns {ModelBase} | ||
*/ | ||
ModelBase.prototype.$omit = function $omit() { | ||
if (arguments.length === 1 && _lodash2.default.isObject(arguments[0])) { | ||
var keys = arguments[0]; | ||
if (_lodash2.default.isArray(keys)) { | ||
omitArray(this, keys); | ||
} else { | ||
pickArray(this, _lodash2.default.toArray(arguments)); | ||
omitObject(this, keys); | ||
} | ||
return this; | ||
} else { | ||
omitArray(this, _lodash2.default.toArray(arguments)); | ||
} | ||
/** | ||
* @param {Array.<string>} props | ||
* @return {Array.<*>} | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: '$values', | ||
value: function $values() { | ||
var _this = this; | ||
/** | ||
* @param {string|Array.<string>|Object.<string, boolean>} keys | ||
* @returns {ModelBase} `this` for chaining. | ||
*/ | ||
if (arguments.length === 0) { | ||
return _lodash2.default.values(this); | ||
} else if (arguments.length === 1 && _lodash2.default.isArray(arguments[0])) { | ||
return _lodash2.default.map(arguments[0], function (prop) { | ||
return _this[prop]; | ||
}); | ||
ModelBase.prototype.$pick = function $pick() { | ||
if (arguments.length === 1 && _lodash2.default.isObject(arguments[0])) { | ||
var keys = arguments[0]; | ||
if (_lodash2.default.isArray(keys)) { | ||
pickArray(this, keys); | ||
} else { | ||
return _lodash2.default.map(arguments, function (prop) { | ||
return _this[prop]; | ||
}); | ||
pickObject(this, keys); | ||
} | ||
} else { | ||
pickArray(this, _lodash2.default.toArray(arguments)); | ||
} | ||
/** | ||
* @return {ModelBase} | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: '$clone', | ||
value: function $clone() { | ||
var clone = new this.constructor(); | ||
/** | ||
* @param {Array.<string>} props | ||
* @return {Array.<*>} | ||
*/ | ||
_lodash2.default.each(this, function (value, key) { | ||
if (_lodash2.default.isObject(value)) { | ||
clone[key] = cloneObject(value); | ||
} else { | ||
clone[key] = value; | ||
} | ||
ModelBase.prototype.$values = function $values() { | ||
var _this = this; | ||
if (arguments.length === 0) { | ||
return _lodash2.default.values(this); | ||
} else if (arguments.length === 1 && _lodash2.default.isArray(arguments[0])) { | ||
return _lodash2.default.map(arguments[0], function (prop) { | ||
return _this[prop]; | ||
}); | ||
return clone; | ||
} else { | ||
return _lodash2.default.map(arguments, function (prop) { | ||
return _this[prop]; | ||
}); | ||
} | ||
}; | ||
/** | ||
* @protected | ||
*/ | ||
/** | ||
* @return {ModelBase} | ||
*/ | ||
}, { | ||
key: '$$toJson', | ||
value: function $$toJson(createDbJson, omit, pick) { | ||
var json = toJsonImpl(this, createDbJson, omit, pick); | ||
if (createDbJson) { | ||
return this.$formatDatabaseJson(json); | ||
ModelBase.prototype.$clone = function $clone() { | ||
var clone = new this.constructor(); | ||
_lodash2.default.each(this, function (value, key) { | ||
if (_lodash2.default.isObject(value)) { | ||
clone[key] = cloneObject(value); | ||
} else { | ||
return this.$formatJson(json); | ||
clone[key] = value; | ||
} | ||
} | ||
}); | ||
/** | ||
* @param {function=} subclassConstructor | ||
* @return {Constructor.<ModelBase>} | ||
*/ | ||
return clone; | ||
}; | ||
}], [{ | ||
key: 'extend', | ||
value: function extend(subclassConstructor) { | ||
if (_lodash2.default.isEmpty(subclassConstructor.name)) { | ||
throw new Error('Each ModelBase subclass constructor must have a name'); | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
(0, _classUtils.inherits)(subclassConstructor, this); | ||
return subclassConstructor; | ||
} | ||
/** | ||
* @param {Object=} json | ||
* @param {ModelOptions=} options | ||
* @returns {Model} | ||
* @throws ValidationError | ||
*/ | ||
ModelBase.prototype.$$toJson = function $$toJson(createDbJson, omit, pick) { | ||
var json = toJsonImpl(this, createDbJson, omit, pick); | ||
}, { | ||
key: 'fromJson', | ||
value: function fromJson(json, options) { | ||
var model = new this(); | ||
model.$setJson(json || {}, options); | ||
return model; | ||
if (createDbJson) { | ||
return this.$formatDatabaseJson(json); | ||
} else { | ||
return this.$formatJson(json); | ||
} | ||
}; | ||
/** | ||
* @param {Object=} json | ||
* @returns {Model} | ||
*/ | ||
/** | ||
* @param {function=} subclassConstructor | ||
* @return {Constructor.<ModelBase>} | ||
*/ | ||
}, { | ||
key: 'fromDatabaseJson', | ||
value: function fromDatabaseJson(json) { | ||
var model = new this(); | ||
model.$setDatabaseJson(json || {}); | ||
return model; | ||
ModelBase.extend = function extend(subclassConstructor) { | ||
if (_lodash2.default.isEmpty(subclassConstructor.name)) { | ||
throw new Error('Each ModelBase subclass constructor must have a name'); | ||
} | ||
/** | ||
* @param {Object} obj | ||
* @param {string} prop | ||
*/ | ||
(0, _classUtils.inherits)(subclassConstructor, this); | ||
return subclassConstructor; | ||
}; | ||
}, { | ||
key: 'omitImpl', | ||
value: function omitImpl(obj, prop) { | ||
obj[prop] = undefined; | ||
} | ||
/** | ||
* @param {Object=} json | ||
* @param {ModelOptions=} options | ||
* @returns {Model} | ||
* @throws ValidationError | ||
*/ | ||
/** | ||
* @param {string} columnName | ||
* @returns {string} | ||
*/ | ||
}, { | ||
key: 'columnNameToPropertyName', | ||
value: function columnNameToPropertyName(columnName) { | ||
var model = new this(); | ||
var addedProps = _lodash2.default.keys(model.$parseDatabaseJson({})); | ||
ModelBase.fromJson = function fromJson(json, options) { | ||
var model = new this(); | ||
model.$setJson(json || {}, options); | ||
return model; | ||
}; | ||
var row = {}; | ||
row[columnName] = null; | ||
/** | ||
* @param {Object=} json | ||
* @returns {Model} | ||
*/ | ||
var props = _lodash2.default.keys(_lodash2.default.omit(model.$parseDatabaseJson(row), addedProps)); | ||
var propertyName = _lodash2.default.first(props); | ||
return propertyName || null; | ||
} | ||
ModelBase.fromDatabaseJson = function fromDatabaseJson(json) { | ||
var model = new this(); | ||
model.$setDatabaseJson(json || {}); | ||
return model; | ||
}; | ||
/** | ||
* @param {string} propertyName | ||
* @returns {string} | ||
*/ | ||
/** | ||
* @param {Object} obj | ||
* @param {string} prop | ||
*/ | ||
}, { | ||
key: 'propertyNameToColumnName', | ||
value: function propertyNameToColumnName(propertyName) { | ||
var model = new this(); | ||
var addedCols = _lodash2.default.keys(model.$formatDatabaseJson({})); | ||
var obj = {}; | ||
obj[propertyName] = null; | ||
ModelBase.omitImpl = function omitImpl(obj, prop) { | ||
obj[prop] = undefined; | ||
}; | ||
var cols = _lodash2.default.keys(_lodash2.default.omit(model.$formatDatabaseJson(obj), addedCols)); | ||
var columnName = _lodash2.default.first(cols); | ||
/** | ||
* @param {string} columnName | ||
* @returns {string} | ||
*/ | ||
return columnName || null; | ||
} | ||
}]); | ||
ModelBase.columnNameToPropertyName = function columnNameToPropertyName(columnName) { | ||
var model = new this(); | ||
var addedProps = _lodash2.default.keys(model.$parseDatabaseJson({})); | ||
var row = {}; | ||
row[columnName] = null; | ||
var props = _lodash2.default.keys(_lodash2.default.omit(model.$parseDatabaseJson(row), addedProps)); | ||
var propertyName = _lodash2.default.first(props); | ||
return propertyName || null; | ||
}; | ||
/** | ||
* @param {string} propertyName | ||
* @returns {string} | ||
*/ | ||
ModelBase.propertyNameToColumnName = function propertyNameToColumnName(propertyName) { | ||
var model = new this(); | ||
var addedCols = _lodash2.default.keys(model.$formatDatabaseJson({})); | ||
var obj = {}; | ||
obj[propertyName] = null; | ||
var cols = _lodash2.default.keys(_lodash2.default.omit(model.$formatDatabaseJson(obj), addedCols)); | ||
var columnName = _lodash2.default.first(cols); | ||
return columnName || null; | ||
}; | ||
return ModelBase; | ||
@@ -540,2 +510,3 @@ }(), _class2.jsonSchema = null, _temp), (_applyDecoratedDescriptor(_class.prototype, '$omitFromJson', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, '$omitFromJson'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, '$omitFromDatabaseJson', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, '$omitFromDatabaseJson'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, '$stashedQueryProps', [_dec3], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, '$stashedQueryProps'), _class.prototype), _applyDecoratedDescriptor(_class, 'columnNameToPropertyName', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'columnNameToPropertyName'), _class), _applyDecoratedDescriptor(_class, 'propertyNameToColumnName', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'propertyNameToColumnName'), _class)), _class)); | ||
function mergeWithDefaults(jsonSchema, json) { | ||
@@ -574,3 +545,3 @@ var merged = null; | ||
function tryValidate(jsonSchema, json, options) { | ||
var required = undefined; | ||
var required = void 0; | ||
@@ -577,0 +548,0 @@ try { |
@@ -6,3 +6,3 @@ 'use strict'; | ||
}); | ||
exports.Promise = exports.transaction = exports.ManyToManyRelation = exports.BelongsToOneRelation = exports.HasManyRelation = exports.HasOneRelation = exports.Relation = exports.ValidationError = exports.RelationExpression = exports.QueryBuilderBase = exports.QueryBuilder = exports.Model = exports.ModelBase = undefined; | ||
exports.Promise = exports.transaction = exports.ManyToManyRelation = exports.BelongsToOneRelation = exports.HasManyRelation = exports.HasOneRelation = exports.Relation = exports.ValidationError = exports.RelationExpression = exports.QueryBuilderOperation = exports.QueryBuilderBase = exports.QueryBuilder = exports.Model = exports.ModelBase = undefined; | ||
@@ -25,2 +25,6 @@ var _ModelBase = require('./model/ModelBase'); | ||
var _QueryBuilderOperation = require('./queryBuilder/operations/QueryBuilderOperation'); | ||
var _QueryBuilderOperation2 = _interopRequireDefault(_QueryBuilderOperation); | ||
var _RelationExpression = require('./queryBuilder/RelationExpression'); | ||
@@ -38,15 +42,15 @@ | ||
var _HasOneRelation = require('./relations/HasOneRelation'); | ||
var _HasOneRelation = require('./relations/hasOne/HasOneRelation'); | ||
var _HasOneRelation2 = _interopRequireDefault(_HasOneRelation); | ||
var _HasManyRelation = require('./relations/HasManyRelation'); | ||
var _HasManyRelation = require('./relations/hasMany/HasManyRelation'); | ||
var _HasManyRelation2 = _interopRequireDefault(_HasManyRelation); | ||
var _BelongsToOneRelation = require('./relations/BelongsToOneRelation'); | ||
var _BelongsToOneRelation = require('./relations/belongsToOne/BelongsToOneRelation'); | ||
var _BelongsToOneRelation2 = _interopRequireDefault(_BelongsToOneRelation); | ||
var _ManyToManyRelation = require('./relations/ManyToManyRelation'); | ||
var _ManyToManyRelation = require('./relations/manyToMany/ManyToManyRelation'); | ||
@@ -69,2 +73,3 @@ var _ManyToManyRelation2 = _interopRequireDefault(_ManyToManyRelation); | ||
exports.QueryBuilderBase = _QueryBuilderBase2.default; | ||
exports.QueryBuilderOperation = _QueryBuilderOperation2.default; | ||
exports.RelationExpression = _RelationExpression2.default; | ||
@@ -80,2 +85,3 @@ exports.ValidationError = _ValidationError2.default; | ||
Object.defineProperty(module.exports, "OneToOneRelation", { | ||
@@ -82,0 +88,0 @@ get: function get() { |
@@ -16,6 +16,2 @@ 'use strict'; | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _lodash = require('lodash'); | ||
@@ -59,76 +55,73 @@ | ||
(0, _createClass3.default)(EagerFetcher, [{ | ||
key: 'fetch', | ||
value: function fetch() { | ||
var _this = this; | ||
EagerFetcher.prototype.fetch = function fetch() { | ||
var _this = this; | ||
if (this.promise) { | ||
return this.promise; | ||
} | ||
if (this.promise) { | ||
return this.promise; | ||
} | ||
if (_lodash2.default.isEmpty(this.models)) { | ||
this.promise = _bluebird2.default.resolve([]); | ||
return this.promise; | ||
if (_lodash2.default.isEmpty(this.models)) { | ||
this.promise = _bluebird2.default.resolve([]); | ||
return this.promise; | ||
} | ||
var promises = []; | ||
this.eager.forEachChild(function (child) { | ||
var relation = _this.modelClass.getRelations()[child.name]; | ||
if (!relation) { | ||
throw new _ValidationError2.default({ eager: 'unknown relation "' + child.name + '" in an eager expression' }); | ||
} | ||
}); | ||
var promises = []; | ||
_lodash2.default.each(this.modelClass.getRelations(), function (relation) { | ||
var nextEager = _this.eager.childExpression(relation.name); | ||
this.eager.forEachChild(function (child) { | ||
var relation = _this.modelClass.getRelations()[child.name]; | ||
if (nextEager) { | ||
promises.push(_this._fetchRelation(relation, nextEager)); | ||
} | ||
}); | ||
if (!relation) { | ||
throw new _ValidationError2.default({ eager: 'unknown relation "' + child.name + '" in an eager expression' }); | ||
} | ||
}); | ||
this.promise = _bluebird2.default.all(promises).return(this.models); | ||
return this.promise; | ||
}; | ||
_lodash2.default.each(this.modelClass.getRelations(), function (relation) { | ||
var nextEager = _this.eager.childExpression(relation.name); | ||
EagerFetcher.prototype._fetchRelation = function _fetchRelation(relation, nextEager) { | ||
var _this2 = this; | ||
if (nextEager) { | ||
promises.push(_this._fetchRelation(relation, nextEager)); | ||
} | ||
}); | ||
var ModelClass = relation.relatedModelClass; | ||
var queryBuilder = ModelClass.RelatedQueryBuilder.forClass(ModelClass).childQueryOf(this.rootQuery); | ||
var operation = relation.find(queryBuilder, this.models); | ||
this.promise = _bluebird2.default.all(promises).return(this.models); | ||
return this.promise; | ||
} | ||
}, { | ||
key: '_fetchRelation', | ||
value: function _fetchRelation(relation, nextEager) { | ||
var _this2 = this; | ||
queryBuilder.callQueryBuilderOperation(operation, []); | ||
var ModelClass = relation.relatedModelClass; | ||
var queryBuilder = ModelClass.RelatedQueryBuilder.forClass(ModelClass).childQueryOf(this.rootQuery); | ||
_lodash2.default.each(nextEager.args, function (filterName) { | ||
var filter = _this2.filters[filterName]; | ||
relation.find(queryBuilder, this.models); | ||
if (!_lodash2.default.isFunction(filter)) { | ||
throw new _ValidationError2.default({ eager: 'could not find filter "' + filterName + '" for relation "' + relation.name + '"' }); | ||
} | ||
_lodash2.default.each(nextEager.args, function (filterName) { | ||
var filter = _this2.filters[filterName]; | ||
filter(queryBuilder); | ||
}); | ||
if (!_lodash2.default.isFunction(filter)) { | ||
throw new _ValidationError2.default({ eager: 'could not find filter "' + filterName + '" for relation "' + relation.name + '"' }); | ||
} | ||
return queryBuilder.then(function (related) { | ||
return _this2._fetchNextEager(relation, related, nextEager); | ||
}); | ||
}; | ||
filter(queryBuilder); | ||
}); | ||
EagerFetcher.prototype._fetchNextEager = function _fetchNextEager(relation, related, eager) { | ||
this.children[relation.name] = new EagerFetcher({ | ||
modelClass: relation.relatedModelClass, | ||
models: related, | ||
eager: eager, | ||
filters: this.filters, | ||
parent: this, | ||
rootQuery: this.rootQuery | ||
}); | ||
return queryBuilder.then(function (related) { | ||
return _this2._fetchNextEager(relation, related, nextEager); | ||
}); | ||
} | ||
}, { | ||
key: '_fetchNextEager', | ||
value: function _fetchNextEager(relation, related, eager) { | ||
this.children[relation.name] = new EagerFetcher({ | ||
modelClass: relation.relatedModelClass, | ||
models: related, | ||
eager: eager, | ||
filters: this.filters, | ||
parent: this, | ||
rootQuery: this.rootQuery | ||
}); | ||
return this.children[relation.name].fetch(); | ||
}; | ||
return this.children[relation.name].fetch(); | ||
} | ||
}]); | ||
return EagerFetcher; | ||
@@ -135,0 +128,0 @@ }(); |
@@ -16,6 +16,2 @@ 'use strict'; | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _lodash = require('lodash'); | ||
@@ -33,11 +29,11 @@ | ||
var _ManyToManyRelation = require('../relations/ManyToManyRelation'); | ||
var _ManyToManyRelation = require('../relations/manyToMany/ManyToManyRelation'); | ||
var _ManyToManyRelation2 = _interopRequireDefault(_ManyToManyRelation); | ||
var _HasManyRelation = require('../relations/HasManyRelation'); | ||
var _HasManyRelation = require('../relations/hasMany/HasManyRelation'); | ||
var _HasManyRelation2 = _interopRequireDefault(_HasManyRelation); | ||
var _BelongsToOneRelation = require('../relations/BelongsToOneRelation'); | ||
var _BelongsToOneRelation = require('../relations/belongsToOne/BelongsToOneRelation'); | ||
@@ -52,3 +48,3 @@ var _BelongsToOneRelation2 = _interopRequireDefault(_BelongsToOneRelation); | ||
var Model = undefined; | ||
var Model = void 0; | ||
@@ -77,267 +73,257 @@ var InsertWithRelated = function () { | ||
(0, _createClass3.default)(InsertWithRelated, [{ | ||
key: 'execute', | ||
value: function execute(inserter) { | ||
return this._executeNextBatch(inserter); | ||
} | ||
/** | ||
* @returns {DependencyGraph} | ||
* @private | ||
*/ | ||
InsertWithRelated.prototype.execute = function execute(inserter) { | ||
return this._executeNextBatch(inserter); | ||
}; | ||
}, { | ||
key: '_buildDependencyGraph', | ||
value: function _buildDependencyGraph() { | ||
var graph = new DependencyGraph(this.allowedRelations); | ||
graph.build(this.modelClass, this.models); | ||
return graph; | ||
} | ||
/** | ||
* @returns {DependencyGraph} | ||
* @private | ||
*/ | ||
/** | ||
* @param {function(TableInsertion)} inserter | ||
* @returns {Promise} | ||
* @private | ||
*/ | ||
}, { | ||
key: '_executeNextBatch', | ||
value: function _executeNextBatch(inserter) { | ||
var _this = this; | ||
InsertWithRelated.prototype._buildDependencyGraph = function _buildDependencyGraph() { | ||
var graph = new DependencyGraph(this.allowedRelations); | ||
graph.build(this.modelClass, this.models); | ||
return graph; | ||
}; | ||
var batch = this._nextBatch(); | ||
/** | ||
* @param {function(TableInsertion)} inserter | ||
* @returns {Promise} | ||
* @private | ||
*/ | ||
if (!batch) { | ||
// If we get here, we are done. All we need to do now is to finalize the object graph | ||
// and return it as the final output. | ||
return this._finalize(); | ||
} | ||
// Insert the batch using the `inserter` function. | ||
return _bluebird2.default.all(_lodash2.default.map(batch, function (tableInsertion) { | ||
var uids = undefined; | ||
InsertWithRelated.prototype._executeNextBatch = function _executeNextBatch(inserter) { | ||
var _this = this; | ||
if (!tableInsertion.isJoinTableInsertion) { | ||
// We need to omit the uid properties so that they don't get inserted | ||
// into the database. Join table insertions never have uids. | ||
uids = _this._omitUids(tableInsertion); | ||
} | ||
var batch = this._nextBatch(); | ||
return inserter(tableInsertion).then(function () { | ||
if (!tableInsertion.isJoinTableInsertion) { | ||
// Resolve dependencies to the inserted objects. | ||
_this._resolveDepsForInsertion(tableInsertion, uids); | ||
} | ||
}); | ||
})).then(function () { | ||
return _this._executeNextBatch(inserter); | ||
}); | ||
if (!batch) { | ||
// If we get here, we are done. All we need to do now is to finalize the object graph | ||
// and return it as the final output. | ||
return this._finalize(); | ||
} | ||
/** | ||
* @private | ||
* @returns {Object.<string, TableInsertion>} | ||
*/ | ||
// Insert the batch using the `inserter` function. | ||
return _bluebird2.default.all(_lodash2.default.map(batch, function (tableInsertion) { | ||
var uids = void 0; | ||
}, { | ||
key: '_nextBatch', | ||
value: function _nextBatch() { | ||
if (this.done) { | ||
return null; | ||
if (!tableInsertion.isJoinTableInsertion) { | ||
// We need to omit the uid properties so that they don't get inserted | ||
// into the database. Join table insertions never have uids. | ||
uids = _this._omitUids(tableInsertion); | ||
} | ||
var batch = this._createBatch(); | ||
return inserter(tableInsertion).then(function () { | ||
if (!tableInsertion.isJoinTableInsertion) { | ||
// Resolve dependencies to the inserted objects. | ||
_this._resolveDepsForInsertion(tableInsertion, uids); | ||
} | ||
}); | ||
})).then(function () { | ||
return _this._executeNextBatch(inserter); | ||
}); | ||
}; | ||
if (_lodash2.default.isEmpty(batch)) { | ||
this.done = true; | ||
return this._createManyToManyRelationJoinRowBatch(); | ||
} else { | ||
this._markBatchHandled(batch); | ||
return batch; | ||
} | ||
/** | ||
* @private | ||
* @returns {Object.<string, TableInsertion>} | ||
*/ | ||
InsertWithRelated.prototype._nextBatch = function _nextBatch() { | ||
if (this.done) { | ||
return null; | ||
} | ||
/** | ||
* @private | ||
* @returns {Object.<string, TableInsertion>} | ||
*/ | ||
var batch = this._createBatch(); | ||
}, { | ||
key: '_createBatch', | ||
value: function _createBatch() { | ||
var batch = (0, _create2.default)(null); | ||
var nodes = this.graph.nodes; | ||
if (_lodash2.default.isEmpty(batch)) { | ||
this.done = true; | ||
return this._createManyToManyRelationJoinRowBatch(); | ||
} else { | ||
this._markBatchHandled(batch); | ||
return batch; | ||
} | ||
}; | ||
for (var n = 0, ln = nodes.length; n < ln; ++n) { | ||
var node = nodes[n]; | ||
/** | ||
* @private | ||
* @returns {Object.<string, TableInsertion>} | ||
*/ | ||
if (!node.handled && node.needs.length === node.numHandledNeeds) { | ||
var tableInsertion = getTableInsertion(batch, node.modelClass.tableName); | ||
if (!tableInsertion) { | ||
tableInsertion = new TableInsertion(node.modelClass, false); | ||
setTableInsertion(batch, node.modelClass.tableName, tableInsertion); | ||
} | ||
InsertWithRelated.prototype._createBatch = function _createBatch() { | ||
var batch = (0, _create2.default)(null); | ||
var nodes = this.graph.nodes; | ||
tableInsertion.models.push(node.model); | ||
tableInsertion.isInputModel.push(isInputNode(this.graph.inputNodesById, node)); | ||
for (var n = 0, ln = nodes.length; n < ln; ++n) { | ||
var node = nodes[n]; | ||
if (!node.handled && node.needs.length === node.numHandledNeeds) { | ||
var tableInsertion = getTableInsertion(batch, node.modelClass.tableName); | ||
if (!tableInsertion) { | ||
tableInsertion = new TableInsertion(node.modelClass, false); | ||
setTableInsertion(batch, node.modelClass.tableName, tableInsertion); | ||
} | ||
tableInsertion.models.push(node.model); | ||
tableInsertion.isInputModel.push(isInputNode(this.graph.inputNodesById, node)); | ||
} | ||
return batch; | ||
} | ||
/** | ||
* @private | ||
* @param {Object.<string, TableInsertion>} batch | ||
*/ | ||
return batch; | ||
}; | ||
}, { | ||
key: '_markBatchHandled', | ||
value: function _markBatchHandled(batch) { | ||
var models = _lodash2.default.flatten(_lodash2.default.pluck(batch, 'models')); | ||
var nodes = this.graph.nodesById; | ||
/** | ||
* @private | ||
* @param {Object.<string, TableInsertion>} batch | ||
*/ | ||
for (var m = 0, lm = models.length; m < lm; ++m) { | ||
var id = getUid(models[m]); | ||
var node = getNode(nodes, id); | ||
for (var nb = 0, lnb = node.isNeededBy.length; nb < lnb; ++nb) { | ||
var dep = node.isNeededBy[nb]; | ||
dep.node.numHandledNeeds++; | ||
} | ||
InsertWithRelated.prototype._markBatchHandled = function _markBatchHandled(batch) { | ||
var models = _lodash2.default.flatten(_lodash2.default.map(batch, 'models')); | ||
var nodes = this.graph.nodesById; | ||
node.handled = true; | ||
for (var m = 0, lm = models.length; m < lm; ++m) { | ||
var id = getUid(models[m]); | ||
var node = getNode(nodes, id); | ||
for (var nb = 0, lnb = node.isNeededBy.length; nb < lnb; ++nb) { | ||
var dep = node.isNeededBy[nb]; | ||
dep.node.numHandledNeeds++; | ||
} | ||
node.handled = true; | ||
} | ||
}; | ||
/** | ||
* @private | ||
* @returns {Object.<string, TableInsertion>} | ||
*/ | ||
/** | ||
* @private | ||
* @returns {Object.<string, TableInsertion>} | ||
*/ | ||
}, { | ||
key: '_createManyToManyRelationJoinRowBatch', | ||
value: function _createManyToManyRelationJoinRowBatch() { | ||
var batch = (0, _create2.default)(null); | ||
for (var n = 0, ln = this.graph.nodes.length; n < ln; ++n) { | ||
var node = this.graph.nodes[n]; | ||
InsertWithRelated.prototype._createManyToManyRelationJoinRowBatch = function _createManyToManyRelationJoinRowBatch() { | ||
var batch = (0, _create2.default)(null); | ||
for (var m = 0, lm = node.manyToManyConnections.length; m < lm; ++m) { | ||
var conn = node.manyToManyConnections[m]; | ||
var tableInsertion = getTableInsertion(batch, conn.relation.joinTable); | ||
for (var n = 0, ln = this.graph.nodes.length; n < ln; ++n) { | ||
var node = this.graph.nodes[n]; | ||
var ownerProp = node.model.$values(conn.relation.ownerProp); | ||
var knex = conn.relation.ownerModelClass.knex(); | ||
var modelClass = conn.relation.joinTableModelClass; | ||
for (var m = 0, lm = node.manyToManyConnections.length; m < lm; ++m) { | ||
var conn = node.manyToManyConnections[m]; | ||
var tableInsertion = getTableInsertion(batch, conn.relation.joinTable); | ||
if (knex) { | ||
// TODO: Because the joinTableModelClass may have been created inside ManyToManyRelation, it may not be bound. We really should not have to know about it here... | ||
modelClass = modelClass.bindKnex(knex); | ||
} | ||
var ownerProp = node.model.$values(conn.relation.ownerProp); | ||
var knex = conn.relation.ownerModelClass.knex(); | ||
var modelClass = conn.relation.joinTableModelClass; | ||
var joinModel = conn.relation.createJoinModels(ownerProp, [conn.node.model]); | ||
joinModel = modelClass.fromJson(joinModel[0]); | ||
if (knex) { | ||
// TODO: Because the joinTableModelClass may have been created inside ManyToManyRelation, it may not be bound. We really should not have to know about it here... | ||
modelClass = modelClass.bindKnex(knex); | ||
} | ||
if (!tableInsertion) { | ||
tableInsertion = new TableInsertion(modelClass, true); | ||
setTableInsertion(batch, modelClass.tableName, tableInsertion); | ||
} | ||
var joinModel = conn.relation.createJoinModels(ownerProp, [conn.node.model]); | ||
joinModel = modelClass.fromJson(joinModel[0]); | ||
tableInsertion.models.push(joinModel); | ||
tableInsertion.isInputModel.push(false); | ||
if (!tableInsertion) { | ||
tableInsertion = new TableInsertion(modelClass, true); | ||
setTableInsertion(batch, modelClass.tableName, tableInsertion); | ||
} | ||
tableInsertion.models.push(joinModel); | ||
tableInsertion.isInputModel.push(false); | ||
} | ||
} | ||
// Remove duplicates. | ||
_lodash2.default.each(batch, function (tableInsertion) { | ||
if (tableInsertion.models.length) { | ||
(function () { | ||
var keys = _lodash2.default.keys(tableInsertion.models[0]); | ||
tableInsertion.models = _lodash2.default.unique(tableInsertion.models, function (model) { | ||
return model.$values(keys).join(); | ||
}); | ||
tableInsertion.isInputModel = _lodash2.default.times(tableInsertion.models.length, _lodash2.default.constant(false)); | ||
})(); | ||
} | ||
}); | ||
// Remove duplicates. | ||
_lodash2.default.each(batch, function (tableInsertion) { | ||
if (tableInsertion.models.length) { | ||
(function () { | ||
var keys = _lodash2.default.keys(tableInsertion.models[0]); | ||
tableInsertion.models = _lodash2.default.uniqBy(tableInsertion.models, function (model) { | ||
return model.$values(keys).join(); | ||
}); | ||
tableInsertion.isInputModel = _lodash2.default.times(tableInsertion.models.length, _lodash2.default.constant(false)); | ||
})(); | ||
} | ||
}); | ||
return batch; | ||
} | ||
return batch; | ||
}; | ||
/** | ||
* @private | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: '_omitUids', | ||
value: function _omitUids(tableInsertion) { | ||
var ids = _lodash2.default.pluck(tableInsertion.models, tableInsertion.modelClass.uidProp); | ||
for (var m = 0, lm = tableInsertion.models.length; m < lm; ++m) { | ||
tableInsertion.models[m].$omit(tableInsertion.modelClass.uidProp); | ||
} | ||
InsertWithRelated.prototype._omitUids = function _omitUids(tableInsertion) { | ||
var ids = _lodash2.default.map(tableInsertion.models, tableInsertion.modelClass.uidProp); | ||
return ids; | ||
for (var m = 0, lm = tableInsertion.models.length; m < lm; ++m) { | ||
tableInsertion.models[m].$omit(tableInsertion.modelClass.uidProp); | ||
} | ||
/** | ||
* @private | ||
* @param {TableInsertion} tableInsertion | ||
* @param {Array.<string>} uids | ||
*/ | ||
return ids; | ||
}; | ||
}, { | ||
key: '_resolveDepsForInsertion', | ||
value: function _resolveDepsForInsertion(tableInsertion, uids) { | ||
for (var m = 0, lm = tableInsertion.models.length; m < lm; ++m) { | ||
var node = getNode(this.graph.nodesById, uids[m]); | ||
var model = tableInsertion.models[m]; | ||
/** | ||
* @private | ||
* @param {TableInsertion} tableInsertion | ||
* @param {Array.<string>} uids | ||
*/ | ||
for (var d = 0, ld = node.isNeededBy.length; d < ld; ++d) { | ||
var dep = node.isNeededBy[d]; | ||
dep.resolve(model); | ||
} | ||
InsertWithRelated.prototype._resolveDepsForInsertion = function _resolveDepsForInsertion(tableInsertion, uids) { | ||
for (var m = 0, lm = tableInsertion.models.length; m < lm; ++m) { | ||
var node = getNode(this.graph.nodesById, uids[m]); | ||
var model = tableInsertion.models[m]; | ||
for (var d = 0, ld = node.isNeededBy.length; d < ld; ++d) { | ||
var dep = node.isNeededBy[d]; | ||
dep.resolve(model); | ||
} | ||
} | ||
}; | ||
/** | ||
* @private | ||
* @return {Promise} | ||
*/ | ||
/** | ||
* @private | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: '_finalize', | ||
value: function _finalize() { | ||
var _this2 = this; | ||
var _loop = function _loop(n, ln) { | ||
var refNode = _this2.graph.nodes[n]; | ||
var ref = getUidRef(refNode.model); | ||
InsertWithRelated.prototype._finalize = function _finalize() { | ||
var _this2 = this; | ||
if (ref) { | ||
(function () { | ||
// Copy all the properties to the reference nodes. | ||
var actualNode = getNode(_this2.graph.nodesById, ref); | ||
var relations = actualNode.modelClass.getRelations(); | ||
var _loop = function _loop(n, ln) { | ||
var refNode = _this2.graph.nodes[n]; | ||
var ref = getUidRef(refNode.model); | ||
_lodash2.default.each(actualNode.model, function (value, key) { | ||
if (!getRelation(relations, key) && !_lodash2.default.isFunction(value)) { | ||
refNode.model[key] = value; | ||
} | ||
}); | ||
if (ref) { | ||
(function () { | ||
// Copy all the properties to the reference nodes. | ||
var actualNode = getNode(_this2.graph.nodesById, ref); | ||
var relations = actualNode.modelClass.getRelations(); | ||
refNode.model.$omit(refNode.modelClass.uidProp, refNode.modelClass.uidRefProp); | ||
})(); | ||
} | ||
}; | ||
_lodash2.default.each(actualNode.model, function (value, key) { | ||
if (!getRelation(relations, key) && !_lodash2.default.isFunction(value)) { | ||
refNode.model[key] = value; | ||
} | ||
}); | ||
for (var n = 0, ln = this.graph.nodes.length; n < ln; ++n) { | ||
_loop(n, ln); | ||
refNode.model.$omit(refNode.modelClass.uidProp, refNode.modelClass.uidRefProp); | ||
})(); | ||
} | ||
}; | ||
return _bluebird2.default.resolve(this.models); | ||
for (var n = 0, ln = this.graph.nodes.length; n < ln; ++n) { | ||
_loop(n, ln); | ||
} | ||
}]); | ||
return _bluebird2.default.resolve(this.models); | ||
}; | ||
return InsertWithRelated; | ||
@@ -348,2 +334,3 @@ }(); | ||
function TableInsertion(modelClass, isJoinTableInsertion) { | ||
@@ -522,4 +509,4 @@ this.modelClass = modelClass; | ||
var d = undefined, | ||
ld = undefined; | ||
var d = void 0, | ||
ld = void 0; | ||
@@ -548,6 +535,6 @@ for (d = 0, ld = _refNode.needs.length; d < ld; ++d) { | ||
var node = this.nodes[n]; | ||
var d = undefined, | ||
ld = undefined, | ||
dep = undefined, | ||
actualNode = undefined; | ||
var d = void 0, | ||
ld = void 0, | ||
dep = void 0, | ||
actualNode = void 0; | ||
@@ -554,0 +541,0 @@ for (d = 0, ld = node.needs.length; d < ld; ++d) { |
'use strict'; | ||
var _dec, _desc, _value, _class; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -18,6 +16,2 @@ value: true | ||
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); | ||
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
@@ -27,6 +21,2 @@ | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); | ||
@@ -36,6 +26,2 @@ | ||
var _get3 = require('babel-runtime/helpers/get'); | ||
var _get4 = _interopRequireDefault(_get3); | ||
var _inherits2 = require('babel-runtime/helpers/inherits'); | ||
@@ -45,2 +31,4 @@ | ||
var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec10, _dec11, _dec12, _desc, _value, _class; | ||
var _lodash = require('lodash'); | ||
@@ -54,13 +42,13 @@ | ||
var _RelationExpression = require('./RelationExpression'); | ||
var _queryBuilderOperation = require('./decorators/queryBuilderOperation'); | ||
var _RelationExpression2 = _interopRequireDefault(_RelationExpression); | ||
var _queryBuilderOperation2 = _interopRequireDefault(_queryBuilderOperation); | ||
var _InsertionOrUpdate = require('./InsertionOrUpdate'); | ||
var _QueryBuilderContext = require('./QueryBuilderContext'); | ||
var _InsertionOrUpdate2 = _interopRequireDefault(_InsertionOrUpdate); | ||
var _QueryBuilderContext2 = _interopRequireDefault(_QueryBuilderContext); | ||
var _InsertWithRelated = require('./InsertWithRelated'); | ||
var _RelationExpression = require('./RelationExpression'); | ||
var _InsertWithRelated2 = _interopRequireDefault(_InsertWithRelated); | ||
var _RelationExpression2 = _interopRequireDefault(_RelationExpression); | ||
@@ -79,4 +67,2 @@ var _QueryBuilderBase2 = require('./QueryBuilderBase'); | ||
var _dbUtils = require('../utils/dbUtils'); | ||
var _deprecated = require('../utils/decorators/deprecated'); | ||
@@ -86,2 +72,46 @@ | ||
var _DeleteOperation = require('./operations/DeleteOperation'); | ||
var _DeleteOperation2 = _interopRequireDefault(_DeleteOperation); | ||
var _UpdateOperation = require('./operations/UpdateOperation'); | ||
var _UpdateOperation2 = _interopRequireDefault(_UpdateOperation); | ||
var _InsertOperation = require('./operations/InsertOperation'); | ||
var _InsertOperation2 = _interopRequireDefault(_InsertOperation); | ||
var _InsertWithRelatedOperation = require('./operations/InsertWithRelatedOperation'); | ||
var _InsertWithRelatedOperation2 = _interopRequireDefault(_InsertWithRelatedOperation); | ||
var _InsertAndFetchOperation = require('./operations/InsertAndFetchOperation'); | ||
var _InsertAndFetchOperation2 = _interopRequireDefault(_InsertAndFetchOperation); | ||
var _UpdateAndFetchOperation = require('./operations/UpdateAndFetchOperation'); | ||
var _UpdateAndFetchOperation2 = _interopRequireDefault(_UpdateAndFetchOperation); | ||
var _QueryBuilderOperation = require('./operations/QueryBuilderOperation'); | ||
var _QueryBuilderOperation2 = _interopRequireDefault(_QueryBuilderOperation); | ||
var _JoinRelationOperation = require('./operations/JoinRelationOperation'); | ||
var _JoinRelationOperation2 = _interopRequireDefault(_JoinRelationOperation); | ||
var _RunBeforeOperation = require('./operations/RunBeforeOperation'); | ||
var _RunBeforeOperation2 = _interopRequireDefault(_RunBeforeOperation); | ||
var _RunAfterOperation = require('./operations/RunAfterOperation'); | ||
var _RunAfterOperation2 = _interopRequireDefault(_RunAfterOperation); | ||
var _OnBuildOperation = require('./operations/OnBuildOperation'); | ||
var _OnBuildOperation2 = _interopRequireDefault(_OnBuildOperation); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -118,3 +148,3 @@ | ||
var QueryBuilder = (_dec = (0, _deprecated2.default)({ removedIn: '0.6.0', useInstead: 'debug()' }), (_class = function (_QueryBuilderBase) { | ||
var QueryBuilder = (_dec = (0, _queryBuilderOperation2.default)(_RunBeforeOperation2.default), _dec2 = (0, _queryBuilderOperation2.default)(_OnBuildOperation2.default), _dec3 = (0, _queryBuilderOperation2.default)(_RunAfterOperation2.default), _dec4 = (0, _deprecated2.default)({ removedIn: '0.6.0', useInstead: 'debug()' }), _dec5 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'join' }]), _dec6 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'innerJoin' }]), _dec7 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'outerJoin' }]), _dec8 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'leftJoin' }]), _dec9 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'leftOuterJoin' }]), _dec10 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'rightJoin' }]), _dec11 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'rightOuterJoin' }]), _dec12 = (0, _queryBuilderOperation2.default)([_JoinRelationOperation2.default, { joinOperation: 'fullOuterJoin' }]), (_class = function (_QueryBuilderBase) { | ||
(0, _inherits3.default)(QueryBuilder, _QueryBuilderBase); | ||
@@ -125,12 +155,8 @@ | ||
var _this = (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(QueryBuilder).call(this, modelClass.knex())); | ||
var _this = (0, _possibleConstructorReturn3.default)(this, _QueryBuilderBase.call(this, modelClass.knex(), _QueryBuilderContext2.default)); | ||
_this._modelClass = modelClass; | ||
_this._calledWriteMethod = null; | ||
_this._explicitRejectValue = null; | ||
_this._explicitResolveValue = null; | ||
_this._hooks = null; | ||
_this._customImpl = null; | ||
_this._eagerExpression = null; | ||
@@ -142,8 +168,23 @@ _this._eagerFilters = null; | ||
_this.internalContext().runBefore = []; | ||
_this.internalContext().runAfter = []; | ||
_this.internalContext().onBuild = []; | ||
_this.clearHooks(); | ||
_this.clearCustomImpl(); | ||
_this._findOperationFactory = function (builder) { | ||
return new _QueryBuilderOperation2.default(builder, 'find'); | ||
}; | ||
_this._insertOperationFactory = function (builder) { | ||
return new _InsertOperation2.default(builder, 'insert'); | ||
}; | ||
_this._updateOperationFactory = function (builder) { | ||
return new _UpdateOperation2.default(builder, 'update'); | ||
}; | ||
_this._patchOperationFactory = function (builder) { | ||
return new _UpdateOperation2.default(builder, 'patch', { modelOptions: { patch: true } }); | ||
}; | ||
_this._relateOperationFactory = function (builder) { | ||
return new _QueryBuilderOperation2.default(builder, 'relate'); | ||
}; | ||
_this._unrelateOperationFactory = function (builder) { | ||
return new _QueryBuilderOperation2.default(builder, 'unrelate'); | ||
}; | ||
_this._deleteOperationFactory = function (builder) { | ||
return new _DeleteOperation2.default(builder, 'delete'); | ||
}; | ||
return _this; | ||
@@ -157,1436 +198,960 @@ } | ||
(0, _createClass3.default)(QueryBuilder, [{ | ||
key: 'context', | ||
/** | ||
* @param {Object=} ctx | ||
* @returns {QueryBuilder|Object} | ||
*/ | ||
value: function context() { | ||
var _get2; | ||
QueryBuilder.forClass = function forClass(modelClass) { | ||
return new this(modelClass); | ||
}; | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
/** | ||
* @param {QueryBuilderBase} query | ||
* @returns {QueryBuilder} | ||
*/ | ||
// This implementation is here just so that we can document it. | ||
return (_get2 = (0, _get4.default)((0, _getPrototypeOf2.default)(QueryBuilder.prototype), 'context', this)).call.apply(_get2, [this].concat(args)); | ||
QueryBuilder.prototype.childQueryOf = function childQueryOf(query) { | ||
if (query) { | ||
this.internalContext(query.internalContext()); | ||
} | ||
/** | ||
* @param {QueryBuilderBase} query | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: 'childQueryOf', | ||
value: function childQueryOf(query) { | ||
if (query) { | ||
this.internalContext(query.internalContext()); | ||
/** | ||
* @param {Error} error | ||
* @returns {QueryBuilder} | ||
*/ | ||
if (query.has(/debug/)) { | ||
this.debug(); | ||
} | ||
} | ||
return this; | ||
} | ||
/** | ||
* @param {Error} error | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.reject = function reject(error) { | ||
this._explicitRejectValue = error; | ||
return this; | ||
}; | ||
}, { | ||
key: 'reject', | ||
value: function reject(error) { | ||
this._explicitRejectValue = error; | ||
return this; | ||
} | ||
/** | ||
* @param {*} value | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {*} value | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'resolve', | ||
value: function resolve(value) { | ||
this._explicitResolveValue = value; | ||
return this; | ||
} | ||
QueryBuilder.prototype.resolve = function resolve(value) { | ||
this._explicitResolveValue = value; | ||
return this; | ||
}; | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
}, { | ||
key: 'isExecutable', | ||
value: function isExecutable() { | ||
return !this._explicitRejectValue && !this._explicitResolveValue && !this._hooks.executor; | ||
} | ||
/** | ||
* @param {function(*, QueryBuilder)} runBefore | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.isExecutable = function isExecutable() { | ||
var hasExecutor = !!this._queryExecutorOperation(); | ||
return !this._explicitRejectValue && !this._explicitResolveValue && !hasExecutor; | ||
}; | ||
}, { | ||
key: 'runBefore', | ||
value: function runBefore(_runBefore) { | ||
this._hooks.before.push(_runBefore); | ||
return this; | ||
} | ||
/** | ||
* @param {function(*, QueryBuilder)} runBefore | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {function(*, QueryBuilder)} runBefore | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'runBeforePushFront', | ||
value: function runBeforePushFront(runBefore) { | ||
this._hooks.before.unshift(runBefore); | ||
return this; | ||
} | ||
QueryBuilder.prototype.runBefore = function runBefore(_runBefore) {}; | ||
/** | ||
* @param {function(QueryBuilder)} onBuild | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {function(QueryBuilder)} onBuild | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'onBuild', | ||
value: function onBuild(_onBuild) { | ||
this._hooks.onBuild.push(_onBuild); | ||
return this; | ||
} | ||
/** | ||
* @param {function(QueryBuilder)} executor | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.onBuild = function onBuild(_onBuild) {}; | ||
}, { | ||
key: 'setQueryExecutor', | ||
value: function setQueryExecutor(executor) { | ||
if (this._hooks.executor) { | ||
throw Error('overwriting an executor. you should not do this.'); | ||
} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfter | ||
* @returns {QueryBuilder} | ||
*/ | ||
this._hooks.executor = executor; | ||
return this; | ||
} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfterModelCreate | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.runAfter = function runAfter(_runAfter) {}; | ||
}, { | ||
key: 'runAfterModelCreate', | ||
value: function runAfterModelCreate(_runAfterModelCreate) { | ||
this._hooks.afterModelCreate.push(_runAfterModelCreate); | ||
return this; | ||
} | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfterModelCreate | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'runAfterModelCreatePushFront', | ||
value: function runAfterModelCreatePushFront(runAfterModelCreate) { | ||
this._hooks.afterModelCreate.unshift(runAfterModelCreate); | ||
return this; | ||
} | ||
QueryBuilder.prototype.findOperationFactory = function findOperationFactory(factory) { | ||
this._findOperationFactory = factory; | ||
return this; | ||
}; | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfter | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'runAfter', | ||
value: function runAfter(_runAfter) { | ||
this._hooks.after.push(_runAfter); | ||
return this; | ||
} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfter | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.insertOperationFactory = function insertOperationFactory(factory) { | ||
this._insertOperationFactory = factory; | ||
return this; | ||
}; | ||
}, { | ||
key: 'runAfterPushFront', | ||
value: function runAfterPushFront(runAfter) { | ||
this._hooks.after.unshift(runAfter); | ||
return this; | ||
} | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'findImpl', | ||
value: function findImpl(_findImpl) { | ||
this._customImpl.find = _findImpl || null; | ||
return this; | ||
} | ||
QueryBuilder.prototype.updateOperationFactory = function updateOperationFactory(factory) { | ||
this._updateOperationFactory = factory; | ||
return this; | ||
}; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'insertImpl', | ||
value: function insertImpl(_insertImpl) { | ||
this._customImpl.insert = _insertImpl || null; | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.patchOperationFactory = function patchOperationFactory(factory) { | ||
this._patchOperationFactory = factory; | ||
return this; | ||
}; | ||
}, { | ||
key: 'updateImpl', | ||
value: function updateImpl(_updateImpl) { | ||
this._customImpl.update = _updateImpl || null; | ||
return this; | ||
} | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'patchImpl', | ||
value: function patchImpl(_patchImpl) { | ||
this._customImpl.patch = _patchImpl || null; | ||
return this; | ||
} | ||
QueryBuilder.prototype.deleteOperationFactory = function deleteOperationFactory(factory) { | ||
this._deleteOperationFactory = factory; | ||
return this; | ||
}; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'deleteImpl', | ||
value: function deleteImpl(_deleteImpl) { | ||
this._customImpl.delete = _deleteImpl || null; | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.relateOperationFactory = function relateOperationFactory(factory) { | ||
this._relateOperationFactory = factory; | ||
return this; | ||
}; | ||
}, { | ||
key: 'relateImpl', | ||
value: function relateImpl(_relateImpl) { | ||
this._customImpl.relate = _relateImpl || null; | ||
return this; | ||
} | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'unrelateImpl', | ||
value: function unrelateImpl(_unrelateImpl) { | ||
this._customImpl.unrelate = _unrelateImpl || null; | ||
return this; | ||
} | ||
QueryBuilder.prototype.unrelateOperationFactory = function unrelateOperationFactory(factory) { | ||
this._unrelateOperationFactory = factory; | ||
return this; | ||
}; | ||
/** | ||
* @param {string|RelationExpression} exp | ||
* @param {Object.<string, function(QueryBuilder)>=} filters | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {string|RelationExpression} exp | ||
* @param {Object.<string, function(QueryBuilder)>=} filters | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'eager', | ||
value: function eager(exp, filters) { | ||
this._eagerExpression = exp || null; | ||
this._eagerFilters = filters || null; | ||
if (_lodash2.default.isString(this._eagerExpression)) { | ||
this._eagerExpression = _RelationExpression2.default.parse(this._eagerExpression); | ||
} | ||
QueryBuilder.prototype.eager = function eager(exp, filters) { | ||
this._eagerExpression = exp || null; | ||
this._eagerFilters = filters || null; | ||
checkEager(this); | ||
return this; | ||
if (_lodash2.default.isString(this._eagerExpression)) { | ||
this._eagerExpression = _RelationExpression2.default.parse(this._eagerExpression); | ||
} | ||
/** | ||
* @param {string|RelationExpression} exp | ||
* @returns {QueryBuilder} | ||
*/ | ||
checkEager(this); | ||
return this; | ||
}; | ||
}, { | ||
key: 'allowEager', | ||
value: function allowEager(exp) { | ||
this._allowedEagerExpression = exp || null; | ||
/** | ||
* @param {string|RelationExpression} exp | ||
* @returns {QueryBuilder} | ||
*/ | ||
if (_lodash2.default.isString(this._allowedEagerExpression)) { | ||
this._allowedEagerExpression = _RelationExpression2.default.parse(this._allowedEagerExpression); | ||
} | ||
checkEager(this); | ||
return this; | ||
QueryBuilder.prototype.allowEager = function allowEager(exp) { | ||
this._allowedEagerExpression = exp || null; | ||
if (_lodash2.default.isString(this._allowedEagerExpression)) { | ||
this._allowedEagerExpression = _RelationExpression2.default.parse(this._allowedEagerExpression); | ||
} | ||
/** | ||
* @param {string|RelationExpression} path | ||
* @param {function(QueryBuilder)} filter | ||
* @returns {QueryBuilder} | ||
*/ | ||
checkEager(this); | ||
return this; | ||
}; | ||
}, { | ||
key: 'filterEager', | ||
value: function filterEager(path, filter) { | ||
this._eagerFilterExpressions.push({ | ||
path: path, | ||
filter: filter | ||
}); | ||
/** | ||
* @param {string|RelationExpression} path | ||
* @param {function(QueryBuilder)} filter | ||
* @returns {QueryBuilder} | ||
*/ | ||
return this; | ||
} | ||
/** | ||
* @param {string|RelationExpression} exp | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.filterEager = function filterEager(path, filter) { | ||
this._eagerFilterExpressions.push({ | ||
path: path, | ||
filter: filter | ||
}); | ||
}, { | ||
key: 'allowInsert', | ||
value: function allowInsert(exp) { | ||
this._allowedInsertExpression = exp || null; | ||
return this; | ||
}; | ||
if (_lodash2.default.isString(this._allowedInsertExpression)) { | ||
this._allowedInsertExpression = _RelationExpression2.default.parse(this._allowedInsertExpression); | ||
} | ||
/** | ||
* @param {string|RelationExpression} exp | ||
* @returns {QueryBuilder} | ||
*/ | ||
return this; | ||
} | ||
/** | ||
* @returns {Model} | ||
*/ | ||
QueryBuilder.prototype.allowInsert = function allowInsert(exp) { | ||
this._allowedInsertExpression = exp || null; | ||
}, { | ||
key: 'modelClass', | ||
value: function modelClass() { | ||
return this._modelClass; | ||
if (_lodash2.default.isString(this._allowedInsertExpression)) { | ||
this._allowedInsertExpression = _RelationExpression2.default.parse(this._allowedInsertExpression); | ||
} | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: 'isFindQuery', | ||
value: function isFindQuery() { | ||
return !this._calledWriteMethod && !this.has(/insert|update|delete/); | ||
} | ||
/** | ||
* @returns {Constructor.<Model>} | ||
*/ | ||
/** | ||
* @returns {string} | ||
*/ | ||
}, { | ||
key: 'toString', | ||
value: function toString() { | ||
return this.build().toString(); | ||
} | ||
QueryBuilder.prototype.modelClass = function modelClass() { | ||
return this._modelClass; | ||
}; | ||
/** | ||
* @returns {string} | ||
*/ | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
}, { | ||
key: 'toSql', | ||
value: function toSql() { | ||
return this.toString(); | ||
} | ||
/** | ||
* @param {function(string)=} logger | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.isFindQuery = function isFindQuery() { | ||
return !_lodash2.default.some(this._operations, function (method) { | ||
return method.isWriteOperation; | ||
}) && !this._explicitRejectValue; | ||
}; | ||
}, { | ||
key: 'dumpSql', | ||
value: function dumpSql(logger) { | ||
(logger || console.log)(this.toString()); | ||
return this; | ||
} | ||
/** | ||
* @returns {string} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'clone', | ||
value: function clone() { | ||
var builder = new this.constructor(this._modelClass); | ||
// This is a QueryBuilderBase method. | ||
this.cloneInto(builder); | ||
QueryBuilder.prototype.toString = function toString() { | ||
return this.build().toString(); | ||
}; | ||
var builderIntCtx = builder.internalContext(); | ||
var intCtx = this.internalContext(); | ||
/** | ||
* @returns {string} | ||
*/ | ||
builderIntCtx.runBefore = intCtx.runBefore.slice(); | ||
builderIntCtx.runAfter = intCtx.runAfter.slice(); | ||
builderIntCtx.onBuild = intCtx.onBuild.slice(); | ||
builder._calledWriteMethod = this._calledWriteMethod; | ||
builder._explicitRejectValue = this._explicitRejectValue; | ||
builder._explicitResolveValue = this._explicitResolveValue; | ||
QueryBuilder.prototype.toSql = function toSql() { | ||
return this.toString(); | ||
}; | ||
_lodash2.default.forEach(this._hooks, function (funcs, key) { | ||
builder._hooks[key] = _lodash2.default.isArray(funcs) ? funcs.slice() : funcs; | ||
}); | ||
/** | ||
* @param {function(string)=} logger | ||
* @returns {QueryBuilder} | ||
*/ | ||
_lodash2.default.forEach(this._customImpl, function (impl, key) { | ||
builder._customImpl[key] = impl; | ||
}); | ||
builder._eagerExpression = this._eagerExpression; | ||
builder._eagerFilters = this._eagerFilters; | ||
builder._eagerFilterExpressions = this._eagerFilterExpressions.slice(); | ||
builder._allowedEagerExpression = this._allowedEagerExpression; | ||
builder._allowedInsertExpression = this._allowedInsertExpression; | ||
QueryBuilder.prototype.dumpSql = function dumpSql(logger) { | ||
(logger || console.log)(this.toString()); | ||
return this; | ||
}; | ||
return builder; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'clearCustomImpl', | ||
value: function clearCustomImpl() { | ||
this._customImpl = { | ||
find: function find() {}, | ||
relate: function relate() {}, | ||
unrelate: function unrelate() {}, | ||
insert: function insert(_insert, builder) { | ||
builder.onBuild(function (builder) { | ||
builder.$$insert(_insert); | ||
}); | ||
}, | ||
update: function update(_update, builder) { | ||
builder.onBuild(function (builder) { | ||
builder.$$update(_update); | ||
}); | ||
}, | ||
patch: function patch(_patch, builder) { | ||
builder.onBuild(function (builder) { | ||
builder.$$update(_patch); | ||
}); | ||
}, | ||
delete: function _delete(builder) { | ||
builder.onBuild(function (builder) { | ||
builder.$$delete(); | ||
}); | ||
} | ||
}; | ||
QueryBuilder.prototype.clone = function clone() { | ||
var builder = new this.constructor(this._modelClass); | ||
this.baseCloneInto(builder); | ||
return this; | ||
} | ||
builder._explicitRejectValue = this._explicitRejectValue; | ||
builder._explicitResolveValue = this._explicitResolveValue; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
builder._eagerExpression = this._eagerExpression; | ||
builder._eagerFilters = this._eagerFilters; | ||
builder._eagerFilterExpressions = this._eagerFilterExpressions.slice(); | ||
builder._allowedEagerExpression = this._allowedEagerExpression; | ||
builder._allowedInsertExpression = this._allowedInsertExpression; | ||
}, { | ||
key: 'clearHooks', | ||
value: function clearHooks() { | ||
this._hooks = { | ||
before: [], | ||
onBuild: [], | ||
executor: null, | ||
afterModelCreate: [], | ||
after: [] | ||
}; | ||
builder._findOperationFactory = this._findOperationFactory; | ||
builder._insertOperationFactory = this._insertOperationFactory; | ||
builder._updateOperationFactory = this._updateOperationFactory; | ||
builder._patchOperationFactory = this._patchOperationFactory; | ||
builder._relateOperationFactory = this._relateOperationFactory; | ||
builder._unrelateOperationFactory = this._unrelateOperationFactory; | ||
builder._deleteOperationFactory = this._deleteOperationFactory; | ||
return this; | ||
} | ||
return builder; | ||
}; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'clearEager', | ||
value: function clearEager() { | ||
this._eagerExpression = null; | ||
this._eagerFilters = null; | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.clearEager = function clearEager() { | ||
this._eagerExpression = null; | ||
this._eagerFilters = null; | ||
return this; | ||
}; | ||
}, { | ||
key: 'clearReject', | ||
value: function clearReject() { | ||
this._explicitRejectValue = null; | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'clearResolve', | ||
value: function clearResolve() { | ||
this._explicitResolveValue = null; | ||
return this; | ||
} | ||
QueryBuilder.prototype.clearReject = function clearReject() { | ||
this._explicitRejectValue = null; | ||
return this; | ||
}; | ||
/** | ||
* @param {RegExp=} regex | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'clear', | ||
value: function clear(regex) { | ||
(0, _get4.default)((0, _getPrototypeOf2.default)(QueryBuilder.prototype), 'clear', this).call(this, regex); | ||
if (regex) { | ||
// Clear the write method call also if it doesn't pass the filter. | ||
if (regex.test(this._calledWriteMethod)) { | ||
this._calledWriteMethod = null; | ||
} | ||
} else { | ||
this._calledWriteMethod = null; | ||
} | ||
QueryBuilder.prototype.clearResolve = function clearResolve() { | ||
this._explicitResolveValue = null; | ||
return this; | ||
}; | ||
return this; | ||
} | ||
/** | ||
* @param {function=} successHandler | ||
* @param {function=} errorHandler | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {RegExp} methodNameRegex | ||
* @returns {boolean} | ||
*/ | ||
}, { | ||
key: 'has', | ||
value: function has(methodNameRegex) { | ||
return (0, _get4.default)((0, _getPrototypeOf2.default)(QueryBuilder.prototype), 'has', this).call(this, methodNameRegex) || methodNameRegex.test(this._calledWriteMethod); | ||
} | ||
QueryBuilder.prototype.then = function then(successHandler, errorHandler) { | ||
var promise = this._execute(); | ||
return promise.then.apply(promise, arguments); | ||
}; | ||
/** | ||
* @param {function=} successHandler | ||
* @param {function=} errorHandler | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {function} mapper | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'then', | ||
value: function then() { | ||
var promise = this._execute(); | ||
return promise.then.apply(promise, arguments); | ||
} | ||
/** | ||
* @param {function} mapper | ||
* @returns {Promise} | ||
*/ | ||
QueryBuilder.prototype.map = function map(mapper) { | ||
var promise = this._execute(); | ||
return promise.map.apply(promise, arguments); | ||
}; | ||
}, { | ||
key: 'map', | ||
value: function map() { | ||
var promise = this._execute(); | ||
return promise.map.apply(promise, arguments); | ||
} | ||
/** | ||
* @param {function} errorHandler | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {function} errorHandler | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'catch', | ||
value: function _catch() { | ||
var promise = this._execute(); | ||
return promise.catch.apply(promise, arguments); | ||
} | ||
QueryBuilder.prototype.catch = function _catch(errorHandler) { | ||
var promise = this._execute(); | ||
return promise.catch.apply(promise, arguments); | ||
}; | ||
/** | ||
* @param {*} returnValue | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {*} returnValue | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'return', | ||
value: function _return() { | ||
var promise = this._execute(); | ||
return promise.return.apply(promise, arguments); | ||
} | ||
/** | ||
* @param {*} context | ||
* @returns {Promise} | ||
*/ | ||
QueryBuilder.prototype.return = function _return(returnValue) { | ||
var promise = this._execute(); | ||
return promise.return.apply(promise, arguments); | ||
}; | ||
}, { | ||
key: 'bind', | ||
value: function bind() { | ||
var promise = this._execute(); | ||
return promise.bind.apply(promise, arguments); | ||
} | ||
/** | ||
* @param {*} context | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {function} callback | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'asCallback', | ||
value: function asCallback() { | ||
var promise = this._execute(); | ||
return promise.asCallback.apply(promise, arguments); | ||
} | ||
QueryBuilder.prototype.bind = function bind(context) { | ||
var promise = this._execute(); | ||
return promise.bind.apply(promise, arguments); | ||
}; | ||
/** | ||
* @param {function} callback | ||
* @returns {Promise} | ||
*/ | ||
/** | ||
* @param {function} callback | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'nodeify', | ||
value: function nodeify() /*callback*/{ | ||
var promise = this._execute(); | ||
return promise.nodeify.apply(promise, arguments); | ||
} | ||
/** | ||
* @returns {Promise} | ||
*/ | ||
QueryBuilder.prototype.asCallback = function asCallback(callback) { | ||
var promise = this._execute(); | ||
return promise.asCallback.apply(promise, arguments); | ||
}; | ||
}, { | ||
key: 'resultSize', | ||
value: function resultSize() { | ||
var knex = this._modelClass.knex(); | ||
/** | ||
* @param {function} callback | ||
* @returns {Promise} | ||
*/ | ||
// orderBy is useless here and it can make things a lot slower (at least with postgresql 9.3). | ||
// Remove it from the count query. We also remove the offset and limit | ||
var query = this.clone().clear(/orderBy|offset|limit/).build(); | ||
var rawQuery = knex.raw(query).wrap('(', ') as temp'); | ||
var countQuery = knex.count('* as count').from(rawQuery); | ||
return countQuery.then(function (result) { | ||
return result[0] ? result[0].count : 0; | ||
}); | ||
} | ||
QueryBuilder.prototype.nodeify = function nodeify(callback) { | ||
var promise = this._execute(); | ||
return promise.nodeify.apply(promise, arguments); | ||
}; | ||
/** | ||
* @param {number} page | ||
* @param {number} pageSize | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'page', | ||
value: function page(_page, pageSize) { | ||
return this.range(_page * pageSize, (_page + 1) * pageSize - 1); | ||
} | ||
/** | ||
* @param {number} start | ||
* @param {number} end | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.resultSize = function resultSize() { | ||
var knex = this._modelClass.knex(); | ||
}, { | ||
key: 'range', | ||
value: function range(start, end) { | ||
var self = this; | ||
var resultSizePromise = undefined; | ||
// orderBy is useless here and it can make things a lot slower (at least with postgresql 9.3). | ||
// Remove it from the count query. We also remove the offset and limit | ||
var query = this.clone().clear(/orderBy|offset|limit/).build(); | ||
var rawQuery = knex.raw(query).wrap('(', ') as temp'); | ||
var countQuery = knex.count('* as count').from(rawQuery); | ||
return this.limit(end - start + 1).offset(start).runBefore(function () { | ||
// Don't return the promise so that it is executed | ||
// in parallel with the actual query. | ||
resultSizePromise = self.resultSize(); | ||
}).runAfter(function (results) { | ||
// Now that the actual query is finished, wait until the | ||
// result size has been calculated. | ||
return _bluebird2.default.all([results, resultSizePromise]); | ||
}).runAfter(function (arr) { | ||
return { | ||
results: arr[0], | ||
total: _lodash2.default.parseInt(arr[1]) | ||
}; | ||
}); | ||
} | ||
}, { | ||
key: 'build', | ||
return countQuery.then(function (result) { | ||
return result[0] ? result[0].count : 0; | ||
}); | ||
}; | ||
/** | ||
* @returns {knex.QueryBuilder} | ||
*/ | ||
value: function build() { | ||
var builder = this.clone(); | ||
/** | ||
* @param {number} page | ||
* @param {number} pageSize | ||
* @returns {QueryBuilder} | ||
*/ | ||
if (builder.isFindQuery()) { | ||
// If no write methods have been called at this point this query is a | ||
// find query and we need to call the custom find implementation. | ||
builder._customImpl.find.call(builder, builder); | ||
} | ||
// We need to build the builder even if the _hooks.executor function | ||
// has been defined so that the onBuild hooks get called. | ||
var knexBuilder = _build(builder); | ||
QueryBuilder.prototype.page = function page(_page, pageSize) { | ||
return this.range(_page * pageSize, (_page + 1) * pageSize - 1); | ||
}; | ||
if (_lodash2.default.isFunction(builder._hooks.executor)) { | ||
// If the query executor is set, we build the builder that it returns. | ||
return builder._hooks.executor.call(builder, builder).build(); | ||
} else { | ||
return knexBuilder; | ||
} | ||
} | ||
/** | ||
* @param {number} start | ||
* @param {number} end | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: '_execute', | ||
value: function _execute() { | ||
// Take a clone so that we don't modify this instance during execution. | ||
// The hooks and onBuild callbacks usually modify the query and we want | ||
// this builder to be re-executable. | ||
var builder = this.clone(); | ||
var promise = _bluebird2.default.resolve(); | ||
var context = builder.context() || {}; | ||
var internalContext = builder.internalContext(); | ||
QueryBuilder.prototype.range = function range(start, end) { | ||
var _this2 = this; | ||
if (builder.isFindQuery()) { | ||
// If no write methods have been called at this point this query is a | ||
// find query and we need to call the custom find implementation. | ||
builder._customImpl.find.call(builder, builder); | ||
} | ||
var resultSizePromise = void 0; | ||
promise = chainBuilderFuncs(promise, builder, context.runBefore); | ||
promise = chainBuilderFuncs(promise, builder, internalContext.runBefore); | ||
promise = chainBuilderFuncs(promise, builder, builder._hooks.before); | ||
return this.limit(end - start + 1).offset(start).runBefore(function () { | ||
// Don't return the promise so that it is executed | ||
// in parallel with the actual query. | ||
resultSizePromise = _this2.resultSize(); | ||
}).runAfter(function (results) { | ||
// Now that the actual query is finished, wait until the | ||
// result size has been calculated. | ||
return _bluebird2.default.all([results, resultSizePromise]); | ||
}).runAfter(function (arr) { | ||
return { | ||
results: arr[0], | ||
total: _lodash2.default.parseInt(arr[1]) | ||
}; | ||
}); | ||
}; | ||
// Resolve all before hooks before building and executing the query | ||
// and the rest of the hooks. | ||
return promise.then(function () { | ||
// We need to build the builder even if the _explicit(Resolve|Reject)Value or _hooks.executor | ||
// has been defined so that the onBuild hooks get called. | ||
var knexBuilder = _build(builder); | ||
var promise = undefined; | ||
/** | ||
* @returns {knex.QueryBuilder} | ||
*/ | ||
if (builder._explicitResolveValue) { | ||
promise = _bluebird2.default.resolve(builder._explicitResolveValue); | ||
} else if (builder._explicitRejectValue) { | ||
promise = _bluebird2.default.reject(builder._explicitRejectValue); | ||
} else if (_lodash2.default.isFunction(builder._hooks.executor)) { | ||
promise = builder._hooks.executor.call(builder, builder); | ||
} else { | ||
promise = knexBuilder.then(function (result) { | ||
return createModels(builder, result); | ||
}); | ||
} | ||
QueryBuilder.prototype.build = function build() { | ||
// Take a clone so that we don't modify this instance during build. | ||
var builder = this.clone(); | ||
promise = chainBuilderFuncs(promise, builder, builder._hooks.afterModelCreate); | ||
if (builder.isFindQuery()) { | ||
// If no write operations have been called at this point this query is a | ||
// find query and we need to call the custom find implementation. | ||
builder._callFindOperation(); | ||
} | ||
if (builder._eagerExpression) { | ||
promise = promise.then(function (models) { | ||
return eagerFetch(builder, models); | ||
}); | ||
} | ||
// We need to build the builder even if a query executor operation | ||
// has been called so that the onBuild hooks get called. | ||
var knexBuilder = _build(builder); | ||
var queryExecutorOperation = builder._queryExecutorOperation(); | ||
promise = chainBuilderFuncs(promise, builder, context.runAfter); | ||
promise = chainBuilderFuncs(promise, builder, internalContext.runAfter); | ||
promise = chainBuilderFuncs(promise, builder, builder._hooks.after); | ||
return promise; | ||
}); | ||
if (queryExecutorOperation) { | ||
// If the query executor is set, we build the builder that it returns. | ||
return queryExecutorOperation.queryExecutor(builder).build(); | ||
} else { | ||
return knexBuilder; | ||
} | ||
}; | ||
/** | ||
* @param {string} propertyName | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @private | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
}, { | ||
key: 'pluck', | ||
value: function pluck(propertyName) { | ||
return this.runAfter(function (result) { | ||
if (_lodash2.default.isArray(result)) { | ||
return _lodash2.default.pluck(result, propertyName); | ||
} else { | ||
return result; | ||
} | ||
}); | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype._queryExecutorOperation = function _queryExecutorOperation() { | ||
var executors = _lodash2.default.filter(this._operations, function (method) { | ||
return method.hasQueryExecutor(); | ||
}); | ||
}, { | ||
key: 'first', | ||
value: function first() { | ||
return this.runAfter(function (result) { | ||
if (_lodash2.default.isArray(result)) { | ||
return result[0]; | ||
} else { | ||
return result; | ||
} | ||
}); | ||
if (executors.length > 1) { | ||
throw new Error('there can only be one method call that implements queryExecutor()'); | ||
} | ||
/** | ||
* @param {Constructor.<Model>=} modelClass | ||
* @param {function(Model, Model, string)} traverser | ||
* @returns {QueryBuilder} | ||
*/ | ||
return executors[0]; | ||
}; | ||
}, { | ||
key: 'traverse', | ||
value: function traverse(modelClass, traverser) { | ||
var self = this; | ||
/** | ||
* @private | ||
*/ | ||
if (_lodash2.default.isUndefined(traverser)) { | ||
traverser = modelClass; | ||
modelClass = null; | ||
} | ||
return this.runAfter(function (result) { | ||
self._modelClass.traverse(modelClass, result, traverser); | ||
return result; | ||
}); | ||
} | ||
QueryBuilder.prototype._callFindOperation = function _callFindOperation() { | ||
this.callQueryBuilderOperation(this._findOperationFactory(this), []); | ||
}; | ||
/** | ||
* @param {Constructor.<Model>=} modelClass | ||
* @param {Array.<string>} properties | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @private | ||
* @returns {Promise} | ||
*/ | ||
}, { | ||
key: 'pick', | ||
value: function pick(modelClass, properties) { | ||
if (_lodash2.default.isUndefined(properties)) { | ||
properties = modelClass; | ||
modelClass = null; | ||
} | ||
properties = _lodash2.default.reduce(properties, function (obj, prop) { | ||
obj[prop] = true; | ||
return obj; | ||
}, {}); | ||
QueryBuilder.prototype._execute = function _execute() { | ||
// Take a clone so that we don't modify this instance during execution. | ||
var builder = this.clone(); | ||
var promise = _bluebird2.default.resolve(); | ||
var context = builder.context() || {}; | ||
var internalContext = builder.internalContext(); | ||
return this.traverse(modelClass, function (model) { | ||
model.$pick(properties); | ||
}); | ||
if (builder.isFindQuery()) { | ||
// If no write operations have been called at this point this query is a | ||
// find query and we need to call the custom find implementation. | ||
builder._callFindOperation(); | ||
} | ||
/** | ||
* @param {Constructor.<Model>=} modelClass | ||
* @param {Array.<string>} properties | ||
* @returns {QueryBuilder} | ||
*/ | ||
promise = chainBeforeOperations(promise, builder, builder._operations); | ||
promise = chainHooks(promise, builder, context.runBefore); | ||
promise = chainHooks(promise, builder, internalContext.runBefore); | ||
promise = chainBeforeInternalOperations(promise, builder, builder._operations); | ||
}, { | ||
key: 'omit', | ||
value: function omit(modelClass, properties) { | ||
if (_lodash2.default.isUndefined(properties)) { | ||
properties = modelClass; | ||
modelClass = null; | ||
// Resolve all before hooks before building and executing the query | ||
// and the rest of the hooks. | ||
return promise.then(function () { | ||
// We need to build the builder even if the _explicit(Resolve|Reject)Value or _hooks.executor | ||
// has been defined so that the onBuild hooks get called. | ||
var knexBuilder = _build(builder); | ||
var queryExecutorOperation = builder._queryExecutorOperation(); | ||
var promise = void 0; | ||
if (builder._explicitRejectValue) { | ||
promise = _bluebird2.default.reject(builder._explicitRejectValue); | ||
} else if (builder._explicitResolveValue) { | ||
promise = _bluebird2.default.resolve(builder._explicitResolveValue); | ||
} else if (queryExecutorOperation) { | ||
promise = queryExecutorOperation.queryExecutor(builder); | ||
} else { | ||
promise = knexBuilder.then(function (result) { | ||
return createModels(builder, result); | ||
}); | ||
} | ||
// Turn the properties into a hash for performance. | ||
properties = _lodash2.default.reduce(properties, function (obj, prop) { | ||
obj[prop] = true; | ||
return obj; | ||
}, {}); | ||
promise = chainAfterQueryOperations(promise, builder, builder._operations); | ||
promise = chainAfterIntenralOperations(promise, builder, builder._operations); | ||
return this.traverse(modelClass, function (model) { | ||
model.$omit(properties); | ||
}); | ||
} | ||
if (builder._eagerExpression) { | ||
promise = promise.then(function (models) { | ||
return eagerFetch(builder, models); | ||
}); | ||
} | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
promise = chainHooks(promise, builder, context.runAfter); | ||
promise = chainHooks(promise, builder, internalContext.runAfter); | ||
promise = chainAfterOperations(promise, builder, builder._operations); | ||
}, { | ||
key: 'joinRelation', | ||
value: function joinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'join'); | ||
} | ||
return promise; | ||
}); | ||
}; | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {string} propertyName | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'innerJoinRelation', | ||
value: function innerJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'innerJoin'); | ||
} | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.pluck = function pluck(propertyName) { | ||
return this.runAfter(function (result) { | ||
if (_lodash2.default.isArray(result)) { | ||
return _lodash2.default.map(result, propertyName); | ||
} else { | ||
return result; | ||
} | ||
}); | ||
}; | ||
}, { | ||
key: 'outerJoinRelation', | ||
value: function outerJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'outerJoin'); | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'leftJoinRelation', | ||
value: function leftJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'leftJoin'); | ||
} | ||
QueryBuilder.prototype.first = function first() { | ||
return this.runAfter(function (result) { | ||
if (_lodash2.default.isArray(result)) { | ||
return result[0]; | ||
} else { | ||
return result; | ||
} | ||
}); | ||
}; | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {Constructor.<Model>=} modelClass | ||
* @param {function(Model, Model, string)} traverser | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'leftOuterJoinRelation', | ||
value: function leftOuterJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'leftOuterJoin'); | ||
} | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.traverse = function traverse(modelClass, traverser) { | ||
var _this3 = this; | ||
}, { | ||
key: 'rightJoinRelation', | ||
value: function rightJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'rightJoin'); | ||
if (_lodash2.default.isUndefined(traverser)) { | ||
traverser = modelClass; | ||
modelClass = null; | ||
} | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
return this.runAfter(function (result) { | ||
_this3._modelClass.traverse(modelClass, result, traverser); | ||
return result; | ||
}); | ||
}; | ||
}, { | ||
key: 'rightOuterJoinRelation', | ||
value: function rightOuterJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'rightOuterJoin'); | ||
} | ||
/** | ||
* @param {Constructor.<Model>=} modelClass | ||
* @param {Array.<string>} properties | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'fullOuterJoinRelation', | ||
value: function fullOuterJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'fullOuterJoin'); | ||
QueryBuilder.prototype.pick = function pick(modelClass, properties) { | ||
if (_lodash2.default.isUndefined(properties)) { | ||
properties = modelClass; | ||
modelClass = null; | ||
} | ||
/** | ||
* @private | ||
*/ | ||
properties = _lodash2.default.reduce(properties, function (obj, prop) { | ||
obj[prop] = true; | ||
return obj; | ||
}, {}); | ||
}, { | ||
key: '$$joinRelation', | ||
value: function $$joinRelation(relationName, joinMethod) { | ||
var relation = this._modelClass.getRelation(relationName); | ||
relation.join(this, joinMethod, relation.name); | ||
return this; | ||
} | ||
return this.traverse(modelClass, function (model) { | ||
model.$pick(properties); | ||
}); | ||
}; | ||
/** | ||
* @param {string|number|Array.<string|number>} id | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {Constructor.<Model>=} modelClass | ||
* @param {Array.<string>} properties | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'findById', | ||
value: function findById(id) { | ||
return this.whereComposite(this._modelClass.getFullIdColumn(), id).first(); | ||
QueryBuilder.prototype.omit = function omit(modelClass, properties) { | ||
if (_lodash2.default.isUndefined(properties)) { | ||
properties = modelClass; | ||
modelClass = null; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
// Turn the properties into a hash for performance. | ||
properties = _lodash2.default.reduce(properties, function (obj, prop) { | ||
obj[prop] = true; | ||
return obj; | ||
}, {}); | ||
}, { | ||
key: 'withSchema', | ||
value: function withSchema(schema) { | ||
this.internalContext().onBuild.push(function (builder) { | ||
if (!builder.has(/withSchema/)) { | ||
// If the builder already has a schema, don't override it. | ||
builder.callKnexMethod('withSchema', [schema]); | ||
} | ||
}); | ||
return this.traverse(modelClass, function (model) { | ||
model.$omit(properties); | ||
}); | ||
}; | ||
return this; | ||
} | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'insert', | ||
value: function insert(modelsOrObjects) { | ||
var ModelClass = this._modelClass; | ||
QueryBuilder.prototype.joinRelation = function joinRelation(relationName) {}; | ||
var insertion = new _InsertionOrUpdate2.default({ | ||
ModelClass: ModelClass, | ||
modelsOrObjects: modelsOrObjects | ||
}); | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
this.$$callWriteMethodImpl('insert', [insertion, this]); | ||
this.runBefore(function (result, builder) { | ||
if (insertion.models().length > 1 && !(0, _dbUtils.isPostgres)(ModelClass.knex())) { | ||
throw new Error('batch insert only works with Postgresql'); | ||
} else { | ||
return _bluebird2.default.map(insertion.models(), function (model) { | ||
return model.$beforeInsert(builder.context()); | ||
}); | ||
} | ||
}); | ||
QueryBuilder.prototype.innerJoinRelation = function innerJoinRelation(relationName) {}; | ||
this.onBuild(function (builder) { | ||
if (!builder.has(/returning/)) { | ||
// If the user hasn't specified a `returning` clause, we make sure | ||
// that at least the identifier is returned. | ||
builder.returning(ModelClass.idColumn); | ||
} | ||
}); | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
this.runAfterModelCreatePushFront(function (ret) { | ||
if (!_lodash2.default.isArray(ret) || _lodash2.default.isEmpty(ret)) { | ||
// Early exit if there is nothing to do. | ||
return insertion.models(); | ||
} | ||
// If the user specified a `returning` clause the result may already bean array of objects. | ||
if (_lodash2.default.all(ret, _lodash2.default.isObject)) { | ||
_lodash2.default.forEach(insertion.models(), function (model, index) { | ||
model.$set(ret[index]); | ||
}); | ||
} else { | ||
// If the return value is not an array of objects, we assume it is an array of identifiers. | ||
_lodash2.default.forEach(insertion.models(), function (model, idx) { | ||
// Don't set the id if the model already has one. MySQL and Sqlite don't return the correct | ||
// primary key value if the id is not generated in db, but given explicitly. | ||
if (!model.$id()) { | ||
model.$id(ret[idx]); | ||
} | ||
}); | ||
} | ||
QueryBuilder.prototype.outerJoinRelation = function outerJoinRelation(relationName) {}; | ||
return insertion.models(); | ||
}); | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
this.runAfterModelCreate(function (models, builder) { | ||
return _bluebird2.default.map(models, function (model) { | ||
return model.$afterInsert(builder.context()); | ||
}).then(function () { | ||
if (insertion.isArray()) { | ||
return models; | ||
} else { | ||
return models[0] || null; | ||
} | ||
}); | ||
}); | ||
return this; | ||
} | ||
QueryBuilder.prototype.leftJoinRelation = function leftJoinRelation(relationName) {}; | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'insertAndFetch', | ||
value: function insertAndFetch(modelsOrObjects) { | ||
var ModelClass = this._modelClass; | ||
return this.insert(modelsOrObjects).runAfterModelCreate(function (insertedModels, builder) { | ||
var insertedModelArray = _lodash2.default.isArray(insertedModels) ? insertedModels : [insertedModels]; | ||
QueryBuilder.prototype.leftOuterJoinRelation = function leftOuterJoinRelation(relationName) {}; | ||
return ModelClass.query().childQueryOf(builder).whereInComposite(ModelClass.getFullIdColumn(), _lodash2.default.map(insertedModelArray, function (model) { | ||
return model.$id(); | ||
})).then(function (fetchedModels) { | ||
fetchedModels = _lodash2.default.indexBy(fetchedModels, function (model) { | ||
return model.$id(); | ||
}); | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
// Instead of returning the freshly fetched models, update the input | ||
// models with the fresh values. | ||
_lodash2.default.forEach(insertedModelArray, function (insertedModel) { | ||
insertedModel.$set(fetchedModels[insertedModel.$id()]); | ||
}); | ||
return insertedModels; | ||
}); | ||
}); | ||
} | ||
QueryBuilder.prototype.rightJoinRelation = function rightJoinRelation(relationName) {}; | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'insertWithRelated', | ||
value: function insertWithRelated(modelsOrObjects) { | ||
var ModelClass = this._modelClass; | ||
var batchSize = (0, _dbUtils.isPostgres)(ModelClass.knex()) ? 100 : 1; | ||
var insertion = new _InsertionOrUpdate2.default({ | ||
ModelClass: ModelClass, | ||
modelsOrObjects: modelsOrObjects, | ||
// We need to skip validation at this point because the models may contain | ||
// references and special properties. We validate the models upon insertion. | ||
modelOptions: { skipValidation: true } | ||
}); | ||
QueryBuilder.prototype.rightOuterJoinRelation = function rightOuterJoinRelation(relationName) {}; | ||
this.$$callWriteMethodImpl('insert', [insertion, this]); | ||
/** | ||
* @param {string} relationName | ||
* @returns {QueryBuilder} | ||
*/ | ||
// We resolve this query here and will not execute it. This is because the root | ||
// value may depend on other models in the graph and cannot be inserted first. | ||
this.resolve([]); | ||
this.runAfterModelCreatePushFront(function (result, builder) { | ||
var inserter = new _InsertWithRelated2.default({ | ||
modelClass: ModelClass, | ||
models: insertion.models(), | ||
allowedRelations: builder._allowedInsertExpression || null | ||
}); | ||
QueryBuilder.prototype.fullOuterJoinRelation = function fullOuterJoinRelation(relationName) {}; | ||
return inserter.execute(function (tableInsertion) { | ||
var insertQuery = tableInsertion.modelClass.query().childQueryOf(builder); | ||
/** | ||
* @param {string|number|Array.<string|number>} id | ||
* @returns {QueryBuilder} | ||
*/ | ||
// We skipped the validation above. We need to validate here since at this point | ||
// the models should no longer contain any special properties. | ||
_lodash2.default.forEach(tableInsertion.models, function (model) { | ||
model.$validate(); | ||
}); | ||
var inputs = _lodash2.default.filter(tableInsertion.models, function (model, idx) { | ||
return tableInsertion.isInputModel[idx]; | ||
}); | ||
QueryBuilder.prototype.findById = function findById(id) { | ||
return this.whereComposite(this._modelClass.getFullIdColumn(), id).first(); | ||
}; | ||
var others = _lodash2.default.filter(tableInsertion.models, function (model, idx) { | ||
return !tableInsertion.isInputModel[idx]; | ||
}); | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
return _bluebird2.default.all(_lodash2.default.flatten([batchInsert(inputs, insertQuery.clone().copyFrom(builder, /returning/), batchSize), batchInsert(others, insertQuery.clone(), batchSize)])); | ||
}); | ||
}); | ||
this.runAfterModelCreate(function (models) { | ||
if (insertion.isArray()) { | ||
return models; | ||
} else { | ||
return _lodash2.default.first(models) || null; | ||
} | ||
}); | ||
} | ||
QueryBuilder.prototype.withSchema = function withSchema(schema) { | ||
this.internalContext().onBuild.push(function (builder) { | ||
if (!builder.has(/withSchema/)) { | ||
builder.callKnexQueryBuilderOperation('withSchema', [schema]); | ||
} | ||
}); | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: '$$insert', | ||
value: function $$insert(insertion) { | ||
var input = insertion; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
if (insertion instanceof _InsertionOrUpdate2.default) { | ||
insertion = insertion.models(); | ||
} | ||
if (_lodash2.default.isArray(insertion)) { | ||
input = _lodash2.default.map(insertion, function (obj) { | ||
if (_lodash2.default.isFunction(obj.$toDatabaseJson)) { | ||
return obj.$toDatabaseJson(); | ||
} else { | ||
return obj; | ||
} | ||
}); | ||
} else if (_lodash2.default.isFunction(insertion.$toDatabaseJson)) { | ||
input = insertion.$toDatabaseJson(); | ||
} | ||
QueryBuilder.prototype.debug = function debug() { | ||
this.internalContext().onBuild.push(function (builder) { | ||
builder.callKnexQueryBuilderOperation('debug', []); | ||
}); | ||
return (0, _get4.default)((0, _getPrototypeOf2.default)(QueryBuilder.prototype), 'insert', this).call(this, input); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'update', | ||
value: function update(modelOrObject) { | ||
return this.$$updateWithOptions(modelOrObject, 'update', {}); | ||
} | ||
/** | ||
* @param {number|string|Array.<number|string>} id | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.insert = function insert(modelsOrObjects) { | ||
var insertOperation = this._insertOperationFactory(this); | ||
return this.callQueryBuilderOperation(insertOperation, [modelsOrObjects]); | ||
}; | ||
}, { | ||
key: 'updateAndFetchById', | ||
value: function updateAndFetchById(id, modelOrObject) { | ||
return this.$$updateWithOptions(modelOrObject, 'update', {}, id).whereComposite(this._modelClass.getFullIdColumn(), id); | ||
} | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: '$$updateWithOptions', | ||
value: function $$updateWithOptions(modelOrObject, method, modelOptions, fetchId) { | ||
var ModelClass = this._modelClass; | ||
QueryBuilder.prototype.insertAndFetch = function insertAndFetch(modelsOrObjects) { | ||
var insertAndFetchOperation = new _InsertAndFetchOperation2.default(this, 'insertAndFetch', { | ||
delegate: this._insertOperationFactory(this) | ||
}); | ||
var update = new _InsertionOrUpdate2.default({ | ||
ModelClass: ModelClass, | ||
modelOptions: modelOptions, | ||
modelsOrObjects: modelOrObject | ||
}); | ||
return this.callQueryBuilderOperation(insertAndFetchOperation, [modelsOrObjects]); | ||
}; | ||
this.$$callWriteMethodImpl(method, [update, this]); | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
this.runBefore(function (result, builder) { | ||
return update.model().$beforeUpdate(modelOptions, builder.context()); | ||
}); | ||
this.runAfterModelCreate(function (numUpdated, builder) { | ||
var promise = undefined; | ||
QueryBuilder.prototype.insertWithRelated = function insertWithRelated(modelsOrObjects) { | ||
var insertWithRelatedOperation = new _InsertWithRelatedOperation2.default(this, 'insertWithRelated', { | ||
delegate: this._insertOperationFactory(this) | ||
}); | ||
if (fetchId) { | ||
promise = ModelClass.query().first().childQueryOf(builder).whereComposite(ModelClass.getFullIdColumn(), fetchId).then(function (model) { | ||
return model ? update.model().$set(model) : null; | ||
}); | ||
} else { | ||
promise = _bluebird2.default.resolve(numUpdated); | ||
} | ||
return this.callQueryBuilderOperation(insertWithRelatedOperation, [modelsOrObjects]); | ||
}; | ||
return promise.then(function (result) { | ||
return [result, update.model().$afterUpdate(modelOptions, builder.context())]; | ||
}).spread(function (result) { | ||
return result; | ||
}); | ||
}); | ||
/** | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.update = function update(modelOrObject) { | ||
var updateOperation = this._updateOperationFactory(this); | ||
return this.callQueryBuilderOperation(updateOperation, [modelOrObject]); | ||
}; | ||
}, { | ||
key: '$$update', | ||
value: function $$update(update) { | ||
var input = update; | ||
var idColumn = this._modelClass.idColumn; | ||
/** | ||
* @param {number|string|Array.<number|string>} id | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
if (update instanceof _InsertionOrUpdate2.default) { | ||
update = update.model(); | ||
} | ||
if (_lodash2.default.isFunction(update.$toDatabaseJson)) { | ||
input = update.$toDatabaseJson(); | ||
} | ||
QueryBuilder.prototype.updateAndFetchById = function updateAndFetchById(id, modelOrObject) { | ||
var updateAndFetch = new _UpdateAndFetchOperation2.default(this, 'updateAndFetch', { | ||
delegate: this._updateOperationFactory(this) | ||
}); | ||
// We never want to update the identifier. | ||
// TODO: Maybe we do? | ||
if (_lodash2.default.isArray(idColumn)) { | ||
_lodash2.default.each(idColumn, function (col) { | ||
delete input[col]; | ||
}); | ||
} else { | ||
delete input[idColumn]; | ||
} | ||
return this.callQueryBuilderOperation(updateAndFetch, [id, modelOrObject]); | ||
}; | ||
return (0, _get4.default)((0, _getPrototypeOf2.default)(QueryBuilder.prototype), 'update', this).call(this, input); | ||
} | ||
/** | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'patch', | ||
value: function patch(modelOrObject) { | ||
return this.$$updateWithOptions(modelOrObject, 'patch', { patch: true }); | ||
} | ||
QueryBuilder.prototype.patch = function patch(modelOrObject) { | ||
var patchOperation = this._patchOperationFactory(this); | ||
return this.callQueryBuilderOperation(patchOperation, [modelOrObject]); | ||
}; | ||
/** | ||
* @param {number|string|Array.<number|string>} id | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {number|string|Array.<number|string>} id | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'patchAndFetchById', | ||
value: function patchAndFetchById(id, modelOrObject) { | ||
return this.$$updateWithOptions(modelOrObject, 'patch', { patch: true }, id).whereComposite(this._modelClass.getFullIdColumn(), id); | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.patchAndFetchById = function patchAndFetchById(id, modelOrObject) { | ||
var patchAndFetch = new _UpdateAndFetchOperation2.default(this, 'patchAndFetch', { | ||
delegate: this._patchOperationFactory(this) | ||
}); | ||
}, { | ||
key: 'delete', | ||
value: function _delete() { | ||
this.$$callWriteMethodImpl('delete', [this]); | ||
return this; | ||
} | ||
return this.callQueryBuilderOperation(patchAndFetch, [id, modelOrObject]); | ||
}; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'del', | ||
value: function del() { | ||
return this.delete(); | ||
} | ||
/** | ||
* @param {number|string|Array.<number|string>} id | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.delete = function _delete() { | ||
var deleteOperation = this._deleteOperationFactory(this); | ||
return this.callQueryBuilderOperation(deleteOperation, []); | ||
}; | ||
}, { | ||
key: 'deleteById', | ||
value: function deleteById(id) { | ||
return this.delete().whereComposite(this._modelClass.getFullIdColumn(), id); | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: '$$delete', | ||
value: function $$delete() { | ||
return (0, _get4.default)((0, _getPrototypeOf2.default)(QueryBuilder.prototype), 'delete', this).call(this); | ||
} | ||
QueryBuilder.prototype.del = function del() { | ||
return this.delete(); | ||
}; | ||
/** | ||
* @param {number|string|object|Array.<number|string>|Array.<Array.<number|string>>|Array.<object>} ids | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @param {number|string|Array.<number|string>} id | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'relate', | ||
value: function relate(ids) { | ||
this.$$callWriteMethodImpl('relate', [ids, this]); | ||
return this.runAfterModelCreate(function () { | ||
return ids; | ||
}); | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.deleteById = function deleteById(id) { | ||
return this.delete().whereComposite(this._modelClass.getFullIdColumn(), id); | ||
}; | ||
}, { | ||
key: 'unrelate', | ||
value: function unrelate() { | ||
this.$$callWriteMethodImpl('unrelate', [this]); | ||
this.runAfterModelCreate(function () { | ||
return {}; | ||
}); | ||
return this; | ||
} | ||
/** | ||
* @param {number|string|object|Array.<number|string>|Array.<Array.<number|string>>|Array.<object>} ids | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'increment', | ||
value: function increment(propertyName, howMuch) { | ||
var patch = {}; | ||
var columnName = this._modelClass.propertyNameToColumnName(propertyName); | ||
patch[propertyName] = this._modelClass.knex().raw('?? + ?', [columnName, howMuch]); | ||
return this.patch(patch); | ||
} | ||
QueryBuilder.prototype.relate = function relate(ids) { | ||
var relateOperation = this._relateOperationFactory(this); | ||
return this.callQueryBuilderOperation(relateOperation, [ids]); | ||
}; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'decrement', | ||
value: function decrement(propertyName, howMuch) { | ||
var patch = {}; | ||
var columnName = this._modelClass.propertyNameToColumnName(propertyName); | ||
patch[propertyName] = this._modelClass.knex().raw('?? - ?', [columnName, howMuch]); | ||
return this.patch(patch); | ||
} | ||
/** | ||
* @private | ||
*/ | ||
QueryBuilder.prototype.unrelate = function unrelate() { | ||
var unrelateOperation = this._unrelateOperationFactory(this); | ||
return this.callQueryBuilderOperation(unrelateOperation, []); | ||
}; | ||
}, { | ||
key: '$$callWriteMethodImpl', | ||
value: function $$callWriteMethodImpl(method, args) { | ||
this._calledWriteMethod = 'method'; | ||
return this._customImpl[method].apply(this, args); | ||
} | ||
}], [{ | ||
key: 'forClass', | ||
value: function forClass(modelClass) { | ||
return new this(modelClass); | ||
} | ||
}]); | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.increment = function increment(propertyName, howMuch) { | ||
var patch = {}; | ||
var columnName = this._modelClass.propertyNameToColumnName(propertyName); | ||
patch[propertyName] = this._modelClass.knex().raw('?? + ?', [columnName, howMuch]); | ||
return this.patch(patch); | ||
}; | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
QueryBuilder.prototype.decrement = function decrement(propertyName, howMuch) { | ||
var patch = {}; | ||
var columnName = this._modelClass.propertyNameToColumnName(propertyName); | ||
patch[propertyName] = this._modelClass.knex().raw('?? - ?', [columnName, howMuch]); | ||
return this.patch(patch); | ||
}; | ||
return QueryBuilder; | ||
}(_QueryBuilderBase3.default), (_applyDecoratedDescriptor(_class.prototype, 'dumpSql', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'dumpSql'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'insert', [writeQueryMethod], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'insert'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'insertWithRelated', [writeQueryMethod], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'insertWithRelated'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, '$$updateWithOptions', [writeQueryMethod], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, '$$updateWithOptions'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'delete', [writeQueryMethod], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'delete'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'relate', [writeQueryMethod], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'relate'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'unrelate', [writeQueryMethod], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'unrelate'), _class.prototype)), _class)); | ||
}(_QueryBuilderBase3.default), (_applyDecoratedDescriptor(_class.prototype, 'runBefore', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'runBefore'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'onBuild', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'onBuild'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'runAfter', [_dec3], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'runAfter'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'dumpSql', [_dec4], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'dumpSql'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'joinRelation', [_dec5], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'joinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'innerJoinRelation', [_dec6], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'innerJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'outerJoinRelation', [_dec7], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'outerJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'leftJoinRelation', [_dec8], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'leftJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'leftOuterJoinRelation', [_dec9], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'leftOuterJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'rightJoinRelation', [_dec10], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'rightJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'rightOuterJoinRelation', [_dec11], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'rightOuterJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'fullOuterJoinRelation', [_dec12], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullOuterJoinRelation'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'insert', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'insert'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'insertAndFetch', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'insertAndFetch'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'insertWithRelated', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'insertWithRelated'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'update', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'update'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'updateAndFetchById', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'updateAndFetchById'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'patch', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'patch'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'patchAndFetchById', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'patchAndFetchById'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'delete', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'delete'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'relate', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'relate'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'unrelate', [writeQueryOperation], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'unrelate'), _class.prototype)), _class)); | ||
exports.default = QueryBuilder; | ||
function writeQueryMethod(target, property, descriptor) { | ||
descriptor.value = tryCallWriteMethod(descriptor.value); | ||
} | ||
function tryCallWriteMethod(func) { | ||
return function () { | ||
if (this._calledWriteMethod) { | ||
this.reject(new Error('Double call to a write method. ' + 'You can only call one of the write methods ' + '(insert, update, patch, delete, relate, unrelate, increment, decrement) ' + 'and only once per query builder.')); | ||
return this; | ||
function writeQueryOperation(target, property, descriptor) { | ||
var func = descriptor.value; | ||
descriptor.value = function decorator$writeQueryOperation() { | ||
if (!this.isFindQuery()) { | ||
return this.reject(new Error('Double call to a write method. ' + 'You can only call one of the write methods ' + '(insert, update, patch, delete, relate, unrelate, increment, decrement) ' + 'and only once per query builder.')); | ||
} | ||
@@ -1672,24 +1237,16 @@ | ||
var internalContext = builder.internalContext(); | ||
var knexBuilder = builder.knex().queryBuilder(); | ||
if (!builder.has(/from|table|into/)) { | ||
// Set the table only if it hasn't been explicitly set yet. | ||
builder.table(builder._modelClass.tableName); | ||
builder.table(builder.modelClass().tableName); | ||
} | ||
callBuilderFuncs(builder, context.onBuild); | ||
callBuilderFuncs(builder, internalContext.onBuild); | ||
callBuilderFuncs(builder, builder._hooks.onBuild); | ||
callOnBuildHooks(builder, context.onBuild); | ||
callOnBuildHooks(builder, internalContext.onBuild); | ||
// noinspection JSUnresolvedVariable | ||
return _QueryBuilderBase3.default.prototype.build.call(builder); | ||
return builder.buildInto(knexBuilder); | ||
} | ||
function batchInsert(models, queryBuilder, batchSize) { | ||
var batches = _lodash2.default.chunk(models, batchSize); | ||
return _lodash2.default.map(batches, function (batch) { | ||
return queryBuilder.clone().insert(batch); | ||
}); | ||
} | ||
function callBuilderFuncs(builder, func) { | ||
function callOnBuildHooks(builder, func) { | ||
if (_lodash2.default.isFunction(func)) { | ||
@@ -1704,3 +1261,3 @@ func.call(builder, builder); | ||
function chainBuilderFuncs(promise, builder, func) { | ||
function chainHooks(promise, builder, func) { | ||
if (_lodash2.default.isFunction(func)) { | ||
@@ -1719,2 +1276,56 @@ promise = promise.then(function (result) { | ||
return promise; | ||
} | ||
function chainBeforeOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, function (res, method) { | ||
return method.onBefore(builder, res); | ||
}, function (method) { | ||
return method.hasOnBefore(); | ||
}); | ||
} | ||
function chainBeforeInternalOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, function (res, method) { | ||
return method.onBeforeInternal(builder, res); | ||
}, function (method) { | ||
return method.hasOnBeforeInternal(); | ||
}); | ||
} | ||
function chainAfterQueryOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, function (res, method) { | ||
return method.onAfterQuery(builder, res); | ||
}, function (method) { | ||
return method.hasOnAfterQuery(); | ||
}); | ||
} | ||
function chainAfterOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, function (res, method) { | ||
return method.onAfter(builder, res); | ||
}, function (method) { | ||
return method.hasOnAfter(); | ||
}); | ||
} | ||
function chainAfterIntenralOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, function (res, method) { | ||
return method.onAfterInternal(builder, res); | ||
}, function (method) { | ||
return method.hasOnAfterInternal(); | ||
}); | ||
} | ||
function promiseChain(promise, items, call, has) { | ||
_lodash2.default.each(items, function (item) { | ||
if (!has(item)) { | ||
return; | ||
} | ||
promise = promise.then(function (res) { | ||
return call(res, item); | ||
}); | ||
}); | ||
return promise; | ||
} |
'use strict'; | ||
var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec10, _dec11, _dec12, _dec13, _dec14, _dec15, _dec16, _dec17, _dec18, _dec19, _dec20, _dec21, _dec22, _dec23, _dec24, _dec25, _dec26, _dec27, _dec28, _dec29, _dec30, _dec31, _dec32, _dec33, _dec34, _dec35, _dec36, _dec37, _dec38, _dec39, _dec40, _dec41, _dec42, _dec43, _dec44, _dec45, _dec46, _dec47, _dec48, _dec49, _dec50, _dec51, _dec52, _dec53, _dec54, _dec55, _dec56, _dec57, _dec58, _dec59, _dec60, _dec61, _dec62, _dec63, _dec64, _dec65, _dec66, _dec67, _dec68, _dec69, _dec70, _dec71, _dec72, _dec73, _dec74, _dec75, _dec76, _class, _desc, _value, _class2; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -10,6 +8,2 @@ value: true | ||
var _stringify = require('babel-runtime/core-js/json/stringify'); | ||
var _stringify2 = _interopRequireDefault(_stringify); | ||
var _getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor'); | ||
@@ -19,6 +13,2 @@ | ||
var _typeof2 = require('babel-runtime/helpers/typeof'); | ||
var _typeof3 = _interopRequireDefault(_typeof2); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
@@ -28,6 +18,4 @@ | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec10, _dec11, _dec12, _dec13, _dec14, _dec15, _dec16, _dec17, _dec18, _dec19, _dec20, _dec21, _dec22, _dec23, _dec24, _dec25, _dec26, _dec27, _dec28, _dec29, _dec30, _dec31, _dec32, _dec33, _dec34, _dec35, _dec36, _dec37, _dec38, _dec39, _dec40, _dec41, _dec42, _dec43, _dec44, _dec45, _dec46, _dec47, _dec48, _dec49, _dec50, _dec51, _dec52, _dec53, _dec54, _dec55, _dec56, _dec57, _dec58, _dec59, _dec60, _dec61, _dec62, _dec63, _dec64, _dec65, _dec66, _dec67, _dec68, _dec69, _dec70, _dec71, _dec72, _dec73, _dec74, _dec75, _dec76, _dec77, _dec78, _dec79, _dec80, _dec81, _dec82, _dec83, _dec84, _dec85, _dec86, _dec87, _dec88, _dec89, _dec90, _dec91, _dec92, _dec93, _dec94, _dec95, _dec96, _dec97, _dec98, _dec99, _dec100, _dec101, _dec102, _dec103, _desc, _value, _class; | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _lodash = require('lodash'); | ||
@@ -37,10 +25,48 @@ | ||
var _jsonFieldExpressionParser = require('./parsers/jsonFieldExpressionParser'); | ||
var _queryBuilderOperation = require('./decorators/queryBuilderOperation'); | ||
var _jsonFieldExpressionParser2 = _interopRequireDefault(_jsonFieldExpressionParser); | ||
var _queryBuilderOperation2 = _interopRequireDefault(_queryBuilderOperation); | ||
var _classUtils = require('../utils/classUtils'); | ||
var _dbUtils = require('../utils/dbUtils'); | ||
var _QueryBuilderContextBase = require('./QueryBuilderContextBase'); | ||
var _QueryBuilderContextBase2 = _interopRequireDefault(_QueryBuilderContextBase); | ||
var _KnexOperation = require('./operations/KnexOperation'); | ||
var _KnexOperation2 = _interopRequireDefault(_KnexOperation); | ||
var _WhereRefOperation = require('./operations/WhereRefOperation'); | ||
var _WhereRefOperation2 = _interopRequireDefault(_WhereRefOperation); | ||
var _WhereCompositeOperation = require('./operations/WhereCompositeOperation'); | ||
var _WhereCompositeOperation2 = _interopRequireDefault(_WhereCompositeOperation); | ||
var _WhereInCompositeOperation = require('./operations/WhereInCompositeOperation'); | ||
var _WhereInCompositeOperation2 = _interopRequireDefault(_WhereInCompositeOperation); | ||
var _WhereInCompositeSqliteOperation = require('./operations/WhereInCompositeSqliteOperation'); | ||
var _WhereInCompositeSqliteOperation2 = _interopRequireDefault(_WhereInCompositeSqliteOperation); | ||
var _WhereJsonPostgresOperation = require('./operations/jsonApi/WhereJsonPostgresOperation'); | ||
var _WhereJsonPostgresOperation2 = _interopRequireDefault(_WhereJsonPostgresOperation); | ||
var _WhereJsonHasPostgresOperation = require('./operations/jsonApi/WhereJsonHasPostgresOperation'); | ||
var _WhereJsonHasPostgresOperation2 = _interopRequireDefault(_WhereJsonHasPostgresOperation); | ||
var _WhereJsonFieldPostgresOperation = require('./operations/jsonApi/WhereJsonFieldPostgresOperation'); | ||
var _WhereJsonFieldPostgresOperation2 = _interopRequireDefault(_WhereJsonFieldPostgresOperation); | ||
var _WhereJsonNotObjectPostgresOperation = require('./operations/jsonApi/WhereJsonNotObjectPostgresOperation'); | ||
var _WhereJsonNotObjectPostgresOperation2 = _interopRequireDefault(_WhereJsonNotObjectPostgresOperation); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -81,13 +107,25 @@ | ||
*/ | ||
var QueryBuilderBase = (_dec = (0, _dbUtils.overwriteForDatabase)(), _dec2 = knexQueryMethod(), _dec3 = knexQueryMethod(), _dec4 = knexQueryMethod(), _dec5 = knexQueryMethod('delete'), _dec6 = knexQueryMethod(), _dec7 = knexQueryMethod(), _dec8 = knexQueryMethod(), _dec9 = knexQueryMethod(), _dec10 = knexQueryMethod(), _dec11 = knexQueryMethod(), _dec12 = knexQueryMethod(), _dec13 = knexQueryMethod(), _dec14 = knexQueryMethod(), _dec15 = knexQueryMethod(), _dec16 = knexQueryMethod(), _dec17 = knexQueryMethod(), _dec18 = knexQueryMethod(), _dec19 = knexQueryMethod(), _dec20 = knexQueryMethod(), _dec21 = knexQueryMethod(), _dec22 = knexQueryMethod(), _dec23 = knexQueryMethod(), _dec24 = knexQueryMethod(), _dec25 = knexQueryMethod(), _dec26 = knexQueryMethod(), _dec27 = knexQueryMethod(), _dec28 = knexQueryMethod(), _dec29 = knexQueryMethod(), _dec30 = knexQueryMethod(), _dec31 = knexQueryMethod(), _dec32 = knexQueryMethod(), _dec33 = knexQueryMethod(), _dec34 = knexQueryMethod(), _dec35 = knexQueryMethod(), _dec36 = knexQueryMethod(), _dec37 = knexQueryMethod(), _dec38 = knexQueryMethod(), _dec39 = knexQueryMethod(), _dec40 = knexQueryMethod(), _dec41 = knexQueryMethod(), _dec42 = knexQueryMethod(), _dec43 = knexQueryMethod(), _dec44 = knexQueryMethod(), _dec45 = knexQueryMethod(), _dec46 = knexQueryMethod(), _dec47 = knexQueryMethod(), _dec48 = knexQueryMethod(), _dec49 = knexQueryMethod(), _dec50 = knexQueryMethod(), _dec51 = knexQueryMethod(), _dec52 = knexQueryMethod(), _dec53 = knexQueryMethod(), _dec54 = knexQueryMethod(), _dec55 = knexQueryMethod(), _dec56 = knexQueryMethod(), _dec57 = knexQueryMethod(), _dec58 = knexQueryMethod(), _dec59 = knexQueryMethod(), _dec60 = knexQueryMethod(), _dec61 = knexQueryMethod(), _dec62 = knexQueryMethod(), _dec63 = knexQueryMethod(), _dec64 = knexQueryMethod(), _dec65 = knexQueryMethod(), _dec66 = knexQueryMethod(), _dec67 = knexQueryMethod(), _dec68 = knexQueryMethod(), _dec69 = knexQueryMethod(), _dec70 = knexQueryMethod(), _dec71 = knexQueryMethod(), _dec72 = knexQueryMethod(), _dec73 = knexQueryMethod(), _dec74 = knexQueryMethod(), _dec75 = knexQueryMethod(), _dec76 = (0, _dbUtils.overwriteForDatabase)({ | ||
sqlite3: 'whereInComposite_sqlite3' | ||
}), _dec(_class = (_class2 = function () { | ||
function QueryBuilderBase(knex) { | ||
var QueryBuilderBase = (_dec = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec2 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec3 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec4 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default, 'delete'), _dec5 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec6 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec7 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec8 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec9 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec10 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec11 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec12 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec13 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec14 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec15 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec16 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec17 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec18 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec19 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec20 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec21 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec22 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec23 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec24 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec25 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec26 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec27 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec28 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec29 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec30 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec31 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec32 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec33 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec34 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec35 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec36 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec37 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec38 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec39 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec40 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec41 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec42 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec43 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec44 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec45 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec46 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec47 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec48 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec49 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec50 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec51 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec52 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec53 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec54 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec55 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec56 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec57 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec58 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec59 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec60 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec61 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec62 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec63 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec64 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec65 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec66 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec67 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec68 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec69 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec70 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec71 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec72 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec73 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec74 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec75 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec76 = (0, _queryBuilderOperation2.default)(_KnexOperation2.default), _dec77 = (0, _queryBuilderOperation2.default)([_KnexOperation2.default, { acceptUndefinedArgs: true }]), _dec78 = (0, _queryBuilderOperation2.default)([_WhereRefOperation2.default, { bool: 'and' }]), _dec79 = (0, _queryBuilderOperation2.default)([_WhereRefOperation2.default, { bool: 'or' }]), _dec80 = (0, _queryBuilderOperation2.default)(_WhereCompositeOperation2.default), _dec81 = (0, _queryBuilderOperation2.default)({ | ||
default: _WhereInCompositeOperation2.default, | ||
sqlite3: _WhereInCompositeSqliteOperation2.default | ||
}), _dec82 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '=', bool: 'and' }]), _dec83 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '=', bool: 'or' }]), _dec84 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '!=', bool: 'and' }]), _dec85 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '!=', bool: 'or' }]), _dec86 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '@>', bool: 'and' }]), _dec87 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '@>', bool: 'or' }]), _dec88 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '@>', bool: 'and', prefix: 'not' }]), _dec89 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '@>', bool: 'or', prefix: 'not' }]), _dec90 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '<@', bool: 'and' }]), _dec91 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '<@', bool: 'or' }]), _dec92 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '<@', bool: 'and', prefix: 'not' }]), _dec93 = (0, _queryBuilderOperation2.default)([_WhereJsonPostgresOperation2.default, { operator: '<@', bool: 'or', prefix: 'not' }]), _dec94 = (0, _queryBuilderOperation2.default)([_WhereJsonNotObjectPostgresOperation2.default, { bool: 'and', compareValue: [] }]), _dec95 = (0, _queryBuilderOperation2.default)([_WhereJsonNotObjectPostgresOperation2.default, { bool: 'or', compareValue: [] }]), _dec96 = (0, _queryBuilderOperation2.default)([_WhereJsonNotObjectPostgresOperation2.default, { bool: 'and', compareValue: {} }]), _dec97 = (0, _queryBuilderOperation2.default)([_WhereJsonNotObjectPostgresOperation2.default, { bool: 'or', compareValue: {} }]), _dec98 = (0, _queryBuilderOperation2.default)([_WhereJsonHasPostgresOperation2.default, { bool: 'and', operator: '?|' }]), _dec99 = (0, _queryBuilderOperation2.default)([_WhereJsonHasPostgresOperation2.default, { bool: 'or', operator: '?|' }]), _dec100 = (0, _queryBuilderOperation2.default)([_WhereJsonHasPostgresOperation2.default, { bool: 'and', operator: '?&' }]), _dec101 = (0, _queryBuilderOperation2.default)([_WhereJsonHasPostgresOperation2.default, { bool: 'or', operator: '?&' }]), _dec102 = (0, _queryBuilderOperation2.default)([_WhereJsonFieldPostgresOperation2.default, { bool: 'and' }]), _dec103 = (0, _queryBuilderOperation2.default)([_WhereJsonFieldPostgresOperation2.default, { bool: 'or' }]), (_class = function () { | ||
function QueryBuilderBase(knex, QueryBuilderContext) { | ||
(0, _classCallCheck3.default)(this, QueryBuilderBase); | ||
/** | ||
* @type {knex} | ||
* @protected | ||
*/ | ||
this._knex = knex; | ||
this._knexMethodCalls = []; | ||
this._context = { | ||
userContext: {} | ||
}; | ||
/** | ||
* @type {Array.<QueryBuilderOperation>} | ||
* @protected | ||
*/ | ||
this._operations = []; | ||
/** | ||
* @type {QueryBuilderContextBase} | ||
* @protected | ||
*/ | ||
this._context = new (QueryBuilderContext || _QueryBuilderContextBase2.default)(); | ||
} | ||
@@ -100,1436 +138,1010 @@ | ||
(0, _createClass3.default)(QueryBuilderBase, [{ | ||
key: 'context', | ||
/** | ||
* Sets/gets the query context. | ||
*/ | ||
value: function context() { | ||
if (arguments.length === 0) { | ||
return this._context.userContext; | ||
} else { | ||
this._context.userContext = arguments[0]; | ||
return this; | ||
} | ||
} | ||
QueryBuilderBase.extend = function extend(subclassConstructor) { | ||
(0, _classUtils.inherits)(subclassConstructor, this); | ||
return subclassConstructor; | ||
}; | ||
/** | ||
* Sets/gets the query's internal context. | ||
*/ | ||
/** | ||
* @param {Object=} ctx | ||
* @returns {Object|QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'internalContext', | ||
value: function internalContext() { | ||
if (arguments.length === 0) { | ||
return this._context; | ||
} else { | ||
this._context = arguments[0]; | ||
return this; | ||
} | ||
QueryBuilderBase.prototype.context = function context(ctx) { | ||
if (arguments.length === 0) { | ||
return this._context.userContext; | ||
} else { | ||
this._context.userContext = ctx; | ||
return this; | ||
} | ||
}; | ||
/** | ||
* @returns {knex} | ||
*/ | ||
/** | ||
* @param {QueryBuilderContextBase=} ctx | ||
* @returns {QueryBuilderContextBase|QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'knex', | ||
value: function knex() { | ||
return this._knex; | ||
QueryBuilderBase.prototype.internalContext = function internalContext(ctx) { | ||
if (arguments.length === 0) { | ||
return this._context; | ||
} else { | ||
this._context = ctx; | ||
return this; | ||
} | ||
}; | ||
/** | ||
* @param {function} func | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @param {knex=} knex | ||
* @returns {Object|QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'call', | ||
value: function call(func) { | ||
func.call(this, this); | ||
QueryBuilderBase.prototype.knex = function knex(_knex) { | ||
if (arguments.length === 0) { | ||
return this._knex; | ||
} else { | ||
this._knex = _knex; | ||
return this; | ||
} | ||
}; | ||
/** | ||
* @returns {string} | ||
*/ | ||
/** | ||
* @param {function} func | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'toString', | ||
value: function toString() { | ||
return this.build().toString(); | ||
} | ||
/** | ||
* @returns {string} | ||
*/ | ||
QueryBuilderBase.prototype.call = function call(func) { | ||
func.call(this, this); | ||
}, { | ||
key: 'toSql', | ||
value: function toSql() { | ||
return this.toString(); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @param {RegExp=} methodNameRegex | ||
*/ | ||
}, { | ||
key: 'clone', | ||
value: function clone() { | ||
var clone = new this.constructor(this._knex); | ||
this.cloneInto(clone); | ||
return clone; | ||
QueryBuilderBase.prototype.clear = function clear(methodNameRegex) { | ||
if (_lodash2.default.isRegExp(methodNameRegex)) { | ||
this._operations = _lodash2.default.reject(this._operations, function (method) { | ||
return methodNameRegex.test(method.name); | ||
}); | ||
} else { | ||
this._operations = []; | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: 'cloneInto', | ||
value: function cloneInto(builder) { | ||
builder._knex = this._knex; | ||
builder._knexMethodCalls = this._knexMethodCalls.slice(); | ||
builder._context = _lodash2.default.clone(this._context); | ||
} | ||
/** | ||
* @param {QueryBuilderBase} queryBuilder | ||
* @param {RegExp} methodNameRegex | ||
*/ | ||
/** | ||
* @param {RegExp=} methodNameRegex | ||
*/ | ||
}, { | ||
key: 'clear', | ||
value: function clear(methodNameRegex) { | ||
if (methodNameRegex) { | ||
// Reject all query method calls that don't pass the filter. | ||
this._knexMethodCalls = _lodash2.default.reject(this._knexMethodCalls, function (call) { | ||
return methodNameRegex.test(call.method); | ||
}); | ||
} else { | ||
// If no arguments are given, clear all query method calls. | ||
this._knexMethodCalls = []; | ||
QueryBuilderBase.prototype.copyFrom = function copyFrom(queryBuilder, methodNameRegex) { | ||
var _this = this; | ||
_lodash2.default.each(queryBuilder._operations, function (method) { | ||
if (!methodNameRegex || methodNameRegex.test(method.name)) { | ||
_this._operations.push(method); | ||
} | ||
}); | ||
return this; | ||
} | ||
return this; | ||
}; | ||
/** | ||
* @param {QueryBuilderBase} queryBuilder | ||
* @param {RegExp} methodNameRegex | ||
*/ | ||
/** | ||
* @param {RegExp} methodNameRegex | ||
* @returns {boolean} | ||
*/ | ||
}, { | ||
key: 'copyFrom', | ||
value: function copyFrom(queryBuilder, methodNameRegex) { | ||
var self = this; | ||
_lodash2.default.forEach(queryBuilder._knexMethodCalls, function (call) { | ||
if (!methodNameRegex || methodNameRegex.test(call.method)) { | ||
self._knexMethodCalls.push(call); | ||
} | ||
}); | ||
QueryBuilderBase.prototype.has = function has(methodNameRegex) { | ||
return _lodash2.default.some(this._operations, function (method) { | ||
return methodNameRegex.test(method.name); | ||
}); | ||
}; | ||
return this; | ||
} | ||
/** | ||
* @param {QueryBuilderOperation} method | ||
* @param {Array.<*>} args | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @param {RegExp} methodNameRegex | ||
* @returns {boolean} | ||
*/ | ||
}, { | ||
key: 'has', | ||
value: function has(methodNameRegex) { | ||
return _lodash2.default.any(this._knexMethodCalls, function (call) { | ||
return methodNameRegex.test(call.method); | ||
}); | ||
QueryBuilderBase.prototype.callQueryBuilderOperation = function callQueryBuilderOperation(method, args) { | ||
if (method.call(this, args || [])) { | ||
this._operations.push(method); | ||
} | ||
/** | ||
* @protected | ||
* @returns {knex.QueryBuilder} | ||
*/ | ||
return this; | ||
}; | ||
}, { | ||
key: 'build', | ||
value: function build() { | ||
return this.buildInto(this._knex.queryBuilder()); | ||
} | ||
/** | ||
* @param {string} methodName | ||
* @param {Array.<*>} args | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: 'buildInto', | ||
value: function buildInto(knexBuilder) { | ||
_lodash2.default.forEach(this._knexMethodCalls, function (call) { | ||
if (_lodash2.default.isFunction(knexBuilder[call.method])) { | ||
knexBuilder[call.method].apply(knexBuilder, call.args); | ||
} | ||
}); | ||
QueryBuilderBase.prototype.callKnexQueryBuilderOperation = function callKnexQueryBuilderOperation(methodName, args) { | ||
return this.callQueryBuilderOperation(new _KnexOperation2.default(this, methodName), args); | ||
}; | ||
return knexBuilder; | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: 'callKnexMethod', | ||
value: function callKnexMethod(methodName, args) { | ||
for (var i = 0, l = args.length; i < l; ++i) { | ||
if (_lodash2.default.isUndefined(args[i])) { | ||
// None of the query builder methods should accept undefined. Do nothing if | ||
// one of the arguments is undefined. This enables us to do things like | ||
// `.where('name', req.query.name)` without checking if req.query has the | ||
// property `name`. | ||
return this; | ||
} else if (args[i] instanceof QueryBuilderBase) { | ||
// Convert QueryBuilderBase instances into knex query builders. | ||
args[i] = args[i].build(); | ||
} else if (_lodash2.default.isFunction(args[i])) { | ||
// If an argument is a function, knex calls it with a query builder as | ||
// `this` context. We call the function with a QueryBuilderBase as | ||
// `this` context instead. | ||
args[i] = wrapFunctionArg(args[i], this); | ||
} | ||
} | ||
QueryBuilderBase.prototype.clone = function clone() { | ||
return this.baseCloneInto(new this.constructor(this._knex)); | ||
}; | ||
this._knexMethodCalls.push({ | ||
method: methodName, | ||
args: args | ||
}); | ||
/** | ||
* @protected | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.baseCloneInto = function baseCloneInto(builder) { | ||
builder._knex = this._knex; | ||
builder._operations = this._operations.slice(); | ||
builder._context = this._context.clone(); | ||
}, { | ||
key: 'insert', | ||
value: function insert() {} | ||
return builder; | ||
}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {knex.QueryBuilder} | ||
*/ | ||
}, { | ||
key: 'update', | ||
value: function update() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.build = function build() { | ||
return this.buildInto(this._knex.queryBuilder()); | ||
}; | ||
}, { | ||
key: 'delete', | ||
value: function _delete() {} | ||
/** | ||
* @protected | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'del', | ||
value: function del() {} | ||
QueryBuilderBase.prototype.buildInto = function buildInto(knexBuilder) { | ||
var _this2 = this; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
_lodash2.default.each(this._operations, function (method) { | ||
return method.onBeforeBuild(_this2); | ||
}); | ||
_lodash2.default.each(this._operations, function (method) { | ||
return method.onBuild(knexBuilder, _this2); | ||
}); | ||
}, { | ||
key: 'select', | ||
value: function select() {} | ||
return knexBuilder; | ||
}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {string} | ||
*/ | ||
}, { | ||
key: 'forUpdate', | ||
value: function forUpdate() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.toString = function toString() { | ||
return this.build().toString(); | ||
}; | ||
}, { | ||
key: 'forShare', | ||
value: function forShare() {} | ||
/** | ||
* @returns {string} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'as', | ||
value: function as() {} | ||
QueryBuilderBase.prototype.toSql = function toSql() { | ||
return this.toString(); | ||
}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'columns', | ||
value: function columns() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.insert = function insert() {}; | ||
}, { | ||
key: 'column', | ||
value: function column() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'from', | ||
value: function from() {} | ||
QueryBuilderBase.prototype.update = function update() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'fromJS', | ||
value: function fromJS() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.delete = function _delete() {}; | ||
}, { | ||
key: 'into', | ||
value: function into() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'withSchema', | ||
value: function withSchema() {} | ||
QueryBuilderBase.prototype.del = function del() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'table', | ||
value: function table() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.select = function select() {}; | ||
}, { | ||
key: 'distinct', | ||
value: function distinct() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'join', | ||
value: function join() {} | ||
QueryBuilderBase.prototype.forUpdate = function forUpdate() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'joinRaw', | ||
value: function joinRaw() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.forShare = function forShare() {}; | ||
}, { | ||
key: 'innerJoin', | ||
value: function innerJoin() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'leftJoin', | ||
value: function leftJoin() {} | ||
QueryBuilderBase.prototype.as = function as() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'leftOuterJoin', | ||
value: function leftOuterJoin() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.columns = function columns() {}; | ||
}, { | ||
key: 'rightJoin', | ||
value: function rightJoin() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'rightOuterJoin', | ||
value: function rightOuterJoin() {} | ||
QueryBuilderBase.prototype.column = function column() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'outerJoin', | ||
value: function outerJoin() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.from = function from() {}; | ||
}, { | ||
key: 'fullOuterJoin', | ||
value: function fullOuterJoin() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'crossJoin', | ||
value: function crossJoin() {} | ||
QueryBuilderBase.prototype.fromJS = function fromJS() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'where', | ||
value: function where() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.into = function into() {}; | ||
}, { | ||
key: 'andWhere', | ||
value: function andWhere() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhere', | ||
value: function orWhere() {} | ||
QueryBuilderBase.prototype.withSchema = function withSchema() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereNot', | ||
value: function whereNot() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.table = function table() {}; | ||
}, { | ||
key: 'orWhereNot', | ||
value: function orWhereNot() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereRaw', | ||
value: function whereRaw() {} | ||
QueryBuilderBase.prototype.distinct = function distinct() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereWrapped', | ||
value: function whereWrapped() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.join = function join() {}; | ||
}, { | ||
key: 'havingWrapped', | ||
value: function havingWrapped() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereRaw', | ||
value: function orWhereRaw() {} | ||
QueryBuilderBase.prototype.joinRaw = function joinRaw() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereExists', | ||
value: function whereExists() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.innerJoin = function innerJoin() {}; | ||
}, { | ||
key: 'orWhereExists', | ||
value: function orWhereExists() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereNotExists', | ||
value: function whereNotExists() {} | ||
QueryBuilderBase.prototype.leftJoin = function leftJoin() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereNotExists', | ||
value: function orWhereNotExists() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.leftOuterJoin = function leftOuterJoin() {}; | ||
}, { | ||
key: 'whereIn', | ||
value: function whereIn() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereIn', | ||
value: function orWhereIn() {} | ||
QueryBuilderBase.prototype.rightJoin = function rightJoin() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereNotIn', | ||
value: function whereNotIn() {} | ||
/** | ||
*/ | ||
QueryBuilderBase.prototype.rightOuterJoin = function rightOuterJoin() {}; | ||
}, { | ||
key: 'orWhereNotIn', | ||
value: function orWhereNotIn() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereNull', | ||
value: function whereNull() {} | ||
QueryBuilderBase.prototype.outerJoin = function outerJoin() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereNull', | ||
value: function orWhereNull() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.fullOuterJoin = function fullOuterJoin() {}; | ||
}, { | ||
key: 'whereNotNull', | ||
value: function whereNotNull() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereNotNull', | ||
value: function orWhereNotNull() {} | ||
QueryBuilderBase.prototype.crossJoin = function crossJoin() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereBetween', | ||
value: function whereBetween() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.where = function where() {}; | ||
}, { | ||
key: 'whereNotBetween', | ||
value: function whereNotBetween() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereBetween', | ||
value: function orWhereBetween() {} | ||
QueryBuilderBase.prototype.andWhere = function andWhere() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereNotBetween', | ||
value: function orWhereNotBetween() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhere = function orWhere() {}; | ||
}, { | ||
key: 'groupBy', | ||
value: function groupBy() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'groupByRaw', | ||
value: function groupByRaw() {} | ||
QueryBuilderBase.prototype.whereNot = function whereNot() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orderBy', | ||
value: function orderBy() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereNot = function orWhereNot() {}; | ||
}, { | ||
key: 'orderByRaw', | ||
value: function orderByRaw() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'union', | ||
value: function union() {} | ||
QueryBuilderBase.prototype.whereRaw = function whereRaw() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'unionAll', | ||
value: function unionAll() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereWrapped = function whereWrapped() {}; | ||
}, { | ||
key: 'having', | ||
value: function having() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'havingRaw', | ||
value: function havingRaw() {} | ||
QueryBuilderBase.prototype.havingWrapped = function havingWrapped() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orHaving', | ||
value: function orHaving() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereRaw = function orWhereRaw() {}; | ||
}, { | ||
key: 'orHavingRaw', | ||
value: function orHavingRaw() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'offset', | ||
value: function offset() {} | ||
QueryBuilderBase.prototype.whereExists = function whereExists() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'limit', | ||
value: function limit() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereExists = function orWhereExists() {}; | ||
}, { | ||
key: 'count', | ||
value: function count() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'countDistinct', | ||
value: function countDistinct() {} | ||
QueryBuilderBase.prototype.whereNotExists = function whereNotExists() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'min', | ||
value: function min() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereNotExists = function orWhereNotExists() {}; | ||
}, { | ||
key: 'max', | ||
value: function max() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'sum', | ||
value: function sum() {} | ||
QueryBuilderBase.prototype.whereIn = function whereIn() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'avg', | ||
value: function avg() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereIn = function orWhereIn() {}; | ||
}, { | ||
key: 'avgDistinct', | ||
value: function avgDistinct() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'debug', | ||
value: function debug() {} | ||
QueryBuilderBase.prototype.whereNotIn = function whereNotIn() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
*/ | ||
}, { | ||
key: 'returning', | ||
value: function returning() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereNotIn = function orWhereNotIn() {}; | ||
}, { | ||
key: 'truncate', | ||
value: function truncate() {} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'connection', | ||
value: function connection() {} | ||
QueryBuilderBase.prototype.whereNull = function whereNull() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereRef', | ||
value: function whereRef(lhs, op, rhs) { | ||
return this._whereRef('and', lhs, op, rhs); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereNull = function orWhereNull() {}; | ||
}, { | ||
key: 'orWhereRef', | ||
value: function orWhereRef(lhs, op, rhs) { | ||
return this._whereRef('or', lhs, op, rhs); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereComposite', | ||
value: function whereComposite(cols, op, values) { | ||
var _this = this; | ||
QueryBuilderBase.prototype.whereNotNull = function whereNotNull() {}; | ||
if (_lodash2.default.isUndefined(values)) { | ||
values = op; | ||
op = '='; | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
var colsIsArray = _lodash2.default.isArray(cols); | ||
var valuesIsArray = _lodash2.default.isArray(values); | ||
if (!colsIsArray && !valuesIsArray) { | ||
return this.where(cols, op, values); | ||
} else if (colsIsArray && cols.length === 1 && !valuesIsArray) { | ||
return this.where(cols[0], op, values); | ||
} else if (colsIsArray && valuesIsArray && cols.length === values.length) { | ||
_lodash2.default.each(cols, function (col, idx) { | ||
return _this.where(col, op, values[idx]); | ||
}); | ||
return this; | ||
} else { | ||
throw new Error('both cols and values must have same dimensions'); | ||
} | ||
} | ||
QueryBuilderBase.prototype.orWhereNotNull = function orWhereNotNull() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereInComposite', | ||
value: function whereInComposite(columns, values) { | ||
var _this2 = this; | ||
var isCompositeKey = _lodash2.default.isArray(columns) && columns.length > 1; | ||
QueryBuilderBase.prototype.whereBetween = function whereBetween() {}; | ||
if (isCompositeKey) { | ||
if (_lodash2.default.isArray(values)) { | ||
return this.whereIn(columns, values); | ||
} else { | ||
var _ret = function () { | ||
// Because of a bug in knex, we need to build the where-in query from pieces | ||
// if the value is a subquery. | ||
var formatter = _this2._knex.client.formatter(); | ||
var sql = '(' + _lodash2.default.map(columns, function (col) { | ||
return formatter.wrap(col); | ||
}).join() + ')'; | ||
return { | ||
v: _this2.whereIn(_this2._knex.raw(sql), values) | ||
}; | ||
}(); | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
if ((typeof _ret === 'undefined' ? 'undefined' : (0, _typeof3.default)(_ret)) === "object") return _ret.v; | ||
} | ||
} else { | ||
var col = _lodash2.default.isString(columns) ? columns : columns[0]; | ||
if (_lodash2.default.isArray(values)) { | ||
values = _lodash2.default.compact(_lodash2.default.flatten(values)); | ||
} | ||
QueryBuilderBase.prototype.whereNotBetween = function whereNotBetween() {}; | ||
// For non-composite keys we can use the normal whereIn. | ||
return this.whereIn(col, values); | ||
} | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: 'whereInComposite_sqlite3', | ||
value: function whereInComposite_sqlite3(columns, values) { | ||
var isCompositeKey = _lodash2.default.isArray(columns) && columns.length > 1; | ||
QueryBuilderBase.prototype.orWhereBetween = function orWhereBetween() {}; | ||
if (isCompositeKey) { | ||
if (!_lodash2.default.isArray(values)) { | ||
// If the `values` is not an array of values but a function or a subquery | ||
// we have no way to implement this method. | ||
throw new Error('sqlite doesn\'t support multi-column where in clauses'); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
// Sqlite doesn't support the `where in` syntax for multiple columns but | ||
// we can emulate it using grouped `or` clauses. | ||
return this.where(function (builder) { | ||
_lodash2.default.each(values, function (val) { | ||
builder.orWhere(function (builder) { | ||
_lodash2.default.each(columns, function (col, idx) { | ||
builder.andWhere(col, val[idx]); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} else { | ||
var col = _lodash2.default.isString(columns) ? columns : columns[0]; | ||
if (_lodash2.default.isArray(values)) { | ||
values = _lodash2.default.compact(_lodash2.default.flatten(values)); | ||
} | ||
QueryBuilderBase.prototype.orWhereNotBetween = function orWhereNotBetween() {}; | ||
// For non-composite keys we can use the normal whereIn. | ||
return this.whereIn(col, values); | ||
} | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* Json query APIs | ||
*/ | ||
/** | ||
* @typedef {String} FieldExpression | ||
* | ||
* Field expressions allow one to refer to separate JSONB fields inside columns. | ||
* | ||
* Syntax: <column reference>[:<json field reference>] | ||
* | ||
* e.g. `Person.jsonColumnName:details.names[1]` would refer to value `'Second'` | ||
* in column `Person.jsonColumnName` which has | ||
* `{ details: { names: ['First', 'Second', 'Last'] } }` object stored in it. | ||
* | ||
* First part `<column reference>` is compatible with column references used in | ||
* knex e.g. `MyFancyTable.tributeToThBestColumnNameEver`. | ||
* | ||
* Second part describes a path to an attribute inside the referred column. | ||
* It is optional and it always starts with colon which follows directly with | ||
* first path element. e.g. `Table.jsonObjectColumnName:jsonFieldName` or | ||
* `Table.jsonArrayColumn:[321]`. | ||
* | ||
* Syntax supports `[<key or index>]` and `.<key or index>` flavors of reference | ||
* to json keys / array indexes: | ||
* | ||
* e.g. both `Table.myColumn:[1][3]` and `Table.myColumn:1.3` would access correctly | ||
* both of the following objects `[null, [null,null,null, "I was accessed"]]` and | ||
* `{ "1": { "3" : "I was accessed" } }` | ||
* | ||
* Caveats when using special characters in keys: | ||
* | ||
* 1. `objectColumn.key` This is the most common syntax, good if you are | ||
* not using dots or square brackets `[]` in your json object key name. | ||
* 2. Keys containing dots `objectColumn:[keywith.dots]` Column `{ "keywith.dots" : "I was referred" }` | ||
* 3. Keys containing square brackets `column['[]']` `{ "[]" : "This is getting ridiculous..." }` | ||
* 4. Keys containing square brackets and quotes | ||
* `objectColumn:['Double."Quote".[]']` and `objectColumn:["Sinlge.'Quote'.[]"]` | ||
* Column `{ "Double.\"Quote\".[]" : "I was referred", "Sinlge.'Quote'.[]" : "Mee too!" }` | ||
* 99. Keys containing dots, square brackets, single quotes and double quotes in one json key is | ||
* not currently supported | ||
*/ | ||
QueryBuilderBase.prototype.groupBy = function groupBy() {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonEquals', | ||
value: function whereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "=", jsonObjectOrFieldExpression); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.groupByRaw = function groupByRaw() {}; | ||
}, { | ||
key: 'orWhereJsonEquals', | ||
value: function orWhereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "=", jsonObjectOrFieldExpression); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonNotEquals', | ||
value: function whereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "!=", jsonObjectOrFieldExpression); | ||
} | ||
QueryBuilderBase.prototype.orderBy = function orderBy() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonNotEquals', | ||
value: function orWhereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "!=", jsonObjectOrFieldExpression); | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orderByRaw = function orderByRaw() {}; | ||
}, { | ||
key: 'whereJsonSupersetOf', | ||
value: function whereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonSupersetOf', | ||
value: function orWhereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression); | ||
} | ||
QueryBuilderBase.prototype.union = function union() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonNotSupersetOf', | ||
value: function whereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.unionAll = function unionAll() {}; | ||
}, { | ||
key: 'orWhereJsonNotSupersetOf', | ||
value: function orWhereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonSubsetOf', | ||
value: function whereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression); | ||
} | ||
QueryBuilderBase.prototype.having = function having() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonSubsetOf', | ||
value: function orWhereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.havingRaw = function havingRaw() {}; | ||
}, { | ||
key: 'whereJsonNotSubsetOf', | ||
value: function whereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonNotSubsetOf', | ||
value: function orWhereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
QueryBuilderBase.prototype.orHaving = function orHaving() {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonIsArray', | ||
value: function whereJsonIsArray(fieldExpression) { | ||
return this.whereJsonSupersetOf(fieldExpression, []); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orHavingRaw = function orHavingRaw() {}; | ||
}, { | ||
key: 'orWhereJsonIsArray', | ||
value: function orWhereJsonIsArray(fieldExpression) { | ||
return this.orWhereJsonSupersetOf(fieldExpression, []); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonNotArray', | ||
value: function whereJsonNotArray(fieldExpression) { | ||
var knex = this._knex; | ||
// uhh... ugly. own subquery builder could help... now this refers to plain knex subquery builder | ||
return this.where(function () { | ||
// not array | ||
var builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", [], 'not'); | ||
var ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
} | ||
QueryBuilderBase.prototype.offset = function offset() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonNotArray', | ||
value: function orWhereJsonNotArray(fieldExpression) { | ||
var knex = this._knex; | ||
return this.orWhere(function () { | ||
// not array | ||
var builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", [], 'not'); | ||
var ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.limit = function limit() {}; | ||
}, { | ||
key: 'whereJsonIsObject', | ||
value: function whereJsonIsObject(fieldExpression) { | ||
return this.whereJsonSupersetOf(fieldExpression, {}); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonIsObject', | ||
value: function orWhereJsonIsObject(fieldExpression) { | ||
return this.orWhereJsonSupersetOf(fieldExpression, {}); | ||
} | ||
QueryBuilderBase.prototype.count = function count() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonNotObject', | ||
value: function whereJsonNotObject(fieldExpression) { | ||
var knex = this._knex; | ||
return this.where(function () { | ||
// not object | ||
var builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", {}, 'not'); | ||
var ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.countDistinct = function countDistinct() {}; | ||
}, { | ||
key: 'orWhereJsonNotObject', | ||
value: function orWhereJsonNotObject(fieldExpression) { | ||
var knex = this._knex; | ||
return this.orWhere(function () { | ||
// not object | ||
var builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", {}, 'not'); | ||
var ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonHasAny', | ||
value: function whereJsonHasAny(fieldExpression, keys) { | ||
return whereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?|', keys); | ||
} | ||
QueryBuilderBase.prototype.min = function min() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonHasAny', | ||
value: function orWhereJsonHasAny(fieldExpression, keys) { | ||
return orWhereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?|', keys); | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.max = function max() {}; | ||
}, { | ||
key: 'whereJsonHasAll', | ||
value: function whereJsonHasAll(fieldExpression, keys) { | ||
return whereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?&', keys); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'orWhereJsonHasAll', | ||
value: function orWhereJsonHasAll(fieldExpression, keys) { | ||
return orWhereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?&', keys); | ||
} | ||
QueryBuilderBase.prototype.sum = function sum() {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string} operator | ||
* @param {boolean|Number|string|null} value | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
}, { | ||
key: 'whereJsonField', | ||
value: function whereJsonField(fieldExpression, operator, value) { | ||
var query = whereJsonFieldQuery(this._knex, fieldExpression, operator, value); | ||
return this.whereRaw(query); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.avg = function avg() {}; | ||
}, { | ||
key: 'orWhereJsonField', | ||
value: function orWhereJsonField(fieldExpression, operator, value) { | ||
var query = whereJsonFieldQuery(this._knex, fieldExpression, operator, value); | ||
return this.orWhereRaw(query); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
}, { | ||
key: '_whereRef', | ||
value: function _whereRef(bool, lhs, op, rhs) { | ||
if (!rhs) { | ||
rhs = op; | ||
op = '='; | ||
} | ||
QueryBuilderBase.prototype.avgDistinct = function avgDistinct() {}; | ||
var formatter = this._knex.client.formatter(); | ||
op = formatter.operator(op); | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
if (!_lodash2.default.isString(lhs) || !_lodash2.default.isString(rhs) || !_lodash2.default.isString(op)) { | ||
throw new Error('whereRef: invalid operands or operator'); | ||
} | ||
var sql = formatter.wrap(lhs) + ' ' + op + ' ' + formatter.wrap(rhs); | ||
if (bool === 'or') { | ||
return this.orWhereRaw(sql); | ||
} else { | ||
return this.whereRaw(sql); | ||
} | ||
} | ||
}], [{ | ||
key: 'extend', | ||
value: function extend(subclassConstructor) { | ||
(0, _classUtils.inherits)(subclassConstructor, this); | ||
return subclassConstructor; | ||
} | ||
}]); | ||
return QueryBuilderBase; | ||
}(), (_applyDecoratedDescriptor(_class2.prototype, 'insert', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'insert'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'update', [_dec3], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'update'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'delete', [_dec4], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'delete'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'del', [_dec5], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'del'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'select', [_dec6], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'select'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'forUpdate', [_dec7], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'forUpdate'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'forShare', [_dec8], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'forShare'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'as', [_dec9], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'as'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'columns', [_dec10], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'columns'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'column', [_dec11], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'column'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'from', [_dec12], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'from'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'fromJS', [_dec13], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'fromJS'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'into', [_dec14], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'into'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'withSchema', [_dec15], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'withSchema'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'table', [_dec16], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'table'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'distinct', [_dec17], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'distinct'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'join', [_dec18], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'join'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'joinRaw', [_dec19], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'joinRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'innerJoin', [_dec20], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'innerJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'leftJoin', [_dec21], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'leftJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'leftOuterJoin', [_dec22], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'leftOuterJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'rightJoin', [_dec23], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'rightJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'rightOuterJoin', [_dec24], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'rightOuterJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'outerJoin', [_dec25], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'outerJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'fullOuterJoin', [_dec26], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'fullOuterJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'crossJoin', [_dec27], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'crossJoin'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'where', [_dec28], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'where'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'andWhere', [_dec29], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'andWhere'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhere', [_dec30], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhere'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereNot', [_dec31], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereNot'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereNot', [_dec32], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereNot'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereRaw', [_dec33], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereWrapped', [_dec34], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereWrapped'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'havingWrapped', [_dec35], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'havingWrapped'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereRaw', [_dec36], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereExists', [_dec37], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereExists'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereExists', [_dec38], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereExists'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereNotExists', [_dec39], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereNotExists'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereNotExists', [_dec40], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereNotExists'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereIn', [_dec41], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereIn'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereIn', [_dec42], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereIn'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereNotIn', [_dec43], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereNotIn'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereNotIn', [_dec44], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereNotIn'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereNull', [_dec45], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereNull'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereNull', [_dec46], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereNull'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereNotNull', [_dec47], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereNotNull'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereNotNull', [_dec48], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereNotNull'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereBetween', [_dec49], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereBetween'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereNotBetween', [_dec50], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereNotBetween'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereBetween', [_dec51], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereBetween'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orWhereNotBetween', [_dec52], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orWhereNotBetween'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'groupBy', [_dec53], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'groupBy'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'groupByRaw', [_dec54], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'groupByRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orderBy', [_dec55], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orderBy'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orderByRaw', [_dec56], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orderByRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'union', [_dec57], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'union'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'unionAll', [_dec58], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'unionAll'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'having', [_dec59], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'having'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'havingRaw', [_dec60], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'havingRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orHaving', [_dec61], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orHaving'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'orHavingRaw', [_dec62], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'orHavingRaw'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'offset', [_dec63], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'offset'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'limit', [_dec64], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'limit'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'count', [_dec65], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'count'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'countDistinct', [_dec66], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'countDistinct'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'min', [_dec67], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'min'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'max', [_dec68], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'max'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'sum', [_dec69], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'sum'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'avg', [_dec70], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'avg'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'avgDistinct', [_dec71], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'avgDistinct'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'debug', [_dec72], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'debug'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'returning', [_dec73], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'returning'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'truncate', [_dec74], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'truncate'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'connection', [_dec75], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'connection'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'whereInComposite', [_dec76], (0, _getOwnPropertyDescriptor2.default)(_class2.prototype, 'whereInComposite'), _class2.prototype)), _class2)) || _class); | ||
exports.default = QueryBuilderBase; | ||
QueryBuilderBase.prototype.debug = function debug() {}; | ||
function knexQueryMethod(overrideMethodName) { | ||
return function (target, methodName, descriptor) { | ||
descriptor.value = function () { | ||
return this.callKnexMethod(overrideMethodName || methodName, _lodash2.default.toArray(arguments)); | ||
}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.returning = function returning() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.truncate = function truncate() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.connection = function connection() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.options = function options() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.columnInfo = function columnInfo() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.modify = function modify() {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereRef = function whereRef(lhs, op, rhs) {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereRef = function orWhereRef(lhs, op, rhs) {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereComposite = function whereComposite(cols, op, values) {}; | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereInComposite = function whereInComposite(columns, values) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonEquals = function whereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonEquals = function orWhereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonNotEquals = function whereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonNotEquals = function orWhereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonSupersetOf = function whereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonSupersetOf = function orWhereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonNotSupersetOf = function whereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonNotSupersetOf = function orWhereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonSubsetOf = function whereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonSubsetOf = function orWhereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonNotSubsetOf = function whereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonNotSubsetOf = function orWhereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonIsArray = function whereJsonIsArray(fieldExpression) { | ||
return this.whereJsonSupersetOf(fieldExpression, []); | ||
}; | ||
} | ||
function wrapFunctionArg(func, query) { | ||
return function () { | ||
if ((0, _dbUtils.isKnexQueryBuilder)(this)) { | ||
var builder = new QueryBuilderBase(query._knex); | ||
func.call(builder, builder); | ||
builder.buildInto(this); | ||
} else { | ||
return func.apply(this, arguments); | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonIsArray = function orWhereJsonIsArray(fieldExpression) { | ||
return this.orWhereJsonSupersetOf(fieldExpression, []); | ||
}; | ||
} | ||
function parseFieldExpression(expression, extractAsText) { | ||
var parsed = _jsonFieldExpressionParser2.default.parse(expression); | ||
var jsonRefs = (0, _lodash2.default)(parsed.access).pluck('ref').value().join(","); | ||
var extractor = extractAsText ? '#>>' : '#>'; | ||
var middleQuotedColumnName = parsed.columnName.split('.').join('"."'); | ||
return '"' + middleQuotedColumnName + '"' + extractor + '\'{' + jsonRefs + '}\''; | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
function whereJsonbRefOnLeftJsonbValOrRefOnRight(builder, fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { | ||
var queryParams = whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix); | ||
return builder.whereRaw.apply(builder, queryParams); | ||
} | ||
function orWhereJsonbRefOnLeftJsonbValOrRefOnRight(builder, fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { | ||
var queryParams = whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix); | ||
return builder.orWhereRaw.apply(builder, queryParams); | ||
} | ||
QueryBuilderBase.prototype.whereJsonIsObject = function whereJsonIsObject(fieldExpression) { | ||
return this.whereJsonSupersetOf(fieldExpression, {}); | ||
}; | ||
function whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { | ||
var fieldReference = parseFieldExpression(fieldExpression); | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
if (_lodash2.default.isString(jsonObjectOrFieldExpression)) { | ||
var rightHandReference = parseFieldExpression(jsonObjectOrFieldExpression); | ||
var refRefQuery = ["(", fieldReference, ")::jsonb", operator, "(", rightHandReference, ")::jsonb"]; | ||
if (queryPrefix) { | ||
refRefQuery.unshift(queryPrefix); | ||
} | ||
return [refRefQuery.join(" ")]; | ||
} else if (_lodash2.default.isObject(jsonObjectOrFieldExpression)) { | ||
var refValQuery = ["(", fieldReference, ")::jsonb", operator, "?::jsonb"]; | ||
if (queryPrefix) { | ||
refValQuery.unshift(queryPrefix); | ||
} | ||
return [refValQuery.join(" "), (0, _stringify2.default)(jsonObjectOrFieldExpression)]; | ||
} | ||
throw new Error("Invalid right hand expression."); | ||
} | ||
QueryBuilderBase.prototype.orWhereJsonIsObject = function orWhereJsonIsObject(fieldExpression) { | ||
return this.orWhereJsonSupersetOf(fieldExpression, {}); | ||
}; | ||
function whereJsonFieldRightStringArrayOnLeft(builder, fieldExpression, operator, keys) { | ||
return builder.whereRaw(whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys)); | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
function orWhereJsonFieldRightStringArrayOnLeft(builder, fieldExpression, operator, keys) { | ||
return builder.orWhereRaw(whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys)); | ||
} | ||
function whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys) { | ||
var knex = builder._knex; | ||
var fieldReference = parseFieldExpression(fieldExpression); | ||
keys = _lodash2.default.isArray(keys) ? keys : [keys]; | ||
QueryBuilderBase.prototype.whereJsonNotArray = function whereJsonNotArray(fieldExpression) {}; | ||
var questionMarksArray = _lodash2.default.map(keys, function (key) { | ||
if (!_lodash2.default.isString(key)) { | ||
throw new Error("All keys to find must be strings."); | ||
} | ||
return "?"; | ||
}); | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
var rawSqlTemplateString = "array[" + questionMarksArray.join(",") + "]"; | ||
var rightHandExpression = knex.raw(rawSqlTemplateString, keys); | ||
return fieldReference + ' ' + operator.replace('?', '\\?') + ' ' + rightHandExpression; | ||
} | ||
QueryBuilderBase.prototype.orWhereJsonNotArray = function orWhereJsonNotArray(fieldExpression) {}; | ||
function whereJsonFieldQuery(knex, fieldExpression, operator, value) { | ||
var fieldReference = parseFieldExpression(fieldExpression, true); | ||
var normalizedOperator = normalizeOperator(knex, operator); | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
// json type comparison takes json type in string format | ||
var cast = undefined; | ||
var escapedValue = knex.raw(" ?", [value]); | ||
if (_lodash2.default.isNumber(value)) { | ||
cast = "::NUMERIC"; | ||
} else if (_lodash2.default.isBoolean(value)) { | ||
cast = "::BOOLEAN"; | ||
} else if (_lodash2.default.isString(value)) { | ||
cast = "::TEXT"; | ||
} else if (_lodash2.default.isNull(value)) { | ||
cast = "::TEXT"; | ||
escapedValue = 'NULL'; | ||
} else { | ||
throw new Error("Value must be string, number, boolean or null."); | ||
} | ||
return '(' + fieldReference + ')' + cast + ' ' + normalizedOperator + ' ' + escapedValue; | ||
} | ||
QueryBuilderBase.prototype.whereJsonNotObject = function whereJsonNotObject(fieldExpression) {}; | ||
function normalizeOperator(knex, operator) { | ||
var trimmedLowerCase = operator.trim().toLowerCase(); | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
switch (trimmedLowerCase) { | ||
case "is": | ||
case "is not": | ||
return trimmedLowerCase; | ||
default: | ||
return knex.client.formatter().operator(operator); | ||
} | ||
} | ||
QueryBuilderBase.prototype.orWhereJsonNotObject = function orWhereJsonNotObject(fieldExpression) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonHasAny = function whereJsonHasAny(fieldExpression, keys) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonHasAny = function orWhereJsonHasAny(fieldExpression, keys) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonHasAll = function whereJsonHasAll(fieldExpression, keys) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonHasAll = function orWhereJsonHasAll(fieldExpression, keys) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string} operator | ||
* @param {boolean|Number|string|null} value | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.whereJsonField = function whereJsonField(fieldExpression, operator, value) {}; | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string} operator | ||
* @param {boolean|Number|string|null} value | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
QueryBuilderBase.prototype.orWhereJsonField = function orWhereJsonField(fieldExpression, operator, value) {}; | ||
return QueryBuilderBase; | ||
}(), (_applyDecoratedDescriptor(_class.prototype, 'insert', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'insert'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'update', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'update'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'delete', [_dec3], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'delete'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'del', [_dec4], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'del'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'select', [_dec5], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'select'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'forUpdate', [_dec6], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'forUpdate'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'forShare', [_dec7], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'forShare'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'as', [_dec8], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'as'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'columns', [_dec9], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'columns'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'column', [_dec10], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'column'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'from', [_dec11], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'from'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'fromJS', [_dec12], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fromJS'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'into', [_dec13], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'into'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'withSchema', [_dec14], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'withSchema'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'table', [_dec15], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'table'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'distinct', [_dec16], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'distinct'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'join', [_dec17], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'join'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'joinRaw', [_dec18], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'joinRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'innerJoin', [_dec19], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'innerJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'leftJoin', [_dec20], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'leftJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'leftOuterJoin', [_dec21], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'leftOuterJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'rightJoin', [_dec22], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'rightJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'rightOuterJoin', [_dec23], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'rightOuterJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'outerJoin', [_dec24], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'outerJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'fullOuterJoin', [_dec25], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullOuterJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'crossJoin', [_dec26], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'crossJoin'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'where', [_dec27], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'where'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'andWhere', [_dec28], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'andWhere'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhere', [_dec29], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhere'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereNot', [_dec30], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereNot'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereNot', [_dec31], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereNot'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereRaw', [_dec32], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereWrapped', [_dec33], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereWrapped'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'havingWrapped', [_dec34], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'havingWrapped'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereRaw', [_dec35], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereExists', [_dec36], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereExists'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereExists', [_dec37], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereExists'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereNotExists', [_dec38], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereNotExists'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereNotExists', [_dec39], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereNotExists'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereIn', [_dec40], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereIn'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereIn', [_dec41], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereIn'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereNotIn', [_dec42], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereNotIn'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereNotIn', [_dec43], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereNotIn'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereNull', [_dec44], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereNull'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereNull', [_dec45], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereNull'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereNotNull', [_dec46], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereNotNull'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereNotNull', [_dec47], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereNotNull'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereBetween', [_dec48], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereBetween'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereNotBetween', [_dec49], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereNotBetween'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereBetween', [_dec50], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereBetween'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereNotBetween', [_dec51], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereNotBetween'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'groupBy', [_dec52], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'groupBy'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'groupByRaw', [_dec53], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'groupByRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orderBy', [_dec54], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orderBy'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orderByRaw', [_dec55], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orderByRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'union', [_dec56], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'union'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'unionAll', [_dec57], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'unionAll'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'having', [_dec58], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'having'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'havingRaw', [_dec59], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'havingRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orHaving', [_dec60], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orHaving'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orHavingRaw', [_dec61], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orHavingRaw'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'offset', [_dec62], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'offset'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'limit', [_dec63], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'limit'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'count', [_dec64], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'count'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'countDistinct', [_dec65], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'countDistinct'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'min', [_dec66], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'min'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'max', [_dec67], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'max'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'sum', [_dec68], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'sum'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'avg', [_dec69], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'avg'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'avgDistinct', [_dec70], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'avgDistinct'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'debug', [_dec71], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'debug'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'returning', [_dec72], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'returning'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'truncate', [_dec73], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'truncate'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'connection', [_dec74], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'connection'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'options', [_dec75], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'options'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'columnInfo', [_dec76], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'columnInfo'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'modify', [_dec77], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'modify'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereRef', [_dec78], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereRef'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereRef', [_dec79], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereRef'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereComposite', [_dec80], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereComposite'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereInComposite', [_dec81], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereInComposite'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonEquals', [_dec82], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonEquals'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonEquals', [_dec83], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonEquals'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonNotEquals', [_dec84], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonNotEquals'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonNotEquals', [_dec85], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonNotEquals'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonSupersetOf', [_dec86], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonSupersetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonSupersetOf', [_dec87], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonSupersetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonNotSupersetOf', [_dec88], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonNotSupersetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonNotSupersetOf', [_dec89], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonNotSupersetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonSubsetOf', [_dec90], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonSubsetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonSubsetOf', [_dec91], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonSubsetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonNotSubsetOf', [_dec92], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonNotSubsetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonNotSubsetOf', [_dec93], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonNotSubsetOf'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonNotArray', [_dec94], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonNotArray'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonNotArray', [_dec95], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonNotArray'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonNotObject', [_dec96], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonNotObject'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonNotObject', [_dec97], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonNotObject'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonHasAny', [_dec98], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonHasAny'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonHasAny', [_dec99], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonHasAny'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonHasAll', [_dec100], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonHasAll'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonHasAll', [_dec101], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonHasAll'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'whereJsonField', [_dec102], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'whereJsonField'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'orWhereJsonField', [_dec103], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'orWhereJsonField'), _class.prototype)), _class)); | ||
exports.default = QueryBuilderBase; |
@@ -16,6 +16,2 @@ 'use strict'; | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _lodash = require('lodash'); | ||
@@ -60,170 +56,162 @@ | ||
(0, _createClass3.default)(RelationExpression, [{ | ||
key: 'isSubExpression', | ||
/** | ||
* @param {string|RelationExpression} expr | ||
* @returns {boolean} | ||
*/ | ||
value: function isSubExpression(expr) { | ||
var _this = this; | ||
expr = RelationExpression.parse(expr); | ||
if (this.isAllRecursive()) { | ||
return true; | ||
RelationExpression.parse = function parse(expr) { | ||
if (expr instanceof RelationExpression) { | ||
return expr; | ||
} else if (!_lodash2.default.isString(expr) || _lodash2.default.isEmpty(expr.trim())) { | ||
return new RelationExpression(); | ||
} else { | ||
try { | ||
return new RelationExpression(_relationExpressionParser2.default.parse(expr)); | ||
} catch (err) { | ||
throw new _ValidationError2.default({ | ||
message: 'Invalid relation expression "' + expr + '"', | ||
cause: err.message | ||
}); | ||
} | ||
} | ||
}; | ||
if (expr.isAllRecursive()) { | ||
return this.isAllRecursive(); | ||
} | ||
/** | ||
* @param {string|RelationExpression} expr | ||
* @returns {boolean} | ||
*/ | ||
if (this.name !== expr.name) { | ||
return false; | ||
} | ||
var maxRecursionDepth = expr.maxRecursionDepth(); | ||
RelationExpression.prototype.isSubExpression = function isSubExpression(expr) { | ||
var _this = this; | ||
if (maxRecursionDepth > 0) { | ||
return this.isAllRecursive() || this.maxRecursionDepth() >= maxRecursionDepth; | ||
} | ||
expr = RelationExpression.parse(expr); | ||
return _lodash2.default.all(expr.children, function (child, childName) { | ||
var ownSubExpression = _this.childExpression(childName); | ||
var subExpression = expr.childExpression(childName); | ||
if (this.isAllRecursive()) { | ||
return true; | ||
} | ||
return ownSubExpression && ownSubExpression.isSubExpression(subExpression); | ||
}); | ||
if (expr.isAllRecursive()) { | ||
return this.isAllRecursive(); | ||
} | ||
/** | ||
* @returns {number} | ||
*/ | ||
if (this.name !== expr.name) { | ||
return false; | ||
} | ||
}, { | ||
key: 'maxRecursionDepth', | ||
value: function maxRecursionDepth() { | ||
if (this.numChildren !== 1) { | ||
return 0; | ||
} | ||
var maxRecursionDepth = expr.maxRecursionDepth(); | ||
return _lodash2.default.map(this.children, function (val, key) { | ||
var rec = RECURSIVE_REGEX.exec(key); | ||
if (maxRecursionDepth > 0) { | ||
return this.isAllRecursive() || this.maxRecursionDepth() >= maxRecursionDepth; | ||
} | ||
if (rec) { | ||
var maxDepth = rec[1]; | ||
return _lodash2.default.every(expr.children, function (child, childName) { | ||
var ownSubExpression = _this.childExpression(childName); | ||
var subExpression = expr.childExpression(childName); | ||
if (maxDepth) { | ||
return parseInt(maxDepth, 10); | ||
} else { | ||
return Number.POSITIVE_INFINITY; | ||
} | ||
} else { | ||
return 0; | ||
} | ||
})[0]; | ||
} | ||
return ownSubExpression && ownSubExpression.isSubExpression(subExpression); | ||
}); | ||
}; | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
/** | ||
* @returns {number} | ||
*/ | ||
}, { | ||
key: 'isAllRecursive', | ||
value: function isAllRecursive() { | ||
return this.numChildren === 1 && _lodash2.default.all(this.children, function (val, key) { | ||
return ALL_RECURSIVE_REGEX.test(key); | ||
}); | ||
RelationExpression.prototype.maxRecursionDepth = function maxRecursionDepth() { | ||
if (this.numChildren !== 1) { | ||
return 0; | ||
} | ||
/** | ||
* @returns {RelationExpression} | ||
*/ | ||
return _lodash2.default.map(this.children, function (val, key) { | ||
var rec = RECURSIVE_REGEX.exec(key); | ||
}, { | ||
key: 'childExpression', | ||
value: function childExpression(childName) { | ||
if (this.isAllRecursive() || childName === this.name && this.recursionDepth < this.maxRecursionDepth() - 1) { | ||
return new RelationExpression(this, this.recursionDepth + 1); | ||
} | ||
if (rec) { | ||
var maxDepth = rec[1]; | ||
if (this.children[childName]) { | ||
return new RelationExpression(this.children[childName]); | ||
if (maxDepth) { | ||
return parseInt(maxDepth, 10); | ||
} else { | ||
return Number.POSITIVE_INFINITY; | ||
} | ||
} else { | ||
return null; | ||
return 0; | ||
} | ||
} | ||
})[0]; | ||
}; | ||
/** | ||
* @returns {RelationExpression} | ||
*/ | ||
/** | ||
* @returns {boolean} | ||
*/ | ||
}, { | ||
key: 'clone', | ||
value: function clone() { | ||
return new RelationExpression(JSON.parse((0, _stringify2.default)(this))); | ||
RelationExpression.prototype.isAllRecursive = function isAllRecursive() { | ||
return this.numChildren === 1 && _lodash2.default.every(this.children, function (val, key) { | ||
return ALL_RECURSIVE_REGEX.test(key); | ||
}); | ||
}; | ||
/** | ||
* @returns {RelationExpression} | ||
*/ | ||
RelationExpression.prototype.childExpression = function childExpression(childName) { | ||
if (this.isAllRecursive() || childName === this.name && this.recursionDepth < this.maxRecursionDepth() - 1) { | ||
return new RelationExpression(this, this.recursionDepth + 1); | ||
} | ||
}, { | ||
key: 'forEachChild', | ||
value: function forEachChild(cb) { | ||
_lodash2.default.each(this.children, function (child, childName) { | ||
if (!ALL_RECURSIVE_REGEX.test(childName) && !RECURSIVE_REGEX.test(childName)) { | ||
cb(child, childName); | ||
} | ||
}); | ||
if (this.children[childName]) { | ||
return new RelationExpression(this.children[childName]); | ||
} else { | ||
return null; | ||
} | ||
}; | ||
/** | ||
* @return {Array.<RelationExpression>} | ||
*/ | ||
/** | ||
* @returns {RelationExpression} | ||
*/ | ||
}, { | ||
key: 'expressionsAtPath', | ||
value: function expressionsAtPath(pathExpression) { | ||
var path = RelationExpression.parse(pathExpression); | ||
var expressions = []; | ||
RelationExpression.expressionsAtPath(this, path, expressions); | ||
return expressions; | ||
} | ||
/** | ||
* @private | ||
*/ | ||
RelationExpression.prototype.clone = function clone() { | ||
return new RelationExpression(JSON.parse((0, _stringify2.default)(this))); | ||
}; | ||
}], [{ | ||
key: 'parse', | ||
value: function parse(expr) { | ||
if (expr instanceof RelationExpression) { | ||
return expr; | ||
} else if (!_lodash2.default.isString(expr) || _lodash2.default.isEmpty(expr.trim())) { | ||
return new RelationExpression(); | ||
} else { | ||
try { | ||
return new RelationExpression(_relationExpressionParser2.default.parse(expr)); | ||
} catch (err) { | ||
throw new _ValidationError2.default({ | ||
message: 'Invalid relation expression "' + expr + '"', | ||
cause: err.message | ||
}); | ||
} | ||
RelationExpression.prototype.forEachChild = function forEachChild(cb) { | ||
_lodash2.default.each(this.children, function (child, childName) { | ||
if (!ALL_RECURSIVE_REGEX.test(childName) && !RECURSIVE_REGEX.test(childName)) { | ||
cb(child, childName); | ||
} | ||
} | ||
}, { | ||
key: 'expressionsAtPath', | ||
value: function expressionsAtPath(target, path, expressions) { | ||
var _this2 = this; | ||
}); | ||
}; | ||
if (path.numChildren == 0) { | ||
expressions.push(target); | ||
} else { | ||
_lodash2.default.each(path.children, function (child) { | ||
var targetChild = target.children[child.name]; | ||
/** | ||
* @return {Array.<RelationExpression>} | ||
*/ | ||
if (targetChild) { | ||
_this2.expressionsAtPath(targetChild, child, expressions); | ||
} | ||
}); | ||
} | ||
RelationExpression.prototype.expressionsAtPath = function expressionsAtPath(pathExpression) { | ||
var path = RelationExpression.parse(pathExpression); | ||
var expressions = []; | ||
RelationExpression.expressionsAtPath(this, path, expressions); | ||
return expressions; | ||
}; | ||
/** | ||
* @private | ||
*/ | ||
RelationExpression.expressionsAtPath = function expressionsAtPath(target, path, expressions) { | ||
var _this2 = this; | ||
if (path.numChildren == 0) { | ||
expressions.push(target); | ||
} else { | ||
_lodash2.default.each(path.children, function (child) { | ||
var targetChild = target.children[child.name]; | ||
if (targetChild) { | ||
_this2.expressionsAtPath(targetChild, child, expressions); | ||
} | ||
}); | ||
} | ||
}]); | ||
}; | ||
return RelationExpression; | ||
@@ -230,0 +218,0 @@ }(); |
'use strict'; | ||
var _desc, _value, _class; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -22,6 +20,4 @@ value: true | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _desc, _value, _class; | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
var _lodash = require('lodash'); | ||
@@ -31,4 +27,2 @@ | ||
var _classUtils = require('../utils/classUtils'); | ||
var _memoize = require('../utils/decorators/memoize'); | ||
@@ -38,2 +32,4 @@ | ||
var _classUtils = require('../utils/classUtils'); | ||
var _QueryBuilder = require('../queryBuilder/QueryBuilder'); | ||
@@ -43,2 +39,14 @@ | ||
var _RelationFindOperation = require('./RelationFindOperation'); | ||
var _RelationFindOperation2 = _interopRequireDefault(_RelationFindOperation); | ||
var _RelationUpdateOperation = require('./RelationUpdateOperation'); | ||
var _RelationUpdateOperation2 = _interopRequireDefault(_RelationUpdateOperation); | ||
var _RelationDeleteOperation = require('./RelationDeleteOperation'); | ||
var _RelationDeleteOperation2 = _interopRequireDefault(_RelationDeleteOperation); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -149,483 +157,449 @@ | ||
(0, _createClass3.default)(Relation, [{ | ||
key: 'setMapping', | ||
/** | ||
* @param {RelationMapping} mapping | ||
*/ | ||
value: function setMapping(mapping) { | ||
// Avoid require loop and import here. | ||
var Model = require(__dirname + '/../model/Model').default; | ||
Relation.extend = function extend(subclassConstructor) { | ||
(0, _classUtils.inherits)(subclassConstructor, this); | ||
return subclassConstructor; | ||
}; | ||
if (!(0, _classUtils.isSubclassOf)(this.ownerModelClass, Model)) { | ||
this.throwError('Relation\'s owner is not a subclass of Model'); | ||
} | ||
/** | ||
* @param {RelationMapping} mapping | ||
*/ | ||
if (!mapping.modelClass) { | ||
this.throwError('modelClass is not defined'); | ||
} | ||
if (_lodash2.default.isString(mapping.modelClass)) { | ||
try { | ||
// babel 6 style of exposing es6 exports to commonjs https://github.com/babel/babel/issues/2683 | ||
var relatedModelClassModule = require(mapping.modelClass); | ||
this.relatedModelClass = (0, _classUtils.isSubclassOf)(relatedModelClassModule.default, Model) ? relatedModelClassModule.default : relatedModelClassModule; | ||
} catch (err) { | ||
this.throwError('modelClass is an invalid file path to a model class.'); | ||
} | ||
Relation.prototype.setMapping = function setMapping(mapping) { | ||
// Avoid require loop and import here. | ||
var Model = require(__dirname + '/../model/Model').default; | ||
if (!(0, _classUtils.isSubclassOf)(this.relatedModelClass, Model)) { | ||
this.throwError('modelClass is a valid path to a module, but the module doesn\'t export a Model subclass.'); | ||
} | ||
} else { | ||
this.relatedModelClass = mapping.modelClass; | ||
if (!(0, _classUtils.isSubclassOf)(this.ownerModelClass, Model)) { | ||
this.throwError('Relation\'s owner is not a subclass of Model'); | ||
} | ||
if (!(0, _classUtils.isSubclassOf)(this.relatedModelClass, Model)) { | ||
this.throwError('modelClass is not a subclass of Model or a file path to a module that exports one.'); | ||
} | ||
} | ||
if (!mapping.modelClass) { | ||
this.throwError('modelClass is not defined'); | ||
} | ||
if (!mapping.relation) { | ||
this.throwError('relation is not defined'); | ||
if (_lodash2.default.isString(mapping.modelClass)) { | ||
try { | ||
// babel 6 style of exposing es6 exports to commonjs https://github.com/babel/babel/issues/2683 | ||
var relatedModelClassModule = require(mapping.modelClass); | ||
this.relatedModelClass = (0, _classUtils.isSubclassOf)(relatedModelClassModule.default, Model) ? relatedModelClassModule.default : relatedModelClassModule; | ||
} catch (err) { | ||
this.throwError('modelClass is an invalid file path to a model class.'); | ||
} | ||
if (!(0, _classUtils.isSubclassOf)(mapping.relation, Relation)) { | ||
this.throwError('relation is not a subclass of Relation'); | ||
if (!(0, _classUtils.isSubclassOf)(this.relatedModelClass, Model)) { | ||
this.throwError('modelClass is a valid path to a module, but the module doesn\'t export a Model subclass.'); | ||
} | ||
} else { | ||
this.relatedModelClass = mapping.modelClass; | ||
if (!mapping.join || !mapping.join.from || !mapping.join.to) { | ||
this.throwError('join must be an object that maps the columns of the related models together. For example: {from: "SomeTable.id", to: "SomeOtherTable.someModelId"}'); | ||
if (!(0, _classUtils.isSubclassOf)(this.relatedModelClass, Model)) { | ||
this.throwError('modelClass is not a subclass of Model or a file path to a module that exports one.'); | ||
} | ||
} | ||
var joinOwner = null; | ||
var joinRelated = null; | ||
if (!mapping.relation) { | ||
this.throwError('relation is not defined'); | ||
} | ||
var joinFrom = this.parseReference(mapping.join.from); | ||
var joinTo = this.parseReference(mapping.join.to); | ||
if (!(0, _classUtils.isSubclassOf)(mapping.relation, Relation)) { | ||
this.throwError('relation is not a subclass of Relation'); | ||
} | ||
if (!joinFrom.table || _lodash2.default.isEmpty(joinFrom.columns)) { | ||
this.throwError('join.from must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].'); | ||
} | ||
if (!mapping.join || !mapping.join.from || !mapping.join.to) { | ||
this.throwError('join must be an object that maps the columns of the related models together. For example: {from: "SomeTable.id", to: "SomeOtherTable.someModelId"}'); | ||
} | ||
if (!joinTo.table || _lodash2.default.isEmpty(joinTo.columns)) { | ||
this.throwError('join.to must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].'); | ||
} | ||
var joinOwner = null; | ||
var joinRelated = null; | ||
if (joinFrom.table === this.ownerModelClass.tableName) { | ||
joinOwner = joinFrom; | ||
joinRelated = joinTo; | ||
} else if (joinTo.table === this.ownerModelClass.tableName) { | ||
joinOwner = joinTo; | ||
joinRelated = joinFrom; | ||
} else { | ||
this.throwError('join: either `from` or `to` must point to the owner model table.'); | ||
} | ||
var joinFrom = this.parseReference(mapping.join.from); | ||
var joinTo = this.parseReference(mapping.join.to); | ||
if (joinRelated.table !== this.relatedModelClass.tableName) { | ||
this.throwError('join: either `from` or `to` must point to the related model table.'); | ||
} | ||
if (!joinFrom.table || _lodash2.default.isEmpty(joinFrom.columns)) { | ||
this.throwError('join.from must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].'); | ||
} | ||
this.ownerCol = joinOwner.columns; | ||
this.ownerProp = this.propertyName(this.ownerCol, this.ownerModelClass); | ||
this.relatedCol = joinRelated.columns; | ||
this.relatedProp = this.propertyName(this.relatedCol, this.relatedModelClass); | ||
this.filter = this.parseFilter(mapping); | ||
if (!joinTo.table || _lodash2.default.isEmpty(joinTo.columns)) { | ||
this.throwError('join.to must have format TableName.columnName. For example "SomeTable.id" or in case of composite key ["SomeTable.a", "SomeTable.b"].'); | ||
} | ||
/** | ||
* @returns {knex} | ||
*/ | ||
if (joinFrom.table === this.ownerModelClass.tableName) { | ||
joinOwner = joinFrom; | ||
joinRelated = joinTo; | ||
} else if (joinTo.table === this.ownerModelClass.tableName) { | ||
joinOwner = joinTo; | ||
joinRelated = joinFrom; | ||
} else { | ||
this.throwError('join: either `from` or `to` must point to the owner model table.'); | ||
} | ||
}, { | ||
key: 'knex', | ||
value: function knex() { | ||
return this.ownerModelClass.knex(); | ||
if (joinRelated.table !== this.relatedModelClass.tableName) { | ||
this.throwError('join: either `from` or `to` must point to the related model table.'); | ||
} | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
this.ownerCol = joinOwner.columns; | ||
this.ownerProp = this.propertyName(this.ownerCol, this.ownerModelClass); | ||
this.relatedCol = joinRelated.columns; | ||
this.relatedProp = this.propertyName(this.relatedCol, this.relatedModelClass); | ||
this.filter = this.parseFilter(mapping); | ||
}; | ||
}, { | ||
key: 'fullOwnerCol', | ||
value: function fullOwnerCol() { | ||
var _this = this; | ||
/** | ||
* @returns {knex} | ||
*/ | ||
return _lodash2.default.map(this.ownerCol, function (col) { | ||
return _this.ownerModelClass.tableName + '.' + col; | ||
}); | ||
} | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
Relation.prototype.knex = function knex() { | ||
return this.ownerModelClass.knex(); | ||
}; | ||
}, { | ||
key: 'fullRelatedCol', | ||
value: function fullRelatedCol() { | ||
var _this2 = this; | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
return _lodash2.default.map(this.relatedCol, function (col) { | ||
return _this2.relatedModelClass.tableName + '.' + col; | ||
}); | ||
} | ||
/** | ||
* @returns {string} | ||
*/ | ||
Relation.prototype.fullOwnerCol = function fullOwnerCol() { | ||
var _this = this; | ||
}, { | ||
key: 'relatedTableAlias', | ||
value: function relatedTableAlias() { | ||
return this.relatedModelClass.tableName + '_rel_' + this.name; | ||
} | ||
return _lodash2.default.map(this.ownerCol, function (col) { | ||
return _this.ownerModelClass.tableName + '.' + col; | ||
}); | ||
}; | ||
/** | ||
* @returns {Relation} | ||
*/ | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
}, { | ||
key: 'clone', | ||
value: function clone() { | ||
var relation = new this.constructor(this.name, this.ownerModelClass); | ||
relation.relatedModelClass = this.relatedModelClass; | ||
relation.ownerCol = this.ownerCol; | ||
relation.ownerProp = this.ownerProp; | ||
relation.relatedCol = this.relatedCol; | ||
relation.relatedProp = this.relatedProp; | ||
relation.filter = this.filter; | ||
Relation.prototype.fullRelatedCol = function fullRelatedCol() { | ||
var _this2 = this; | ||
return relation; | ||
} | ||
return _lodash2.default.map(this.relatedCol, function (col) { | ||
return _this2.relatedModelClass.tableName + '.' + col; | ||
}); | ||
}; | ||
/** | ||
* @param {knex} knex | ||
* @returns {Relation} | ||
*/ | ||
/** | ||
* @returns {string} | ||
*/ | ||
}, { | ||
key: 'bindKnex', | ||
value: function bindKnex(knex) { | ||
var bound = this.clone(); | ||
bound.relatedModelClass = this.relatedModelClass.bindKnex(knex); | ||
bound.ownerModelClass = this.ownerModelClass.bindKnex(knex); | ||
Relation.prototype.relatedTableAlias = function relatedTableAlias() { | ||
return this.relatedModelClass.tableName + '_rel_' + this.name; | ||
}; | ||
return bound; | ||
} | ||
/** | ||
* @returns {Relation} | ||
*/ | ||
/** | ||
* @protected | ||
* @param {Array.<Model>} models1 | ||
* @param {Array.<Model>} models2 | ||
* @returns {Array.<Model>} | ||
*/ | ||
}, { | ||
key: 'mergeModels', | ||
value: function mergeModels(models1, models2) { | ||
var modelsById = (0, _create2.default)(null); | ||
Relation.prototype.clone = function clone() { | ||
var relation = new this.constructor(this.name, this.ownerModelClass); | ||
models1 = _lodash2.default.compact(models1); | ||
models2 = _lodash2.default.compact(models2); | ||
relation.relatedModelClass = this.relatedModelClass; | ||
relation.ownerCol = this.ownerCol; | ||
relation.ownerProp = this.ownerProp; | ||
relation.relatedCol = this.relatedCol; | ||
relation.relatedProp = this.relatedProp; | ||
relation.filter = this.filter; | ||
_lodash2.default.forEach(models1, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
return relation; | ||
}; | ||
_lodash2.default.forEach(models2, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
/** | ||
* @param {knex} knex | ||
* @returns {Relation} | ||
*/ | ||
var models = _lodash2.default.values(modelsById); | ||
if (models.length === 0) { | ||
return []; | ||
} | ||
var modelClass = models[0].constructor; | ||
var idProperty = modelClass.getIdProperty(); | ||
Relation.prototype.bindKnex = function bindKnex(knex) { | ||
var bound = this.clone(); | ||
return _lodash2.default.sortByAll(models, _lodash2.default.isArray(idProperty) ? idProperty : [idProperty]); | ||
} | ||
bound.relatedModelClass = this.relatedModelClass.bindKnex(knex); | ||
bound.ownerModelClass = this.ownerModelClass.bindKnex(knex); | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Array.<string>|Array.<Array.<(string|number)>>} ownerIds | ||
* @param {boolean=} isColumnRef | ||
* @returns {QueryBuilder} | ||
*/ | ||
return bound; | ||
}; | ||
}, { | ||
key: 'findQuery', | ||
value: function findQuery(builder, ownerIds, isColumnRef) { | ||
var fullRelatedCol = this.fullRelatedCol(); | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Array.<string>|Array.<Array.<(string|number)>>} ownerIds | ||
* @param {boolean=} isColumnRef | ||
* @returns {QueryBuilder} | ||
*/ | ||
if (isColumnRef) { | ||
_lodash2.default.each(fullRelatedCol, function (col, idx) { | ||
builder.whereRef(col, ownerIds[idx]); | ||
}); | ||
Relation.prototype.findQuery = function findQuery(builder, ownerIds, isColumnRef) { | ||
var fullRelatedCol = this.fullRelatedCol(); | ||
if (isColumnRef) { | ||
_lodash2.default.each(fullRelatedCol, function (col, idx) { | ||
builder.whereRef(col, ownerIds[idx]); | ||
}); | ||
} else { | ||
if ((0, _lodash2.default)(ownerIds).flatten().every(function (id) { | ||
return _lodash2.default.isNull(id) || _lodash2.default.isUndefined(id); | ||
})) { | ||
// Nothing to fetch. | ||
builder.resolve([]); | ||
} else { | ||
if ((0, _lodash2.default)(ownerIds).flatten().all(function (id) { | ||
return _lodash2.default.isNull(id) || _lodash2.default.isUndefined(id); | ||
})) { | ||
// Nothing to fetch. | ||
builder.resolve([]); | ||
} else { | ||
builder.whereInComposite(fullRelatedCol, ownerIds); | ||
} | ||
builder.whereInComposite(fullRelatedCol, ownerIds); | ||
} | ||
return builder.call(this.filter); | ||
} | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {string=} joinMethod | ||
* @param {string=} relatedTableAlias | ||
* @returns {QueryBuilder} | ||
*/ | ||
return builder.call(this.filter); | ||
}; | ||
}, { | ||
key: 'join', | ||
value: function join(builder, joinMethod, relatedTableAlias) { | ||
joinMethod = joinMethod || 'join'; | ||
relatedTableAlias = relatedTableAlias || this.relatedTableAlias(); | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {string=} joinOperation | ||
* @param {string=} relatedTableAlias | ||
* @returns {QueryBuilder} | ||
*/ | ||
var relatedTable = this.relatedModelClass.tableName; | ||
var relatedTableAsAlias = relatedTable + ' as ' + relatedTableAlias; | ||
var relatedCol = _lodash2.default.map(this.relatedCol, function (col) { | ||
return relatedTableAlias + '.' + col; | ||
Relation.prototype.join = function join(builder, joinOperation, relatedTableAlias) { | ||
joinOperation = joinOperation || 'join'; | ||
relatedTableAlias = relatedTableAlias || this.relatedTableAlias(); | ||
var relatedTable = this.relatedModelClass.tableName; | ||
var relatedTableAsAlias = relatedTable + ' as ' + relatedTableAlias; | ||
var relatedCol = _lodash2.default.map(this.relatedCol, function (col) { | ||
return relatedTableAlias + '.' + col; | ||
}); | ||
var ownerCol = this.fullOwnerCol(); | ||
return builder[joinOperation](relatedTableAsAlias, function (join) { | ||
_lodash2.default.each(relatedCol, function (relatedCol, idx) { | ||
join.on(relatedCol, '=', ownerCol[idx]); | ||
}); | ||
var ownerCol = this.fullOwnerCol(); | ||
}).call(this.filter); | ||
}; | ||
return builder[joinMethod](relatedTableAsAlias, function (join) { | ||
_lodash2.default.each(relatedCol, function (relatedCol, idx) { | ||
join.on(relatedCol, '=', ownerCol[idx]); | ||
}); | ||
}).call(this.filter); | ||
} | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Array.<Model>} owners | ||
*/ | ||
}, { | ||
key: 'find', | ||
value: function find(builder, owners) { | ||
var _this3 = this; | ||
Relation.prototype.insert = function insert(builder, owner) { | ||
this.throwError('not implemented'); | ||
}; | ||
builder.onBuild(function (builder) { | ||
var ids = (0, _lodash2.default)(owners).map(function (owner) { | ||
return owner.$values(_this3.ownerProp); | ||
}).unique(function (id) { | ||
return id.join(); | ||
}).value(); | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
_this3.findQuery(builder, ids); | ||
}); | ||
builder.runAfterModelCreate(function (related) { | ||
_this3.createRelationProp(owners, related); | ||
return related; | ||
}); | ||
} | ||
Relation.prototype.update = function update(builder, owner) { | ||
return new _RelationUpdateOperation2.default(builder, 'update', { | ||
relation: this, | ||
owner: owner | ||
}); | ||
}; | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @protected | ||
*/ | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
}, { | ||
key: 'createRelationProp', | ||
value: function createRelationProp(owners, related) { | ||
this.throwError('not implemented'); | ||
} | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @param {InsertionOrUpdate} insertion | ||
*/ | ||
Relation.prototype.patch = function patch(builder, owner) { | ||
return new _RelationUpdateOperation2.default(builder, 'patch', { | ||
relation: this, | ||
owner: owner, | ||
modelOptions: { patch: true } | ||
}); | ||
}; | ||
}, { | ||
key: 'insert', | ||
value: function insert(builder, owner, insertion) { | ||
this.throwError('not implemented'); | ||
} | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Array.<Model>} owners | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @param {InsertionOrUpdate} update | ||
*/ | ||
}, { | ||
key: 'update', | ||
value: function update(builder, owner, _update) { | ||
var _this4 = this; | ||
Relation.prototype.find = function find(builder, owners) { | ||
return new _RelationFindOperation2.default(builder, 'find', { | ||
relation: this, | ||
owners: owners | ||
}); | ||
}; | ||
builder.onBuild(function (builder) { | ||
_this4.findQuery(builder, [owner.$values(_this4.ownerProp)]); | ||
builder.$$update(_update); | ||
}); | ||
} | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @param {InsertionOrUpdate} patch | ||
*/ | ||
}, { | ||
key: 'patch', | ||
value: function patch(builder, owner, _patch) { | ||
return this.update(builder, owner, _patch); | ||
} | ||
Relation.prototype.delete = function _delete(builder, owner) { | ||
return new _RelationDeleteOperation2.default(builder, 'delete', { | ||
relation: this, | ||
owner: owner | ||
}); | ||
}; | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
*/ | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
}, { | ||
key: 'delete', | ||
value: function _delete(builder, owner) { | ||
var _this5 = this; | ||
builder.onBuild(function (builder) { | ||
_this5.findQuery(builder, [owner.$values(_this5.ownerProp)]); | ||
builder.$$delete(); | ||
}); | ||
} | ||
Relation.prototype.relate = function relate(builder, owner) { | ||
this.throwError('not implemented'); | ||
}; | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model|Object} owner | ||
* @param {number|string|Array.<number|string>|Array.<Array.<number|string>>} ids | ||
*/ | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
}, { | ||
key: 'relate', | ||
value: function relate(builder, owner, ids) { | ||
this.throwError('not implemented'); | ||
} | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model|Object} owner | ||
*/ | ||
Relation.prototype.unrelate = function unrelate(builder, owner) { | ||
this.throwError('not implemented'); | ||
}; | ||
}, { | ||
key: 'unrelate', | ||
value: function unrelate(builder, owner) { | ||
this.throwError('not implemented'); | ||
} | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @protected | ||
*/ | ||
/** | ||
* @protected | ||
*/ | ||
}, { | ||
key: 'propertyName', | ||
value: function propertyName(columns, modelClass) { | ||
var _this6 = this; | ||
Relation.prototype.createRelationProp = function createRelationProp(owners, related) { | ||
this.throwError('not implemented'); | ||
}; | ||
return _lodash2.default.map(columns, function (column) { | ||
var propertyName = modelClass.columnNameToPropertyName(column); | ||
/** | ||
* @protected | ||
*/ | ||
if (!propertyName) { | ||
throw new Error(modelClass.name + '.$parseDatabaseJson probably transforms the value of the column ' + column + '.' + ' This is a no-no because ' + column + ' is needed in the relation ' + _this6.ownerModelClass.tableName + '.' + _this6.name); | ||
} | ||
return propertyName; | ||
}); | ||
Relation.prototype.propertyName = function propertyName(columns, modelClass) { | ||
var _this3 = this; | ||
return _lodash2.default.map(columns, function (column) { | ||
var propertyName = modelClass.columnNameToPropertyName(column); | ||
if (!propertyName) { | ||
throw new Error(modelClass.name + '.$parseDatabaseJson probably transforms the value of the column ' + column + '.' + ' This is a no-no because ' + column + ' is needed in the relation ' + _this3.ownerModelClass.tableName + '.' + _this3.name); | ||
} | ||
return propertyName; | ||
}); | ||
}; | ||
/** | ||
* @protected | ||
*/ | ||
Relation.prototype.parseFilter = function parseFilter(mapping) { | ||
if (_lodash2.default.isFunction(mapping.filter)) { | ||
return mapping.filter; | ||
} else if (_lodash2.default.isObject(mapping.filter)) { | ||
return function (queryBuilder) { | ||
queryBuilder.where(mapping.filter); | ||
}; | ||
} else { | ||
return _lodash2.default.noop; | ||
} | ||
}; | ||
/** | ||
* @protected | ||
*/ | ||
/** | ||
* @protected | ||
*/ | ||
}, { | ||
key: 'parseFilter', | ||
value: function parseFilter(mapping) { | ||
if (_lodash2.default.isFunction(mapping.filter)) { | ||
return mapping.filter; | ||
} else if (_lodash2.default.isObject(mapping.filter)) { | ||
return function (queryBuilder) { | ||
queryBuilder.where(mapping.filter); | ||
Relation.prototype.parseReference = function parseReference(ref) { | ||
if (!_lodash2.default.isArray(ref)) { | ||
ref = [ref]; | ||
} | ||
var table = null; | ||
var columns = []; | ||
for (var i = 0; i < ref.length; ++i) { | ||
var refItem = ref[i]; | ||
var ndx = refItem.lastIndexOf('.'); | ||
var tableName = refItem.substr(0, ndx).trim(); | ||
var columnName = refItem.substr(ndx + 1, refItem.length).trim(); | ||
if (!tableName || table && table !== tableName || !columnName) { | ||
return { | ||
table: null, | ||
columns: [] | ||
}; | ||
} else { | ||
return _lodash2.default.noop; | ||
table = tableName; | ||
} | ||
columns.push(columnName); | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
return { | ||
table: table, | ||
columns: columns | ||
}; | ||
}; | ||
}, { | ||
key: 'parseReference', | ||
value: function parseReference(ref) { | ||
if (!_lodash2.default.isArray(ref)) { | ||
ref = [ref]; | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
var table = null; | ||
var columns = []; | ||
for (var i = 0; i < ref.length; ++i) { | ||
var refItem = ref[i]; | ||
var ndx = refItem.lastIndexOf('.'); | ||
var tableName = refItem.substr(0, ndx).trim(); | ||
var columnName = refItem.substr(ndx + 1, refItem.length).trim(); | ||
Relation.prototype.mergeModels = function mergeModels(models1, models2) { | ||
var modelsById = (0, _create2.default)(null); | ||
if (!tableName || table && table !== tableName || !columnName) { | ||
return { | ||
table: null, | ||
columns: [] | ||
}; | ||
} else { | ||
table = tableName; | ||
} | ||
models1 = _lodash2.default.compact(models1); | ||
models2 = _lodash2.default.compact(models2); | ||
columns.push(columnName); | ||
} | ||
_lodash2.default.forEach(models1, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
return { | ||
table: table, | ||
columns: columns | ||
}; | ||
_lodash2.default.forEach(models2, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
var models = _lodash2.default.values(modelsById); | ||
if (models.length === 0) { | ||
return []; | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
var modelClass = models[0].constructor; | ||
var idProperty = modelClass.getIdProperty(); | ||
}, { | ||
key: 'throwError', | ||
value: function throwError(message) { | ||
if (this.ownerModelClass && this.ownerModelClass.name && this.name) { | ||
throw new Error(this.ownerModelClass.name + '.relationMappings.' + this.name + ': ' + message); | ||
} else { | ||
throw new Error(this.constructor.name + ': ' + message); | ||
} | ||
return _lodash2.default.sortBy(models, _lodash2.default.isArray(idProperty) ? idProperty : [idProperty]); | ||
}; | ||
/** | ||
* @protected | ||
*/ | ||
Relation.prototype.throwError = function throwError(message) { | ||
if (this.ownerModelClass && this.ownerModelClass.name && this.name) { | ||
throw new Error(this.ownerModelClass.name + '.relationMappings.' + this.name + ': ' + message); | ||
} else { | ||
throw new Error(this.constructor.name + ': ' + message); | ||
} | ||
}], [{ | ||
key: 'extend', | ||
value: function extend(subclassConstructor) { | ||
(0, _classUtils.inherits)(subclassConstructor, this); | ||
return subclassConstructor; | ||
} | ||
}]); | ||
}; | ||
return Relation; | ||
}(), (_applyDecoratedDescriptor(_class.prototype, 'fullOwnerCol', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullOwnerCol'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'fullRelatedCol', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'fullRelatedCol'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, 'relatedTableAlias', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, 'relatedTableAlias'), _class.prototype)), _class); | ||
exports.default = Relation; |
@@ -36,3 +36,3 @@ 'use strict'; | ||
var modelClasses = _lodash2.default.take(arguments, arguments.length - 1); | ||
var i = undefined; | ||
var i = void 0; | ||
@@ -39,0 +39,0 @@ for (i = 0; i < modelClasses.length; ++i) { |
@@ -6,4 +6,2 @@ "use strict"; | ||
}); | ||
exports.inherits = inherits; | ||
exports.isSubclassOf = isSubclassOf; | ||
@@ -18,2 +16,5 @@ var _create = require("babel-runtime/core-js/object/create"); | ||
exports.inherits = inherits; | ||
exports.isSubclassOf = isSubclassOf; | ||
var _lodash = require("lodash"); | ||
@@ -20,0 +21,0 @@ |
@@ -6,2 +6,7 @@ 'use strict'; | ||
}); | ||
var _defineProperty = require('babel-runtime/core-js/object/define-property'); | ||
var _defineProperty2 = _interopRequireDefault(_defineProperty); | ||
exports.getDialect = getDialect; | ||
@@ -14,6 +19,2 @@ exports.isPostgres = isPostgres; | ||
var _defineProperty = require('babel-runtime/core-js/object/define-property'); | ||
var _defineProperty2 = _interopRequireDefault(_defineProperty); | ||
var _lodash = require('lodash'); | ||
@@ -44,2 +45,3 @@ | ||
function isKnexQueryBuilder(knexQueryBuilder) { | ||
// TODO: Use something safer | ||
return knexQueryBuilder && knexQueryBuilder.client && _lodash2.default.isString(knexQueryBuilder.client.dialect); | ||
@@ -46,0 +48,0 @@ } |
@@ -6,3 +6,2 @@ 'use strict'; | ||
}); | ||
exports.default = memoize; | ||
@@ -13,2 +12,4 @@ var _create = require('babel-runtime/core-js/object/create'); | ||
exports.default = memoize; | ||
var _lodash = require('lodash'); | ||
@@ -15,0 +16,0 @@ |
@@ -15,3 +15,3 @@ 'use strict'; |
function createHiddenDataSetter(propName) { |
return new Function('obj', 'data', '\n var hiddenData = obj.' + HIDDEN_DATA + ';\n\n if (typeof hiddenData !== \'object\') {\n hiddenData = Object.create(null);\n\n Object.defineProperty(obj, "' + HIDDEN_DATA + '", {\n enumerable: false,\n writable: false,\n value: hiddenData\n });\n }\n\n hiddenData.' + propName + ' = data;\n '); |
return new Function('obj', 'data', '\n if (!obj.hasOwnProperty("' + HIDDEN_DATA + '")) {\n Object.defineProperty(obj, "' + HIDDEN_DATA + '", {\n enumerable: false,\n writable: false,\n value: Object.create(null)\n });\n }\n\n obj.' + HIDDEN_DATA + '.' + propName + ' = data;\n '); |
} |
@@ -7,2 +7,6 @@ 'use strict'; | ||
var _stringify = require('babel-runtime/core-js/json/stringify'); | ||
var _stringify2 = _interopRequireDefault(_stringify); | ||
exports.default = function (ids, expectedProperties, opt) { | ||
@@ -63,3 +67,3 @@ opt = opt || {}; | ||
ids = _lodash2.default.map(ids, function (item) { | ||
return _lodash2.default.object(expectedProperties, [item]); | ||
return _lodash2.default.zipObject(expectedProperties, [item]); | ||
}); | ||
@@ -72,3 +76,3 @@ } | ||
// 1. | ||
ids = [_lodash2.default.object(expectedProperties, [ids])]; | ||
ids = [_lodash2.default.zipObject(expectedProperties, [ids])]; | ||
} | ||
@@ -96,6 +100,2 @@ } | ||
var _stringify = require('babel-runtime/core-js/json/stringify'); | ||
var _stringify2 = _interopRequireDefault(_stringify); | ||
var _lodash = require('lodash'); | ||
@@ -118,3 +118,3 @@ | ||
return _lodash2.default.object(expectedProperties, ids); | ||
return _lodash2.default.zipObject(expectedProperties, ids); | ||
} | ||
@@ -121,0 +121,0 @@ |
@@ -13,3 +13,3 @@ 'use strict'; | ||
var needsSplit = _lodash2.default.any(obj, function (value) { | ||
var needsSplit = _lodash2.default.some(obj, function (value) { | ||
return isQueryProp; | ||
@@ -16,0 +16,0 @@ }); |
@@ -6,3 +6,2 @@ 'use strict'; | ||
}); | ||
exports.default = ValidationError; | ||
@@ -13,2 +12,4 @@ var _stringify = require('babel-runtime/core-js/json/stringify'); | ||
exports.default = ValidationError; | ||
var _util = require('util'); | ||
@@ -15,0 +16,0 @@ |
{ | ||
"name": "objection", | ||
"version": "0.5.0-rc.1", | ||
"version": "0.5.0-rc.2", | ||
"description": "An SQL-friendly ORM for Node.js", | ||
@@ -9,5 +9,5 @@ "main": "lib/objection.js", | ||
"build": "node build", | ||
"test": "npm run build && istanbul --config=.istanbul.yml cover _mocha -- --slow 10 --timeout 5000 --reporter spec --recursive tests", | ||
"test": "npm run build && istanbul --config=.istanbul.yml cover _mocha -- --slow 10 --timeout 15000 --reporter spec --recursive tests", | ||
"perf": "mocha --slow 60000 --timeout 60000 --reporter spec --recursive perf", | ||
"test-bail": "mocha --slow 10 --timeout 5000 --reporter spec --recursive tests --bail", | ||
"test-bail": "mocha --slow 10 --timeout 15000 --reporter spec --recursive tests --bail", | ||
"coveralls": "cat ./testCoverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", | ||
@@ -47,7 +47,7 @@ "prepublish": "npm run build" | ||
"dependencies": { | ||
"babel-runtime": "^6.3.19", | ||
"bluebird": "^3.0.5", | ||
"lodash": "^3.9.0", | ||
"babel-runtime": "^6.6.1", | ||
"bluebird": "^3.3.4", | ||
"lodash": "^4.7.0", | ||
"tv4": "^1.1.9", | ||
"tv4-formats": "^1.0.0" | ||
"tv4-formats": "^1.0.2" | ||
}, | ||
@@ -58,12 +58,29 @@ "devDependencies": { | ||
"babel-plugin-transform-runtime": "^6.3.13", | ||
"babel-preset-es2015": "^6.3.13", | ||
"babel-preset-stage-0": "^6.3.13", | ||
"babel-plugin-transform-class-properties": "^6.3.13", | ||
"babel-plugin-transform-es2015-template-literals": "^6.3.13", | ||
"babel-plugin-transform-es2015-literals": "^6.3.13", | ||
"babel-plugin-transform-es2015-function-name": "^6.3.13", | ||
"babel-plugin-transform-es2015-arrow-functions": "^6.3.13", | ||
"babel-plugin-transform-es2015-block-scoped-functions": "^6.3.13", | ||
"babel-plugin-transform-es2015-classes": "^6.3.13", | ||
"babel-plugin-transform-es2015-shorthand-properties": "^6.3.13", | ||
"babel-plugin-transform-es2015-duplicate-keys": "^6.3.13", | ||
"babel-plugin-transform-es2015-computed-properties": "^6.3.13", | ||
"babel-plugin-transform-es2015-sticky-regex": "^6.3.13", | ||
"babel-plugin-transform-es2015-unicode-regex": "^6.3.13", | ||
"babel-plugin-check-es2015-constants": "^6.3.13", | ||
"babel-plugin-transform-es2015-spread": "^6.3.13", | ||
"babel-plugin-transform-es2015-parameters": "^6.3.13", | ||
"babel-plugin-transform-es2015-destructuring": "^6.3.13", | ||
"babel-plugin-transform-es2015-block-scoping": "^6.3.13", | ||
"babel-plugin-transform-es2015-typeof-symbol": "^6.3.13", | ||
"babel-plugin-transform-es2015-modules-commonjs": "^6.3.13", | ||
"coveralls": "^2.11.2", | ||
"expect.js": "^0.3.1", | ||
"fs-extra": "^0.26.4", | ||
"glob": "^6.0.1", | ||
"glob": "^7.0.3", | ||
"grunt": "^0.4.5", | ||
"grunt-jsdoc": "^1.0.0", | ||
"istanbul": "^0.4.0", | ||
"knex": "^0.9.0", | ||
"knex": "^0.10.0", | ||
"mocha": "^2.3.4", | ||
@@ -70,0 +87,0 @@ "mysql": "^2.7.0", |
@@ -6,2 +6,3 @@ import _ from 'lodash'; | ||
import RelationExpression from '../queryBuilder/RelationExpression'; | ||
import hiddenDataGetterSetter from '../utils/decorators/hiddenDataGetterSetter'; | ||
import ValidationError from '../ValidationError'; | ||
@@ -13,7 +14,12 @@ import EagerFetcher from '../queryBuilder/EagerFetcher'; | ||
import Relation from '../relations/Relation'; | ||
import HasOneRelation from '../relations/HasOneRelation'; | ||
import HasManyRelation from '../relations/HasManyRelation'; | ||
import BelongsToOneRelation from '../relations/BelongsToOneRelation'; | ||
import ManyToManyRelation from '../relations/ManyToManyRelation'; | ||
import HasOneRelation from '../relations/hasOne/HasOneRelation'; | ||
import HasManyRelation from '../relations/hasMany/HasManyRelation'; | ||
import ManyToManyRelation from '../relations/manyToMany/ManyToManyRelation'; | ||
import BelongsToOneRelation from '../relations/belongsToOne/BelongsToOneRelation'; | ||
import InstanceFindOperation from '../queryBuilder/operations/InstanceFindOperation'; | ||
import InstanceInsertOperation from '../queryBuilder/operations/InstanceInsertOperation'; | ||
import InstanceUpdateOperation from '../queryBuilder/operations/InstanceUpdateOperation'; | ||
import InstanceDeleteOperation from '../queryBuilder/operations/InstanceDeleteOperation'; | ||
export default class Model extends ModelBase { | ||
@@ -23,6 +29,7 @@ | ||
static RelatedQueryBuilder = QueryBuilder; | ||
static HasOneRelation = HasOneRelation; | ||
static BelongsToOneRelation = BelongsToOneRelation; | ||
static HasManyRelation = HasManyRelation; | ||
static ManyToManyRelation = ManyToManyRelation; | ||
static BelongsToOneRelation = BelongsToOneRelation; | ||
@@ -80,11 +87,6 @@ @deprecated({removedIn: '0.7.0', useInstead: 'BelongsToOneRelation'}) | ||
/** | ||
* @private | ||
*/ | ||
static $$relations = null; | ||
/** | ||
* @param {string|number|Array.<string|number>=} id | ||
* @returns {string|number|Array.<string|number>} | ||
*/ | ||
$id() { | ||
$id(id) { | ||
if (arguments.length > 0) { | ||
@@ -119,41 +121,21 @@ return setId(this, arguments[0]); | ||
.forClass(ModelClass) | ||
.findImpl((builder) => { | ||
builder.first(); | ||
builder.onBuild((builder) => { | ||
builder.whereComposite(ModelClass.getFullIdColumn(), this.$id()); | ||
}); | ||
.findOperationFactory(builder => { | ||
return new InstanceFindOperation(builder, 'find', {instance: this}); | ||
}) | ||
.insertImpl((insertion, builder) => { | ||
insertion.setData(this); | ||
builder.onBuild((builder) => { | ||
builder.$$insert(insertion); | ||
}); | ||
.insertOperationFactory(builder => { | ||
return new InstanceInsertOperation(builder, 'insert', {instance: this}); | ||
}) | ||
.updateImpl((update, builder) => { | ||
if (!update.model()) { | ||
update.setData(this); | ||
} | ||
builder.onBuild((builder) => { | ||
builder.$$update(update).whereComposite(ModelClass.getFullIdColumn(), this.$id()); | ||
}); | ||
.updateOperationFactory(builder => { | ||
return new InstanceUpdateOperation(builder, 'update', {instance: this}); | ||
}) | ||
.patchImpl((patch, builder) => { | ||
if (!patch.model()) { | ||
patch.setData(this); | ||
} | ||
builder.onBuild((builder) => { | ||
builder.$$update(patch).whereComposite(ModelClass.getFullIdColumn(), this.$id()); | ||
}); | ||
.patchOperationFactory(builder => { | ||
return new InstanceUpdateOperation(builder, 'patch', {instance: this, modelOptions: {patch: true}}); | ||
}) | ||
.deleteImpl((builder) => { | ||
builder.onBuild((builder) => { | ||
builder.$$delete().whereComposite(ModelClass.getFullIdColumn(), this.$id()); | ||
}); | ||
.deleteOperationFactory(builder => { | ||
return new InstanceDeleteOperation(builder, 'delete', {instance: this}); | ||
}) | ||
.relateImpl(() => { | ||
.relateOperationFactory(() => { | ||
throw new Error('`relate` makes no sense in this context'); | ||
}) | ||
.unrelateImpl(() => { | ||
.unrelateOperationFactory(() => { | ||
throw new Error('`unrelate` makes no sense in this context'); | ||
@@ -173,22 +155,22 @@ }); | ||
.forClass(ModelClass) | ||
.findImpl((builder) => { | ||
relation.find(builder, [this]); | ||
.findOperationFactory(builder => { | ||
return relation.find(builder, [this]); | ||
}) | ||
.insertImpl((insert, builder) => { | ||
relation.insert(builder, this, insert); | ||
.insertOperationFactory(builder => { | ||
return relation.insert(builder, this); | ||
}) | ||
.updateImpl((update, builder) => { | ||
relation.update(builder, this, update); | ||
.updateOperationFactory(builder => { | ||
return relation.update(builder, this); | ||
}) | ||
.patchImpl((patch, builder) => { | ||
relation.patch(builder, this, patch); | ||
.patchOperationFactory(builder => { | ||
return relation.patch(builder, this); | ||
}) | ||
.deleteImpl((builder) => { | ||
relation.delete(builder, this); | ||
.deleteOperationFactory(builder => { | ||
return relation.delete(builder, this); | ||
}) | ||
.relateImpl((ids, builder) => { | ||
relation.relate(builder, this, ids); | ||
.relateOperationFactory(builder => { | ||
return relation.relate(builder, this); | ||
}) | ||
.unrelateImpl((builder) => { | ||
relation.unrelate(builder, this); | ||
.unrelateOperationFactory(builder => { | ||
return relation.unrelate(builder, this); | ||
}); | ||
@@ -342,6 +324,6 @@ } | ||
.forClass(ModelClass) | ||
.relateImpl(() => { | ||
.relateOperationFactory(() => { | ||
throw new Error('`relate` makes no sense in this context'); | ||
}) | ||
.unrelateImpl(() => { | ||
.unrelateOperationFactory(() => { | ||
throw new Error('`unrelate` makes no sense in this context'); | ||
@@ -431,6 +413,7 @@ }); | ||
BoundModelClass.$$relations = _.reduce(ModelClass.getRelations(), (relations, relation, relationName) => { | ||
// Bind all relations also. | ||
BoundModelClass.relations(_.reduce(ModelClass.getRelations(), (relations, relation, relationName) => { | ||
relations[relationName] = relation.bindKnex(knex); | ||
return relations; | ||
}, Object.create(null)); | ||
}, Object.create(null))); | ||
@@ -495,12 +478,12 @@ return BoundModelClass; | ||
/** | ||
* @returns {number} | ||
* @returns {Array.<string>} | ||
*/ | ||
@memoize | ||
static getIdPropertyArray() { | ||
static getIdColumnArray() { | ||
let ModelClass = this; | ||
if (_.isArray(ModelClass.idColumn)) { | ||
return _.map(ModelClass.idColumn, col => idColumnToIdProperty(ModelClass, col)); | ||
return ModelClass.idColumn; | ||
} else { | ||
return [idColumnToIdProperty(ModelClass, ModelClass.idColumn)]; | ||
return [ModelClass.idColumn]; | ||
} | ||
@@ -510,2 +493,11 @@ } | ||
/** | ||
* @returns {Array.<string>} | ||
*/ | ||
@memoize | ||
static getIdPropertyArray() { | ||
let ModelClass = this; | ||
return _.map(ModelClass.getIdColumnArray(), col => idColumnToIdProperty(ModelClass, col)); | ||
} | ||
/** | ||
* @returns {string|Array.<string>} | ||
@@ -537,10 +529,17 @@ */ | ||
/** | ||
* @private | ||
*/ | ||
@hiddenDataGetterSetter('relations') | ||
static relations(relations) {} | ||
/** | ||
* @return {Object.<string, Relation>} | ||
*/ | ||
static getRelations() { | ||
const ModelClass = this; | ||
let relations = this.relations(); | ||
if (!this.$$relations) { | ||
// Lazy-load the relations to prevent require loops. | ||
this.$$relations = _.reduce(this.relationMappings, (relations, mapping, relationName) => { | ||
if (!relations) { | ||
const ModelClass = this; | ||
relations = _.reduce(this.relationMappings, (relations, mapping, relationName) => { | ||
relations[relationName] = new mapping.relation(relationName, ModelClass); | ||
@@ -550,5 +549,7 @@ relations[relationName].setMapping(mapping); | ||
}, Object.create(null)); | ||
this.relations(relations); | ||
} | ||
return this.$$relations; | ||
return relations; | ||
} | ||
@@ -628,10 +629,10 @@ | ||
if (types.length === 0 && _.isArray(prop.anyOf)) { | ||
types = _.flattenDeep(_.pluck(prop.anyOf, 'type')); | ||
types = _.flattenDeep(_.map(prop.anyOf, 'type')); | ||
} | ||
if (types.length === 0 && _.isArray(prop.oneOf)) { | ||
types = _.flattenDeep(_.pluck(prop.oneOf, 'type')); | ||
types = _.flattenDeep(_.map(prop.oneOf, 'type')); | ||
} | ||
if (_.contains(types, 'object') || _.contains(types, 'array')) { | ||
if (_.includes(types, 'object') || _.includes(types, 'array')) { | ||
this.jsonAttributes.push(propName); | ||
@@ -638,0 +639,0 @@ } |
@@ -5,2 +5,3 @@ import ModelBase from './model/ModelBase'; | ||
import QueryBuilder from './queryBuilder/QueryBuilder'; | ||
import QueryBuilderOperation from './queryBuilder/operations/QueryBuilderOperation' | ||
import RelationExpression from './queryBuilder/RelationExpression'; | ||
@@ -10,6 +11,6 @@ import ValidationError from './ValidationError'; | ||
import Relation from './relations/Relation'; | ||
import HasOneRelation from './relations/HasOneRelation'; | ||
import HasManyRelation from './relations/HasManyRelation'; | ||
import BelongsToOneRelation from './relations/BelongsToOneRelation'; | ||
import ManyToManyRelation from './relations/ManyToManyRelation'; | ||
import HasOneRelation from './relations/hasOne/HasOneRelation'; | ||
import HasManyRelation from './relations/hasMany/HasManyRelation'; | ||
import BelongsToOneRelation from './relations/belongsToOne/BelongsToOneRelation'; | ||
import ManyToManyRelation from './relations/manyToMany/ManyToManyRelation'; | ||
@@ -24,2 +25,3 @@ import transaction from './transaction'; | ||
QueryBuilderBase, | ||
QueryBuilderOperation, | ||
RelationExpression, | ||
@@ -26,0 +28,0 @@ ValidationError, |
@@ -54,4 +54,5 @@ import _ from 'lodash'; | ||
let queryBuilder = ModelClass.RelatedQueryBuilder.forClass(ModelClass).childQueryOf(this.rootQuery); | ||
let operation = relation.find(queryBuilder, this.models); | ||
relation.find(queryBuilder, this.models); | ||
queryBuilder.callQueryBuilderOperation(operation, []); | ||
@@ -58,0 +59,0 @@ _.each(nextEager.args, filterName => { |
import _ from 'lodash'; | ||
import Promise from 'bluebird'; | ||
import RelationExpression from './RelationExpression'; | ||
import ManyToManyRelation from '../relations/ManyToManyRelation'; | ||
import HasManyRelation from '../relations/HasManyRelation'; | ||
import BelongsToOneRelation from '../relations/BelongsToOneRelation'; | ||
import ManyToManyRelation from '../relations/manyToMany/ManyToManyRelation'; | ||
import HasManyRelation from '../relations/hasMany/HasManyRelation'; | ||
import BelongsToOneRelation from '../relations/belongsToOne/BelongsToOneRelation'; | ||
import ValidationError from '../ValidationError'; | ||
@@ -126,3 +126,3 @@ let Model; | ||
_markBatchHandled(batch) { | ||
let models = _.flatten(_.pluck(batch, 'models')); | ||
let models = _.flatten(_.map(batch, 'models')); | ||
let nodes = this.graph.nodesById; | ||
@@ -183,3 +183,3 @@ | ||
let keys = _.keys(tableInsertion.models[0]); | ||
tableInsertion.models = _.unique(tableInsertion.models, model => model.$values(keys).join()); | ||
tableInsertion.models = _.uniqBy(tableInsertion.models, model => model.$values(keys).join()); | ||
tableInsertion.isInputModel = _.times(tableInsertion.models.length, _.constant(false)); | ||
@@ -196,3 +196,3 @@ } | ||
_omitUids(tableInsertion) { | ||
let ids = _.pluck(tableInsertion.models, tableInsertion.modelClass.uidProp); | ||
let ids = _.map(tableInsertion.models, tableInsertion.modelClass.uidProp); | ||
@@ -199,0 +199,0 @@ for (let m = 0, lm = tableInsertion.models.length; m < lm; ++m) { |
import _ from 'lodash'; | ||
import Promise from 'bluebird'; | ||
import queryBuilderOperation from './decorators/queryBuilderOperation'; | ||
import QueryBuilderContext from './QueryBuilderContext'; | ||
import RelationExpression from './RelationExpression'; | ||
import InsertionOrUpdate from './InsertionOrUpdate'; | ||
import InsertWithRelated from './InsertWithRelated'; | ||
import QueryBuilderBase from './QueryBuilderBase'; | ||
import ValidationError from '../ValidationError'; | ||
import EagerFetcher from './EagerFetcher'; | ||
import {isPostgres} from '../utils/dbUtils'; | ||
import deprecated from '../utils/decorators/deprecated'; | ||
import DeleteOperation from './operations/DeleteOperation'; | ||
import UpdateOperation from './operations/UpdateOperation'; | ||
import InsertOperation from './operations/InsertOperation'; | ||
import InsertWithRelatedOperation from './operations/InsertWithRelatedOperation'; | ||
import InsertAndFetchOperation from './operations/InsertAndFetchOperation'; | ||
import UpdateAndFetchOperation from './operations/UpdateAndFetchOperation'; | ||
import QueryBuilderOperation from './operations/QueryBuilderOperation'; | ||
import JoinRelationOperation from './operations/JoinRelationOperation'; | ||
import RunBeforeOperation from './operations/RunBeforeOperation'; | ||
import RunAfterOperation from './operations/RunAfterOperation'; | ||
import OnBuildOperation from './operations/OnBuildOperation'; | ||
export default class QueryBuilder extends QueryBuilderBase { | ||
constructor(modelClass) { | ||
super(modelClass.knex()); | ||
super(modelClass.knex(), QueryBuilderContext); | ||
this._modelClass = modelClass; | ||
this._calledWriteMethod = null; | ||
this._explicitRejectValue = null; | ||
this._explicitResolveValue = null; | ||
this._hooks = null; | ||
this._customImpl = null; | ||
this._eagerExpression = null; | ||
@@ -31,8 +39,9 @@ this._eagerFilters = null; | ||
this.internalContext().runBefore = []; | ||
this.internalContext().runAfter = []; | ||
this.internalContext().onBuild = []; | ||
this.clearHooks(); | ||
this.clearCustomImpl(); | ||
this._findOperationFactory = builder => new QueryBuilderOperation(builder, 'find'); | ||
this._insertOperationFactory = builder => new InsertOperation(builder, 'insert'); | ||
this._updateOperationFactory = builder => new UpdateOperation(builder, 'update'); | ||
this._patchOperationFactory = builder => new UpdateOperation(builder, 'patch', {modelOptions: {patch: true}}); | ||
this._relateOperationFactory = builder => new QueryBuilderOperation(builder, 'relate'); | ||
this._unrelateOperationFactory = builder => new QueryBuilderOperation(builder, 'unrelate'); | ||
this._deleteOperationFactory = builder => new DeleteOperation(builder, 'delete'); | ||
} | ||
@@ -49,12 +58,4 @@ | ||
/** | ||
* @param {Object=} ctx | ||
* @returns {QueryBuilder|Object} | ||
*/ | ||
context(...args) { | ||
// This implementation is here just so that we can document it. | ||
return super.context(...args); | ||
} | ||
/** | ||
* @param {QueryBuilderBase} query | ||
* @returns {QueryBuilder} | ||
*/ | ||
@@ -64,7 +65,4 @@ childQueryOf(query) { | ||
this.internalContext(query.internalContext()); | ||
} | ||
if (query.has(/debug/)) { | ||
this.debug(); | ||
} | ||
} | ||
return this; | ||
@@ -95,3 +93,4 @@ } | ||
isExecutable() { | ||
return !this._explicitRejectValue && !this._explicitResolveValue && !this._hooks.executor; | ||
const hasExecutor = !!this._queryExecutorOperation(); | ||
return !this._explicitRejectValue && !this._explicitResolveValue && !hasExecutor; | ||
} | ||
@@ -103,71 +102,25 @@ | ||
*/ | ||
runBefore(runBefore) { | ||
this._hooks.before.push(runBefore); | ||
return this; | ||
} | ||
@queryBuilderOperation(RunBeforeOperation) | ||
runBefore(runBefore) {} | ||
/** | ||
* @param {function(*, QueryBuilder)} runBefore | ||
* @returns {QueryBuilder} | ||
*/ | ||
runBeforePushFront(runBefore) { | ||
this._hooks.before.unshift(runBefore); | ||
return this; | ||
} | ||
/** | ||
* @param {function(QueryBuilder)} onBuild | ||
* @returns {QueryBuilder} | ||
*/ | ||
onBuild(onBuild) { | ||
this._hooks.onBuild.push(onBuild); | ||
return this; | ||
} | ||
@queryBuilderOperation(OnBuildOperation) | ||
onBuild(onBuild) {} | ||
/** | ||
* @param {function(QueryBuilder)} executor | ||
* @returns {QueryBuilder} | ||
*/ | ||
setQueryExecutor(executor) { | ||
if (this._hooks.executor) { | ||
throw Error('overwriting an executor. you should not do this.'); | ||
} | ||
this._hooks.executor = executor; | ||
return this; | ||
} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfterModelCreate | ||
* @returns {QueryBuilder} | ||
*/ | ||
runAfterModelCreate(runAfterModelCreate) { | ||
this._hooks.afterModelCreate.push(runAfterModelCreate); | ||
return this; | ||
} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfterModelCreate | ||
* @returns {QueryBuilder} | ||
*/ | ||
runAfterModelCreatePushFront(runAfterModelCreate) { | ||
this._hooks.afterModelCreate.unshift(runAfterModelCreate); | ||
return this; | ||
} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfter | ||
* @returns {QueryBuilder} | ||
*/ | ||
runAfter(runAfter) { | ||
this._hooks.after.push(runAfter); | ||
return this; | ||
} | ||
@queryBuilderOperation(RunAfterOperation) | ||
runAfter(runAfter) {} | ||
/** | ||
* @param {function(Model|Array.<Model>, QueryBuilder)} runAfter | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
runAfterPushFront(runAfter) { | ||
this._hooks.after.unshift(runAfter); | ||
findOperationFactory(factory) { | ||
this._findOperationFactory = factory; | ||
return this; | ||
@@ -177,6 +130,7 @@ } | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
findImpl(findImpl) { | ||
this._customImpl.find = findImpl || null; | ||
insertOperationFactory(factory) { | ||
this._insertOperationFactory = factory; | ||
return this; | ||
@@ -186,6 +140,7 @@ } | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
insertImpl(insertImpl) { | ||
this._customImpl.insert = insertImpl || null; | ||
updateOperationFactory(factory) { | ||
this._updateOperationFactory = factory; | ||
return this; | ||
@@ -195,6 +150,7 @@ } | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
updateImpl(updateImpl) { | ||
this._customImpl.update = updateImpl || null; | ||
patchOperationFactory(factory) { | ||
this._patchOperationFactory = factory; | ||
return this; | ||
@@ -204,6 +160,7 @@ } | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
patchImpl(patchImpl) { | ||
this._customImpl.patch = patchImpl || null; | ||
deleteOperationFactory(factory) { | ||
this._deleteOperationFactory = factory; | ||
return this; | ||
@@ -213,6 +170,7 @@ } | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
deleteImpl(deleteImpl) { | ||
this._customImpl.delete = deleteImpl || null; | ||
relateOperationFactory(factory) { | ||
this._relateOperationFactory = factory; | ||
return this; | ||
@@ -222,6 +180,7 @@ } | ||
/** | ||
* @param {function(QueryBuilder):QueryBuilderOperation} factory | ||
* @returns {QueryBuilder} | ||
*/ | ||
relateImpl(relateImpl) { | ||
this._customImpl.relate = relateImpl || null; | ||
unrelateOperationFactory(factory) { | ||
this._unrelateOperationFactory = factory; | ||
return this; | ||
@@ -231,10 +190,2 @@ } | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
unrelateImpl(unrelateImpl) { | ||
this._customImpl.unrelate = unrelateImpl || null; | ||
return this; | ||
} | ||
/** | ||
* @param {string|RelationExpression} exp | ||
@@ -300,3 +251,3 @@ * @param {Object.<string, function(QueryBuilder)>=} filters | ||
/** | ||
* @returns {Model} | ||
* @returns {Constructor.<Model>} | ||
*/ | ||
@@ -311,3 +262,3 @@ modelClass() { | ||
isFindQuery() { | ||
return !this._calledWriteMethod && !this.has(/insert|update|delete/); | ||
return !_.some(this._operations, method => method.isWriteOperation) && !this._explicitRejectValue; | ||
} | ||
@@ -343,25 +294,8 @@ | ||
clone() { | ||
let builder = new this.constructor(this._modelClass); | ||
// This is a QueryBuilderBase method. | ||
this.cloneInto(builder); | ||
const builder = new this.constructor(this._modelClass); | ||
this.baseCloneInto(builder); | ||
let builderIntCtx = builder.internalContext(); | ||
let intCtx = this.internalContext(); | ||
builderIntCtx.runBefore = intCtx.runBefore.slice(); | ||
builderIntCtx.runAfter = intCtx.runAfter.slice(); | ||
builderIntCtx.onBuild = intCtx.onBuild.slice(); | ||
builder._calledWriteMethod = this._calledWriteMethod; | ||
builder._explicitRejectValue = this._explicitRejectValue; | ||
builder._explicitResolveValue = this._explicitResolveValue; | ||
_.forEach(this._hooks, (funcs, key) => { | ||
builder._hooks[key] = _.isArray(funcs) ? funcs.slice() : funcs; | ||
}); | ||
_.forEach(this._customImpl, (impl, key) => { | ||
builder._customImpl[key] = impl; | ||
}); | ||
builder._eagerExpression = this._eagerExpression; | ||
@@ -373,2 +307,10 @@ builder._eagerFilters = this._eagerFilters; | ||
builder._findOperationFactory = this._findOperationFactory; | ||
builder._insertOperationFactory = this._insertOperationFactory; | ||
builder._updateOperationFactory = this._updateOperationFactory; | ||
builder._patchOperationFactory = this._patchOperationFactory; | ||
builder._relateOperationFactory = this._relateOperationFactory; | ||
builder._unrelateOperationFactory = this._unrelateOperationFactory; | ||
builder._deleteOperationFactory = this._deleteOperationFactory; | ||
return builder; | ||
@@ -380,50 +322,2 @@ } | ||
*/ | ||
clearCustomImpl() { | ||
this._customImpl = { | ||
find() {}, | ||
relate() {}, | ||
unrelate() {}, | ||
insert(insert, builder) { | ||
builder.onBuild(builder => { | ||
builder.$$insert(insert); | ||
}); | ||
}, | ||
update(update, builder) { | ||
builder.onBuild(builder => { | ||
builder.$$update(update); | ||
}); | ||
}, | ||
patch(patch, builder) { | ||
builder.onBuild(builder => { | ||
builder.$$update(patch); | ||
}); | ||
}, | ||
delete(builder) { | ||
builder.onBuild(builder => { | ||
builder.$$delete(); | ||
}); | ||
} | ||
}; | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
clearHooks() { | ||
this._hooks = { | ||
before: [], | ||
onBuild: [], | ||
executor: null, | ||
afterModelCreate: [], | ||
after: [] | ||
}; | ||
return this; | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
clearEager() { | ||
@@ -452,29 +346,2 @@ this._eagerExpression = null; | ||
/** | ||
* @param {RegExp=} regex | ||
* @returns {QueryBuilder} | ||
*/ | ||
clear(regex) { | ||
super.clear(regex); | ||
if (regex) { | ||
// Clear the write method call also if it doesn't pass the filter. | ||
if (regex.test(this._calledWriteMethod)) { | ||
this._calledWriteMethod = null; | ||
} | ||
} else { | ||
this._calledWriteMethod = null; | ||
} | ||
return this; | ||
} | ||
/** | ||
* @param {RegExp} methodNameRegex | ||
* @returns {boolean} | ||
*/ | ||
has(methodNameRegex) { | ||
return super.has(methodNameRegex) || methodNameRegex.test(this._calledWriteMethod); | ||
} | ||
/** | ||
* @param {function=} successHandler | ||
@@ -484,3 +351,3 @@ * @param {function=} errorHandler | ||
*/ | ||
then() { | ||
then(successHandler, errorHandler) { | ||
var promise = this._execute(); | ||
@@ -494,3 +361,3 @@ return promise.then.apply(promise, arguments); | ||
*/ | ||
map() { | ||
map(mapper) { | ||
var promise = this._execute(); | ||
@@ -504,3 +371,3 @@ return promise.map.apply(promise, arguments); | ||
*/ | ||
catch() { | ||
catch(errorHandler) { | ||
var promise = this._execute(); | ||
@@ -514,3 +381,3 @@ return promise.catch.apply(promise, arguments); | ||
*/ | ||
return() { | ||
return(returnValue) { | ||
var promise = this._execute(); | ||
@@ -524,3 +391,3 @@ return promise.return.apply(promise, arguments); | ||
*/ | ||
bind() { | ||
bind(context) { | ||
var promise = this._execute(); | ||
@@ -534,3 +401,3 @@ return promise.bind.apply(promise, arguments); | ||
*/ | ||
asCallback() { | ||
asCallback(callback) { | ||
var promise = this._execute(); | ||
@@ -544,3 +411,3 @@ return promise.asCallback.apply(promise, arguments); | ||
*/ | ||
nodeify(/*callback*/) { | ||
nodeify(callback) { | ||
var promise = this._execute(); | ||
@@ -580,3 +447,2 @@ return promise.nodeify.apply(promise, arguments); | ||
range(start, end) { | ||
const self = this; | ||
let resultSizePromise; | ||
@@ -590,3 +456,3 @@ | ||
// in parallel with the actual query. | ||
resultSizePromise = self.resultSize(); | ||
resultSizePromise = this.resultSize(); | ||
}) | ||
@@ -610,17 +476,19 @@ .runAfter(results => { | ||
build() { | ||
// Take a clone so that we don't modify this instance during build. | ||
let builder = this.clone(); | ||
if (builder.isFindQuery()) { | ||
// If no write methods have been called at this point this query is a | ||
// If no write operations have been called at this point this query is a | ||
// find query and we need to call the custom find implementation. | ||
builder._customImpl.find.call(builder, builder); | ||
builder._callFindOperation(); | ||
} | ||
// We need to build the builder even if the _hooks.executor function | ||
// has been defined so that the onBuild hooks get called. | ||
// We need to build the builder even if a query executor operation | ||
// has been called so that the onBuild hooks get called. | ||
let knexBuilder = build(builder); | ||
let queryExecutorOperation = builder._queryExecutorOperation(); | ||
if (_.isFunction(builder._hooks.executor)) { | ||
if (queryExecutorOperation) { | ||
// If the query executor is set, we build the builder that it returns. | ||
return builder._hooks.executor.call(builder, builder).build(); | ||
return queryExecutorOperation.queryExecutor(builder).build(); | ||
} else { | ||
@@ -632,2 +500,24 @@ return knexBuilder; | ||
/** | ||
* @private | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
_queryExecutorOperation() { | ||
let executors = _.filter(this._operations, method => method.hasQueryExecutor()); | ||
if (executors.length > 1) { | ||
throw new Error('there can only be one method call that implements queryExecutor()'); | ||
} | ||
return executors[0]; | ||
} | ||
/** | ||
* @private | ||
*/ | ||
_callFindOperation() { | ||
this.callQueryBuilderOperation(this._findOperationFactory(this), []); | ||
} | ||
/** | ||
* @private | ||
* @returns {Promise} | ||
@@ -637,4 +527,2 @@ */ | ||
// Take a clone so that we don't modify this instance during execution. | ||
// The hooks and onBuild callbacks usually modify the query and we want | ||
// this builder to be re-executable. | ||
let builder = this.clone(); | ||
@@ -646,10 +534,11 @@ let promise = Promise.resolve(); | ||
if (builder.isFindQuery()) { | ||
// If no write methods have been called at this point this query is a | ||
// If no write operations have been called at this point this query is a | ||
// find query and we need to call the custom find implementation. | ||
builder._customImpl.find.call(builder, builder); | ||
builder._callFindOperation(); | ||
} | ||
promise = chainBuilderFuncs(promise, builder, context.runBefore); | ||
promise = chainBuilderFuncs(promise, builder, internalContext.runBefore); | ||
promise = chainBuilderFuncs(promise, builder, builder._hooks.before); | ||
promise = chainBeforeOperations(promise, builder, builder._operations); | ||
promise = chainHooks(promise, builder, context.runBefore); | ||
promise = chainHooks(promise, builder, internalContext.runBefore); | ||
promise = chainBeforeInternalOperations(promise, builder, builder._operations); | ||
@@ -662,10 +551,11 @@ // Resolve all before hooks before building and executing the query | ||
let knexBuilder = build(builder); | ||
let queryExecutorOperation = builder._queryExecutorOperation(); | ||
let promise; | ||
if (builder._explicitResolveValue) { | ||
if (builder._explicitRejectValue) { | ||
promise = Promise.reject(builder._explicitRejectValue); | ||
} else if (builder._explicitResolveValue) { | ||
promise = Promise.resolve(builder._explicitResolveValue); | ||
} else if (builder._explicitRejectValue) { | ||
promise = Promise.reject(builder._explicitRejectValue); | ||
} else if (_.isFunction(builder._hooks.executor)) { | ||
promise = builder._hooks.executor.call(builder, builder); | ||
} else if (queryExecutorOperation) { | ||
promise = queryExecutorOperation.queryExecutor(builder); | ||
} else { | ||
@@ -675,3 +565,4 @@ promise = knexBuilder.then(result => createModels(builder, result)); | ||
promise = chainBuilderFuncs(promise, builder, builder._hooks.afterModelCreate); | ||
promise = chainAfterQueryOperations(promise, builder, builder._operations); | ||
promise = chainAfterIntenralOperations(promise, builder, builder._operations); | ||
@@ -682,5 +573,5 @@ if (builder._eagerExpression) { | ||
promise = chainBuilderFuncs(promise, builder, context.runAfter); | ||
promise = chainBuilderFuncs(promise, builder, internalContext.runAfter); | ||
promise = chainBuilderFuncs(promise, builder, builder._hooks.after); | ||
promise = chainHooks(promise, builder, context.runAfter); | ||
promise = chainHooks(promise, builder, internalContext.runAfter); | ||
promise = chainAfterOperations(promise, builder, builder._operations); | ||
@@ -698,3 +589,3 @@ return promise; | ||
if (_.isArray(result)) { | ||
return _.pluck(result, propertyName); | ||
return _.map(result, propertyName); | ||
} else { | ||
@@ -725,4 +616,2 @@ return result; | ||
traverse(modelClass, traverser) { | ||
var self = this; | ||
if (_.isUndefined(traverser)) { | ||
@@ -734,3 +623,3 @@ traverser = modelClass; | ||
return this.runAfter(result => { | ||
self._modelClass.traverse(modelClass, result, traverser); | ||
this._modelClass.traverse(modelClass, result, traverser); | ||
return result; | ||
@@ -787,5 +676,4 @@ }); | ||
*/ | ||
joinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'join'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'join'}]) | ||
joinRelation(relationName) {} | ||
@@ -796,5 +684,4 @@ /** | ||
*/ | ||
innerJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'innerJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'innerJoin'}]) | ||
innerJoinRelation(relationName) {} | ||
@@ -805,5 +692,4 @@ /** | ||
*/ | ||
outerJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'outerJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'outerJoin'}]) | ||
outerJoinRelation(relationName) {} | ||
@@ -814,5 +700,4 @@ /** | ||
*/ | ||
leftJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'leftJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'leftJoin'}]) | ||
leftJoinRelation(relationName) {} | ||
@@ -823,5 +708,4 @@ /** | ||
*/ | ||
leftOuterJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'leftOuterJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'leftOuterJoin'}]) | ||
leftOuterJoinRelation(relationName) {} | ||
@@ -832,5 +716,4 @@ /** | ||
*/ | ||
rightJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'rightJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'rightJoin'}]) | ||
rightJoinRelation(relationName) {} | ||
@@ -841,5 +724,4 @@ /** | ||
*/ | ||
rightOuterJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'rightOuterJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'rightOuterJoin'}]) | ||
rightOuterJoinRelation(relationName) {} | ||
@@ -850,16 +732,6 @@ /** | ||
*/ | ||
fullOuterJoinRelation(relationName) { | ||
return this.$$joinRelation(relationName, 'fullOuterJoin'); | ||
} | ||
@queryBuilderOperation([JoinRelationOperation, {joinOperation: 'fullOuterJoin'}]) | ||
fullOuterJoinRelation(relationName) {} | ||
/** | ||
* @private | ||
*/ | ||
$$joinRelation(relationName, joinMethod) { | ||
let relation = this._modelClass.getRelation(relationName); | ||
relation.join(this, joinMethod, relation.name); | ||
return this; | ||
} | ||
/** | ||
* @param {string|number|Array.<string|number>} id | ||
@@ -876,6 +748,5 @@ * @returns {QueryBuilder} | ||
withSchema(schema) { | ||
this.internalContext().onBuild.push((builder) => { | ||
this.internalContext().onBuild.push(builder => { | ||
if (!builder.has(/withSchema/)) { | ||
// If the builder already has a schema, don't override it. | ||
builder.callKnexMethod('withSchema', [schema]); | ||
builder.callKnexQueryBuilderOperation('withSchema', [schema]); | ||
} | ||
@@ -888,69 +759,9 @@ }); | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
@writeQueryMethod | ||
insert(modelsOrObjects) { | ||
const ModelClass = this._modelClass; | ||
let insertion = new InsertionOrUpdate({ | ||
ModelClass, | ||
modelsOrObjects | ||
debug() { | ||
this.internalContext().onBuild.push(builder => { | ||
builder.callKnexQueryBuilderOperation('debug', []); | ||
}); | ||
this.$$callWriteMethodImpl('insert', [insertion, this]); | ||
this.runBefore((result, builder) => { | ||
if (insertion.models().length > 1 && !isPostgres(ModelClass.knex())) { | ||
throw new Error('batch insert only works with Postgresql'); | ||
} else { | ||
return Promise.map(insertion.models(), model => model.$beforeInsert(builder.context())); | ||
} | ||
}); | ||
this.onBuild(builder => { | ||
if (!builder.has(/returning/)) { | ||
// If the user hasn't specified a `returning` clause, we make sure | ||
// that at least the identifier is returned. | ||
builder.returning(ModelClass.idColumn); | ||
} | ||
}); | ||
this.runAfterModelCreatePushFront(ret => { | ||
if (!_.isArray(ret) || _.isEmpty(ret)) { | ||
// Early exit if there is nothing to do. | ||
return insertion.models(); | ||
} | ||
// If the user specified a `returning` clause the result may already bean array of objects. | ||
if (_.all(ret, _.isObject)) { | ||
_.forEach(insertion.models(), (model, index) => { | ||
model.$set(ret[index]); | ||
}); | ||
} else { | ||
// If the return value is not an array of objects, we assume it is an array of identifiers. | ||
_.forEach(insertion.models(), (model, idx) => { | ||
// Don't set the id if the model already has one. MySQL and Sqlite don't return the correct | ||
// primary key value if the id is not generated in db, but given explicitly. | ||
if (!model.$id()) { | ||
model.$id(ret[idx]); | ||
} | ||
}); | ||
} | ||
return insertion.models(); | ||
}); | ||
this.runAfterModelCreate((models, builder) => { | ||
return Promise.map(models, model => { | ||
return model.$afterInsert(builder.context()); | ||
}).then(() => { | ||
if (insertion.isArray()) { | ||
return models; | ||
} else { | ||
return models[0] || null; | ||
} | ||
}); | ||
}); | ||
return this; | ||
@@ -963,24 +774,6 @@ } | ||
*/ | ||
insertAndFetch(modelsOrObjects) { | ||
const ModelClass = this._modelClass; | ||
return this.insert(modelsOrObjects).runAfterModelCreate((insertedModels, builder) => { | ||
let insertedModelArray = _.isArray(insertedModels) ? insertedModels : [insertedModels]; | ||
return ModelClass | ||
.query() | ||
.childQueryOf(builder) | ||
.whereInComposite(ModelClass.getFullIdColumn(), _.map(insertedModelArray, model => model.$id())) | ||
.then(fetchedModels => { | ||
fetchedModels = _.indexBy(fetchedModels, (model) => model.$id()); | ||
// Instead of returning the freshly fetched models, update the input | ||
// models with the fresh values. | ||
_.forEach(insertedModelArray, insertedModel => { | ||
insertedModel.$set(fetchedModels[insertedModel.$id()]); | ||
}); | ||
return insertedModels; | ||
}); | ||
}); | ||
@writeQueryOperation | ||
insert(modelsOrObjects) { | ||
const insertOperation = this._insertOperationFactory(this); | ||
return this.callQueryBuilderOperation(insertOperation, [modelsOrObjects]); | ||
} | ||
@@ -992,84 +785,22 @@ | ||
*/ | ||
@writeQueryMethod | ||
insertWithRelated(modelsOrObjects) { | ||
const ModelClass = this._modelClass; | ||
const batchSize = isPostgres(ModelClass.knex()) ? 100 : 1; | ||
let insertion = new InsertionOrUpdate({ | ||
ModelClass, | ||
modelsOrObjects, | ||
// We need to skip validation at this point because the models may contain | ||
// references and special properties. We validate the models upon insertion. | ||
modelOptions: {skipValidation: true} | ||
@writeQueryOperation | ||
insertAndFetch(modelsOrObjects) { | ||
const insertAndFetchOperation = new InsertAndFetchOperation(this, 'insertAndFetch', { | ||
delegate: this._insertOperationFactory(this) | ||
}); | ||
this.$$callWriteMethodImpl('insert', [insertion, this]); | ||
// We resolve this query here and will not execute it. This is because the root | ||
// value may depend on other models in the graph and cannot be inserted first. | ||
this.resolve([]); | ||
this.runAfterModelCreatePushFront((result, builder) => { | ||
let inserter = new InsertWithRelated({ | ||
modelClass: ModelClass, | ||
models: insertion.models(), | ||
allowedRelations: builder._allowedInsertExpression || null | ||
}); | ||
return inserter.execute(tableInsertion => { | ||
let insertQuery = tableInsertion.modelClass.query().childQueryOf(builder); | ||
// We skipped the validation above. We need to validate here since at this point | ||
// the models should no longer contain any special properties. | ||
_.forEach(tableInsertion.models, model => { | ||
model.$validate(); | ||
}); | ||
let inputs = _.filter(tableInsertion.models, (model, idx) => { | ||
return tableInsertion.isInputModel[idx]; | ||
}); | ||
let others = _.filter(tableInsertion.models, (model, idx) => { | ||
return !tableInsertion.isInputModel[idx]; | ||
}); | ||
return Promise.all(_.flatten([ | ||
batchInsert(inputs, insertQuery.clone().copyFrom(builder, /returning/), batchSize), | ||
batchInsert(others, insertQuery.clone(), batchSize) | ||
])); | ||
}); | ||
}); | ||
this.runAfterModelCreate(models => { | ||
if (insertion.isArray()) { | ||
return models | ||
} else { | ||
return _.first(models) || null; | ||
} | ||
}); | ||
return this.callQueryBuilderOperation(insertAndFetchOperation, [modelsOrObjects]); | ||
} | ||
/** | ||
* @param {Object|Model|Array.<Object>|Array.<Model>} modelsOrObjects | ||
* @returns {QueryBuilder} | ||
*/ | ||
$$insert(insertion) { | ||
let input = insertion; | ||
@writeQueryOperation | ||
insertWithRelated(modelsOrObjects) { | ||
const insertWithRelatedOperation = new InsertWithRelatedOperation(this, 'insertWithRelated', { | ||
delegate: this._insertOperationFactory(this) | ||
}); | ||
if (insertion instanceof InsertionOrUpdate) { | ||
insertion = insertion.models(); | ||
} | ||
if (_.isArray(insertion)) { | ||
input = _.map(insertion, obj => { | ||
if (_.isFunction(obj.$toDatabaseJson)) { | ||
return obj.$toDatabaseJson(); | ||
} else { | ||
return obj; | ||
} | ||
}); | ||
} else if (_.isFunction(insertion.$toDatabaseJson)) { | ||
input = insertion.$toDatabaseJson(); | ||
} | ||
return super.insert(input); | ||
return this.callQueryBuilderOperation(insertWithRelatedOperation, [modelsOrObjects]); | ||
} | ||
@@ -1081,4 +812,6 @@ | ||
*/ | ||
@writeQueryOperation | ||
update(modelOrObject) { | ||
return this.$$updateWithOptions(modelOrObject, 'update', {}); | ||
const updateOperation = this._updateOperationFactory(this); | ||
return this.callQueryBuilderOperation(updateOperation, [modelOrObject]); | ||
} | ||
@@ -1091,85 +824,19 @@ | ||
*/ | ||
@writeQueryOperation | ||
updateAndFetchById(id, modelOrObject) { | ||
return this | ||
.$$updateWithOptions(modelOrObject, 'update', {}, id) | ||
.whereComposite(this._modelClass.getFullIdColumn(), id); | ||
} | ||
/** | ||
* @private | ||
*/ | ||
@writeQueryMethod | ||
$$updateWithOptions(modelOrObject, method, modelOptions, fetchId) { | ||
const ModelClass = this._modelClass; | ||
let update = new InsertionOrUpdate({ | ||
ModelClass, | ||
modelOptions, | ||
modelsOrObjects: modelOrObject | ||
const updateAndFetch = new UpdateAndFetchOperation(this, 'updateAndFetch', { | ||
delegate: this._updateOperationFactory(this) | ||
}); | ||
this.$$callWriteMethodImpl(method, [update, this]); | ||
this.runBefore((result, builder) => { | ||
return update.model().$beforeUpdate(modelOptions, builder.context()); | ||
}); | ||
this.runAfterModelCreate((numUpdated, builder) => { | ||
let promise; | ||
if (fetchId) { | ||
promise = ModelClass | ||
.query() | ||
.first() | ||
.childQueryOf(builder) | ||
.whereComposite(ModelClass.getFullIdColumn(), fetchId) | ||
.then(model => model ? update.model().$set(model) : null); | ||
} else { | ||
promise = Promise.resolve(numUpdated); | ||
} | ||
return promise.then(result => { | ||
return [result, update.model().$afterUpdate(modelOptions, builder.context())]; | ||
}).spread(function (result) { | ||
return result; | ||
}); | ||
}); | ||
return this; | ||
return this.callQueryBuilderOperation(updateAndFetch, [id, modelOrObject]); | ||
} | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
$$update(update) { | ||
let input = update; | ||
let idColumn = this._modelClass.idColumn; | ||
if (update instanceof InsertionOrUpdate) { | ||
update = update.model(); | ||
} | ||
if (_.isFunction(update.$toDatabaseJson)) { | ||
input = update.$toDatabaseJson(); | ||
} | ||
// We never want to update the identifier. | ||
// TODO: Maybe we do? | ||
if (_.isArray(idColumn)) { | ||
_.each(idColumn, col => { | ||
delete input[col] | ||
}); | ||
} else { | ||
delete input[idColumn]; | ||
} | ||
return super.update(input); | ||
} | ||
/** | ||
* @param {Model|Object=} modelOrObject | ||
* @returns {QueryBuilder} | ||
*/ | ||
@writeQueryOperation | ||
patch(modelOrObject) { | ||
return this.$$updateWithOptions(modelOrObject, 'patch', {patch: true}); | ||
const patchOperation = this._patchOperationFactory(this); | ||
return this.callQueryBuilderOperation(patchOperation, [modelOrObject]); | ||
} | ||
@@ -1182,6 +849,9 @@ | ||
*/ | ||
@writeQueryOperation | ||
patchAndFetchById(id, modelOrObject) { | ||
return this | ||
.$$updateWithOptions(modelOrObject, 'patch', {patch: true}, id) | ||
.whereComposite(this._modelClass.getFullIdColumn(), id); | ||
const patchAndFetch = new UpdateAndFetchOperation(this, 'patchAndFetch', { | ||
delegate: this._patchOperationFactory(this) | ||
}); | ||
return this.callQueryBuilderOperation(patchAndFetch, [id, modelOrObject]); | ||
} | ||
@@ -1192,6 +862,6 @@ | ||
*/ | ||
@writeQueryMethod | ||
@writeQueryOperation | ||
delete() { | ||
this.$$callWriteMethodImpl('delete', [this]); | ||
return this; | ||
const deleteOperation = this._deleteOperationFactory(this); | ||
return this.callQueryBuilderOperation(deleteOperation, []); | ||
} | ||
@@ -1215,16 +885,9 @@ | ||
/** | ||
* @returns {QueryBuilder} | ||
*/ | ||
$$delete() { | ||
return super.delete(); | ||
} | ||
/** | ||
* @param {number|string|object|Array.<number|string>|Array.<Array.<number|string>>|Array.<object>} ids | ||
* @returns {QueryBuilder} | ||
*/ | ||
@writeQueryMethod | ||
@writeQueryOperation | ||
relate(ids) { | ||
this.$$callWriteMethodImpl('relate', [ids, this]); | ||
return this.runAfterModelCreate(() => ids); | ||
const relateOperation = this._relateOperationFactory(this); | ||
return this.callQueryBuilderOperation(relateOperation, [ids]); | ||
} | ||
@@ -1235,7 +898,6 @@ | ||
*/ | ||
@writeQueryMethod | ||
@writeQueryOperation | ||
unrelate() { | ||
this.$$callWriteMethodImpl('unrelate', [this]); | ||
this.runAfterModelCreate(() => { return {}; }); | ||
return this; | ||
const unrelateOperation = this._unrelateOperationFactory(this); | ||
return this.callQueryBuilderOperation(unrelateOperation, []); | ||
} | ||
@@ -1262,24 +924,13 @@ | ||
} | ||
/** | ||
* @private | ||
*/ | ||
$$callWriteMethodImpl(method, args) { | ||
this._calledWriteMethod = 'method'; | ||
return this._customImpl[method].apply(this, args); | ||
} | ||
} | ||
function writeQueryMethod(target, property, descriptor) { | ||
descriptor.value = tryCallWriteMethod(descriptor.value); | ||
} | ||
function writeQueryOperation(target, property, descriptor) { | ||
const func = descriptor.value; | ||
function tryCallWriteMethod(func) { | ||
return function () { | ||
if (this._calledWriteMethod) { | ||
this.reject(new Error('Double call to a write method. ' + | ||
descriptor.value = function decorator$writeQueryOperation() { | ||
if (!this.isFindQuery()) { | ||
return this.reject(new Error('Double call to a write method. ' + | ||
'You can only call one of the write methods ' + | ||
'(insert, update, patch, delete, relate, unrelate, increment, decrement) ' + | ||
'and only once per query builder.')); | ||
return this; | ||
} | ||
@@ -1355,22 +1006,16 @@ | ||
let internalContext = builder.internalContext(); | ||
let knexBuilder = builder.knex().queryBuilder(); | ||
if (!builder.has(/from|table|into/)) { | ||
// Set the table only if it hasn't been explicitly set yet. | ||
builder.table(builder._modelClass.tableName); | ||
builder.table(builder.modelClass().tableName); | ||
} | ||
callBuilderFuncs(builder, context.onBuild); | ||
callBuilderFuncs(builder, internalContext.onBuild); | ||
callBuilderFuncs(builder, builder._hooks.onBuild); | ||
callOnBuildHooks(builder, context.onBuild); | ||
callOnBuildHooks(builder, internalContext.onBuild); | ||
// noinspection JSUnresolvedVariable | ||
return QueryBuilderBase.prototype.build.call(builder); | ||
return builder.buildInto(knexBuilder); | ||
} | ||
function batchInsert(models, queryBuilder, batchSize) { | ||
let batches = _.chunk(models, batchSize); | ||
return _.map(batches, batch => queryBuilder.clone().insert(batch)); | ||
} | ||
function callBuilderFuncs(builder, func) { | ||
function callOnBuildHooks(builder, func) { | ||
if (_.isFunction(func)) { | ||
@@ -1385,3 +1030,3 @@ func.call(builder, builder); | ||
function chainBuilderFuncs(promise, builder, func) { | ||
function chainHooks(promise, builder, func) { | ||
if (_.isFunction(func)) { | ||
@@ -1396,2 +1041,56 @@ promise = promise.then(result => func.call(builder, result, builder)); | ||
return promise; | ||
} | ||
function chainBeforeOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, (res, method) => { | ||
return method.onBefore(builder, res); | ||
}, method => { | ||
return method.hasOnBefore(); | ||
}); | ||
} | ||
function chainBeforeInternalOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, (res, method) => { | ||
return method.onBeforeInternal(builder, res); | ||
}, method => { | ||
return method.hasOnBeforeInternal(); | ||
}); | ||
} | ||
function chainAfterQueryOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, (res, method) => { | ||
return method.onAfterQuery(builder, res); | ||
}, method => { | ||
return method.hasOnAfterQuery(); | ||
}); | ||
} | ||
function chainAfterOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, (res, method) => { | ||
return method.onAfter(builder, res); | ||
}, method => { | ||
return method.hasOnAfter(); | ||
}); | ||
} | ||
function chainAfterIntenralOperations(promise, builder, methods) { | ||
return promiseChain(promise, methods, (res, method) => { | ||
return method.onAfterInternal(builder, res); | ||
}, method => { | ||
return method.hasOnAfterInternal(); | ||
}); | ||
} | ||
function promiseChain(promise, items, call, has) { | ||
_.each(items, item => { | ||
if (!has(item)) { | ||
return; | ||
} | ||
promise = promise.then(res => { | ||
return call(res, item); | ||
}); | ||
}); | ||
return promise; | ||
} |
import _ from 'lodash'; | ||
import jsonFieldExpressionParser from './parsers/jsonFieldExpressionParser'; | ||
import queryBuilderOperation from './decorators/queryBuilderOperation'; | ||
import {inherits} from '../utils/classUtils'; | ||
import {isKnexQueryBuilder, overwriteForDatabase} from '../utils/dbUtils'; | ||
import QueryBuilderContextBase from './QueryBuilderContextBase'; | ||
import KnexOperation from './operations/KnexOperation'; | ||
import WhereRefOperation from './operations/WhereRefOperation'; | ||
import WhereCompositeOperation from './operations/WhereCompositeOperation'; | ||
import WhereInCompositeOperation from './operations/WhereInCompositeOperation'; | ||
import WhereInCompositeSqliteOperation from './operations/WhereInCompositeSqliteOperation'; | ||
import WhereJsonPostgresOperation from './operations/jsonApi/WhereJsonPostgresOperation'; | ||
import WhereJsonHasPostgresOperation from './operations/jsonApi/WhereJsonHasPostgresOperation'; | ||
import WhereJsonFieldPostgresOperation from './operations/jsonApi/WhereJsonFieldPostgresOperation'; | ||
import WhereJsonNotObjectPostgresOperation from './operations/jsonApi/WhereJsonNotObjectPostgresOperation'; | ||
/** | ||
@@ -10,11 +22,21 @@ * This class is a thin wrapper around knex query builder. This class allows us to add our own | ||
*/ | ||
@overwriteForDatabase() | ||
export default class QueryBuilderBase { | ||
constructor(knex) { | ||
constructor(knex, QueryBuilderContext) { | ||
/** | ||
* @type {knex} | ||
* @protected | ||
*/ | ||
this._knex = knex; | ||
this._knexMethodCalls = []; | ||
this._context = { | ||
userContext: {} | ||
}; | ||
/** | ||
* @type {Array.<QueryBuilderOperation>} | ||
* @protected | ||
*/ | ||
this._operations = []; | ||
/** | ||
* @type {QueryBuilderContextBase} | ||
* @protected | ||
*/ | ||
this._context = new (QueryBuilderContext || QueryBuilderContextBase)(); | ||
} | ||
@@ -32,9 +54,10 @@ | ||
/** | ||
* Sets/gets the query context. | ||
* @param {Object=} ctx | ||
* @returns {Object|QueryBuilderBase} | ||
*/ | ||
context() { | ||
context(ctx) { | ||
if (arguments.length === 0) { | ||
return this._context.userContext; | ||
} else { | ||
this._context.userContext = arguments[0]; | ||
this._context.userContext = ctx; | ||
return this; | ||
@@ -45,9 +68,10 @@ } | ||
/** | ||
* Sets/gets the query's internal context. | ||
* @param {QueryBuilderContextBase=} ctx | ||
* @returns {QueryBuilderContextBase|QueryBuilderBase} | ||
*/ | ||
internalContext() { | ||
internalContext(ctx) { | ||
if (arguments.length === 0) { | ||
return this._context; | ||
} else { | ||
this._context = arguments[0]; | ||
this._context = ctx; | ||
return this; | ||
@@ -58,6 +82,12 @@ } | ||
/** | ||
* @returns {knex} | ||
* @param {knex=} knex | ||
* @returns {Object|QueryBuilderBase} | ||
*/ | ||
knex() { | ||
return this._knex; | ||
knex(knex) { | ||
if (arguments.length === 0) { | ||
return this._knex; | ||
} else { | ||
this._knex = knex; | ||
return this; | ||
} | ||
} | ||
@@ -71,2 +101,3 @@ | ||
func.call(this, this); | ||
return this; | ||
@@ -76,43 +107,11 @@ } | ||
/** | ||
* @returns {string} | ||
*/ | ||
toString() { | ||
return this.build().toString(); | ||
} | ||
/** | ||
* @returns {string} | ||
*/ | ||
toSql() { | ||
return this.toString(); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
clone() { | ||
var clone = new this.constructor(this._knex); | ||
this.cloneInto(clone); | ||
return clone; | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
cloneInto(builder) { | ||
builder._knex = this._knex; | ||
builder._knexMethodCalls = this._knexMethodCalls.slice(); | ||
builder._context = _.clone(this._context); | ||
} | ||
/** | ||
* @param {RegExp=} methodNameRegex | ||
*/ | ||
clear(methodNameRegex) { | ||
if (methodNameRegex) { | ||
// Reject all query method calls that don't pass the filter. | ||
this._knexMethodCalls = _.reject(this._knexMethodCalls, call => methodNameRegex.test(call.method)); | ||
if (_.isRegExp(methodNameRegex)) { | ||
this._operations = _.reject(this._operations, method => { | ||
return methodNameRegex.test(method.name) | ||
}); | ||
} else { | ||
// If no arguments are given, clear all query method calls. | ||
this._knexMethodCalls = []; | ||
this._operations = []; | ||
} | ||
@@ -128,7 +127,5 @@ | ||
copyFrom(queryBuilder, methodNameRegex) { | ||
var self = this; | ||
_.forEach(queryBuilder._knexMethodCalls, call => { | ||
if (!methodNameRegex || methodNameRegex.test(call.method)) { | ||
self._knexMethodCalls.push(call); | ||
_.each(queryBuilder._operations, method => { | ||
if (!methodNameRegex || methodNameRegex.test(method.name)) { | ||
this._operations.push(method); | ||
} | ||
@@ -145,4 +142,4 @@ }); | ||
has(methodNameRegex) { | ||
return _.any(this._knexMethodCalls, call => { | ||
return methodNameRegex.test(call.method); | ||
return _.some(this._operations, method => { | ||
return methodNameRegex.test(method.name); | ||
}); | ||
@@ -152,3 +149,43 @@ } | ||
/** | ||
* @param {QueryBuilderOperation} method | ||
* @param {Array.<*>} args | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
callQueryBuilderOperation(method, args) { | ||
if (method.call(this, args || [])) { | ||
this._operations.push(method); | ||
} | ||
return this; | ||
} | ||
/** | ||
* @param {string} methodName | ||
* @param {Array.<*>} args | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
callKnexQueryBuilderOperation(methodName, args) { | ||
return this.callQueryBuilderOperation(new KnexOperation(this, methodName), args); | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
clone() { | ||
return this.baseCloneInto(new this.constructor(this._knex)); | ||
} | ||
/** | ||
* @protected | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
baseCloneInto(builder) { | ||
builder._knex = this._knex; | ||
builder._operations = this._operations.slice(); | ||
builder._context = this._context.clone(); | ||
return builder; | ||
} | ||
/** | ||
* @returns {knex.QueryBuilder} | ||
@@ -161,10 +198,7 @@ */ | ||
/** | ||
* @private | ||
* @protected | ||
*/ | ||
buildInto(knexBuilder) { | ||
_.forEach(this._knexMethodCalls, call => { | ||
if (_.isFunction(knexBuilder[call.method])) { | ||
knexBuilder[call.method].apply(knexBuilder, call.args); | ||
} | ||
}); | ||
_.each(this._operations, method => method.onBeforeBuild(this)); | ||
_.each(this._operations, method => method.onBuild(knexBuilder, this)); | ||
@@ -175,29 +209,13 @@ return knexBuilder; | ||
/** | ||
* @private | ||
* @returns {string} | ||
*/ | ||
callKnexMethod(methodName, args) { | ||
for (let i = 0, l = args.length; i < l; ++i) { | ||
if (_.isUndefined(args[i])) { | ||
// None of the query builder methods should accept undefined. Do nothing if | ||
// one of the arguments is undefined. This enables us to do things like | ||
// `.where('name', req.query.name)` without checking if req.query has the | ||
// property `name`. | ||
return this; | ||
} else if (args[i] instanceof QueryBuilderBase) { | ||
// Convert QueryBuilderBase instances into knex query builders. | ||
args[i] = args[i].build(); | ||
} else if (_.isFunction(args[i])) { | ||
// If an argument is a function, knex calls it with a query builder as | ||
// `this` context. We call the function with a QueryBuilderBase as | ||
// `this` context instead. | ||
args[i] = wrapFunctionArg(args[i], this); | ||
} | ||
} | ||
toString() { | ||
return this.build().toString(); | ||
} | ||
this._knexMethodCalls.push({ | ||
method: methodName, | ||
args: args | ||
}); | ||
return this; | ||
/** | ||
* @returns {string} | ||
*/ | ||
toSql() { | ||
return this.toString(); | ||
} | ||
@@ -208,3 +226,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
insert(...args) {} | ||
@@ -215,3 +233,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
update(...args) {} | ||
@@ -222,3 +240,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
delete(...args) {} | ||
@@ -229,3 +247,3 @@ | ||
*/ | ||
@knexQueryMethod('delete') | ||
@queryBuilderOperation(KnexOperation, 'delete') | ||
del(...args) {} | ||
@@ -236,3 +254,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
select(...args) {} | ||
@@ -243,3 +261,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
forUpdate(...args) {} | ||
@@ -250,3 +268,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
forShare(...args) {} | ||
@@ -257,3 +275,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
as(...args) {} | ||
@@ -264,3 +282,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
columns(...args) {} | ||
@@ -271,3 +289,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
column(...args) {} | ||
@@ -278,3 +296,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
from(...args) {} | ||
@@ -285,3 +303,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
fromJS(...args) {} | ||
@@ -292,3 +310,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
into(...args) {} | ||
@@ -299,3 +317,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
withSchema(...args) {} | ||
@@ -306,3 +324,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
table(...args) {} | ||
@@ -313,3 +331,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
distinct(...args) {} | ||
@@ -320,3 +338,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
join(...args) {} | ||
@@ -327,3 +345,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
joinRaw(...args) {} | ||
@@ -334,3 +352,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
innerJoin(...args) {} | ||
@@ -341,3 +359,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
leftJoin(...args) {} | ||
@@ -348,3 +366,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
leftOuterJoin(...args) {} | ||
@@ -355,3 +373,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
rightJoin(...args) {} | ||
@@ -362,3 +380,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
rightOuterJoin(...args) {} | ||
@@ -369,3 +387,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
outerJoin(...args) {} | ||
@@ -376,3 +394,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
fullOuterJoin(...args) {} | ||
@@ -383,3 +401,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
crossJoin(...args) {} | ||
@@ -390,3 +408,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
where(...args) {} | ||
@@ -397,3 +415,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
andWhere(...args) {} | ||
@@ -404,3 +422,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhere(...args) {} | ||
@@ -411,3 +429,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereNot(...args) {} | ||
@@ -418,3 +436,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereNot(...args) {} | ||
@@ -425,3 +443,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereRaw(...args) {} | ||
@@ -432,3 +450,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereWrapped(...args) {} | ||
@@ -439,3 +457,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
havingWrapped(...args) {} | ||
@@ -446,3 +464,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereRaw(...args) {} | ||
@@ -453,3 +471,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereExists(...args) {} | ||
@@ -460,3 +478,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereExists(...args) {} | ||
@@ -467,3 +485,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereNotExists(...args) {} | ||
@@ -474,3 +492,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereNotExists(...args) {} | ||
@@ -481,3 +499,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereIn(...args) {} | ||
@@ -488,3 +506,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereIn(...args) {} | ||
@@ -495,3 +513,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereNotIn(...args) {} | ||
@@ -501,3 +519,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereNotIn(...args) {} | ||
@@ -508,3 +526,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereNull(...args) {} | ||
@@ -515,3 +533,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereNull(...args) {} | ||
@@ -522,3 +540,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereNotNull(...args) {} | ||
@@ -529,3 +547,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereNotNull(...args) {} | ||
@@ -536,3 +554,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereBetween(...args) {} | ||
@@ -543,3 +561,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
whereNotBetween(...args) {} | ||
@@ -550,3 +568,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereBetween(...args) {} | ||
@@ -557,3 +575,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orWhereNotBetween(...args) {} | ||
@@ -564,3 +582,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
groupBy(...args) {} | ||
@@ -571,3 +589,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
groupByRaw(...args) {} | ||
@@ -578,3 +596,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orderBy(...args) {} | ||
@@ -585,3 +603,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orderByRaw(...args) {} | ||
@@ -592,3 +610,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
union(...args) {} | ||
@@ -599,3 +617,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
unionAll(...args) {} | ||
@@ -606,3 +624,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
having(...args) {} | ||
@@ -613,3 +631,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
havingRaw(...args) {} | ||
@@ -620,3 +638,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orHaving(...args) {} | ||
@@ -627,3 +645,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
orHavingRaw(...args) {} | ||
@@ -634,3 +652,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
offset(...args) {} | ||
@@ -641,3 +659,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
limit(...args) {} | ||
@@ -648,3 +666,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
count(...args) {} | ||
@@ -655,3 +673,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
countDistinct(...args) {} | ||
@@ -662,3 +680,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
min(...args) {} | ||
@@ -669,3 +687,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
max(...args) {} | ||
@@ -676,3 +694,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
sum(...args) {} | ||
@@ -683,3 +701,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
avg(...args) {} | ||
@@ -690,3 +708,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
avgDistinct(...args) {} | ||
@@ -697,3 +715,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
debug(...args) {} | ||
@@ -704,3 +722,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
returning(...args) {} | ||
@@ -711,3 +729,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
truncate(...args) {} | ||
@@ -718,3 +736,3 @@ | ||
*/ | ||
@knexQueryMethod() | ||
@queryBuilderOperation(KnexOperation) | ||
connection(...args) {} | ||
@@ -725,5 +743,4 @@ | ||
*/ | ||
whereRef(lhs, op, rhs) { | ||
return this._whereRef('and', lhs, op, rhs); | ||
} | ||
@queryBuilderOperation(KnexOperation) | ||
options(...args) {} | ||
@@ -733,5 +750,4 @@ /** | ||
*/ | ||
orWhereRef(lhs, op, rhs) { | ||
return this._whereRef('or', lhs, op, rhs); | ||
} | ||
@queryBuilderOperation(KnexOperation) | ||
columnInfo(...args) {} | ||
@@ -741,133 +757,32 @@ /** | ||
*/ | ||
whereComposite(cols, op, values) { | ||
if (_.isUndefined(values)) { | ||
values = op; | ||
op = '='; | ||
} | ||
@queryBuilderOperation([KnexOperation, {acceptUndefinedArgs: true}]) | ||
modify(...args) {} | ||
let colsIsArray = _.isArray(cols); | ||
let valuesIsArray = _.isArray(values); | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
@queryBuilderOperation([WhereRefOperation, {bool: 'and'}]) | ||
whereRef(lhs, op, rhs) {} | ||
if (!colsIsArray && !valuesIsArray) { | ||
return this.where(cols, op, values); | ||
} else if (colsIsArray && cols.length === 1 && !valuesIsArray) { | ||
return this.where(cols[0], op, values); | ||
} else if (colsIsArray && valuesIsArray && cols.length === values.length) { | ||
_.each(cols, (col, idx) => this.where(col, op, values[idx])); | ||
return this; | ||
} else { | ||
throw new Error('both cols and values must have same dimensions'); | ||
} | ||
} | ||
/** | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
@overwriteForDatabase({ | ||
sqlite3: 'whereInComposite_sqlite3' | ||
}) | ||
whereInComposite(columns, values) { | ||
let isCompositeKey = _.isArray(columns) && columns.length > 1; | ||
@queryBuilderOperation([WhereRefOperation, {bool: 'or'}]) | ||
orWhereRef(lhs, op, rhs) {} | ||
if (isCompositeKey) { | ||
if (_.isArray(values)) { | ||
return this.whereIn(columns, values); | ||
} else { | ||
// Because of a bug in knex, we need to build the where-in query from pieces | ||
// if the value is a subquery. | ||
let formatter = this._knex.client.formatter(); | ||
let sql = '(' + _.map(columns, col => formatter.wrap(col)).join() + ')'; | ||
return this.whereIn(this._knex.raw(sql), values); | ||
} | ||
} else { | ||
let col = _.isString(columns) ? columns : columns[0]; | ||
if (_.isArray(values)) { | ||
values = _.compact(_.flatten(values)); | ||
} | ||
// For non-composite keys we can use the normal whereIn. | ||
return this.whereIn(col, values); | ||
} | ||
} | ||
/** | ||
* @private | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
whereInComposite_sqlite3(columns, values) { | ||
let isCompositeKey = _.isArray(columns) && columns.length > 1; | ||
@queryBuilderOperation(WhereCompositeOperation) | ||
whereComposite(cols, op, values) {} | ||
if (isCompositeKey) { | ||
if (!_.isArray(values)) { | ||
// If the `values` is not an array of values but a function or a subquery | ||
// we have no way to implement this method. | ||
throw new Error('sqlite doesn\'t support multi-column where in clauses'); | ||
} | ||
// Sqlite doesn't support the `where in` syntax for multiple columns but | ||
// we can emulate it using grouped `or` clauses. | ||
return this.where(builder => { | ||
_.each(values, (val) => { | ||
builder.orWhere(builder => { | ||
_.each(columns, (col, idx) => { | ||
builder.andWhere(col, val[idx]); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} else { | ||
let col = _.isString(columns) ? columns : columns[0]; | ||
if (_.isArray(values)) { | ||
values = _.compact(_.flatten(values)); | ||
} | ||
// For non-composite keys we can use the normal whereIn. | ||
return this.whereIn(col, values); | ||
} | ||
} | ||
/** | ||
* Json query APIs | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
@queryBuilderOperation({ | ||
default: WhereInCompositeOperation, | ||
sqlite3: WhereInCompositeSqliteOperation | ||
}) | ||
whereInComposite(columns, values) {} | ||
/** | ||
* @typedef {String} FieldExpression | ||
* | ||
* Field expressions allow one to refer to separate JSONB fields inside columns. | ||
* | ||
* Syntax: <column reference>[:<json field reference>] | ||
* | ||
* e.g. `Person.jsonColumnName:details.names[1]` would refer to value `'Second'` | ||
* in column `Person.jsonColumnName` which has | ||
* `{ details: { names: ['First', 'Second', 'Last'] } }` object stored in it. | ||
* | ||
* First part `<column reference>` is compatible with column references used in | ||
* knex e.g. `MyFancyTable.tributeToThBestColumnNameEver`. | ||
* | ||
* Second part describes a path to an attribute inside the referred column. | ||
* It is optional and it always starts with colon which follows directly with | ||
* first path element. e.g. `Table.jsonObjectColumnName:jsonFieldName` or | ||
* `Table.jsonArrayColumn:[321]`. | ||
* | ||
* Syntax supports `[<key or index>]` and `.<key or index>` flavors of reference | ||
* to json keys / array indexes: | ||
* | ||
* e.g. both `Table.myColumn:[1][3]` and `Table.myColumn:1.3` would access correctly | ||
* both of the following objects `[null, [null,null,null, "I was accessed"]]` and | ||
* `{ "1": { "3" : "I was accessed" } }` | ||
* | ||
* Caveats when using special characters in keys: | ||
* | ||
* 1. `objectColumn.key` This is the most common syntax, good if you are | ||
* not using dots or square brackets `[]` in your json object key name. | ||
* 2. Keys containing dots `objectColumn:[keywith.dots]` Column `{ "keywith.dots" : "I was referred" }` | ||
* 3. Keys containing square brackets `column['[]']` `{ "[]" : "This is getting ridiculous..." }` | ||
* 4. Keys containing square brackets and quotes | ||
* `objectColumn:['Double."Quote".[]']` and `objectColumn:["Sinlge.'Quote'.[]"]` | ||
* Column `{ "Double.\"Quote\".[]" : "I was referred", "Sinlge.'Quote'.[]" : "Mee too!" }` | ||
* 99. Keys containing dots, square brackets, single quotes and double quotes in one json key is | ||
* not currently supported | ||
*/ | ||
/** | ||
@@ -878,26 +793,28 @@ * @param {FieldExpression} fieldExpression | ||
*/ | ||
whereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "=", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '=', bool: 'and'}]) | ||
whereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "=", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '=', bool: 'or'}]) | ||
orWhereJsonEquals(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
whereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "!=", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '!=', bool: 'and'}]) | ||
whereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "!=", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '!=', bool: 'or'}]) | ||
orWhereJsonNotEquals(fieldExpression, jsonObjectOrFieldExpression) {} | ||
@@ -909,26 +826,28 @@ /** | ||
*/ | ||
whereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '@>', bool: 'and'}]) | ||
whereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '@>', bool: 'or'}]) | ||
orWhereJsonSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
whereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '@>', bool: 'and', prefix: 'not'}]) | ||
whereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '@>', bool: 'or', prefix: 'not'}]) | ||
orWhereJsonNotSupersetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
@@ -940,26 +859,28 @@ /** | ||
*/ | ||
whereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '<@', bool: 'and'}]) | ||
whereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '<@', bool: 'or'}]) | ||
orWhereJsonSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
whereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '<@', bool: 'and', prefix: 'not'}]) | ||
whereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {Object|Array|FieldExpression} jsonObjectOrFieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) { | ||
return orWhereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "<@", jsonObjectOrFieldExpression, 'not'); | ||
} | ||
@queryBuilderOperation([WhereJsonPostgresOperation, {operator: '<@', bool: 'or', prefix: 'not'}]) | ||
orWhereJsonNotSubsetOf(fieldExpression, jsonObjectOrFieldExpression) {} | ||
@@ -975,2 +896,3 @@ /** | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
@@ -983,28 +905,15 @@ */ | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
whereJsonNotArray(fieldExpression) { | ||
let knex = this._knex; | ||
// uhh... ugly. own subquery builder could help... now this refers to plain knex subquery builder | ||
return this.where(function () { | ||
// not array | ||
let builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", [], 'not'); | ||
let ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
whereJsonIsObject(fieldExpression) { | ||
return this.whereJsonSupersetOf(fieldExpression, {}); | ||
} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonNotArray(fieldExpression) { | ||
let knex = this._knex; | ||
return this.orWhere(function () { | ||
// not array | ||
let builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", [], 'not'); | ||
let ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
orWhereJsonIsObject(fieldExpression) { | ||
return this.orWhereJsonSupersetOf(fieldExpression, {}); | ||
} | ||
@@ -1016,40 +925,25 @@ | ||
*/ | ||
whereJsonIsObject(fieldExpression) { | ||
return this.whereJsonSupersetOf(fieldExpression, {}); | ||
} | ||
@queryBuilderOperation([WhereJsonNotObjectPostgresOperation, {bool: 'and', compareValue: []}]) | ||
whereJsonNotArray(fieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonIsObject(fieldExpression) { | ||
return this.orWhereJsonSupersetOf(fieldExpression, {}); | ||
} | ||
@queryBuilderOperation([WhereJsonNotObjectPostgresOperation, {bool: 'or', compareValue: []}]) | ||
orWhereJsonNotArray(fieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
whereJsonNotObject(fieldExpression) { | ||
let knex = this._knex; | ||
return this.where(function () { | ||
// not object | ||
let builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", {}, 'not'); | ||
let ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
} | ||
@queryBuilderOperation([WhereJsonNotObjectPostgresOperation, {bool: 'and', compareValue: {}}]) | ||
whereJsonNotObject(fieldExpression) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonNotObject(fieldExpression) { | ||
let knex = this._knex; | ||
return this.orWhere(function () { | ||
// not object | ||
let builder = whereJsonbRefOnLeftJsonbValOrRefOnRight(this, fieldExpression, "@>", {}, 'not'); | ||
let ifRefNotExistQuery = whereJsonFieldQuery(knex, fieldExpression, "IS", null); | ||
// or not exist | ||
builder.orWhereRaw(ifRefNotExistQuery); | ||
}); | ||
} | ||
@queryBuilderOperation([WhereJsonNotObjectPostgresOperation, {bool: 'or', compareValue: {}}]) | ||
orWhereJsonNotObject(fieldExpression) {} | ||
@@ -1061,12 +955,12 @@ /** | ||
*/ | ||
whereJsonHasAny(fieldExpression, keys) { | ||
return whereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?|', keys); | ||
} | ||
@queryBuilderOperation([WhereJsonHasPostgresOperation, {bool: 'and', operator: '?|'}]) | ||
whereJsonHasAny(fieldExpression, keys) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonHasAny(fieldExpression, keys) { | ||
return orWhereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?|', keys); | ||
} | ||
@queryBuilderOperation([WhereJsonHasPostgresOperation, {bool: 'or', operator: '?|'}]) | ||
orWhereJsonHasAny(fieldExpression, keys) {} | ||
@@ -1078,12 +972,12 @@ /** | ||
*/ | ||
whereJsonHasAll(fieldExpression, keys) { | ||
return whereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?&', keys); | ||
} | ||
@queryBuilderOperation([WhereJsonHasPostgresOperation, {bool: 'and', operator: '?&'}]) | ||
whereJsonHasAll(fieldExpression, keys) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string|Array.<string>} keys | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonHasAll(fieldExpression, keys) { | ||
return orWhereJsonFieldRightStringArrayOnLeft(this, fieldExpression, '?&', keys); | ||
} | ||
@queryBuilderOperation([WhereJsonHasPostgresOperation, {bool: 'or', operator: '?&'}]) | ||
orWhereJsonHasAll(fieldExpression, keys) {} | ||
@@ -1096,158 +990,13 @@ /** | ||
*/ | ||
whereJsonField(fieldExpression, operator, value) { | ||
let query = whereJsonFieldQuery(this._knex, fieldExpression, operator, value); | ||
return this.whereRaw(query); | ||
} | ||
@queryBuilderOperation([WhereJsonFieldPostgresOperation, {bool: 'and'}]) | ||
whereJsonField(fieldExpression, operator, value) {} | ||
/** | ||
* @param {FieldExpression} fieldExpression | ||
* @param {string} operator | ||
* @param {boolean|Number|string|null} value | ||
* @returns {QueryBuilderBase} | ||
*/ | ||
orWhereJsonField(fieldExpression, operator, value) { | ||
let query = whereJsonFieldQuery(this._knex, fieldExpression, operator, value); | ||
return this.orWhereRaw(query); | ||
} | ||
/** | ||
* @private | ||
*/ | ||
_whereRef(bool, lhs, op, rhs) { | ||
if (!rhs) { | ||
rhs = op; | ||
op = '='; | ||
} | ||
let formatter = this._knex.client.formatter(); | ||
op = formatter.operator(op); | ||
if (!_.isString(lhs) || !_.isString(rhs) || !_.isString(op)) { | ||
throw new Error('whereRef: invalid operands or operator'); | ||
} | ||
let sql = formatter.wrap(lhs) + ' ' + op + ' ' + formatter.wrap(rhs); | ||
if (bool === 'or') { | ||
return this.orWhereRaw(sql); | ||
} else { | ||
return this.whereRaw(sql); | ||
} | ||
} | ||
} | ||
function knexQueryMethod(overrideMethodName) { | ||
return function (target, methodName, descriptor) { | ||
descriptor.value = function () { | ||
return this.callKnexMethod(overrideMethodName || methodName, _.toArray(arguments)); | ||
}; | ||
}; | ||
} | ||
function wrapFunctionArg(func, query) { | ||
return function () { | ||
if (isKnexQueryBuilder(this)) { | ||
let builder = new QueryBuilderBase(query._knex); | ||
func.call(builder, builder); | ||
builder.buildInto(this); | ||
} else { | ||
return func.apply(this, arguments); | ||
} | ||
}; | ||
} | ||
function parseFieldExpression(expression, extractAsText) { | ||
let parsed = jsonFieldExpressionParser.parse(expression); | ||
let jsonRefs = _(parsed.access).pluck('ref').value().join(","); | ||
let extractor = extractAsText ? '#>>' : '#>'; | ||
let middleQuotedColumnName = parsed.columnName.split('.').join('"."'); | ||
return `"${middleQuotedColumnName}"${extractor}'{${jsonRefs}}'`; | ||
} | ||
function whereJsonbRefOnLeftJsonbValOrRefOnRight(builder, fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { | ||
let queryParams = whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix); | ||
return builder.whereRaw.apply(builder, queryParams); | ||
} | ||
function orWhereJsonbRefOnLeftJsonbValOrRefOnRight(builder, fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { | ||
let queryParams = whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix); | ||
return builder.orWhereRaw.apply(builder, queryParams); | ||
} | ||
function whereJsonbRefOnLeftJsonbValOrRefOnRightRawQueryParams(fieldExpression, operator, jsonObjectOrFieldExpression, queryPrefix) { | ||
let fieldReference = parseFieldExpression(fieldExpression); | ||
if (_.isString(jsonObjectOrFieldExpression)) { | ||
let rightHandReference = parseFieldExpression(jsonObjectOrFieldExpression); | ||
let refRefQuery = ["(", fieldReference, ")::jsonb", operator, "(", rightHandReference, ")::jsonb"]; | ||
if (queryPrefix) { | ||
refRefQuery.unshift(queryPrefix); | ||
} | ||
return [refRefQuery.join(" ")]; | ||
} else if (_.isObject(jsonObjectOrFieldExpression)) { | ||
let refValQuery = ["(", fieldReference, ")::jsonb", operator, "?::jsonb"]; | ||
if (queryPrefix) { | ||
refValQuery.unshift(queryPrefix); | ||
} | ||
return [refValQuery.join(" "), JSON.stringify(jsonObjectOrFieldExpression)]; | ||
} | ||
throw new Error("Invalid right hand expression."); | ||
} | ||
function whereJsonFieldRightStringArrayOnLeft(builder, fieldExpression, operator, keys) { | ||
return builder.whereRaw(whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys)); | ||
} | ||
function orWhereJsonFieldRightStringArrayOnLeft(builder, fieldExpression, operator, keys) { | ||
return builder.orWhereRaw(whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys)); | ||
} | ||
function whereJsonFieldRightStringArrayOnLeftQuery(builder, fieldExpression, operator, keys) { | ||
let knex = builder._knex; | ||
let fieldReference = parseFieldExpression(fieldExpression); | ||
keys = _.isArray(keys) ? keys : [keys]; | ||
let questionMarksArray = _.map(keys, function (key) { | ||
if (!_.isString(key)) { | ||
throw new Error("All keys to find must be strings."); | ||
} | ||
return "?"; | ||
}); | ||
let rawSqlTemplateString = "array[" + questionMarksArray.join(",") + "]"; | ||
let rightHandExpression = knex.raw(rawSqlTemplateString, keys); | ||
return `${fieldReference} ${operator.replace('?', '\\?')} ${rightHandExpression}`; | ||
} | ||
function whereJsonFieldQuery(knex, fieldExpression, operator, value) { | ||
let fieldReference = parseFieldExpression(fieldExpression, true); | ||
let normalizedOperator = normalizeOperator(knex, operator); | ||
// json type comparison takes json type in string format | ||
let cast; | ||
let escapedValue = knex.raw(" ?", [value]); | ||
if (_.isNumber(value)) { | ||
cast = "::NUMERIC"; | ||
} else if (_.isBoolean(value)) { | ||
cast = "::BOOLEAN"; | ||
} else if (_.isString(value)) { | ||
cast = "::TEXT"; | ||
} else if (_.isNull(value)) { | ||
cast = "::TEXT"; | ||
escapedValue = 'NULL'; | ||
} else { | ||
throw new Error("Value must be string, number, boolean or null."); | ||
} | ||
return `(${fieldReference})${cast} ${normalizedOperator} ${escapedValue}`; | ||
} | ||
function normalizeOperator(knex, operator) { | ||
let trimmedLowerCase = operator.trim().toLowerCase(); | ||
switch (trimmedLowerCase) { | ||
case "is": | ||
case "is not": | ||
return trimmedLowerCase; | ||
default: | ||
return knex.client.formatter().operator(operator); | ||
} | ||
} | ||
@queryBuilderOperation([WhereJsonFieldPostgresOperation, {bool: 'or'}]) | ||
orWhereJsonField(fieldExpression, operator, value) {} | ||
} |
@@ -70,3 +70,3 @@ import _ from 'lodash'; | ||
return _.all(expr.children, (child, childName) => { | ||
return _.every(expr.children, (child, childName) => { | ||
var ownSubExpression = this.childExpression(childName); | ||
@@ -108,3 +108,3 @@ var subExpression = expr.childExpression(childName); | ||
isAllRecursive() { | ||
return this.numChildren === 1 && _.all(this.children, (val, key) => ALL_RECURSIVE_REGEX.test(key)); | ||
return this.numChildren === 1 && _.every(this.children, (val, key) => ALL_RECURSIVE_REGEX.test(key)); | ||
} | ||
@@ -111,0 +111,0 @@ |
import _ from 'lodash'; | ||
import memoize from '../utils/decorators/memoize'; | ||
import {inherits, isSubclassOf} from '../utils/classUtils'; | ||
import memoize from '../utils/decorators/memoize'; | ||
import QueryBuilder from '../queryBuilder/QueryBuilder'; | ||
import RelationFindOperation from './RelationFindOperation'; | ||
import RelationUpdateOperation from './RelationUpdateOperation'; | ||
import RelationDeleteOperation from './RelationDeleteOperation'; | ||
/** | ||
@@ -201,3 +205,3 @@ * @typedef {Object} RelationJoin | ||
clone() { | ||
let relation = new this.constructor(this.name, this.ownerModelClass); | ||
const relation = new this.constructor(this.name, this.ownerModelClass); | ||
@@ -211,2 +215,3 @@ relation.relatedModelClass = this.relatedModelClass; | ||
return relation; | ||
@@ -220,3 +225,3 @@ } | ||
bindKnex(knex) { | ||
let bound = this.clone(); | ||
const bound = this.clone(); | ||
@@ -230,33 +235,2 @@ bound.relatedModelClass = this.relatedModelClass.bindKnex(knex); | ||
/** | ||
* @protected | ||
* @param {Array.<Model>} models1 | ||
* @param {Array.<Model>} models2 | ||
* @returns {Array.<Model>} | ||
*/ | ||
mergeModels(models1, models2) { | ||
let modelsById = Object.create(null); | ||
models1 = _.compact(models1); | ||
models2 = _.compact(models2); | ||
_.forEach(models1, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
_.forEach(models2, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
let models = _.values(modelsById); | ||
if (models.length === 0) { | ||
return []; | ||
} | ||
let modelClass = models[0].constructor; | ||
let idProperty = modelClass.getIdProperty(); | ||
return _.sortByAll(models, _.isArray(idProperty) ? idProperty : [idProperty]); | ||
} | ||
/** | ||
* @param {QueryBuilder} builder | ||
@@ -268,3 +242,3 @@ * @param {Array.<string>|Array.<Array.<(string|number)>>} ownerIds | ||
findQuery(builder, ownerIds, isColumnRef) { | ||
let fullRelatedCol = this.fullRelatedCol(); | ||
const fullRelatedCol = this.fullRelatedCol(); | ||
@@ -276,3 +250,3 @@ if (isColumnRef) { | ||
} else { | ||
if (_(ownerIds).flatten().all(id => _.isNull(id) || _.isUndefined(id))) { | ||
if (_(ownerIds).flatten().every(id => _.isNull(id) || _.isUndefined(id))) { | ||
// Nothing to fetch. | ||
@@ -290,17 +264,17 @@ builder.resolve([]); | ||
* @param {QueryBuilder} builder | ||
* @param {string=} joinMethod | ||
* @param {string=} joinOperation | ||
* @param {string=} relatedTableAlias | ||
* @returns {QueryBuilder} | ||
*/ | ||
join(builder, joinMethod, relatedTableAlias) { | ||
joinMethod = joinMethod || 'join'; | ||
join(builder, joinOperation, relatedTableAlias) { | ||
joinOperation = joinOperation || 'join'; | ||
relatedTableAlias = relatedTableAlias || this.relatedTableAlias(); | ||
let relatedTable = this.relatedModelClass.tableName; | ||
let relatedTableAsAlias = relatedTable + ' as ' + relatedTableAlias; | ||
let relatedCol = _.map(this.relatedCol, col => relatedTableAlias + '.' + col); | ||
let ownerCol = this.fullOwnerCol(); | ||
const relatedTable = this.relatedModelClass.tableName; | ||
const relatedTableAsAlias = `${relatedTable} as ${relatedTableAlias}`; | ||
const relatedCol = _.map(this.relatedCol, col => `${relatedTableAlias}.${col}`); | ||
const ownerCol = this.fullOwnerCol(); | ||
return builder | ||
[joinMethod](relatedTableAsAlias, join => { | ||
[joinOperation](relatedTableAsAlias, join => { | ||
_.each(relatedCol, (relatedCol, idx) => { | ||
@@ -313,40 +287,23 @@ join.on(relatedCol, '=', ownerCol[idx]); | ||
/** | ||
* @param {QueryBuilder} builder | ||
* @param {Array.<Model>} owners | ||
*/ | ||
find(builder, owners) { | ||
builder.onBuild(builder => { | ||
let ids = _(owners) | ||
.map(owner => owner.$values(this.ownerProp)) | ||
.unique(id => id.join()) | ||
.value(); | ||
this.findQuery(builder, ids); | ||
}); | ||
builder.runAfterModelCreate(related => { | ||
this.createRelationProp(owners, related); | ||
return related; | ||
}); | ||
} | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @protected | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
createRelationProp(owners, related) { | ||
insert(builder, owner) { | ||
this.throwError('not implemented'); | ||
} | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @param {InsertionOrUpdate} insertion | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
insert(builder, owner, insertion) { | ||
this.throwError('not implemented'); | ||
update(builder, owner) { | ||
return new RelationUpdateOperation(builder, 'update', { | ||
relation: this, | ||
owner: owner | ||
}); | ||
} | ||
@@ -357,8 +314,9 @@ | ||
* @param {Model} owner | ||
* @param {InsertionOrUpdate} update | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
update(builder, owner, update) { | ||
builder.onBuild(builder => { | ||
this.findQuery(builder, [owner.$values(this.ownerProp)]); | ||
builder.$$update(update); | ||
patch(builder, owner) { | ||
return new RelationUpdateOperation(builder, 'patch', { | ||
relation: this, | ||
owner: owner, | ||
modelOptions: {patch: true} | ||
}); | ||
@@ -369,7 +327,10 @@ } | ||
* @param {QueryBuilder} builder | ||
* @param {Model} owner | ||
* @param {InsertionOrUpdate} patch | ||
* @param {Array.<Model>} owners | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
patch(builder, owner, patch) { | ||
return this.update(builder, owner, patch); | ||
find(builder, owners) { | ||
return new RelationFindOperation(builder, 'find', { | ||
relation: this, | ||
owners: owners | ||
}); | ||
} | ||
@@ -380,7 +341,8 @@ | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
delete(builder, owner) { | ||
builder.onBuild(builder => { | ||
this.findQuery(builder, [owner.$values(this.ownerProp)]); | ||
builder.$$delete(); | ||
return new RelationDeleteOperation(builder, 'delete', { | ||
relation: this, | ||
owner: owner | ||
}); | ||
@@ -393,6 +355,6 @@ } | ||
* @param {QueryBuilder} builder | ||
* @param {Model|Object} owner | ||
* @param {number|string|Array.<number|string>|Array.<Array.<number|string>>} ids | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
relate(builder, owner, ids) { | ||
relate(builder, owner) { | ||
this.throwError('not implemented'); | ||
@@ -405,3 +367,4 @@ } | ||
* @param {QueryBuilder} builder | ||
* @param {Model|Object} owner | ||
* @param {Model} owner | ||
* @returns {QueryBuilderOperation} | ||
*/ | ||
@@ -412,5 +375,14 @@ unrelate(builder, owner) { | ||
/* istanbul ignore next */ | ||
/** | ||
* @abstract | ||
* @protected | ||
*/ | ||
createRelationProp(owners, related) { | ||
this.throwError('not implemented'); | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
propertyName(columns, modelClass) { | ||
@@ -484,2 +456,30 @@ return _.map(columns, column => { | ||
*/ | ||
mergeModels(models1, models2) { | ||
let modelsById = Object.create(null); | ||
models1 = _.compact(models1); | ||
models2 = _.compact(models2); | ||
_.forEach(models1, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
_.forEach(models2, function (model) { | ||
modelsById[model.$id()] = model; | ||
}); | ||
let models = _.values(modelsById); | ||
if (models.length === 0) { | ||
return []; | ||
} | ||
let modelClass = models[0].constructor; | ||
let idProperty = modelClass.getIdProperty(); | ||
return _.sortBy(models, _.isArray(idProperty) ? idProperty : [idProperty]); | ||
} | ||
/** | ||
* @protected | ||
*/ | ||
throwError(message) { | ||
@@ -486,0 +486,0 @@ if (this.ownerModelClass && this.ownerModelClass.name && this.name) { |
@@ -22,2 +22,3 @@ import _ from 'lodash'; | ||
export function isKnexQueryBuilder(knexQueryBuilder) { | ||
// TODO: Use something safer | ||
return knexQueryBuilder | ||
@@ -24,0 +25,0 @@ && knexQueryBuilder.client |
@@ -11,16 +11,12 @@ const HIDDEN_DATA = '$$hiddenData'; |
return new Function('obj', 'data', ` |
var hiddenData = obj.${HIDDEN_DATA}; |
if (typeof hiddenData !== 'object') { |
hiddenData = Object.create(null); |
if (!obj.hasOwnProperty("${HIDDEN_DATA}")) { |
Object.defineProperty(obj, "${HIDDEN_DATA}", { |
enumerable: false, |
writable: false, |
value: hiddenData |
value: Object.create(null) |
}); |
} |
hiddenData.${propName} = data; |
obj.${HIDDEN_DATA}.${propName} = data; |
`); |
} |
@@ -55,3 +55,3 @@ import _ from 'lodash'; | ||
// 3. | ||
ids = _.map(ids, item => _.object(expectedProperties, [item])); | ||
ids = _.map(ids, item => _.zipObject(expectedProperties, [item])); | ||
} | ||
@@ -63,3 +63,3 @@ } else if (_.isObject(ids)) { | ||
// 1. | ||
ids = [_.object(expectedProperties, [ids])]; | ||
ids = [_.zipObject(expectedProperties, [ids])]; | ||
} | ||
@@ -92,3 +92,3 @@ } | ||
return _.object(expectedProperties, ids); | ||
return _.zipObject(expectedProperties, ids); | ||
} | ||
@@ -95,0 +95,0 @@ |
@@ -13,3 +13,3 @@ import _ from 'lodash'; | ||
const needsSplit = _.any(obj, value => isQueryProp); | ||
const needsSplit = _.some(obj, value => isQueryProp); | ||
@@ -16,0 +16,0 @@ if (needsSplit) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
638286
158
16852
34
1
0
+ Addedlodash@4.17.21(transitive)
- Removedlodash@3.10.1(transitive)
Updatedbabel-runtime@^6.6.1
Updatedbluebird@^3.3.4
Updatedlodash@^4.7.0
Updatedtv4-formats@^1.0.2