@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.
Files changed (192) hide show
  1. package/README.md +103 -67
  2. package/lib/index.mjs +6 -0
  3. package/lib/initialize.js +6 -9
  4. package/lib/model/AjvValidator.js +235 -282
  5. package/lib/model/Model.js +653 -823
  6. package/lib/model/ModifierNotFoundError.js +5 -7
  7. package/lib/model/NotFoundError.js +14 -18
  8. package/lib/model/RelationDoesNotExistError.js +6 -9
  9. package/lib/model/ValidationError.js +33 -41
  10. package/lib/model/Validator.js +15 -21
  11. package/lib/model/getModel.js +1 -3
  12. package/lib/model/graph/ModelGraph.js +44 -64
  13. package/lib/model/graph/ModelGraphBuilder.js +164 -217
  14. package/lib/model/graph/ModelGraphEdge.js +31 -43
  15. package/lib/model/graph/ModelGraphNode.js +192 -231
  16. package/lib/model/inheritModel.js +9 -18
  17. package/lib/model/modelBindKnex.js +48 -62
  18. package/lib/model/modelClone.js +79 -98
  19. package/lib/model/modelColPropMap.js +16 -26
  20. package/lib/model/modelConcurrency.js +24 -0
  21. package/lib/model/modelId.js +44 -49
  22. package/lib/model/modelJsonAttributes.js +56 -76
  23. package/lib/model/modelParseRelations.js +68 -67
  24. package/lib/model/modelQueryProps.js +76 -107
  25. package/lib/model/modelSet.js +92 -112
  26. package/lib/model/modelTableMetadata.js +60 -72
  27. package/lib/model/modelToJson.js +120 -150
  28. package/lib/model/modelUtils.js +30 -37
  29. package/lib/model/modelValidate.js +34 -42
  30. package/lib/model/modelValues.js +78 -91
  31. package/lib/model/modelVisitor.js +22 -29
  32. package/lib/objection.js +42 -67
  33. package/lib/queryBuilder/FunctionBuilder.js +231 -279
  34. package/lib/queryBuilder/InternalOptions.js +19 -24
  35. package/lib/queryBuilder/JoinBuilder.js +116 -149
  36. package/lib/queryBuilder/QueryBuilder.js +1009 -1271
  37. package/lib/queryBuilder/QueryBuilderBase.js +647 -865
  38. package/lib/queryBuilder/QueryBuilderContext.js +14 -21
  39. package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
  40. package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
  41. package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
  42. package/lib/queryBuilder/RawBuilder.js +58 -73
  43. package/lib/queryBuilder/ReferenceBuilder.js +232 -270
  44. package/lib/queryBuilder/RelationExpression.js +322 -380
  45. package/lib/queryBuilder/StaticHookArguments.js +94 -106
  46. package/lib/queryBuilder/ValueBuilder.js +100 -112
  47. package/lib/queryBuilder/expressions.js +86 -116
  48. package/lib/queryBuilder/functions/mysql.js +642 -697
  49. package/lib/queryBuilder/graph/GraphAction.js +44 -59
  50. package/lib/queryBuilder/graph/GraphData.js +7 -9
  51. package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
  52. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
  53. package/lib/queryBuilder/graph/GraphOperation.js +16 -22
  54. package/lib/queryBuilder/graph/GraphOptions.js +143 -185
  55. package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
  56. package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
  57. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
  58. package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
  59. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
  60. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
  61. package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
  62. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
  63. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
  65. package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
  66. package/lib/queryBuilder/join/JoinResultParser.js +88 -101
  67. package/lib/queryBuilder/join/RelationJoiner.js +205 -288
  68. package/lib/queryBuilder/join/TableNode.js +117 -144
  69. package/lib/queryBuilder/join/TableTree.js +60 -76
  70. package/lib/queryBuilder/join/utils.js +10 -16
  71. package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
  72. package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
  73. package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
  74. package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
  75. package/lib/queryBuilder/operations/FindOperation.js +114 -131
  76. package/lib/queryBuilder/operations/FirstOperation.js +14 -19
  77. package/lib/queryBuilder/operations/FromOperation.js +69 -88
  78. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
  79. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
  80. package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
  81. package/lib/queryBuilder/operations/InsertOperation.js +132 -165
  82. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
  83. package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
  84. package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
  85. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
  86. package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
  87. package/lib/queryBuilder/operations/KnexOperation.js +4 -7
  88. package/lib/queryBuilder/operations/MergeOperation.js +32 -45
  89. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
  90. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
  91. package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
  92. package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
  93. package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
  94. package/lib/queryBuilder/operations/RangeOperation.js +30 -40
  95. package/lib/queryBuilder/operations/RelateOperation.js +14 -21
  96. package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
  97. package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
  98. package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
  99. package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
  100. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
  101. package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
  102. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
  103. package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
  104. package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
  105. package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
  106. package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
  107. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
  108. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
  109. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
  110. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
  114. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
  115. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
  116. package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
  117. package/lib/queryBuilder/operations/select/Selection.js +94 -105
  118. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
  121. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
  122. package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
  123. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
  124. package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
  125. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
  126. package/lib/queryBuilder/transformations/index.js +3 -9
  127. package/lib/queryBuilder/whereScopes.js +158 -186
  128. package/lib/relations/Relation.js +293 -375
  129. package/lib/relations/RelationDeleteOperation.js +24 -28
  130. package/lib/relations/RelationFindOperation.js +108 -138
  131. package/lib/relations/RelationInsertOperation.js +24 -32
  132. package/lib/relations/RelationOwner.js +175 -209
  133. package/lib/relations/RelationProperty.js +186 -223
  134. package/lib/relations/RelationUpdateOperation.js +23 -29
  135. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +16 -21
  136. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +30 -41
  137. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +36 -47
  138. package/lib/relations/belongsToOne/BelongsToOneRelation.js +42 -50
  139. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +43 -58
  140. package/lib/relations/hasMany/HasManyInsertOperation.js +40 -56
  141. package/lib/relations/hasMany/HasManyRelateOperation.js +45 -61
  142. package/lib/relations/hasMany/HasManyRelation.js +38 -46
  143. package/lib/relations/hasMany/HasManyUnrelateOperation.js +25 -32
  144. package/lib/relations/hasOne/HasOneRelation.js +9 -12
  145. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +9 -12
  146. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +73 -95
  147. package/lib/relations/manyToMany/ManyToManyRelation.js +374 -473
  148. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +23 -30
  149. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -10
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -25
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -12
  152. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +77 -100
  153. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +37 -49
  154. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +58 -74
  155. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +10 -13
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +26 -33
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +10 -15
  158. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -10
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +61 -78
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -12
  161. package/lib/transaction.js +53 -83
  162. package/lib/utils/assert.js +15 -21
  163. package/lib/utils/buildUtils.js +17 -19
  164. package/lib/utils/classUtils.js +7 -11
  165. package/lib/utils/cloneDeep.js +365 -0
  166. package/lib/utils/createModifier.js +36 -41
  167. package/lib/utils/deprecate.js +8 -12
  168. package/lib/utils/identifierMapping.js +153 -192
  169. package/lib/utils/internalPropUtils.js +4 -8
  170. package/lib/utils/knexUtils.js +61 -56
  171. package/lib/utils/mixin.js +16 -23
  172. package/lib/utils/mysqlJsonPath.js +55 -40
  173. package/lib/utils/normalizeIds.js +110 -127
  174. package/lib/utils/objectUtils.js +236 -338
  175. package/lib/utils/parseFieldExpression.js +66 -44
  176. package/lib/utils/postgresJsonPath.js +48 -62
  177. package/lib/utils/promiseUtils/after.js +10 -13
  178. package/lib/utils/promiseUtils/afterReturn.js +10 -13
  179. package/lib/utils/promiseUtils/index.js +15 -17
  180. package/lib/utils/promiseUtils/isPromise.js +6 -9
  181. package/lib/utils/promiseUtils/map.js +75 -89
  182. package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
  183. package/lib/utils/promiseUtils/try.js +15 -18
  184. package/lib/utils/resolveModel.js +91 -94
  185. package/lib/utils/tmpColumnUtils.js +4 -13
  186. package/package.json +50 -23
  187. package/typings/objection/index.d.mts +362 -0
  188. package/typings/objection/index.d.ts +36 -9
  189. package/lib/.eslintrc.json +0 -8
  190. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
  191. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
  192. 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
- constructor({ rootModelClass, objects, upsertOptions }) {
20
- checkCanBeConvertedToModels(rootModelClass, objects);
21
-
22
- this.objects = rootModelClass.ensureModelArray(objects, GraphUpsert.modelOptions);
23
- this.isArray = Array.isArray(objects);
24
- this.upsertOpt = upsertOptions;
25
- }
26
-
27
- static get modelOptions() {
28
- return { skipValidation: true };
29
- }
30
-
31
- run(builder) {
32
- const modelClass = builder.modelClass();
33
- const graphOptions = new GraphOptions(this.upsertOpt);
34
-
35
- const graph = ModelGraph.create(modelClass, this.objects);
36
- assignDbRefsAsRelateProps(graph);
37
-
38
- return createGraphData(builder, graphOptions, graph)
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
- asArray(objects).forEach((obj) => {
48
- if (!isObject(obj)) {
49
- throw createNotModelError(modelClass, obj);
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
- for (const node of graph.nodes) {
56
- if (!node.parentEdge || !node.parentEdge.relation || !node.isDbReference) {
57
- continue;
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
- const currentGraph = await fetchCurrentGraph(builder, graphOptions, graph);
66
-
67
- const nodeDbExistence = await GraphNodeDbExistence.create({
68
- builder,
69
- graph,
70
- graphOptions,
71
- currentGraph,
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
- if (graphOptions.isInsertOnly()) {
79
- return Promise.resolve(ModelGraph.createEmpty());
80
- } else {
81
- return GraphFetcher.fetchCurrentGraph({ builder, graph, graphOptions });
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
- return (graphData) => {
90
- pruneRelatedBranches(graphData);
91
-
92
- if (!graphData.graphOptions.isInsertOnly()) {
93
- pruneDeletedBranches(graphData);
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
- const relateNodes = graphData.graph.nodes.filter((node) => {
102
- return (
103
- !graphData.currentGraph.nodeForNode(node) &&
104
- !graphData.graphOptions.shouldInsertIgnoreDisable(node, graphData)
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
- const { graph, currentGraph } = graphData;
113
-
114
- const deleteNodes = currentGraph.nodes.filter((currentNode) => !graph.nodeForNode(currentNode));
115
- const roots = findRoots(deleteNodes);
116
-
117
- // Don't delete relations the current graph doesn't even mention.
118
- // So if the parent node doesn't even have the relation, it's not
119
- // supposed to be deleted.
120
- const rootsNotInRelation = roots.filter((deleteRoot) => {
121
- if (!deleteRoot.parentNode) {
122
- return false;
123
- }
124
-
125
- const { relation } = deleteRoot.parentEdge;
126
- const parentNode = graph.nodeForNode(deleteRoot.parentNode);
127
-
128
- if (!parentNode) {
129
- return false;
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
- const nodeSet = new Set(nodes);
141
-
142
- return uniqBy(
143
- nodes.filter((node) => {
144
- let parentNode = node.parentNode;
145
-
146
- while (parentNode) {
147
- if (nodeSet.has(parentNode)) {
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
- parentNode = parentNode.parentNode;
152
- }
153
-
154
- return true;
155
- }),
156
- );
121
+ return true;
122
+ }));
157
123
  }
158
-
159
124
  function removeBranchesFromGraph(branchRoots, graph) {
160
- const nodesToRemove = new Set(
161
- branchRoots.reduce(
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
- const edgesToRemove = new Set();
172
-
173
- for (const node of nodesToRemove) {
174
- for (const edge of node.edges) {
175
- const otherNode = edge.getOtherNode(node);
176
-
177
- if (!nodesToRemove.has(otherNode)) {
178
- otherNode.removeEdge(edge);
179
- edgesToRemove.add(edge);
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
- graph.nodes = graph.nodes.filter((node) => !nodesToRemove.has(node));
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
- return (graphData) => {
192
- checkForNotFoundErrors(graphData, builder);
193
- checkForUnallowedRelationErrors(graphData, builder);
194
- checkForUnallowedReferenceErrors(graphData, builder);
195
-
196
- if (graphData.graphOptions.isInsertOnly()) {
197
- checkForHasManyRelateErrors(graphData);
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
- const { graphOptions, currentGraph, graph } = graphData;
206
-
207
- for (const node of graph.nodes) {
208
- if (
209
- node.obj.$hasId() &&
210
- !graphOptions.shouldInsertIgnoreDisable(node, graphData) &&
211
- !graphOptions.shouldRelateIgnoreDisable(node, graphData) &&
212
- !currentGraph.nodeForNode(node)
213
- ) {
214
- if (!node.parentNode) {
215
- throw node.modelClass.createNotFoundError(builder.context(), {
216
- message: `root model (id=${node.obj.$id()}) does not exist. If you want to insert it with an id, use the insertMissing option`,
217
- dataPath: node.dataPath,
218
- });
219
- } else {
220
- throw node.modelClass.createNotFoundError(builder.context(), {
221
- 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`,
222
- dataPath: node.dataPath,
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
- const { graph } = graphData;
231
- const allowedExpression = builder.allowedGraphExpression();
232
-
233
- if (allowedExpression) {
234
- const rootsObjs = graph.nodes.filter((node) => !node.parentEdge).map((node) => node.obj);
235
- const expression = RelationExpression.fromModelGraph(rootsObjs);
236
-
237
- if (!allowedExpression.isSubExpression(expression)) {
238
- throw builder.modelClass().createValidationError({
239
- type: ValidationErrorType.UnallowedRelation,
240
- message: 'trying to upsert an unallowed relation',
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
- const { graph, graphOptions } = graphData;
248
-
249
- if (graphOptions.allowRefs()) {
250
- return;
251
- }
252
-
253
- if (graph.edges.some((edge) => edge.type === ModelGraphEdge.Type.Reference)) {
254
- throw builder.modelClass().createValidationError({
255
- type: ValidationErrorType.InvalidGraph,
256
- message:
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
- const { graph, graphOptions } = graphData;
264
-
265
- for (const node of graph.nodes) {
266
- if (
267
- graphOptions.shouldRelate(node, graphData) &&
268
- node.parentEdge.relation.isObjectionHasManyRelation
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
- return (graphData) => {
279
- const operations = graphData.graphOptions.isInsertOnly()
280
- ? [GraphInsert]
281
- : [GraphDelete, GraphInsert, GraphPatch, GraphRecursiveUpsert];
282
-
283
- return operations.reduce((promise, Operation) => {
284
- const operation = new Operation(graphData);
285
- const actions = operation.createActions();
286
-
287
- return promise.then(() => executeActions(builder, actions));
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
- return actions.reduce(
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
- return () => (isArray ? objects : objects[0]);
227
+ return () => (isArray ? objects : objects[0]);
301
228
  }
302
-
303
229
  module.exports = {
304
- GraphUpsert,
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
- createActions() {
8
- return [
9
- new GraphDeleteAction(this.graphData, {
10
- nodes: this.currentGraph.nodes.filter((currentNode) =>
11
- this.graphOptions.shouldDeleteOrUnrelate(currentNode, this.graphData),
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
- GraphDelete,
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
- constructor(graphData, { nodes }) {
9
- super(graphData);
10
- // Nodes to delete.
11
- this.nodes = nodes;
12
- }
13
-
14
- run(builder) {
15
- const nodesTodelete = this._filterOutBelongsToOneRelationUnrelates(this.nodes);
16
- const builders = this._createDeleteBuilders(builder, nodesTodelete);
17
-
18
- return promiseUtils.map(builders, (builder) => builder.execute(), {
19
- concurrency: this._getConcurrency(builder, nodesTodelete),
20
- });
21
- }
22
-
23
- _filterOutBelongsToOneRelationUnrelates(nodes) {
24
- // `BelongsToOneRelation` unrelate is handled by `GraphPatch` because
25
- // unrelating a `BelongsToOneRelation` is just a matter of updating
26
- // one field of the parent node.
27
- return nodes.filter((node) => {
28
- return !(
29
- this.graphOptions.shouldUnrelate(node, this.graphData) &&
30
- node.parentEdge.relation.isObjectionBelongsToOneRelation
31
- );
32
- });
33
- }
34
-
35
- _createDeleteBuilders(parentBuilder, nodesTodelete) {
36
- const nodesByRelation = groupBy(nodesTodelete, getRelation);
37
- const builders = [];
38
-
39
- nodesByRelation.forEach((nodes, relation) => {
40
- const nodesByParent = groupBy(nodes, getParent);
41
-
42
- nodesByParent.forEach((nodes, parentNode) => {
43
- const shouldUnrelate = this.graphOptions.shouldUnrelate(nodes[0], this.graphData);
44
-
45
- const builder = parentNode.obj.$relatedQuery(relation.name).childQueryOf(parentBuilder);
46
-
47
- if (!relation.isObjectionBelongsToOneRelation) {
48
- // This is useless in case of BelongsToOneRelation.
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
- return node.parentEdge.relation;
49
+ return node.parentEdge.relation;
66
50
  }
67
-
68
51
  function getParent(node) {
69
- return node.parentNode;
52
+ return node.parentNode;
70
53
  }
71
-
72
54
  module.exports = {
73
- GraphDeleteAction,
55
+ GraphDeleteAction,
74
56
  };