@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,7 +1,5 @@
1
1
  'use strict';
2
-
3
2
  const promiseUtils = require('../../../utils/promiseUtils');
4
-
5
3
  const { EagerOperation } = require('./EagerOperation');
6
4
  const { isMsSql, isOracle, isSqlite } = require('../../../utils/knexUtils');
7
5
  const { isObject, asArray, flatten, chunk } = require('../../../utils/objectUtils');
@@ -9,277 +7,221 @@ const { ValidationErrorType } = require('../../../model/ValidationError');
9
7
  const { createModifier } = require('../../../utils/createModifier');
10
8
  const { RelationDoesNotExistError } = require('../../../model/RelationDoesNotExistError');
11
9
  const { RelationOwner } = require('../../../relations/RelationOwner');
12
-
10
+ const { getReadConcurrency } = require('../../../model/modelConcurrency');
13
11
  class WhereInEagerOperation extends EagerOperation {
14
- constructor(name, opt) {
15
- super(name, opt);
16
-
17
- this.relationsToFetch = [];
18
- this.omitProps = [];
19
- }
20
-
21
- batchSize(knex) {
22
- if (this.graphOptions.maxBatchSize) {
23
- return this.graphOptions.maxBatchSize;
24
- } else if (isMsSql(knex)) {
25
- // On MSSQL the parameter limit is actually 2100, but since I couldn't figure out
26
- // if the limit is for all parameters in a query or for individual clauses, we set
27
- // the limit to 2000 to leave 100 parameters for where clauses etc.
28
- return 2000;
29
- } else if (isOracle(knex)) {
30
- return 1000;
31
- } else if (isSqlite(knex)) {
32
- // SQLITE_MAX_VARIABLE_NUMBER is 999 by default
33
- return 999;
34
- } else {
35
- // I'm sure there is some kind of limit for other databases too, but let's lower
36
- // this if someone ever hits those limits.
37
- return 10000;
12
+ constructor(name, opt) {
13
+ super(name, opt);
14
+ this.relationsToFetch = [];
15
+ this.omitProps = [];
38
16
  }
39
- }
40
-
41
- onBuild(builder) {
42
- const relationsToFetch = findRelationsToFetch(
43
- builder.modelClass(),
44
- this.buildFinalExpression(),
45
- );
46
-
47
- const { selectionsToAdd, selectedProps } = findRelationPropsToSelect(builder, relationsToFetch);
48
-
49
- if (selectionsToAdd.length) {
50
- builder.select(selectionsToAdd);
51
- }
52
-
53
- this.relationsToFetch = relationsToFetch;
54
- this.omitProps = selectedProps;
55
- }
56
-
57
- async onAfter2(builder, result) {
58
- const modelClass = builder.resultModelClass();
59
-
60
- if (!result) {
61
- return result;
17
+ batchSize(knex) {
18
+ if (this.graphOptions.maxBatchSize) {
19
+ return this.graphOptions.maxBatchSize;
20
+ }
21
+ else if (isMsSql(knex)) {
22
+ // On MSSQL the parameter limit is actually 2100, but since I couldn't figure out
23
+ // if the limit is for all parameters in a query or for individual clauses, we set
24
+ // the limit to 2000 to leave 100 parameters for where clauses etc.
25
+ return 2000;
26
+ }
27
+ else if (isOracle(knex)) {
28
+ return 1000;
29
+ }
30
+ else if (isSqlite(knex)) {
31
+ // SQLITE_MAX_VARIABLE_NUMBER is 999 by default
32
+ return 999;
33
+ }
34
+ else {
35
+ // I'm sure there is some kind of limit for other databases too, but let's lower
36
+ // this if someone ever hits those limits.
37
+ return 10000;
38
+ }
62
39
  }
63
-
64
- const models = asArray(result);
65
-
66
- // Check models to be actual objects, to filter out `count` results (#2397).
67
- if (!models.length || !isObject(models[0])) {
68
- return result;
40
+ onBuild(builder) {
41
+ const relationsToFetch = findRelationsToFetch(builder.modelClass(), this.buildFinalExpression());
42
+ const { selectionsToAdd, selectedProps } = findRelationPropsToSelect(builder, relationsToFetch);
43
+ if (selectionsToAdd.length) {
44
+ builder.select(selectionsToAdd);
45
+ }
46
+ this.relationsToFetch = relationsToFetch;
47
+ this.omitProps = selectedProps;
69
48
  }
70
-
71
- await promiseUtils.map(
72
- this.relationsToFetch,
73
- (it) => this.fetchRelation(builder, models, it.relation, it.childExpression),
74
- { concurrency: modelClass.getConcurrency(builder.unsafeKnex()) },
75
- );
76
-
77
- const intOpt = builder.internalOptions();
78
-
79
- if (!this.omitProps.length || intOpt.keepImplicitJoinProps) {
80
- return result;
49
+ async onAfter2(builder, result) {
50
+ const modelClass = builder.resultModelClass();
51
+ if (!result) {
52
+ return result;
53
+ }
54
+ const models = asArray(result);
55
+ // Check models to be actual objects, to filter out `count` results (#2397).
56
+ if (!models.length || !isObject(models[0])) {
57
+ return result;
58
+ }
59
+ await promiseUtils.map(this.relationsToFetch, (it) => this.fetchRelation(builder, models, it.relation, it.childExpression), { concurrency: getReadConcurrency(modelClass, builder.unsafeKnex()) });
60
+ const intOpt = builder.internalOptions();
61
+ if (!this.omitProps.length || intOpt.keepImplicitJoinProps) {
62
+ return result;
63
+ }
64
+ // Now that relations have been fetched for `models` we can omit the
65
+ // columns that were implicitly selected by this class.
66
+ for (let i = 0, l = result.length; i < l; ++i) {
67
+ const model = result[i];
68
+ for (let c = 0, lc = this.omitProps.length; c < lc; ++c) {
69
+ modelClass.omitImpl(model, this.omitProps[c]);
70
+ }
71
+ }
72
+ return result;
81
73
  }
82
-
83
- // Now that relations have been fetched for `models` we can omit the
84
- // columns that were implicitly selected by this class.
85
- for (let i = 0, l = result.length; i < l; ++i) {
86
- const model = result[i];
87
-
88
- for (let c = 0, lc = this.omitProps.length; c < lc; ++c) {
89
- modelClass.omitImpl(model, this.omitProps[c]);
90
- }
74
+ async fetchRelation(builder, models, relation, expr) {
75
+ const modelClass = builder.resultModelClass();
76
+ const batchSize = this.batchSize(builder.knex());
77
+ const modelBatches = chunk(models, batchSize);
78
+ const result = await promiseUtils.map(modelBatches, (batch) => this.fetchRelationBatch(builder, batch, relation, expr), {
79
+ concurrency: getReadConcurrency(modelClass, builder.unsafeKnex()),
80
+ });
81
+ return flatten(result);
91
82
  }
92
-
93
- return result;
94
- }
95
-
96
- async fetchRelation(builder, models, relation, expr) {
97
- const modelClass = builder.resultModelClass();
98
- const batchSize = this.batchSize(builder.knex());
99
- const modelBatches = chunk(models, batchSize);
100
-
101
- const result = await promiseUtils.map(
102
- modelBatches,
103
- (batch) => this.fetchRelationBatch(builder, batch, relation, expr),
104
- {
105
- concurrency: modelClass.getConcurrency(builder.unsafeKnex()),
106
- },
107
- );
108
-
109
- return flatten(result);
110
- }
111
-
112
- fetchRelationBatch(builder, models, relation, expr) {
113
- if (this.shouldSkipFetched(models, relation, expr)) {
114
- return this.createSkippedQuery(builder, models, relation, expr);
83
+ fetchRelationBatch(builder, models, relation, expr) {
84
+ if (this.shouldSkipFetched(models, relation, expr)) {
85
+ return this.createSkippedQuery(builder, models, relation, expr);
86
+ }
87
+ const queryBuilder = this.createRelationQuery(builder, relation, expr);
88
+ const findOperation = relation.find(queryBuilder, RelationOwner.create(models));
89
+ findOperation.alwaysReturnArray = true;
90
+ findOperation.assignResultToOwner = true;
91
+ findOperation.relationProperty = expr.node.$name;
92
+ queryBuilder.addOperation(findOperation, []);
93
+ for (const modifierName of expr.node.$modify) {
94
+ const modifier = createModifier({
95
+ modifier: modifierName,
96
+ modelClass: relation.relatedModelClass,
97
+ modifiers: this.buildFinalModifiers(builder),
98
+ });
99
+ try {
100
+ modifier(queryBuilder);
101
+ }
102
+ catch (err) {
103
+ const modelClass = builder.modelClass();
104
+ if (err instanceof modelClass.ModifierNotFoundError) {
105
+ throw modelClass.createValidationError({
106
+ type: ValidationErrorType.RelationExpression,
107
+ message: `could not find modifier "${modifierName}" for relation "${relation.name}"`,
108
+ });
109
+ }
110
+ else {
111
+ throw err;
112
+ }
113
+ }
114
+ }
115
+ return queryBuilder;
115
116
  }
116
-
117
- const queryBuilder = this.createRelationQuery(builder, relation, expr);
118
- const findOperation = relation.find(queryBuilder, RelationOwner.create(models));
119
-
120
- findOperation.alwaysReturnArray = true;
121
- findOperation.assignResultToOwner = true;
122
- findOperation.relationProperty = expr.node.$name;
123
-
124
- queryBuilder.addOperation(findOperation, []);
125
-
126
- for (const modifierName of expr.node.$modify) {
127
- const modifier = createModifier({
128
- modifier: modifierName,
129
- modelClass: relation.relatedModelClass,
130
- modifiers: this.buildFinalModifiers(builder),
131
- });
132
-
133
- try {
134
- modifier(queryBuilder);
135
- } catch (err) {
136
- const modelClass = builder.modelClass();
137
-
138
- if (err instanceof modelClass.ModifierNotFoundError) {
139
- throw modelClass.createValidationError({
140
- type: ValidationErrorType.RelationExpression,
141
- message: `could not find modifier "${modifierName}" for relation "${relation.name}"`,
142
- });
143
- } else {
144
- throw err;
117
+ shouldSkipFetched(models, relation, expr) {
118
+ if (!this.graphOptions.skipFetched) {
119
+ return false;
120
+ }
121
+ if (models.some((it) => it[expr.node.$name] === undefined)) {
122
+ return false;
123
+ }
124
+ const relationsToFetch = findRelationsToFetch(relation.relatedModelClass, expr);
125
+ const childModels = getRelatedModels(models, expr);
126
+ // We can only skip fetching a relation if all already fetched models
127
+ // have all needed relation properties so that we can fetch the next
128
+ // level of relations.
129
+ for (const { relation } of relationsToFetch) {
130
+ const { ownerProp } = relation;
131
+ for (let c = 0, lc = ownerProp.size; c < lc; ++c) {
132
+ const prop = ownerProp.props[c];
133
+ for (const model of childModels) {
134
+ if (model[prop] === undefined) {
135
+ return false;
136
+ }
137
+ }
138
+ }
145
139
  }
146
- }
140
+ return true;
147
141
  }
148
-
149
- return queryBuilder;
150
- }
151
-
152
- shouldSkipFetched(models, relation, expr) {
153
- if (!this.graphOptions.skipFetched) {
154
- return false;
142
+ createSkippedQuery(builder, models, relation, expr) {
143
+ const childModels = getRelatedModels(models, expr);
144
+ return relation.relatedModelClass
145
+ .query()
146
+ .childQueryOf(builder)
147
+ .findOptions({ dontCallFindHooks: true })
148
+ .withGraphFetched(expr, this.graphOptions)
149
+ .resolve(childModels);
155
150
  }
156
-
157
- if (models.some((it) => it[expr.node.$name] === undefined)) {
158
- return false;
151
+ createRelationQuery(builder, relation, expr) {
152
+ return relation.relatedModelClass
153
+ .query()
154
+ .childQueryOf(builder)
155
+ .withGraphFetched(expr, this.graphOptions)
156
+ .modifiers(this.buildFinalModifiers(builder));
159
157
  }
160
-
161
- const relationsToFetch = findRelationsToFetch(relation.relatedModelClass, expr);
162
- const childModels = getRelatedModels(models, expr);
163
-
164
- // We can only skip fetching a relation if all already fetched models
165
- // have all needed relation properties so that we can fetch the next
166
- // level of relations.
167
- for (const { relation } of relationsToFetch) {
168
- const { ownerProp } = relation;
169
-
170
- for (let c = 0, lc = ownerProp.size; c < lc; ++c) {
171
- const prop = ownerProp.props[c];
172
-
173
- for (const model of childModels) {
174
- if (model[prop] === undefined) {
175
- return false;
176
- }
177
- }
178
- }
158
+ clone() {
159
+ const clone = super.clone();
160
+ clone.relationsToFetch = this.relationsToFetch.slice();
161
+ clone.omitProps = this.omitProps.slice();
162
+ return clone;
179
163
  }
180
-
181
- return true;
182
- }
183
-
184
- createSkippedQuery(builder, models, relation, expr) {
185
- const childModels = getRelatedModels(models, expr);
186
-
187
- return relation.relatedModelClass
188
- .query()
189
- .childQueryOf(builder)
190
- .findOptions({ dontCallFindHooks: true })
191
- .withGraphFetched(expr, this.graphOptions)
192
- .resolve(childModels);
193
- }
194
-
195
- createRelationQuery(builder, relation, expr) {
196
- return relation.relatedModelClass
197
- .query()
198
- .childQueryOf(builder)
199
- .withGraphFetched(expr, this.graphOptions)
200
- .modifiers(this.buildFinalModifiers(builder));
201
- }
202
-
203
- clone() {
204
- const clone = super.clone();
205
-
206
- clone.relationsToFetch = this.relationsToFetch.slice();
207
- clone.omitProps = this.omitProps.slice();
208
-
209
- return clone;
210
- }
211
164
  }
212
-
213
165
  function findRelationsToFetch(modelClass, eagerExpression) {
214
- const relationsToFetch = [];
215
-
216
- try {
217
- eagerExpression.forEachChildExpression(modelClass, (childExpression, relation) => {
218
- relationsToFetch.push({
219
- childExpression,
220
- relation,
221
- });
222
- });
223
- } catch (err) {
224
- if (err instanceof RelationDoesNotExistError) {
225
- throw modelClass.createValidationError({
226
- type: ValidationErrorType.RelationExpression,
227
- message: `unknown relation "${err.relationName}" in an eager expression`,
228
- });
166
+ const relationsToFetch = [];
167
+ try {
168
+ eagerExpression.forEachChildExpression(modelClass, (childExpression, relation) => {
169
+ relationsToFetch.push({
170
+ childExpression,
171
+ relation,
172
+ });
173
+ });
174
+ }
175
+ catch (err) {
176
+ if (err instanceof RelationDoesNotExistError) {
177
+ throw modelClass.createValidationError({
178
+ type: ValidationErrorType.RelationExpression,
179
+ message: `unknown relation "${err.relationName}" in an eager expression`,
180
+ });
181
+ }
182
+ throw err;
229
183
  }
230
- throw err;
231
- }
232
-
233
- return relationsToFetch;
184
+ return relationsToFetch;
234
185
  }
235
-
236
186
  function findRelationPropsToSelect(builder, relationsToFetch) {
237
- const selectionsToAdd = [];
238
- const selectedProps = [];
239
-
240
- // Collect columns that need to be selected for the eager fetch
241
- // to work that are not currently selected.
242
- for (const { relation } of relationsToFetch) {
243
- const ownerProp = relation.ownerProp;
244
-
245
- for (let c = 0, lc = ownerProp.size; c < lc; ++c) {
246
- const fullCol = ownerProp.ref(builder, c).fullColumn(builder);
247
- const prop = ownerProp.props[c];
248
- const col = ownerProp.cols[c];
249
-
250
- if (!builder.hasSelectionAs(fullCol, col) && selectionsToAdd.indexOf(fullCol) === -1) {
251
- selectedProps.push(prop);
252
- selectionsToAdd.push(fullCol);
253
- }
187
+ const selectionsToAdd = [];
188
+ const selectedProps = [];
189
+ // Collect columns that need to be selected for the eager fetch
190
+ // to work that are not currently selected.
191
+ for (const { relation } of relationsToFetch) {
192
+ const ownerProp = relation.ownerProp;
193
+ for (let c = 0, lc = ownerProp.size; c < lc; ++c) {
194
+ const fullCol = ownerProp.ref(builder, c).fullColumn(builder);
195
+ const prop = ownerProp.props[c];
196
+ const col = ownerProp.cols[c];
197
+ if (!builder.hasSelectionAs(fullCol, col) && selectionsToAdd.indexOf(fullCol) === -1) {
198
+ selectedProps.push(prop);
199
+ selectionsToAdd.push(fullCol);
200
+ }
201
+ }
254
202
  }
255
- }
256
-
257
- return {
258
- selectionsToAdd,
259
- selectedProps,
260
- };
203
+ return {
204
+ selectionsToAdd,
205
+ selectedProps,
206
+ };
261
207
  }
262
-
263
208
  function getRelatedModels(models, expr) {
264
- const allRelated = [];
265
-
266
- for (const model of models) {
267
- const related = model[expr.node.$name];
268
-
269
- if (related) {
270
- if (Array.isArray(related)) {
271
- for (const rel of related) {
272
- allRelated.push(rel);
209
+ const allRelated = [];
210
+ for (const model of models) {
211
+ const related = model[expr.node.$name];
212
+ if (related) {
213
+ if (Array.isArray(related)) {
214
+ for (const rel of related) {
215
+ allRelated.push(rel);
216
+ }
217
+ }
218
+ else {
219
+ allRelated.push(related);
220
+ }
273
221
  }
274
- } else {
275
- allRelated.push(related);
276
- }
277
222
  }
278
- }
279
-
280
- return allRelated;
223
+ return allRelated;
281
224
  }
282
-
283
225
  module.exports = {
284
- WhereInEagerOperation,
226
+ WhereInEagerOperation,
285
227
  };
@@ -1,36 +1,29 @@
1
1
  'use strict';
2
-
3
2
  const postgresJsonApi = require('./postgresJsonApi');
4
3
  const mysqlJsonApi = require('./mysqlJsonApi');
5
4
  const { getJsonDialect } = require('../../../utils/postgresJsonPath');
5
+ const { jsonCastsForDialect } = require('../../../utils/mysqlJsonPath');
6
6
  const { ObjectionToKnexConvertingOperation } = require('../ObjectionToKnexConvertingOperation');
7
-
8
7
  // `whereJsonHasAny` and `whereJsonHasAll`.
9
8
  class WhereJsonHasOperation extends ObjectionToKnexConvertingOperation {
10
- onBuildKnex(knexBuilder, builder) {
11
- const dialect = getJsonDialect(builder.unsafeKnex(), this.name);
12
- const args = this.getKnexArgs(builder);
13
-
14
- const [sql, bindings] =
15
- dialect === 'mysql'
16
- ? mysqlJsonApi.whereJsonHas(args[0], this.opt.operator, args[1])
17
- : postgresJsonApi.whereJsonFieldRightStringArrayOnLeftQuery(
18
- builder.knex(),
19
- args[0],
20
- this.opt.operator,
21
- args[1],
22
- );
23
-
24
- if (this.opt.bool === 'or') {
25
- knexBuilder = knexBuilder.orWhereRaw(sql, bindings);
26
- } else {
27
- knexBuilder = knexBuilder.whereRaw(sql, bindings);
9
+ onBuildKnex(knexBuilder, builder) {
10
+ const dialect = getJsonDialect(builder.unsafeKnex(), this.name);
11
+ const args = this.getKnexArgs(builder);
12
+ let [sql, bindings] = dialect === 'mysql'
13
+ ? mysqlJsonApi.whereJsonHas(args[0], this.opt.operator, args[1], builder.unsafeKnex())
14
+ : postgresJsonApi.whereJsonFieldRightStringArrayOnLeftQuery(builder.knex(), args[0], this.opt.operator, args[1]);
15
+ if (dialect === 'mysql') {
16
+ sql = jsonCastsForDialect(sql, builder.unsafeKnex());
17
+ }
18
+ if (this.opt.bool === 'or') {
19
+ knexBuilder = knexBuilder.orWhereRaw(sql, bindings);
20
+ }
21
+ else {
22
+ knexBuilder = knexBuilder.whereRaw(sql, bindings);
23
+ }
24
+ return knexBuilder;
28
25
  }
29
-
30
- return knexBuilder;
31
- }
32
26
  }
33
-
34
27
  module.exports = {
35
- WhereJsonHasOperation,
28
+ WhereJsonHasOperation,
36
29
  };
@@ -1,53 +1,37 @@
1
1
  'use strict';
2
-
3
2
  const jsonApi = require('./postgresJsonApi');
4
3
  const mysqlJsonApi = require('./mysqlJsonApi');
5
4
  const { getJsonDialect } = require('../../../utils/postgresJsonPath');
5
+ const { jsonCastsForDialect } = require('../../../utils/mysqlJsonPath');
6
6
  const { ObjectionToKnexConvertingOperation } = require('../ObjectionToKnexConvertingOperation');
7
-
8
7
  // `whereJsonNotArray` and `whereJsonNotObject`.
9
8
  class WhereJsonNotObjectOperation extends ObjectionToKnexConvertingOperation {
10
- onBuildKnex(knexBuilder, builder) {
11
- const dialect = getJsonDialect(builder.unsafeKnex(), this.name);
12
- const fieldExpression = this.getKnexArgs(builder)[0];
13
-
14
- if (dialect === 'mysql') {
15
- const [sql, bindings] = mysqlJsonApi.whereJsonNotContains(
16
- fieldExpression,
17
- this.opt.compareValue,
18
- );
19
-
20
- return this.opt.bool === 'or'
21
- ? knexBuilder.orWhereRaw(sql, bindings)
22
- : knexBuilder.whereRaw(sql, bindings);
9
+ onBuildKnex(knexBuilder, builder) {
10
+ const dialect = getJsonDialect(builder.unsafeKnex(), this.name);
11
+ const fieldExpression = this.getKnexArgs(builder)[0];
12
+ if (dialect === 'mysql') {
13
+ const [rawSql, bindings] = mysqlJsonApi.whereJsonNotContains(fieldExpression, this.opt.compareValue);
14
+ const sql = jsonCastsForDialect(rawSql, builder.unsafeKnex());
15
+ return this.opt.bool === 'or'
16
+ ? knexBuilder.orWhereRaw(sql, bindings)
17
+ : knexBuilder.whereRaw(sql, bindings);
18
+ }
19
+ return this.whereJsonNotObject(knexBuilder, builder.knex(), fieldExpression);
23
20
  }
24
-
25
- return this.whereJsonNotObject(knexBuilder, builder.knex(), fieldExpression);
26
- }
27
-
28
- whereJsonNotObject(knexBuilder, knex, fieldExpression) {
29
- const innerQuery = (innerQuery) => {
30
- const builder = jsonApi.whereJsonbRefOnLeftJsonbValOrRefOnRight(
31
- innerQuery,
32
- fieldExpression,
33
- '@>',
34
- this.opt.compareValue,
35
- 'not',
36
- );
37
-
38
- builder.orWhereRaw(...jsonApi.whereJsonFieldQuery(knex, fieldExpression, 'IS', null));
39
- };
40
-
41
- if (this.opt.bool === 'or') {
42
- knexBuilder = knexBuilder.orWhere(innerQuery);
43
- } else {
44
- knexBuilder = knexBuilder.where(innerQuery);
21
+ whereJsonNotObject(knexBuilder, knex, fieldExpression) {
22
+ const innerQuery = (innerQuery) => {
23
+ const builder = jsonApi.whereJsonbRefOnLeftJsonbValOrRefOnRight(innerQuery, fieldExpression, '@>', this.opt.compareValue, 'not');
24
+ builder.orWhereRaw(...jsonApi.whereJsonFieldQuery(knex, fieldExpression, 'IS', null));
25
+ };
26
+ if (this.opt.bool === 'or') {
27
+ knexBuilder = knexBuilder.orWhere(innerQuery);
28
+ }
29
+ else {
30
+ knexBuilder = knexBuilder.where(innerQuery);
31
+ }
32
+ return knexBuilder;
45
33
  }
46
-
47
- return knexBuilder;
48
- }
49
34
  }
50
-
51
35
  module.exports = {
52
- WhereJsonNotObjectOperation,
36
+ WhereJsonNotObjectOperation,
53
37
  };