@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,147 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
const { StaticHookArguments, hasStaticHook } = require('../StaticHookArguments');
|
|
4
|
+
const { isPromise, after, afterReturn } = require('../../utils/promiseUtils');
|
|
5
|
+
const { isObject } = require('../../utils/objectUtils');
|
|
6
|
+
class FindOperation extends QueryBuilderOperation {
|
|
7
|
+
onBefore2(builder, result) {
|
|
8
|
+
return afterReturn(callStaticBeforeFind(builder), result);
|
|
9
|
+
}
|
|
10
|
+
onAfter3(builder, results) {
|
|
11
|
+
const opt = builder.findOptions();
|
|
12
|
+
if (opt.dontCallFindHooks) {
|
|
13
|
+
return results;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
return callAfterFind(builder, results);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function callStaticBeforeFind(builder) {
|
|
21
|
+
if (!hasStaticHook(builder.modelClass(), 'beforeFind')) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const args = StaticHookArguments.create({ builder });
|
|
25
|
+
return builder.modelClass().beforeFind(args);
|
|
26
|
+
}
|
|
27
|
+
function callAfterFind(builder, result) {
|
|
28
|
+
const opt = builder.findOptions();
|
|
29
|
+
const maybePromise = callInstanceAfterFind(builder.context(), result, opt.callAfterFindDeeply);
|
|
30
|
+
return after(maybePromise, () => callStaticAfterFind(builder, result));
|
|
31
|
+
}
|
|
32
|
+
function callStaticAfterFind(builder, result) {
|
|
33
|
+
if (!hasStaticHook(builder.modelClass(), 'afterFind')) {
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
const args = StaticHookArguments.create({ builder, result });
|
|
37
|
+
const maybePromise = builder.modelClass().afterFind(args);
|
|
38
|
+
return after(maybePromise, (maybeResult) => {
|
|
39
|
+
if (maybeResult === undefined) {
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return maybeResult;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function callInstanceAfterFind(ctx, results, deep) {
|
|
48
|
+
if (Array.isArray(results)) {
|
|
49
|
+
if (results.length === 1) {
|
|
50
|
+
return callAfterFindForOne(ctx, results[0], results, deep);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return callAfterFindArray(ctx, results, deep);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
return callAfterFindForOne(ctx, results, results, deep);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function callAfterFindArray(ctx, results, deep) {
|
|
61
|
+
if (results.length === 0 || !isObject(results[0])) {
|
|
62
|
+
return results;
|
|
63
|
+
}
|
|
64
|
+
const mapped = new Array(results.length);
|
|
65
|
+
let containsPromise = false;
|
|
66
|
+
for (let i = 0, l = results.length; i < l; ++i) {
|
|
67
|
+
mapped[i] = callAfterFindForOne(ctx, results[i], results[i], deep);
|
|
68
|
+
if (isPromise(mapped[i])) {
|
|
69
|
+
containsPromise = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (containsPromise) {
|
|
73
|
+
return Promise.all(mapped);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return mapped;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function callAfterFindForOne(ctx, model, result, deep) {
|
|
80
|
+
if (!isObject(model) || !model.$isObjectionModel) {
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
if (deep) {
|
|
84
|
+
const results = [];
|
|
85
|
+
const containsPromise = callAfterFindForRelations(ctx, model, results);
|
|
86
|
+
if (containsPromise) {
|
|
87
|
+
return Promise.all(results).then(() => {
|
|
88
|
+
return doCallAfterFind(ctx, model, result);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return doCallAfterFind(ctx, model, result);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
return doCallAfterFind(ctx, model, result);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function callAfterFindForRelations(ctx, model, results) {
|
|
100
|
+
const keys = Object.keys(model);
|
|
101
|
+
let containsPromise = false;
|
|
102
|
+
for (let i = 0, l = keys.length; i < l; ++i) {
|
|
103
|
+
const key = keys[i];
|
|
104
|
+
const value = model[key];
|
|
105
|
+
if (isRelation(value)) {
|
|
106
|
+
const maybePromise = callInstanceAfterFind(ctx, value, true);
|
|
107
|
+
if (isPromise(maybePromise)) {
|
|
108
|
+
containsPromise = true;
|
|
109
|
+
}
|
|
110
|
+
results.push(maybePromise);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return containsPromise;
|
|
114
|
+
}
|
|
115
|
+
function isRelation(value) {
|
|
116
|
+
return ((isObject(value) && value.$isObjectionModel) ||
|
|
117
|
+
(isNonEmptyObjectArray(value) && value[0].$isObjectionModel));
|
|
118
|
+
}
|
|
119
|
+
function isNonEmptyObjectArray(value) {
|
|
120
|
+
return Array.isArray(value) && value.length > 0 && isObject(value[0]);
|
|
121
|
+
}
|
|
122
|
+
function doCallAfterFind(ctx, model, result) {
|
|
123
|
+
const afterFind = getAfterFindHook(model);
|
|
124
|
+
if (afterFind !== null) {
|
|
125
|
+
const maybePromise = afterFind.call(model, ctx);
|
|
126
|
+
if (isPromise(maybePromise)) {
|
|
127
|
+
return maybePromise.then(() => result);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function getAfterFindHook(model) {
|
|
138
|
+
if (model.$afterFind !== model.$objectionModelClass.prototype.$afterFind) {
|
|
139
|
+
return model.$afterFind;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
module.exports = {
|
|
146
|
+
FindOperation,
|
|
147
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
3
|
+
class FirstOperation extends QueryBuilderOperation {
|
|
4
|
+
onBuildKnex(knexBuilder, builder) {
|
|
5
|
+
const modelClass = builder.modelClass();
|
|
6
|
+
if (builder.isFind() && modelClass.useLimitInFirst) {
|
|
7
|
+
knexBuilder = knexBuilder.limit(1);
|
|
8
|
+
}
|
|
9
|
+
return knexBuilder;
|
|
10
|
+
}
|
|
11
|
+
onAfter3(_, result) {
|
|
12
|
+
if (Array.isArray(result)) {
|
|
13
|
+
return result[0];
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
module.exports = {
|
|
21
|
+
FirstOperation,
|
|
22
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { ObjectionToKnexConvertingOperation } = require('./ObjectionToKnexConvertingOperation');
|
|
3
|
+
const { isPlainObject, isString } = require('../../utils/objectUtils');
|
|
4
|
+
const { isModelClass } = require('../../utils/resolveModel');
|
|
5
|
+
const ALIAS_REGEX = /\s+as\s+/i;
|
|
6
|
+
// FromOperation corresponds to a `.from(args)` call. The call is delegated to
|
|
7
|
+
// knex, but we first try to parse the arguments so that we can determine which
|
|
8
|
+
// tables have been mentioned in a query's from clause. We only parse string
|
|
9
|
+
// references and not `raw` or `ref` etc. references at this point thouhg.
|
|
10
|
+
class FromOperation extends ObjectionToKnexConvertingOperation {
|
|
11
|
+
constructor(name, opt) {
|
|
12
|
+
super(name, opt);
|
|
13
|
+
this.table = null;
|
|
14
|
+
this.alias = null;
|
|
15
|
+
}
|
|
16
|
+
onAdd(builder, args) {
|
|
17
|
+
const ret = super.onAdd(builder, args);
|
|
18
|
+
const parsed = parseTableAndAlias(this.args[0], builder);
|
|
19
|
+
if (parsed.table) {
|
|
20
|
+
builder.tableName(parsed.table);
|
|
21
|
+
this.table = parsed.table;
|
|
22
|
+
}
|
|
23
|
+
if (parsed.alias) {
|
|
24
|
+
builder.aliasFor(builder.modelClass().getTableName(), parsed.alias);
|
|
25
|
+
this.alias = parsed.alias;
|
|
26
|
+
}
|
|
27
|
+
return ret;
|
|
28
|
+
}
|
|
29
|
+
onBuildKnex(knexBuilder, builder) {
|
|
30
|
+
// Simply call knex's from method with the converted arguments.
|
|
31
|
+
return knexBuilder.from.apply(knexBuilder, this.getKnexArgs(builder));
|
|
32
|
+
}
|
|
33
|
+
clone() {
|
|
34
|
+
const clone = super.clone();
|
|
35
|
+
clone.table = this.table;
|
|
36
|
+
clone.alias = this.alias;
|
|
37
|
+
return clone;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function parseTableAndAlias(arg, builder) {
|
|
41
|
+
if (isModelClass(arg)) {
|
|
42
|
+
return parseTableAndAliasFromString(arg.getTableName());
|
|
43
|
+
}
|
|
44
|
+
else if (isString(arg)) {
|
|
45
|
+
return parseTableAndAliasFromString(arg);
|
|
46
|
+
}
|
|
47
|
+
else if (isPlainObject(arg)) {
|
|
48
|
+
return parseTableAndAliasFromObject(arg, builder);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Could not parse table and alias from the arguments.
|
|
52
|
+
return {
|
|
53
|
+
table: null,
|
|
54
|
+
alias: null,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function parseTableAndAliasFromString(arg) {
|
|
59
|
+
if (ALIAS_REGEX.test(arg)) {
|
|
60
|
+
const parts = arg.split(ALIAS_REGEX);
|
|
61
|
+
return {
|
|
62
|
+
table: parts[0].trim(),
|
|
63
|
+
alias: parts[1].trim(),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return {
|
|
68
|
+
table: arg.trim(),
|
|
69
|
+
alias: null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function parseTableAndAliasFromObject(arg, builder) {
|
|
74
|
+
for (const alias of Object.keys(arg)) {
|
|
75
|
+
const value = isModelClass(arg[alias]) ? arg[alias].getTableName() : arg[alias];
|
|
76
|
+
if (!isString(value)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const table = value.trim();
|
|
80
|
+
if (table === builder.modelClass().getTableName()) {
|
|
81
|
+
return {
|
|
82
|
+
alias,
|
|
83
|
+
table,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`one of the tables in ${JSON.stringify(arg)} must be the query's model class's table.`);
|
|
88
|
+
}
|
|
89
|
+
module.exports = {
|
|
90
|
+
FromOperation,
|
|
91
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { InsertOperation } = require('./InsertOperation');
|
|
3
|
+
const { DelegateOperation } = require('./DelegateOperation');
|
|
4
|
+
const { keyByProps } = require('../../model/modelUtils');
|
|
5
|
+
const { asArray } = require('../../utils/objectUtils');
|
|
6
|
+
class InsertAndFetchOperation extends DelegateOperation {
|
|
7
|
+
constructor(name, opt) {
|
|
8
|
+
super(name, opt);
|
|
9
|
+
if (!this.delegate.is(InsertOperation)) {
|
|
10
|
+
throw new Error('Invalid delegate');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
get models() {
|
|
14
|
+
return this.delegate.models;
|
|
15
|
+
}
|
|
16
|
+
async onAfter2(builder, inserted) {
|
|
17
|
+
const modelClass = builder.modelClass();
|
|
18
|
+
const insertedModels = await super.onAfter2(builder, inserted);
|
|
19
|
+
const insertedModelArray = asArray(insertedModels);
|
|
20
|
+
const idProps = modelClass.getIdPropertyArray();
|
|
21
|
+
const ids = insertedModelArray.map((model) => model.$id());
|
|
22
|
+
const fetchedModels = await modelClass
|
|
23
|
+
.query()
|
|
24
|
+
.childQueryOf(builder)
|
|
25
|
+
.findByIds(ids)
|
|
26
|
+
.castTo(builder.resultModelClass());
|
|
27
|
+
const modelsById = keyByProps(fetchedModels, idProps);
|
|
28
|
+
// Instead of returning the freshly fetched models, update the input
|
|
29
|
+
// models with the fresh values.
|
|
30
|
+
insertedModelArray.forEach((insertedModel) => {
|
|
31
|
+
insertedModel.$set(modelsById.get(insertedModel.$propKey(idProps)));
|
|
32
|
+
});
|
|
33
|
+
return insertedModels;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
module.exports = {
|
|
37
|
+
InsertAndFetchOperation,
|
|
38
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { DelegateOperation } = require('./DelegateOperation');
|
|
3
|
+
const { InsertGraphOperation } = require('./InsertGraphOperation');
|
|
4
|
+
const { RelationExpression } = require('../RelationExpression');
|
|
5
|
+
class InsertGraphAndFetchOperation extends DelegateOperation {
|
|
6
|
+
constructor(name, opt) {
|
|
7
|
+
super(name, opt);
|
|
8
|
+
if (!this.delegate.is(InsertGraphOperation)) {
|
|
9
|
+
throw new Error('Invalid delegate');
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
get models() {
|
|
13
|
+
return this.delegate.models;
|
|
14
|
+
}
|
|
15
|
+
get isArray() {
|
|
16
|
+
return this.delegate.isArray;
|
|
17
|
+
}
|
|
18
|
+
async onAfter2(builder) {
|
|
19
|
+
if (this.models.length === 0) {
|
|
20
|
+
return this.isArray ? [] : null;
|
|
21
|
+
}
|
|
22
|
+
const eager = RelationExpression.fromModelGraph(this.models);
|
|
23
|
+
const modelClass = this.models[0].constructor;
|
|
24
|
+
const ids = this.models.map((model) => model.$id());
|
|
25
|
+
const models = await modelClass
|
|
26
|
+
.query()
|
|
27
|
+
.childQueryOf(builder)
|
|
28
|
+
.findByIds(ids)
|
|
29
|
+
.withGraphFetched(eager);
|
|
30
|
+
return this.isArray ? models : models[0] || null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
module.exports = {
|
|
34
|
+
InsertGraphAndFetchOperation,
|
|
35
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { DelegateOperation } = require('./DelegateOperation');
|
|
3
|
+
const { InsertOperation } = require('./InsertOperation');
|
|
4
|
+
const { GraphUpsert } = require('../graph/GraphUpsert');
|
|
5
|
+
class InsertGraphOperation extends DelegateOperation {
|
|
6
|
+
constructor(name, opt = null) {
|
|
7
|
+
super(name, opt);
|
|
8
|
+
if (!this.delegate.is(InsertOperation)) {
|
|
9
|
+
throw new Error('Invalid delegate');
|
|
10
|
+
}
|
|
11
|
+
Object.assign(this.delegate.modelOptions, GraphUpsert.modelOptions);
|
|
12
|
+
this.upsertOptions = opt.opt || {};
|
|
13
|
+
this.upsert = null;
|
|
14
|
+
}
|
|
15
|
+
get models() {
|
|
16
|
+
return this.delegate.models;
|
|
17
|
+
}
|
|
18
|
+
get isArray() {
|
|
19
|
+
return this.delegate.isArray;
|
|
20
|
+
}
|
|
21
|
+
get relation() {
|
|
22
|
+
return this.delegate.relation;
|
|
23
|
+
}
|
|
24
|
+
onAdd(builder, args) {
|
|
25
|
+
const retVal = super.onAdd(builder, args);
|
|
26
|
+
this.upsert = new GraphUpsert({
|
|
27
|
+
objects: this.models,
|
|
28
|
+
rootModelClass: builder.modelClass(),
|
|
29
|
+
upsertOptions: Object.assign({}, this.upsertOptions, {
|
|
30
|
+
noUpdate: true,
|
|
31
|
+
noDelete: true,
|
|
32
|
+
noUnrelate: true,
|
|
33
|
+
insertMissing: true,
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
// We resolve this query here and will not execute it. This is because the root
|
|
37
|
+
// value may depend on other models in the graph and cannot be inserted first.
|
|
38
|
+
builder.resolve([]);
|
|
39
|
+
return retVal;
|
|
40
|
+
}
|
|
41
|
+
onBefore1(_, result) {
|
|
42
|
+
// Do nothing.
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
onBefore2(builder, result) {
|
|
46
|
+
// We override this with empty implementation so that the $beforeInsert()
|
|
47
|
+
// hooks are not called twice for the root models.
|
|
48
|
+
if (this.relation) {
|
|
49
|
+
// We still need to call the relation before insert hook if the the
|
|
50
|
+
// delegate operation is a RelationInsertOperation.
|
|
51
|
+
return this.relation.executeBeforeInsert(this.models, builder.context(), result);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
onBefore3(_, result) {
|
|
58
|
+
// Do nothing.
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
onBuild() {
|
|
62
|
+
// Do nothing.
|
|
63
|
+
}
|
|
64
|
+
onBuildKnex(knexBuilder) {
|
|
65
|
+
// Do nothing.
|
|
66
|
+
return knexBuilder;
|
|
67
|
+
}
|
|
68
|
+
// We overrode all other hooks but this one and do all the work in here.
|
|
69
|
+
// This is a bit hacky.
|
|
70
|
+
async onAfter1(builder, ...restArgs) {
|
|
71
|
+
await this.upsert.run(builder);
|
|
72
|
+
return await super.onAfter1(builder, ...restArgs);
|
|
73
|
+
}
|
|
74
|
+
onAfter2() {
|
|
75
|
+
// We override this with empty implementation so that the $afterInsert() hooks
|
|
76
|
+
// are not called twice for the root models.
|
|
77
|
+
return this.isArray ? this.models : this.models[0] || null;
|
|
78
|
+
}
|
|
79
|
+
clone() {
|
|
80
|
+
const clone = super.clone();
|
|
81
|
+
clone.upsert = this.upsert;
|
|
82
|
+
return clone;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
module.exports = {
|
|
86
|
+
InsertGraphOperation,
|
|
87
|
+
};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/* global BigInt */
|
|
3
|
+
const { QueryBuilderOperation } = require('./QueryBuilderOperation');
|
|
4
|
+
const { StaticHookArguments, hasStaticHook } = require('../StaticHookArguments');
|
|
5
|
+
const { after, mapAfterAllReturn } = require('../../utils/promiseUtils');
|
|
6
|
+
const { isSqlite, isMySql } = require('../../utils/knexUtils');
|
|
7
|
+
const { isObject } = require('../../utils/objectUtils');
|
|
8
|
+
// `@@auto_increment_increment` for each MySQL knex instance, keyed by the knex config,
|
|
9
|
+
// which transactions share with the knex they were started from.
|
|
10
|
+
const autoIncrementIncrements = new WeakMap();
|
|
11
|
+
// Base class for all insert operations.
|
|
12
|
+
class InsertOperation extends QueryBuilderOperation {
|
|
13
|
+
constructor(name, opt) {
|
|
14
|
+
super(name, opt);
|
|
15
|
+
this.models = null;
|
|
16
|
+
this.isArray = false;
|
|
17
|
+
this.modelOptions = Object.assign({}, this.opt.modelOptions || {});
|
|
18
|
+
this.autoIncrementIncrement = null;
|
|
19
|
+
}
|
|
20
|
+
onAdd(builder, args) {
|
|
21
|
+
const json = args[0];
|
|
22
|
+
const modelClass = builder.modelClass();
|
|
23
|
+
this.isArray = Array.isArray(json);
|
|
24
|
+
this.models = modelClass.ensureModelArray(json, this.modelOptions);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
async onBefore2(builder, result) {
|
|
28
|
+
await callBeforeInsert(builder, this.models);
|
|
29
|
+
if (this.models.length > 1 && isMySql(builder.knex())) {
|
|
30
|
+
await this.prepareMySqlBatchInsert(builder);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
// MySQL only returns the id of the first row of a multi-row insert. InnoDB
|
|
35
|
+
// gives the rows of one multi-row VALUES insert consecutive ids (in every
|
|
36
|
+
// `innodb_autoinc_lock_mode`), so the other ids can be computed from it and
|
|
37
|
+
// `@@auto_increment_increment`.
|
|
38
|
+
async prepareMySqlBatchInsert(builder) {
|
|
39
|
+
const withId = this.models.filter((model) => model.$hasId()).length;
|
|
40
|
+
if (withId === this.models.length) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (withId > 0) {
|
|
44
|
+
throw new Error(`batch insert on MySQL can't return ids when only some rows have an id. Set the id on all rows or none.`);
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(builder.modelClass().getIdColumn())) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const knex = builder.knex();
|
|
50
|
+
let increment = autoIncrementIncrements.get(knex.client.config);
|
|
51
|
+
if (increment === undefined) {
|
|
52
|
+
const [rows] = await knex.raw('select @@auto_increment_increment as increment');
|
|
53
|
+
increment = Number(rows[0].increment);
|
|
54
|
+
autoIncrementIncrements.set(knex.client.config, increment);
|
|
55
|
+
}
|
|
56
|
+
this.autoIncrementIncrement = increment;
|
|
57
|
+
}
|
|
58
|
+
onBuildKnex(knexBuilder, builder) {
|
|
59
|
+
const knex = builder.knex();
|
|
60
|
+
const returnsIds = !isMySql(knex) && (!isSqlite(knex) || this.models.length > 1);
|
|
61
|
+
if (returnsIds && !builder.has(/returning/)) {
|
|
62
|
+
// If the user hasn't specified a `returning` clause, we make sure
|
|
63
|
+
// that at least the identifier is returned. SQLite only returns the
|
|
64
|
+
// id of the last row without one.
|
|
65
|
+
knexBuilder = knexBuilder.returning(builder.modelClass().getIdColumn());
|
|
66
|
+
}
|
|
67
|
+
return knexBuilder.insert(this.models.map((model) => model.$toDatabaseJson(builder)));
|
|
68
|
+
}
|
|
69
|
+
onAfter1(builder, ret) {
|
|
70
|
+
if (!Array.isArray(ret) || !ret.length || ret === this.models) {
|
|
71
|
+
// Early exit if there is nothing to do.
|
|
72
|
+
return this.models;
|
|
73
|
+
}
|
|
74
|
+
if (ret.length === 1 && this.models.length > 1) {
|
|
75
|
+
this.setMySqlBatchInsertIds(builder, ret[0]);
|
|
76
|
+
}
|
|
77
|
+
else if (isObject(ret[0])) {
|
|
78
|
+
// If the user specified a `returning` clause the result may be an array of objects.
|
|
79
|
+
// Merge all values of the objects to our models.
|
|
80
|
+
for (let i = 0, l = this.models.length; i < l; ++i) {
|
|
81
|
+
this.models[i].$setDatabaseJson(ret[i]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// If the return value is not an array of objects, we assume it is an array of identifiers.
|
|
86
|
+
for (let i = 0, l = this.models.length; i < l; ++i) {
|
|
87
|
+
const model = this.models[i];
|
|
88
|
+
// Don't set the id if the model already has one. MySQL and Sqlite don't return the correct
|
|
89
|
+
// primary key value if the id is not generated in db, but given explicitly.
|
|
90
|
+
if (!model.$id()) {
|
|
91
|
+
model.$id(ret[i]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return this.models;
|
|
96
|
+
}
|
|
97
|
+
setMySqlBatchInsertIds(builder, firstId) {
|
|
98
|
+
const increment = this.autoIncrementIncrement;
|
|
99
|
+
// `onConflict()` may skip or update rows, which breaks the id sequence.
|
|
100
|
+
if (increment === null || builder.has(/onConflict/) || !firstId) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
for (let i = 0, l = this.models.length; i < l; ++i) {
|
|
104
|
+
this.models[i].$id(addToId(firstId, i * increment));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
onAfter2(builder, models) {
|
|
108
|
+
const result = this.isArray ? models : models[0] || null;
|
|
109
|
+
return callAfterInsert(builder, this.models, result);
|
|
110
|
+
}
|
|
111
|
+
toFindOperation() {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
clone() {
|
|
115
|
+
const clone = super.clone();
|
|
116
|
+
clone.models = this.models;
|
|
117
|
+
clone.isArray = this.isArray;
|
|
118
|
+
clone.autoIncrementIncrement = this.autoIncrementIncrement;
|
|
119
|
+
return clone;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// The id can be a string or a BigInt when the driver is configured to
|
|
123
|
+
// return big numbers that way.
|
|
124
|
+
function addToId(id, amount) {
|
|
125
|
+
if (typeof id === 'number') {
|
|
126
|
+
return id + amount;
|
|
127
|
+
}
|
|
128
|
+
else if (typeof id === 'bigint') {
|
|
129
|
+
return id + BigInt(amount);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
return String(BigInt(id) + BigInt(amount));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function callBeforeInsert(builder, models) {
|
|
136
|
+
const maybePromise = callInstanceBeforeInsert(builder, models);
|
|
137
|
+
return after(maybePromise, () => callStaticBeforeInsert(builder));
|
|
138
|
+
}
|
|
139
|
+
function callInstanceBeforeInsert(builder, models) {
|
|
140
|
+
return mapAfterAllReturn(models, (model) => model.$beforeInsert(builder.context()), models);
|
|
141
|
+
}
|
|
142
|
+
function callStaticBeforeInsert(builder) {
|
|
143
|
+
if (!hasStaticHook(builder.modelClass(), 'beforeInsert')) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const args = StaticHookArguments.create({ builder });
|
|
147
|
+
return builder.modelClass().beforeInsert(args);
|
|
148
|
+
}
|
|
149
|
+
function callAfterInsert(builder, models, result) {
|
|
150
|
+
const maybePromise = callInstanceAfterInsert(builder, models);
|
|
151
|
+
return after(maybePromise, () => callStaticAfterInsert(builder, result));
|
|
152
|
+
}
|
|
153
|
+
function callInstanceAfterInsert(builder, models) {
|
|
154
|
+
return mapAfterAllReturn(models, (model) => model.$afterInsert(builder.context()), models);
|
|
155
|
+
}
|
|
156
|
+
function callStaticAfterInsert(builder, result) {
|
|
157
|
+
if (!hasStaticHook(builder.modelClass(), 'afterInsert')) {
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
const args = StaticHookArguments.create({ builder, result });
|
|
161
|
+
const maybePromise = builder.modelClass().afterInsert(args);
|
|
162
|
+
return after(maybePromise, (maybeResult) => {
|
|
163
|
+
if (maybeResult === undefined) {
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
return maybeResult;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
module.exports = {
|
|
172
|
+
InsertOperation,
|
|
173
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { withWhereScope } = require('../whereScopes');
|
|
3
|
+
const { DeleteOperation } = require('./DeleteOperation');
|
|
4
|
+
const { InstanceFindOperation } = require('./InstanceFindOperation');
|
|
5
|
+
const { assertHasId } = require('../../utils/assert');
|
|
6
|
+
class InstanceDeleteOperation extends DeleteOperation {
|
|
7
|
+
constructor(name, opt) {
|
|
8
|
+
super(name, opt);
|
|
9
|
+
this.instance = opt.instance;
|
|
10
|
+
}
|
|
11
|
+
async onBefore2(builder, result) {
|
|
12
|
+
await this.instance.$beforeDelete(builder.context());
|
|
13
|
+
await super.onBefore2(builder, result);
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
onBuild(builder) {
|
|
17
|
+
super.onBuild(builder);
|
|
18
|
+
assertHasId(this.instance);
|
|
19
|
+
withWhereScope(builder, () => builder.findById(this.instance.$id()));
|
|
20
|
+
}
|
|
21
|
+
async onAfter2(builder, result) {
|
|
22
|
+
// The result may be an object if `returning` was used.
|
|
23
|
+
if (Array.isArray(result)) {
|
|
24
|
+
result = result[0];
|
|
25
|
+
}
|
|
26
|
+
await this.instance.$afterDelete(builder.context());
|
|
27
|
+
return super.onAfter2(builder, result);
|
|
28
|
+
}
|
|
29
|
+
toFindOperation() {
|
|
30
|
+
return new InstanceFindOperation('find', {
|
|
31
|
+
instance: this.instance,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
module.exports = {
|
|
36
|
+
InstanceDeleteOperation,
|
|
37
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { withWhereScope } = require('../whereScopes');
|
|
3
|
+
const { FindOperation } = require('./FindOperation');
|
|
4
|
+
const { assertHasId } = require('../../utils/assert');
|
|
5
|
+
class InstanceFindOperation extends FindOperation {
|
|
6
|
+
constructor(name, opt) {
|
|
7
|
+
super(name, opt);
|
|
8
|
+
this.instance = opt.instance;
|
|
9
|
+
}
|
|
10
|
+
onBuild(builder) {
|
|
11
|
+
assertHasId(this.instance);
|
|
12
|
+
withWhereScope(builder, () => builder.findById(this.instance.$id()));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
module.exports = {
|
|
16
|
+
InstanceFindOperation,
|
|
17
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { InsertOperation } = require('./InsertOperation');
|
|
3
|
+
class InstanceInsertOperation extends InsertOperation {
|
|
4
|
+
constructor(name, opt) {
|
|
5
|
+
super(name, opt);
|
|
6
|
+
this.instance = opt.instance;
|
|
7
|
+
}
|
|
8
|
+
onAdd(builder, args) {
|
|
9
|
+
if (!args || args.length === 0) {
|
|
10
|
+
args = [this.instance];
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
args[0] = this.instance;
|
|
14
|
+
}
|
|
15
|
+
return super.onAdd(builder, args);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
module.exports = {
|
|
19
|
+
InstanceInsertOperation,
|
|
20
|
+
};
|