Socket
Socket
Sign inDemoInstall

objection

Package Overview
Dependencies
Maintainers
2
Versions
200
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

objection - npm Package Compare versions

Comparing version 0.5.0-rc.1 to 0.5.0-rc.2

lib/queryBuilder/decorators/queryBuilderOperation.js

1034

lib/model/Model.js
'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) {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc