@abedmurrar/objection 4.0.0-alpha.0 → 4.0.0-beta.1
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 +293 -375
- package/lib/relations/RelationDeleteOperation.js +24 -28
- package/lib/relations/RelationFindOperation.js +108 -138
- package/lib/relations/RelationInsertOperation.js +24 -32
- package/lib/relations/RelationOwner.js +175 -209
- package/lib/relations/RelationProperty.js +186 -223
- package/lib/relations/RelationUpdateOperation.js +23 -29
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +16 -21
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +30 -41
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +36 -47
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +42 -50
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +43 -58
- package/lib/relations/hasMany/HasManyInsertOperation.js +40 -56
- package/lib/relations/hasMany/HasManyRelateOperation.js +45 -61
- package/lib/relations/hasMany/HasManyRelation.js +38 -46
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +25 -32
- package/lib/relations/hasOne/HasOneRelation.js +9 -12
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +9 -12
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +73 -95
- package/lib/relations/manyToMany/ManyToManyRelation.js +374 -473
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +23 -30
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -10
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -25
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -12
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +77 -100
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +37 -49
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +58 -74
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +10 -13
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +26 -33
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +10 -15
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -10
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +61 -78
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -12
- 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,5 +1,4 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { ModelGraph } = require('../../model/graph/ModelGraph');
|
|
4
3
|
const { ModelGraphEdge } = require('../../model/graph/ModelGraphEdge');
|
|
5
4
|
const { createNotModelError } = require('../../model/graph/ModelGraphBuilder');
|
|
@@ -14,292 +13,219 @@ const { RelationExpression } = require('../RelationExpression');
|
|
|
14
13
|
const { GraphNodeDbExistence } = require('./GraphNodeDbExistence');
|
|
15
14
|
const { GraphData } = require('./GraphData');
|
|
16
15
|
const { uniqBy, asArray, isObject } = require('../../utils/objectUtils');
|
|
17
|
-
|
|
18
16
|
class GraphUpsert {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.then(checkForErrors(builder))
|
|
40
|
-
.then(pruneGraphs())
|
|
41
|
-
.then(executeOperations(builder))
|
|
42
|
-
.then(returnResult(this.objects, this.isArray));
|
|
43
|
-
}
|
|
17
|
+
constructor({ rootModelClass, objects, upsertOptions }) {
|
|
18
|
+
checkCanBeConvertedToModels(rootModelClass, objects);
|
|
19
|
+
this.objects = rootModelClass.ensureModelArray(objects, GraphUpsert.modelOptions);
|
|
20
|
+
this.isArray = Array.isArray(objects);
|
|
21
|
+
this.upsertOpt = upsertOptions;
|
|
22
|
+
}
|
|
23
|
+
static get modelOptions() {
|
|
24
|
+
return { skipValidation: true };
|
|
25
|
+
}
|
|
26
|
+
run(builder) {
|
|
27
|
+
const modelClass = builder.modelClass();
|
|
28
|
+
const graphOptions = new GraphOptions(this.upsertOpt);
|
|
29
|
+
const graph = ModelGraph.create(modelClass, this.objects);
|
|
30
|
+
assignDbRefsAsRelateProps(graph);
|
|
31
|
+
return createGraphData(builder, graphOptions, graph)
|
|
32
|
+
.then(checkForErrors(builder))
|
|
33
|
+
.then(pruneGraphs())
|
|
34
|
+
.then(executeOperations(builder))
|
|
35
|
+
.then(returnResult(this.objects, this.isArray));
|
|
36
|
+
}
|
|
44
37
|
}
|
|
45
|
-
|
|
46
38
|
function checkCanBeConvertedToModels(modelClass, objects) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
asArray(objects).forEach((obj) => {
|
|
40
|
+
if (!isObject(obj)) {
|
|
41
|
+
throw createNotModelError(modelClass, obj);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
52
44
|
}
|
|
53
|
-
|
|
54
45
|
function assignDbRefsAsRelateProps(graph) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
for (const node of graph.nodes) {
|
|
47
|
+
if (!node.parentEdge || !node.parentEdge.relation || !node.isDbReference) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
node.parentEdge.relation.setRelateProp(node.obj, asArray(node.dbReference));
|
|
58
51
|
}
|
|
59
|
-
|
|
60
|
-
node.parentEdge.relation.setRelateProp(node.obj, asArray(node.dbReference));
|
|
61
|
-
}
|
|
62
52
|
}
|
|
63
|
-
|
|
64
53
|
async function createGraphData(builder, graphOptions, graph) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return new GraphData({ graph, currentGraph, graphOptions, nodeDbExistence });
|
|
54
|
+
const currentGraph = await fetchCurrentGraph(builder, graphOptions, graph);
|
|
55
|
+
const nodeDbExistence = await GraphNodeDbExistence.create({
|
|
56
|
+
builder,
|
|
57
|
+
graph,
|
|
58
|
+
graphOptions,
|
|
59
|
+
currentGraph,
|
|
60
|
+
});
|
|
61
|
+
return new GraphData({ graph, currentGraph, graphOptions, nodeDbExistence });
|
|
75
62
|
}
|
|
76
|
-
|
|
77
63
|
function fetchCurrentGraph(builder, graphOptions, graph) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
if (graphOptions.isInsertOnly()) {
|
|
65
|
+
return Promise.resolve(ModelGraph.createEmpty());
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
return GraphFetcher.fetchCurrentGraph({ builder, graph, graphOptions });
|
|
69
|
+
}
|
|
83
70
|
}
|
|
84
|
-
|
|
85
71
|
// Remove branches from the graph that require no operations. For example
|
|
86
72
|
// we never want to do anything for descendant nodes of a node that is
|
|
87
73
|
// deleted or unrelated. We never delete recursively.
|
|
88
74
|
function pruneGraphs() {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return graphData;
|
|
97
|
-
};
|
|
75
|
+
return (graphData) => {
|
|
76
|
+
pruneRelatedBranches(graphData);
|
|
77
|
+
if (!graphData.graphOptions.isInsertOnly()) {
|
|
78
|
+
pruneDeletedBranches(graphData);
|
|
79
|
+
}
|
|
80
|
+
return graphData;
|
|
81
|
+
};
|
|
98
82
|
}
|
|
99
|
-
|
|
100
83
|
function pruneRelatedBranches(graphData) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
removeBranchesFromGraph(findRoots(relateNodes), graphData.graph);
|
|
84
|
+
const relateNodes = graphData.graph.nodes.filter((node) => {
|
|
85
|
+
return (!graphData.currentGraph.nodeForNode(node) &&
|
|
86
|
+
!graphData.graphOptions.shouldInsertIgnoreDisable(node, graphData));
|
|
87
|
+
});
|
|
88
|
+
removeBranchesFromGraph(findRoots(relateNodes), graphData.graph);
|
|
109
89
|
}
|
|
110
|
-
|
|
111
90
|
function pruneDeletedBranches(graphData) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return parentNode.obj[relation.name] === undefined;
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
removeBranchesFromGraph(roots, currentGraph);
|
|
136
|
-
removeNodesFromGraph(new Set(rootsNotInRelation), currentGraph);
|
|
91
|
+
const { graph, currentGraph } = graphData;
|
|
92
|
+
const deleteNodes = currentGraph.nodes.filter((currentNode) => !graph.nodeForNode(currentNode));
|
|
93
|
+
const roots = findRoots(deleteNodes);
|
|
94
|
+
// Don't delete relations the current graph doesn't even mention.
|
|
95
|
+
// So if the parent node doesn't even have the relation, it's not
|
|
96
|
+
// supposed to be deleted.
|
|
97
|
+
const rootsNotInRelation = roots.filter((deleteRoot) => {
|
|
98
|
+
if (!deleteRoot.parentNode) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
const { relation } = deleteRoot.parentEdge;
|
|
102
|
+
const parentNode = graph.nodeForNode(deleteRoot.parentNode);
|
|
103
|
+
if (!parentNode) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return parentNode.obj[relation.name] === undefined;
|
|
107
|
+
});
|
|
108
|
+
removeBranchesFromGraph(roots, currentGraph);
|
|
109
|
+
removeNodesFromGraph(new Set(rootsNotInRelation), currentGraph);
|
|
137
110
|
}
|
|
138
|
-
|
|
139
111
|
function findRoots(nodes) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return false;
|
|
112
|
+
const nodeSet = new Set(nodes);
|
|
113
|
+
return uniqBy(nodes.filter((node) => {
|
|
114
|
+
let parentNode = node.parentNode;
|
|
115
|
+
while (parentNode) {
|
|
116
|
+
if (nodeSet.has(parentNode)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
parentNode = parentNode.parentNode;
|
|
149
120
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return true;
|
|
155
|
-
}),
|
|
156
|
-
);
|
|
121
|
+
return true;
|
|
122
|
+
}));
|
|
157
123
|
}
|
|
158
|
-
|
|
159
124
|
function removeBranchesFromGraph(branchRoots, graph) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
(nodesToRemove, node) => [...nodesToRemove, ...node.descendantRelationNodes],
|
|
163
|
-
[],
|
|
164
|
-
),
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
removeNodesFromGraph(nodesToRemove, graph);
|
|
125
|
+
const nodesToRemove = new Set(branchRoots.reduce((nodesToRemove, node) => [...nodesToRemove, ...node.descendantRelationNodes], []));
|
|
126
|
+
removeNodesFromGraph(nodesToRemove, graph);
|
|
168
127
|
}
|
|
169
|
-
|
|
170
128
|
function removeNodesFromGraph(nodesToRemove, graph) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
129
|
+
const edgesToRemove = new Set();
|
|
130
|
+
for (const node of nodesToRemove) {
|
|
131
|
+
for (const edge of node.edges) {
|
|
132
|
+
const otherNode = edge.getOtherNode(node);
|
|
133
|
+
if (!nodesToRemove.has(otherNode)) {
|
|
134
|
+
otherNode.removeEdge(edge);
|
|
135
|
+
edgesToRemove.add(edge);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
181
138
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
graph.edges = graph.edges.filter((edge) => !edgesToRemove.has(edge));
|
|
186
|
-
|
|
187
|
-
return graph;
|
|
139
|
+
graph.nodes = graph.nodes.filter((node) => !nodesToRemove.has(node));
|
|
140
|
+
graph.edges = graph.edges.filter((edge) => !edgesToRemove.has(edge));
|
|
141
|
+
return graph;
|
|
188
142
|
}
|
|
189
|
-
|
|
190
143
|
function checkForErrors(builder) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return graphData;
|
|
201
|
-
};
|
|
144
|
+
return (graphData) => {
|
|
145
|
+
checkForNotFoundErrors(graphData, builder);
|
|
146
|
+
checkForUnallowedRelationErrors(graphData, builder);
|
|
147
|
+
checkForUnallowedReferenceErrors(graphData, builder);
|
|
148
|
+
if (graphData.graphOptions.isInsertOnly()) {
|
|
149
|
+
checkForHasManyRelateErrors(graphData);
|
|
150
|
+
}
|
|
151
|
+
return graphData;
|
|
152
|
+
};
|
|
202
153
|
}
|
|
203
|
-
|
|
204
154
|
function checkForNotFoundErrors(graphData, builder) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
}
|
|
155
|
+
const { graphOptions, currentGraph, graph } = graphData;
|
|
156
|
+
for (const node of graph.nodes) {
|
|
157
|
+
if (node.obj.$hasId() &&
|
|
158
|
+
!graphOptions.shouldInsertIgnoreDisable(node, graphData) &&
|
|
159
|
+
!graphOptions.shouldRelateIgnoreDisable(node, graphData) &&
|
|
160
|
+
!currentGraph.nodeForNode(node)) {
|
|
161
|
+
if (!node.parentNode) {
|
|
162
|
+
throw node.modelClass.createNotFoundError(builder.context(), {
|
|
163
|
+
message: `root model (id=${node.obj.$id()}) does not exist. If you want to insert it with an id, use the insertMissing option`,
|
|
164
|
+
dataPath: node.dataPath,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
throw node.modelClass.createNotFoundError(builder.context(), {
|
|
169
|
+
message: `model (id=${node.obj.$id()}) is not a child of model (id=${node.parentNode.obj.$id()}). If you want to relate it, use the relate option. If you want to insert it with an id, use the insertMissing option`,
|
|
170
|
+
dataPath: node.dataPath,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
225
174
|
}
|
|
226
|
-
}
|
|
227
175
|
}
|
|
228
|
-
|
|
229
176
|
function checkForUnallowedRelationErrors(graphData, builder) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
});
|
|
177
|
+
const { graph } = graphData;
|
|
178
|
+
const allowedExpression = builder.allowedGraphExpression();
|
|
179
|
+
if (allowedExpression) {
|
|
180
|
+
const rootsObjs = graph.nodes.filter((node) => !node.parentEdge).map((node) => node.obj);
|
|
181
|
+
const expression = RelationExpression.fromModelGraph(rootsObjs);
|
|
182
|
+
if (!allowedExpression.isSubExpression(expression)) {
|
|
183
|
+
throw builder.modelClass().createValidationError({
|
|
184
|
+
type: ValidationErrorType.UnallowedRelation,
|
|
185
|
+
message: 'trying to upsert an unallowed relation',
|
|
186
|
+
});
|
|
187
|
+
}
|
|
242
188
|
}
|
|
243
|
-
}
|
|
244
189
|
}
|
|
245
|
-
|
|
246
190
|
function checkForUnallowedReferenceErrors(graphData, builder) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
'#ref references are not allowed in a graph by default. see the allowRefs insert/upsert graph option',
|
|
258
|
-
});
|
|
259
|
-
}
|
|
191
|
+
const { graph, graphOptions } = graphData;
|
|
192
|
+
if (graphOptions.allowRefs()) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (graph.edges.some((edge) => edge.type === ModelGraphEdge.Type.Reference)) {
|
|
196
|
+
throw builder.modelClass().createValidationError({
|
|
197
|
+
type: ValidationErrorType.InvalidGraph,
|
|
198
|
+
message: '#ref references are not allowed in a graph by default. see the allowRefs insert/upsert graph option',
|
|
199
|
+
});
|
|
200
|
+
}
|
|
260
201
|
}
|
|
261
|
-
|
|
262
202
|
function checkForHasManyRelateErrors(graphData) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
) {
|
|
270
|
-
throw new Error(
|
|
271
|
-
'You cannot relate HasManyRelation or HasOneRelation using insertGraph, because those require update operations. Consider using upsertGraph instead.',
|
|
272
|
-
);
|
|
203
|
+
const { graph, graphOptions } = graphData;
|
|
204
|
+
for (const node of graph.nodes) {
|
|
205
|
+
if (graphOptions.shouldRelate(node, graphData) &&
|
|
206
|
+
node.parentEdge.relation.isObjectionHasManyRelation) {
|
|
207
|
+
throw new Error('You cannot relate HasManyRelation or HasOneRelation using insertGraph, because those require update operations. Consider using upsertGraph instead.');
|
|
208
|
+
}
|
|
273
209
|
}
|
|
274
|
-
}
|
|
275
210
|
}
|
|
276
|
-
|
|
277
211
|
function executeOperations(builder) {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}, Promise.resolve());
|
|
289
|
-
};
|
|
212
|
+
return (graphData) => {
|
|
213
|
+
const operations = graphData.graphOptions.isInsertOnly()
|
|
214
|
+
? [GraphInsert]
|
|
215
|
+
: [GraphDelete, GraphInsert, GraphPatch, GraphRecursiveUpsert];
|
|
216
|
+
return operations.reduce((promise, Operation) => {
|
|
217
|
+
const operation = new Operation(graphData);
|
|
218
|
+
const actions = operation.createActions();
|
|
219
|
+
return promise.then(() => executeActions(builder, actions));
|
|
220
|
+
}, Promise.resolve());
|
|
221
|
+
};
|
|
290
222
|
}
|
|
291
|
-
|
|
292
223
|
function executeActions(builder, actions) {
|
|
293
|
-
|
|
294
|
-
(promise, action) => promise.then(() => action.run(builder)),
|
|
295
|
-
Promise.resolve(),
|
|
296
|
-
);
|
|
224
|
+
return actions.reduce((promise, action) => promise.then(() => action.run(builder)), Promise.resolve());
|
|
297
225
|
}
|
|
298
|
-
|
|
299
226
|
function returnResult(objects, isArray) {
|
|
300
|
-
|
|
227
|
+
return () => (isArray ? objects : objects[0]);
|
|
301
228
|
}
|
|
302
|
-
|
|
303
229
|
module.exports = {
|
|
304
|
-
|
|
230
|
+
GraphUpsert,
|
|
305
231
|
};
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { GraphOperation } = require('../GraphOperation');
|
|
4
3
|
const { GraphDeleteAction } = require('./GraphDeleteAction');
|
|
5
|
-
|
|
6
4
|
class GraphDelete extends GraphOperation {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
];
|
|
15
|
-
}
|
|
5
|
+
createActions() {
|
|
6
|
+
return [
|
|
7
|
+
new GraphDeleteAction(this.graphData, {
|
|
8
|
+
nodes: this.currentGraph.nodes.filter((currentNode) => this.graphOptions.shouldDeleteOrUnrelate(currentNode, this.graphData)),
|
|
9
|
+
}),
|
|
10
|
+
];
|
|
11
|
+
}
|
|
16
12
|
}
|
|
17
|
-
|
|
18
13
|
module.exports = {
|
|
19
|
-
|
|
14
|
+
GraphDelete,
|
|
20
15
|
};
|
|
@@ -1,74 +1,56 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { GraphAction } = require('../GraphAction');
|
|
4
3
|
const { groupBy } = require('../../../utils/objectUtils');
|
|
5
4
|
const promiseUtils = require('../../../utils/promiseUtils');
|
|
6
|
-
|
|
7
5
|
class GraphDeleteAction extends GraphAction {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
builder.findByIds(nodes.map((node) => node.obj.$id()));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
for (const node of nodes) {
|
|
53
|
-
node.userData.deleted = true;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
builders.push(shouldUnrelate ? builder.unrelate() : builder.delete());
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return builders;
|
|
61
|
-
}
|
|
6
|
+
constructor(graphData, { nodes }) {
|
|
7
|
+
super(graphData);
|
|
8
|
+
// Nodes to delete.
|
|
9
|
+
this.nodes = nodes;
|
|
10
|
+
}
|
|
11
|
+
run(builder) {
|
|
12
|
+
const nodesTodelete = this._filterOutBelongsToOneRelationUnrelates(this.nodes);
|
|
13
|
+
const builders = this._createDeleteBuilders(builder, nodesTodelete);
|
|
14
|
+
return promiseUtils.map(builders, (builder) => builder.execute(), {
|
|
15
|
+
concurrency: this._getConcurrency(builder, nodesTodelete),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
_filterOutBelongsToOneRelationUnrelates(nodes) {
|
|
19
|
+
// `BelongsToOneRelation` unrelate is handled by `GraphPatch` because
|
|
20
|
+
// unrelating a `BelongsToOneRelation` is just a matter of updating
|
|
21
|
+
// one field of the parent node.
|
|
22
|
+
return nodes.filter((node) => {
|
|
23
|
+
return !(this.graphOptions.shouldUnrelate(node, this.graphData) &&
|
|
24
|
+
node.parentEdge.relation.isObjectionBelongsToOneRelation);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
_createDeleteBuilders(parentBuilder, nodesTodelete) {
|
|
28
|
+
const nodesByRelation = groupBy(nodesTodelete, getRelation);
|
|
29
|
+
const builders = [];
|
|
30
|
+
nodesByRelation.forEach((nodes, relation) => {
|
|
31
|
+
const nodesByParent = groupBy(nodes, getParent);
|
|
32
|
+
nodesByParent.forEach((nodes, parentNode) => {
|
|
33
|
+
const shouldUnrelate = this.graphOptions.shouldUnrelate(nodes[0], this.graphData);
|
|
34
|
+
const builder = parentNode.obj.$relatedQuery(relation.name).childQueryOf(parentBuilder);
|
|
35
|
+
if (!relation.isObjectionBelongsToOneRelation) {
|
|
36
|
+
// This is useless in case of BelongsToOneRelation.
|
|
37
|
+
builder.findByIds(nodes.map((node) => node.obj.$id()));
|
|
38
|
+
}
|
|
39
|
+
for (const node of nodes) {
|
|
40
|
+
node.userData.deleted = true;
|
|
41
|
+
}
|
|
42
|
+
builders.push(shouldUnrelate ? builder.unrelate() : builder.delete());
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
return builders;
|
|
46
|
+
}
|
|
62
47
|
}
|
|
63
|
-
|
|
64
48
|
function getRelation(node) {
|
|
65
|
-
|
|
49
|
+
return node.parentEdge.relation;
|
|
66
50
|
}
|
|
67
|
-
|
|
68
51
|
function getParent(node) {
|
|
69
|
-
|
|
52
|
+
return node.parentNode;
|
|
70
53
|
}
|
|
71
|
-
|
|
72
54
|
module.exports = {
|
|
73
|
-
|
|
55
|
+
GraphDeleteAction,
|
|
74
56
|
};
|