Socket
Socket
Sign inDemoInstall

objection

Package Overview
Dependencies
8
Maintainers
1
Versions
200
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.1 to 0.2.2

lib/EagerInserter.js

7

lib/EagerFetcher.js

@@ -49,4 +49,9 @@ 'use strict';

var self = this;
var ModelClass = relation.relatedModelClass;
var QueryBuilder = relation.relatedModelClass.RelatedQueryBuilder;
var queryBuilder = QueryBuilder.forClass(ModelClass);
return relation.find(relation.relatedModelClass.query(), this.models).then(function (related) {
relation.find(queryBuilder, this.models);
return queryBuilder.then(function (related) {
return self._fetchNextEager(relation, related, nextEager);

@@ -53,0 +58,0 @@ });

226

lib/Model.js

@@ -192,15 +192,27 @@ 'use strict';

.findImpl(function () {
this.where(ModelClass.getFullIdColumn(), self.$id());
var queryBuilder = this;
queryBuilder.where(ModelClass.getFullIdColumn(), self.$id());
})
.insertImpl(function () {
ModelClass.$$insert(this, self);
.insertImpl(function (insertion) {
var queryBuilder = this;
insertion.setModels(self);
queryBuilder.$$insert(self);
})
.updateImpl(function (update) {
ModelClass.$$update(this, update || self).where(ModelClass.getFullIdColumn(), self.$id());
var queryBuilder = this;
if (!update.model()) {
update.setModels([self]);
}
queryBuilder.$$update(update).where(ModelClass.getFullIdColumn(), self.$id());
})
.patchImpl(function (patch) {
ModelClass.$$patch(this, patch || self).where(ModelClass.getFullIdColumn(), self.$id());
var queryBuilder = this;
if (!patch.model()) {
patch.setModels([self]);
}
queryBuilder.$$update(patch).where(ModelClass.getFullIdColumn(), self.$id());
})
.deleteImpl(function () {
ModelClass.$$delete(this).where(ModelClass.getFullIdColumn(), self.$id());
var queryBuilder = this;
queryBuilder.$$delete().where(ModelClass.getFullIdColumn(), self.$id());
})

@@ -340,24 +352,31 @@ .relateImpl(function () {

return ModelClass.QueryBuilder
return ModelClass.RelatedQueryBuilder
.forClass(ModelClass)
.findImpl(function () {
relation.find(this, self);
var queryBuilder = this;
relation.find(queryBuilder, [self]);
})
.insertImpl(function (modelsToInsert) {
relation.insert(this, self, modelsToInsert);
.insertImpl(function (insert) {
var queryBuilder = this;
relation.insert(queryBuilder, self, insert);
})
.updateImpl(function (update) {
relation.update(this, self, update);
var queryBuilder = this;
relation.update(queryBuilder, self, update);
})
.patchImpl(function (patch) {
relation.patch(this, self, patch);
var queryBuilder = this;
relation.patch(queryBuilder, self, patch);
})
.deleteImpl(function () {
relation.delete(this, self);
var queryBuilder = this;
relation.delete(queryBuilder, self);
})
.relateImpl(function (ids) {
relation.relate(this, self, ids);
var queryBuilder = this;
relation.relate(queryBuilder, self, ids);
})
.unrelateImpl(function () {
relation.unrelate(this, self);
var queryBuilder = this;
relation.unrelate(queryBuilder, self);
});

@@ -477,2 +496,8 @@ };

* Called before a model is inserted into the database.
*
* You can return a promise from this function if you need to do asynchronous stuff. You can
* also throw an exception to abort the insert and reject the query. This can be useful if
* you need to do insert specific validation.
*
* @returns {Promise|*}
*/

@@ -485,2 +510,6 @@ Model.prototype.$beforeInsert = function () {

* Called after a model has been inserted into the database.
*
* You can return a promise from this function if you need to do asynchronous stuff.
*
* @returns {Promise|*}
*/

@@ -494,2 +523,6 @@ Model.prototype.$afterInsert = function () {

*
* You can return a promise from this function if you need to do asynchronous stuff. You can
* also throw an exception to abort the update and reject the query. This can be useful if
* you need to do update specific validation.
*
* This method is also called before a model is patched. Therefore all the model's properties

@@ -517,2 +550,3 @@ * may not exist. You can check if the update operation is a patch by checking the `opt.patch`

* @param {ModelOptions} opt
* @returns {Promise|*}
*/

@@ -526,2 +560,4 @@ Model.prototype.$beforeUpdate = function (opt) {

*
* You can return a promise from this function if you need to do asynchronous stuff.
*
* This method is also called after a model is patched. Therefore all the model's properties

@@ -549,2 +585,3 @@ * may not exist. You can check if the update operation is a patch by checking the `opt.patch`

* @param {ModelOptions} opt
* @returns {Promise|*}
*/

@@ -556,6 +593,6 @@ Model.prototype.$afterUpdate = function (opt) {

/**
* QueryBuilder subclass to use.
* QueryBuilder subclass to use in `query()` or `$query()` methods.
*
* This constructor is used whenever a query builder is created. You can override this
* to use your own `QueryBuilder` subclass.
* This constructor is used whenever a query builder is created using `query()` or `$query()` methods.
* You can override this to use your own `QueryBuilder` subclass.
*/

@@ -565,2 +602,10 @@ Model.QueryBuilder = QueryBuilder;

/**
* QueryBuilder subclass to use in `$relatedQuery()` method.
*
* This constructor is used whenever a query builder is created using the `$relatedQuery()` method.
* You can override this to use your own `QueryBuilder` subclass.
*/
Model.RelatedQueryBuilder = QueryBuilder;
/**
* one-to-many relation type.

@@ -827,14 +872,2 @@ *

.forClass(ModelClass)
.insertImpl(function (models) {
ModelClass.$$insert(this, models);
})
.updateImpl(function (update) {
ModelClass.$$update(this, update);
})
.patchImpl(function (patch) {
ModelClass.$$patch(this, patch);
})
.deleteImpl(function () {
ModelClass.$$delete(this);
})
.relateImpl(function () {

@@ -895,2 +928,10 @@ throw new Error('`relate` makes no sense in this context');

/**
* Shortcut for `SomeModel.knex().fn`.
*/
Model.fn = function () {
var knex = this.knex();
return knex.fn;
};
/**
* Shortcut for `SomeModel.knex().client.formatter()`.

@@ -1034,10 +1075,13 @@ *

input = ensureArray(input);
var models = new Array(input.length);
if (_.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);
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)];
}
return models;
};

@@ -1200,112 +1244,2 @@

*/
Model.$$insert = function (builder, $models) {
if (_.isArray($models) && $models.length > 1 && !utils.isPostgres(this.knex())) {
throw new Error('batch insert only works with Postgresql');
}
var ModelClass = this;
var models = ModelClass.ensureModelArray($models);
var json = _.map(models, function (model) {
var id = ModelClass.generateId();
if (!_.isNull(id)) {
model.$id(id);
}
model.$beforeInsert();
return model.$toDatabaseJson();
});
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);
}
return builder.insert(json).runAfterModelCreatePushFront(function (ret) {
// If the user specified a `returning` clause the result may already be
// an array of models.
if (!_.isEmpty(ret) && _.isObject(ret[0])) {
_.each(models, function (model, index) {
model.$set(ret[index]);
// The returning clause must return at least the identifier.
if (!model.$id()) {
throw new Error('the identifier column "' + ModelClass.idColumn + '"' +
' must be listed in the `returning` clause. (`returning *` is fine also)');
}
});
} else {
// If the return value is not an array of models, it is an array of identifiers.
_.each(models, function (model, idx) {
model.$id(ret[idx]);
});
}
_.each(models, function (model) {
model.$afterInsert();
});
if (_.isArray($models)) {
return models;
} else {
return models[0];
}
});
};
/**
* @protected
* @returns {QueryBuilder}
*/
Model.$$update = function (builder, $update) {
return this.$$updateWithOptions(builder, $update);
};
/**
* @protected
* @returns {QueryBuilder}
*/
Model.$$patch = function (builder, $patch) {
return this.$$updateWithOptions(builder, $patch, {patch: true});
};
/**
* @private
* @returns {QueryBuilder}
*/
Model.$$updateWithOptions = function (builder, $update, options) {
if (!$update) {
return builder;
}
var ModelClass = this;
$update = ModelClass.ensureModel($update, options);
$update.$beforeUpdate(options);
// We never want to change the identifier of a model. Delete it from the copy.
var update = $update.$clone();
delete update[ModelClass.getIdProperty()];
return builder.update(update.$toDatabaseJson()).runAfterModelCreatePushFront(function () {
$update.$afterUpdate(options);
return $update;
});
};
/**
* @protected
* @returns {QueryBuilder}
*/
Model.$$delete = function (builder) {
return builder.delete().runAfterModelCreatePushFront(function () {
return {};
});
};
/**
* @protected
* @returns {QueryBuilder}
*/
Model.$$omitNonColumns = function (json) {

@@ -1312,0 +1246,0 @@ if (this.jsonSchema) {

@@ -390,2 +390,12 @@ "use strict";

/**
* @private
*/
ModelBase.$$colToProp = null;
/**
* @private
*/
ModelBase.$$propToCol = null;
/**
* Makes the given constructor a subclass of this class.

@@ -457,3 +467,29 @@ *

/**
* @ignore
* @param {string} columnName
* @returns {string}
*/
ModelBase.columnNameToPropertyName = function (columnName) {
this.$$propToCol = this.$$propToCol || Object.create(null);
this.$$colToProp = this.$$colToProp || Object.create(null);
if (this.$$colToProp[columnName]) {
return this.$$colToProp[columnName];
}
var propertyName = this.$$columnNameToPropertyName(columnName);
this.$$propToCol[propertyName] = columnName;
this.$$colToProp[columnName] = propertyName;
return propertyName;
};
/**
* @ignore
* @param {string} columnName
* @returns {string}
*/
ModelBase.$$columnNameToPropertyName = function (columnName) {
var row = {};

@@ -476,3 +512,29 @@ var value = uuid.v4();

/**
* @ignore
* @param {string} propertyName
* @returns {string}
*/
ModelBase.propertyNameToColumnName = function (propertyName) {
this.$$propToCol = this.$$propToCol || Object.create(null);
this.$$colToProp = this.$$colToProp || Object.create(null);
if (this.$$propToCol[propertyName]) {
return this.$$propToCol[propertyName];
}
var columnName = this.$$propertyNameToColumnName(propertyName);
this.$$propToCol[propertyName] = columnName;
this.$$colToProp[columnName] = propertyName;
return columnName;
};
/**
* @ignore
* @param {string} propertyName
* @returns {string}
*/
ModelBase.$$propertyNameToColumnName = function (propertyName) {
var model = {};

@@ -479,0 +541,0 @@ var value = uuid.v4();

@@ -58,17 +58,38 @@ 'use strict';

*/
ManyToManyRelation.prototype.find = function (builder, $owners) {
ManyToManyRelation.prototype.join = function (builder, joinMethod) {
joinMethod = joinMethod || 'join';
var joinTable = this.joinTable;
var relatedTable = this.relatedModelClass.tableName;
var joinTableAlias = this.joinTableAlias();
var relatedTableAlias = this.relatedTableAlias();
return builder
[joinMethod](joinTable + ' as ' + joinTableAlias, joinTableAlias + '.' + this.joinTableOwnerCol, this.fullOwnerCol())
[joinMethod](relatedTable + ' as ' + relatedTableAlias, joinTableAlias + '.' + this.joinTableRelatedCol, relatedTableAlias + '.' + this.relatedCol)
.call(this.filter);
};
/**
* @override
* @inheritDoc
*/
ManyToManyRelation.prototype.find = function (builder, owners) {
var self = this;
var owners = this.ownerModelClass.ensureModelArray($owners);
if (!builder.has('select')) {
builder.select(this.relatedModelClass.tableName + '.*');
}
builder.onBuild(function (builder) {
var ownerIds = _.pluck(owners, self.ownerProp);
var ownerJoinColumn = self.fullJoinTableOwnerCol();
// Add the statements that select the owners' rows.
this.findQuery(builder, _.unique(_.pluck(owners, this.ownerProp)));
if (!builder.has('select')) {
// If the user hasn't specified a select clause, select the related model's columns.
// If we don't do this we also get the join table's columns.
builder.select(self.relatedModelClass.tableName + '.*');
}
// Select the joined identifier of the owner model.
builder.select(this.fullJoinTableOwnerCol() + ' as ' + ownerJoinColumnAlias);
self.findQuery(builder, ownerIds).select(ownerJoinColumn + ' as ' + ownerJoinColumnAlias);
});
return builder.runAfterModelCreate(function (related) {
builder.runAfterModelCreate(function (related) {
var relatedByOwnerId = _.groupBy(related, ownerJoinColumnAlias);

@@ -91,35 +112,20 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.join = function (builder, joinMethod) {
joinMethod = joinMethod || 'join';
ManyToManyRelation.prototype.insert = function (builder, owner, insertion) {
var self = this;
var joinTable = this.joinTable;
var relatedTable = this.relatedModelClass.tableName;
builder.onBuild(function (builder) {
builder.$$insert(insertion);
});
var joinTableAlias = this.joinTableAlias();
var relatedTableAlias = this.relatedTableAlias();
builder.runAfterModelCreate(function (related) {
var ownerId = owner[self.ownerProp];
var relatedIds = _.pluck(related, self.relatedProp);
var joinRows = self._createJoinRows(ownerId, relatedIds);
return builder
[joinMethod](joinTable + ' as ' + joinTableAlias, joinTableAlias + '.' + this.joinTableOwnerCol, this.fullOwnerCol())
[joinMethod](relatedTable + ' as ' + relatedTableAlias, joinTableAlias + '.' + this.joinTableRelatedCol, relatedTableAlias + '.' + this.relatedCol)
.call(this.filter);
};
owner[self.name] = _.chain([owner[self.name], related])
.flatten()
.compact()
.value();
/**
* @override
* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.insert = function (builder, $owner, $insertion) {
var self = this;
var owner = this.ownerModelClass.ensureModel($owner);
// This adds the insert operation and the needed runAfter* methods.
this.relatedModelClass.$$insert(builder, $insertion);
return builder.runAfterModelCreate(function (related) {
var joinRows = self._createJoinRows(owner[self.ownerProp], _.isArray(related) ? _.pluck(related, self.relatedProp) : [related[self.relatedProp]]);
owner[self.name] = _.compact(_.flatten([owner[self.name], related]));
// Insert the join rows to the join table.

@@ -139,14 +145,14 @@ return self.relatedModelClass

* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.update = function (builder, $owner, $update) {
var owner = this.ownerModelClass.ensureModel($owner);
var idSelectQuery = this._makeFindIdQuery(owner[this.ownerProp]);
ManyToManyRelation.prototype.update = function (builder, owner, update) {
var self = this;
// This adds the update operation and the needed runAfter* methods.
this.relatedModelClass.$$update(builder, $update);
builder.onBuild(function (builder) {
var idSelectQuery = self._makeFindIdQuery(owner[self.ownerProp]);
return builder
.whereIn(this.relatedModelClass.getFullIdColumn(), idSelectQuery)
.call(this.filter);
builder
.$$update(update)
.whereIn(self.relatedModelClass.getFullIdColumn(), idSelectQuery)
.call(self.filter);
});
};

@@ -157,14 +163,5 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.patch = function (builder, $owner, $patch) {
var owner = this.ownerModelClass.ensureModel($owner);
var idSelectQuery = this._makeFindIdQuery(owner[this.ownerProp]);
// This adds the patch operation and the needed runAfter* methods.
this.relatedModelClass.$$patch(builder, $patch);
return builder
.whereIn(this.relatedModelClass.getFullIdColumn(), idSelectQuery)
.call(this.filter);
ManyToManyRelation.prototype.patch = function (builder, owner, patch) {
return this.update(builder, owner, patch);
};

@@ -175,14 +172,14 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.delete = function (builder, $owner) {
var owner = this.ownerModelClass.ensureModel($owner);
var idSelectQuery = this._makeFindIdQuery(owner[this.ownerProp]);
ManyToManyRelation.prototype.delete = function (builder, owner) {
var self = this;
// This adds the delete operation and the needed runAfter* methods.
this.relatedModelClass.$$delete(builder);
builder.onBuild(function (builder) {
var idSelectQuery = self._makeFindIdQuery(owner[self.ownerProp]);
return builder
.whereIn(this.relatedModelClass.getFullIdColumn(), idSelectQuery)
.call(this.filter);
builder
.$$delete()
.whereIn(self.relatedModelClass.getFullIdColumn(), idSelectQuery)
.call(self.filter);
});
};

@@ -193,15 +190,11 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.relate = function (builder, $owner, $ids) {
var owner = this.ownerModelClass.ensureModel($owner);
var joinRows = this._createJoinRows(owner[this.ownerProp], _.flatten([$ids]));
var arrayInput = _.isArray($ids);
ManyToManyRelation.prototype.relate = function (builder, owner, ids) {
var self = this;
// Insert join rows into the join table.
return builder.insert(joinRows).into(this.joinTable).returning('id').runAfterModelCreate(function (ids) {
_.each(joinRows, function (row, idx) {
row.id = ids[idx] || null;
});
return arrayInput ? joinRows : joinRows[0];
builder.onBuild(function (builder) {
var joinRows = self._createJoinRows(owner[self.ownerProp], ids);
// This is a bit weird: we make this query to the joinTable even though
// this query builder is bound to the related model class.
builder.$$insert(joinRows).into(self.joinTable);
});

@@ -213,25 +206,23 @@ };

* @inheritDoc
* @returns {QueryBuilder}
*/
ManyToManyRelation.prototype.unrelate = function (builder, $owner) {
ManyToManyRelation.prototype.unrelate = function (builder, owner) {
var self = this;
var owner = this.ownerModelClass.ensureModel($owner);
var idSelectQuery = builder
.clone()
.clear('select')
.clearCustomImpl()
.select(this.fullRelatedCol())
.call(this.filter);
builder.onBuild(function (builder) {
var idSelectQuery = builder.cloneWhereQuery().select(self.fullRelatedCol()).call(self.filter);
// Delete the join rows from the join table.
return builder
.clear()
.delete()
.from(self.joinTable)
.where(self.fullJoinTableOwnerCol(), owner[this.ownerProp])
.whereIn(self.fullJoinTableRelatedCol(), idSelectQuery.build())
.runAfterModelCreate(_.constant({}));
// This is a bit weird: we make this query to the joinTable even though
// this query builder is bound to the related model class.
builder
.clear()
.$$delete()
.from(self.joinTable)
.where(self.fullJoinTableOwnerCol(), owner[self.ownerProp])
.whereIn(self.fullJoinTableRelatedCol(), idSelectQuery);
});
};
/**
* @private
*/
ManyToManyRelation.prototype._makeFindIdQuery = function (ownerId) {

@@ -238,0 +229,0 @@ return this.ownerModelClass

@@ -41,8 +41,26 @@ 'use strict';

*/
OneToManyRelation.prototype.find = function (builder, $owners) {
OneToManyRelation.prototype.join = function (builder, joinMethod) {
joinMethod = joinMethod || 'join';
var relatedTable = this.relatedModelClass.tableName;
var relatedTableAlias = this.relatedTableAlias();
return builder
[joinMethod](relatedTable + ' as ' + relatedTableAlias, relatedTableAlias + '.' + this.relatedCol, this.fullOwnerCol())
.call(this.filter);
};
/**
* @override
* @inheritDoc
*/
OneToManyRelation.prototype.find = function (builder, owners) {
var self = this;
var owners = this.ownerModelClass.ensureModelArray($owners);
var ownerIds = _.unique(_.pluck(owners, this.ownerProp));
return this.findQuery(builder, ownerIds).runAfterModelCreate(function (related) {
builder.onBuild(function (builder) {
self.findQuery(builder, ownerIds);
});
builder.runAfterModelCreate(function (related) {
var relatedByOwnerId = _.groupBy(related, self.relatedProp);

@@ -61,13 +79,18 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToManyRelation.prototype.join = function (builder, joinMethod) {
joinMethod = joinMethod || 'join';
OneToManyRelation.prototype.insert = function (builder, owner, insertion) {
var self = this;
var relatedTable = this.relatedModelClass.tableName;
var relatedTableAlias = this.relatedTableAlias();
_.each(insertion.models(), function (insert) {
insert[self.relatedProp] = owner[self.ownerProp];
});
return builder
[joinMethod](relatedTable + ' as ' + relatedTableAlias, relatedTableAlias + '.' + this.relatedCol, this.fullOwnerCol())
.call(this.filter);
builder.onBuild(function (builder) {
builder.$$insert(insertion);
});
builder.runAfterModelCreate(function (models) {
owner[self.name] = _.compact(_.flatten([owner[self.name], models]));
return models;
});
};

@@ -78,17 +101,10 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToManyRelation.prototype.insert = function (builder, $owner, $insertion) {
OneToManyRelation.prototype.update = function (builder, owner, update) {
var self = this;
var owner = this.ownerModelClass.ensureModel($owner);
var insertion = this.relatedModelClass.ensureModelArray($insertion);
_.each(insertion, function (insert) {
insert[self.relatedProp] = owner[self.ownerProp];
builder.onBuild(function (builder) {
self.findQuery(builder, owner[self.ownerProp]);
builder.$$update(update);
});
return this.relatedModelClass.$$insert(builder, insertion).runAfterModelCreate(function (models) {
owner[self.name] = _.compact(_.flatten([owner[self.name], models]));
return _.isArray($insertion) ? models : models[0];
});
};

@@ -99,11 +115,5 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToManyRelation.prototype.update = function (builder, $owner, $update) {
var owner = this.ownerModelClass.ensureModel($owner);
this.findQuery(builder, [owner[this.ownerProp]]);
this.relatedModelClass.$$update(builder, $update);
return builder;
OneToManyRelation.prototype.patch = function (builder, owner, patch) {
return this.update(builder, owner, patch);
};

@@ -114,11 +124,10 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToManyRelation.prototype.patch = function (builder, $owner, $patch) {
var owner = this.ownerModelClass.ensureModel($owner);
OneToManyRelation.prototype.delete = function (builder, owner) {
var self = this;
this.findQuery(builder, [owner[this.ownerProp]]);
this.relatedModelClass.$$patch(builder, $patch);
return builder;
builder.onBuild(function (builder) {
self.findQuery(builder, owner[self.ownerProp]);
builder.$$delete();
});
};

@@ -129,11 +138,28 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToManyRelation.prototype.delete = function (builder, $owner) {
var owner = this.ownerModelClass.ensureModel($owner);
OneToManyRelation.prototype.relate = function (builder, owner, ids) {
var self = this;
this.findQuery(builder, [owner[this.ownerProp]]);
this.relatedModelClass.$$delete(builder);
builder.onBuild(function (builder) {
var patch = relatePatch(self, owner[self.ownerProp]);
return builder;
// We build the input query, but we never actually execute it. Instead we resolve it here.
// This query is not executed, because it would not invoke the $beforeUpdate and $afterUpdate
// hooks. We build it so that toSql(), toString() etc. return the correct string.
builder
.$$update(patch)
.whereIn(self.relatedModelClass.getFullIdColumn(), ids)
.resolve(ids);
});
builder.runAfterModelCreatePushFront(function (input) {
var patch = relatePatch(self, owner[self.ownerProp]);
// Here we execute the actual update query.
return self.relatedModelClass
.query()
.patch(patch)
.whereIn(self.relatedModelClass.getFullIdColumn(), ids)
.return(input);
});
};

@@ -144,38 +170,41 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToManyRelation.prototype.relate = function (builder, $owner, $ids) {
var owner = this.ownerModelClass.ensureModel($owner);
OneToManyRelation.prototype.unrelate = function (builder, owner) {
var self = this;
var patch = {};
patch[this.relatedProp] = owner[this.ownerProp];
builder.onBuild(function (builder) {
var patch = relatePatch(self, null);
return this.relatedModelClass
.$$patch(builder, patch)
.whereIn(this.relatedModelClass.getFullIdColumn(), _.flatten([$ids]))
.runAfterModelCreate(function () {
return $ids;
});
// We build the input query, but we never actually execute it. Instead we resolve it here.
// This query is not executed, because it would not invoke the $beforeUpdate and $afterUpdate
// hooks. We build it so that toSql(), toString() etc. return the correct string.
builder
.$$update(patch)
.where(self.fullRelatedCol(), owner[self.ownerProp])
.call(self.filter)
.resolve({});
});
builder.runAfterModelCreatePushFront(function (input) {
var builder = this;
var patch = relatePatch(self, null);
// Here we execute the actual update query.
return self.relatedModelClass
.query()
.patch(patch)
.copyFrom(builder.cloneWhereQuery())
.return(input);
});
};
/**
* @override
* @inheritDoc
* @returns {QueryBuilder}
* @private
*/
OneToManyRelation.prototype.unrelate = function (builder, $owner) {
var owner = this.ownerModelClass.ensureModel($owner);
function relatePatch(relation, value) {
var patch = {};
patch[this.relatedProp] = null;
patch[relation.relatedProp] = value;
return patch;
}
return this.relatedModelClass
.$$patch(builder, patch)
.where(this.fullRelatedCol(), owner[this.ownerProp])
.call(this.filter)
.runAfterModelCreate(function () {
return {};
});
};
module.exports = OneToManyRelation;

@@ -27,3 +27,3 @@ 'use strict';

if (_.isArray(ownerCol)) {
builder.whereIn(this.fullRelatedCol(), ownerCol);
builder.whereIn(this.fullRelatedCol(), _.compact(ownerCol));
} else {

@@ -42,8 +42,26 @@ builder.where(this.fullRelatedCol(), ownerCol)

*/
OneToOneRelation.prototype.find = function (builder, $owners) {
OneToOneRelation.prototype.join = function (builder, joinMethod) {
joinMethod = joinMethod || 'join';
var relatedTable = this.relatedModelClass.tableName;
var relatedTableAlias = this.relatedTableAlias();
return builder
[joinMethod](relatedTable + ' as ' + relatedTableAlias, relatedTableAlias + '.' + this.relatedCol, this.fullOwnerCol())
.call(this.filter);
};
/**
* @override
* @inheritDoc
*/
OneToOneRelation.prototype.find = function (builder, owners) {
var self = this;
var owners = this.ownerModelClass.ensureModelArray($owners);
var relatedIds = _.unique(_.compact(_.pluck(owners, this.ownerProp)));
return this._makeFindQuery(builder, relatedIds).runAfterModelCreate(function (related) {
builder.onBuild(function (builder) {
var relatedIds = _.unique(_.compact(_.pluck(owners, self.ownerProp)));
self._makeFindQuery(builder, relatedIds);
});
builder.runAfterModelCreate(function (related) {
var relatedById = _.indexBy(related, self.relatedProp);

@@ -60,32 +78,26 @@

/**
* @override
* @inheritDoc
* @returns {QueryBuilder}
* Person
* .query()
* .update({
* age: Person.query().avg('age'),
*
* })
*/
OneToOneRelation.prototype.join = function (builder, joinMethod) {
joinMethod = joinMethod || 'join';
var relatedTable = this.relatedModelClass.tableName;
var relatedTableAlias = this.relatedTableAlias();
return builder
[joinMethod](relatedTable + ' as ' + relatedTableAlias, relatedTableAlias + '.' + this.relatedCol, this.fullOwnerCol())
.call(this.filter);
};
/**
* @override
* @inheritDoc
* @returns {QueryBuilder}
*/
OneToOneRelation.prototype.insert = function (builder, $owner, $insertion) {
OneToOneRelation.prototype.insert = function (builder, owner, insertion) {
var self = this;
var owner = this.ownerModelClass.ensureModel($owner);
var insertion = this.relatedModelClass.ensureModelArray($insertion);
if (insertion.length > 1) {
if (insertion.models().length > 1) {
throw new Error('can only insert one model to a OneToOneRelation');
}
return this.relatedModelClass.$$insert(builder, insertion).runAfterModelCreate(function (inserted) {
builder.onBuild(function (builder) {
builder.$$insert(insertion);
});
builder.runAfterModelCreate(function (inserted) {
owner[self.ownerProp] = inserted[0][self.relatedProp];

@@ -96,3 +108,2 @@ owner[self.name] = inserted[0];

patch[self.ownerProp] = inserted[0][self.relatedProp];
owner[self.ownerProp] = inserted[0][self.relatedProp];

@@ -103,5 +114,3 @@ return self.ownerModelClass

.where(self.ownerModelClass.getFullIdColumn(), owner.$id())
.then(function () {
return _.isArray($insertion) ? inserted : inserted[0];
});
.return(inserted);
});

@@ -113,11 +122,10 @@ };

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToOneRelation.prototype.update = function (builder, $owner, $update) {
var owner = this.ownerModelClass.ensureModel($owner);
OneToOneRelation.prototype.update = function (builder, owner, update) {
var self = this;
this._makeFindQuery(builder, [owner[this.ownerProp]]);
this.relatedModelClass.$$update(builder, $update);
return builder;
builder.onBuild(function (builder) {
self._makeFindQuery(builder, owner[self.ownerProp]);
builder.$$update(update);
});
};

@@ -128,11 +136,5 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToOneRelation.prototype.patch = function (builder, $owner, $patch) {
var owner = this.ownerModelClass.ensureModel($owner);
this._makeFindQuery(builder, [owner[this.ownerProp]]);
this.relatedModelClass.$$patch(builder, $patch);
return builder;
OneToOneRelation.prototype.patch = function (builder, owner, patch) {
return this.update(builder, owner, patch);
};

@@ -143,11 +145,10 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToOneRelation.prototype.delete = function (builder, $owner) {
var owner = this.ownerModelClass.ensureModel($owner);
OneToOneRelation.prototype.delete = function (builder, owner) {
var self = this;
this._makeFindQuery(builder, [owner[this.ownerProp]]);
this.relatedModelClass.$$delete(builder);
return builder;
builder.onBuild(function (builder) {
self._makeFindQuery(builder, owner[self.ownerProp]);
builder.$$delete();
});
};

@@ -158,7 +159,5 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToOneRelation.prototype.relate = function (builder, $owner, $ids) {
var owner = this.ownerModelClass.ensureModel($owner);
var ids = _.flatten([$ids]);
OneToOneRelation.prototype.relate = function (builder, owner, ids) {
var self = this;

@@ -169,13 +168,30 @@ if (ids.length > 1) {

var patch = {};
patch[this.ownerProp] = ids[0];
owner[this.ownerProp] = ids[0];
builder.onBuild(function (builder) {
var patch = {};
patch[self.ownerProp] = ids[0];
owner[self.ownerProp] = ids[0];
return this.ownerModelClass
.$$patch(builder, patch)
.from(this.ownerModelClass.tableName)
.where(this.ownerModelClass.getFullIdColumn(), owner.$id())
.runAfterModelCreate(function () {
return $ids;
});
// We build the input query, but we never actually execute it. Instead we resolve it here.
// This query is not executed, because it would not invoke the $beforeUpdate and $afterUpdate
// hooks. We build it so that toSql(), toString() etc. return the correct string.
builder
.$$update(patch)
.from(self.ownerModelClass.tableName)
.where(self.ownerModelClass.getFullIdColumn(), owner.$id())
.call(self.filter)
.resolve({});
});
builder.runAfterModelCreatePushFront(function (input) {
var builder = this;
var patch = {};
patch[self.ownerProp] = ids[0];
// Here we execute the actual update query.
return self.ownerModelClass
.query()
.patch(patch)
.copyFrom(builder.cloneWhereQuery())
.return(input);
});
};

@@ -186,18 +202,34 @@

* @inheritDoc
* @returns {QueryBuilder}
*/
OneToOneRelation.prototype.unrelate = function (builder, $owner) {
var owner = this.ownerModelClass.ensureModel($owner);
OneToOneRelation.prototype.unrelate = function (builder, owner) {
var self = this;
var patch = {};
patch[this.ownerProp] = null;
owner[this.ownerProp] = null;
builder.onBuild(function (builder) {
var patch = {};
patch[self.ownerProp] = null;
owner[self.ownerProp] = null;
return this.ownerModelClass
.$$patch(builder, patch)
.from(this.ownerModelClass.tableName)
.where(this.ownerModelClass.getFullIdColumn(), owner.$id())
.runAfterModelCreate(function () {
return {};
});
// We build the input query, but we never actually execute it. Instead we resolve it here.
// This query is not executed, because it would not invoke the $beforeUpdate and $afterUpdate
// hooks. We build it so that toSql(), toString() etc. return the correct string.
builder
.$$update(patch)
.from(self.ownerModelClass.tableName)
.where(self.ownerModelClass.getFullIdColumn(), owner.$id())
.call(self.filter)
.resolve({});
});
builder.runAfterModelCreatePushFront(function (input) {
var builder = this;
var patch = {};
patch[self.ownerProp] = null;
// Here we execute the actual update query.
return self.ownerModelClass
.query()
.patch(patch)
.copyFrom(builder.cloneWhereQuery())
.return(input);
});
};

@@ -209,5 +241,3 @@

OneToOneRelation.prototype._makeFindQuery = function (builder, relatedIds) {
relatedIds = _.compact(relatedIds);
if (_.isEmpty(relatedIds)) {
if ((_.isArray(relatedIds) && _.isEmpty(relatedIds)) || !relatedIds) {
return builder.resolve([]);

@@ -214,0 +244,0 @@ } else {

@@ -416,6 +416,6 @@ 'use strict';

* @param {QueryBuilder} builder
* @param {Model|Object|Array.<Model>|Array.<Object>} $owners
* @param {string} joinMethod
* @returns {QueryBuilder}
*/
Relation.prototype.find = function (builder, $owners) {
Relation.prototype.join = function (builder, joinMethod) {
throw new Error('not implemented');

@@ -428,6 +428,5 @@ };

* @param {QueryBuilder} builder
* @param {string} joinMethod
* @returns {QueryBuilder}
* @param {Model|Object|Array.<Model>|Array.<Object>} owners
*/
Relation.prototype.join = function (builder, joinMethod) {
Relation.prototype.find = function (builder, owners) {
throw new Error('not implemented');

@@ -439,7 +438,6 @@ };

* @param {QueryBuilder} builder
* @param {Model|Object} $owner
* @param {Model|Object|Array.<Model>|Array.<Object>} $insertion
* @returns {QueryBuilder}
* @param {Model|Object} owner
* @param {InsertionOrUpdate} insertion
*/
Relation.prototype.insert = function (builder, $owner, $insertion) {
Relation.prototype.insert = function (builder, owner, insertion) {
throw new Error('not implemented');

@@ -452,7 +450,6 @@ };

* @param {QueryBuilder} builder
* @param {Model|Object} $owner
* @param {Model|Object} $update
* @returns {QueryBuilder}
* @param {Model|Object} owner
* @param {InsertionOrUpdate} update
*/
Relation.prototype.update = function (builder, $owner, $update) {
Relation.prototype.update = function (builder, owner, update) {
return builder;

@@ -465,7 +462,6 @@ };

* @param {QueryBuilder} builder
* @param {Model|Object} $owner
* @param {Model|Object} $patch
* @returns {QueryBuilder}
* @param {Model|Object} owner
* @param {InsertionOrUpdate} patch
*/
Relation.prototype.patch = function (builder, $owner, $patch) {
Relation.prototype.patch = function (builder, owner, patch) {
throw new Error('not implemented');

@@ -478,6 +474,5 @@ };

* @param {QueryBuilder} builder
* @param {Model|Object} $owner
* @returns {QueryBuilder}
* @param {Model|Object} owner
*/
Relation.prototype.delete = function (builder, $owner) {
Relation.prototype.delete = function (builder, owner) {
throw new Error('not implemented');

@@ -490,7 +485,6 @@ };

* @param {QueryBuilder} builder
* @param {Model|Object} $owner
* @param {Model|Object} owner
* @param {number|string|Array.<number>|Array.<string>} ids
* @returns {QueryBuilder}
*/
Relation.prototype.relate = function (builder, $owner, ids) {
Relation.prototype.relate = function (builder, owner, ids) {
throw new Error('not implemented');

@@ -503,6 +497,5 @@ };

* @param {QueryBuilder} builder
* @param {Model|Object} $owner
* @returns {QueryBuilder}
* @param {Model|Object} owner
*/
Relation.prototype.unrelate = function (builder, $owner) {
Relation.prototype.unrelate = function (builder, owner) {
throw new Error('not implemented');

@@ -509,0 +502,0 @@ };

{
"name": "objection",
"version": "0.2.1",
"version": "0.2.2",
"description": "An SQL-friendly ORM for Node.js",

@@ -5,0 +5,0 @@ "main": "objection.js",

@@ -653,2 +653,8 @@ [![Build Status](https://travis-ci.org/Vincit/objection.js.svg?branch=master)](https://travis-ci.org/Vincit/objection.js) [![Coverage Status](https://coveralls.io/repos/Vincit/objection.js/badge.svg?branch=master&service=github)](https://coveralls.io/github/Vincit/objection.js?branch=master)

## 0.2.1
### What's new
* bugfix: Chaining `insert` with `returning` now returns all listed columns.
## 0.2.0

@@ -655,0 +661,0 @@

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc