@abedmurrar/objection 0.0.0-stage → 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 (190) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +105 -2
  3. package/lib/index.mjs +6 -0
  4. package/lib/initialize.js +11 -0
  5. package/lib/model/AjvValidator.js +278 -0
  6. package/lib/model/Model.js +772 -0
  7. package/lib/model/ModifierNotFoundError.js +10 -0
  8. package/lib/model/NotFoundError.js +19 -0
  9. package/lib/model/RelationDoesNotExistError.js +11 -0
  10. package/lib/model/ValidationError.js +46 -0
  11. package/lib/model/Validator.js +20 -0
  12. package/lib/model/getModel.js +7 -0
  13. package/lib/model/graph/ModelGraph.js +60 -0
  14. package/lib/model/graph/ModelGraphBuilder.js +188 -0
  15. package/lib/model/graph/ModelGraphEdge.js +40 -0
  16. package/lib/model/graph/ModelGraphNode.js +201 -0
  17. package/lib/model/inheritModel.js +19 -0
  18. package/lib/model/modelBindKnex.js +69 -0
  19. package/lib/model/modelClone.js +102 -0
  20. package/lib/model/modelColPropMap.js +24 -0
  21. package/lib/model/modelConcurrency.js +24 -0
  22. package/lib/model/modelId.js +57 -0
  23. package/lib/model/modelJsonAttributes.js +72 -0
  24. package/lib/model/modelParseRelations.js +83 -0
  25. package/lib/model/modelQueryProps.js +116 -0
  26. package/lib/model/modelSet.js +116 -0
  27. package/lib/model/modelTableMetadata.js +71 -0
  28. package/lib/model/modelToJson.js +157 -0
  29. package/lib/model/modelUtils.js +40 -0
  30. package/lib/model/modelValidate.js +40 -0
  31. package/lib/model/modelValues.js +113 -0
  32. package/lib/model/modelVisitor.js +34 -0
  33. package/lib/objection.js +89 -0
  34. package/lib/queryBuilder/FunctionBuilder.js +291 -0
  35. package/lib/queryBuilder/InternalOptions.js +24 -0
  36. package/lib/queryBuilder/JoinBuilder.js +124 -0
  37. package/lib/queryBuilder/QueryBuilder.js +1136 -0
  38. package/lib/queryBuilder/QueryBuilderBase.js +666 -0
  39. package/lib/queryBuilder/QueryBuilderContext.js +20 -0
  40. package/lib/queryBuilder/QueryBuilderContextBase.js +26 -0
  41. package/lib/queryBuilder/QueryBuilderOperationSupport.js +484 -0
  42. package/lib/queryBuilder/QueryBuilderUserContext.js +25 -0
  43. package/lib/queryBuilder/RawBuilder.js +78 -0
  44. package/lib/queryBuilder/ReferenceBuilder.js +246 -0
  45. package/lib/queryBuilder/RelationExpression.js +373 -0
  46. package/lib/queryBuilder/StaticHookArguments.js +122 -0
  47. package/lib/queryBuilder/ValueBuilder.js +115 -0
  48. package/lib/queryBuilder/expressions.js +121 -0
  49. package/lib/queryBuilder/functions/mysql.js +762 -0
  50. package/lib/queryBuilder/graph/GraphAction.js +54 -0
  51. package/lib/queryBuilder/graph/GraphData.js +12 -0
  52. package/lib/queryBuilder/graph/GraphFetcher.js +155 -0
  53. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +146 -0
  54. package/lib/queryBuilder/graph/GraphOperation.js +21 -0
  55. package/lib/queryBuilder/graph/GraphOptions.js +165 -0
  56. package/lib/queryBuilder/graph/GraphUpsert.js +231 -0
  57. package/lib/queryBuilder/graph/delete/GraphDelete.js +15 -0
  58. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +56 -0
  59. package/lib/queryBuilder/graph/insert/GraphInsert.js +116 -0
  60. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +183 -0
  61. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +70 -0
  62. package/lib/queryBuilder/graph/patch/GraphPatch.js +15 -0
  63. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +205 -0
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +26 -0
  65. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +96 -0
  66. package/lib/queryBuilder/join/JoinResultColumn.js +19 -0
  67. package/lib/queryBuilder/join/JoinResultParser.js +106 -0
  68. package/lib/queryBuilder/join/RelationJoiner.js +258 -0
  69. package/lib/queryBuilder/join/TableNode.js +136 -0
  70. package/lib/queryBuilder/join/TableTree.js +69 -0
  71. package/lib/queryBuilder/join/utils.js +19 -0
  72. package/lib/queryBuilder/operations/DelegateOperation.js +101 -0
  73. package/lib/queryBuilder/operations/DeleteOperation.js +47 -0
  74. package/lib/queryBuilder/operations/FindByIdOperation.js +29 -0
  75. package/lib/queryBuilder/operations/FindByIdsOperation.js +23 -0
  76. package/lib/queryBuilder/operations/FindOperation.js +147 -0
  77. package/lib/queryBuilder/operations/FirstOperation.js +22 -0
  78. package/lib/queryBuilder/operations/FromOperation.js +91 -0
  79. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +38 -0
  80. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +35 -0
  81. package/lib/queryBuilder/operations/InsertGraphOperation.js +87 -0
  82. package/lib/queryBuilder/operations/InsertOperation.js +173 -0
  83. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +37 -0
  84. package/lib/queryBuilder/operations/InstanceFindOperation.js +17 -0
  85. package/lib/queryBuilder/operations/InstanceInsertOperation.js +20 -0
  86. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +45 -0
  87. package/lib/queryBuilder/operations/JoinRelatedOperation.js +83 -0
  88. package/lib/queryBuilder/operations/KnexOperation.js +11 -0
  89. package/lib/queryBuilder/operations/MergeOperation.js +43 -0
  90. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +173 -0
  91. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +23 -0
  92. package/lib/queryBuilder/operations/OnBuildOperation.js +23 -0
  93. package/lib/queryBuilder/operations/OnErrorOperation.js +23 -0
  94. package/lib/queryBuilder/operations/QueryBuilderOperation.js +258 -0
  95. package/lib/queryBuilder/operations/RangeOperation.js +37 -0
  96. package/lib/queryBuilder/operations/RelateOperation.js +20 -0
  97. package/lib/queryBuilder/operations/ReturningOperation.js +24 -0
  98. package/lib/queryBuilder/operations/RunAfterOperation.js +23 -0
  99. package/lib/queryBuilder/operations/RunBeforeOperation.js +23 -0
  100. package/lib/queryBuilder/operations/UnrelateOperation.js +18 -0
  101. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +63 -0
  102. package/lib/queryBuilder/operations/UpdateOperation.js +130 -0
  103. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +35 -0
  104. package/lib/queryBuilder/operations/UpsertGraphOperation.js +47 -0
  105. package/lib/queryBuilder/operations/WhereCompositeOperation.js +48 -0
  106. package/lib/queryBuilder/operations/WhereInOperation.js +46 -0
  107. package/lib/queryBuilder/operations/eager/EagerOperation.js +46 -0
  108. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +41 -0
  109. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +10 -0
  110. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +227 -0
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +29 -0
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +37 -0
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +30 -0
  114. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +33 -0
  115. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +155 -0
  116. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +135 -0
  117. package/lib/queryBuilder/operations/select/SelectOperation.js +50 -0
  118. package/lib/queryBuilder/operations/select/Selection.js +112 -0
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +84 -0
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +90 -0
  121. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +95 -0
  122. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +787 -0
  123. package/lib/queryBuilder/parsers/relationExpressionParser.js +930 -0
  124. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +17 -0
  125. package/lib/queryBuilder/transformations/QueryTransformation.js +9 -0
  126. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +57 -0
  127. package/lib/queryBuilder/transformations/index.js +9 -0
  128. package/lib/queryBuilder/whereScopes.js +199 -0
  129. package/lib/relations/Relation.js +317 -0
  130. package/lib/relations/RelationDeleteOperation.js +23 -0
  131. package/lib/relations/RelationFindOperation.js +116 -0
  132. package/lib/relations/RelationInsertOperation.js +25 -0
  133. package/lib/relations/RelationOwner.js +199 -0
  134. package/lib/relations/RelationProperty.js +207 -0
  135. package/lib/relations/RelationUpdateOperation.js +23 -0
  136. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +18 -0
  137. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +33 -0
  138. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +39 -0
  139. package/lib/relations/belongsToOne/BelongsToOneRelation.js +45 -0
  140. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +46 -0
  141. package/lib/relations/hasMany/HasManyInsertOperation.js +45 -0
  142. package/lib/relations/hasMany/HasManyRelateOperation.js +48 -0
  143. package/lib/relations/hasMany/HasManyRelation.js +41 -0
  144. package/lib/relations/hasMany/HasManyUnrelateOperation.js +26 -0
  145. package/lib/relations/hasOne/HasOneRelation.js +10 -0
  146. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +10 -0
  147. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +82 -0
  148. package/lib/relations/manyToMany/ManyToManyRelation.js +405 -0
  149. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +29 -0
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -0
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -0
  152. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -0
  153. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +82 -0
  154. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +40 -0
  155. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +64 -0
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +11 -0
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +27 -0
  158. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +11 -0
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -0
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +65 -0
  161. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -0
  162. package/lib/transaction.js +66 -0
  163. package/lib/utils/assert.js +19 -0
  164. package/lib/utils/buildUtils.js +19 -0
  165. package/lib/utils/classUtils.js +9 -0
  166. package/lib/utils/cloneDeep.js +365 -0
  167. package/lib/utils/createModifier.js +37 -0
  168. package/lib/utils/deprecate.js +11 -0
  169. package/lib/utils/identifierMapping.js +188 -0
  170. package/lib/utils/internalPropUtils.js +7 -0
  171. package/lib/utils/knexUtils.js +81 -0
  172. package/lib/utils/mixin.js +18 -0
  173. package/lib/utils/mysqlJsonPath.js +70 -0
  174. package/lib/utils/normalizeIds.js +127 -0
  175. package/lib/utils/objectUtils.js +314 -0
  176. package/lib/utils/parseFieldExpression.js +73 -0
  177. package/lib/utils/postgresJsonPath.js +96 -0
  178. package/lib/utils/promiseUtils/after.js +14 -0
  179. package/lib/utils/promiseUtils/afterReturn.js +14 -0
  180. package/lib/utils/promiseUtils/index.js +15 -0
  181. package/lib/utils/promiseUtils/isPromise.js +8 -0
  182. package/lib/utils/promiseUtils/map.js +96 -0
  183. package/lib/utils/promiseUtils/mapAfterAllReturn.js +23 -0
  184. package/lib/utils/promiseUtils/try.js +19 -0
  185. package/lib/utils/resolveModel.js +104 -0
  186. package/lib/utils/tmpColumnUtils.js +7 -0
  187. package/package.json +113 -4
  188. package/typings/objection/index.d.mts +362 -0
  189. package/typings/objection/index.d.ts +4131 -0
  190. package/typings/objection/relation-expression.d.ts +237 -0
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+ const { InternalOptions } = require('./InternalOptions');
3
+ class QueryBuilderContextBase {
4
+ constructor(builder) {
5
+ this.userContext = builder ? new builder.constructor.QueryBuilderUserContext(builder) : null;
6
+ this.options = builder ? new this.constructor.InternalOptions() : null;
7
+ this.knex = null;
8
+ this.aliasMap = null;
9
+ this.tableMap = null;
10
+ }
11
+ static get InternalOptions() {
12
+ return InternalOptions;
13
+ }
14
+ clone() {
15
+ const ctx = new this.constructor();
16
+ ctx.userContext = this.userContext;
17
+ ctx.options = this.options.clone();
18
+ ctx.knex = this.knex;
19
+ ctx.aliasMap = this.aliasMap;
20
+ ctx.tableMap = this.tableMap;
21
+ return ctx;
22
+ }
23
+ }
24
+ module.exports = {
25
+ QueryBuilderContextBase,
26
+ };
@@ -0,0 +1,484 @@
1
+ 'use strict';
2
+ const { isString, isFunction, isRegExp, mergeMaps, last } = require('../utils/objectUtils');
3
+ const { QueryBuilderContextBase } = require('./QueryBuilderContextBase');
4
+ const { QueryBuilderUserContext } = require('./QueryBuilderUserContext');
5
+ const { deprecate } = require('../utils/deprecate');
6
+ const { effectiveWhereScope, createWhereGrouping } = require('./whereScopes');
7
+ const AllSelector = () => true;
8
+ const SelectSelector = /^(select|columns|column|distinct|count|countDistinct|min|max|sum|sumDistinct|avg|avgDistinct)$/;
9
+ const WhereSelector = /^(where|orWhere|andWhere|find\w+)/;
10
+ const OnSelector = /^(on|orOn|andOn)/;
11
+ const OrderBySelector = /orderBy/;
12
+ const JoinSelector = /(join|joinRaw|joinRelated)$/i;
13
+ const FromSelector = /^(from|fromRaw|into|table)$/;
14
+ class QueryBuilderOperationSupport {
15
+ constructor(...args) {
16
+ this.constructor.init(this, ...args);
17
+ }
18
+ static init(self, modelClass) {
19
+ self._modelClass = modelClass;
20
+ self._operations = [];
21
+ self._context = new this.QueryBuilderContext(self);
22
+ self._parentQuery = null;
23
+ self._isPartialQuery = false;
24
+ self._activeOperations = [];
25
+ self._whereScope = null;
26
+ }
27
+ static forClass(modelClass) {
28
+ return new this(modelClass);
29
+ }
30
+ static get AllSelector() {
31
+ return AllSelector;
32
+ }
33
+ static get QueryBuilderContext() {
34
+ return QueryBuilderContextBase;
35
+ }
36
+ static get QueryBuilderUserContext() {
37
+ return QueryBuilderUserContext;
38
+ }
39
+ static get SelectSelector() {
40
+ return SelectSelector;
41
+ }
42
+ static get WhereSelector() {
43
+ return WhereSelector;
44
+ }
45
+ static get OnSelector() {
46
+ return OnSelector;
47
+ }
48
+ static get JoinSelector() {
49
+ return JoinSelector;
50
+ }
51
+ static get FromSelector() {
52
+ return FromSelector;
53
+ }
54
+ static get OrderBySelector() {
55
+ return OrderBySelector;
56
+ }
57
+ modelClass() {
58
+ return this._modelClass;
59
+ }
60
+ context(obj) {
61
+ const ctx = this._context;
62
+ if (arguments.length === 0) {
63
+ return ctx.userContext;
64
+ }
65
+ else {
66
+ ctx.userContext = ctx.userContext.newMerge(this, obj);
67
+ return this;
68
+ }
69
+ }
70
+ clearContext() {
71
+ const ctx = this._context;
72
+ ctx.userContext = new this.constructor.QueryBuilderUserContext(this);
73
+ return this;
74
+ }
75
+ internalContext(ctx) {
76
+ if (arguments.length === 0) {
77
+ return this._context;
78
+ }
79
+ else {
80
+ this._context = ctx;
81
+ return this;
82
+ }
83
+ }
84
+ internalOptions(opt) {
85
+ if (arguments.length === 0) {
86
+ return this._context.options;
87
+ }
88
+ else {
89
+ const oldOpt = this._context.options;
90
+ this._context.options = Object.assign(oldOpt, opt);
91
+ return this;
92
+ }
93
+ }
94
+ isPartial(isPartial) {
95
+ if (arguments.length === 0) {
96
+ return this._isPartialQuery;
97
+ }
98
+ else {
99
+ this._isPartialQuery = isPartial;
100
+ return this;
101
+ }
102
+ }
103
+ isInternal() {
104
+ return this.internalOptions().isInternalQuery;
105
+ }
106
+ tableNameFor(modelClassOrTableName, newTableName) {
107
+ const tableName = getTableName(modelClassOrTableName);
108
+ const ctx = this.internalContext();
109
+ const tableMap = ctx.tableMap;
110
+ if (isString(newTableName)) {
111
+ ctx.tableMap = tableMap || new Map();
112
+ ctx.tableMap.set(tableName, newTableName);
113
+ return this;
114
+ }
115
+ else {
116
+ return (tableMap && tableMap.get(tableName)) || tableName;
117
+ }
118
+ }
119
+ aliasFor(modelClassOrTableName, alias) {
120
+ const tableName = getTableName(modelClassOrTableName);
121
+ const ctx = this.internalContext();
122
+ const aliasMap = ctx.aliasMap;
123
+ if (isString(alias)) {
124
+ ctx.aliasMap = aliasMap || new Map();
125
+ ctx.aliasMap.set(tableName, alias);
126
+ return this;
127
+ }
128
+ else {
129
+ return (aliasMap && aliasMap.get(tableName)) || null;
130
+ }
131
+ }
132
+ tableRefFor(modelClassOrTableName) {
133
+ return this.aliasFor(modelClassOrTableName) || this.tableNameFor(modelClassOrTableName);
134
+ }
135
+ childQueryOf(query, { fork, isInternalQuery } = {}) {
136
+ if (query) {
137
+ const currentCtx = this.context();
138
+ let ctx = query.internalContext();
139
+ if (fork) {
140
+ ctx = ctx.clone();
141
+ }
142
+ if (isInternalQuery) {
143
+ ctx.options.isInternalQuery = true;
144
+ }
145
+ this._parentQuery = query;
146
+ this.internalContext(ctx);
147
+ this.context(currentCtx);
148
+ // Use the parent's knex if there was no knex in `ctx`.
149
+ if (this.unsafeKnex() === null) {
150
+ this.knex(query.unsafeKnex());
151
+ }
152
+ }
153
+ return this;
154
+ }
155
+ subqueryOf(query) {
156
+ if (query) {
157
+ if (this._isPartialQuery) {
158
+ // Merge alias and table name maps for "partial" subqueries.
159
+ const ctx = this.internalContext();
160
+ ctx.aliasMap = mergeMaps(query.internalContext().aliasMap, ctx.aliasMap);
161
+ ctx.tableMap = mergeMaps(query.internalContext().tableMap, ctx.tableMap);
162
+ }
163
+ this._parentQuery = query;
164
+ if (this.unsafeKnex() === null) {
165
+ this.knex(query.unsafeKnex());
166
+ }
167
+ }
168
+ return this;
169
+ }
170
+ parentQuery() {
171
+ return this._parentQuery;
172
+ }
173
+ knex(...args) {
174
+ if (args.length === 0) {
175
+ const knex = this.unsafeKnex();
176
+ if (!knex) {
177
+ throw new Error(`no database connection available for a query. You need to bind the model class or the query to a knex instance.`);
178
+ }
179
+ return knex;
180
+ }
181
+ else {
182
+ this._context.knex = args[0];
183
+ return this;
184
+ }
185
+ }
186
+ unsafeKnex() {
187
+ return this._context.knex || this._modelClass.knex() || null;
188
+ }
189
+ clear(operationSelector) {
190
+ const operationsToRemove = new Set();
191
+ this.forEachOperation(operationSelector, (op) => {
192
+ // If an ancestor operation has already been removed,
193
+ // there's no need to remove the children anymore.
194
+ if (!op.isAncestorInSet(operationsToRemove)) {
195
+ operationsToRemove.add(op);
196
+ }
197
+ });
198
+ for (const op of operationsToRemove) {
199
+ this.removeOperation(op);
200
+ }
201
+ return this;
202
+ }
203
+ toFindQuery() {
204
+ const findQuery = this.clone();
205
+ const operationsToReplace = [];
206
+ const operationsToRemove = [];
207
+ findQuery.forEachOperation((op) => op.hasToFindOperation(), (op) => {
208
+ const findOp = op.toFindOperation(findQuery);
209
+ if (!findOp) {
210
+ operationsToRemove.push(op);
211
+ }
212
+ else {
213
+ operationsToReplace.push({ op, findOp });
214
+ }
215
+ });
216
+ for (const op of operationsToRemove) {
217
+ findQuery.removeOperation(op);
218
+ }
219
+ for (const { op, findOp } of operationsToReplace) {
220
+ findQuery.replaceOperation(op, findOp);
221
+ }
222
+ return findQuery;
223
+ }
224
+ clearSelect() {
225
+ return this.clear(SelectSelector);
226
+ }
227
+ clearWhere() {
228
+ return this.clear(WhereSelector);
229
+ }
230
+ clearOrder() {
231
+ return this.clear(OrderBySelector);
232
+ }
233
+ copyFrom(queryBuilder, operationSelector) {
234
+ const operationsToAdd = new Set();
235
+ queryBuilder.forEachOperation(operationSelector, (op) => {
236
+ // If an ancestor operation has already been added,
237
+ // there is no need to add
238
+ if (!op.isAncestorInSet(operationsToAdd)) {
239
+ operationsToAdd.add(op);
240
+ }
241
+ });
242
+ for (const op of operationsToAdd) {
243
+ const opClone = op.clone();
244
+ // The scope may come from a parent operation that is not copied.
245
+ opClone.whereScope = effectiveWhereScope(op);
246
+ // We may be moving nested operations to the root. Clear
247
+ // any links to the parent operations.
248
+ opClone.parentOperation = null;
249
+ opClone.adderHookName = null;
250
+ // We don't use `addOperation` here because we don't what to
251
+ // call `onAdd` or add these operations as child operations.
252
+ this._operations.push(opClone);
253
+ }
254
+ return this;
255
+ }
256
+ has(operationSelector) {
257
+ return !!this.findOperation(operationSelector);
258
+ }
259
+ forEachOperation(operationSelector, callback, match = true) {
260
+ visitOperations(this._operations, selectorKind(operationSelector), operationSelector, callback, match);
261
+ return this;
262
+ }
263
+ findOperation(operationSelector) {
264
+ let op = null;
265
+ this.forEachOperation(operationSelector, (it) => {
266
+ op = it;
267
+ return false;
268
+ });
269
+ return op;
270
+ }
271
+ findLastOperation(operationSelector) {
272
+ let op = null;
273
+ this.forEachOperation(operationSelector, (it) => {
274
+ op = it;
275
+ });
276
+ return op;
277
+ }
278
+ everyOperation(operationSelector) {
279
+ let every = true;
280
+ this.forEachOperation(operationSelector, () => {
281
+ every = false;
282
+ return false;
283
+ }, false);
284
+ return every;
285
+ }
286
+ callOperationMethod(operation, hookName, args) {
287
+ try {
288
+ operation.removeChildOperationsByHookName(hookName);
289
+ this._activeOperations.push({
290
+ operation,
291
+ hookName,
292
+ });
293
+ return operation[hookName](...args);
294
+ }
295
+ finally {
296
+ this._activeOperations.pop();
297
+ }
298
+ }
299
+ async callAsyncOperationMethod(operation, hookName, args) {
300
+ operation.removeChildOperationsByHookName(hookName);
301
+ this._activeOperations.push({
302
+ operation,
303
+ hookName,
304
+ });
305
+ try {
306
+ return await operation[hookName](...args);
307
+ }
308
+ finally {
309
+ this._activeOperations.pop();
310
+ }
311
+ }
312
+ addOperation(operation, args) {
313
+ const ret = this.addOperationUsingMethod('push', operation, args);
314
+ return ret;
315
+ }
316
+ addOperationToFront(operation, args) {
317
+ return this.addOperationUsingMethod('unshift', operation, args);
318
+ }
319
+ addOperationUsingMethod(arrayMethod, operation, args) {
320
+ const shouldAdd = this.callOperationMethod(operation, 'onAdd', [this, args]);
321
+ if (shouldAdd) {
322
+ if (this._whereScope !== null && operation.whereScope === null) {
323
+ operation.whereScope = this._whereScope;
324
+ }
325
+ if (this._activeOperations.length) {
326
+ const { operation: parentOperation, hookName } = last(this._activeOperations);
327
+ parentOperation.addChildOperation(hookName, operation);
328
+ }
329
+ else {
330
+ this._operations[arrayMethod](operation);
331
+ }
332
+ }
333
+ return this;
334
+ }
335
+ removeOperation(operation) {
336
+ if (operation.parentOperation) {
337
+ operation.parentOperation.removeChildOperation(operation);
338
+ }
339
+ else {
340
+ const index = this._operations.indexOf(operation);
341
+ if (index !== -1) {
342
+ this._operations.splice(index, 1);
343
+ }
344
+ }
345
+ return this;
346
+ }
347
+ replaceOperation(operation, newOperation) {
348
+ if (operation.parentOperation) {
349
+ operation.parentOperation.replaceChildOperation(operation, newOperation);
350
+ }
351
+ else {
352
+ const index = this._operations.indexOf(operation);
353
+ if (index !== -1) {
354
+ this._operations[index] = newOperation;
355
+ }
356
+ }
357
+ return this;
358
+ }
359
+ clone() {
360
+ return this.baseCloneInto(new this.constructor(this.unsafeKnex()));
361
+ }
362
+ baseCloneInto(builder) {
363
+ builder._modelClass = this._modelClass;
364
+ builder._operations = this._operations.map((it) => it.clone());
365
+ builder._context = this._context.clone();
366
+ builder._parentQuery = this._parentQuery;
367
+ builder._isPartialQuery = this._isPartialQuery;
368
+ // Don't copy the active operation stack. We never continue (nor can we)
369
+ // a query from the exact mid-hook-call state.
370
+ builder._activeOperations = [];
371
+ return builder;
372
+ }
373
+ toKnexQuery(knexBuilder = this.knex().queryBuilder()) {
374
+ this.executeOnBuild();
375
+ return this.executeOnBuildKnex(knexBuilder);
376
+ }
377
+ executeOnBuild() {
378
+ this.forEachOperation(true, (op) => {
379
+ if (op.hasOnBuild()) {
380
+ this.callOperationMethod(op, 'onBuild', [this]);
381
+ }
382
+ });
383
+ }
384
+ executeOnBuildKnex(knexBuilder) {
385
+ const whereGrouping = createWhereGrouping(this);
386
+ this.forEachOperation(true, (op) => {
387
+ if (whereGrouping !== null && whereGrouping.isGrouped(op)) {
388
+ knexBuilder = whereGrouping.build(op, knexBuilder);
389
+ }
390
+ else if (op.hasOnBuildKnex()) {
391
+ const newKnexBuilder = this.callOperationMethod(op, 'onBuildKnex', [knexBuilder, this]);
392
+ // Default to the input knex builder for backwards compatibility
393
+ // with QueryBuilder.onBuildKnex hooks.
394
+ knexBuilder = newKnexBuilder || knexBuilder;
395
+ }
396
+ });
397
+ return knexBuilder;
398
+ }
399
+ toString() {
400
+ return this.toKnexQuery().toString();
401
+ }
402
+ toSql() {
403
+ return this.toString();
404
+ }
405
+ skipUndefined() {
406
+ deprecate('skipUndefined() is deprecated and will be removed in objection 4.0');
407
+ this.internalOptions().skipUndefined = true;
408
+ return this;
409
+ }
410
+ }
411
+ // Operation selectors are `true` (every operation), a regex or a string that
412
+ // is matched against the operation name, an operation class, or a predicate.
413
+ // Queries walk their operations many times, so the selector is classified
414
+ // once per walk instead of being wrapped in a new function.
415
+ const SELECT_ALL = 0;
416
+ const SELECT_REGEX = 1;
417
+ const SELECT_NAME = 2;
418
+ const SELECT_CLASS = 3;
419
+ const SELECT_PREDICATE = 4;
420
+ const SELECT_NONE = 5;
421
+ function selectorKind(operationSelector) {
422
+ if (operationSelector === true) {
423
+ return SELECT_ALL;
424
+ }
425
+ else if (isRegExp(operationSelector)) {
426
+ return SELECT_REGEX;
427
+ }
428
+ else if (isString(operationSelector)) {
429
+ return SELECT_NAME;
430
+ }
431
+ else if (isFunction(operationSelector) &&
432
+ operationSelector.isObjectionQueryBuilderOperationClass) {
433
+ return SELECT_CLASS;
434
+ }
435
+ else if (isFunction(operationSelector)) {
436
+ return SELECT_PREDICATE;
437
+ }
438
+ else {
439
+ return SELECT_NONE;
440
+ }
441
+ }
442
+ function matchesSelector(op, kind, operationSelector) {
443
+ switch (kind) {
444
+ case SELECT_ALL:
445
+ return true;
446
+ case SELECT_REGEX:
447
+ return operationSelector.test(op.name);
448
+ case SELECT_NAME:
449
+ return op.name === operationSelector;
450
+ case SELECT_CLASS:
451
+ return op.is(operationSelector);
452
+ case SELECT_PREDICATE:
453
+ return operationSelector(op);
454
+ default:
455
+ return false;
456
+ }
457
+ }
458
+ // Visits the operations and their descendants depth first, each operation
459
+ // before its children. Returns false if the callback stopped the walk by
460
+ // returning false. The arrays are read as the walk goes, so operations that
461
+ // the callback adds are visited too, as before.
462
+ function visitOperations(operations, kind, operationSelector, callback, match) {
463
+ for (const op of operations) {
464
+ if (matchesSelector(op, kind, operationSelector) === match && callback(op) === false) {
465
+ return false;
466
+ }
467
+ if (op.childOperations.length !== 0 &&
468
+ visitOperations(op.childOperations, kind, operationSelector, callback, match) === false) {
469
+ return false;
470
+ }
471
+ }
472
+ return true;
473
+ }
474
+ function getTableName(modelClassOrTableName) {
475
+ if (isString(modelClassOrTableName)) {
476
+ return modelClassOrTableName;
477
+ }
478
+ else {
479
+ return modelClassOrTableName.getTableName();
480
+ }
481
+ }
482
+ module.exports = {
483
+ QueryBuilderOperationSupport,
484
+ };
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+ const SYMBOL_BUILDER = Symbol();
3
+ class QueryBuilderUserContext {
4
+ constructor(builder) {
5
+ // This should never ever be accessed outside this class. We only
6
+ // store it so that we can access builder.knex() lazily.
7
+ this[SYMBOL_BUILDER] = builder;
8
+ }
9
+ get transaction() {
10
+ return this[SYMBOL_BUILDER].knex();
11
+ }
12
+ newFromObject(builder, obj) {
13
+ const ctx = new this.constructor(builder);
14
+ Object.assign(ctx, obj);
15
+ return ctx;
16
+ }
17
+ newMerge(builder, obj) {
18
+ const ctx = new this.constructor(builder);
19
+ Object.assign(ctx, this, obj);
20
+ return ctx;
21
+ }
22
+ }
23
+ module.exports = {
24
+ QueryBuilderUserContext,
25
+ };
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+ const { isPlainObject } = require('../utils/objectUtils');
3
+ const { buildArg } = require('../utils/buildUtils');
4
+ const { addExpressionMethods } = require('./expressions');
5
+ class RawBuilder {
6
+ constructor(sql, args) {
7
+ this._sql = `${sql}`;
8
+ this._args = args;
9
+ this._as = null;
10
+ }
11
+ get alias() {
12
+ return this._as;
13
+ }
14
+ as(as) {
15
+ this._as = as;
16
+ return this;
17
+ }
18
+ toKnexRaw(builder) {
19
+ let args = null;
20
+ let sql = this._sql;
21
+ if (this._args.length === 1 && isPlainObject(this._args[0])) {
22
+ args = buildObject(this._args[0], builder);
23
+ if (this._as) {
24
+ args.__alias__ = this._as;
25
+ sql += ' as :__alias__:';
26
+ }
27
+ }
28
+ else {
29
+ args = buildArray(this._args, builder);
30
+ if (this._as) {
31
+ args.push(this._as);
32
+ sql += ' as ??';
33
+ }
34
+ }
35
+ return builder.knex().raw(sql, args);
36
+ }
37
+ }
38
+ Object.defineProperties(RawBuilder.prototype, {
39
+ isObjectionRawBuilder: {
40
+ enumerable: false,
41
+ writable: false,
42
+ value: true,
43
+ },
44
+ });
45
+ addExpressionMethods(RawBuilder.prototype);
46
+ function buildArray(arr, builder) {
47
+ return arr.map((it) => buildArg(it, builder));
48
+ }
49
+ function buildObject(obj, builder) {
50
+ return Object.keys(obj).reduce((args, key) => {
51
+ args[key] = buildArg(obj[key], builder);
52
+ return args;
53
+ }, {});
54
+ }
55
+ function normalizeRawArgs(argsIn) {
56
+ const [sql, ...restArgs] = argsIn;
57
+ if (restArgs.length === 1 && Array.isArray(restArgs[0])) {
58
+ return {
59
+ sql,
60
+ args: restArgs[0],
61
+ };
62
+ }
63
+ else {
64
+ return {
65
+ sql,
66
+ args: restArgs,
67
+ };
68
+ }
69
+ }
70
+ function raw(...argsIn) {
71
+ const { sql, args } = normalizeRawArgs(argsIn);
72
+ return new RawBuilder(sql, args);
73
+ }
74
+ module.exports = {
75
+ RawBuilder,
76
+ normalizeRawArgs,
77
+ raw,
78
+ };