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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +293 -375
  129. package/lib/relations/RelationDeleteOperation.js +24 -28
  130. package/lib/relations/RelationFindOperation.js +108 -138
  131. package/lib/relations/RelationInsertOperation.js +24 -32
  132. package/lib/relations/RelationOwner.js +175 -209
  133. package/lib/relations/RelationProperty.js +186 -223
  134. package/lib/relations/RelationUpdateOperation.js +23 -29
  135. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +16 -21
  136. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +30 -41
  137. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +36 -47
  138. package/lib/relations/belongsToOne/BelongsToOneRelation.js +42 -50
  139. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +43 -58
  140. package/lib/relations/hasMany/HasManyInsertOperation.js +40 -56
  141. package/lib/relations/hasMany/HasManyRelateOperation.js +45 -61
  142. package/lib/relations/hasMany/HasManyRelation.js +38 -46
  143. package/lib/relations/hasMany/HasManyUnrelateOperation.js +25 -32
  144. package/lib/relations/hasOne/HasOneRelation.js +9 -12
  145. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +9 -12
  146. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +73 -95
  147. package/lib/relations/manyToMany/ManyToManyRelation.js +374 -473
  148. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +23 -30
  149. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -10
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -25
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -12
  152. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +77 -100
  153. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +37 -49
  154. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +58 -74
  155. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +10 -13
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +26 -33
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +10 -15
  158. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -10
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +61 -78
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -12
  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,284 +1,246 @@
1
1
  'use strict';
2
-
3
2
  const { parseFieldExpression } = require('../utils/parseFieldExpression');
4
3
  const { isObject } = require('../utils/objectUtils');
5
- const { isMySql } = require('../utils/knexUtils');
4
+ const { isMySql, isMariaDb } = require('../utils/knexUtils');
6
5
  const { toPgJsonPathLiteral, getJsonDialect } = require('../utils/postgresJsonPath');
7
- const { toMySqlJsonPath, toMySqlCastType, isBooleanType } = require('../utils/mysqlJsonPath');
6
+ const { toMySqlJsonPath, toMySqlCastType, isBooleanType, toJsonSql, } = require('../utils/mysqlJsonPath');
8
7
  const { addExpressionMethods } = require('./expressions');
9
-
10
8
  class ReferenceBuilder {
11
- constructor(expr) {
12
- this._expr = expr;
13
- this._parsedExpr = null;
14
- this._column = null;
15
- this._table = null;
16
- this._cast = null;
17
- this._toJson = false;
18
- this._table = null;
19
- this._alias = null;
20
- this._modelClass = null;
21
-
22
- // This `if` makes it possible for `clone` to skip
23
- // parsing the expression again.
24
- if (expr !== null) {
25
- this._parseExpression(expr);
26
- }
27
- }
28
-
29
- get parsedExpr() {
30
- return this._parsedExpr;
31
- }
32
-
33
- get column() {
34
- return this._column;
35
- }
36
-
37
- set column(column) {
38
- this._column = column;
39
- }
40
-
41
- get alias() {
42
- return this._alias;
43
- }
44
-
45
- set alias(alias) {
46
- this._alias = alias;
47
- }
48
-
49
- get tableName() {
50
- return this._table;
51
- }
52
-
53
- set tableName(table) {
54
- this._table = table;
55
- }
56
-
57
- get modelClass() {
58
- return this._modelClass;
59
- }
60
-
61
- set modelClass(modelClass) {
62
- this._modelClass = modelClass;
63
- }
64
-
65
- get isPlainColumnRef() {
66
- return (
67
- (!this._parsedExpr || this._parsedExpr.access.length === 0) && !this._cast && !this._toJson
68
- );
69
- }
70
-
71
- get expression() {
72
- return this._expr;
73
- }
74
-
75
- get cast() {
76
- return this._cast;
77
- }
78
-
79
- fullColumn(builder) {
80
- const table = this.tableName
81
- ? this.tableName
82
- : this.modelClass
83
- ? builder.tableRefFor(this.modelClass)
84
- : null;
85
-
86
- if (table) {
87
- return `${table}.${this.column}`;
88
- } else {
89
- return this.column;
90
- }
91
- }
92
-
93
- castText() {
94
- return this.castTo('text');
95
- }
96
-
97
- castInt() {
98
- return this.castTo('integer');
99
- }
100
-
101
- castBigInt() {
102
- return this.castTo('bigint');
103
- }
104
-
105
- castFloat() {
106
- return this.castTo('float');
107
- }
108
-
109
- castDecimal() {
110
- return this.castTo('decimal');
111
- }
112
-
113
- castReal() {
114
- return this.castTo('real');
115
- }
116
-
117
- castBool() {
118
- return this.castTo('boolean');
119
- }
120
-
121
- castJson() {
122
- this._toJson = true;
123
- return this;
124
- }
125
-
126
- castTo(sqlType) {
127
- this._cast = sqlType;
128
- return this;
129
- }
130
-
131
- from(table) {
132
- this._table = table;
133
- return this;
134
- }
135
-
136
- table(table) {
137
- this._table = table;
138
- return this;
139
- }
140
-
141
- model(modelClass) {
142
- this._modelClass = modelClass;
143
- return this;
144
- }
145
-
146
- as(alias) {
147
- this._alias = alias;
148
- return this;
149
- }
150
-
151
- clone() {
152
- const clone = new this.constructor(null);
153
-
154
- clone._expr = this._expr;
155
- clone._parsedExpr = this._parsedExpr;
156
- clone._column = this._column;
157
- clone._table = this._table;
158
- clone._cast = this._cast;
159
- clone._toJson = this._toJson;
160
- clone._alias = this._alias;
161
- clone._modelClass = this._modelClass;
162
-
163
- return clone;
164
- }
165
-
166
- toKnexRaw(builder) {
167
- return builder.knex().raw(...this._createRawArgs(builder));
168
- }
169
-
170
- _parseExpression(expr) {
171
- this._parsedExpr = parseFieldExpression(expr);
172
- this._column = this._parsedExpr.column;
173
- this._table = this._parsedExpr.table;
174
- }
175
-
176
- _createRawArgs(builder) {
177
- const mysql = isMySql(builder.unsafeKnex());
178
- let bindings = [];
179
- let sql = this._createReferenceSql(builder, bindings);
180
-
181
- sql = this._maybeCast(sql, mysql);
182
- sql = this._maybeToJsonb(sql, mysql);
183
- sql = this._maybeAlias(sql, bindings);
184
-
185
- return [sql, bindings];
186
- }
187
-
188
- _createReferenceSql(builder, bindings) {
189
- const access = this._parsedExpr.access;
190
- bindings.push(this.fullColumn(builder));
191
-
192
- if (access.length === 0) {
193
- return '??';
194
- }
195
-
196
- if (getJsonDialect(builder.unsafeKnex(), this._expr) === 'mysql') {
197
- bindings.push(toMySqlJsonPath(access));
198
- // Casts need the unquoted value: `abc` instead of the JSON string `"abc"`.
199
- return this._cast ? 'JSON_UNQUOTE(JSON_EXTRACT(??, ?))' : 'JSON_EXTRACT(??, ?)';
200
- }
201
-
202
- const extractor = this._cast ? '#>>' : '#>';
203
- return `??${extractor}${toPgJsonPathLiteral(access)}`;
204
- }
205
-
206
- _maybeCast(sql, mysql) {
207
- if (!this._cast) {
208
- return sql;
209
- } else if (!mysql) {
210
- return `CAST(${sql} AS ${this._cast})`;
211
- }
212
-
213
- const isJsonField = this._parsedExpr.access.length > 0;
214
-
215
- // MySQL can't cast to a boolean.
216
- if (isBooleanType(this._cast)) {
217
- return isJsonField ? `(${sql} IN ('true', '1'))` : `(${sql} <> 0)`;
218
- }
219
-
220
- const type = toMySqlCastType(this._cast);
221
-
222
- // `JSON_UNQUOTE()` already returns text. Casting it would change its collation
223
- // from the case sensitive one `->>` also uses.
224
- if (isJsonField && type === 'CHAR') {
225
- return sql;
226
- }
227
-
228
- return `CAST(${sql} AS ${type})`;
229
- }
230
-
231
- _maybeToJsonb(sql, mysql) {
232
- if (!this._toJson) {
233
- return sql;
234
- } else if (mysql) {
235
- return `CAST(${sql} AS JSON)`;
236
- } else {
237
- return `to_jsonb(${sql})`;
238
- }
239
- }
240
-
241
- _maybeAlias(sql, bindings) {
242
- if (this._shouldAlias()) {
243
- bindings.push(this._alias);
244
- return `${sql} as ??`;
245
- } else {
246
- return sql;
247
- }
248
- }
249
-
250
- _shouldAlias() {
251
- if (!this._alias) {
252
- return false;
253
- } else if (!this.isPlainColumnRef) {
254
- return true;
255
- } else {
256
- // No need to alias if we are dealing with a simple column reference
257
- // and the alias is the same as the column name.
258
- return this._alias !== this._column;
259
- }
260
- }
9
+ constructor(expr) {
10
+ this._expr = expr;
11
+ this._parsedExpr = null;
12
+ this._column = null;
13
+ this._table = null;
14
+ this._cast = null;
15
+ this._toJson = false;
16
+ this._table = null;
17
+ this._alias = null;
18
+ this._modelClass = null;
19
+ // This `if` makes it possible for `clone` to skip
20
+ // parsing the expression again.
21
+ if (expr !== null) {
22
+ this._parseExpression(expr);
23
+ }
24
+ }
25
+ get parsedExpr() {
26
+ return this._parsedExpr;
27
+ }
28
+ get column() {
29
+ return this._column;
30
+ }
31
+ set column(column) {
32
+ this._column = column;
33
+ }
34
+ get alias() {
35
+ return this._alias;
36
+ }
37
+ set alias(alias) {
38
+ this._alias = alias;
39
+ }
40
+ get tableName() {
41
+ return this._table;
42
+ }
43
+ set tableName(table) {
44
+ this._table = table;
45
+ }
46
+ get modelClass() {
47
+ return this._modelClass;
48
+ }
49
+ set modelClass(modelClass) {
50
+ this._modelClass = modelClass;
51
+ }
52
+ get isPlainColumnRef() {
53
+ return ((!this._parsedExpr || this._parsedExpr.access.length === 0) && !this._cast && !this._toJson);
54
+ }
55
+ get expression() {
56
+ return this._expr;
57
+ }
58
+ get cast() {
59
+ return this._cast;
60
+ }
61
+ fullColumn(builder) {
62
+ const table = this.tableName
63
+ ? this.tableName
64
+ : this.modelClass
65
+ ? builder.tableRefFor(this.modelClass)
66
+ : null;
67
+ if (table) {
68
+ return `${table}.${this.column}`;
69
+ }
70
+ else {
71
+ return this.column;
72
+ }
73
+ }
74
+ castText() {
75
+ return this.castTo('text');
76
+ }
77
+ castInt() {
78
+ return this.castTo('integer');
79
+ }
80
+ castBigInt() {
81
+ return this.castTo('bigint');
82
+ }
83
+ castFloat() {
84
+ return this.castTo('float');
85
+ }
86
+ castDecimal() {
87
+ return this.castTo('decimal');
88
+ }
89
+ castReal() {
90
+ return this.castTo('real');
91
+ }
92
+ castBool() {
93
+ return this.castTo('boolean');
94
+ }
95
+ castJson() {
96
+ this._toJson = true;
97
+ return this;
98
+ }
99
+ castTo(sqlType) {
100
+ this._cast = sqlType;
101
+ return this;
102
+ }
103
+ from(table) {
104
+ this._table = table;
105
+ return this;
106
+ }
107
+ table(table) {
108
+ this._table = table;
109
+ return this;
110
+ }
111
+ model(modelClass) {
112
+ this._modelClass = modelClass;
113
+ return this;
114
+ }
115
+ as(alias) {
116
+ this._alias = alias;
117
+ return this;
118
+ }
119
+ clone() {
120
+ const clone = new this.constructor(null);
121
+ clone._expr = this._expr;
122
+ clone._parsedExpr = this._parsedExpr;
123
+ clone._column = this._column;
124
+ clone._table = this._table;
125
+ clone._cast = this._cast;
126
+ clone._toJson = this._toJson;
127
+ clone._alias = this._alias;
128
+ clone._modelClass = this._modelClass;
129
+ return clone;
130
+ }
131
+ toKnexRaw(builder) {
132
+ return builder.knex().raw(...this._createRawArgs(builder));
133
+ }
134
+ _parseExpression(expr) {
135
+ this._parsedExpr = parseFieldExpression(expr);
136
+ this._column = this._parsedExpr.column;
137
+ this._table = this._parsedExpr.table;
138
+ }
139
+ _createRawArgs(builder) {
140
+ const knex = builder.unsafeKnex();
141
+ const mysql = isMySql(knex);
142
+ const bindings = [];
143
+ let sql = this._createReferenceSql(builder, bindings);
144
+ sql = this._maybeCast(sql, mysql, knex);
145
+ sql = this._maybeToJsonb(sql, mysql, knex);
146
+ sql = this._maybeAlias(sql, bindings);
147
+ return [sql, bindings];
148
+ }
149
+ _createReferenceSql(builder, bindings) {
150
+ const access = this._parsedExpr.access;
151
+ bindings.push(this.fullColumn(builder));
152
+ if (access.length === 0) {
153
+ return '??';
154
+ }
155
+ if (getJsonDialect(builder.unsafeKnex(), this._expr) === 'mysql') {
156
+ bindings.push(toMySqlJsonPath(access));
157
+ // Casts need the unquoted value: `abc` instead of the JSON string `"abc"`.
158
+ if (this._cast) {
159
+ return 'JSON_UNQUOTE(JSON_EXTRACT(??, ?))';
160
+ }
161
+ // MariaDB's JSON_EXTRACT() returns the JSON with spaces, so it would never
162
+ // be equal to a value like `val({ a: 1 })`, which is compact.
163
+ return isMariaDb(builder.unsafeKnex())
164
+ ? 'JSON_COMPACT(JSON_EXTRACT(??, ?))'
165
+ : 'JSON_EXTRACT(??, ?)';
166
+ }
167
+ const extractor = this._cast ? '#>>' : '#>';
168
+ return `??${extractor}${toPgJsonPathLiteral(access)}`;
169
+ }
170
+ _maybeCast(sql, mysql, knex) {
171
+ if (!this._cast) {
172
+ return sql;
173
+ }
174
+ else if (!mysql) {
175
+ return `CAST(${sql} AS ${this._cast})`;
176
+ }
177
+ const isJsonField = this._parsedExpr.access.length > 0;
178
+ // MySQL can't cast to a boolean.
179
+ if (isBooleanType(this._cast)) {
180
+ return isJsonField ? `(${sql} IN ('true', '1'))` : `(${sql} <> 0)`;
181
+ }
182
+ const type = toMySqlCastType(this._cast);
183
+ // `JSON_UNQUOTE()` already returns text. Casting it would change its collation
184
+ // from the case sensitive one `->>` also uses.
185
+ if (isJsonField && type === 'CHAR') {
186
+ return sql;
187
+ }
188
+ if (type === 'JSON') {
189
+ return toJsonSql(sql, knex);
190
+ }
191
+ return `CAST(${sql} AS ${type})`;
192
+ }
193
+ _maybeToJsonb(sql, mysql, knex) {
194
+ if (!this._toJson) {
195
+ return sql;
196
+ }
197
+ else if (mysql) {
198
+ return toJsonSql(sql, knex);
199
+ }
200
+ else {
201
+ return `to_jsonb(${sql})`;
202
+ }
203
+ }
204
+ _maybeAlias(sql, bindings) {
205
+ if (this._shouldAlias()) {
206
+ bindings.push(this._alias);
207
+ return `${sql} as ??`;
208
+ }
209
+ else {
210
+ return sql;
211
+ }
212
+ }
213
+ _shouldAlias() {
214
+ if (!this._alias) {
215
+ return false;
216
+ }
217
+ else if (!this.isPlainColumnRef) {
218
+ return true;
219
+ }
220
+ else {
221
+ // No need to alias if we are dealing with a simple column reference
222
+ // and the alias is the same as the column name.
223
+ return this._alias !== this._column;
224
+ }
225
+ }
261
226
  }
262
-
263
227
  Object.defineProperties(ReferenceBuilder.prototype, {
264
- isObjectionReferenceBuilder: {
265
- enumerable: false,
266
- writable: false,
267
- value: true,
268
- },
228
+ isObjectionReferenceBuilder: {
229
+ enumerable: false,
230
+ writable: false,
231
+ value: true,
232
+ },
269
233
  });
270
-
271
234
  addExpressionMethods(ReferenceBuilder.prototype);
272
-
273
235
  const ref = (reference) => {
274
- if (isObject(reference) && reference.isObjectionReferenceBuilder) {
275
- return reference;
276
- } else {
277
- return new ReferenceBuilder(reference);
278
- }
236
+ if (isObject(reference) && reference.isObjectionReferenceBuilder) {
237
+ return reference;
238
+ }
239
+ else {
240
+ return new ReferenceBuilder(reference);
241
+ }
279
242
  };
280
-
281
243
  module.exports = {
282
- ReferenceBuilder,
283
- ref,
244
+ ReferenceBuilder,
245
+ ref,
284
246
  };