@abedmurrar/objection 4.0.0-alpha.0 → 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/README.md +103 -67
- package/lib/index.mjs +6 -0
- package/lib/initialize.js +6 -9
- package/lib/model/AjvValidator.js +235 -282
- package/lib/model/Model.js +653 -823
- package/lib/model/ModifierNotFoundError.js +5 -7
- package/lib/model/NotFoundError.js +14 -18
- package/lib/model/RelationDoesNotExistError.js +6 -9
- package/lib/model/ValidationError.js +33 -41
- package/lib/model/Validator.js +15 -21
- package/lib/model/getModel.js +1 -3
- package/lib/model/graph/ModelGraph.js +44 -64
- package/lib/model/graph/ModelGraphBuilder.js +164 -217
- package/lib/model/graph/ModelGraphEdge.js +31 -43
- package/lib/model/graph/ModelGraphNode.js +192 -231
- package/lib/model/inheritModel.js +9 -18
- package/lib/model/modelBindKnex.js +48 -62
- package/lib/model/modelClone.js +79 -98
- package/lib/model/modelColPropMap.js +16 -26
- package/lib/model/modelConcurrency.js +24 -0
- package/lib/model/modelId.js +44 -49
- package/lib/model/modelJsonAttributes.js +56 -76
- package/lib/model/modelParseRelations.js +68 -67
- package/lib/model/modelQueryProps.js +76 -107
- package/lib/model/modelSet.js +92 -112
- package/lib/model/modelTableMetadata.js +60 -72
- package/lib/model/modelToJson.js +120 -150
- package/lib/model/modelUtils.js +30 -37
- package/lib/model/modelValidate.js +34 -42
- package/lib/model/modelValues.js +78 -91
- package/lib/model/modelVisitor.js +22 -29
- package/lib/objection.js +42 -67
- package/lib/queryBuilder/FunctionBuilder.js +231 -279
- package/lib/queryBuilder/InternalOptions.js +19 -24
- package/lib/queryBuilder/JoinBuilder.js +116 -149
- package/lib/queryBuilder/QueryBuilder.js +1009 -1271
- package/lib/queryBuilder/QueryBuilderBase.js +647 -865
- package/lib/queryBuilder/QueryBuilderContext.js +14 -21
- package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
- package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
- package/lib/queryBuilder/RawBuilder.js +58 -73
- package/lib/queryBuilder/ReferenceBuilder.js +232 -270
- package/lib/queryBuilder/RelationExpression.js +322 -380
- package/lib/queryBuilder/StaticHookArguments.js +94 -106
- package/lib/queryBuilder/ValueBuilder.js +100 -112
- package/lib/queryBuilder/expressions.js +86 -116
- package/lib/queryBuilder/functions/mysql.js +642 -697
- package/lib/queryBuilder/graph/GraphAction.js +44 -59
- package/lib/queryBuilder/graph/GraphData.js +7 -9
- package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
- package/lib/queryBuilder/graph/GraphOperation.js +16 -22
- package/lib/queryBuilder/graph/GraphOptions.js +143 -185
- package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
- package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
- package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
- package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
- package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
- package/lib/queryBuilder/join/JoinResultParser.js +88 -101
- package/lib/queryBuilder/join/RelationJoiner.js +205 -288
- package/lib/queryBuilder/join/TableNode.js +117 -144
- package/lib/queryBuilder/join/TableTree.js +60 -76
- package/lib/queryBuilder/join/utils.js +10 -16
- package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
- package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
- package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
- package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
- package/lib/queryBuilder/operations/FindOperation.js +114 -131
- package/lib/queryBuilder/operations/FirstOperation.js +14 -19
- package/lib/queryBuilder/operations/FromOperation.js +69 -88
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
- package/lib/queryBuilder/operations/InsertOperation.js +132 -165
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
- package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
- package/lib/queryBuilder/operations/KnexOperation.js +4 -7
- package/lib/queryBuilder/operations/MergeOperation.js +32 -45
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
- package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
- package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
- package/lib/queryBuilder/operations/RangeOperation.js +30 -40
- package/lib/queryBuilder/operations/RelateOperation.js +14 -21
- package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
- package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
- package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
- package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
- package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
- package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
- package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
- package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
- package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
- package/lib/queryBuilder/operations/select/Selection.js +94 -105
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
- package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
- package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
- package/lib/queryBuilder/transformations/index.js +3 -9
- package/lib/queryBuilder/whereScopes.js +158 -186
- package/lib/relations/Relation.js +279 -363
- package/lib/relations/RelationDeleteOperation.js +16 -22
- package/lib/relations/RelationFindOperation.js +100 -133
- package/lib/relations/RelationInsertOperation.js +19 -27
- package/lib/relations/RelationOwner.js +167 -204
- package/lib/relations/RelationProperty.js +177 -217
- package/lib/relations/RelationUpdateOperation.js +16 -23
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +11 -16
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +24 -35
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +30 -41
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +33 -41
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +38 -53
- package/lib/relations/hasMany/HasManyInsertOperation.js +35 -51
- package/lib/relations/hasMany/HasManyRelateOperation.js +38 -54
- package/lib/relations/hasMany/HasManyRelation.js +30 -38
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +19 -26
- package/lib/relations/hasOne/HasOneRelation.js +4 -7
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +4 -7
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +67 -90
- package/lib/relations/manyToMany/ManyToManyRelation.js +349 -451
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +19 -26
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +3 -5
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +14 -20
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -7
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +71 -94
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +31 -43
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +50 -67
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +4 -7
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +20 -27
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +5 -10
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +3 -5
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +55 -72
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -7
- package/lib/transaction.js +53 -83
- package/lib/utils/assert.js +15 -21
- package/lib/utils/buildUtils.js +17 -19
- package/lib/utils/classUtils.js +7 -11
- package/lib/utils/cloneDeep.js +365 -0
- package/lib/utils/createModifier.js +36 -41
- package/lib/utils/deprecate.js +8 -12
- package/lib/utils/identifierMapping.js +153 -192
- package/lib/utils/internalPropUtils.js +4 -8
- package/lib/utils/knexUtils.js +61 -56
- package/lib/utils/mixin.js +16 -23
- package/lib/utils/mysqlJsonPath.js +55 -40
- package/lib/utils/normalizeIds.js +110 -127
- package/lib/utils/objectUtils.js +236 -338
- package/lib/utils/parseFieldExpression.js +66 -44
- package/lib/utils/postgresJsonPath.js +48 -62
- package/lib/utils/promiseUtils/after.js +10 -13
- package/lib/utils/promiseUtils/afterReturn.js +10 -13
- package/lib/utils/promiseUtils/index.js +15 -17
- package/lib/utils/promiseUtils/isPromise.js +6 -9
- package/lib/utils/promiseUtils/map.js +75 -89
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
- package/lib/utils/promiseUtils/try.js +15 -18
- package/lib/utils/resolveModel.js +91 -94
- package/lib/utils/tmpColumnUtils.js +4 -13
- package/package.json +50 -23
- package/typings/objection/index.d.mts +362 -0
- package/typings/objection/index.d.ts +36 -9
- package/lib/.eslintrc.json +0 -8
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
- package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
- package/lib/utils/clone.js +0 -2329
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ManyToManyModifyMixin } = require('./ManyToManyModifyMixin');
|
|
4
3
|
const SQLITE_BUILTIN_ROW_ID = '_rowid_';
|
|
5
|
-
|
|
6
4
|
// We need to override this mixin for sqlite because sqlite doesn't support
|
|
7
5
|
// multi-column where in statements with subqueries. We need to use the
|
|
8
6
|
// internal _rowid_ column instead.
|
|
9
7
|
const ManyToManySqliteModifyMixin = (Operation) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.whereInComposite(rowIdRef, subquery)
|
|
29
|
-
.whereInComposite(joinTableOwnerRefs, ownerValues);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
8
|
+
return class extends ManyToManyModifyMixin(Operation) {
|
|
9
|
+
applyModifyFilterForRelatedTable(builder) {
|
|
10
|
+
const tableRef = builder.tableRefFor(this.relation.relatedModelClass);
|
|
11
|
+
const rowIdRef = `${tableRef}.${SQLITE_BUILTIN_ROW_ID}`;
|
|
12
|
+
const subquery = this.modifyFilterSubquery.clone().select(rowIdRef);
|
|
13
|
+
return builder.whereInComposite(rowIdRef, subquery);
|
|
14
|
+
}
|
|
15
|
+
applyModifyFilterForJoinTable(builder) {
|
|
16
|
+
const joinTableOwnerRefs = this.relation.joinTableOwnerProp.refs(builder);
|
|
17
|
+
const tableRef = builder.tableRefFor(this.relation.getJoinModelClass(builder));
|
|
18
|
+
const rowIdRef = `${tableRef}.${SQLITE_BUILTIN_ROW_ID}`;
|
|
19
|
+
const ownerValues = this.owner.getProps(this.relation);
|
|
20
|
+
const subquery = this.modifyFilterSubquery.clone().select(rowIdRef);
|
|
21
|
+
return builder
|
|
22
|
+
.whereInComposite(rowIdRef, subquery)
|
|
23
|
+
.whereInComposite(joinTableOwnerRefs, ownerValues);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
32
26
|
};
|
|
33
|
-
|
|
34
27
|
module.exports = {
|
|
35
|
-
|
|
28
|
+
ManyToManySqliteModifyMixin,
|
|
36
29
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ManyToManyDeleteOperationBase } = require('./ManyToManyDeleteOperationBase');
|
|
4
3
|
const { ManyToManyModifyMixin } = require('../ManyToManyModifyMixin');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class ManyToManyDeleteOperation extends ManyToManyModifyMixin(ManyToManyDeleteOperationBase) {
|
|
5
|
+
}
|
|
8
6
|
module.exports = {
|
|
9
|
-
|
|
7
|
+
ManyToManyDeleteOperation,
|
|
10
8
|
};
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { DeleteOperation } = require('../../../queryBuilder/operations/DeleteOperation');
|
|
4
|
-
|
|
5
3
|
class ManyToManyDeleteOperationBase extends DeleteOperation {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
applyModifyFilterForJoinTable(builder) {
|
|
20
|
-
throw new Error('not implemented');
|
|
21
|
-
}
|
|
4
|
+
constructor(name, opt) {
|
|
5
|
+
super(name, opt);
|
|
6
|
+
this.relation = opt.relation;
|
|
7
|
+
this.owner = opt.owner;
|
|
8
|
+
}
|
|
9
|
+
/* istanbul ignore next */
|
|
10
|
+
applyModifyFilterForRelatedTable(builder) {
|
|
11
|
+
throw new Error('not implemented');
|
|
12
|
+
}
|
|
13
|
+
/* istanbul ignore next */
|
|
14
|
+
applyModifyFilterForJoinTable(builder) {
|
|
15
|
+
throw new Error('not implemented');
|
|
16
|
+
}
|
|
22
17
|
}
|
|
23
|
-
|
|
24
18
|
module.exports = {
|
|
25
|
-
|
|
19
|
+
ManyToManyDeleteOperationBase,
|
|
26
20
|
};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ManyToManyDeleteOperationBase } = require('./ManyToManyDeleteOperationBase');
|
|
4
3
|
const { ManyToManySqliteModifyMixin } = require('../ManyToManySqliteModifyMixin');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ManyToManyDeleteOperationBase,
|
|
8
|
-
) {}
|
|
9
|
-
|
|
4
|
+
class ManyToManyDeleteSqliteOperation extends ManyToManySqliteModifyMixin(ManyToManyDeleteOperationBase) {
|
|
5
|
+
}
|
|
10
6
|
module.exports = {
|
|
11
|
-
|
|
7
|
+
ManyToManyDeleteSqliteOperation,
|
|
12
8
|
};
|
|
@@ -1,105 +1,82 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { RelationFindOperation } = require('../../RelationFindOperation');
|
|
4
3
|
const { getTempColumn } = require('../../../utils/tmpColumnUtils');
|
|
5
|
-
|
|
6
4
|
class ManyToManyFindOperation extends RelationFindOperation {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.ownerJoinColumnAlias[i] = getTempColumn(i);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
onBuild(builder) {
|
|
18
|
-
const relatedModelClass = this.relation.relatedModelClass;
|
|
19
|
-
|
|
20
|
-
this.maybeApplyAlias(builder);
|
|
21
|
-
this.relation.findQuery(builder, this.owner);
|
|
22
|
-
|
|
23
|
-
if (!builder.hasSelects()) {
|
|
24
|
-
const table = builder.tableRefFor(relatedModelClass);
|
|
25
|
-
|
|
26
|
-
// If the user hasn't specified a select clause, select the related model's columns.
|
|
27
|
-
// If we don't do this we also get the join table's columns.
|
|
28
|
-
builder.select(`${table}.*`);
|
|
29
|
-
|
|
30
|
-
// Also select all extra columns.
|
|
31
|
-
for (const extra of this.relation.joinTableExtras) {
|
|
32
|
-
const joinTable = builder.tableRefFor(this.relation.joinTable);
|
|
33
|
-
builder.select(`${joinTable}.${extra.joinTableCol} as ${extra.aliasCol}`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (this.assignResultToOwner && this.owner.isModels) {
|
|
38
|
-
this.selectMissingJoinColumns(builder);
|
|
5
|
+
constructor(name, opt) {
|
|
6
|
+
super(name, opt);
|
|
7
|
+
this.ownerJoinColumnAlias = new Array(this.relation.joinTableOwnerProp.size);
|
|
8
|
+
for (let i = 0, l = this.ownerJoinColumnAlias.length; i < l; ++i) {
|
|
9
|
+
this.ownerJoinColumnAlias[i] = getTempColumn(i);
|
|
10
|
+
}
|
|
39
11
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (!arr) {
|
|
56
|
-
arr = [];
|
|
57
|
-
relatedByOwnerId.set(key, arr);
|
|
12
|
+
onBuild(builder) {
|
|
13
|
+
const relatedModelClass = this.relation.relatedModelClass;
|
|
14
|
+
this.maybeApplyAlias(builder);
|
|
15
|
+
this.relation.findQuery(builder, this.owner);
|
|
16
|
+
if (!builder.hasSelects()) {
|
|
17
|
+
const table = builder.tableRefFor(relatedModelClass);
|
|
18
|
+
// If the user hasn't specified a select clause, select the related model's columns.
|
|
19
|
+
// If we don't do this we also get the join table's columns.
|
|
20
|
+
builder.select(`${table}.*`);
|
|
21
|
+
// Also select all extra columns.
|
|
22
|
+
for (const extra of this.relation.joinTableExtras) {
|
|
23
|
+
const joinTable = builder.tableRefFor(this.relation.joinTable);
|
|
24
|
+
builder.select(`${joinTable}.${extra.joinTableCol} as ${extra.aliasCol}`);
|
|
25
|
+
}
|
|
58
26
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
for (let i = 0, l = owners.length; i < l; ++i) {
|
|
64
|
-
const own = owners[i];
|
|
65
|
-
const key = ownerProp.propKey(own);
|
|
66
|
-
const related = relatedByOwnerId.get(key);
|
|
67
|
-
|
|
68
|
-
if (isOneToOne) {
|
|
69
|
-
own[this.relationProperty] = (related && related[0]) || null;
|
|
70
|
-
} else {
|
|
71
|
-
own[this.relationProperty] = related || [];
|
|
27
|
+
if (this.assignResultToOwner && this.owner.isModels) {
|
|
28
|
+
this.selectMissingJoinColumns(builder);
|
|
72
29
|
}
|
|
73
|
-
}
|
|
74
30
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
31
|
+
onAfter2(_, related) {
|
|
32
|
+
const isOneToOne = this.relation.isOneToOne();
|
|
33
|
+
if (this.assignResultToOwner && this.owner.isModels) {
|
|
34
|
+
const owners = this.owner.modelArray;
|
|
35
|
+
const ownerProp = this.relation.ownerProp;
|
|
36
|
+
const relatedByOwnerId = new Map();
|
|
37
|
+
for (let i = 0, l = related.length; i < l; ++i) {
|
|
38
|
+
const rel = related[i];
|
|
39
|
+
const key = rel.$propKey(this.ownerJoinColumnAlias);
|
|
40
|
+
let arr = relatedByOwnerId.get(key);
|
|
41
|
+
if (!arr) {
|
|
42
|
+
arr = [];
|
|
43
|
+
relatedByOwnerId.set(key, arr);
|
|
44
|
+
}
|
|
45
|
+
arr.push(rel);
|
|
46
|
+
}
|
|
47
|
+
for (let i = 0, l = owners.length; i < l; ++i) {
|
|
48
|
+
const own = owners[i];
|
|
49
|
+
const key = ownerProp.propKey(own);
|
|
50
|
+
const related = relatedByOwnerId.get(key);
|
|
51
|
+
if (isOneToOne) {
|
|
52
|
+
own[this.relationProperty] = (related && related[0]) || null;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
own[this.relationProperty] = related || [];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return related;
|
|
60
|
+
}
|
|
61
|
+
clone() {
|
|
62
|
+
const clone = super.clone();
|
|
63
|
+
clone.ownerJoinColumnAlias = this.ownerJoinColumnAlias.slice();
|
|
64
|
+
return clone;
|
|
65
|
+
}
|
|
66
|
+
selectMissingJoinColumns(builder) {
|
|
67
|
+
const { relatedModelClass, joinTableOwnerProp } = this.relation;
|
|
68
|
+
// We must select the owner join columns so that we know for which owner model the related
|
|
69
|
+
// models belong to after the requests.
|
|
70
|
+
joinTableOwnerProp.forEach((i) => {
|
|
71
|
+
const joinTableOwnerRef = joinTableOwnerProp.ref(builder, i);
|
|
72
|
+
const propName = relatedModelClass.columnNameToPropertyName(this.ownerJoinColumnAlias[i]);
|
|
73
|
+
builder.select(joinTableOwnerRef.as(this.ownerJoinColumnAlias[i]));
|
|
74
|
+
// Mark them to be omitted later.
|
|
75
|
+
this.omitProps.push(propName);
|
|
76
|
+
});
|
|
77
|
+
super.selectMissingJoinColumns(builder);
|
|
78
|
+
}
|
|
101
79
|
}
|
|
102
|
-
|
|
103
80
|
module.exports = {
|
|
104
|
-
|
|
81
|
+
ManyToManyFindOperation,
|
|
105
82
|
};
|
|
@@ -1,52 +1,40 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { RelationInsertOperation } = require('../../RelationInsertOperation');
|
|
4
3
|
const { ManyToManyRelateOperation } = require('../relate/ManyToManyRelateOperation');
|
|
5
|
-
|
|
6
4
|
class ManyToManyInsertOperation extends RelationInsertOperation {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return retVal;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async onAfter1(builder, ret) {
|
|
20
|
-
const inserted = await super.onAfter1(builder, ret);
|
|
21
|
-
|
|
22
|
-
const relateOp = new ManyToManyRelateOperation('relate', {
|
|
23
|
-
dontCopyReturning: true,
|
|
24
|
-
dontCopyOnConflict: true,
|
|
25
|
-
relation: this.relation,
|
|
26
|
-
owner: this.owner,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const modelsToRelate = inserted.filter((it) => {
|
|
30
|
-
return this.relation.relatedProp.hasProps(it);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
if (this.assignResultToOwner && this.owner.isModels) {
|
|
34
|
-
for (const owner of this.owner.modelArray) {
|
|
35
|
-
owner.$appendRelated(this.relation, inserted);
|
|
36
|
-
}
|
|
5
|
+
onAdd(builder, args) {
|
|
6
|
+
const retVal = super.onAdd(builder, args);
|
|
7
|
+
// Omit extra properties so that we don't try to insert
|
|
8
|
+
// them to the related table. We don't actually remove them
|
|
9
|
+
// from the objects, but simply mark them to be removed
|
|
10
|
+
// from the inserted row.
|
|
11
|
+
this.relation.omitExtraProps(this.models);
|
|
12
|
+
return retVal;
|
|
37
13
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
14
|
+
async onAfter1(builder, ret) {
|
|
15
|
+
const inserted = await super.onAfter1(builder, ret);
|
|
16
|
+
const relateOp = new ManyToManyRelateOperation('relate', {
|
|
17
|
+
dontCopyReturning: true,
|
|
18
|
+
dontCopyOnConflict: true,
|
|
19
|
+
relation: this.relation,
|
|
20
|
+
owner: this.owner,
|
|
21
|
+
});
|
|
22
|
+
const modelsToRelate = inserted.filter((it) => {
|
|
23
|
+
return this.relation.relatedProp.hasProps(it);
|
|
24
|
+
});
|
|
25
|
+
if (this.assignResultToOwner && this.owner.isModels) {
|
|
26
|
+
for (const owner of this.owner.modelArray) {
|
|
27
|
+
owner.$appendRelated(this.relation, inserted);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (modelsToRelate.length === 0) {
|
|
31
|
+
return inserted;
|
|
32
|
+
}
|
|
33
|
+
relateOp.onAdd(builder, [modelsToRelate]);
|
|
34
|
+
await relateOp.queryExecutor(builder);
|
|
35
|
+
return inserted;
|
|
41
36
|
}
|
|
42
|
-
|
|
43
|
-
relateOp.onAdd(builder, [modelsToRelate]);
|
|
44
|
-
await relateOp.queryExecutor(builder);
|
|
45
|
-
|
|
46
|
-
return inserted;
|
|
47
|
-
}
|
|
48
37
|
}
|
|
49
|
-
|
|
50
38
|
module.exports = {
|
|
51
|
-
|
|
39
|
+
ManyToManyInsertOperation,
|
|
52
40
|
};
|
|
@@ -1,81 +1,64 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { isPostgres } = require('../../../utils/knexUtils');
|
|
4
3
|
const { normalizeIds } = require('../../../utils/normalizeIds');
|
|
5
4
|
const { RelateOperation } = require('../../../queryBuilder/operations/RelateOperation');
|
|
6
|
-
|
|
7
5
|
class ManyToManyRelateOperation extends RelateOperation {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
queryExecutor(builder) {
|
|
17
|
-
const joinModelClass = this.relation.getJoinModelClass(builder.knex());
|
|
18
|
-
const ownerValues = this.owner.getSplitProps(builder, this.relation);
|
|
19
|
-
const joinModels = [];
|
|
20
|
-
|
|
21
|
-
for (const ownerValue of ownerValues) {
|
|
22
|
-
for (const relatedValue of this.ids) {
|
|
23
|
-
joinModels.push(
|
|
24
|
-
joinModelClass.fromJson(this.relation.createJoinModel(ownerValue, relatedValue)),
|
|
25
|
-
);
|
|
26
|
-
}
|
|
6
|
+
onAdd(builder, args) {
|
|
7
|
+
this.input = args[0];
|
|
8
|
+
this.ids = normalizeIds(args[0], this.relation.relatedProp);
|
|
9
|
+
assertOwnerIsSingleItem(builder, this.owner, this.relation);
|
|
10
|
+
return true;
|
|
27
11
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
12
|
+
queryExecutor(builder) {
|
|
13
|
+
const joinModelClass = this.relation.getJoinModelClass(builder.knex());
|
|
14
|
+
const ownerValues = this.owner.getSplitProps(builder, this.relation);
|
|
15
|
+
const joinModels = [];
|
|
16
|
+
for (const ownerValue of ownerValues) {
|
|
17
|
+
for (const relatedValue of this.ids) {
|
|
18
|
+
joinModels.push(joinModelClass.fromJson(this.relation.createJoinModel(ownerValue, relatedValue)));
|
|
19
|
+
}
|
|
35
20
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
21
|
+
return joinModelClass
|
|
22
|
+
.query()
|
|
23
|
+
.childQueryOf(builder)
|
|
24
|
+
.modify((query) => {
|
|
25
|
+
if (!this.opt.dontCopyReturning) {
|
|
26
|
+
query.copyFrom(builder, /returning/);
|
|
27
|
+
}
|
|
28
|
+
if (!this.opt.dontCopyOnConflict) {
|
|
29
|
+
query.copyFrom(builder, /onConflict|ignore|merge/);
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
.runBefore((_, builder) => {
|
|
33
|
+
return this.relation.executeJoinTableBeforeInsert(joinModels, builder.context(), null);
|
|
34
|
+
})
|
|
35
|
+
.insert(joinModels)
|
|
36
|
+
.runAfter((models) => {
|
|
37
|
+
return Array.isArray(models) ? models.length : 1;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
49
40
|
}
|
|
50
|
-
|
|
51
41
|
function assertOwnerIsSingleItem(builder, owner, relation) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new Error(
|
|
61
|
-
'Parent must be a list of identifiers or a list of models when relating a ManyToManyRelation',
|
|
62
|
-
);
|
|
42
|
+
const { isModels, isIdentifiers, isQueryBuilder } = owner;
|
|
43
|
+
const { ownerProp } = relation;
|
|
44
|
+
const singleModel = isModels && owner.modelArray.length === 1;
|
|
45
|
+
const singleId = isIdentifiers && owner.getNormalizedIdentifiers(ownerProp).length === 1;
|
|
46
|
+
if (isPostgres(builder.unsafeKnex())) {
|
|
47
|
+
if (!isModels && !isIdentifiers && !isQueryBuilder) {
|
|
48
|
+
throw new Error('Parent must be a list of identifiers or a list of models when relating a ManyToManyRelation');
|
|
49
|
+
}
|
|
63
50
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
].join(' '),
|
|
74
|
-
);
|
|
51
|
+
else {
|
|
52
|
+
if (!singleModel && !singleId && !isQueryBuilder) {
|
|
53
|
+
throw new Error([
|
|
54
|
+
'Can only relate items for one parent at a time in case of ManyToManyRelation.',
|
|
55
|
+
'Otherwise multiple insert queries would need to be created.',
|
|
56
|
+
'If you need to relate items for multiple parents, simply loop through them.',
|
|
57
|
+
`That's the most performant way.`,
|
|
58
|
+
].join(' '));
|
|
59
|
+
}
|
|
75
60
|
}
|
|
76
|
-
}
|
|
77
61
|
}
|
|
78
|
-
|
|
79
62
|
module.exports = {
|
|
80
|
-
|
|
63
|
+
ManyToManyRelateOperation,
|
|
81
64
|
};
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ManyToManyUnrelateOperationBase } = require('./ManyToManyUnrelateOperationBase');
|
|
4
3
|
const { ManyToManyModifyMixin } = require('../ManyToManyModifyMixin');
|
|
5
|
-
|
|
6
4
|
class ManyToManyUnrelateOperation extends ManyToManyModifyMixin(ManyToManyUnrelateOperationBase) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
get modifyMainQuery() {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
10
8
|
}
|
|
11
|
-
|
|
12
9
|
module.exports = {
|
|
13
|
-
|
|
10
|
+
ManyToManyUnrelateOperation,
|
|
14
11
|
};
|
|
@@ -1,34 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { withWhereScope } = require('../../../queryBuilder/whereScopes');
|
|
4
3
|
const { UnrelateOperation } = require('../../../queryBuilder/operations/UnrelateOperation');
|
|
5
|
-
|
|
6
4
|
class ManyToManyUnrelateOperationBase extends UnrelateOperation {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/* istanbul ignore next */
|
|
27
|
-
applyModifyFilterForJoinTable(builder) {
|
|
28
|
-
throw new Error('not implemented');
|
|
29
|
-
}
|
|
5
|
+
queryExecutor(builder) {
|
|
6
|
+
const unrelateQuery = this.relation
|
|
7
|
+
.getJoinModelClass(builder.knex())
|
|
8
|
+
.query()
|
|
9
|
+
.childQueryOf(builder)
|
|
10
|
+
.delete();
|
|
11
|
+
withWhereScope(unrelateQuery, () => {
|
|
12
|
+
this.applyModifyFilterForJoinTable(unrelateQuery);
|
|
13
|
+
});
|
|
14
|
+
return unrelateQuery.modify(this.relation.joinTableModify);
|
|
15
|
+
}
|
|
16
|
+
/* istanbul ignore next */
|
|
17
|
+
applyModifyFilterForRelatedTable(builder) {
|
|
18
|
+
throw new Error('not implemented');
|
|
19
|
+
}
|
|
20
|
+
/* istanbul ignore next */
|
|
21
|
+
applyModifyFilterForJoinTable(builder) {
|
|
22
|
+
throw new Error('not implemented');
|
|
23
|
+
}
|
|
30
24
|
}
|
|
31
|
-
|
|
32
25
|
module.exports = {
|
|
33
|
-
|
|
26
|
+
ManyToManyUnrelateOperationBase,
|
|
34
27
|
};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ManyToManyUnrelateOperationBase } = require('./ManyToManyUnrelateOperationBase');
|
|
4
3
|
const { ManyToManySqliteModifyMixin } = require('../ManyToManySqliteModifyMixin');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
get modifyMainQuery() {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
4
|
+
class ManyToManyUnrelateSqliteOperation extends ManyToManySqliteModifyMixin(ManyToManyUnrelateOperationBase) {
|
|
5
|
+
get modifyMainQuery() {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
12
8
|
}
|
|
13
|
-
|
|
14
9
|
module.exports = {
|
|
15
|
-
|
|
10
|
+
ManyToManyUnrelateSqliteOperation,
|
|
16
11
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ManyToManyUpdateOperationBase } = require('./ManyToManyUpdateOperationBase');
|
|
4
3
|
const { ManyToManyModifyMixin } = require('../ManyToManyModifyMixin');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class ManyToManyUpdateOperation extends ManyToManyModifyMixin(ManyToManyUpdateOperationBase) {
|
|
5
|
+
}
|
|
8
6
|
module.exports = {
|
|
9
|
-
|
|
7
|
+
ManyToManyUpdateOperation,
|
|
10
8
|
};
|