@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,145 +1,116 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { JoinRowGraphInsertAction } = require('./JoinRowGraphInsertAction');
|
|
4
3
|
const { GraphInsertAction } = require('./GraphInsertAction');
|
|
5
4
|
const { GraphOperation } = require('../GraphOperation');
|
|
6
5
|
const { ModelGraphEdge } = require('../../../model/graph/ModelGraphEdge');
|
|
7
|
-
|
|
8
6
|
class GraphInsert extends GraphOperation {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
createActions() {
|
|
15
|
-
return [...this._createNormalActions(), ...this._createJoinRowActions()];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
_createDependencyMap() {
|
|
19
|
-
const dependencies = new Map();
|
|
20
|
-
|
|
21
|
-
for (const edge of this.graph.edges) {
|
|
22
|
-
if (edge.type == ModelGraphEdge.Type.Relation) {
|
|
23
|
-
this._createRelationDependency(edge, dependencies);
|
|
24
|
-
} else {
|
|
25
|
-
this._createReferenceDependency(edge, dependencies);
|
|
26
|
-
}
|
|
7
|
+
constructor(...args) {
|
|
8
|
+
super(...args);
|
|
9
|
+
this.dependencies = this._createDependencyMap();
|
|
27
10
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
_createRelationDependency(edge, dependencies) {
|
|
33
|
-
if (edge.relation.isObjectionHasManyRelation) {
|
|
34
|
-
// In case of HasManyRelation the related node depends on the owner node
|
|
35
|
-
// because the related node has the foreign key.
|
|
36
|
-
this._addDependency(edge.relatedNode, edge, dependencies);
|
|
37
|
-
} else if (edge.relation.isObjectionBelongsToOneRelation) {
|
|
38
|
-
// In case of BelongsToOneRelation the owner node depends on the related
|
|
39
|
-
// node because the owner node has the foreign key.
|
|
40
|
-
this._addDependency(edge.ownerNode, edge, dependencies);
|
|
11
|
+
createActions() {
|
|
12
|
+
return [...this._createNormalActions(), ...this._createJoinRowActions()];
|
|
41
13
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
dependencies.set(node, edges);
|
|
14
|
+
_createDependencyMap() {
|
|
15
|
+
const dependencies = new Map();
|
|
16
|
+
for (const edge of this.graph.edges) {
|
|
17
|
+
if (edge.type == ModelGraphEdge.Type.Relation) {
|
|
18
|
+
this._createRelationDependency(edge, dependencies);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
this._createReferenceDependency(edge, dependencies);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return dependencies;
|
|
54
25
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// new ones. We need to pass all nodes to `GraphInsertActions` so that we
|
|
67
|
-
// can resolve all dependencies.
|
|
68
|
-
const nodesToInsert = this.graph.nodes.filter((node) => {
|
|
69
|
-
return !this._isHandled(node, handledNodes) && !this._hasDependencies(node, handledNodes);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (nodesToInsert.length === 0) {
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
actions.push(
|
|
77
|
-
new GraphInsertAction(this.graphData, {
|
|
78
|
-
nodes: nodesToInsert,
|
|
79
|
-
dependencies: this.dependencies,
|
|
80
|
-
}),
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
for (const node of nodesToInsert) {
|
|
84
|
-
this._markHandled(node, handledNodes);
|
|
85
|
-
}
|
|
26
|
+
_createRelationDependency(edge, dependencies) {
|
|
27
|
+
if (edge.relation.isObjectionHasManyRelation) {
|
|
28
|
+
// In case of HasManyRelation the related node depends on the owner node
|
|
29
|
+
// because the related node has the foreign key.
|
|
30
|
+
this._addDependency(edge.relatedNode, edge, dependencies);
|
|
31
|
+
}
|
|
32
|
+
else if (edge.relation.isObjectionBelongsToOneRelation) {
|
|
33
|
+
// In case of BelongsToOneRelation the owner node depends on the related
|
|
34
|
+
// node because the owner node has the foreign key.
|
|
35
|
+
this._addDependency(edge.ownerNode, edge, dependencies);
|
|
36
|
+
}
|
|
86
37
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
throw new Error('the object graph contains cyclic references');
|
|
38
|
+
_createReferenceDependency(edge, dependencies) {
|
|
39
|
+
this._addDependency(edge.ownerNode, edge, dependencies);
|
|
90
40
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
_hasDependencies(node, handledNodes) {
|
|
100
|
-
if (!this.dependencies.has(node)) {
|
|
101
|
-
return false;
|
|
41
|
+
_addDependency(node, edge, dependencies) {
|
|
42
|
+
let edges = dependencies.get(node);
|
|
43
|
+
if (!edges) {
|
|
44
|
+
edges = [];
|
|
45
|
+
dependencies.set(node, edges);
|
|
46
|
+
}
|
|
47
|
+
edges.push(edge);
|
|
102
48
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
49
|
+
_createNormalActions() {
|
|
50
|
+
const handledNodes = new Set();
|
|
51
|
+
const actions = [];
|
|
52
|
+
while (true) {
|
|
53
|
+
// At this point, don't care if the nodes have already been inserted before
|
|
54
|
+
// given to this class. `GraphInsertAction` will test that and only insert
|
|
55
|
+
// new ones. We need to pass all nodes to `GraphInsertActions` so that we
|
|
56
|
+
// can resolve all dependencies.
|
|
57
|
+
const nodesToInsert = this.graph.nodes.filter((node) => {
|
|
58
|
+
return !this._isHandled(node, handledNodes) && !this._hasDependencies(node, handledNodes);
|
|
59
|
+
});
|
|
60
|
+
if (nodesToInsert.length === 0) {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
actions.push(new GraphInsertAction(this.graphData, {
|
|
64
|
+
nodes: nodesToInsert,
|
|
65
|
+
dependencies: this.dependencies,
|
|
66
|
+
}));
|
|
67
|
+
for (const node of nodesToInsert) {
|
|
68
|
+
this._markHandled(node, handledNodes);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (handledNodes.size !== this.graph.nodes.length) {
|
|
72
|
+
throw new Error('the object graph contains cyclic references');
|
|
73
|
+
}
|
|
74
|
+
return actions;
|
|
110
75
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
76
|
+
_isHandled(node, handledNodes) {
|
|
77
|
+
return handledNodes.has(node);
|
|
78
|
+
}
|
|
79
|
+
_hasDependencies(node, handledNodes) {
|
|
80
|
+
if (!this.dependencies.has(node)) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
for (const edge of this.dependencies.get(node)) {
|
|
84
|
+
const dependencyNode = edge.getOtherNode(node);
|
|
85
|
+
if (!handledNodes.has(dependencyNode) && !this.currentGraph.nodeForNode(dependencyNode)) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
_markHandled(node, handledNodes) {
|
|
92
|
+
handledNodes.add(node);
|
|
93
|
+
// The referencing nodes are all references that don't
|
|
94
|
+
// represent any real entity. They are simply intermediate nodes
|
|
95
|
+
// that depend on this node. Once this node is handled, we can
|
|
96
|
+
// also mark those nodes as handled as there is nothing to actually
|
|
97
|
+
// insert.
|
|
98
|
+
for (const refNode of node.referencingNodes) {
|
|
99
|
+
this._markHandled(refNode, handledNodes);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
_createJoinRowActions() {
|
|
103
|
+
return [
|
|
104
|
+
new JoinRowGraphInsertAction(this.graphData, {
|
|
105
|
+
nodes: this.graph.nodes.filter((node) => {
|
|
106
|
+
return (this.currentGraph.nodeForNode(node) === null &&
|
|
107
|
+
node.parentEdge &&
|
|
108
|
+
node.parentEdge.relation.isObjectionManyToManyRelation);
|
|
109
|
+
}),
|
|
110
|
+
}),
|
|
111
|
+
];
|
|
125
112
|
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
_createJoinRowActions() {
|
|
129
|
-
return [
|
|
130
|
-
new JoinRowGraphInsertAction(this.graphData, {
|
|
131
|
-
nodes: this.graph.nodes.filter((node) => {
|
|
132
|
-
return (
|
|
133
|
-
this.currentGraph.nodeForNode(node) === null &&
|
|
134
|
-
node.parentEdge &&
|
|
135
|
-
node.parentEdge.relation.isObjectionManyToManyRelation
|
|
136
|
-
);
|
|
137
|
-
}),
|
|
138
|
-
}),
|
|
139
|
-
];
|
|
140
|
-
}
|
|
141
113
|
}
|
|
142
|
-
|
|
143
114
|
module.exports = {
|
|
144
|
-
|
|
115
|
+
GraphInsert,
|
|
145
116
|
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { GraphAction } = require('../GraphAction');
|
|
4
3
|
const { groupBy, chunk, get, set } = require('../../../utils/objectUtils');
|
|
5
4
|
const { ModelGraphEdge } = require('../../../model/graph/ModelGraphEdge');
|
|
6
5
|
const promiseUtils = require('../../../utils/promiseUtils');
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* Inserts a batch of nodes for a GraphInsert.
|
|
10
8
|
*
|
|
@@ -14,212 +12,172 @@ const promiseUtils = require('../../../utils/promiseUtils');
|
|
|
14
12
|
* when needed.
|
|
15
13
|
*/
|
|
16
14
|
class GraphInsertAction extends GraphAction {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.dependencies = dependencies;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
run(builder) {
|
|
26
|
-
const batches = this._createInsertBatches(builder);
|
|
27
|
-
const concurrency = this._getConcurrency(builder, this.nodes);
|
|
28
|
-
|
|
29
|
-
return promiseUtils.map(batches, (batch) => this._insertBatch(builder, batch), { concurrency });
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
_createInsertBatches(builder) {
|
|
33
|
-
const batches = [];
|
|
34
|
-
const batchSize = this._getBatchSize(builder);
|
|
35
|
-
const nodesByModelClass = groupBy(this.nodes, getModelClass);
|
|
36
|
-
|
|
37
|
-
for (const nodes of nodesByModelClass.values()) {
|
|
38
|
-
for (const nodeBatch of chunk(nodes, batchSize)) {
|
|
39
|
-
batches.push(nodeBatch);
|
|
40
|
-
}
|
|
15
|
+
constructor(graphData, { nodes, dependencies }) {
|
|
16
|
+
super(graphData);
|
|
17
|
+
// Nodes to insert.
|
|
18
|
+
this.nodes = nodes;
|
|
19
|
+
this.dependencies = dependencies;
|
|
41
20
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
async _insertBatch(parentBuilder, nodes) {
|
|
47
|
-
await this._beforeInsert(nodes);
|
|
48
|
-
await this._insert(parentBuilder, nodes);
|
|
49
|
-
await this._afterInsert(nodes);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
_beforeInsert(nodes) {
|
|
53
|
-
this._resolveDependencies(nodes);
|
|
54
|
-
this._omitManyToManyExtraProps(nodes);
|
|
55
|
-
this._copyRelationPropsFromCurrentIfNeeded(nodes);
|
|
56
|
-
|
|
57
|
-
return Promise.resolve();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
_resolveDependencies(nodes) {
|
|
61
|
-
for (const node of nodes) {
|
|
62
|
-
const edges = this.dependencies.get(node);
|
|
63
|
-
|
|
64
|
-
if (edges) {
|
|
65
|
-
for (const edge of edges) {
|
|
66
|
-
// `node` needs `dependencyNode` to have been inserted (and it has been).
|
|
67
|
-
const dependencyNode = edge.getOtherNode(node);
|
|
68
|
-
|
|
69
|
-
this._resolveDependency(dependencyNode, edge);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
21
|
+
run(builder) {
|
|
22
|
+
const batches = this._createInsertBatches(builder);
|
|
23
|
+
const concurrency = this._getConcurrency(builder, this.nodes);
|
|
24
|
+
return promiseUtils.map(batches, (batch) => this._insertBatch(builder, batch), { concurrency });
|
|
72
25
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
26
|
+
_createInsertBatches(builder) {
|
|
27
|
+
const batches = [];
|
|
28
|
+
const batchSize = this._getBatchSize(builder);
|
|
29
|
+
const nodesByModelClass = groupBy(this.nodes, getModelClass);
|
|
30
|
+
for (const nodes of nodesByModelClass.values()) {
|
|
31
|
+
for (const nodeBatch of chunk(nodes, batchSize)) {
|
|
32
|
+
batches.push(nodeBatch);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return batches;
|
|
80
36
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
let sourceProp;
|
|
87
|
-
let targetProp;
|
|
88
|
-
|
|
89
|
-
if (edge.isOwnerNode(dependencyNode)) {
|
|
90
|
-
sourceProp = edge.relation.ownerProp;
|
|
91
|
-
targetProp = edge.relation.relatedProp;
|
|
92
|
-
} else {
|
|
93
|
-
targetProp = edge.relation.ownerProp;
|
|
94
|
-
sourceProp = edge.relation.relatedProp;
|
|
37
|
+
async _insertBatch(parentBuilder, nodes) {
|
|
38
|
+
await this._beforeInsert(nodes);
|
|
39
|
+
await this._insert(parentBuilder, nodes);
|
|
40
|
+
await this._afterInsert(nodes);
|
|
95
41
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
_resolvePropertyReferenceNode(dependencyNode, edge) {
|
|
105
|
-
const dependentNode = edge.getOtherNode(dependencyNode);
|
|
106
|
-
|
|
107
|
-
let sourcePath;
|
|
108
|
-
let targetPath;
|
|
109
|
-
|
|
110
|
-
if (edge.isOwnerNode(dependencyNode)) {
|
|
111
|
-
sourcePath = edge.refOwnerDataPath;
|
|
112
|
-
targetPath = edge.refRelatedDataPath;
|
|
113
|
-
} else {
|
|
114
|
-
targetPath = edge.refOwnerDataPath;
|
|
115
|
-
sourcePath = edge.refRelatedDataPath;
|
|
42
|
+
_beforeInsert(nodes) {
|
|
43
|
+
this._resolveDependencies(nodes);
|
|
44
|
+
this._omitManyToManyExtraProps(nodes);
|
|
45
|
+
this._copyRelationPropsFromCurrentIfNeeded(nodes);
|
|
46
|
+
return Promise.resolve();
|
|
116
47
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
48
|
+
_resolveDependencies(nodes) {
|
|
49
|
+
for (const node of nodes) {
|
|
50
|
+
const edges = this.dependencies.get(node);
|
|
51
|
+
if (edges) {
|
|
52
|
+
for (const edge of edges) {
|
|
53
|
+
// `node` needs `dependencyNode` to have been inserted (and it has been).
|
|
54
|
+
const dependencyNode = edge.getOtherNode(node);
|
|
55
|
+
this._resolveDependency(dependencyNode, edge);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
125
59
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
node.parentEdge.relation.joinTableExtras.length > 0
|
|
134
|
-
) {
|
|
135
|
-
node.parentEdge.relation.omitExtraProps([node.obj]);
|
|
136
|
-
}
|
|
60
|
+
_resolveDependency(dependencyNode, edge) {
|
|
61
|
+
if (edge.type === ModelGraphEdge.Type.Relation && !edge.relation.joinTable) {
|
|
62
|
+
this._resolveRelationDependency(dependencyNode, edge);
|
|
63
|
+
}
|
|
64
|
+
else if (edge.refType === ModelGraphEdge.ReferenceType.Property) {
|
|
65
|
+
this._resolvePropertyReferenceNode(dependencyNode, edge);
|
|
66
|
+
}
|
|
137
67
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const prop = edge.isOwnerNode(node) ? edge.relation.ownerProp : edge.relation.relatedProp;
|
|
154
|
-
|
|
155
|
-
prop.forEach((i) => {
|
|
156
|
-
const value = prop.getProp(node.obj, i);
|
|
157
|
-
|
|
158
|
-
if (value !== undefined) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
prop.setProp(node.obj, i, prop.getProp(currentNode.obj, i));
|
|
68
|
+
_resolveRelationDependency(dependencyNode, edge) {
|
|
69
|
+
const dependentNode = edge.getOtherNode(dependencyNode);
|
|
70
|
+
let sourceProp;
|
|
71
|
+
let targetProp;
|
|
72
|
+
if (edge.isOwnerNode(dependencyNode)) {
|
|
73
|
+
sourceProp = edge.relation.ownerProp;
|
|
74
|
+
targetProp = edge.relation.relatedProp;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
targetProp = edge.relation.ownerProp;
|
|
78
|
+
sourceProp = edge.relation.relatedProp;
|
|
79
|
+
}
|
|
80
|
+
this._resolveReferences(dependencyNode);
|
|
81
|
+
targetProp.forEach((i) => {
|
|
82
|
+
targetProp.setProp(dependentNode.obj, i, sourceProp.getProp(dependencyNode.obj, i));
|
|
163
83
|
});
|
|
164
|
-
}
|
|
165
84
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
85
|
+
_resolvePropertyReferenceNode(dependencyNode, edge) {
|
|
86
|
+
const dependentNode = edge.getOtherNode(dependencyNode);
|
|
87
|
+
let sourcePath;
|
|
88
|
+
let targetPath;
|
|
89
|
+
if (edge.isOwnerNode(dependencyNode)) {
|
|
90
|
+
sourcePath = edge.refOwnerDataPath;
|
|
91
|
+
targetPath = edge.refRelatedDataPath;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
targetPath = edge.refOwnerDataPath;
|
|
95
|
+
sourcePath = edge.refRelatedDataPath;
|
|
96
|
+
}
|
|
97
|
+
const sourceValue = get(dependencyNode.obj, sourcePath);
|
|
98
|
+
const targetValue = get(dependentNode.obj, targetPath);
|
|
99
|
+
if (targetValue === edge.refMatch) {
|
|
100
|
+
set(dependentNode.obj, targetPath, sourceValue);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
set(dependentNode.obj, targetPath, targetValue.replace(edge.refMatch, sourceValue));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
_omitManyToManyExtraProps(nodes) {
|
|
107
|
+
for (const node of nodes) {
|
|
108
|
+
if (node.parentEdge &&
|
|
109
|
+
node.parentEdge.type === ModelGraphEdge.Type.Relation &&
|
|
110
|
+
node.parentEdge.relation.joinTableExtras.length > 0) {
|
|
111
|
+
node.parentEdge.relation.omitExtraProps([node.obj]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
178
114
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
115
|
+
_copyRelationPropsFromCurrentIfNeeded(nodes) {
|
|
116
|
+
for (const node of nodes) {
|
|
117
|
+
const currentNode = this.currentGraph.nodeForNode(node);
|
|
118
|
+
if (!currentNode) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
for (const edge of node.edges) {
|
|
122
|
+
if (edge.type !== ModelGraphEdge.Type.Relation) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const prop = edge.isOwnerNode(node) ? edge.relation.ownerProp : edge.relation.relatedProp;
|
|
126
|
+
prop.forEach((i) => {
|
|
127
|
+
const value = prop.getProp(node.obj, i);
|
|
128
|
+
if (value !== undefined) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
prop.setProp(node.obj, i, prop.getProp(currentNode.obj, i));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
182
135
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
136
|
+
_insert(parentBuilder, nodes) {
|
|
137
|
+
const [{ modelClass }] = nodes;
|
|
138
|
+
nodes = nodes.filter((node) => {
|
|
139
|
+
return this.graphOptions.shouldInsert(node, this.graphData);
|
|
140
|
+
});
|
|
141
|
+
for (const node of nodes) {
|
|
142
|
+
delete node.obj[modelClass.uidProp];
|
|
143
|
+
node.obj.$validate(null, { dataPath: node.dataPathKey });
|
|
144
|
+
}
|
|
145
|
+
if (nodes.length === 0) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
for (const node of nodes) {
|
|
149
|
+
node.userData.inserted = true;
|
|
150
|
+
}
|
|
151
|
+
return this._runRelationBeforeInsertMethods(parentBuilder, nodes).then(() => {
|
|
152
|
+
return modelClass
|
|
153
|
+
.query()
|
|
154
|
+
.insert(nodes.map((node) => node.obj))
|
|
155
|
+
.childQueryOf(parentBuilder)
|
|
156
|
+
.copyFrom(parentBuilder, GraphAction.ReturningAllSelector)
|
|
157
|
+
.execute();
|
|
158
|
+
});
|
|
186
159
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
} else {
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
}),
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
_afterInsert(nodes) {
|
|
211
|
-
for (const node of nodes) {
|
|
212
|
-
for (const refNode of node.referencingNodes) {
|
|
213
|
-
this._resolveDependency(refNode, refNode.parentEdge);
|
|
214
|
-
}
|
|
160
|
+
_runRelationBeforeInsertMethods(parentBuilder, nodes) {
|
|
161
|
+
return Promise.all(nodes.map((node) => {
|
|
162
|
+
if (node.parentEdge) {
|
|
163
|
+
return node.parentEdge.relation.beforeInsert(node.obj, parentBuilder.context());
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
_afterInsert(nodes) {
|
|
171
|
+
for (const node of nodes) {
|
|
172
|
+
for (const refNode of node.referencingNodes) {
|
|
173
|
+
this._resolveDependency(refNode, refNode.parentEdge);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
215
176
|
}
|
|
216
|
-
}
|
|
217
177
|
}
|
|
218
|
-
|
|
219
178
|
function getModelClass(node) {
|
|
220
|
-
|
|
179
|
+
return node.modelClass;
|
|
221
180
|
}
|
|
222
|
-
|
|
223
181
|
module.exports = {
|
|
224
|
-
|
|
182
|
+
GraphInsertAction,
|
|
225
183
|
};
|