@abedmurrar/objection 4.0.0-alpha.0 → 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +279 -363
  129. package/lib/relations/RelationDeleteOperation.js +16 -22
  130. package/lib/relations/RelationFindOperation.js +100 -133
  131. package/lib/relations/RelationInsertOperation.js +19 -27
  132. package/lib/relations/RelationOwner.js +167 -204
  133. package/lib/relations/RelationProperty.js +177 -217
  134. package/lib/relations/RelationUpdateOperation.js +16 -23
  135. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +11 -16
  136. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +24 -35
  137. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +30 -41
  138. package/lib/relations/belongsToOne/BelongsToOneRelation.js +33 -41
  139. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +38 -53
  140. package/lib/relations/hasMany/HasManyInsertOperation.js +35 -51
  141. package/lib/relations/hasMany/HasManyRelateOperation.js +38 -54
  142. package/lib/relations/hasMany/HasManyRelation.js +30 -38
  143. package/lib/relations/hasMany/HasManyUnrelateOperation.js +19 -26
  144. package/lib/relations/hasOne/HasOneRelation.js +4 -7
  145. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +4 -7
  146. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +67 -90
  147. package/lib/relations/manyToMany/ManyToManyRelation.js +349 -451
  148. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +19 -26
  149. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +3 -5
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +14 -20
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -7
  152. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +71 -94
  153. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +31 -43
  154. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +50 -67
  155. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +4 -7
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +20 -27
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +5 -10
  158. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +3 -5
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +55 -72
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -7
  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,69 +1,54 @@
1
1
  'use strict';
2
-
3
2
  const { isPostgres } = require('../../utils/knexUtils');
4
-
5
3
  const POSTGRES_MAX_INSERT_BATCH_SIZE = 100;
6
4
  const MAX_CONCURRENCY = 100;
7
-
8
5
  class GraphAction {
9
- constructor(graphData) {
10
- this.graphData = graphData;
11
- }
12
-
13
- static get ReturningAllSelector() {
14
- return (op) => {
15
- // Only select `returning('*')` operation.
16
- return op.name === 'returning' && op.args.includes('*');
17
- };
18
- }
19
-
20
- static getConcurrency(builder, nodes) {
21
- return nodes.reduce((minConcurrency, node) => {
22
- return Math.min(minConcurrency, node.modelClass.getConcurrency(builder.unsafeKnex()));
23
- }, MAX_CONCURRENCY);
24
- }
25
-
26
- get graph() {
27
- return this.graphData.graph;
28
- }
29
-
30
- get currentGraph() {
31
- return this.graphData.currentGraph;
32
- }
33
-
34
- get graphOptions() {
35
- return this.graphData.graphOptions;
36
- }
37
-
38
- run(builder) {
39
- return null;
40
- }
41
-
42
- _getConcurrency(builder, nodes) {
43
- return GraphAction.getConcurrency(builder, nodes);
44
- }
45
-
46
- _getBatchSize(builder) {
47
- return isPostgres(builder.unsafeKnex()) ? POSTGRES_MAX_INSERT_BATCH_SIZE : 1;
48
- }
49
-
50
- _resolveReferences(node) {
51
- if (node.isReference) {
52
- this._resolveReference(node);
6
+ constructor(graphData) {
7
+ this.graphData = graphData;
53
8
  }
54
- }
55
-
56
- _resolveReference(node) {
57
- const refNode = node.referencedNode;
58
-
59
- for (const prop of Object.keys(refNode.obj)) {
60
- if (!node.obj.hasOwnProperty(prop)) {
61
- node.obj[prop] = refNode.obj[prop];
62
- }
9
+ static get ReturningAllSelector() {
10
+ return (op) => {
11
+ // Only select `returning('*')` operation.
12
+ return op.name === 'returning' && op.args.includes('*');
13
+ };
14
+ }
15
+ static getConcurrency(builder, nodes) {
16
+ return nodes.reduce((minConcurrency, node) => {
17
+ return Math.min(minConcurrency, node.modelClass.getConcurrency(builder.unsafeKnex()));
18
+ }, MAX_CONCURRENCY);
19
+ }
20
+ get graph() {
21
+ return this.graphData.graph;
22
+ }
23
+ get currentGraph() {
24
+ return this.graphData.currentGraph;
25
+ }
26
+ get graphOptions() {
27
+ return this.graphData.graphOptions;
28
+ }
29
+ run(builder) {
30
+ return null;
31
+ }
32
+ _getConcurrency(builder, nodes) {
33
+ return GraphAction.getConcurrency(builder, nodes);
34
+ }
35
+ _getBatchSize(builder) {
36
+ return isPostgres(builder.unsafeKnex()) ? POSTGRES_MAX_INSERT_BATCH_SIZE : 1;
37
+ }
38
+ _resolveReferences(node) {
39
+ if (node.isReference) {
40
+ this._resolveReference(node);
41
+ }
42
+ }
43
+ _resolveReference(node) {
44
+ const refNode = node.referencedNode;
45
+ for (const prop of Object.keys(refNode.obj)) {
46
+ if (!Object.hasOwn(node.obj, prop)) {
47
+ node.obj[prop] = refNode.obj[prop];
48
+ }
49
+ }
63
50
  }
64
- }
65
51
  }
66
-
67
52
  module.exports = {
68
- GraphAction,
53
+ GraphAction,
69
54
  };
@@ -1,14 +1,12 @@
1
1
  'use strict';
2
-
3
2
  class GraphData {
4
- constructor({ graph, currentGraph, graphOptions, nodeDbExistence }) {
5
- this.graph = graph;
6
- this.currentGraph = currentGraph;
7
- this.graphOptions = graphOptions;
8
- this.nodeDbExistence = nodeDbExistence;
9
- }
3
+ constructor({ graph, currentGraph, graphOptions, nodeDbExistence }) {
4
+ this.graph = graph;
5
+ this.currentGraph = currentGraph;
6
+ this.graphOptions = graphOptions;
7
+ this.nodeDbExistence = nodeDbExistence;
8
+ }
10
9
  }
11
-
12
10
  module.exports = {
13
- GraphData,
11
+ GraphData,
14
12
  };
@@ -1,191 +1,155 @@
1
1
  'use strict';
2
-
3
2
  const { asArray, groupBy } = require('../../utils/objectUtils');
4
3
  const { ModelGraph } = require('../../model/graph/ModelGraph');
5
4
  const { FetchStrategy } = require('./GraphOptions');
6
5
  const { RelationExpression } = require('../RelationExpression');
7
-
8
6
  class GraphFetcher {
9
- /**
10
- * Given a graph and options, fetches the current state of that graph
11
- * from the database and returns it as a ModelGraph instance.
12
- */
13
- static async fetchCurrentGraph({ builder, graph, graphOptions }) {
14
- const { rootObjects } = graph;
15
-
16
- const rootIds = getRootIds(rootObjects);
17
- const modelClass = builder.modelClass();
18
-
19
- if (rootIds.length === 0) {
20
- return Promise.resolve(ModelGraph.create(modelClass, []));
7
+ /**
8
+ * Given a graph and options, fetches the current state of that graph
9
+ * from the database and returns it as a ModelGraph instance.
10
+ */
11
+ static async fetchCurrentGraph({ builder, graph, graphOptions }) {
12
+ const { rootObjects } = graph;
13
+ const rootIds = getRootIds(rootObjects);
14
+ const modelClass = builder.modelClass();
15
+ if (rootIds.length === 0) {
16
+ return Promise.resolve(ModelGraph.create(modelClass, []));
17
+ }
18
+ const eagerExpr = RelationExpression.fromModelGraph(rootObjects);
19
+ const models = await modelClass
20
+ .query()
21
+ .childQueryOf(builder, childQueryOptions())
22
+ .modify(propagateMethodCallsFromQuery(builder))
23
+ .modify(buildFetchQuerySelects(graph, graphOptions, eagerExpr))
24
+ .findByIds(rootIds)
25
+ .withGraphFetched(eagerExpr)
26
+ .internalOptions(fetchQueryInternalOptions());
27
+ return ModelGraph.create(modelClass, models);
21
28
  }
22
-
23
- const eagerExpr = RelationExpression.fromModelGraph(rootObjects);
24
- const models = await modelClass
25
- .query()
26
- .childQueryOf(builder, childQueryOptions())
27
- .modify(propagateMethodCallsFromQuery(builder))
28
- .modify(buildFetchQuerySelects(graph, graphOptions, eagerExpr))
29
- .findByIds(rootIds)
30
- .withGraphFetched(eagerExpr)
31
- .internalOptions(fetchQueryInternalOptions());
32
-
33
- return ModelGraph.create(modelClass, models);
34
- }
35
29
  }
36
-
37
30
  function getRootIds(rootObjects) {
38
- return asArray(rootObjects)
39
- .filter((it) => it.$hasId())
40
- .map((root) => root.$id());
31
+ return asArray(rootObjects)
32
+ .filter((it) => it.$hasId())
33
+ .map((root) => root.$id());
41
34
  }
42
-
43
35
  function propagateMethodCallsFromQuery(builder) {
44
- return (fetchBuilder) => {
45
- // Propagate some method calls from the root query.
46
- for (const method of ['forUpdate', 'forShare', 'forNoKeyUpdate', 'forKeyShare']) {
47
- if (builder.has(method)) {
48
- fetchBuilder[method]();
49
- }
50
- }
51
- };
36
+ return (fetchBuilder) => {
37
+ // Propagate some method calls from the root query.
38
+ for (const method of ['forUpdate', 'forShare', 'forNoKeyUpdate', 'forKeyShare']) {
39
+ if (builder.has(method)) {
40
+ fetchBuilder[method]();
41
+ }
42
+ }
43
+ };
52
44
  }
53
-
54
45
  function buildFetchQuerySelects(graph, graphOptions, eagerExpr) {
55
- return (builder) => {
56
- const nodesByRelationPath = groupNodesByRelationPath(graph, eagerExpr);
57
-
58
- for (const [relationPath, nodes] of nodesByRelationPath.entries()) {
59
- const selectModifier = createFetchSelectModifier(nodes, graphOptions);
60
-
61
- if (!relationPath) {
62
- builder.modify(selectModifier);
63
- } else {
64
- builder.modifyGraph(relationPath, selectModifier);
65
- }
66
- }
67
- };
46
+ return (builder) => {
47
+ const nodesByRelationPath = groupNodesByRelationPath(graph, eagerExpr);
48
+ for (const [relationPath, nodes] of nodesByRelationPath.entries()) {
49
+ const selectModifier = createFetchSelectModifier(nodes, graphOptions);
50
+ if (!relationPath) {
51
+ builder.modify(selectModifier);
52
+ }
53
+ else {
54
+ builder.modifyGraph(relationPath, selectModifier);
55
+ }
56
+ }
57
+ };
68
58
  }
69
-
70
59
  function groupNodesByRelationPath(graph, eagerExpr) {
71
- const nodesByRelationPath = groupBy(graph.nodes, (node) => node.relationPathKey);
72
-
73
- // Not all relation paths have nodes. Relations with nulls or empty arrays
74
- // don't have nodes, but will still need to be fetched. Add these to the
75
- // map as empty arrays.
76
- forEachPath(eagerExpr.node, (relationPath) => {
77
- if (!nodesByRelationPath.has(relationPath)) {
78
- nodesByRelationPath.set(relationPath, []);
79
- }
80
- });
81
-
82
- return nodesByRelationPath;
60
+ const nodesByRelationPath = groupBy(graph.nodes, (node) => node.relationPathKey);
61
+ // Not all relation paths have nodes. Relations with nulls or empty arrays
62
+ // don't have nodes, but will still need to be fetched. Add these to the
63
+ // map as empty arrays.
64
+ forEachPath(eagerExpr.node, (relationPath) => {
65
+ if (!nodesByRelationPath.has(relationPath)) {
66
+ nodesByRelationPath.set(relationPath, []);
67
+ }
68
+ });
69
+ return nodesByRelationPath;
83
70
  }
84
-
85
71
  function createFetchSelectModifier(nodes, graphOptions) {
86
- if (graphOptions.isFetchStrategy(FetchStrategy.OnlyIdentifiers)) {
87
- return createIdentifierSelector();
88
- } else if (graphOptions.isFetchStrategy(FetchStrategy.OnlyNeeded)) {
89
- return createInputColumnSelector(nodes);
90
- } else {
91
- return () => {};
92
- }
72
+ if (graphOptions.isFetchStrategy(FetchStrategy.OnlyIdentifiers)) {
73
+ return createIdentifierSelector();
74
+ }
75
+ else if (graphOptions.isFetchStrategy(FetchStrategy.OnlyNeeded)) {
76
+ return createInputColumnSelector(nodes);
77
+ }
78
+ else {
79
+ return () => { };
80
+ }
93
81
  }
94
-
95
82
  // Returns a function that only selects the id column.
96
83
  function createIdentifierSelector() {
97
- return (builder) => {
98
- builder.select(builder.fullIdColumn());
99
- };
84
+ return (builder) => {
85
+ builder.select(builder.fullIdColumn());
86
+ };
100
87
  }
101
-
102
88
  // Returns a function that only selects the columns that exist in the input.
103
89
  function createInputColumnSelector(nodes) {
104
- return (builder) => {
105
- const selects = new Map();
106
-
107
- for (const node of nodes) {
108
- const databaseJson = node.obj.$toDatabaseJson(builder);
109
-
110
- for (const column of Object.keys(databaseJson)) {
111
- if (!shouldSelectColumn(column, selects, node)) {
112
- continue;
90
+ return (builder) => {
91
+ const selects = new Map();
92
+ for (const node of nodes) {
93
+ const databaseJson = node.obj.$toDatabaseJson(builder);
94
+ for (const column of Object.keys(databaseJson)) {
95
+ if (!shouldSelectColumn(column, selects, node)) {
96
+ continue;
97
+ }
98
+ const selection = createManyToManyExtraSelectionIfNeeded(builder, column, node) ||
99
+ createSelection(builder, column, node);
100
+ selects.set(column, selection);
101
+ }
113
102
  }
114
-
115
- const selection =
116
- createManyToManyExtraSelectionIfNeeded(builder, column, node) ||
117
- createSelection(builder, column, node);
118
-
119
- selects.set(column, selection);
120
- }
121
- }
122
-
123
- const selectArr = Array.from(selects.values());
124
- const idColumns = asArray(builder.fullIdColumn());
125
-
126
- for (const idColumn of idColumns) {
127
- if (!selectArr.includes(idColumn)) {
128
- // Always select the identifers.
129
- selectArr.push(idColumn);
130
- }
131
- }
132
-
133
- builder.select(selectArr);
134
- };
103
+ const selectArr = Array.from(selects.values());
104
+ const idColumns = asArray(builder.fullIdColumn());
105
+ for (const idColumn of idColumns) {
106
+ if (!selectArr.includes(idColumn)) {
107
+ // Always select the identifers.
108
+ selectArr.push(idColumn);
109
+ }
110
+ }
111
+ builder.select(selectArr);
112
+ };
135
113
  }
136
-
137
114
  function shouldSelectColumn(column, selects, node) {
138
- const modelClass = node.modelClass;
139
-
140
- return (
141
- !selects.has(column) &&
142
- column !== modelClass.propertyNameToColumnName(modelClass.dbRefProp) &&
143
- column !== modelClass.propertyNameToColumnName(modelClass.uidRefProp) &&
144
- column !== modelClass.propertyNameToColumnName(modelClass.uidProp)
145
- );
115
+ const modelClass = node.modelClass;
116
+ return (!selects.has(column) &&
117
+ column !== modelClass.propertyNameToColumnName(modelClass.dbRefProp) &&
118
+ column !== modelClass.propertyNameToColumnName(modelClass.uidRefProp) &&
119
+ column !== modelClass.propertyNameToColumnName(modelClass.uidProp));
146
120
  }
147
-
148
121
  function createManyToManyExtraSelectionIfNeeded(builder, column, node) {
149
- if (node.parentEdge && node.parentEdge.relation.isObjectionManyToManyRelation) {
150
- const relation = node.parentEdge.relation;
151
- const extra = relation.joinTableExtras.find((extra) => extra.aliasCol === column);
152
-
153
- if (extra) {
154
- return `${builder.tableRefFor(relation.joinModelClass)}.${extra.joinTableCol} as ${
155
- extra.aliasCol
156
- }`;
122
+ if (node.parentEdge && node.parentEdge.relation.isObjectionManyToManyRelation) {
123
+ const relation = node.parentEdge.relation;
124
+ const extra = relation.joinTableExtras.find((extra) => extra.aliasCol === column);
125
+ if (extra) {
126
+ return `${builder.tableRefFor(relation.joinModelClass)}.${extra.joinTableCol} as ${extra.aliasCol}`;
127
+ }
157
128
  }
158
- }
159
-
160
- return null;
129
+ return null;
161
130
  }
162
-
163
131
  function createSelection(builder, column, node) {
164
- return `${builder.tableRefFor(node.modelClass)}.${column}`;
132
+ return `${builder.tableRefFor(node.modelClass)}.${column}`;
165
133
  }
166
-
167
134
  function childQueryOptions() {
168
- return {
169
- fork: true,
170
- isInternalQuery: true,
171
- };
135
+ return {
136
+ fork: true,
137
+ isInternalQuery: true,
138
+ };
172
139
  }
173
-
174
140
  function fetchQueryInternalOptions() {
175
- return {
176
- keepImplicitJoinProps: true,
177
- };
141
+ return {
142
+ keepImplicitJoinProps: true,
143
+ };
178
144
  }
179
-
180
145
  function forEachPath(eagerExprNode, cb, path = []) {
181
- for (const relation of eagerExprNode.$childNames) {
182
- path.push(relation);
183
- cb(path.join('.'));
184
- forEachPath(eagerExprNode[relation], cb, path);
185
- path.pop();
186
- }
146
+ for (const relation of eagerExprNode.$childNames) {
147
+ path.push(relation);
148
+ cb(path.join('.'));
149
+ forEachPath(eagerExprNode[relation], cb, path);
150
+ path.pop();
151
+ }
187
152
  }
188
-
189
153
  module.exports = {
190
- GraphFetcher,
154
+ GraphFetcher,
191
155
  };