@abedmurrar/objection 0.0.0-stage → 4.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +105 -2
- package/lib/index.mjs +6 -0
- package/lib/initialize.js +11 -0
- package/lib/model/AjvValidator.js +278 -0
- package/lib/model/Model.js +772 -0
- package/lib/model/ModifierNotFoundError.js +10 -0
- package/lib/model/NotFoundError.js +19 -0
- package/lib/model/RelationDoesNotExistError.js +11 -0
- package/lib/model/ValidationError.js +46 -0
- package/lib/model/Validator.js +20 -0
- package/lib/model/getModel.js +7 -0
- package/lib/model/graph/ModelGraph.js +60 -0
- package/lib/model/graph/ModelGraphBuilder.js +188 -0
- package/lib/model/graph/ModelGraphEdge.js +40 -0
- package/lib/model/graph/ModelGraphNode.js +201 -0
- package/lib/model/inheritModel.js +19 -0
- package/lib/model/modelBindKnex.js +69 -0
- package/lib/model/modelClone.js +102 -0
- package/lib/model/modelColPropMap.js +24 -0
- package/lib/model/modelConcurrency.js +24 -0
- package/lib/model/modelId.js +57 -0
- package/lib/model/modelJsonAttributes.js +72 -0
- package/lib/model/modelParseRelations.js +83 -0
- package/lib/model/modelQueryProps.js +116 -0
- package/lib/model/modelSet.js +116 -0
- package/lib/model/modelTableMetadata.js +71 -0
- package/lib/model/modelToJson.js +157 -0
- package/lib/model/modelUtils.js +40 -0
- package/lib/model/modelValidate.js +40 -0
- package/lib/model/modelValues.js +113 -0
- package/lib/model/modelVisitor.js +34 -0
- package/lib/objection.js +89 -0
- package/lib/queryBuilder/FunctionBuilder.js +291 -0
- package/lib/queryBuilder/InternalOptions.js +24 -0
- package/lib/queryBuilder/JoinBuilder.js +124 -0
- package/lib/queryBuilder/QueryBuilder.js +1136 -0
- package/lib/queryBuilder/QueryBuilderBase.js +666 -0
- package/lib/queryBuilder/QueryBuilderContext.js +20 -0
- package/lib/queryBuilder/QueryBuilderContextBase.js +26 -0
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +484 -0
- package/lib/queryBuilder/QueryBuilderUserContext.js +25 -0
- package/lib/queryBuilder/RawBuilder.js +78 -0
- package/lib/queryBuilder/ReferenceBuilder.js +246 -0
- package/lib/queryBuilder/RelationExpression.js +373 -0
- package/lib/queryBuilder/StaticHookArguments.js +122 -0
- package/lib/queryBuilder/ValueBuilder.js +115 -0
- package/lib/queryBuilder/expressions.js +121 -0
- package/lib/queryBuilder/functions/mysql.js +762 -0
- package/lib/queryBuilder/graph/GraphAction.js +54 -0
- package/lib/queryBuilder/graph/GraphData.js +12 -0
- package/lib/queryBuilder/graph/GraphFetcher.js +155 -0
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +146 -0
- package/lib/queryBuilder/graph/GraphOperation.js +21 -0
- package/lib/queryBuilder/graph/GraphOptions.js +165 -0
- package/lib/queryBuilder/graph/GraphUpsert.js +231 -0
- package/lib/queryBuilder/graph/delete/GraphDelete.js +15 -0
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +56 -0
- package/lib/queryBuilder/graph/insert/GraphInsert.js +116 -0
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +183 -0
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +70 -0
- package/lib/queryBuilder/graph/patch/GraphPatch.js +15 -0
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +205 -0
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +26 -0
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +96 -0
- package/lib/queryBuilder/join/JoinResultColumn.js +19 -0
- package/lib/queryBuilder/join/JoinResultParser.js +106 -0
- package/lib/queryBuilder/join/RelationJoiner.js +258 -0
- package/lib/queryBuilder/join/TableNode.js +136 -0
- package/lib/queryBuilder/join/TableTree.js +69 -0
- package/lib/queryBuilder/join/utils.js +19 -0
- package/lib/queryBuilder/operations/DelegateOperation.js +101 -0
- package/lib/queryBuilder/operations/DeleteOperation.js +47 -0
- package/lib/queryBuilder/operations/FindByIdOperation.js +29 -0
- package/lib/queryBuilder/operations/FindByIdsOperation.js +23 -0
- package/lib/queryBuilder/operations/FindOperation.js +147 -0
- package/lib/queryBuilder/operations/FirstOperation.js +22 -0
- package/lib/queryBuilder/operations/FromOperation.js +91 -0
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +38 -0
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +35 -0
- package/lib/queryBuilder/operations/InsertGraphOperation.js +87 -0
- package/lib/queryBuilder/operations/InsertOperation.js +173 -0
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +37 -0
- package/lib/queryBuilder/operations/InstanceFindOperation.js +17 -0
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +20 -0
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +45 -0
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +83 -0
- package/lib/queryBuilder/operations/KnexOperation.js +11 -0
- package/lib/queryBuilder/operations/MergeOperation.js +43 -0
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +173 -0
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +23 -0
- package/lib/queryBuilder/operations/OnBuildOperation.js +23 -0
- package/lib/queryBuilder/operations/OnErrorOperation.js +23 -0
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +258 -0
- package/lib/queryBuilder/operations/RangeOperation.js +37 -0
- package/lib/queryBuilder/operations/RelateOperation.js +20 -0
- package/lib/queryBuilder/operations/ReturningOperation.js +24 -0
- package/lib/queryBuilder/operations/RunAfterOperation.js +23 -0
- package/lib/queryBuilder/operations/RunBeforeOperation.js +23 -0
- package/lib/queryBuilder/operations/UnrelateOperation.js +18 -0
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +63 -0
- package/lib/queryBuilder/operations/UpdateOperation.js +130 -0
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +35 -0
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +47 -0
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +48 -0
- package/lib/queryBuilder/operations/WhereInOperation.js +46 -0
- package/lib/queryBuilder/operations/eager/EagerOperation.js +46 -0
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +41 -0
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +10 -0
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +227 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +29 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +37 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +30 -0
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +33 -0
- package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +155 -0
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +135 -0
- package/lib/queryBuilder/operations/select/SelectOperation.js +50 -0
- package/lib/queryBuilder/operations/select/Selection.js +112 -0
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +84 -0
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +90 -0
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +95 -0
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +787 -0
- package/lib/queryBuilder/parsers/relationExpressionParser.js +930 -0
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +17 -0
- package/lib/queryBuilder/transformations/QueryTransformation.js +9 -0
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +57 -0
- package/lib/queryBuilder/transformations/index.js +9 -0
- package/lib/queryBuilder/whereScopes.js +199 -0
- package/lib/relations/Relation.js +317 -0
- package/lib/relations/RelationDeleteOperation.js +23 -0
- package/lib/relations/RelationFindOperation.js +116 -0
- package/lib/relations/RelationInsertOperation.js +25 -0
- package/lib/relations/RelationOwner.js +199 -0
- package/lib/relations/RelationProperty.js +207 -0
- package/lib/relations/RelationUpdateOperation.js +23 -0
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +18 -0
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +33 -0
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +39 -0
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +45 -0
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +46 -0
- package/lib/relations/hasMany/HasManyInsertOperation.js +45 -0
- package/lib/relations/hasMany/HasManyRelateOperation.js +48 -0
- package/lib/relations/hasMany/HasManyRelation.js +41 -0
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +26 -0
- package/lib/relations/hasOne/HasOneRelation.js +10 -0
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +10 -0
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +82 -0
- package/lib/relations/manyToMany/ManyToManyRelation.js +405 -0
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +29 -0
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -0
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -0
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -0
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +82 -0
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +40 -0
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +64 -0
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +11 -0
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +27 -0
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +11 -0
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -0
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +65 -0
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -0
- package/lib/transaction.js +66 -0
- package/lib/utils/assert.js +19 -0
- package/lib/utils/buildUtils.js +19 -0
- package/lib/utils/classUtils.js +9 -0
- package/lib/utils/cloneDeep.js +365 -0
- package/lib/utils/createModifier.js +37 -0
- package/lib/utils/deprecate.js +11 -0
- package/lib/utils/identifierMapping.js +188 -0
- package/lib/utils/internalPropUtils.js +7 -0
- package/lib/utils/knexUtils.js +81 -0
- package/lib/utils/mixin.js +18 -0
- package/lib/utils/mysqlJsonPath.js +70 -0
- package/lib/utils/normalizeIds.js +127 -0
- package/lib/utils/objectUtils.js +314 -0
- package/lib/utils/parseFieldExpression.js +73 -0
- package/lib/utils/postgresJsonPath.js +96 -0
- package/lib/utils/promiseUtils/after.js +14 -0
- package/lib/utils/promiseUtils/afterReturn.js +14 -0
- package/lib/utils/promiseUtils/index.js +15 -0
- package/lib/utils/promiseUtils/isPromise.js +8 -0
- package/lib/utils/promiseUtils/map.js +96 -0
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +23 -0
- package/lib/utils/promiseUtils/try.js +19 -0
- package/lib/utils/resolveModel.js +104 -0
- package/lib/utils/tmpColumnUtils.js +7 -0
- package/package.json +113 -4
- package/typings/objection/index.d.mts +362 -0
- package/typings/objection/index.d.ts +4131 -0
- package/typings/objection/relation-expression.d.ts +237 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { withWhereScope } = require('../whereScopes');
|
|
3
|
+
const { UpdateOperation } = require('./UpdateOperation');
|
|
4
|
+
const { InstanceFindOperation } = require('./InstanceFindOperation');
|
|
5
|
+
const { assertHasId } = require('../../utils/assert');
|
|
6
|
+
const { isObject } = require('../../utils/objectUtils');
|
|
7
|
+
class InstanceUpdateOperation extends UpdateOperation {
|
|
8
|
+
constructor(name, opt) {
|
|
9
|
+
super(name, opt);
|
|
10
|
+
this.instance = opt.instance;
|
|
11
|
+
this.modelOptions.old = opt.instance;
|
|
12
|
+
}
|
|
13
|
+
onAdd(builder, args) {
|
|
14
|
+
const retVal = super.onAdd(builder, args);
|
|
15
|
+
if (!this.model) {
|
|
16
|
+
this.model = this.instance;
|
|
17
|
+
}
|
|
18
|
+
return retVal;
|
|
19
|
+
}
|
|
20
|
+
onBuild(builder) {
|
|
21
|
+
super.onBuild(builder);
|
|
22
|
+
assertHasId(this.instance);
|
|
23
|
+
withWhereScope(builder, () => builder.findById(this.instance.$id()));
|
|
24
|
+
}
|
|
25
|
+
async onAfter2(builder, result) {
|
|
26
|
+
// The result may be an object if `returning` was used.
|
|
27
|
+
if (Array.isArray(result)) {
|
|
28
|
+
result = result[0];
|
|
29
|
+
}
|
|
30
|
+
result = await super.onAfter2(builder, result);
|
|
31
|
+
this.instance.$set(this.model);
|
|
32
|
+
if (isObject(result)) {
|
|
33
|
+
this.instance.$set(result);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
toFindOperation() {
|
|
38
|
+
return new InstanceFindOperation('find', {
|
|
39
|
+
instance: this.instance,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
module.exports = {
|
|
44
|
+
InstanceUpdateOperation,
|
|
45
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
const { RelationExpression } = require('../RelationExpression');
|
|
4
|
+
const { RelationJoiner } = require('../join/RelationJoiner');
|
|
5
|
+
const { isString } = require('../../utils/objectUtils');
|
|
6
|
+
class JoinRelatedOperation extends QueryBuilderOperation {
|
|
7
|
+
constructor(name, opt) {
|
|
8
|
+
super(name, opt);
|
|
9
|
+
this.calls = [];
|
|
10
|
+
}
|
|
11
|
+
get joinOperation() {
|
|
12
|
+
return this.opt.joinOperation;
|
|
13
|
+
}
|
|
14
|
+
addCall(call) {
|
|
15
|
+
this.calls.push(call);
|
|
16
|
+
}
|
|
17
|
+
onBuild(builder) {
|
|
18
|
+
const modelClass = builder.modelClass();
|
|
19
|
+
const joinOperation = this.joinOperation;
|
|
20
|
+
let mergedExpr = RelationExpression.create();
|
|
21
|
+
for (const call of this.calls) {
|
|
22
|
+
const expr = RelationExpression.create(call.expression).toPojo();
|
|
23
|
+
const childNames = expr.$childNames;
|
|
24
|
+
const options = call.options || {};
|
|
25
|
+
if (childNames.length === 1) {
|
|
26
|
+
applyAlias(expr, modelClass, builder, options);
|
|
27
|
+
}
|
|
28
|
+
if (options.aliases) {
|
|
29
|
+
applyAliases(expr, modelClass, options);
|
|
30
|
+
}
|
|
31
|
+
mergedExpr = mergedExpr.merge(expr);
|
|
32
|
+
}
|
|
33
|
+
const joiner = new RelationJoiner({
|
|
34
|
+
modelClass,
|
|
35
|
+
});
|
|
36
|
+
joiner.setOptions({ joinOperation });
|
|
37
|
+
joiner.setExpression(mergedExpr);
|
|
38
|
+
joiner.setModifiers(builder.modifiers());
|
|
39
|
+
joiner.build(builder, false);
|
|
40
|
+
}
|
|
41
|
+
clone() {
|
|
42
|
+
const clone = super.clone();
|
|
43
|
+
clone.calls = this.calls.slice();
|
|
44
|
+
return clone;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function applyAlias(expr, modelClass, builder, options) {
|
|
48
|
+
const childNames = expr.$childNames;
|
|
49
|
+
const childName = childNames[0];
|
|
50
|
+
const childExpr = expr[childName];
|
|
51
|
+
const relation = modelClass.getRelation(childExpr.$relation);
|
|
52
|
+
let alias = childName;
|
|
53
|
+
if (options.alias === false) {
|
|
54
|
+
alias = builder.tableRefFor(relation.relatedModelClass);
|
|
55
|
+
}
|
|
56
|
+
else if (isString(options.alias)) {
|
|
57
|
+
alias = options.alias;
|
|
58
|
+
}
|
|
59
|
+
if (childName !== alias) {
|
|
60
|
+
renameRelationExpressionNode(expr, childName, alias);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function applyAliases(expr, modelClass, options) {
|
|
64
|
+
for (const childName of expr.$childNames) {
|
|
65
|
+
const childExpr = expr[childName];
|
|
66
|
+
const relation = modelClass.getRelation(childExpr.$relation);
|
|
67
|
+
const alias = options.aliases[childExpr.$relation];
|
|
68
|
+
if (alias && alias !== childName) {
|
|
69
|
+
renameRelationExpressionNode(expr, childName, alias);
|
|
70
|
+
}
|
|
71
|
+
applyAliases(childExpr, relation.relatedModelClass, options);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function renameRelationExpressionNode(expr, oldName, newName) {
|
|
75
|
+
const childExpr = expr[oldName];
|
|
76
|
+
delete expr[oldName];
|
|
77
|
+
expr[newName] = childExpr;
|
|
78
|
+
childExpr.$name = newName;
|
|
79
|
+
expr.$childNames = expr.$childNames.map((it) => (it === oldName ? newName : it));
|
|
80
|
+
}
|
|
81
|
+
module.exports = {
|
|
82
|
+
JoinRelatedOperation,
|
|
83
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { ObjectionToKnexConvertingOperation } = require('./ObjectionToKnexConvertingOperation');
|
|
3
|
+
// An operation that simply calls the equivalent knex method.
|
|
4
|
+
class KnexOperation extends ObjectionToKnexConvertingOperation {
|
|
5
|
+
onBuildKnex(knexBuilder, builder) {
|
|
6
|
+
return knexBuilder[this.name].apply(knexBuilder, this.getKnexArgs(builder));
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
module.exports = {
|
|
10
|
+
KnexOperation,
|
|
11
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { isFunction, isEmpty, isObject } = require('../../utils/objectUtils');
|
|
3
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
4
|
+
const { convertFieldExpressionsToRaw } = require('./UpdateOperation');
|
|
5
|
+
class MergeOperation extends QueryBuilderOperation {
|
|
6
|
+
constructor(name, opt) {
|
|
7
|
+
super(name, opt);
|
|
8
|
+
this.model = null;
|
|
9
|
+
this.args = null;
|
|
10
|
+
}
|
|
11
|
+
onAdd(builder, args) {
|
|
12
|
+
this.args = args;
|
|
13
|
+
if (!isEmpty(args) && isObject(args[0]) && !Array.isArray(args[0])) {
|
|
14
|
+
const json = args[0];
|
|
15
|
+
const modelClass = builder.modelClass();
|
|
16
|
+
this.model = modelClass.ensureModel(json, { patch: true });
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
onBuildKnex(knexBuilder, builder) {
|
|
21
|
+
if (!isFunction(knexBuilder.merge)) {
|
|
22
|
+
throw new Error('merge method can only be chained right after onConflict method');
|
|
23
|
+
}
|
|
24
|
+
if (this.model) {
|
|
25
|
+
const json = this.model.$toDatabaseJson(builder);
|
|
26
|
+
const convertedJson = convertFieldExpressionsToRaw(builder, this.model, json);
|
|
27
|
+
return knexBuilder.merge(convertedJson);
|
|
28
|
+
}
|
|
29
|
+
return knexBuilder.merge(...this.args);
|
|
30
|
+
}
|
|
31
|
+
toFindOperation() {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
clone() {
|
|
35
|
+
const clone = super.clone();
|
|
36
|
+
clone.model = this.model;
|
|
37
|
+
clone.args = this.args;
|
|
38
|
+
return clone;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
module.exports = {
|
|
42
|
+
MergeOperation,
|
|
43
|
+
};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
const { isPlainObject, isObject, isFunction, once } = require('../../utils/objectUtils');
|
|
4
|
+
const { isKnexQueryBuilder, isKnexJoinBuilder } = require('../../utils/knexUtils');
|
|
5
|
+
const { transformation } = require('../transformations');
|
|
6
|
+
const { isModelClass } = require('../../utils/resolveModel');
|
|
7
|
+
const getJoinBuilder = once(() => require('../JoinBuilder').JoinBuilder);
|
|
8
|
+
// An abstract operation base class that converts all arguments from objection types
|
|
9
|
+
// to knex types. For example objection query builders are converted into knex query
|
|
10
|
+
// builders and objection RawBuilder instances are converted into knex Raw instances.
|
|
11
|
+
class ObjectionToKnexConvertingOperation extends QueryBuilderOperation {
|
|
12
|
+
constructor(name, opt) {
|
|
13
|
+
super(name, opt);
|
|
14
|
+
this.args = null;
|
|
15
|
+
}
|
|
16
|
+
getKnexArgs(builder) {
|
|
17
|
+
return convertArgs(this.name, builder, this.args);
|
|
18
|
+
}
|
|
19
|
+
onAdd(builder, args) {
|
|
20
|
+
this.args = Array.from(args);
|
|
21
|
+
return shouldBeAdded(this.name, builder, this.args);
|
|
22
|
+
}
|
|
23
|
+
clone() {
|
|
24
|
+
const clone = super.clone();
|
|
25
|
+
clone.args = this.args;
|
|
26
|
+
return clone;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function shouldBeAdded(opName, builder, args) {
|
|
30
|
+
const skipUndefined = builder.internalOptions().skipUndefined;
|
|
31
|
+
for (let i = 0, l = args.length; i < l; ++i) {
|
|
32
|
+
const arg = args[i];
|
|
33
|
+
if (isUndefined(arg)) {
|
|
34
|
+
if (skipUndefined) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
throw new Error(`undefined passed as argument #${i} for '${opName}' operation. Call skipUndefined() method to ignore the undefined values.`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
function convertArgs(opName, builder, args) {
|
|
45
|
+
const skipUndefined = builder.internalOptions().skipUndefined;
|
|
46
|
+
return args.map((arg, i) => {
|
|
47
|
+
if (hasToKnexRawMethod(arg)) {
|
|
48
|
+
return convertToKnexRaw(arg, builder);
|
|
49
|
+
}
|
|
50
|
+
else if (isObjectionQueryBuilderBase(arg)) {
|
|
51
|
+
return convertQueryBuilderBase(arg, builder);
|
|
52
|
+
}
|
|
53
|
+
else if (isArray(arg)) {
|
|
54
|
+
return convertArray(arg, builder, i, opName, skipUndefined);
|
|
55
|
+
}
|
|
56
|
+
else if (isModelClass(arg)) {
|
|
57
|
+
// Model classes can be used in place of their table names, for example
|
|
58
|
+
// `join(Pet, ...)`. They are functions, so this check must come first.
|
|
59
|
+
return arg.getTableName();
|
|
60
|
+
}
|
|
61
|
+
else if (isFunction(arg)) {
|
|
62
|
+
return convertFunction(arg, builder);
|
|
63
|
+
}
|
|
64
|
+
else if (isModel(arg)) {
|
|
65
|
+
return convertModel(arg);
|
|
66
|
+
}
|
|
67
|
+
else if (isPlainObject(arg)) {
|
|
68
|
+
return convertPlainObject(arg, builder, i, opName, skipUndefined);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return arg;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function isUndefined(item) {
|
|
76
|
+
return item === undefined;
|
|
77
|
+
}
|
|
78
|
+
function hasToKnexRawMethod(item) {
|
|
79
|
+
return isObject(item) && isFunction(item.toKnexRaw);
|
|
80
|
+
}
|
|
81
|
+
function convertToKnexRaw(item, builder) {
|
|
82
|
+
return item.toKnexRaw(builder);
|
|
83
|
+
}
|
|
84
|
+
function isObjectionQueryBuilderBase(item) {
|
|
85
|
+
return isObject(item) && item.isObjectionQueryBuilderBase === true;
|
|
86
|
+
}
|
|
87
|
+
function convertQueryBuilderBase(item, builder) {
|
|
88
|
+
item = transformation.onConvertQueryBuilderBase(item, builder);
|
|
89
|
+
return item.subqueryOf(builder).toKnexQuery();
|
|
90
|
+
}
|
|
91
|
+
function isArray(item) {
|
|
92
|
+
return Array.isArray(item);
|
|
93
|
+
}
|
|
94
|
+
function convertArray(arr, builder, i, opName, skipUndefined) {
|
|
95
|
+
return arr.map((item) => {
|
|
96
|
+
if (item === undefined) {
|
|
97
|
+
if (!skipUndefined) {
|
|
98
|
+
throw new Error(`undefined passed as an item in argument #${i} for '${opName}' operation. Call skipUndefined() method to ignore the undefined values.`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (hasToKnexRawMethod(item)) {
|
|
102
|
+
return convertToKnexRaw(item, builder);
|
|
103
|
+
}
|
|
104
|
+
else if (isObjectionQueryBuilderBase(item)) {
|
|
105
|
+
return convertQueryBuilderBase(item, builder);
|
|
106
|
+
}
|
|
107
|
+
else if (isModelClass(item)) {
|
|
108
|
+
return item.getTableName();
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
return item;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function convertFunction(func, builder) {
|
|
116
|
+
return function convertedKnexArgumentFunction(...args) {
|
|
117
|
+
if (isKnexQueryBuilder(this)) {
|
|
118
|
+
convertQueryBuilderFunction(this, func, builder);
|
|
119
|
+
}
|
|
120
|
+
else if (isKnexJoinBuilder(this)) {
|
|
121
|
+
convertJoinBuilderFunction(this, func, builder);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return func.apply(this, args);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function convertQueryBuilderFunction(knexQueryBuilder, func, builder) {
|
|
129
|
+
const convertedQueryBuilder = builder.constructor.forClass(builder.modelClass());
|
|
130
|
+
convertedQueryBuilder.isPartial(true).subqueryOf(builder);
|
|
131
|
+
func.call(convertedQueryBuilder, convertedQueryBuilder);
|
|
132
|
+
convertedQueryBuilder.toKnexQuery(knexQueryBuilder);
|
|
133
|
+
}
|
|
134
|
+
function convertJoinBuilderFunction(knexJoinBuilder, func, builder) {
|
|
135
|
+
const JoinBuilder = getJoinBuilder();
|
|
136
|
+
const joinClauseBuilder = JoinBuilder.forClass(builder.modelClass());
|
|
137
|
+
joinClauseBuilder.isPartial(true).subqueryOf(builder);
|
|
138
|
+
func.call(joinClauseBuilder, joinClauseBuilder);
|
|
139
|
+
joinClauseBuilder.toKnexQuery(knexJoinBuilder);
|
|
140
|
+
}
|
|
141
|
+
function isModel(item) {
|
|
142
|
+
return isObject(item) && item.$isObjectionModel;
|
|
143
|
+
}
|
|
144
|
+
function convertModel(model) {
|
|
145
|
+
return model.$toDatabaseJson();
|
|
146
|
+
}
|
|
147
|
+
function convertPlainObject(obj, builder, i, opName, skipUndefined) {
|
|
148
|
+
return Object.keys(obj).reduce((out, key) => {
|
|
149
|
+
const item = obj[key];
|
|
150
|
+
if (item === undefined) {
|
|
151
|
+
if (!skipUndefined) {
|
|
152
|
+
throw new Error(`undefined passed as a property in argument #${i} for '${opName}' operation. Call skipUndefined() method to ignore the undefined values.`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else if (hasToKnexRawMethod(item)) {
|
|
156
|
+
out[key] = convertToKnexRaw(item, builder);
|
|
157
|
+
}
|
|
158
|
+
else if (isObjectionQueryBuilderBase(item)) {
|
|
159
|
+
out[key] = convertQueryBuilderBase(item, builder);
|
|
160
|
+
}
|
|
161
|
+
else if (isModelClass(item)) {
|
|
162
|
+
// `{ alias: ModelClass }`.
|
|
163
|
+
out[key] = item.getTableName();
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
out[key] = item;
|
|
167
|
+
}
|
|
168
|
+
return out;
|
|
169
|
+
}, {});
|
|
170
|
+
}
|
|
171
|
+
module.exports = {
|
|
172
|
+
ObjectionToKnexConvertingOperation,
|
|
173
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
class OnBuildKnexOperation extends QueryBuilderOperation {
|
|
4
|
+
constructor(name, opt) {
|
|
5
|
+
super(name, opt);
|
|
6
|
+
this.func = null;
|
|
7
|
+
}
|
|
8
|
+
onAdd(_, args) {
|
|
9
|
+
this.func = args[0];
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
onBuildKnex(knexBuilder, builder) {
|
|
13
|
+
return this.func.call(knexBuilder, knexBuilder, builder);
|
|
14
|
+
}
|
|
15
|
+
clone() {
|
|
16
|
+
const clone = super.clone();
|
|
17
|
+
clone.func = this.func;
|
|
18
|
+
return clone;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
module.exports = {
|
|
22
|
+
OnBuildKnexOperation,
|
|
23
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
class OnBuildOperation extends QueryBuilderOperation {
|
|
4
|
+
constructor(name, opt) {
|
|
5
|
+
super(name, opt);
|
|
6
|
+
this.func = null;
|
|
7
|
+
}
|
|
8
|
+
onAdd(_, args) {
|
|
9
|
+
this.func = args[0];
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
onBuild(builder) {
|
|
13
|
+
return this.func.call(builder, builder);
|
|
14
|
+
}
|
|
15
|
+
clone() {
|
|
16
|
+
const clone = super.clone();
|
|
17
|
+
clone.func = this.func;
|
|
18
|
+
return clone;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
module.exports = {
|
|
22
|
+
OnBuildOperation,
|
|
23
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
class OnErrorOperation extends QueryBuilderOperation {
|
|
4
|
+
constructor(name, opt) {
|
|
5
|
+
super(name, opt);
|
|
6
|
+
this.func = null;
|
|
7
|
+
}
|
|
8
|
+
onAdd(_, args) {
|
|
9
|
+
this.func = args[0];
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
onError(builder, error) {
|
|
13
|
+
return this.func.call(builder, error, builder);
|
|
14
|
+
}
|
|
15
|
+
clone() {
|
|
16
|
+
const clone = super.clone();
|
|
17
|
+
clone.func = this.func;
|
|
18
|
+
return clone;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
module.exports = {
|
|
22
|
+
OnErrorOperation,
|
|
23
|
+
};
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const hookNameToHasMethodName = {
|
|
3
|
+
onAdd: 'hasOnAdd',
|
|
4
|
+
onBefore1: 'hasOnBefore1',
|
|
5
|
+
onBefore2: 'hasOnBefore2',
|
|
6
|
+
onBefore3: 'hasOnBefore3',
|
|
7
|
+
onBuild: 'hasOnBuild',
|
|
8
|
+
onBuildKnex: 'hasOnBuildKnex',
|
|
9
|
+
onRawResult: 'hasOnRawResult',
|
|
10
|
+
queryExecutor: 'hasQueryExecutor',
|
|
11
|
+
onAfter1: 'hasOnAfter1',
|
|
12
|
+
onAfter2: 'hasOnAfter2',
|
|
13
|
+
onAfter3: 'hasOnAfter3',
|
|
14
|
+
onError: 'hasOnError',
|
|
15
|
+
};
|
|
16
|
+
// An abstract base class for all query builder operations. QueryBuilderOperations almost always
|
|
17
|
+
// correspond to a single query builder method call. For example SelectOperation could be added when
|
|
18
|
+
// a `select` method is called.
|
|
19
|
+
//
|
|
20
|
+
// QueryBuilderOperation is just a bunch of query execution lifecycle hooks that subclasses
|
|
21
|
+
// can (but don't have to) implement.
|
|
22
|
+
//
|
|
23
|
+
// Basically a query builder is nothing but an array of QueryBuilderOperations. When the query is
|
|
24
|
+
// executed the hooks are called in the order explained below. The hooks are called so that a
|
|
25
|
+
// certain hook is called for _all_ operations before the next hook is called. For example if
|
|
26
|
+
// a builder has 5 operations, onBefore1 hook is called for each of them (and their results are awaited)
|
|
27
|
+
// before onBefore2 hook is called for any of the operations.
|
|
28
|
+
class QueryBuilderOperation {
|
|
29
|
+
constructor(name = null, opt = {}) {
|
|
30
|
+
this.name = name;
|
|
31
|
+
this.opt = opt;
|
|
32
|
+
// From which hook was this operation added as a child
|
|
33
|
+
// operation.
|
|
34
|
+
this.adderHookName = null;
|
|
35
|
+
// The parent operation that added this operation.
|
|
36
|
+
this.parentOperation = null;
|
|
37
|
+
// Operations this operation added in any of its hooks.
|
|
38
|
+
this.childOperations = [];
|
|
39
|
+
// The where scope (see `whereScopes.js`) this operation was added in.
|
|
40
|
+
this.whereScope = null;
|
|
41
|
+
}
|
|
42
|
+
is(OperationClass) {
|
|
43
|
+
return this instanceof OperationClass;
|
|
44
|
+
}
|
|
45
|
+
hasHook(hookName) {
|
|
46
|
+
return this[hookNameToHasMethodName[hookName]]();
|
|
47
|
+
}
|
|
48
|
+
// This is called immediately when a query builder method is called.
|
|
49
|
+
//
|
|
50
|
+
// This method must be synchronous.
|
|
51
|
+
// This method should never call any methods that add operations to the builder.
|
|
52
|
+
onAdd(builder, args) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
hasOnAdd() {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// This is called as the first thing when the query is executed but before
|
|
59
|
+
// the actual database operation (knex query) is executed.
|
|
60
|
+
//
|
|
61
|
+
// This method can be asynchronous.
|
|
62
|
+
// You may call methods that add operations to to the builder.
|
|
63
|
+
onBefore1(builder, result) { }
|
|
64
|
+
hasOnBefore1() {
|
|
65
|
+
return this.onBefore1 !== QueryBuilderOperation.prototype.onBefore1;
|
|
66
|
+
}
|
|
67
|
+
// This is called as the second thing when the query is executed but before
|
|
68
|
+
// the actual database operation (knex query) is executed.
|
|
69
|
+
//
|
|
70
|
+
// This method can be asynchronous.
|
|
71
|
+
// You may call methods that add operations to to the builder.
|
|
72
|
+
onBefore2(builder, result) { }
|
|
73
|
+
hasOnBefore2() {
|
|
74
|
+
return this.onBefore2 !== QueryBuilderOperation.prototype.onBefore2;
|
|
75
|
+
}
|
|
76
|
+
// This is called as the third thing when the query is executed but before
|
|
77
|
+
// the actual database operation (knex query) is executed.
|
|
78
|
+
//
|
|
79
|
+
// This method can be asynchronous.
|
|
80
|
+
// You may call methods that add operations to to the builder.
|
|
81
|
+
onBefore3(builder, result) { }
|
|
82
|
+
hasOnBefore3() {
|
|
83
|
+
return this.onBefore3 !== QueryBuilderOperation.prototype.onBefore3;
|
|
84
|
+
}
|
|
85
|
+
// This is called as the last thing when the query is executed but before
|
|
86
|
+
// the actual database operation (knex query) is executed. If your operation
|
|
87
|
+
// needs to call other query building operations (methods that add QueryBuilderOperations)
|
|
88
|
+
// this is the best and last place to do it.
|
|
89
|
+
//
|
|
90
|
+
// This method must be synchronous.
|
|
91
|
+
// You may call methods that add operations to to the builder.
|
|
92
|
+
onBuild(builder) { }
|
|
93
|
+
hasOnBuild() {
|
|
94
|
+
return this.onBuild !== QueryBuilderOperation.prototype.onBuild;
|
|
95
|
+
}
|
|
96
|
+
// This is called when the knex query is built. Here you should only call knex
|
|
97
|
+
// methods. You may call getters and other immutable methods of the `builder`
|
|
98
|
+
// but you should never call methods that add QueryBuilderOperations.
|
|
99
|
+
//
|
|
100
|
+
// This method must be synchronous.
|
|
101
|
+
// This method should never call any methods that add operations to the builder.
|
|
102
|
+
// This method should always return the knex query builder.
|
|
103
|
+
onBuildKnex(knexBuilder, builder) {
|
|
104
|
+
return knexBuilder;
|
|
105
|
+
}
|
|
106
|
+
hasOnBuildKnex() {
|
|
107
|
+
return this.onBuildKnex !== QueryBuilderOperation.prototype.onBuildKnex;
|
|
108
|
+
}
|
|
109
|
+
// The raw knex result is passed to this method right after the database query
|
|
110
|
+
// has finished. This method may modify it and return the modified rows. The
|
|
111
|
+
// rows are automatically converted to models (if possible) after this hook
|
|
112
|
+
// is called.
|
|
113
|
+
//
|
|
114
|
+
// This method can be asynchronous.
|
|
115
|
+
onRawResult(builder, rows) {
|
|
116
|
+
return rows;
|
|
117
|
+
}
|
|
118
|
+
hasOnRawResult() {
|
|
119
|
+
return this.onRawResult !== QueryBuilderOperation.prototype.onRawResult;
|
|
120
|
+
}
|
|
121
|
+
// This is called as the first thing after the query has been executed and
|
|
122
|
+
// rows have been converted to model instances.
|
|
123
|
+
//
|
|
124
|
+
// This method can be asynchronous.
|
|
125
|
+
onAfter1(builder, result) {
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
hasOnAfter1() {
|
|
129
|
+
return this.onAfter1 !== QueryBuilderOperation.prototype.onAfter1;
|
|
130
|
+
}
|
|
131
|
+
// This is called as the second thing after the query has been executed and
|
|
132
|
+
// rows have been converted to model instances.
|
|
133
|
+
//
|
|
134
|
+
// This method can be asynchronous.
|
|
135
|
+
onAfter2(builder, result) {
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
hasOnAfter2() {
|
|
139
|
+
return this.onAfter2 !== QueryBuilderOperation.prototype.onAfter2;
|
|
140
|
+
}
|
|
141
|
+
// This is called as the third thing after the query has been executed and
|
|
142
|
+
// rows have been converted to model instances.
|
|
143
|
+
//
|
|
144
|
+
// This method can be asynchronous.
|
|
145
|
+
onAfter3(builder, result) {
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
hasOnAfter3() {
|
|
149
|
+
return this.onAfter3 !== QueryBuilderOperation.prototype.onAfter3;
|
|
150
|
+
}
|
|
151
|
+
// This method can be implemented to return another operation that will replace
|
|
152
|
+
// this one. This method is called after all `onBeforeX` and `onBuildX` hooks
|
|
153
|
+
// but before the database query is executed.
|
|
154
|
+
//
|
|
155
|
+
// This method must return a QueryBuilder instance.
|
|
156
|
+
queryExecutor(builder) { }
|
|
157
|
+
hasQueryExecutor() {
|
|
158
|
+
return this.queryExecutor !== QueryBuilderOperation.prototype.queryExecutor;
|
|
159
|
+
}
|
|
160
|
+
// This is called if an error occurs in the query execution.
|
|
161
|
+
//
|
|
162
|
+
// This method must return a QueryBuilder instance.
|
|
163
|
+
onError(builder, error) { }
|
|
164
|
+
hasOnError() {
|
|
165
|
+
return this.onError !== QueryBuilderOperation.prototype.onError;
|
|
166
|
+
}
|
|
167
|
+
// Returns the "find" equivalent of this operation.
|
|
168
|
+
//
|
|
169
|
+
// For example an operation that finds an item and updates it
|
|
170
|
+
// should return an operation that simply finds the item but
|
|
171
|
+
// doesn't update anything. An insert operation should return
|
|
172
|
+
// null since there is no find equivalent for it etc.
|
|
173
|
+
toFindOperation(builder) {
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
hasToFindOperation() {
|
|
177
|
+
return this.toFindOperation !== QueryBuilderOperation.prototype.toFindOperation;
|
|
178
|
+
}
|
|
179
|
+
// Given a set of operations, returns true if any of this operation's
|
|
180
|
+
// ancestor operations are included in the set.
|
|
181
|
+
isAncestorInSet(operationSet) {
|
|
182
|
+
let ancestor = this.parentOperation;
|
|
183
|
+
while (ancestor) {
|
|
184
|
+
if (operationSet.has(ancestor)) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
ancestor = ancestor.parentOperation;
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
// Takes a deep clone of this operation.
|
|
192
|
+
clone() {
|
|
193
|
+
const clone = new this.constructor(this.name, this.opt);
|
|
194
|
+
clone.adderHookName = this.adderHookName;
|
|
195
|
+
clone.parentOperation = this.parentOperation;
|
|
196
|
+
clone.whereScope = this.whereScope;
|
|
197
|
+
clone.childOperations = this.childOperations.map((childOp) => {
|
|
198
|
+
const childOpClone = childOp.clone();
|
|
199
|
+
childOpClone.parentOperation = clone;
|
|
200
|
+
return childOpClone;
|
|
201
|
+
});
|
|
202
|
+
return clone;
|
|
203
|
+
}
|
|
204
|
+
// Add an operation as a child operation. `hookName` must be the
|
|
205
|
+
// name of the parent operation's hook that called this method.
|
|
206
|
+
addChildOperation(hookName, operation) {
|
|
207
|
+
operation.adderHookName = hookName;
|
|
208
|
+
operation.parentOperation = this;
|
|
209
|
+
this.childOperations.push(operation);
|
|
210
|
+
}
|
|
211
|
+
// Removes a single child operation.
|
|
212
|
+
removeChildOperation(operation) {
|
|
213
|
+
const index = this.childOperations.indexOf(operation);
|
|
214
|
+
if (index !== -1) {
|
|
215
|
+
operation.parentOperation = null;
|
|
216
|
+
this.childOperations.splice(index, 1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Replaces a single child operation.
|
|
220
|
+
replaceChildOperation(operation, newOperation) {
|
|
221
|
+
const index = this.childOperations.indexOf(operation);
|
|
222
|
+
if (index !== -1) {
|
|
223
|
+
newOperation.adderHookName = operation.adderHookName;
|
|
224
|
+
newOperation.parentOperation = this;
|
|
225
|
+
operation.parentOperation = null;
|
|
226
|
+
this.childOperations[index] = newOperation;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Removes all child operations that were added from the `hookName` hook.
|
|
230
|
+
removeChildOperationsByHookName(hookName) {
|
|
231
|
+
// Called before every hook. Most operations have no children.
|
|
232
|
+
if (this.childOperations.length !== 0) {
|
|
233
|
+
this.childOperations = this.childOperations.filter((op) => op.adderHookName !== hookName);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Iterates through all descendant operations recursively.
|
|
237
|
+
forEachDescendantOperation(callback) {
|
|
238
|
+
for (const operation of this.childOperations) {
|
|
239
|
+
if (callback(operation) === false) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
if (operation.forEachDescendantOperation(callback) === false) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
Object.defineProperties(QueryBuilderOperation, {
|
|
250
|
+
isObjectionQueryBuilderOperationClass: {
|
|
251
|
+
enumerable: false,
|
|
252
|
+
writable: false,
|
|
253
|
+
value: true,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
module.exports = {
|
|
257
|
+
QueryBuilderOperation,
|
|
258
|
+
};
|