Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

objection

Package Overview
Dependencies
Maintainers
2
Versions
201
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.8.3 to 0.8.4

lib/model/modelBindKnex.js

13

lib/model/AjvValidator.js

@@ -12,6 +12,8 @@ 'use strict';

this.ajv = new Ajv(Object.assign({
this.ajvOptions = Object.assign({
useDefaults: true
}, conf.options));
}, conf.options);
this.ajv = new Ajv(this.ajvOptions);
this.ajvNoDefaults = new Ajv(Object.assign({}, conf.options, {

@@ -35,3 +37,3 @@ useDefaults: false

if (model.$beforeValidate !== model.objectionModelClass.prototype.$beforeValidate) {
if (model.$beforeValidate !== model.$objectionModelClass.prototype.$beforeValidate) {
ctx.jsonSchema = cloneDeep(ctx.jsonSchema);

@@ -68,2 +70,5 @@ ctx.jsonSchema = model.$beforeValidate(ctx.jsonSchema, json, options);

getValidator(ModelClass, jsonSchema, skipRequired) {
// Use the AJV custom serializer if provided.
const serialize = this.ajvOptions.serialize || JSON.stringify;
// Optimization for the common case where jsonSchema is never modified.

@@ -73,3 +78,3 @@ // In that case we don't need to call the costly JSON.stringify.

? 'default'
: JSON.stringify(jsonSchema);
: serialize(jsonSchema);

@@ -76,0 +81,0 @@ let validators = this.cache[key];

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

module.exports = (ModelClass) => {
function inheritModel(ModelClass) {
let inherit = cache[ModelClass.name];

@@ -24,3 +24,7 @@

module.exports = {
inheritModel
};
'use strict';
const cloneDeep = require('lodash/cloneDeep');
const difference = require('lodash/difference');
const flattenDeep = require('lodash/flattenDeep');
const $id = require('./modelId').$id;
const $set = require('./modelSet').$set;
const $omit = require('./modelFilter').$omit;
const $pick = require('./modelFilter').$pick;
const $clone = require('./modelClone').$clone;
const $toJson = require('./modelToJson').$toJson;
const $values = require('./modelValues').$values;
const $setJson = require('./modelSet').$setJson;
const $propKey = require('./modelValues').$propKey;
const $validate = require('./modelValidate').$validate;
const $toDatabaseJson = require('./modelToJson').$toDatabaseJson;
const $setDatabaseJson = require('./modelSet').$setDatabaseJson;
const bindKnex = require('./modelBindKnex').bindKnex;
const visitModels = require('./modelVisitor').visitModels;
const AjvValidator = require('./AjvValidator');
const QueryBuilder = require('../queryBuilder/QueryBuilder');
const inheritModel = require('./inheritModel');
const NotFoundError = require('./NotFoundError');
const ValidationError = require('./ValidationError');
const getJsonAttributes = require('./modelJsonAttributes').getJsonAttributes;
const parseJsonAttributes = require('./modelJsonAttributes').parseJsonAttributes;
const formatJsonAttributes = require('./modelJsonAttributes').formatJsonAttributes;
const idColumnToIdProperty = require('./modelColPropMap').idColumnToIdProperty;
const columnNameToPropertyName = require('./modelColPropMap').columnNameToPropertyName;
const propertyNameToColumnName = require('./modelColPropMap').propertyNameToColumnName;
const defineNonEnumerableProperty = require('./modelUtils').defineNonEnumerableProperty;

@@ -30,16 +46,2 @@ const Relation = require('../relations/Relation');

const staticHiddenProps = [
'$$knex',
'$$validator',
'$$jsonSchema',
'$$colToProp',
'$$propToCol',
'$$idColumnArray',
'$$fullIdColumn',
'$$idPropertyArray',
'$$idProperty',
'$$relations',
'$$relationArray'
];
const JoinEagerAlgorithm = () => {

@@ -59,7 +61,7 @@ return new JoinEagerOperation('eager');

get isObjectionModel() {
get $isObjectionModel() {
return true;
}
get objectionModelClass() {
get $objectionModelClass() {
return Model;

@@ -69,7 +71,3 @@ }

$id() {
if (arguments.length > 0) {
return setId(this, arguments[0]);
} else {
return getId(this);
}
return $id.apply(this, arguments);
}

@@ -146,30 +144,3 @@

$validate(json, options) {
json = json || this;
options = options || {};
if (json instanceof Model) {
// Strip away relations and other internal stuff.
json = clone(json, true, true);
// We can mutate `json` now that we took a copy of it.
options.mutable = true;
}
if (options.skipValidation) {
return json;
}
const ModelClass = this.constructor;
const validator = ModelClass.getValidator();
const args = {
options: options,
model: this,
json: json,
ctx: Object.create(null)
};
validator.beforeValidate(args);
json = validator.validate(args);
validator.afterValidate(args);
return json;
return $validate.call(this, json, options);
}

@@ -182,43 +153,7 @@

$parseDatabaseJson(json) {
const ModelClass = this.constructor;
const jsonAttr = ModelClass.getJsonAttributes();
if (jsonAttr.length) {
// JSON attributes may be returned as strings depending on the database and
// the database client. Convert them to objects here.
for (let i = 0, l = jsonAttr.length; i < l; ++i) {
const attr = jsonAttr[i];
const value = json[attr];
if (typeof value === 'string') {
const parsed = tryParseJson(value);
// tryParseJson returns undefined if parsing failed.
if (parsed !== undefined) {
json[attr] = parsed;
}
}
}
}
return json;
return parseJsonAttributes(json, this.constructor);
}
$formatDatabaseJson(json) {
const ModelClass = this.constructor;
const jsonAttr = ModelClass.getJsonAttributes();
if (jsonAttr.length) {
// All database clients want JSON columns as strings. Do the conversion here.
for (let i = 0, l = jsonAttr.length; i < l; ++i) {
const attr = jsonAttr[i];
const value = json[attr];
if (value && typeof value === 'object') {
json[attr] = JSON.stringify(value);
}
}
}
return json;
return formatJsonAttributes(json, this.constructor);
}

@@ -235,181 +170,81 @@

$setJson(json, options) {
json = json || {};
options = options || {};
if (Object.prototype.toString.call(json) !== '[object Object]') {
throw new Error('You should only pass objects to $setJson method. '
+ '$setJson method was given an invalid value '
+ json);
}
json = this.$parseJson(json, options);
json = this.$validate(json, options);
this.$set(json);
if (!options.skipParseRelations) {
parseRelationsIntoModelInstances(this, json, options);
}
return $setJson.call(this, json, options);
}
$setDatabaseJson(json) {
json = this.$parseDatabaseJson(json);
if (json) {
const keys = Object.keys(json);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
this[key] = json[key];
}
}
return this;
return $setDatabaseJson.call(this, json);
}
$set(obj) {
if (obj) {
const keys = Object.keys(obj);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
const value = obj[key];
if (key.charAt(0) !== '$' && typeof value !== 'function') {
this[key] = value;
}
}
}
return this;
return $set.call(this, obj);
}
$toJson(shallow) {
const ModelClass = this.constructor;
if (shallow) {
return toJson(this, false, ModelClass.getRelations(), null);
} else {
return toJson(this, false, null, null);
}
return $toJson.call(this, shallow);
}
toJSON() {
return this.$toJson(false);
return $toJson.call(this, false);
}
$toDatabaseJson() {
const ModelClass = this.constructor;
const jsonSchema = ModelClass.getJsonSchema();
return $toDatabaseJson.call(this);
}
if (jsonSchema && ModelClass.pickJsonSchemaProperties) {
return toJson(this, true, null, jsonSchema.properties);
} else {
return toJson(this, true, ModelClass.getRelations(), null);
}
$beforeInsert(queryContext) {
// Do nothing by default.
}
$beforeInsert(queryContext) {}
$afterInsert(queryContext) {}
$beforeUpdate(opt, queryContext) {}
$afterUpdate(opt, queryContext) {}
$afterGet(queryContext) {}
$beforeDelete(queryContext) {}
$afterDelete(queryContext) {}
$afterInsert(queryContext) {
// Do nothing by default.
}
$traverse(filterConstructor, callback) {
if (callback === undefined) {
callback = filterConstructor;
filterConstructor = null;
}
$beforeUpdate(opt, queryContext) {
// Do nothing by default.
}
this.constructor.traverse(filterConstructor, this, callback);
return this;
$afterUpdate(opt, queryContext) {
// Do nothing by default.
}
$omit() {
if (arguments.length === 1 && arguments[0] && typeof arguments[0] === 'object') {
const keys = arguments[0];
$afterGet(queryContext) {
// Do nothing by default.
}
if (Array.isArray(keys)) {
omitArray(this, keys);
} else {
omitObject(this, keys);
}
} else {
const keys = new Array(arguments.length);
$beforeDelete(queryContext) {
// Do nothing by default.
}
for (let i = 0, l = keys.length; i < l; ++i) {
keys[i] = arguments[i];
}
$afterDelete(queryContext) {
// Do nothing by default.
}
omitArray(this, keys);
}
return this;
$omit() {
return $omit.apply(this, arguments);
}
$pick() {
if (arguments.length === 1 && arguments[0] && typeof arguments[0] === 'object') {
const keys = arguments[0];
if (Array.isArray(keys)) {
pickArray(this, keys);
} else {
pickObject(this, keys);
}
} else {
const keys = new Array(arguments.length);
for (let i = 0, l = keys.length; i < l; ++i) {
keys[i] = arguments[i];
}
pickArray(this, keys);
}
return this;
return $pick.apply(this, arguments);
}
$values() {
if (arguments.length === 0) {
return Object.keys(this).map(key => this[key]);
} else {
if (arguments.length === 1 && Array.isArray(arguments[0])) {
return values(this, arguments[0]);
} else {
const args = new Array(arguments.length);
for (let i = 0, l = args.length; i < l; ++i) {
args[i] = arguments[i];
}
return values(this, args);
}
}
return $values.apply(this, arguments);
}
$propKey(props) {
switch (props.length) {
case 1: return this[props[0]] + '';
case 2: return this[props[0]] + ',' + this[props[1]];
case 3: return this[props[0]] + ',' + this[props[1]] + ',' + this[props[2]];
default: {
// Needs to be `var` instead of `let` to prevent a weird optimization bailout.
var key = '';
return $propKey.apply(this, arguments);
}
for (let i = 0, l = props.length; i < l; ++i) {
key += this[props[i]];
$clone(shallow) {
return $clone.call(this, shallow);
}
if (i < props.length - 1) {
key += ',';
}
}
return key;
}
$traverse(filterConstructor, callback) {
if (callback === undefined) {
callback = filterConstructor;
filterConstructor = null;
}
}
$clone(shallow) {
return clone(this, shallow, false);
this.constructor.traverse(filterConstructor, this, callback);
return this;
}

@@ -579,4 +414,6 @@

const mapping = relationMappings[relationName];
relations[relationName] = new mapping.relation(relationName, this);
relations[relationName].setMapping(mapping);
return relations;

@@ -648,52 +485,7 @@ }, Object.create(null));

static bindKnex(knex) {
const ModelClass = this;
// These are defined here to prevent a ridiculous optimization bailout
// because of "Unsupported phi use of const or let variable".
let BoundModelClass, relations, boundRelations, boundRelationArray;
if (!knex.$$objection) {
defineNonEnumerableProperty(knex, '$$objection', {
boundModels: Object.create(null)
});
}
// Check if this model class has already been bound to the given knex.
if (knex.$$objection.boundModels[ModelClass.uniqueTag()]) {
return knex.$$objection.boundModels[ModelClass.uniqueTag()];
}
// Create a new subclass of this class.
BoundModelClass = inheritModel(ModelClass);
for (let i = 0, l = staticHiddenProps.length; i < l; ++i) {
const prop = staticHiddenProps[i];
if (ModelClass.hasOwnProperty(prop)) {
defineNonEnumerableProperty(BoundModelClass, prop, ModelClass[prop]);
}
}
BoundModelClass.knex(knex);
knex.$$objection.boundModels[ModelClass.uniqueTag()] = BoundModelClass;
relations = ModelClass.getRelationArray();
boundRelations = Object.create(null);
boundRelationArray = [];
for (let i = 0, l = relations.length; i < l; ++i) {
const relation = relations[i];
const boundRelation = relation.bindKnex(knex);
boundRelations[relation.name] = boundRelation;
boundRelationArray.push(boundRelation);
}
defineNonEnumerableProperty(BoundModelClass, '$$relations', boundRelations);
defineNonEnumerableProperty(BoundModelClass, '$$relationArray', boundRelationArray);
return BoundModelClass;
return bindKnex(this, knex);
}
static bindTransaction(trx) {
return this.bindKnex(trx);
return bindKnex(this, trx);
}

@@ -783,35 +575,3 @@

static getJsonAttributes() {
// 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.getJsonSchema()) {
this.jsonAttributes = [];
const props = this.getJsonSchema().properties || {};
const propNames = Object.keys(props);
for (let i = 0, l = propNames.length; i < l; ++i) {
const propName = propNames[i];
const prop = props[propName];
let types = ensureArray(prop.type).filter(it => !!it);
if (types.length === 0 && Array.isArray(prop.anyOf)) {
types = flattenDeep(prop.anyOf.map(it => it.type));
}
if (types.length === 0 && Array.isArray(prop.oneOf)) {
types = flattenDeep(prop.oneOf.map(it => it.type));
}
if (types.indexOf('object') !== -1 || types.indexOf('array') !== -1) {
this.jsonAttributes.push(propName);
}
}
}
if (!Array.isArray(this.jsonAttributes)) {
this.jsonAttributes = [];
}
return this.jsonAttributes;
return getJsonAttributes(this);
}

@@ -851,45 +611,2 @@ }

function setId(model, id) {
const idProp = model.constructor.getIdProperty();
const isArray = Array.isArray(idProp);
if (Array.isArray(id)) {
if (isArray) {
if (id.length !== idProp.length) {
throw new Error('trying to set an invalid identifier for a model');
}
for (let i = 0; i < id.length; ++i) {
model[idProp[i]] = id[i];
}
} else {
if (id.length !== 1) {
throw new Error('trying to set an invalid identifier for a model');
}
model[idProp] = id[0];
}
} else {
if (isArray) {
if (idProp.length > 1) {
throw new Error('trying to set an invalid identifier for a model');
}
model[idProp[0]] = id;
} else {
model[idProp] = id;
}
}
}
function getId(model) {
const idProp = model.constructor.getIdProperty();
if (Array.isArray(idProp)) {
return model.$values(idProp);
} else {
return model[idProp];
}
}
function getIdColumnArray(ModelClass) {

@@ -920,363 +637,2 @@ if (Array.isArray(ModelClass.idColumn)) {

function parseRelationsIntoModelInstances(model, json, options) {
const ModelClass = model.constructor;
const relations = ModelClass.getRelationArray();
for (let i = 0, l = relations.length; i < l; ++i) {
const relation = relations[i];
const relationName = relation.name;
const relationJson = json[relationName];
if (relationJson !== undefined) {
if (Array.isArray(relationJson)) {
model[relationName] = relation.relatedModelClass.ensureModelArray(relationJson, options);
} else if (relationJson) {
model[relationName] = relation.relatedModelClass.ensureModel(relationJson, options);
} else {
model[relationName] = null;
}
}
}
}
function tryParseJson(maybeJsonStr) {
try {
return JSON.parse(maybeJsonStr);
} catch (err) {
// Ignore error.
}
return undefined;
}
function toJson(model, createDbJson, omit, pick) {
const json = toJsonImpl(model, createDbJson, omit, pick);
if (createDbJson) {
return model.$formatDatabaseJson(json);
} else {
return model.$formatJson(json);
}
}
function toJsonImpl(model, createDbJson, omit, pick) {
if (createDbJson) {
return toDatabaseJsonImpl(model, omit, pick);
} else {
return toExternalJsonImpl(model, omit, pick);
}
}
function toDatabaseJsonImpl(model, omit, pick) {
const json = {};
const omitFromJson = model.$omitFromDatabaseJson();
const keys = Object.keys(model);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
assignJsonValue(json, key, model[key], omit, pick, omitFromJson, true);
}
return json;
}
function toExternalJsonImpl(model, omit, pick) {
const json = {};
const omitFromJson = model.$omitFromJson();
const keys = Object.keys(model);
const vAttr = model.constructor.virtualAttributes;
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
const value = model[key];
assignJsonValue(json, key, value, omit, pick, omitFromJson, false);
}
if (vAttr) {
assignVirtualAttributes(json, model, vAttr, omit, pick, omitFromJson);
}
return json;
}
function assignVirtualAttributes(json, model, vAttr, omit, pick, omitFromJson) {
for (let i = 0, l = vAttr.length; i < l; ++i) {
const key = vAttr[i];
let value = model[key];
if (typeof value === 'function') {
value = value.call(model);
}
assignJsonValue(json, key, value, omit, pick, omitFromJson, false);
}
}
function assignJsonValue(json, key, value, omit, pick, omitFromJson, createDbJson) {
const type = typeof value;
if (key.charAt(0) !== '$'
&& type !== 'function'
&& type !== 'undefined'
&& (!omit || !omit[key])
&& (!pick || pick[key])
&& (!omitFromJson || !contains(omitFromJson, key))) {
if (value !== null && type === 'object') {
json[key] = toJsonObject(value, createDbJson);
} else {
json[key] = value;
}
}
}
function toJsonObject(value, createDbJson) {
if (Array.isArray(value)) {
return toJsonArray(value, createDbJson);
} else if (value instanceof Model) {
if (createDbJson) {
return value.$toDatabaseJson();
} else {
return value.$toJson();
}
} else if (Buffer.isBuffer(value)) {
return value;
} else {
return cloneDeep(value);
}
}
function toJsonArray(value, createDbJson) {
const ret = new Array(value.length);
for (let i = 0, l = ret.length; i < l; ++i) {
ret[i] = toJsonObject(value[i], createDbJson)
}
return ret;
}
function clone(model, shallow, stripInternal) {
let clone = null;
const omitFromJson = model.$omitFromJson();
const omitFromDatabaseJson = model.$omitFromDatabaseJson();
if (!shallow && !stripInternal) {
clone = cloneSimple(model);
} else {
clone = cloneWithOpt(model, shallow, stripInternal);
}
if (omitFromJson) {
clone.$omitFromJson(omitFromJson);
}
if (omitFromDatabaseJson) {
clone.$omitFromDatabaseJson(omitFromDatabaseJson);
}
return clone;
}
function cloneSimple(model) {
const clone = new model.constructor();
const keys = Object.keys(model);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
const value = model[key];
if (value !== null && typeof value === 'object') {
clone[key] = cloneObject(value);
} else {
clone[key] = value;
}
}
return clone;
}
function cloneWithOpt(model, shallow, stripInternal) {
const clone = new model.constructor();
const keys = Object.keys(model);
const relations = model.constructor.getRelations();
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
const value = model[key];
if (shallow && relations[key]) {
continue;
}
if (stripInternal && key.charAt(0) === '$') {
continue;
}
if (value !== null && typeof value === 'object') {
clone[key] = cloneObject(value);
} else {
clone[key] = value;
}
}
return clone;
}
function cloneObject(value) {
if (Array.isArray(value)) {
return cloneArray(value);
} else if (value instanceof Model) {
return clone(value, false, false);
} else if (Buffer.isBuffer(value)) {
return new Buffer(value);
} else {
return cloneDeep(value);
}
}
function cloneArray(value) {
const ret = new Array(value.length);
for (let i = 0, l = ret.length; i < l; ++i) {
ret[i] = cloneObject(value[i])
}
return ret;
}
function omitObject(model, keyObj) {
const ModelClass = model.constructor;
const keys = Object.keys(keyObj);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
const value = keyObj[key];
if (value && key.charAt(0) !== '$' && model.hasOwnProperty(key)) {
ModelClass.omitImpl(model, key);
}
}
}
function omitArray(model, keys) {
const ModelClass = model.constructor;
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
if (key.charAt(0) !== '$' && model.hasOwnProperty(key)) {
ModelClass.omitImpl(model, key);
}
}
}
function pickObject(model, keyObj) {
const ModelClass = model.constructor;
const keys = Object.keys(model);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
if (key.charAt(0) !== '$' && !keyObj[key]) {
ModelClass.omitImpl(model, key);
}
}
}
function pickArray(model, pick) {
const ModelClass = model.constructor;
const keys = Object.keys(model);
for (let i = 0, l = keys.length; i < l; ++i) {
const key = keys[i];
if (key.charAt(0) !== '$' && !contains(pick, key)) {
ModelClass.omitImpl(model, key);
}
}
}
function contains(arr, value) {
for (let i = 0, l = arr.length; i < l; ++i) {
if (arr[i] === value) {
return true;
}
}
return false;
}
function ensureArray(obj) {
if (Array.isArray(obj)) {
return obj;
} else {
return [obj];
}
}
function values(model, args) {
switch (args.length) {
case 1: return [model[args[0]]];
case 2: return [model[args[0]], model[args[1]]];
case 3: return [model[args[0]], model[args[1]], model[args[2]]];
default: {
const ret = new Array(args.length);
for (let i = 0, l = args.length; i < l; ++i) {
ret[i] = model[args[i]];
}
return ret;
}
}
}
function columnNameToPropertyName(ModelClass, columnName) {
const model = new ModelClass();
const addedProps = Object.keys(model.$parseDatabaseJson({}));
const row = {};
row[columnName] = null;
const props = Object.keys(model.$parseDatabaseJson(row));
const propertyName = difference(props, addedProps)[0];
return propertyName || null;
}
function propertyNameToColumnName(ModelClass, propertyName) {
const model = new ModelClass();
const addedCols = Object.keys(model.$formatDatabaseJson({}));
const obj = {};
obj[propertyName] = null;
const cols = Object.keys(model.$formatDatabaseJson(obj));
const columnName = difference(cols, addedCols)[0];
return columnName || null;
}
function idColumnToIdProperty(ModelClass, idColumn) {
const idProperty = ModelClass.columnNameToPropertyName(idColumn);
if (!idProperty) {
throw new Error(ModelClass.name + '.$parseDatabaseJson probably changes the value of the id column `' + idColumn + '` which is a no-no.');
}
return idProperty;
}
function defineNonEnumerableProperty(obj, prop, value) {
Object.defineProperty(obj, prop, {
enumerable: false,
writable: true,
configurable: true,
value
});
}
module.exports = Model;

@@ -9,2 +9,3 @@ 'use strict';

validate(args) {
/* istanbul ignore next */
throw new Error('not implemented');

@@ -11,0 +12,0 @@ }

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

buildForModel(modelClass, model, parentNode, rel, allowedRelations) {
if (!model || !model.isObjectionModel) {
if (!model || !model.$isObjectionModel) {
throw modelClass.createValidationError({notModel: 'not a model'});

@@ -228,3 +228,3 @@ }

const relations = node.modelClass.getRelations();
const isModel = obj && obj.isObjectionModel;
const isModel = obj && obj.$isObjectionModel;
const keys = Object.keys(obj);

@@ -231,0 +231,0 @@

@@ -22,28 +22,28 @@ 'use strict';

onBefore(builder, result) {
return this.delegate.onBefore(builder, result);
onBefore1(builder, result) {
return this.delegate.onBefore1(builder, result);
}
hasOnBefore() {
return this.onBefore !== DelegateOperation.prototype.onBefore || this.delegate.hasOnBefore();
hasOnBefore1() {
return this.onBefore1 !== DelegateOperation.prototype.onBefore1 || this.delegate.hasOnBefore1();
}
onBeforeInternal(builder, result) {
return this.delegate.onBeforeInternal(builder, result);
onBefore2(builder, result) {
return this.delegate.onBefore2(builder, result);
}
hasOnBeforeInternal() {
return this.onBeforeInternal !== DelegateOperation.prototype.onBeforeInternal || this.delegate.hasOnBeforeInternal();
hasOnBefore2() {
return this.onBefore2 !== DelegateOperation.prototype.onBefore2 || this.delegate.hasOnBefore2();
}
onBeforeBuild(builder) {
return this.delegate.onBeforeBuild(builder);
onBefore3(builder, result) {
return this.delegate.onBefore3(builder, result);
}
hasOnBeforeBuild() {
return this.onBeforeBuild !== DelegateOperation.prototype.onBeforeBuild || this.delegate.hasOnBeforeBuild();
hasOnBefore3() {
return this.onBefore3 !== DelegateOperation.prototype.onBefore3 || this.delegate.hasOnBefore3();
}
onBuild(knexBuilder, builder) {
return this.delegate.onBuild(knexBuilder, builder);
onBuild(builder) {
return this.delegate.onBuild(builder);
}

@@ -55,2 +55,10 @@

onBuildKnex(knexBuilder, builder) {
return this.delegate.onBuildKnex(knexBuilder, builder);
}
hasOnBuildKnex() {
return this.onBuildKnex !== DelegateOperation.prototype.onBuildKnex || this.delegate.hasOnBuildKnex();
}
onRawResult(builder, result) {

@@ -64,24 +72,24 @@ return this.delegate.onRawResult(builder, result);

onAfterQuery(builder, result) {
return this.delegate.onAfterQuery(builder, result);
onAfter1(builder, result) {
return this.delegate.onAfter1(builder, result);
}
hasOnAfterQuery() {
return this.onAfterQuery !== DelegateOperation.prototype.onAfterQuery || this.delegate.hasOnAfterQuery();
hasOnAfter1() {
return this.onAfter1 !== DelegateOperation.prototype.onAfter1 || this.delegate.hasOnAfter1();
}
onAfterInternal(builder, result) {
return this.delegate.onAfterInternal(builder, result);
onAfter2(builder, result) {
return this.delegate.onAfter2(builder, result);
}
hasOnAfterInternal() {
return this.onAfterInternal !== DelegateOperation.prototype.onAfterInternal || this.delegate.hasOnAfterInternal();
hasOnAfter2() {
return this.onAfter2 !== DelegateOperation.prototype.onAfter2 || this.delegate.hasOnAfter2();
}
onAfter(builder, result) {
return this.delegate.onAfter(builder, result);
onAfter3(builder, result) {
return this.delegate.onAfter3(builder, result);
}
hasOnAfter() {
return this.onAfter !== DelegateOperation.prototype.onAfter || this.delegate.hasOnAfter();
hasOnAfter3() {
return this.onAfter3 !== DelegateOperation.prototype.onAfter3 || this.delegate.hasOnAfter3();
}

@@ -88,0 +96,0 @@

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

onBeforeBuild(builder) {
onBuild(builder) {
builder.whereComposite(builder.fullIdColumnFor(builder.modelClass()), this.id).delete();

@@ -20,0 +20,0 @@ }

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

onBuild(knexBuilder, builder) {
onBuildKnex(knexBuilder) {
knexBuilder.delete();

@@ -15,0 +15,0 @@ }

@@ -41,7 +41,7 @@ 'use strict';

onBeforeInternal(builder) {
onBefore2(builder) {
return this.joinBuilder.fetchColumnInfo(builder);
}
onBeforeBuild(builder) {
onBuild(builder) {
builder.findOptions({

@@ -48,0 +48,0 @@ callAfterGetDeeply: true

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

if (!id) {
if (id === null) {
continue;

@@ -525,3 +525,3 @@ }

if (!val) {
if (isNullOrUndefined(val)) {
return null;

@@ -542,3 +542,3 @@ } else {

if (!val1 || !val2) {
if (isNullOrUndefined(val1) || isNullOrUndefined(val2)) {
return null;

@@ -561,3 +561,3 @@ } else {

if (!val1 || !val2 || !val3) {
if (isNullOrUndefined(val1) || isNullOrUndefined(val2) || isNullOrUndefined(val3)) {
return null;

@@ -577,3 +577,3 @@ } else {

if (!val) {
if (isNullOrUndefined(val)) {
return null;

@@ -589,2 +589,6 @@ }

function isNullOrUndefined(val) {
return val === null || val === undefined;
}
function createFilterQuery(args) {

@@ -591,0 +595,0 @@ const builder = args.builder;

@@ -60,4 +60,4 @@ 'use strict';

onBeforeBuild(builder) {
const addedSelects = {};
onBuild(builder) {
const addedSelects = [];

@@ -73,5 +73,5 @@ // Collect columns that need to be selected for the eager fetch

if (!builder.hasSelectionAs(col, relation.ownerCol[c]) && !addedSelects[col]) {
if (!builder.hasSelectionAs(col, relation.ownerCol[c]) && addedSelects.indexOf(col) === -1) {
this.omitProps.push(relation.ownerProp[c]);
addedSelects[col] = true;
addedSelects.push(col);
}

@@ -81,12 +81,8 @@ }

// This needs to be `var` instead of `let` or `const` to prevent
// bailout because of "Unsupported phi use of const or let variable".
var cols = Object.keys(addedSelects);
if (cols.length) {
builder.select(cols);
if (addedSelects.length) {
builder.select(addedSelects);
}
}
onAfterInternal(builder, result) {
onAfter2(builder, result) {
const modelClass = builder.modelClass();

@@ -93,0 +89,0 @@ const promises = [];

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

onBeforeBuild(builder) {
onBuild(builder) {
builder.whereComposite(builder.fullIdColumnFor(builder.modelClass()), this.id).first();

@@ -20,0 +20,0 @@ }

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

onAfter(builder, results) {
onAfter3(builder, results) {
if (this.opt.dontCallAfterGet) {

@@ -62,3 +62,3 @@ return results;

function callAfterGetForOne(ctx, model, result, deep) {
if (!model || !model.isObjectionModel) {
if (!model || !model.$isObjectionModel) {
return result;

@@ -106,10 +106,10 @@ }

function isRelation(value) {
return (value && value.isObjectionModel) || (Array.isArray(value)
return (value && value.$isObjectionModel) || (Array.isArray(value)
&& value.length
&& value[0]
&& value[0].isObjectionModel);
&& value[0].$isObjectionModel);
}
function doCallAfterGet(ctx, model, result) {
if (model.$afterGet !== model.objectionModelClass.prototype.$afterGet) {
if (model.$afterGet !== model.$objectionModelClass.prototype.$afterGet) {
const maybePromise = model.$afterGet(ctx);

@@ -116,0 +116,0 @@

@@ -38,4 +38,4 @@ 'use strict';

onBuild(builder) {
builder.from.apply(builder, this.args);
onBuildKnex(knexBuilder) {
knexBuilder.from.apply(knexBuilder, this.args);
}

@@ -42,0 +42,0 @@

@@ -18,4 +18,4 @@ 'use strict';

onAfterInternal(builder, inserted) {
const maybePromise = super.onAfterInternal(builder, inserted);
onAfter2(builder, inserted) {
const maybePromise = super.onAfter2(builder, inserted);

@@ -22,0 +22,0 @@ return after(maybePromise, insertedModels => {

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

onAfterInternal(builder) {
onAfter2(builder) {
const eager = RelationExpression.fromGraph(this.models);

@@ -28,0 +28,0 @@ const modelClass = this.models[0].constructor;

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

// Our delegate operation inherits from `InsertOperation`. Disable the call-time
// validation. We do the validation in onAfterQuery instead.
// validation. We do the validation in onAfter1 instead.
this.delegate.modelOptions.skipValidation = true;

@@ -49,7 +49,7 @@

onBefore() {
onBefore1() {
// Do nothing.
}
onBeforeInternal() {
onBefore2() {
// Do nothing. We override this with empty implementation so that

@@ -59,3 +59,3 @@ // the $beforeInsert() hooks are not called twice for the root models.

onBeforeBuild() {
onBefore3() {
// Do nothing.

@@ -68,5 +68,9 @@ }

onBuildKnex() {
// Do nothing.
}
// We overrode all other hooks but this one and do all the work in here.
// This is a bit hacky.
onAfterQuery(builder) {
onAfter1(builder) {
// We split the query props from all the models in the graph in the

@@ -91,7 +95,7 @@ // InsertOperation.call method. We need to set the queryProps option

return graphInserter.execute(insertFunc).then(() => {
return super.onAfterQuery(builder, this.models)
return super.onAfter1(builder, this.models)
});
}
onAfterInternal() {
onAfter2() {
// We override this with empty implementation so that the $afterInsert() hooks

@@ -98,0 +102,0 @@ // are not called twice for the root models.

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

onBeforeInternal(builder, result) {
onBefore2(builder, result) {
if (this.models.length > 1 && !isPostgres(builder.knex())) {

@@ -62,3 +62,3 @@ throw new Error('batch insert only works with Postgresql');

onBuild(knexBuilder, builder) {
onBuildKnex(knexBuilder, builder) {
if (!builder.has(/returning/)) {

@@ -88,3 +88,3 @@ // If the user hasn't specified a `returning` clause, we make sure

onAfterQuery(builder, ret) {
onAfter1(builder, ret) {
if (!Array.isArray(ret) || !ret.length || ret === this.models) {

@@ -117,3 +117,3 @@ // Early exit if there is nothing to do.

onAfterInternal(builder, models) {
onAfter2(builder, models) {
const result = this.isArray ? models : (models[0] || null);

@@ -120,0 +120,0 @@ return mapAfterAllReturn(models, model => model.$afterInsert(builder.context()), result);

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

onBeforeInternal(builder, result) {
onBefore2(builder, result) {
const maybePromise = this.instance.$beforeDelete(builder.context());

@@ -19,8 +19,8 @@ return afterReturn(maybePromise, result);

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
onBuild(builder) {
super.onBuild(builder);
builder.whereComposite(builder.fullIdColumnFor(builder.modelClass()), this.instance.$id());
}
onAfterInternal(builder, result) {
onAfter2(builder, result) {
const maybePromise = this.instance.$afterDelete(builder.context());

@@ -27,0 +27,0 @@ return afterReturn(maybePromise, result);

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

onBeforeBuild(builder) {
onBuild(builder) {
builder.whereComposite(builder.fullIdColumnFor(builder.modelClass()), this.instance.$id()).first()

@@ -15,0 +15,0 @@ }

@@ -25,9 +25,9 @@ 'use strict';

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
onBuild(builder) {
super.onBuild(builder);
builder.whereComposite(builder.fullIdColumnFor(builder.modelClass()), this.instance.$id());
}
onAfterInternal(builder, numUpdated) {
const maybePromise = super.onAfterInternal(builder, numUpdated);
onAfter2(builder, numUpdated) {
const maybePromise = super.onAfter2(builder, numUpdated);

@@ -34,0 +34,0 @@ return after(maybePromise, result => {

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

onBeforeBuild(builder) {
onBuild(builder) {
const modelClass = builder.modelClass();

@@ -25,0 +25,0 @@ const opt = Object.assign({}, this.callOpt);

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
if (this.opt.bool === 'or') {

@@ -24,0 +24,0 @@ knexBuilder.orWhereRaw(this.sql);

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
if (this.opt.bool === 'or') {

@@ -24,0 +24,0 @@ knexBuilder.orWhereRaw(this.sql);

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

onBuild(knexBuilder, builder) {
onBuildKnex(knexBuilder, builder) {
this.whereJsonNotObject(knexBuilder, builder.knex(), this.args[0]);

@@ -11,0 +11,0 @@ }

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
if (this.opt.bool === 'or') {

@@ -28,0 +28,0 @@ knexBuilder.orWhereRaw.apply(knexBuilder, this.rawArgs);

@@ -7,4 +7,4 @@ 'use strict';

onBuild(builder) {
builder[this.name].apply(builder, this.args);
onBuildKnex(knexBuilder) {
knexBuilder[this.name].apply(knexBuilder, this.args);
}

@@ -11,0 +11,0 @@ }

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

onBeforeBuild(builder) {
onBuild(builder) {
return this.func.call(builder, builder);

@@ -15,0 +15,0 @@ }

@@ -19,18 +19,18 @@ 'use strict';

onBefore(builder, result) {}
hasOnBefore() {
return this.onBefore !== QueryBuilderOperation.prototype.onBefore;
onBefore1(builder, result) {}
hasOnBefore1() {
return this.onBefore1 !== QueryBuilderOperation.prototype.onBefore1;
}
onBeforeInternal(builder, result) {}
hasOnBeforeInternal() {
return this.onBeforeInternal !== QueryBuilderOperation.prototype.onBeforeInternal;
onBefore2(builder, result) {}
hasOnBefore2() {
return this.onBefore2 !== QueryBuilderOperation.prototype.onBefore2;
}
onBeforeBuild(builder) {}
hasOnBeforeBuild() {
return this.onBeforeBuild !== QueryBuilderOperation.prototype.onBeforeBuild;
onBefore3(builder, result) {}
hasOnBefore3() {
return this.onBefore3 !== QueryBuilderOperation.prototype.onBefore3;
}
onBuild(knexBuilder, builder) {}
onBuild(builder) {}
hasOnBuild() {

@@ -40,2 +40,7 @@ return this.onBuild !== QueryBuilderOperation.prototype.onBuild;

onBuildKnex(knexBuilder, builder) {}
hasOnBuildKnex() {
return this.onBuildKnex !== QueryBuilderOperation.prototype.onBuildKnex;
}
onRawResult(builder, rows) { return rows; }

@@ -46,15 +51,15 @@ hasOnRawResult() {

onAfterQuery(builder, result) {}
hasOnAfterQuery() {
return this.onAfterQuery !== QueryBuilderOperation.prototype.onAfterQuery;
onAfter1(builder, result) { return result; }
hasOnAfter1() {
return this.onAfter1 !== QueryBuilderOperation.prototype.onAfter1;
}
onAfterInternal(builder, result) {}
hasOnAfterInternal() {
return this.onAfterInternal !== QueryBuilderOperation.prototype.onAfterInternal;
onAfter2(builder, result) { return result; }
hasOnAfter2() {
return this.onAfter2 !== QueryBuilderOperation.prototype.onAfter2;
}
onAfter(builder, result) {}
hasOnAfter() {
return this.onAfter !== QueryBuilderOperation.prototype.onAfter;
onAfter3(builder, result) { return result; }
hasOnAfter3() {
return this.onAfter3 !== QueryBuilderOperation.prototype.onAfter3
}

@@ -61,0 +66,0 @@

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

// Need to set these here instead of `onBuild` so that they
// Need to set these here instead of `onBuildKnex` so that they
// don't end up in the resultSize query.

@@ -26,3 +26,3 @@ builder.limit(end - start + 1).offset(start);

onBefore(builder) {
onBefore1(builder) {
// Don't return the promise so that it is executed

@@ -34,3 +34,3 @@ // in parallel with the actual query.

onAfter(builder, result) {
onAfter3(builder, result) {
return this.resultSizePromise.then(count => {

@@ -37,0 +37,0 @@ return {

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
// Always pass an array of columns to knex.returning.

@@ -28,0 +28,0 @@ knexBuilder.returning(this.args);

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

onAfter(builder, result) {
onAfter3(builder, result) {
return this.func.call(builder, result, builder);

@@ -15,0 +15,0 @@ }

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

onBefore(builder, result) {
onBefore1(builder, result) {
return this.func.call(builder, result, builder);

@@ -15,0 +15,0 @@ }

@@ -72,4 +72,4 @@ 'use strict';

onBuild(builder) {
builder[this.name].apply(builder, this.args);
onBuildKnex(knexBuilder) {
knexBuilder[this.name].apply(knexBuilder, this.args);
}

@@ -76,0 +76,0 @@

@@ -28,11 +28,11 @@ 'use strict';

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
onBuild(builder) {
super.onBuild(builder);
builder.whereComposite(builder.fullIdColumnFor(builder.modelClass()), this.id);
}
onAfterInternal(builder, numUpdated) {
onAfter2(builder, numUpdated) {
if (numUpdated == 0) {
// If nothing was updated, we should fetch nothing.
return afterReturn(super.onAfterInternal(builder, numUpdated), undefined);
return afterReturn(super.onAfter2(builder, numUpdated), undefined);
}

@@ -53,3 +53,3 @@

return afterReturn(super.onAfterInternal(builder, numUpdated), retVal);
return afterReturn(super.onAfter2(builder, numUpdated), retVal);
});

@@ -56,0 +56,0 @@ }

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

onBeforeInternal(builder, result) {
onBefore2(builder, result) {
const maybePromise = this.model.$beforeUpdate(this.modelOptions, builder.context());

@@ -49,3 +49,3 @@ return afterReturn(maybePromise, result);

onBuild(knexBuilder, builder) {
onBuildKnex(knexBuilder, builder) {
// Builder options can contain a queryProps map. Use it

@@ -91,3 +91,3 @@ // if there isn't a local one.

onAfterInternal(builder, numUpdated) {
onAfter2(builder, numUpdated) {
const maybePromise = this.model.$afterUpdate(this.modelOptions, builder.context());

@@ -94,0 +94,0 @@ return afterReturn(maybePromise, numUpdated);

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
if (this.args.length === 2) {

@@ -10,0 +10,0 @@ this.build(knexBuilder, this.args[0], '=', this.args[1]);

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
this.build(knexBuilder, this.args[0], this.args[1]);

@@ -10,0 +10,0 @@ }

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
this.build(knexBuilder, this.args[0], this.args[1]);

@@ -10,0 +10,0 @@ }

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

onBuild(knexBuilder) {
onBuildKnex(knexBuilder) {
if (this.args.length === 2) {

@@ -10,0 +10,0 @@ this.whereRef(knexBuilder, this.args[0], '=', this.args[1]);

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

function isModel(item) {
return item != null && item.isObjectionModel;
return item != null && item.$isObjectionModel;
}

@@ -157,0 +157,0 @@

@@ -29,2 +29,3 @@ 'use strict';

const RangeOperation = require('./operations/RangeOperation');
const FirstOperation = require('./operations/FirstOperation');
const FromOperation = require('./operations/FromOperation');

@@ -122,2 +123,17 @@

modify() {
if (typeof arguments[0] === 'string') {
const namedFilters = this._modelClass.namedFilters;
for (let i = 0, l = arguments.length; i < l; ++i) {
const filter = namedFilters[arguments[i]];
filter(this);
}
return this;
} else {
return super.modify.apply(this, arguments);
}
}
reject(error) {

@@ -207,2 +223,10 @@ this._explicitRejectValue = error;

joinEager(exp, filters) {
return this.eagerAlgorithm(this._modelClass.JoinEagerAlgorithm).eager(exp, filters);
}
naiveEager(exp, filters) {
return this.eagerAlgorithm(this._modelClass.NaiveEagerAlgorithm).eager(exp, filters);
}
mergeEager(exp, filters) {

@@ -225,2 +249,10 @@ if (!this._eagerExpression) {

mergeJoinEager(exp, filters) {
return this.eagerAlgorithm(this._modelClass.JoinEagerAlgorithm).mergeEager(exp, filters);
}
mergeNaiveEager(exp, filters) {
return this.eagerAlgorithm(this._modelClass.NaiveEagerAlgorithm).mergeEager(exp, filters);
}
allowEager(exp) {

@@ -446,7 +478,9 @@ this._allowedEagerExpression = exp || null;

promise = chainBeforeOperations(promise, builder._operations);
promise = chainBefore1Operations(promise, builder._operations);
promise = chainHooks(promise, context.runBefore);
promise = chainHooks(promise, internalContext.runBefore);
promise = chainBeforeInternalOperations(promise, builder._operations);
promise = chainBefore2Operations(promise, builder._operations);
promise = chainBefore3Operations(promise, builder._operations);
// Resolve all before hooks before building and executing the query

@@ -474,7 +508,8 @@ // and the rest of the hooks.

promise = chainAfterQueryOperations(promise, builder._operations);
promise = chainAfterInternalOperations(promise, builder._operations);
promise = chainAfter1Operations(promise, builder._operations);
promise = chainAfter2Operations(promise, builder._operations);
promise = chainHooks(promise, context.runAfter);
promise = chainHooks(promise, internalContext.runAfter);
promise = chainAfterOperations(promise, builder._operations);
promise = chainAfter3Operations(promise, builder._operations);

@@ -495,12 +530,2 @@ return promise;

first() {
return this.runAfter(result => {
if (Array.isArray(result)) {
return result[0];
} else {
return result;
}
});
}
throwIfNotFound() {

@@ -752,3 +777,8 @@ return this.runAfter((result, builder) => {

findOne() {
return this.where.apply(this, arguments).first();
}
range(start, end) {}
first() {}
joinRelation(relationName) {}

@@ -793,2 +823,5 @@ innerJoinRelation(relationName) {}

}, {
decorator: queryBuilderOperation(FirstOperation),
properties: ['first']
}, {
decorator: queryBuilderOperation([JoinRelationOperation, {joinOperation: 'join'}]),

@@ -1018,2 +1051,10 @@ properties: ['joinRelation']

const chainBefore1Operations = createHookCaller('onBefore1');
const chainBefore2Operations = createHookCaller('onBefore2');
const chainBefore3Operations = createHookCaller('onBefore3');
const chainRawResultOperations = createHookCaller('onRawResult');
const chainAfter1Operations = createHookCaller('onAfter1');
const chainAfter2Operations = createHookCaller('onAfter2');
const chainAfter3Operations = createHookCaller('onAfter3');
function createOperationFactory(OperationClass, name, options) {

@@ -1025,9 +1066,2 @@ return () => {

const chainBeforeOperations = createHookCaller('onBefore');
const chainBeforeInternalOperations = createHookCaller('onBeforeInternal');
const chainRawResultOperations = createHookCaller('onRawResult');
const chainAfterQueryOperations = createHookCaller('onAfterQuery');
const chainAfterInternalOperations = createHookCaller('onAfterInternal');
const chainAfterOperations = createHookCaller('onAfter');
const findOperationFactory = createOperationFactory(FindOperation, 'find');

@@ -1034,0 +1068,0 @@ const insertOperationFactory = createOperationFactory(InsertOperation, 'insert');

@@ -30,3 +30,5 @@ 'use strict';

modify(func) {
modify() {
const func = arguments[0];
if (!func) {

@@ -33,0 +35,0 @@ return this;

@@ -181,7 +181,7 @@ 'use strict';

op.onBeforeBuild(this);
op.onBuild(this);
const numNew = this._operations.length - ln;
// onBeforeBuild may call methods that add more operations. If
// onBuild may call methods that add more operations. If
// this was the case, move the operations to be executed next.

@@ -212,9 +212,9 @@ if (numNew > 0) {

// onBuild operations should never add new operations. They should only call
// onBuildKnex operations should never add new operations. They should only call
// methods on the knex query builder.
for (let i = 0, l = this._operations.length; i < l; ++i) {
this._operations[i].onBuild(knexBuilder, this);
this._operations[i].onBuildKnex(knexBuilder, this);
if (this._operations.length !== l) {
throw new Error('onBuild should only call query building methods on the knex builder');
throw new Error('onBuildKnex should only call query building methods on the knex builder');
}

@@ -221,0 +221,0 @@ }

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

const relationName = relationNames[i];
const node = newNode(relation.name, this.children, this.numChildren);
const node = newNode(relationName, this.children, this.numChildren);
const relation = allRelations[relationName];

@@ -191,0 +191,0 @@ const childExpr = new RelationExpression(node, 0, this._filters);

@@ -25,4 +25,4 @@ 'use strict';

onAfterQuery(builder, inserted) {
const maybePromise = super.onAfterQuery(builder, inserted);
onAfter1(builder, inserted) {
const maybePromise = super.onAfter1(builder, inserted);

@@ -29,0 +29,0 @@ return after(maybePromise, inserted => {

@@ -32,4 +32,4 @@ 'use strict';

onAfterQuery(builder, inserted) {
const maybePromise = super.onAfterQuery(builder, inserted);
onAfter1(builder, inserted) {
const maybePromise = super.onAfter1(builder, inserted);

@@ -36,0 +36,0 @@ const isOneToOne = this.relation.isOneToOne();

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

queryExecutor(builder) {
var patch = {};
const patch = {};

@@ -28,0 +28,0 @@ for (let i = 0, l = this.relation.relatedProp.length; i < l; ++i) {

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

queryExecutor(builder) {
var patch = {};
const patch = {};

@@ -20,0 +20,0 @@ for (let i = 0, l = this.relation.relatedProp.length; i < l; ++i) {

'use strict';
const DeleteOperation = require('../../queryBuilder/operations/DeleteOperation');
const ManyToManyHelpersMixin = require('./ManyToManyHelpersMixin');
class ManyToManyDeleteOperation extends DeleteOperation {
class ManyToManyDeleteOperation extends ManyToManyHelpersMixin(DeleteOperation) {

@@ -14,5 +15,5 @@ constructor(name, opt) {

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
this.relation.selectForModify(builder, this.owner).modify(this.relation.modify);
onBuild(builder) {
super.onBuild(builder);
this.selectForModify(builder, this.owner).modify(this.relation.modify);
}

@@ -19,0 +20,0 @@ }

'use strict';
const DeleteOperation = require('../../queryBuilder/operations/DeleteOperation');
const ManyToManySqliteHelpersMixin = require('./ManyToManySqliteHelpersMixin');
class ManyToManyDeleteSqliteOperation extends DeleteOperation {
class ManyToManyDeleteSqliteOperation extends ManyToManySqliteHelpersMixin(DeleteOperation) {

@@ -14,5 +15,5 @@ constructor(name, opt) {

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
this.relation.selectForModifySqlite(builder, this.owner).modify(this.relation.modify);
onBuild(builder) {
super.onBuild(builder);
this.selectForModify(builder, this.owner).modify(this.relation.modify);
}

@@ -19,0 +20,0 @@ }

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

onBeforeBuild(builder) {
onBuild(builder) {
const relatedModelClass = this.relation.relatedModelClass;

@@ -69,3 +69,3 @@ const ids = new Array(this.owners.length);

onAfterInternal(builder, related) {
onAfter2(builder, related) {
const isOneToOne = this.relation.isOneToOne();

@@ -72,0 +72,0 @@ const relatedByOwnerId = Object.create(null);

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

this.relation.omitExtraProps(this.models);
this.relation.omitExtraProps(this.models, this.queryProps);

@@ -24,4 +24,4 @@ return retVal;

onAfterQuery(builder, inserted) {
const maybePromise = super.onAfterQuery(builder, inserted);
onAfter1(builder, inserted) {
const maybePromise = super.onAfter1(builder, inserted);

@@ -33,4 +33,4 @@ const isOneToOne = this.relation.isOneToOne();

return after(maybePromise, inserted => {
let ownerId = this.owner.$values(this.relation.ownerProp);
let joinModels = this.relation.createJoinModels(ownerId, inserted);
const ownerId = this.owner.$values(this.relation.ownerProp);
const joinModels = this.relation.createJoinModels(ownerId, inserted);

@@ -37,0 +37,0 @@ if (isOneToOne) {

'use strict';
const Relation = require('../Relation');
const inheritModel = require('../../model/inheritModel');
const inheritModel = require('../../model/inheritModel').inheritModel;
const resolveModel = require('../../utils/resolveModel').resolveModel

@@ -117,2 +117,4 @@ const isSqlite = require('../../utils/knexUtils').isSqlite;

findQuery(builder, opt) {
const fullJoinTableOwnerCol = this.fullJoinTableOwnerCol(builder);
builder.join(this.joinTable, join => {

@@ -128,24 +130,9 @@ const fullRelatedCol = this.fullRelatedCol(builder);

if (opt.isColumnRef) {
const fullJoinTableOwnerCol = this.fullJoinTableOwnerCol(builder);
for (let i = 0, l = fullJoinTableOwnerCol.length; i < l; ++i) {
builder.whereRef(fullJoinTableOwnerCol[i], opt.ownerIds[i]);
}
} else if (containsNonNull(opt.ownerIds)) {
builder.whereInComposite(fullJoinTableOwnerCol, opt.ownerIds);
} else {
let hasIds = false;
for (let i = 0, l = opt.ownerIds.length; i < l; ++i) {
const id = opt.ownerIds[i];
if (id) {
hasIds = true;
break;
}
}
if (hasIds) {
builder.whereInComposite(this.fullJoinTableOwnerCol(builder), opt.ownerIds);
} else {
builder.resolve([]);
}
builder.resolve([]);
}

@@ -181,2 +168,3 @@

const ownerCol = `${opt.ownerTable}.${this.ownerCol[i]}`;
join.on(joinTableOwnerCol, ownerCol);

@@ -189,2 +177,3 @@ }

const relatedCol = `${opt.relatedTableAlias}.${this.relatedCol[i]}`;
join.on(joinTableRelatedCol, relatedCol);

@@ -274,38 +263,2 @@ }

selectForModify(builder, owner) {
let ownerId = owner.$values(this.ownerProp);
let idQuery = this.joinTableModelClass(builder.knex())
.query()
.childQueryOf(builder)
.select(this.fullJoinTableRelatedCol(builder))
.whereComposite(this.fullJoinTableOwnerCol(builder), ownerId);
return builder.whereInComposite(this.fullRelatedCol(builder), idQuery);
}
selectForModifySqlite(builder, owner) {
const relatedTable = builder.tableNameFor(this.relatedModelClass);
const relatedTableAlias = this.relatedTableAlias(builder);
const relatedTableAsAlias = `${relatedTable} as ${relatedTableAlias}`;
const relatedTableAliasRowId = `${relatedTableAlias}.${SQLITE_BUILTIN_ROW_ID}`;
const relatedTableRowId = `${relatedTable}.${SQLITE_BUILTIN_ROW_ID}`;
const selectRelatedQuery = this.joinTableModelClass(builder.knex())
.query()
.childQueryOf(builder)
.select(relatedTableAliasRowId)
.whereComposite(this.fullJoinTableOwnerCol(builder), owner.$values(this.ownerProp))
.join(relatedTableAsAlias, join => {
const fullJoinTableRelatedCols = this.fullJoinTableRelatedCol(builder);
const fullRelatedCol = this.fullRelatedCol(builder);
for (let i = 0, l = fullJoinTableRelatedCols.length; i < l; ++i) {
join.on(fullJoinTableRelatedCols[i], fullRelatedCol[i]);
}
});
return builder.whereInComposite(relatedTableRowId, selectRelatedQuery);
}
createJoinModels(ownerId, related) {

@@ -341,3 +294,3 @@ const joinModels = new Array(related.length);

omitExtraProps(models) {
omitExtraProps(models, queryProps) {
if (this.joinTableExtras && this.joinTableExtras.length) {

@@ -347,3 +300,19 @@ const props = this.joinTableExtras.map(extra => extra.aliasProp);

for (let i = 0, l = models.length; i < l; ++i) {
// Don't delete the extra properties from the models so that they can
// be used in the `$before` and `$after` hooks.
models[i].$omitFromDatabaseJson(props);
if (queryProps) {
const propObj = queryProps.get(models[i]);
if (propObj) {
for (let j = 0; j < props.length; ++j) {
const prop = props[j];
if (prop in propObj) {
delete propObj[prop];
}
}
}
}
}

@@ -374,2 +343,16 @@ }

function containsNonNull(arr) {
for (let i = 0, l = arr.length; i < l; ++i) {
const val = arr[i];
if (Array.isArray(val) && containsNonNull(val)) {
return true;
} else if (val !== null && val !== undefined) {
return true;
}
}
return false;
}
module.exports = ManyToManyRelation;

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

queryExecutor(builder) {
let selectRelatedColQuery = this.relation.relatedModelClass
const selectRelatedColQuery = this.relation.relatedModelClass
.query()
.childQueryOf(builder)
.copyFrom(builder, /where/i)
.copyFrom(builder, builder.constructor.WhereSelector)
.select(this.relation.fullRelatedCol(builder))

@@ -22,0 +22,0 @@ .modify(this.relation.modify);

@@ -17,11 +17,11 @@ 'use strict';

queryExecutor(builder) {
let joinTableAlias = this.relation.joinTableAlias(builder);
let joinTableAsAlias = this.relation.joinTable + ' as ' + joinTableAlias;
let joinTableAliasRowId = joinTableAlias + '.' + SQLITE_BUILTIN_ROW_ID;
let joinTableRowId = this.relation.joinTable + '.' + SQLITE_BUILTIN_ROW_ID;
const joinTableAlias = this.relation.joinTableAlias(builder);
const joinTableAsAlias = this.relation.joinTable + ' as ' + joinTableAlias;
const joinTableAliasRowId = joinTableAlias + '.' + SQLITE_BUILTIN_ROW_ID;
const joinTableRowId = this.relation.joinTable + '.' + SQLITE_BUILTIN_ROW_ID;
let ownerId = this.owner.$values(this.relation.ownerProp);
let fullRelatedCol = this.relation.fullRelatedCol(builder);
const ownerId = this.owner.$values(this.relation.ownerProp);
const fullRelatedCol = this.relation.fullRelatedCol(builder);
let selectRelatedQuery = this.relation.relatedModelClass
const selectRelatedQuery = this.relation.relatedModelClass
.query()

@@ -28,0 +28,0 @@ .childQueryOf(builder)

'use strict';
const UpdateOperation = require('../../queryBuilder/operations/UpdateOperation');
const ManyToManyUpdateOperationBase = require('./ManyToManyUpdateOperationBase');
const ManyToManyHelpersMixin = require('./ManyToManyHelpersMixin');
class ManyToManyUpdateOperation extends UpdateOperation {
class ManyToManyUpdateOperation extends ManyToManyHelpersMixin(ManyToManyUpdateOperationBase) {
constructor(name, opt) {
super(name, opt);
onBuild(builder) {
if (this.hasExtraProps) {
// Create the join table patch filter query here before we add our
// own where clauses to it. At this point `builder` should only have
// the user's own wheres.
this.joinTablePatchFilterQuery = this.relation.relatedModelClass
.query()
.childQueryOf(builder)
.select(this.relation.fullRelatedCol(builder))
.copyFrom(builder, builder.constructor.WhereSelector)
.modify(this.relation.modify);
}
this.relation = opt.relation;
this.owner = opt.owner;
super.onBuild(builder);
this.selectForModify(builder, this.owner).modify(this.relation.modify);
}
onBeforeBuild(builder) {
super.onBeforeBuild(builder);
this.relation.selectForModify(builder, this.owner).modify(this.relation.modify);
onAfter1(builder, result) {
if (this.hasExtraProps) {
return this.relation.joinTableModelClass(builder.knex())
.query()
.childQueryOf(builder)
.whereComposite(this.relation.fullJoinTableOwnerCol(builder), this.owner.$id())
.whereInComposite(this.relation.fullJoinTableRelatedCol(builder), this.joinTablePatchFilterQuery)
.patch(this.joinTablePatch)
.return(result);
} else {
return result;
}
}

@@ -18,0 +38,0 @@ }

'use strict';
const UpdateOperation = require('../../queryBuilder/operations/UpdateOperation');
const ManyToManyUpdateOperationBase = require('./ManyToManyUpdateOperationBase');
const ManyToManySqliteHelpersMixin = require('./ManyToManySqliteHelpersMixin');
const SQLITE_BUILTIN_ROW_ID = '_rowid_';
class ManyToManyUpdateSqliteOperation extends UpdateOperation {
class ManyToManyUpdateSqliteOperation extends ManyToManySqliteHelpersMixin(ManyToManyUpdateOperationBase) {
constructor(name, opt) {
super(name, opt);
onBuild(builder) {
if (this.hasExtraProps) {
const joinTableModelClass = this.relation.joinTableModelClass(builder.knex());
const joinTableName = builder.tableNameFor(joinTableModelClass);
const joinTableAlias = builder.tableRefFor(joinTableModelClass);
const joinTableAsAlias = `${joinTableName} as ${joinTableAlias}`;
this.relation = opt.relation;
this.owner = opt.owner;
// Create the join table patch filter query here before we add our
// own where clauses to it. At this point `builder` should only have
// the user's own wheres.
this.joinTablePatchFilterQuery = this.relation.relatedModelClass
.query()
.childQueryOf(builder)
.select(`${joinTableAlias}.${SQLITE_BUILTIN_ROW_ID}`)
.copyFrom(builder, builder.constructor.WhereSelector)
.join(joinTableAsAlias, join => {
const fullJoinTableRelatedCols = this.relation.fullJoinTableRelatedCol(builder);
const fullRelatedCol = this.relation.fullRelatedCol(builder);
for (let i = 0, l = fullJoinTableRelatedCols.length; i < l; ++i) {
join.on(fullJoinTableRelatedCols[i], fullRelatedCol[i]);
}
})
.modify(this.relation.modify);
}
super.onBuild(builder);
this.selectForModify(builder, this.owner).modify(this.relation.modify);
}
onBeforeBuild(builder) {
super.onBeforeBuild(builder);
this.relation.selectForModifySqlite(builder, this.owner).modify(this.relation.modify);
onAfter1(builder, result) {
if (this.hasExtraProps) {
const joinTableModelClass = this.relation.joinTableModelClass(builder.knex());
const joinTableName = builder.tableRefFor(joinTableModelClass);
return joinTableModelClass
.query()
.childQueryOf(builder)
.whereComposite(this.relation.fullJoinTableOwnerCol(builder), this.owner.$id())
.whereIn(`${joinTableName}.${SQLITE_BUILTIN_ROW_ID}`, this.joinTablePatchFilterQuery)
.patch(this.joinTablePatch)
.return(result);
} else {
return result;
}
}

@@ -18,0 +55,0 @@ }

@@ -212,2 +212,3 @@ 'use strict';

const ownerCol = `${opt.ownerTable}.${this.ownerCol[i]}`;
join.on(relatedCol, '=', ownerCol);

@@ -214,0 +215,0 @@ }

@@ -14,4 +14,4 @@ 'use strict';

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
onBuild(builder) {
super.onBuild(builder);

@@ -18,0 +18,0 @@ this.relation.findQuery(builder, {

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

onBeforeBuild(builder) {
onBuild(builder) {
let ids = new Array(this.owners.length);

@@ -45,8 +45,3 @@

onAfter(builder, related) {
this.omitImplicitJoinProps(related);
return super.onAfter(builder, related);
}
onAfterInternal(builder, related) {
onAfter2(builder, related) {
const owners = this.owners;

@@ -88,6 +83,10 @@ const isOneToOne = this.relation.isOneToOne();

onAfter3(builder, related) {
this.omitImplicitJoinProps(related);
return super.onAfter3(builder, related);
}
selectMissingJoinColumns(builder) {
const addedSelects = {};
const cols = this.relation.fullRelatedCol(builder);
let selects;
const addedSelects = [];

@@ -97,14 +96,10 @@ for (let c = 0, lc = cols.length; c < lc; ++c) {

if (!builder.hasSelectionAs(col, this.relation.relatedCol[c]) && !addedSelects[col]) {
if (!builder.hasSelectionAs(col, this.relation.relatedCol[c]) && addedSelects.indexOf(col) === -1) {
this.omitProps.push(this.relation.relatedProp[c]);
addedSelects[col] = true;
addedSelects.push(col);
}
}
// Don't move the `let` or `const` here to prevent an optimization
// bailout because of "Unsupported phi use of const or let variable".
selects = Object.keys(addedSelects);
if (selects.length) {
builder.select(selects);
if (addedSelects.length) {
builder.select(addedSelects);
}

@@ -111,0 +106,0 @@ }

@@ -14,4 +14,4 @@ 'use strict';

onBeforeBuild(builder) {
super.onBeforeBuild(builder);
onBuild(builder) {
super.onBuild(builder);

@@ -18,0 +18,0 @@ this.relation.findQuery(builder, {

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

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

@@ -531,2 +531,4 @@ // Type definitions for objection v0.6.1

<T>(knex: knex, callback: (trx: Transaction) => Promise<T>): Promise<T>;
}

@@ -533,0 +535,0 @@

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