@abedmurrar/objection 0.0.0-stage → 4.0.0-alpha.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 (190) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +69 -2
  3. package/lib/.eslintrc.json +8 -0
  4. package/lib/initialize.js +14 -0
  5. package/lib/model/AjvValidator.js +325 -0
  6. package/lib/model/Model.js +942 -0
  7. package/lib/model/ModifierNotFoundError.js +12 -0
  8. package/lib/model/NotFoundError.js +23 -0
  9. package/lib/model/RelationDoesNotExistError.js +14 -0
  10. package/lib/model/ValidationError.js +54 -0
  11. package/lib/model/Validator.js +26 -0
  12. package/lib/model/getModel.js +9 -0
  13. package/lib/model/graph/ModelGraph.js +80 -0
  14. package/lib/model/graph/ModelGraphBuilder.js +241 -0
  15. package/lib/model/graph/ModelGraphEdge.js +52 -0
  16. package/lib/model/graph/ModelGraphNode.js +240 -0
  17. package/lib/model/inheritModel.js +28 -0
  18. package/lib/model/modelBindKnex.js +83 -0
  19. package/lib/model/modelClone.js +121 -0
  20. package/lib/model/modelColPropMap.js +34 -0
  21. package/lib/model/modelId.js +62 -0
  22. package/lib/model/modelJsonAttributes.js +92 -0
  23. package/lib/model/modelParseRelations.js +82 -0
  24. package/lib/model/modelQueryProps.js +147 -0
  25. package/lib/model/modelSet.js +136 -0
  26. package/lib/model/modelTableMetadata.js +83 -0
  27. package/lib/model/modelToJson.js +187 -0
  28. package/lib/model/modelUtils.js +47 -0
  29. package/lib/model/modelValidate.js +48 -0
  30. package/lib/model/modelValues.js +126 -0
  31. package/lib/model/modelVisitor.js +41 -0
  32. package/lib/objection.js +114 -0
  33. package/lib/queryBuilder/FunctionBuilder.js +339 -0
  34. package/lib/queryBuilder/InternalOptions.js +29 -0
  35. package/lib/queryBuilder/JoinBuilder.js +157 -0
  36. package/lib/queryBuilder/QueryBuilder.js +1398 -0
  37. package/lib/queryBuilder/QueryBuilderBase.js +884 -0
  38. package/lib/queryBuilder/QueryBuilderContext.js +27 -0
  39. package/lib/queryBuilder/QueryBuilderContextBase.js +35 -0
  40. package/lib/queryBuilder/QueryBuilderOperationSupport.js +558 -0
  41. package/lib/queryBuilder/QueryBuilderUserContext.js +31 -0
  42. package/lib/queryBuilder/RawBuilder.js +93 -0
  43. package/lib/queryBuilder/ReferenceBuilder.js +284 -0
  44. package/lib/queryBuilder/RelationExpression.js +431 -0
  45. package/lib/queryBuilder/StaticHookArguments.js +134 -0
  46. package/lib/queryBuilder/ValueBuilder.js +127 -0
  47. package/lib/queryBuilder/expressions.js +151 -0
  48. package/lib/queryBuilder/functions/mysql.js +817 -0
  49. package/lib/queryBuilder/graph/GraphAction.js +69 -0
  50. package/lib/queryBuilder/graph/GraphData.js +14 -0
  51. package/lib/queryBuilder/graph/GraphFetcher.js +191 -0
  52. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +184 -0
  53. package/lib/queryBuilder/graph/GraphOperation.js +27 -0
  54. package/lib/queryBuilder/graph/GraphOptions.js +207 -0
  55. package/lib/queryBuilder/graph/GraphUpsert.js +305 -0
  56. package/lib/queryBuilder/graph/delete/GraphDelete.js +20 -0
  57. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +74 -0
  58. package/lib/queryBuilder/graph/insert/GraphInsert.js +145 -0
  59. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +225 -0
  60. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +92 -0
  61. package/lib/queryBuilder/graph/patch/GraphPatch.js +20 -0
  62. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +258 -0
  63. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +31 -0
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +126 -0
  65. package/lib/queryBuilder/join/JoinResultColumn.js +23 -0
  66. package/lib/queryBuilder/join/JoinResultParser.js +119 -0
  67. package/lib/queryBuilder/join/RelationJoiner.js +341 -0
  68. package/lib/queryBuilder/join/TableNode.js +163 -0
  69. package/lib/queryBuilder/join/TableTree.js +85 -0
  70. package/lib/queryBuilder/join/utils.js +25 -0
  71. package/lib/queryBuilder/operations/DelegateOperation.js +141 -0
  72. package/lib/queryBuilder/operations/DeleteOperation.js +51 -0
  73. package/lib/queryBuilder/operations/FindByIdOperation.js +37 -0
  74. package/lib/queryBuilder/operations/FindByIdsOperation.js +29 -0
  75. package/lib/queryBuilder/operations/FindOperation.js +164 -0
  76. package/lib/queryBuilder/operations/FirstOperation.js +27 -0
  77. package/lib/queryBuilder/operations/FromOperation.js +110 -0
  78. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +49 -0
  79. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +45 -0
  80. package/lib/queryBuilder/operations/InsertGraphOperation.js +108 -0
  81. package/lib/queryBuilder/operations/InsertOperation.js +206 -0
  82. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +46 -0
  83. package/lib/queryBuilder/operations/InstanceFindOperation.js +21 -0
  84. package/lib/queryBuilder/operations/InstanceInsertOperation.js +24 -0
  85. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +59 -0
  86. package/lib/queryBuilder/operations/JoinRelatedOperation.js +103 -0
  87. package/lib/queryBuilder/operations/KnexOperation.js +14 -0
  88. package/lib/queryBuilder/operations/MergeOperation.js +56 -0
  89. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +192 -0
  90. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +29 -0
  91. package/lib/queryBuilder/operations/OnBuildOperation.js +29 -0
  92. package/lib/queryBuilder/operations/OnErrorOperation.js +29 -0
  93. package/lib/queryBuilder/operations/QueryBuilderOperation.js +297 -0
  94. package/lib/queryBuilder/operations/RangeOperation.js +47 -0
  95. package/lib/queryBuilder/operations/RelateOperation.js +27 -0
  96. package/lib/queryBuilder/operations/ReturningOperation.js +30 -0
  97. package/lib/queryBuilder/operations/RunAfterOperation.js +29 -0
  98. package/lib/queryBuilder/operations/RunBeforeOperation.js +29 -0
  99. package/lib/queryBuilder/operations/UnrelateOperation.js +23 -0
  100. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +80 -0
  101. package/lib/queryBuilder/operations/UpdateOperation.js +155 -0
  102. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +45 -0
  103. package/lib/queryBuilder/operations/UpsertGraphOperation.js +66 -0
  104. package/lib/queryBuilder/operations/WhereCompositeOperation.js +57 -0
  105. package/lib/queryBuilder/operations/WhereInOperation.js +48 -0
  106. package/lib/queryBuilder/operations/eager/EagerOperation.js +61 -0
  107. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +51 -0
  108. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +13 -0
  109. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +285 -0
  110. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +36 -0
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +53 -0
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +31 -0
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +31 -0
  114. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +167 -0
  115. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +164 -0
  116. package/lib/queryBuilder/operations/select/SelectOperation.js +66 -0
  117. package/lib/queryBuilder/operations/select/Selection.js +123 -0
  118. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +117 -0
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +100 -0
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +104 -0
  121. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +886 -0
  122. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +97 -0
  123. package/lib/queryBuilder/parsers/relationExpressionParser.js +1042 -0
  124. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +141 -0
  125. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +22 -0
  126. package/lib/queryBuilder/transformations/QueryTransformation.js +11 -0
  127. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +71 -0
  128. package/lib/queryBuilder/transformations/index.js +15 -0
  129. package/lib/queryBuilder/whereScopes.js +227 -0
  130. package/lib/relations/Relation.js +401 -0
  131. package/lib/relations/RelationDeleteOperation.js +29 -0
  132. package/lib/relations/RelationFindOperation.js +149 -0
  133. package/lib/relations/RelationInsertOperation.js +33 -0
  134. package/lib/relations/RelationOwner.js +236 -0
  135. package/lib/relations/RelationProperty.js +247 -0
  136. package/lib/relations/RelationUpdateOperation.js +30 -0
  137. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +23 -0
  138. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +44 -0
  139. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +50 -0
  140. package/lib/relations/belongsToOne/BelongsToOneRelation.js +53 -0
  141. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +61 -0
  142. package/lib/relations/hasMany/HasManyInsertOperation.js +61 -0
  143. package/lib/relations/hasMany/HasManyRelateOperation.js +64 -0
  144. package/lib/relations/hasMany/HasManyRelation.js +49 -0
  145. package/lib/relations/hasMany/HasManyUnrelateOperation.js +33 -0
  146. package/lib/relations/hasOne/HasOneRelation.js +13 -0
  147. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +13 -0
  148. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +105 -0
  149. package/lib/relations/manyToMany/ManyToManyRelation.js +507 -0
  150. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +36 -0
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +10 -0
  152. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +26 -0
  153. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +12 -0
  154. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +105 -0
  155. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +52 -0
  156. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +81 -0
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +14 -0
  158. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +34 -0
  159. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +16 -0
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +10 -0
  161. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +82 -0
  162. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +12 -0
  163. package/lib/transaction.js +96 -0
  164. package/lib/utils/assert.js +25 -0
  165. package/lib/utils/buildUtils.js +21 -0
  166. package/lib/utils/classUtils.js +13 -0
  167. package/lib/utils/clone.js +2329 -0
  168. package/lib/utils/createModifier.js +42 -0
  169. package/lib/utils/deprecate.js +15 -0
  170. package/lib/utils/identifierMapping.js +227 -0
  171. package/lib/utils/internalPropUtils.js +11 -0
  172. package/lib/utils/knexUtils.js +76 -0
  173. package/lib/utils/mixin.js +25 -0
  174. package/lib/utils/mysqlJsonPath.js +55 -0
  175. package/lib/utils/normalizeIds.js +144 -0
  176. package/lib/utils/objectUtils.js +416 -0
  177. package/lib/utils/parseFieldExpression.js +51 -0
  178. package/lib/utils/postgresJsonPath.js +110 -0
  179. package/lib/utils/promiseUtils/after.js +17 -0
  180. package/lib/utils/promiseUtils/afterReturn.js +17 -0
  181. package/lib/utils/promiseUtils/index.js +17 -0
  182. package/lib/utils/promiseUtils/isPromise.js +11 -0
  183. package/lib/utils/promiseUtils/map.js +110 -0
  184. package/lib/utils/promiseUtils/mapAfterAllReturn.js +29 -0
  185. package/lib/utils/promiseUtils/try.js +22 -0
  186. package/lib/utils/resolveModel.js +107 -0
  187. package/lib/utils/tmpColumnUtils.js +16 -0
  188. package/package.json +86 -4
  189. package/typings/objection/index.d.ts +4104 -0
  190. package/typings/objection/relation-expression.d.ts +237 -0
@@ -0,0 +1,1398 @@
1
+ 'use strict';
2
+
3
+ const { withWhereScope } = require('./whereScopes');
4
+ const { wrapError } = require('db-errors');
5
+
6
+ const { raw } = require('./RawBuilder');
7
+ const { createModifier } = require('../utils/createModifier');
8
+ const { ValidationErrorType } = require('../model/ValidationError');
9
+ const { isObject, isString, isFunction, last, flatten } = require('../utils/objectUtils');
10
+ const { RelationExpression, DuplicateRelationError } = require('./RelationExpression');
11
+ const { assertIdNotUndefined } = require('../utils/assert');
12
+
13
+ const { Selection } = require('./operations/select/Selection');
14
+
15
+ const { QueryBuilderContext } = require('./QueryBuilderContext');
16
+ const { QueryBuilderBase } = require('./QueryBuilderBase');
17
+
18
+ const { FindOperation } = require('./operations/FindOperation');
19
+ const { DeleteOperation } = require('./operations/DeleteOperation');
20
+ const { UpdateOperation } = require('./operations/UpdateOperation');
21
+ const { InsertOperation } = require('./operations/InsertOperation');
22
+ const { RelateOperation } = require('./operations/RelateOperation');
23
+ const { UnrelateOperation } = require('./operations/UnrelateOperation');
24
+
25
+ const { JoinEagerOperation } = require('./operations/eager/JoinEagerOperation');
26
+ const { NaiveEagerOperation } = require('./operations/eager/NaiveEagerOperation');
27
+ const { WhereInEagerOperation } = require('./operations/eager/WhereInEagerOperation');
28
+
29
+ const { InsertGraphAndFetchOperation } = require('./operations/InsertGraphAndFetchOperation');
30
+ const { UpsertGraphAndFetchOperation } = require('./operations/UpsertGraphAndFetchOperation');
31
+ const { InsertAndFetchOperation } = require('./operations/InsertAndFetchOperation');
32
+ const { UpdateAndFetchOperation } = require('./operations/UpdateAndFetchOperation');
33
+ const { JoinRelatedOperation } = require('./operations/JoinRelatedOperation');
34
+ const { OnBuildKnexOperation } = require('./operations/OnBuildKnexOperation');
35
+ const { InsertGraphOperation } = require('./operations/InsertGraphOperation');
36
+ const { UpsertGraphOperation } = require('./operations/UpsertGraphOperation');
37
+ const { RunBeforeOperation } = require('./operations/RunBeforeOperation');
38
+ const { RunAfterOperation } = require('./operations/RunAfterOperation');
39
+ const { FindByIdOperation } = require('./operations/FindByIdOperation');
40
+ const { FindByIdsOperation } = require('./operations/FindByIdsOperation');
41
+ const { OnBuildOperation } = require('./operations/OnBuildOperation');
42
+ const { OnErrorOperation } = require('./operations/OnErrorOperation');
43
+ const { SelectOperation } = require('./operations/select/SelectOperation');
44
+ const { EagerOperation } = require('./operations/eager/EagerOperation');
45
+ const { RangeOperation } = require('./operations/RangeOperation');
46
+ const { FirstOperation } = require('./operations/FirstOperation');
47
+ const { FromOperation } = require('./operations/FromOperation');
48
+ const { KnexOperation } = require('./operations/KnexOperation');
49
+
50
+ class QueryBuilder extends QueryBuilderBase {
51
+ static init(self, modelClass) {
52
+ super.init(self, modelClass);
53
+
54
+ self._resultModelClass = null;
55
+ self._explicitRejectValue = null;
56
+ self._explicitResolveValue = null;
57
+ self._modifiers = {};
58
+
59
+ self._allowedGraphExpression = null;
60
+ self._findOperationOptions = modelClass.defaultFindOptions;
61
+ self._relatedQueryFor = null;
62
+ self._isRelatedQuery = false;
63
+ self._forError = null;
64
+
65
+ self._findOperationFactory = findOperationFactory;
66
+ self._insertOperationFactory = insertOperationFactory;
67
+ self._updateOperationFactory = updateOperationFactory;
68
+ self._patchOperationFactory = patchOperationFactory;
69
+ self._relateOperationFactory = relateOperationFactory;
70
+ self._unrelateOperationFactory = unrelateOperationFactory;
71
+ self._deleteOperationFactory = deleteOperationFactory;
72
+ }
73
+
74
+ static get QueryBuilderContext() {
75
+ return QueryBuilderContext;
76
+ }
77
+
78
+ static parseRelationExpression(expr) {
79
+ return RelationExpression.create(expr).toPojo();
80
+ }
81
+
82
+ tableName(newTableName) {
83
+ return this.tableNameFor(this.modelClass().getTableName(), newTableName);
84
+ }
85
+
86
+ tableRef() {
87
+ return this.tableRefFor(this.modelClass().getTableName());
88
+ }
89
+
90
+ alias(alias) {
91
+ return this.aliasFor(this.modelClass().getTableName(), alias);
92
+ }
93
+
94
+ fullIdColumnFor(modelClass) {
95
+ const tableName = this.tableRefFor(modelClass);
96
+ const idColumn = modelClass.getIdColumn();
97
+
98
+ if (Array.isArray(idColumn)) {
99
+ return idColumn.map((col) => `${tableName}.${col}`);
100
+ } else {
101
+ return `${tableName}.${idColumn}`;
102
+ }
103
+ }
104
+
105
+ fullIdColumn() {
106
+ return this.fullIdColumnFor(this.modelClass());
107
+ }
108
+
109
+ modifiers(modifiers) {
110
+ if (arguments.length === 0) {
111
+ return { ...this._modifiers };
112
+ } else {
113
+ this._modifiers = { ...this._modifiers, ...modifiers };
114
+ return this;
115
+ }
116
+ }
117
+
118
+ modify(modifier, ...args) {
119
+ if (!modifier) {
120
+ return this;
121
+ }
122
+
123
+ modifier = createModifier({
124
+ modifier,
125
+ modelClass: this.modelClass(),
126
+ modifiers: this._modifiers,
127
+ });
128
+
129
+ modifier(this, ...args);
130
+ return this;
131
+ }
132
+
133
+ reject(error) {
134
+ this._explicitRejectValue = error;
135
+ return this;
136
+ }
137
+
138
+ resolve(value) {
139
+ this._explicitResolveValue = value;
140
+ return this;
141
+ }
142
+
143
+ isExplicitlyResolvedOrRejected() {
144
+ return !!(this._explicitRejectValue || this._explicitResolveValue);
145
+ }
146
+
147
+ isExecutable() {
148
+ return !this.isExplicitlyResolvedOrRejected() && !findQueryExecutorOperation(this);
149
+ }
150
+
151
+ findOperationFactory(factory) {
152
+ this._findOperationFactory = factory;
153
+ return this;
154
+ }
155
+
156
+ insertOperationFactory(factory) {
157
+ this._insertOperationFactory = factory;
158
+ return this;
159
+ }
160
+
161
+ updateOperationFactory(factory) {
162
+ this._updateOperationFactory = factory;
163
+ return this;
164
+ }
165
+
166
+ patchOperationFactory(factory) {
167
+ this._patchOperationFactory = factory;
168
+ return this;
169
+ }
170
+
171
+ deleteOperationFactory(factory) {
172
+ this._deleteOperationFactory = factory;
173
+ return this;
174
+ }
175
+
176
+ relateOperationFactory(factory) {
177
+ this._relateOperationFactory = factory;
178
+ return this;
179
+ }
180
+
181
+ unrelateOperationFactory(factory) {
182
+ this._unrelateOperationFactory = factory;
183
+ return this;
184
+ }
185
+
186
+ withGraphFetched(exp, options = {}) {
187
+ return this._withGraph(exp, options, getWhereInEagerAlgorithm(this));
188
+ }
189
+
190
+ withGraphJoined(exp, options = {}) {
191
+ return this._withGraph(exp, options, getJoinEagerAlgorithm(this));
192
+ }
193
+
194
+ _withGraph(exp, options, algorithm) {
195
+ const eagerOp = ensureEagerOperation(this, algorithm);
196
+ const parsedExp = parseRelationExpression(this.modelClass(), exp);
197
+
198
+ eagerOp.expression = eagerOp.expression.merge(parsedExp);
199
+ eagerOp.graphOptions = { ...eagerOp.graphOptions, ...options };
200
+
201
+ checkEager(this);
202
+ return this;
203
+ }
204
+
205
+ allowGraph(exp) {
206
+ const currentExpr = this._allowedGraphExpression || RelationExpression.create();
207
+
208
+ this._allowedGraphExpression = currentExpr.merge(
209
+ parseRelationExpression(this.modelClass(), exp),
210
+ );
211
+
212
+ checkEager(this);
213
+ return this;
214
+ }
215
+
216
+ allowedGraphExpression() {
217
+ return this._allowedGraphExpression;
218
+ }
219
+
220
+ graphExpressionObject() {
221
+ const eagerOp = this.findOperation(EagerOperation);
222
+
223
+ if (eagerOp && !eagerOp.expression.isEmpty) {
224
+ return eagerOp.expression.toPojo();
225
+ } else {
226
+ return null;
227
+ }
228
+ }
229
+
230
+ graphModifiersAtPath() {
231
+ const eagerOp = this.findOperation(EagerOperation);
232
+
233
+ if (eagerOp && !eagerOp.expression.isEmpty) {
234
+ return eagerOp.modifiersAtPath.map((it) => Object.assign({}, it));
235
+ } else {
236
+ return [];
237
+ }
238
+ }
239
+
240
+ modifyGraph(path, modifier) {
241
+ const eagerOp = ensureEagerOperation(this);
242
+ eagerOp.modifiersAtPath.push({ path, modifier });
243
+ return this;
244
+ }
245
+
246
+ findOptions(opt) {
247
+ if (arguments.length !== 0) {
248
+ this._findOperationOptions = Object.assign({}, this._findOperationOptions, opt);
249
+ return this;
250
+ } else {
251
+ return this._findOperationOptions;
252
+ }
253
+ }
254
+
255
+ resultModelClass() {
256
+ return this._resultModelClass || this.modelClass();
257
+ }
258
+
259
+ isFind() {
260
+ return !(
261
+ this.isInsert() ||
262
+ this.isUpdate() ||
263
+ this.isDelete() ||
264
+ this.isRelate() ||
265
+ this.isUnrelate()
266
+ );
267
+ }
268
+
269
+ isInsert() {
270
+ return this.has(InsertOperation);
271
+ }
272
+
273
+ isUpdate() {
274
+ return this.has(UpdateOperation);
275
+ }
276
+
277
+ isDelete() {
278
+ return this.has(DeleteOperation);
279
+ }
280
+
281
+ isRelate() {
282
+ return this.has(RelateOperation);
283
+ }
284
+
285
+ isUnrelate() {
286
+ return this.has(UnrelateOperation);
287
+ }
288
+
289
+ hasWheres() {
290
+ const queryWithoutGraph = this.clone().clearWithGraph();
291
+ return prebuildQuery(queryWithoutGraph).has(QueryBuilderBase.WhereSelector);
292
+ }
293
+
294
+ hasSelects() {
295
+ return this.has(QueryBuilderBase.SelectSelector);
296
+ }
297
+
298
+ hasWithGraph() {
299
+ const eagerOp = this.findOperation(EagerOperation);
300
+ return !!eagerOp && !eagerOp.expression.isEmpty;
301
+ }
302
+
303
+ isSelectAll() {
304
+ if (this._operations.length === 0) {
305
+ return true;
306
+ }
307
+
308
+ const tableRef = this.tableRef();
309
+ const tableName = this.tableName();
310
+
311
+ return this.everyOperation((op) => {
312
+ if (op.constructor === SelectOperation) {
313
+ // SelectOperations with zero selections are the ones that only have
314
+ // raw items or other non-trivial selections.
315
+ return (
316
+ op.selections.length > 0 &&
317
+ op.selections.every((select) => {
318
+ return (!select.table || select.table === tableRef) && select.column === '*';
319
+ })
320
+ );
321
+ } else if (op.constructor === FromOperation) {
322
+ return op.table === tableName;
323
+ } else if (op.name === 'as' || op.is(FindOperation) || op.is(OnErrorOperation)) {
324
+ return true;
325
+ } else {
326
+ return false;
327
+ }
328
+ });
329
+ }
330
+
331
+ toString() {
332
+ return '[object QueryBuilder]';
333
+ }
334
+
335
+ clone() {
336
+ const builder = this.emptyInstance();
337
+
338
+ // Call the super class's clone implementation.
339
+ this.baseCloneInto(builder);
340
+
341
+ builder._resultModelClass = this._resultModelClass;
342
+
343
+ builder._explicitRejectValue = this._explicitRejectValue;
344
+ builder._explicitResolveValue = this._explicitResolveValue;
345
+ builder._modifiers = { ...this._modifiers };
346
+
347
+ builder._allowedGraphExpression = this._allowedGraphExpression;
348
+ builder._findOperationOptions = this._findOperationOptions;
349
+ builder._relatedQueryFor = this._relatedQueryFor;
350
+
351
+ return builder;
352
+ }
353
+
354
+ emptyInstance() {
355
+ const builder = new this.constructor(this.modelClass());
356
+
357
+ builder._findOperationFactory = this._findOperationFactory;
358
+ builder._insertOperationFactory = this._insertOperationFactory;
359
+ builder._updateOperationFactory = this._updateOperationFactory;
360
+ builder._patchOperationFactory = this._patchOperationFactory;
361
+ builder._relateOperationFactory = this._relateOperationFactory;
362
+ builder._unrelateOperationFactory = this._unrelateOperationFactory;
363
+ builder._deleteOperationFactory = this._deleteOperationFactory;
364
+ builder._relatedQueryFor = this._relatedQueryFor;
365
+ builder._isRelatedQuery = this._isRelatedQuery;
366
+ builder._forError = this._forError;
367
+
368
+ return builder;
369
+ }
370
+
371
+ clearWithGraph() {
372
+ this.clear(EagerOperation);
373
+ return this;
374
+ }
375
+
376
+ clearWithGraphFetched() {
377
+ this.clear(WhereInEagerOperation);
378
+ return this;
379
+ }
380
+
381
+ clearAllowGraph() {
382
+ this._allowedGraphExpression = null;
383
+ return this;
384
+ }
385
+
386
+ clearModifiers() {
387
+ this._modifiers = {};
388
+ return this;
389
+ }
390
+
391
+ clearReject() {
392
+ this._explicitRejectValue = null;
393
+ return this;
394
+ }
395
+
396
+ clearResolve() {
397
+ this._explicitResolveValue = null;
398
+ return this;
399
+ }
400
+
401
+ castTo(modelClass) {
402
+ this._resultModelClass = modelClass || null;
403
+ return this;
404
+ }
405
+
406
+ then(...args) {
407
+ const promise = this.execute();
408
+ return promise.then(...args);
409
+ }
410
+
411
+ catch(...args) {
412
+ const promise = this.execute();
413
+ return promise.catch(...args);
414
+ }
415
+
416
+ async resultSize() {
417
+ const knex = this.knex();
418
+ const builder = this.clone().clear(/orderBy|offset|limit/);
419
+
420
+ const countQuery = knex.count('* as count').from((knexBuilder) => {
421
+ builder.toKnexQuery(knexBuilder).as('temp');
422
+ });
423
+
424
+ if (this.internalOptions().debug) {
425
+ countQuery.debug();
426
+ }
427
+
428
+ const result = await countQuery;
429
+ return result[0] && result[0].count ? parseInt(result[0].count) : 0;
430
+ }
431
+
432
+ toKnexQuery(knexBuilder = this.knex().queryBuilder()) {
433
+ const prebuiltQuery = prebuildQuery(this.clone());
434
+ return buildKnexQuery(prebuiltQuery, knexBuilder);
435
+ }
436
+
437
+ async execute() {
438
+ // Take a clone so that we don't modify this instance during execution.
439
+ const builder = this.clone();
440
+
441
+ try {
442
+ await beforeExecute(builder);
443
+ const result = await doExecute(builder);
444
+ return await afterExecute(builder, result);
445
+ } catch (error) {
446
+ return await handleExecuteError(builder, error);
447
+ }
448
+ }
449
+
450
+ throwIfNotFound(data = {}) {
451
+ return this.runAfter((result) => {
452
+ if (
453
+ (Array.isArray(result) && result.length === 0) ||
454
+ result === null ||
455
+ result === undefined ||
456
+ result === 0
457
+ ) {
458
+ throw this.modelClass().createNotFoundError(this.context(), data);
459
+ } else {
460
+ return result;
461
+ }
462
+ });
463
+ }
464
+
465
+ findSelection(selection, explicit = false) {
466
+ let noSelectStatements = true;
467
+ let selectionInstance = null;
468
+
469
+ this.forEachOperation(true, (op) => {
470
+ if (op.constructor === SelectOperation) {
471
+ selectionInstance = op.findSelection(this, selection);
472
+ noSelectStatements = false;
473
+
474
+ if (selectionInstance) {
475
+ return false;
476
+ }
477
+ }
478
+ });
479
+
480
+ if (selectionInstance) {
481
+ return selectionInstance;
482
+ }
483
+
484
+ if (noSelectStatements && !explicit) {
485
+ const selectAll = new Selection(this.tableRef(), '*');
486
+
487
+ if (Selection.doesSelect(this, selectAll, selection)) {
488
+ return selectAll;
489
+ } else {
490
+ return null;
491
+ }
492
+ } else {
493
+ return null;
494
+ }
495
+ }
496
+
497
+ findAllSelections() {
498
+ let allSelections = [];
499
+
500
+ this.forEachOperation(true, (op) => {
501
+ if (op.constructor === SelectOperation) {
502
+ allSelections = allSelections.concat(op.selections);
503
+ }
504
+ });
505
+
506
+ return allSelections;
507
+ }
508
+
509
+ hasSelection(selection, explicit) {
510
+ return this.findSelection(selection, explicit) !== null;
511
+ }
512
+
513
+ hasSelectionAs(selection, alias, explicit) {
514
+ selection = Selection.create(selection);
515
+ const foundSelection = this.findSelection(selection, explicit);
516
+
517
+ if (foundSelection === null) {
518
+ return false;
519
+ } else {
520
+ if (foundSelection.column === '*') {
521
+ // * selects the columns with their column names as aliases.
522
+ return selection.column === alias;
523
+ } else {
524
+ return foundSelection.name === alias;
525
+ }
526
+ }
527
+ }
528
+
529
+ traverse(modelClass, traverser) {
530
+ if (typeof traverser === 'undefined') {
531
+ traverser = modelClass;
532
+ modelClass = null;
533
+ }
534
+
535
+ return this.runAfter((result) => {
536
+ this.resultModelClass().traverse(modelClass, result, traverser);
537
+ return result;
538
+ });
539
+ }
540
+
541
+ page(page, pageSize) {
542
+ return this.range(+page * +pageSize, (+page + 1) * +pageSize - 1);
543
+ }
544
+
545
+ columnInfo({ table = null } = {}) {
546
+ table = table || this.tableName();
547
+
548
+ const knex = this.knex();
549
+ const tableParts = table.split('.');
550
+ const columnInfoQuery = knex(last(tableParts)).columnInfo();
551
+ const schema = this.internalOptions().schema;
552
+
553
+ if (schema) {
554
+ columnInfoQuery.withSchema(schema);
555
+ } else if (tableParts.length > 1) {
556
+ columnInfoQuery.withSchema(tableParts[0]);
557
+ }
558
+
559
+ if (this.internalOptions().debug) {
560
+ columnInfoQuery.debug();
561
+ }
562
+
563
+ return columnInfoQuery;
564
+ }
565
+
566
+ withSchema(schema) {
567
+ this.internalOptions().schema = schema;
568
+ this.internalContext().onBuild.push((builder) => {
569
+ if (!builder.has(/withSchema/)) {
570
+ // Need to push this operation to the front because knex doesn't use the
571
+ // schema for operations called before `withSchema`.
572
+ builder.addOperationToFront(new KnexOperation('withSchema'), [schema]);
573
+ }
574
+ });
575
+
576
+ return this;
577
+ }
578
+
579
+ debug /* istanbul ignore next */() {
580
+ this.internalOptions().debug = true;
581
+ this.internalContext().onBuild.push((builder) => {
582
+ builder.addOperation(new KnexOperation('debug'), []);
583
+ });
584
+
585
+ return this;
586
+ }
587
+
588
+ insert(modelsOrObjects) {
589
+ return writeOperation(this, () => {
590
+ const insertOperation = this._insertOperationFactory(this);
591
+
592
+ this.addOperation(insertOperation, [modelsOrObjects]);
593
+ });
594
+ }
595
+
596
+ insertAndFetch(modelsOrObjects) {
597
+ return writeOperation(this, () => {
598
+ const insertOperation = this._insertOperationFactory(this);
599
+
600
+ const insertAndFetchOperation = new InsertAndFetchOperation('insertAndFetch', {
601
+ delegate: insertOperation,
602
+ });
603
+
604
+ this.addOperation(insertAndFetchOperation, [modelsOrObjects]);
605
+ });
606
+ }
607
+
608
+ insertGraph(modelsOrObjects, opt) {
609
+ return writeOperation(this, () => {
610
+ const insertOperation = this._insertOperationFactory(this);
611
+
612
+ const insertGraphOperation = new InsertGraphOperation('insertGraph', {
613
+ delegate: insertOperation,
614
+ opt,
615
+ });
616
+
617
+ this.addOperation(insertGraphOperation, [modelsOrObjects]);
618
+ });
619
+ }
620
+
621
+ insertGraphAndFetch(modelsOrObjects, opt) {
622
+ return writeOperation(this, () => {
623
+ const insertOperation = this._insertOperationFactory(this);
624
+
625
+ const insertGraphOperation = new InsertGraphOperation('insertGraph', {
626
+ delegate: insertOperation,
627
+ opt,
628
+ });
629
+
630
+ const insertGraphAndFetchOperation = new InsertGraphAndFetchOperation('insertGraphAndFetch', {
631
+ delegate: insertGraphOperation,
632
+ });
633
+
634
+ return this.addOperation(insertGraphAndFetchOperation, [modelsOrObjects]);
635
+ });
636
+ }
637
+
638
+ update(modelOrObject) {
639
+ return writeOperation(this, () => {
640
+ const updateOperation = this._updateOperationFactory(this);
641
+
642
+ this.addOperation(updateOperation, [modelOrObject]);
643
+ });
644
+ }
645
+
646
+ updateAndFetch(modelOrObject) {
647
+ return writeOperation(this, () => {
648
+ const updateOperation = this._updateOperationFactory(this);
649
+
650
+ if (!(updateOperation.instance instanceof this.modelClass())) {
651
+ throw new Error('updateAndFetch can only be called for instance operations');
652
+ }
653
+
654
+ const updateAndFetch = new UpdateAndFetchOperation('updateAndFetch', {
655
+ delegate: updateOperation,
656
+ });
657
+
658
+ // patchOperation is an instance update operation that already adds the
659
+ // required "where id = $" clause.
660
+ updateAndFetch.skipIdWhere = true;
661
+
662
+ this.addOperation(updateAndFetch, [updateOperation.instance.$id(), modelOrObject]);
663
+ });
664
+ }
665
+
666
+ updateAndFetchById(id, modelOrObject) {
667
+ return writeOperation(this, () => {
668
+ const updateOperation = this._updateOperationFactory(this);
669
+
670
+ const updateAndFetch = new UpdateAndFetchOperation('updateAndFetch', {
671
+ delegate: updateOperation,
672
+ });
673
+
674
+ this.addOperation(updateAndFetch, [id, modelOrObject]);
675
+ });
676
+ }
677
+
678
+ upsertGraph(modelsOrObjects, upsertOptions) {
679
+ return writeOperation(this, () => {
680
+ const upsertGraphOperation = new UpsertGraphOperation('upsertGraph', {
681
+ upsertOptions,
682
+ });
683
+
684
+ this.addOperation(upsertGraphOperation, [modelsOrObjects]);
685
+ });
686
+ }
687
+
688
+ upsertGraphAndFetch(modelsOrObjects, upsertOptions) {
689
+ return writeOperation(this, () => {
690
+ const upsertGraphOperation = new UpsertGraphOperation('upsertGraph', {
691
+ upsertOptions,
692
+ });
693
+
694
+ const upsertGraphAndFetchOperation = new UpsertGraphAndFetchOperation('upsertGraphAndFetch', {
695
+ delegate: upsertGraphOperation,
696
+ });
697
+
698
+ return this.addOperation(upsertGraphAndFetchOperation, [modelsOrObjects]);
699
+ });
700
+ }
701
+
702
+ patch(modelOrObject) {
703
+ return writeOperation(this, () => {
704
+ const patchOperation = this._patchOperationFactory(this);
705
+
706
+ this.addOperation(patchOperation, [modelOrObject]);
707
+ });
708
+ }
709
+
710
+ patchAndFetch(modelOrObject) {
711
+ return writeOperation(this, () => {
712
+ const patchOperation = this._patchOperationFactory(this);
713
+
714
+ if (!(patchOperation.instance instanceof this.modelClass())) {
715
+ throw new Error('patchAndFetch can only be called for instance operations');
716
+ }
717
+
718
+ const patchAndFetch = new UpdateAndFetchOperation('patchAndFetch', {
719
+ delegate: patchOperation,
720
+ });
721
+
722
+ // patchOperation is an instance update operation that already adds the
723
+ // required "where id = $" clause.
724
+ patchAndFetch.skipIdWhere = true;
725
+
726
+ this.addOperation(patchAndFetch, [patchOperation.instance.$id(), modelOrObject]);
727
+ });
728
+ }
729
+
730
+ patchAndFetchById(id, modelOrObject) {
731
+ return writeOperation(this, () => {
732
+ const patchOperation = this._patchOperationFactory(this);
733
+
734
+ const patchAndFetch = new UpdateAndFetchOperation('patchAndFetch', {
735
+ delegate: patchOperation,
736
+ });
737
+
738
+ this.addOperation(patchAndFetch, [id, modelOrObject]);
739
+ });
740
+ }
741
+
742
+ delete(...args) {
743
+ return writeOperation(this, () => {
744
+ if (args.length) {
745
+ throw new Error(
746
+ `Don't pass arguments to delete(). You should use it like this: delete().where('foo', 'bar').andWhere(...)`,
747
+ );
748
+ }
749
+
750
+ const deleteOperation = this._deleteOperationFactory(this);
751
+ this.addOperation(deleteOperation, args);
752
+ });
753
+ }
754
+
755
+ del(...args) {
756
+ return this.delete(...args);
757
+ }
758
+
759
+ relate(...args) {
760
+ return writeOperation(this, () => {
761
+ const relateOperation = this._relateOperationFactory(this);
762
+
763
+ this.addOperation(relateOperation, args);
764
+ });
765
+ }
766
+
767
+ unrelate(...args) {
768
+ return writeOperation(this, () => {
769
+ if (args.length) {
770
+ throw new Error(
771
+ `Don't pass arguments to unrelate(). You should use it like this: unrelate().where('foo', 'bar').andWhere(...)`,
772
+ );
773
+ }
774
+
775
+ const unrelateOperation = this._unrelateOperationFactory(this);
776
+ this.addOperation(unrelateOperation, args);
777
+ });
778
+ }
779
+
780
+ increment(propertyName, howMuch) {
781
+ const columnName = this.modelClass().propertyNameToColumnName(propertyName);
782
+
783
+ return this.patch({
784
+ [columnName]: raw('?? + ?', [columnName, howMuch]),
785
+ });
786
+ }
787
+
788
+ decrement(propertyName, howMuch) {
789
+ const columnName = this.modelClass().propertyNameToColumnName(propertyName);
790
+
791
+ return this.patch({
792
+ [columnName]: raw('?? - ?', [columnName, howMuch]),
793
+ });
794
+ }
795
+
796
+ findOne(...args) {
797
+ return this.where.apply(this, args).first();
798
+ }
799
+
800
+ range(...args) {
801
+ return this.clear(RangeOperation).addOperation(new RangeOperation('range'), args);
802
+ }
803
+
804
+ first(...args) {
805
+ return this.addOperation(new FirstOperation('first'), args);
806
+ }
807
+
808
+ joinRelated(expression, options) {
809
+ ensureJoinRelatedOperation(this, 'innerJoin').addCall({
810
+ expression,
811
+ options,
812
+ });
813
+
814
+ return this;
815
+ }
816
+
817
+ innerJoinRelated(expression, options) {
818
+ ensureJoinRelatedOperation(this, 'innerJoin').addCall({
819
+ expression,
820
+ options,
821
+ });
822
+
823
+ return this;
824
+ }
825
+
826
+ outerJoinRelated(expression, options) {
827
+ ensureJoinRelatedOperation(this, 'outerJoin').addCall({
828
+ expression,
829
+ options,
830
+ });
831
+
832
+ return this;
833
+ }
834
+
835
+ fullOuterJoinRelated(expression, options) {
836
+ ensureJoinRelatedOperation(this, 'fullOuterJoin').addCall({
837
+ expression,
838
+ options,
839
+ });
840
+
841
+ return this;
842
+ }
843
+
844
+ leftJoinRelated(expression, options) {
845
+ ensureJoinRelatedOperation(this, 'leftJoin').addCall({
846
+ expression,
847
+ options,
848
+ });
849
+
850
+ return this;
851
+ }
852
+
853
+ leftOuterJoinRelated(expression, options) {
854
+ ensureJoinRelatedOperation(this, 'leftOuterJoin').addCall({
855
+ expression,
856
+ options,
857
+ });
858
+
859
+ return this;
860
+ }
861
+
862
+ rightJoinRelated(expression, options) {
863
+ ensureJoinRelatedOperation(this, 'rightJoin').addCall({
864
+ expression,
865
+ options,
866
+ });
867
+
868
+ return this;
869
+ }
870
+
871
+ rightOuterJoinRelated(expression, options) {
872
+ ensureJoinRelatedOperation(this, 'rightOuterJoin').addCall({
873
+ expression,
874
+ options,
875
+ });
876
+
877
+ return this;
878
+ }
879
+
880
+ deleteById(id) {
881
+ return withWhereScope(this, () => this.findById(id))
882
+ .delete()
883
+ .runBefore((_, builder) => {
884
+ if (!builder.internalOptions().skipUndefined) {
885
+ assertIdNotUndefined(id, `undefined was passed to deleteById`);
886
+ }
887
+ });
888
+ }
889
+
890
+ findById(...args) {
891
+ return this.addOperation(new FindByIdOperation('findById'), args).first();
892
+ }
893
+
894
+ findByIds(...args) {
895
+ return this.addOperation(new FindByIdsOperation('findByIds'), args);
896
+ }
897
+
898
+ runBefore(...args) {
899
+ return this.addOperation(new RunBeforeOperation('runBefore'), args);
900
+ }
901
+
902
+ onBuild(...args) {
903
+ return this.addOperation(new OnBuildOperation('onBuild'), args);
904
+ }
905
+
906
+ onBuildKnex(...args) {
907
+ return this.addOperation(new OnBuildKnexOperation('onBuildKnex'), args);
908
+ }
909
+
910
+ runAfter(...args) {
911
+ return this.addOperation(new RunAfterOperation('runAfter'), args);
912
+ }
913
+
914
+ onError(...args) {
915
+ return this.addOperation(new OnErrorOperation('onError'), args);
916
+ }
917
+
918
+ from(...args) {
919
+ return this.addOperation(new FromOperation('from'), args);
920
+ }
921
+
922
+ updateFrom(...args) {
923
+ return this.addOperation(new KnexOperation('updateFrom'), args);
924
+ }
925
+
926
+ table(...args) {
927
+ return this.addOperation(new FromOperation('table'), args);
928
+ }
929
+
930
+ for(relatedQueryFor) {
931
+ if (arguments.length === 0) {
932
+ return this._relatedQueryFor;
933
+ }
934
+
935
+ if (this._forError !== null) {
936
+ // Keep the first error.
937
+ } else if (!this._isRelatedQuery) {
938
+ // Without this check `Model.query().for(1).delete()` would delete all rows.
939
+ this._forError = new Error(
940
+ 'for() can only be used with queries created using the static relatedQuery() method',
941
+ );
942
+ } else if (!this.isFind()) {
943
+ // The owner has already been passed to the write operation.
944
+ this._forError = new Error(
945
+ 'for() must be called before the write methods ' +
946
+ '(insert, update, patch, delete, relate, unrelate, increment, decrement)',
947
+ );
948
+ }
949
+
950
+ this._relatedQueryFor = relatedQueryFor;
951
+ return this;
952
+ }
953
+ }
954
+
955
+ Object.defineProperties(QueryBuilder.prototype, {
956
+ isObjectionQueryBuilder: {
957
+ enumerable: false,
958
+ writable: false,
959
+ value: true,
960
+ },
961
+ });
962
+
963
+ function ensureEagerOperation(builder, algorithm = null) {
964
+ const modelClass = builder.modelClass();
965
+ const defaultGraphOptions = modelClass.getDefaultGraphOptions();
966
+ const eagerOp = builder.findOperation(EagerOperation);
967
+
968
+ if (algorithm) {
969
+ const EagerOperationClass = getOperationClassForEagerAlgorithm(builder, algorithm);
970
+
971
+ if (eagerOp instanceof EagerOperationClass) {
972
+ return eagerOp;
973
+ } else {
974
+ const newEagerOp = new EagerOperationClass('eager', {
975
+ defaultGraphOptions,
976
+ });
977
+
978
+ if (eagerOp) {
979
+ newEagerOp.cloneFrom(eagerOp);
980
+ }
981
+
982
+ builder.clear(EagerOperation);
983
+ builder.addOperation(newEagerOp);
984
+
985
+ return newEagerOp;
986
+ }
987
+ } else {
988
+ if (eagerOp) {
989
+ return eagerOp;
990
+ } else {
991
+ const EagerOperationClass = getOperationClassForEagerAlgorithm(
992
+ builder,
993
+ getWhereInEagerAlgorithm(builder),
994
+ );
995
+
996
+ const newEagerOp = new EagerOperationClass('eager', {
997
+ defaultGraphOptions,
998
+ });
999
+
1000
+ builder.addOperation(newEagerOp);
1001
+
1002
+ return newEagerOp;
1003
+ }
1004
+ }
1005
+ }
1006
+
1007
+ function getWhereInEagerAlgorithm(builder) {
1008
+ return builder.modelClass().WhereInEagerAlgorithm;
1009
+ }
1010
+
1011
+ function getJoinEagerAlgorithm(builder) {
1012
+ return builder.modelClass().JoinEagerAlgorithm;
1013
+ }
1014
+
1015
+ function getNaiveEagerAlgorithm(builder) {
1016
+ return builder.modelClass().NaiveEagerAlgorithm;
1017
+ }
1018
+
1019
+ function getOperationClassForEagerAlgorithm(builder, algorithm) {
1020
+ if (algorithm === getJoinEagerAlgorithm(builder)) {
1021
+ return JoinEagerOperation;
1022
+ } else if (algorithm === getNaiveEagerAlgorithm(builder)) {
1023
+ return NaiveEagerOperation;
1024
+ } else {
1025
+ return WhereInEagerOperation;
1026
+ }
1027
+ }
1028
+
1029
+ function parseRelationExpression(modelClass, exp) {
1030
+ try {
1031
+ return RelationExpression.create(exp);
1032
+ } catch (err) {
1033
+ if (err instanceof DuplicateRelationError) {
1034
+ throw modelClass.createValidationError({
1035
+ type: ValidationErrorType.RelationExpression,
1036
+ message: `Duplicate relation name "${err.relationName}" in relation expression "${exp}". For example, use "${err.relationName}.[foo, bar]" instead of "[${err.relationName}.foo, ${err.relationName}.bar]".`,
1037
+ });
1038
+ } else {
1039
+ throw modelClass.createValidationError({
1040
+ type: ValidationErrorType.RelationExpression,
1041
+ message: `Invalid relation expression "${exp}"`,
1042
+ });
1043
+ }
1044
+ }
1045
+ }
1046
+
1047
+ function checkEager(builder) {
1048
+ const eagerOp = builder.findOperation(EagerOperation);
1049
+
1050
+ if (!eagerOp) {
1051
+ return;
1052
+ }
1053
+
1054
+ const expr = eagerOp.expression;
1055
+ const allowedExpr = builder.allowedGraphExpression();
1056
+
1057
+ if (expr.numChildren > 0 && allowedExpr && !allowedExpr.isSubExpression(expr)) {
1058
+ const modelClass = builder.modelClass();
1059
+
1060
+ builder.reject(
1061
+ modelClass.createValidationError({
1062
+ type: ValidationErrorType.UnallowedRelation,
1063
+ message: 'eager expression not allowed',
1064
+ }),
1065
+ );
1066
+ }
1067
+ }
1068
+
1069
+ function findQueryExecutorOperation(builder) {
1070
+ return builder.findOperation((op) => op.hasQueryExecutor());
1071
+ }
1072
+
1073
+ function checkForUsage(builder) {
1074
+ if (builder._forError !== null) {
1075
+ throw builder._forError;
1076
+ }
1077
+ }
1078
+
1079
+ function beforeExecute(builder) {
1080
+ let promise = Promise.resolve();
1081
+
1082
+ // This needs to be checked before any hooks are called.
1083
+ checkForUsage(builder);
1084
+
1085
+ builder = addImplicitOperations(builder);
1086
+
1087
+ // Resolve all before hooks before building and executing the query
1088
+ // and the rest of the hooks.
1089
+ promise = chainOperationHooks(promise, builder, 'onBefore1');
1090
+ promise = chainOperationHooks(promise, builder, 'onBefore2');
1091
+
1092
+ promise = chainHooks(promise, builder, builder.context().runBefore);
1093
+ promise = chainHooks(promise, builder, builder.internalContext().runBefore);
1094
+
1095
+ promise = chainOperationHooks(promise, builder, 'onBefore3');
1096
+
1097
+ return promise;
1098
+ }
1099
+
1100
+ function doExecute(builder) {
1101
+ let promise = Promise.resolve();
1102
+
1103
+ builder = callOnBuildHooks(builder);
1104
+ const queryExecutorOperation = findQueryExecutorOperation(builder);
1105
+
1106
+ const explicitRejectValue = builder._explicitRejectValue;
1107
+ const explicitResolveValue = builder._explicitResolveValue;
1108
+
1109
+ if (explicitRejectValue !== null) {
1110
+ promise = Promise.reject(explicitRejectValue);
1111
+ } else if (explicitResolveValue !== null) {
1112
+ promise = Promise.resolve(explicitResolveValue);
1113
+ } else if (queryExecutorOperation !== null) {
1114
+ promise = Promise.resolve(queryExecutorOperation.queryExecutor(builder));
1115
+ } else {
1116
+ promise = Promise.resolve(buildKnexQuery(builder));
1117
+
1118
+ promise = chainOperationHooks(promise, builder, 'onRawResult');
1119
+ promise = promise.then((result) => createModels(result, builder));
1120
+ }
1121
+
1122
+ return promise;
1123
+ }
1124
+
1125
+ function afterExecute(builder, result) {
1126
+ let promise = Promise.resolve(result);
1127
+
1128
+ promise = chainOperationHooks(promise, builder, 'onAfter1');
1129
+ promise = chainOperationHooks(promise, builder, 'onAfter2');
1130
+
1131
+ promise = chainHooks(promise, builder, builder.context().runAfter);
1132
+ promise = chainHooks(promise, builder, builder.internalContext().runAfter);
1133
+
1134
+ promise = chainOperationHooks(promise, builder, 'onAfter3');
1135
+
1136
+ return promise;
1137
+ }
1138
+
1139
+ class ReturnImmediatelyException {
1140
+ constructor(value) {
1141
+ this.value = value;
1142
+ }
1143
+ }
1144
+
1145
+ function handleReturnImmediatelyValue(builder) {
1146
+ const { returnImmediatelyValue } = builder.internalOptions();
1147
+ if (returnImmediatelyValue !== undefined) {
1148
+ throw new ReturnImmediatelyException(returnImmediatelyValue);
1149
+ }
1150
+ }
1151
+
1152
+ function handleExecuteError(builder, err) {
1153
+ if (err instanceof ReturnImmediatelyException) {
1154
+ return Promise.resolve(err.value);
1155
+ }
1156
+
1157
+ let promise = Promise.reject(wrapError(err));
1158
+
1159
+ builder.forEachOperation(true, (op) => {
1160
+ if (op.hasOnError()) {
1161
+ promise = promise.catch((err) =>
1162
+ builder.callAsyncOperationMethod(op, 'onError', [builder, err]),
1163
+ );
1164
+ }
1165
+ });
1166
+
1167
+ return promise;
1168
+ }
1169
+
1170
+ function chainOperationHooks(promise, builder, hookName) {
1171
+ return promise.then((result) => {
1172
+ let promise = Promise.resolve(result);
1173
+
1174
+ builder.forEachOperation(true, (op) => {
1175
+ if (op.hasHook(hookName)) {
1176
+ promise = promise.then((result) => {
1177
+ const res = builder.callAsyncOperationMethod(op, hookName, [builder, result]);
1178
+ handleReturnImmediatelyValue(builder);
1179
+ return res;
1180
+ });
1181
+ }
1182
+ });
1183
+
1184
+ return promise;
1185
+ });
1186
+ }
1187
+
1188
+ function ensureJoinRelatedOperation(builder, joinOperation) {
1189
+ const opName = joinOperation + 'Relation';
1190
+ let op = builder.findOperation(opName);
1191
+
1192
+ if (!op) {
1193
+ op = new JoinRelatedOperation(opName, { joinOperation });
1194
+ builder.addOperation(op);
1195
+ }
1196
+
1197
+ return op;
1198
+ }
1199
+
1200
+ function prebuildQuery(builder) {
1201
+ checkForUsage(builder);
1202
+
1203
+ builder = addImplicitOperations(builder);
1204
+ builder = callOnBuildHooks(builder);
1205
+
1206
+ const queryExecutorOperation = findQueryExecutorOperation(builder);
1207
+
1208
+ if (queryExecutorOperation) {
1209
+ return prebuildQuery(queryExecutorOperation.queryExecutor(builder));
1210
+ } else {
1211
+ return builder;
1212
+ }
1213
+ }
1214
+
1215
+ function addImplicitOperations(builder) {
1216
+ if (builder.isFind()) {
1217
+ // If no write operations have been called at this point this query is a
1218
+ // find query and we need to call the custom find implementation.
1219
+ addFindOperation(builder);
1220
+ }
1221
+
1222
+ if (builder.hasWithGraph()) {
1223
+ moveEagerOperationToEnd(builder);
1224
+ }
1225
+
1226
+ return builder;
1227
+ }
1228
+
1229
+ function addFindOperation(builder) {
1230
+ if (!builder.has(FindOperation)) {
1231
+ const operation = builder._findOperationFactory(builder);
1232
+ builder.addOperationToFront(operation, []);
1233
+ }
1234
+ }
1235
+
1236
+ function moveEagerOperationToEnd(builder) {
1237
+ const eagerOp = builder.findOperation(EagerOperation);
1238
+
1239
+ builder.clear(EagerOperation);
1240
+ builder.addOperation(eagerOp);
1241
+ }
1242
+
1243
+ function callOnBuildHooks(builder) {
1244
+ callOnBuildFuncs(builder, builder.context().onBuild);
1245
+ callOnBuildFuncs(builder, builder.internalContext().onBuild);
1246
+
1247
+ builder.executeOnBuild();
1248
+ return builder;
1249
+ }
1250
+
1251
+ function callOnBuildFuncs(builder, func) {
1252
+ if (isFunction(func)) {
1253
+ func.call(builder, builder);
1254
+ } else if (Array.isArray(func)) {
1255
+ func.forEach((func) => callOnBuildFuncs(builder, func));
1256
+ }
1257
+ }
1258
+
1259
+ function buildKnexQuery(builder, knexBuilder = builder.knex().queryBuilder()) {
1260
+ knexBuilder = builder.executeOnBuildKnex(knexBuilder);
1261
+
1262
+ const fromOperation = builder.findLastOperation(QueryBuilderBase.FromSelector);
1263
+
1264
+ if (!builder.isPartial()) {
1265
+ // Set the table only if it hasn't been explicitly set yet.
1266
+ if (!fromOperation) {
1267
+ knexBuilder = setDefaultTable(builder, knexBuilder);
1268
+ }
1269
+
1270
+ // Only add `table.*` select if there are no explicit selects
1271
+ // and `from` is a table name and not a subquery.
1272
+ if (!builder.hasSelects() && (!fromOperation || fromOperation.table)) {
1273
+ knexBuilder = setDefaultSelect(builder, knexBuilder);
1274
+ }
1275
+ }
1276
+
1277
+ return knexBuilder;
1278
+ }
1279
+
1280
+ function setDefaultTable(builder, knexBuilder) {
1281
+ const table = builder.tableName();
1282
+ const tableRef = builder.tableRef();
1283
+
1284
+ if (table === tableRef) {
1285
+ return knexBuilder.table(table);
1286
+ } else {
1287
+ return knexBuilder.table(`${table} as ${tableRef}`);
1288
+ }
1289
+ }
1290
+
1291
+ function setDefaultSelect(builder, knexBuilder) {
1292
+ const tableRef = builder.tableRef();
1293
+
1294
+ return knexBuilder.select(`${tableRef}.*`);
1295
+ }
1296
+
1297
+ async function chainHooks(promise, builder, func) {
1298
+ return promise.then((result) => {
1299
+ let promise = Promise.resolve(result);
1300
+
1301
+ if (isFunction(func)) {
1302
+ promise = promise.then((result) => {
1303
+ const res = func.call(builder, result, builder);
1304
+ handleReturnImmediatelyValue(builder);
1305
+ return res;
1306
+ });
1307
+ } else if (Array.isArray(func)) {
1308
+ func.forEach((func) => {
1309
+ promise = chainHooks(promise, builder, func);
1310
+ });
1311
+ }
1312
+
1313
+ return promise;
1314
+ });
1315
+ }
1316
+
1317
+ function createModels(result, builder) {
1318
+ if (result === null || result === undefined) {
1319
+ return null;
1320
+ }
1321
+
1322
+ if (builder.isInsert()) {
1323
+ // results are applied to input models in `InsertOperation.onAfter1` instead.
1324
+ return result;
1325
+ }
1326
+
1327
+ const modelClass = builder.resultModelClass();
1328
+
1329
+ if (Array.isArray(result)) {
1330
+ if (result.length && shouldBeConvertedToModel(result[0], modelClass)) {
1331
+ for (let i = 0, l = result.length; i < l; ++i) {
1332
+ result[i] = modelClass.fromDatabaseJson(result[i]);
1333
+ }
1334
+ }
1335
+ } else if (shouldBeConvertedToModel(result, modelClass)) {
1336
+ result = modelClass.fromDatabaseJson(result);
1337
+ }
1338
+
1339
+ return result;
1340
+ }
1341
+
1342
+ function shouldBeConvertedToModel(obj, modelClass) {
1343
+ return isObject(obj) && !(obj instanceof modelClass);
1344
+ }
1345
+
1346
+ function writeOperation(builder, cb) {
1347
+ if (!builder.isFind()) {
1348
+ return builder.reject(
1349
+ new Error(
1350
+ 'Double call to a write method. ' +
1351
+ 'You can only call one of the write methods ' +
1352
+ '(insert, update, patch, delete, relate, unrelate, increment, decrement) ' +
1353
+ 'and only once per query builder.',
1354
+ ),
1355
+ );
1356
+ }
1357
+
1358
+ try {
1359
+ cb();
1360
+ return builder;
1361
+ } catch (err) {
1362
+ return builder.reject(err);
1363
+ }
1364
+ }
1365
+
1366
+ function findOperationFactory() {
1367
+ return new FindOperation('find');
1368
+ }
1369
+
1370
+ function insertOperationFactory() {
1371
+ return new InsertOperation('insert');
1372
+ }
1373
+
1374
+ function updateOperationFactory() {
1375
+ return new UpdateOperation('update');
1376
+ }
1377
+
1378
+ function patchOperationFactory() {
1379
+ return new UpdateOperation('patch', {
1380
+ modelOptions: { patch: true },
1381
+ });
1382
+ }
1383
+
1384
+ function relateOperationFactory() {
1385
+ return new RelateOperation('relate', {});
1386
+ }
1387
+
1388
+ function unrelateOperationFactory() {
1389
+ return new UnrelateOperation('unrelate', {});
1390
+ }
1391
+
1392
+ function deleteOperationFactory() {
1393
+ return new DeleteOperation('delete');
1394
+ }
1395
+
1396
+ module.exports = {
1397
+ QueryBuilder,
1398
+ };