objection 3.9.0 → 4.0.0-rc.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 (248) hide show
  1. package/lib/dbErrors/LICENSE +21 -0
  2. package/lib/dbErrors/errorCodes/mssql.js +19 -0
  3. package/lib/dbErrors/errorCodes/mysql.js +805 -0
  4. package/lib/dbErrors/errorCodes/postgres.js +241 -0
  5. package/lib/dbErrors/errors/CheckViolationError.js +10 -0
  6. package/lib/dbErrors/errors/ConstraintViolationError.js +3 -0
  7. package/lib/dbErrors/errors/DBError.js +9 -0
  8. package/lib/dbErrors/errors/DataError.js +3 -0
  9. package/lib/dbErrors/errors/ForeignKeyViolationError.js +11 -0
  10. package/lib/dbErrors/errors/NotNullViolationError.js +12 -0
  11. package/lib/dbErrors/errors/UniqueViolationError.js +12 -0
  12. package/lib/dbErrors/index.js +59 -0
  13. package/lib/dbErrors/parsers/mssql/DBError/CheckViolationError/parser.js +28 -0
  14. package/lib/dbErrors/parsers/mssql/DBError/DataError/parser.js +25 -0
  15. package/lib/dbErrors/parsers/mssql/DBError/ForeignKeyViolationError/parser.js +39 -0
  16. package/lib/dbErrors/parsers/mssql/DBError/NotNullViolationError/parser.js +30 -0
  17. package/lib/dbErrors/parsers/mssql/DBError/UniqueViolationError/parser.js +53 -0
  18. package/lib/dbErrors/parsers/mssql/DBError/parser.js +51 -0
  19. package/lib/dbErrors/parsers/mssql/DBError/util.js +16 -0
  20. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +43 -0
  21. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/NotNullViolationError/parser.js +29 -0
  22. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/UniqueViolationError/parser.js +27 -0
  23. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/parser.js +23 -0
  24. package/lib/dbErrors/parsers/mysql/DBError/DataError/parser.js +24 -0
  25. package/lib/dbErrors/parsers/mysql/DBError/parser.js +28 -0
  26. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/CheckViolationError/parser.js +18 -0
  27. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +18 -0
  28. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/NotNullViolationError/parser.js +18 -0
  29. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/UniqueViolationError/parser.js +40 -0
  30. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/parser.js +25 -0
  31. package/lib/dbErrors/parsers/postgres/DBError/DataError/parser.js +16 -0
  32. package/lib/dbErrors/parsers/postgres/DBError/parser.js +27 -0
  33. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/CheckViolationError/parser.js +20 -0
  34. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +20 -0
  35. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/NotNullViolationError/parser.js +27 -0
  36. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/UniqueViolationError/parser.js +28 -0
  37. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/parser.js +24 -0
  38. package/lib/dbErrors/parsers/sqlite/DBError/parser.js +23 -0
  39. package/lib/dbErrors/utils/sqlState.js +3 -0
  40. package/lib/initialize.js +1 -7
  41. package/lib/model/AjvValidator.js +51 -117
  42. package/lib/model/Model.js +84 -59
  43. package/lib/model/ModifierNotFoundError.js +1 -7
  44. package/lib/model/NotFoundError.js +1 -7
  45. package/lib/model/RelationDoesNotExistError.js +1 -7
  46. package/lib/model/ValidationError.js +3 -10
  47. package/lib/model/Validator.js +1 -7
  48. package/lib/model/getModel.js +7 -6
  49. package/lib/model/inheritModel.js +1 -7
  50. package/lib/model/modelBindKnex.js +4 -10
  51. package/lib/model/modelClone.js +5 -11
  52. package/lib/model/modelColPropMap.js +3 -10
  53. package/lib/model/modelId.js +3 -10
  54. package/lib/model/modelJsonAttributes.js +35 -16
  55. package/lib/model/modelParseRelations.js +2 -8
  56. package/lib/model/modelQueryProps.js +43 -27
  57. package/lib/model/modelSet.js +89 -41
  58. package/lib/model/modelTableMetadata.js +4 -11
  59. package/lib/model/modelToJson.js +8 -23
  60. package/lib/model/modelUtils.js +14 -13
  61. package/lib/model/modelValidate.js +3 -9
  62. package/lib/model/modelValues.js +5 -14
  63. package/lib/model/modelVisitor.js +1 -7
  64. package/lib/objection.js +33 -71
  65. package/lib/queryBuilder/FunctionBuilder.js +4 -11
  66. package/lib/queryBuilder/InternalOptions.js +4 -9
  67. package/lib/queryBuilder/JoinBuilder.js +5 -8
  68. package/lib/queryBuilder/QueryBuilder.js +126 -95
  69. package/lib/queryBuilder/QueryBuilderBase.js +41 -123
  70. package/lib/queryBuilder/QueryBuilderContext.js +2 -8
  71. package/lib/queryBuilder/QueryBuilderContextBase.js +2 -8
  72. package/lib/queryBuilder/QueryBuilderOperationSupport.js +7 -21
  73. package/lib/queryBuilder/QueryBuilderUserContext.js +1 -7
  74. package/lib/queryBuilder/RawBuilder.js +5 -13
  75. package/lib/queryBuilder/ReferenceBuilder.js +20 -48
  76. package/lib/queryBuilder/RelationExpression.js +18 -16
  77. package/lib/queryBuilder/StaticHookArguments.js +74 -16
  78. package/lib/queryBuilder/ValueBuilder.js +11 -13
  79. package/lib/queryBuilder/getJoinBuilder.js +10 -0
  80. package/lib/queryBuilder/graph/GraphLoader.js +304 -0
  81. package/lib/queryBuilder/graph/GraphNode.js +235 -0
  82. package/lib/queryBuilder/graph/GraphOptions.js +55 -248
  83. package/lib/queryBuilder/graph/GraphPlan.js +395 -0
  84. package/lib/queryBuilder/graph/GraphUpsert.js +466 -410
  85. package/lib/queryBuilder/graph/GraphWriter.js +1263 -0
  86. package/lib/queryBuilder/join/JoinResultColumn.js +1 -7
  87. package/lib/queryBuilder/join/JoinResultParser.js +6 -11
  88. package/lib/queryBuilder/join/RelationJoiner.js +66 -84
  89. package/lib/queryBuilder/join/TableNode.js +2 -8
  90. package/lib/queryBuilder/join/TableTree.js +3 -9
  91. package/lib/queryBuilder/join/utils.js +5 -15
  92. package/lib/queryBuilder/jsonDialects/JsonDialect.js +51 -0
  93. package/lib/queryBuilder/jsonDialects/MySqlJsonDialect.js +81 -0
  94. package/lib/queryBuilder/jsonDialects/PostgresJsonDialect.js +45 -0
  95. package/lib/queryBuilder/jsonDialects/SqliteJsonDialect.js +67 -0
  96. package/lib/queryBuilder/jsonDialects/index.js +44 -0
  97. package/lib/queryBuilder/operations/DelegateOperation.js +2 -8
  98. package/lib/queryBuilder/operations/DeleteOperation.js +13 -35
  99. package/lib/queryBuilder/operations/FindByIdOperation.js +7 -12
  100. package/lib/queryBuilder/operations/FindByIdsOperation.js +4 -8
  101. package/lib/queryBuilder/operations/FindOperation.js +14 -34
  102. package/lib/queryBuilder/operations/FirstOperation.js +6 -10
  103. package/lib/queryBuilder/operations/FromOperation.js +3 -9
  104. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +13 -12
  105. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +4 -10
  106. package/lib/queryBuilder/operations/InsertGraphOperation.js +7 -18
  107. package/lib/queryBuilder/operations/InsertOperation.js +118 -43
  108. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +5 -12
  109. package/lib/queryBuilder/operations/InstanceFindOperation.js +4 -11
  110. package/lib/queryBuilder/operations/InstanceInsertOperation.js +2 -8
  111. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +7 -14
  112. package/lib/queryBuilder/operations/JoinRelatedOperation.js +5 -11
  113. package/lib/queryBuilder/operations/KnexOperation.js +2 -8
  114. package/lib/queryBuilder/operations/LimitPerParentOperation.js +7 -69
  115. package/lib/queryBuilder/operations/MergeOperation.js +5 -11
  116. package/lib/queryBuilder/operations/NoneOperation.js +2 -8
  117. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +20 -49
  118. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +2 -8
  119. package/lib/queryBuilder/operations/OnBuildOperation.js +2 -8
  120. package/lib/queryBuilder/operations/OnErrorOperation.js +2 -8
  121. package/lib/queryBuilder/operations/QueryBuilderOperation.js +1 -7
  122. package/lib/queryBuilder/operations/RangeOperation.js +11 -26
  123. package/lib/queryBuilder/operations/RelateOperation.js +2 -8
  124. package/lib/queryBuilder/operations/ReturningOperation.js +3 -9
  125. package/lib/queryBuilder/operations/RunAfterOperation.js +2 -12
  126. package/lib/queryBuilder/operations/RunBeforeOperation.js +2 -8
  127. package/lib/queryBuilder/operations/UnrelateOperation.js +2 -8
  128. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +14 -17
  129. package/lib/queryBuilder/operations/UpdateOperation.js +39 -125
  130. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +8 -11
  131. package/lib/queryBuilder/operations/UpsertGraphOperation.js +6 -12
  132. package/lib/queryBuilder/operations/WhereCompositeOperation.js +3 -9
  133. package/lib/queryBuilder/operations/WhereGroupOperation.js +2 -8
  134. package/lib/queryBuilder/operations/eager/EagerOperation.js +3 -9
  135. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +72 -10
  136. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +2 -8
  137. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +23 -44
  138. package/lib/queryBuilder/operations/fieldExpressions.js +122 -0
  139. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +20 -0
  140. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +44 -0
  141. package/lib/queryBuilder/operations/jsonApi/WhereJsonTypeOperation.js +14 -0
  142. package/lib/queryBuilder/operations/select/SelectOperation.js +11 -21
  143. package/lib/queryBuilder/operations/select/Selection.js +19 -17
  144. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +4 -10
  145. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +4 -10
  146. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +4 -10
  147. package/lib/queryBuilder/operations/windowOrder.js +56 -0
  148. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +3 -7
  149. package/lib/queryBuilder/parsers/relationExpressionParser.js +42 -43
  150. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +39 -36
  151. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +2 -8
  152. package/lib/queryBuilder/transformations/QueryTransformation.js +1 -7
  153. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +3 -9
  154. package/lib/queryBuilder/transformations/index.js +3 -11
  155. package/lib/queryBuilder/whereGroups.js +9 -24
  156. package/lib/queryBuilder/withoutOrder.js +4 -11
  157. package/lib/relations/Relation.js +47 -28
  158. package/lib/relations/RelationDeleteOperation.js +4 -14
  159. package/lib/relations/RelationFindOperation.js +119 -90
  160. package/lib/relations/RelationInsertOperation.js +2 -8
  161. package/lib/relations/RelationOwner.js +5 -11
  162. package/lib/relations/RelationProperty.js +4 -10
  163. package/lib/relations/RelationUpdateOperation.js +4 -14
  164. package/lib/relations/RelationWriteResultOperation.js +15 -0
  165. package/lib/relations/belongsToMany/BelongsToManyDeleteOperation.js +23 -0
  166. package/lib/relations/belongsToMany/BelongsToManyFindOperation.js +35 -0
  167. package/lib/relations/belongsToMany/BelongsToManyInsertOperation.js +28 -0
  168. package/lib/relations/belongsToMany/BelongsToManyRelateOperation.js +16 -0
  169. package/lib/relations/belongsToMany/BelongsToManyRelation.js +276 -0
  170. package/lib/relations/belongsToMany/BelongsToManyUnrelateOperation.js +11 -0
  171. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +2 -8
  172. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +6 -11
  173. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +3 -9
  174. package/lib/relations/belongsToOne/BelongsToOneRelation.js +8 -19
  175. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +53 -27
  176. package/lib/relations/hasMany/HasManyInsertOperation.js +8 -9
  177. package/lib/relations/hasMany/HasManyRelateOperation.js +5 -11
  178. package/lib/relations/hasMany/HasManyRelation.js +9 -11
  179. package/lib/relations/hasMany/HasManyUnrelateOperation.js +3 -9
  180. package/lib/relations/hasOne/HasOneRelation.js +2 -8
  181. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +2 -8
  182. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +10 -15
  183. package/lib/relations/manyToMany/ManyToManyMySqlModifyMixin.js +2 -8
  184. package/lib/relations/manyToMany/ManyToManyRelation.js +82 -50
  185. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +2 -8
  186. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +5 -9
  187. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +2 -8
  188. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -9
  189. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +20 -59
  190. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +6 -11
  191. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +4 -10
  192. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateMySqlOperation.js +3 -9
  193. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +5 -9
  194. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +3 -9
  195. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +3 -9
  196. package/lib/relations/manyToMany/update/ManyToManyUpdateMySqlOperation.js +3 -9
  197. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +5 -9
  198. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +79 -64
  199. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -9
  200. package/lib/transaction.js +3 -9
  201. package/lib/utils/assert.js +3 -11
  202. package/lib/utils/buildUtils.js +2 -8
  203. package/lib/utils/classUtils.js +1 -7
  204. package/lib/utils/createModifier.js +2 -8
  205. package/lib/utils/identifierMapping.js +23 -27
  206. package/lib/utils/internalPropUtils.js +1 -7
  207. package/lib/utils/knexUtils.js +84 -40
  208. package/lib/utils/mixin.js +3 -10
  209. package/lib/utils/normalizeIds.js +2 -8
  210. package/lib/utils/objectUtils.js +41 -60
  211. package/lib/utils/parseFieldExpression.js +29 -14
  212. package/lib/utils/promiseUtils/after.js +2 -8
  213. package/lib/utils/promiseUtils/afterReturn.js +2 -8
  214. package/lib/utils/promiseUtils/index.js +7 -16
  215. package/lib/utils/promiseUtils/isPromise.js +2 -8
  216. package/lib/utils/promiseUtils/map.js +25 -14
  217. package/lib/utils/promiseUtils/mapAfterAllReturn.js +2 -8
  218. package/lib/utils/promiseUtils/try.js +2 -8
  219. package/lib/utils/resolveModel.js +10 -17
  220. package/lib/utils/tmpColumnUtils.js +2 -9
  221. package/lib/utils/warnings.js +2 -14
  222. package/package.json +25 -17
  223. package/typings/objection/index.d.ts +3217 -2179
  224. package/lib/.eslintrc.json +0 -8
  225. package/lib/model/graph/ModelGraph.js +0 -80
  226. package/lib/model/graph/ModelGraphBuilder.js +0 -241
  227. package/lib/model/graph/ModelGraphEdge.js +0 -52
  228. package/lib/model/graph/ModelGraphNode.js +0 -253
  229. package/lib/queryBuilder/graph/GraphAction.js +0 -69
  230. package/lib/queryBuilder/graph/GraphData.js +0 -53
  231. package/lib/queryBuilder/graph/GraphFetcher.js +0 -199
  232. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +0 -184
  233. package/lib/queryBuilder/graph/GraphOperation.js +0 -27
  234. package/lib/queryBuilder/graph/delete/GraphDelete.js +0 -73
  235. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +0 -88
  236. package/lib/queryBuilder/graph/insert/DeferredRelationGraphInsertAction.js +0 -57
  237. package/lib/queryBuilder/graph/insert/GraphInsert.js +0 -257
  238. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +0 -238
  239. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +0 -92
  240. package/lib/queryBuilder/graph/patch/GraphPatch.js +0 -20
  241. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +0 -277
  242. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +0 -31
  243. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +0 -126
  244. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasPostgresOperation.js +0 -30
  245. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectPostgresOperation.js +0 -37
  246. package/lib/queryBuilder/operations/jsonApi/WhereJsonPostgresOperation.js +0 -62
  247. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +0 -192
  248. package/lib/utils/wrapDbError.js +0 -50
@@ -1,257 +0,0 @@
1
- 'use strict';
2
-
3
- const { JoinRowGraphInsertAction } = require('./JoinRowGraphInsertAction');
4
- const { DeferredRelationGraphInsertAction } = require('./DeferredRelationGraphInsertAction');
5
- const { GraphInsertAction } = require('./GraphInsertAction');
6
- const { GraphOperation } = require('../GraphOperation');
7
- const { ModelGraphEdge } = require('../../../model/graph/ModelGraphEdge');
8
-
9
- class GraphInsert extends GraphOperation {
10
- constructor(...args) {
11
- super(...args);
12
- this.dependencies = this._createDependencyMap();
13
- this.deferredEdges = new Set();
14
- }
15
-
16
- createActions() {
17
- return [
18
- ...this._createNormalActions(),
19
- ...this._createDeferredRelationActions(),
20
- ...this._createJoinRowActions(),
21
- ];
22
- }
23
-
24
- _createDependencyMap() {
25
- const dependencies = new Map();
26
-
27
- for (const edge of this.graph.edges) {
28
- if (edge.type == ModelGraphEdge.Type.Relation) {
29
- this._createRelationDependency(edge, dependencies);
30
- } else {
31
- this._createReferenceDependency(edge, dependencies);
32
- }
33
- }
34
-
35
- return dependencies;
36
- }
37
-
38
- _createRelationDependency(edge, dependencies) {
39
- if (edge.relatedNode.toBeUnrelatedOrDeleted) {
40
- // Models marked with `#unrelate` or `#delete` are never inserted or
41
- // related, so their keys must not be copied to the owner (or vice versa).
42
- return;
43
- }
44
-
45
- if (edge.relation.isObjectionHasManyRelation) {
46
- // In case of HasManyRelation the related node depends on the owner node
47
- // because the related node has the foreign key.
48
- this._addDependency(edge.relatedNode, edge, dependencies);
49
- } else if (
50
- edge.relation.isObjectionBelongsToOneRelation &&
51
- // Ignored models don't replace the current one, so their keys must not
52
- // be copied to the owner either.
53
- !this.graphOptions.shouldIgnore(edge.relatedNode, this.graphData)
54
- ) {
55
- // In case of BelongsToOneRelation the owner node depends on the related
56
- // node because the owner node has the foreign key.
57
- this._addDependency(edge.ownerNode, edge, dependencies);
58
- }
59
- }
60
-
61
- _createReferenceDependency(edge, dependencies) {
62
- this._addDependency(edge.ownerNode, edge, dependencies);
63
- }
64
-
65
- _addDependency(node, edge, dependencies) {
66
- let edges = dependencies.get(node);
67
-
68
- if (!edges) {
69
- edges = [];
70
- dependencies.set(node, edges);
71
- }
72
-
73
- edges.push(edge);
74
- }
75
-
76
- _createNormalActions() {
77
- const handledNodes = new Set();
78
- const actions = [];
79
-
80
- while (true) {
81
- // At this point, don't care if the nodes have already been inserted before
82
- // given to this class. `GraphInsertAction` will test that and only insert
83
- // new ones. We need to pass all nodes to `GraphInsertActions` so that we
84
- // can resolve all dependencies.
85
- const nodesToInsert = this.graph.nodes.filter((node) => {
86
- return !this._isHandled(node, handledNodes) && !this._hasDependencies(node, handledNodes);
87
- });
88
-
89
- if (nodesToInsert.length === 0) {
90
- if (handledNodes.size !== this.graph.nodes.length && this._breakCycle(handledNodes)) {
91
- continue;
92
- }
93
-
94
- break;
95
- }
96
-
97
- actions.push(
98
- new GraphInsertAction(this.graphData, {
99
- nodes: nodesToInsert,
100
- dependencies: this.dependencies,
101
- deferredEdges: this.deferredEdges,
102
- }),
103
- );
104
-
105
- for (const node of nodesToInsert) {
106
- this._markHandled(node, handledNodes);
107
- }
108
- }
109
-
110
- if (handledNodes.size !== this.graph.nodes.length) {
111
- throw new Error('the object graph contains cyclic references');
112
- }
113
-
114
- return actions;
115
- }
116
-
117
- // Tries to break a dependency cycle by deferring one `BelongsToOneRelation`
118
- // edge that points to a `#ref` node. The owner node is then inserted without
119
- // the foreign key, which is patched in by `DeferredRelationGraphInsertAction`
120
- // once the referenced node has been inserted. Cycles can only exist through
121
- // `#ref` nodes, since the graph is a tree otherwise.
122
- _breakCycle(handledNodes) {
123
- for (const node of this.graph.nodes) {
124
- if (this._isHandled(node, handledNodes)) {
125
- continue;
126
- }
127
-
128
- for (const edge of this._pendingDependencyEdges(node, handledNodes)) {
129
- if (
130
- this._canDeferEdge(edge, node) &&
131
- this._isBlockedBy(edge.relatedNode, node, handledNodes, new Set())
132
- ) {
133
- this.deferredEdges.add(edge);
134
- return true;
135
- }
136
- }
137
- }
138
-
139
- return false;
140
- }
141
-
142
- _canDeferEdge(edge, node) {
143
- return (
144
- edge.type === ModelGraphEdge.Type.Relation &&
145
- edge.relation.isObjectionBelongsToOneRelation &&
146
- edge.isOwnerNode(node) &&
147
- edge.relatedNode.isReference &&
148
- // The owner is patched by its id, which models without one don't have (#2305).
149
- node.modelClass.getIdColumnArray().length > 0 &&
150
- // Both ends need to be inserted for the foreign key to be patched in later.
151
- this.graphOptions.shouldInsert(node, this.graphData) &&
152
- this.graphOptions.shouldInsert(edge.relatedNode.referencedNode, this.graphData) &&
153
- !this._isReadByPropertyReference(node, edge.relation.ownerProp)
154
- );
155
- }
156
-
157
- // Returns true if a `#ref{}` property reference reads one of the `props` of
158
- // `node`. Such references may be resolved before a deferred prop is set,
159
- // which would resolve them to `undefined`.
160
- _isReadByPropertyReference(node, props) {
161
- return node.refEdges.some((edge) => {
162
- return (
163
- edge.refType === ModelGraphEdge.ReferenceType.Property &&
164
- edge.isRelatedNode(node) &&
165
- props.props.includes(edge.refRelatedDataPath[0])
166
- );
167
- });
168
- }
169
-
170
- // Returns true if `node` (transitively) waits for `blockingNode` to be handled.
171
- _isBlockedBy(node, blockingNode, handledNodes, visitedNodes) {
172
- if (node === blockingNode) {
173
- return true;
174
- }
175
-
176
- if (visitedNodes.has(node)) {
177
- return false;
178
- }
179
-
180
- visitedNodes.add(node);
181
-
182
- for (const edge of this._pendingDependencyEdges(node, handledNodes)) {
183
- if (this._isBlockedBy(edge.getOtherNode(node), blockingNode, handledNodes, visitedNodes)) {
184
- return true;
185
- }
186
- }
187
-
188
- return false;
189
- }
190
-
191
- _createDeferredRelationActions() {
192
- if (this.deferredEdges.size === 0) {
193
- return [];
194
- }
195
-
196
- return [
197
- new DeferredRelationGraphInsertAction(this.graphData, {
198
- edges: [...this.deferredEdges],
199
- }),
200
- ];
201
- }
202
-
203
- _isHandled(node, handledNodes) {
204
- return handledNodes.has(node);
205
- }
206
-
207
- _hasDependencies(node, handledNodes) {
208
- return this._pendingDependencyEdges(node, handledNodes).length > 0;
209
- }
210
-
211
- // Returns the dependency edges of `node` whose other node still needs to be
212
- // inserted first. Deferred edges are ignored.
213
- _pendingDependencyEdges(node, handledNodes) {
214
- const edges = this.dependencies.get(node) || [];
215
-
216
- return edges.filter((edge) => {
217
- const dependencyNode = edge.getOtherNode(node);
218
-
219
- return (
220
- !this.deferredEdges.has(edge) &&
221
- !handledNodes.has(dependencyNode) &&
222
- !this.currentGraph.nodeForNode(dependencyNode)
223
- );
224
- });
225
- }
226
-
227
- _markHandled(node, handledNodes) {
228
- handledNodes.add(node);
229
-
230
- // The referencing nodes are all references that don't
231
- // represent any real entity. They are simply intermediate nodes
232
- // that depend on this node. Once this node is handled, we can
233
- // also mark those nodes as handled as there is nothing to actually
234
- // insert.
235
- for (const refNode of node.referencingNodes) {
236
- this._markHandled(refNode, handledNodes);
237
- }
238
- }
239
-
240
- _createJoinRowActions() {
241
- return [
242
- new JoinRowGraphInsertAction(this.graphData, {
243
- nodes: this.graph.nodes.filter((node) => {
244
- return (
245
- this.currentGraph.nodeForNode(node) === null &&
246
- node.parentEdge &&
247
- node.parentEdge.relation.isObjectionManyToManyRelation
248
- );
249
- }),
250
- }),
251
- ];
252
- }
253
- }
254
-
255
- module.exports = {
256
- GraphInsert,
257
- };
@@ -1,238 +0,0 @@
1
- 'use strict';
2
-
3
- const { GraphAction } = require('../GraphAction');
4
- const { groupBy, chunk, get, set } = require('../../../utils/objectUtils');
5
- const { ModelGraphEdge } = require('../../../model/graph/ModelGraphEdge');
6
- const promiseUtils = require('../../../utils/promiseUtils');
7
-
8
- /**
9
- * Inserts a batch of nodes for a GraphInsert.
10
- *
11
- * One of these is created for each batch of nodes that can be inserted at once.
12
- * However, the nodes can have a different table and not all databases support
13
- * batch inserts, so this class splits the inserts into further sub batches
14
- * when needed.
15
- */
16
- class GraphInsertAction extends GraphAction {
17
- constructor(graphData, { nodes, dependencies, deferredEdges }) {
18
- super(graphData);
19
-
20
- // Nodes to insert.
21
- this.nodes = nodes;
22
- this.dependencies = dependencies;
23
- // Dependency edges that are resolved once the dependency node has been
24
- // inserted, and are patched in by `DeferredRelationGraphInsertAction`.
25
- this.deferredEdges = deferredEdges;
26
- }
27
-
28
- run(builder) {
29
- const batches = this._createInsertBatches(builder);
30
- const concurrency = this._getConcurrency(builder, this.nodes);
31
-
32
- return promiseUtils.map(batches, (batch) => this._insertBatch(builder, batch), { concurrency });
33
- }
34
-
35
- _createInsertBatches(builder) {
36
- const batches = [];
37
- const batchSize = this._getBatchSize(builder);
38
- const nodesByModelClass = groupBy(this.nodes, getModelClass);
39
-
40
- for (const nodes of nodesByModelClass.values()) {
41
- for (const nodeBatch of chunk(nodes, batchSize)) {
42
- batches.push(nodeBatch);
43
- }
44
- }
45
-
46
- return batches;
47
- }
48
-
49
- async _insertBatch(parentBuilder, nodes) {
50
- await this._beforeInsert(nodes);
51
- await this._insert(parentBuilder, nodes);
52
- await this._afterInsert(nodes);
53
- }
54
-
55
- _beforeInsert(nodes) {
56
- this._resolveDependencies(nodes);
57
- this._omitManyToManyExtraProps(nodes);
58
- this._copyRelationPropsFromCurrentIfNeeded(nodes);
59
-
60
- return Promise.resolve();
61
- }
62
-
63
- _resolveDependencies(nodes) {
64
- for (const node of nodes) {
65
- const edges = this.dependencies.get(node);
66
-
67
- if (edges) {
68
- for (const edge of edges) {
69
- if (this.deferredEdges.has(edge)) {
70
- continue;
71
- }
72
-
73
- // `node` needs `dependencyNode` to have been inserted (and it has been).
74
- const dependencyNode = edge.getOtherNode(node);
75
-
76
- this._resolveDependency(dependencyNode, edge);
77
- }
78
- }
79
- }
80
- }
81
-
82
- _resolveDependency(dependencyNode, edge) {
83
- if (edge.type === ModelGraphEdge.Type.Relation && !edge.relation.joinTable) {
84
- this._resolveRelationDependency(dependencyNode, edge);
85
- } else if (edge.refType === ModelGraphEdge.ReferenceType.Property) {
86
- this._resolvePropertyReferenceNode(dependencyNode, edge);
87
- }
88
- }
89
-
90
- _resolveRelationDependency(dependencyNode, edge) {
91
- const dependentNode = edge.getOtherNode(dependencyNode);
92
-
93
- let sourceProp;
94
- let targetProp;
95
-
96
- if (edge.isOwnerNode(dependencyNode)) {
97
- sourceProp = edge.relation.ownerProp;
98
- targetProp = edge.relation.relatedProp;
99
- } else {
100
- targetProp = edge.relation.ownerProp;
101
- sourceProp = edge.relation.relatedProp;
102
- }
103
-
104
- this._resolveReferences(dependencyNode);
105
-
106
- targetProp.forEach((i) => {
107
- targetProp.setProp(dependentNode.obj, i, sourceProp.getProp(dependencyNode.obj, i));
108
- });
109
- }
110
-
111
- _resolvePropertyReferenceNode(dependencyNode, edge) {
112
- const dependentNode = edge.getOtherNode(dependencyNode);
113
-
114
- let sourcePath;
115
- let targetPath;
116
-
117
- if (edge.isOwnerNode(dependencyNode)) {
118
- sourcePath = edge.refOwnerDataPath;
119
- targetPath = edge.refRelatedDataPath;
120
- } else {
121
- targetPath = edge.refOwnerDataPath;
122
- sourcePath = edge.refRelatedDataPath;
123
- }
124
-
125
- const sourceValue = get(dependencyNode.obj, sourcePath);
126
- const targetValue = get(dependentNode.obj, targetPath);
127
-
128
- if (targetValue === edge.refMatch) {
129
- set(dependentNode.obj, targetPath, sourceValue);
130
- } else {
131
- set(dependentNode.obj, targetPath, targetValue.replace(edge.refMatch, sourceValue));
132
- }
133
- }
134
-
135
- _omitManyToManyExtraProps(nodes) {
136
- for (const node of nodes) {
137
- if (
138
- node.parentEdge &&
139
- node.parentEdge.type === ModelGraphEdge.Type.Relation &&
140
- node.parentEdge.relation.joinTableExtras.length > 0
141
- ) {
142
- node.parentEdge.relation.omitExtraProps([node.obj]);
143
- }
144
- }
145
- }
146
-
147
- _copyRelationPropsFromCurrentIfNeeded(nodes) {
148
- for (const node of nodes) {
149
- const currentNode = this.currentGraph.nodeForNode(node);
150
-
151
- if (!currentNode) {
152
- continue;
153
- }
154
-
155
- for (const edge of node.edges) {
156
- if (edge.type !== ModelGraphEdge.Type.Relation) {
157
- continue;
158
- }
159
-
160
- const prop = edge.isOwnerNode(node) ? edge.relation.ownerProp : edge.relation.relatedProp;
161
-
162
- prop.forEach((i) => {
163
- const value = prop.getProp(node.obj, i);
164
-
165
- if (value !== undefined) {
166
- return;
167
- }
168
-
169
- prop.setProp(node.obj, i, prop.getProp(currentNode.obj, i));
170
- });
171
- }
172
- }
173
- }
174
-
175
- _insert(parentBuilder, nodes) {
176
- const [{ modelClass }] = nodes;
177
-
178
- nodes = nodes.filter((node) => {
179
- return this.graphOptions.shouldInsert(node, this.graphData);
180
- });
181
-
182
- for (const node of nodes) {
183
- delete node.obj[modelClass.uidProp];
184
- delete node.obj[modelClass.graphUnrelateProp];
185
- delete node.obj[modelClass.graphDeleteProp];
186
- node.obj.$validate(null, { dataPath: node.dataPathKey });
187
- }
188
-
189
- if (nodes.length === 0) {
190
- return;
191
- }
192
-
193
- for (const node of nodes) {
194
- node.userData.inserted = true;
195
- }
196
-
197
- return this._runRelationBeforeInsertMethods(parentBuilder, nodes).then(() => {
198
- return modelClass
199
- .query()
200
- .insert(nodes.map((node) => node.obj))
201
- .childQueryOf(parentBuilder)
202
- .copyFrom(parentBuilder, GraphAction.ReturningAllSelector)
203
- .execute();
204
- });
205
- }
206
-
207
- _runRelationBeforeInsertMethods(parentBuilder, nodes) {
208
- return Promise.all(
209
- nodes.map((node) => {
210
- if (node.parentEdge) {
211
- return node.parentEdge.relation.beforeInsert(
212
- node.obj,
213
- parentBuilder.context(),
214
- node.parentNode.obj,
215
- );
216
- } else {
217
- return null;
218
- }
219
- }),
220
- );
221
- }
222
-
223
- _afterInsert(nodes) {
224
- for (const node of nodes) {
225
- for (const refNode of node.referencingNodes) {
226
- this._resolveDependency(refNode, refNode.parentEdge);
227
- }
228
- }
229
- }
230
- }
231
-
232
- function getModelClass(node) {
233
- return node.modelClass;
234
- }
235
-
236
- module.exports = {
237
- GraphInsertAction,
238
- };
@@ -1,92 +0,0 @@
1
- 'use strict';
2
-
3
- const { GraphAction } = require('../GraphAction');
4
- const { groupBy, chunk } = require('../../../utils/objectUtils');
5
- const promiseUtils = require('../../../utils/promiseUtils');
6
-
7
- class JoinRowGraphInsertAction extends GraphAction {
8
- constructor(graphData, { nodes }) {
9
- super(graphData);
10
- this.nodes = nodes;
11
- }
12
-
13
- run(builder) {
14
- const batches = this._createInsertBatches(builder);
15
- const concurrency = this._getConcurrency(builder, this.nodes);
16
-
17
- return promiseUtils.map(batches, (batch) => this._insertBatch(builder, batch), { concurrency });
18
- }
19
-
20
- _createInsertBatches(builder) {
21
- const batches = [];
22
- const batchSize = this._getBatchSize(builder);
23
- const nodesByModel = groupBy(this.nodes, (node) => getJoinTableModel(builder, node));
24
-
25
- for (const [joinTableModelClass, nodes] of nodesByModel.entries()) {
26
- for (const nodeBatch of chunk(nodes, batchSize)) {
27
- batches.push(this._createBatch(joinTableModelClass, nodeBatch));
28
- }
29
- }
30
-
31
- return batches;
32
- }
33
-
34
- _createBatch(joinTableModelClass, nodes) {
35
- return nodes
36
- .filter((node) => {
37
- return this.graphOptions.shouldRelate(node, this.graphData) || node.userData.inserted;
38
- })
39
- .map((node) => ({
40
- node,
41
- joinTableModelClass,
42
- joinTableObj: this._createJoinTableObj(joinTableModelClass, node),
43
- }));
44
- }
45
-
46
- _createJoinTableObj(joinTableModelClass, node) {
47
- const { parentEdge, parentNode } = node;
48
- const { relation } = parentEdge;
49
-
50
- this._resolveReferences(node);
51
-
52
- return joinTableModelClass.fromJson(
53
- relation.createJoinModel(relation.ownerProp.getProps(parentNode.obj), node.obj),
54
- );
55
- }
56
-
57
- _insertBatch(parentBuilder, batch) {
58
- return this._beforeInsert(parentBuilder, batch).then(() => this._insert(parentBuilder, batch));
59
- }
60
-
61
- _beforeInsert(parentBuilder, batch) {
62
- return Promise.all(
63
- batch.map(({ node, joinTableObj }) => {
64
- if (node.parentEdge) {
65
- return node.parentEdge.relation.joinTableBeforeInsert(
66
- joinTableObj,
67
- parentBuilder.context(),
68
- );
69
- } else {
70
- return null;
71
- }
72
- }),
73
- );
74
- }
75
-
76
- _insert(parentBuilder, batch) {
77
- if (batch.length > 0) {
78
- return batch[0].joinTableModelClass
79
- .query()
80
- .childQueryOf(parentBuilder)
81
- .insert(batch.map((it) => it.joinTableObj));
82
- }
83
- }
84
- }
85
-
86
- function getJoinTableModel(builder, node) {
87
- return node.parentEdge.relation.getJoinModelClass(builder.unsafeKnex());
88
- }
89
-
90
- module.exports = {
91
- JoinRowGraphInsertAction,
92
- };
@@ -1,20 +0,0 @@
1
- 'use strict';
2
-
3
- const { GraphOperation } = require('../GraphOperation');
4
- const { GraphPatchAction } = require('./GraphPatchAction');
5
-
6
- class GraphPatch extends GraphOperation {
7
- createActions() {
8
- return [
9
- new GraphPatchAction(this.graphData, {
10
- nodes: this.graph.nodes.filter((node) =>
11
- this.graphOptions.shouldPatchOrUpdateIgnoreDisable(node, this.graphData),
12
- ),
13
- }),
14
- ];
15
- }
16
- }
17
-
18
- module.exports = {
19
- GraphPatch,
20
- };