@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,134 +1,122 @@
1
1
  'use strict';
2
-
3
2
  const { asArray } = require('../utils/objectUtils');
4
-
5
3
  const BUILDER_SYMBOL = Symbol();
6
-
4
+ // The static hooks of `Model`, which do nothing. Queries skip creating the
5
+ // arguments and calling the hook when a model class hasn't overridden it.
6
+ const defaultStaticHooks = new WeakSet();
7
+ function markDefaultStaticHook(hook) {
8
+ defaultStaticHooks.add(hook);
9
+ }
10
+ function hasStaticHook(modelClass, hookName) {
11
+ return !defaultStaticHooks.has(modelClass[hookName]);
12
+ }
7
13
  class StaticHookArguments {
8
- constructor({ builder, result = null }) {
9
- // The builder should never be accessed through the arguments.
10
- // Hide it as well as possible to discourage people from
11
- // digging it out.
12
- Object.defineProperty(this, BUILDER_SYMBOL, {
13
- value: builder,
14
- });
15
-
16
- Object.defineProperty(this, 'result', {
17
- value: asArray(result),
18
- });
19
- }
20
-
21
- static create(args) {
22
- return new StaticHookArguments(args);
23
- }
24
-
25
- get asFindQuery() {
26
- return () => {
27
- return this[BUILDER_SYMBOL].toFindQuery().clearWithGraphFetched().runAfter(asArray);
28
- };
29
- }
30
-
31
- get context() {
32
- return this[BUILDER_SYMBOL].context();
33
- }
34
-
35
- get transaction() {
36
- return this[BUILDER_SYMBOL].unsafeKnex();
37
- }
38
-
39
- get relation() {
40
- const op = this[BUILDER_SYMBOL].findOperation(hasRelation);
41
-
42
- if (op) {
43
- return getRelation(op);
44
- } else {
45
- return undefined;
14
+ constructor({ builder, result = null }) {
15
+ // The builder should never be accessed through the arguments.
16
+ // Hide it as well as possible to discourage people from
17
+ // digging it out.
18
+ Object.defineProperty(this, BUILDER_SYMBOL, {
19
+ value: builder,
20
+ });
21
+ Object.defineProperty(this, 'result', {
22
+ value: asArray(result),
23
+ });
24
+ }
25
+ static create(args) {
26
+ return new StaticHookArguments(args);
27
+ }
28
+ get asFindQuery() {
29
+ return () => {
30
+ return this[BUILDER_SYMBOL].toFindQuery().clearWithGraphFetched().runAfter(asArray);
31
+ };
46
32
  }
47
- }
48
-
49
- get modelOptions() {
50
- const op = this[BUILDER_SYMBOL].findOperation(hasModelOptions);
51
-
52
- if (op) {
53
- return getModelOptions(op);
54
- } else {
55
- return undefined;
33
+ get context() {
34
+ return this[BUILDER_SYMBOL].context();
56
35
  }
57
- }
58
-
59
- get items() {
60
- const op = this[BUILDER_SYMBOL].findOperation(hasItems);
61
-
62
- if (op) {
63
- return asArray(getItems(op));
64
- } else {
65
- return [];
36
+ get transaction() {
37
+ return this[BUILDER_SYMBOL].unsafeKnex();
66
38
  }
67
- }
68
-
69
- get inputItems() {
70
- const op = this[BUILDER_SYMBOL].findOperation(hasInputItems);
71
-
72
- if (op) {
73
- return asArray(getInputItems(op));
74
- } else {
75
- return [];
39
+ get relation() {
40
+ const op = this[BUILDER_SYMBOL].findOperation(hasRelation);
41
+ if (op) {
42
+ return getRelation(op);
43
+ }
44
+ else {
45
+ return undefined;
46
+ }
76
47
  }
77
- }
78
-
79
- get cancelQuery() {
80
- const args = this;
81
-
82
- return (cancelValue) => {
83
- const builder = this[BUILDER_SYMBOL];
84
-
85
- if (cancelValue === undefined) {
86
- if (builder.isInsert()) {
87
- cancelValue = args.inputItems;
88
- } else if (builder.isFind()) {
89
- cancelValue = [];
90
- } else {
91
- cancelValue = 0;
48
+ get modelOptions() {
49
+ const op = this[BUILDER_SYMBOL].findOperation(hasModelOptions);
50
+ if (op) {
51
+ return getModelOptions(op);
92
52
  }
93
- }
94
-
95
- builder.resolve(cancelValue);
96
- };
97
- }
53
+ else {
54
+ return undefined;
55
+ }
56
+ }
57
+ get items() {
58
+ const op = this[BUILDER_SYMBOL].findOperation(hasItems);
59
+ if (op) {
60
+ return asArray(getItems(op));
61
+ }
62
+ else {
63
+ return [];
64
+ }
65
+ }
66
+ get inputItems() {
67
+ const op = this[BUILDER_SYMBOL].findOperation(hasInputItems);
68
+ if (op) {
69
+ return asArray(getInputItems(op));
70
+ }
71
+ else {
72
+ return [];
73
+ }
74
+ }
75
+ get cancelQuery() {
76
+ const args = this;
77
+ return (cancelValue) => {
78
+ const builder = this[BUILDER_SYMBOL];
79
+ if (cancelValue === undefined) {
80
+ if (builder.isInsert()) {
81
+ cancelValue = args.inputItems;
82
+ }
83
+ else if (builder.isFind()) {
84
+ cancelValue = [];
85
+ }
86
+ else {
87
+ cancelValue = 0;
88
+ }
89
+ }
90
+ builder.resolve(cancelValue);
91
+ };
92
+ }
98
93
  }
99
-
100
94
  function getRelation(op) {
101
- return op.relation;
95
+ return op.relation;
102
96
  }
103
-
104
97
  function hasRelation(op) {
105
- return !!getRelation(op);
98
+ return !!getRelation(op);
106
99
  }
107
-
108
100
  function getModelOptions(op) {
109
- return op.modelOptions;
101
+ return op.modelOptions;
110
102
  }
111
-
112
103
  function hasModelOptions(op) {
113
- return !!getModelOptions(op);
104
+ return !!getModelOptions(op);
114
105
  }
115
-
116
106
  function getItems(op) {
117
- return op.instance || (op.owner && op.owner.isModels && op.owner.modelArray);
107
+ return op.instance || (op.owner && op.owner.isModels && op.owner.modelArray);
118
108
  }
119
-
120
109
  function hasItems(op) {
121
- return !!getItems(op);
110
+ return !!getItems(op);
122
111
  }
123
-
124
112
  function getInputItems(op) {
125
- return op.models || op.model;
113
+ return op.models || op.model;
126
114
  }
127
-
128
115
  function hasInputItems(op) {
129
- return !!getInputItems(op);
116
+ return !!getInputItems(op);
130
117
  }
131
-
132
118
  module.exports = {
133
- StaticHookArguments,
119
+ StaticHookArguments,
120
+ markDefaultStaticHook,
121
+ hasStaticHook,
134
122
  };
@@ -1,127 +1,115 @@
1
1
  'use strict';
2
-
3
2
  const { asArray, isObject } = require('../utils/objectUtils');
4
3
  const { buildArg } = require('../utils/buildUtils');
5
4
  const { isMySql } = require('../utils/knexUtils');
6
- const { toMySqlCastType, isBooleanType } = require('../utils/mysqlJsonPath');
5
+ const { toMySqlCastType, isBooleanType, toJsonSql } = require('../utils/mysqlJsonPath');
7
6
  const { addExpressionMethods } = require('./expressions');
8
-
9
7
  class ValueBuilder {
10
- constructor(value) {
11
- this._value = value;
12
- this._cast = null;
13
- // Cast objects and arrays to json by default.
14
- this._toJson = isObject(value);
15
- this._toArray = false;
16
- this._alias = null;
17
- }
18
-
19
- get cast() {
20
- return this._cast;
21
- }
22
-
23
- castText() {
24
- return this.castTo('text');
25
- }
26
-
27
- castInt() {
28
- return this.castTo('integer');
29
- }
30
-
31
- castBigInt() {
32
- return this.castTo('bigint');
33
- }
34
-
35
- castFloat() {
36
- return this.castTo('float');
37
- }
38
-
39
- castDecimal() {
40
- return this.castTo('decimal');
41
- }
42
-
43
- castReal() {
44
- return this.castTo('real');
45
- }
46
-
47
- castBool() {
48
- return this.castTo('boolean');
49
- }
50
-
51
- castJson() {
52
- this._toArray = false;
53
- this._toJson = true;
54
- this._cast = 'jsonb';
55
- return this;
56
- }
57
-
58
- castTo(sqlType) {
59
- this._cast = sqlType;
60
- return this;
61
- }
62
-
63
- asArray() {
64
- this._toJson = false;
65
- this._toArray = true;
66
- return this;
67
- }
68
-
69
- as(alias) {
70
- this._alias = alias;
71
- return this;
72
- }
73
-
74
- toKnexRaw(builder) {
75
- return builder.knex().raw(...this._createRawArgs(builder));
76
- }
77
-
78
- _createRawArgs(builder) {
79
- let sql = null;
80
- let bindings = [];
81
-
82
- if (this._toJson) {
83
- bindings.push(JSON.stringify(this._value));
84
- sql = '?';
85
- } else if (this._toArray) {
86
- const values = asArray(this._value);
87
- bindings.push(...values.map((it) => buildArg(it, builder)));
88
- sql = `ARRAY[${values.map(() => '?').join(', ')}]`;
89
- } else {
90
- bindings.push(this._value);
91
- sql = '?';
8
+ constructor(value) {
9
+ this._value = value;
10
+ this._cast = null;
11
+ // Cast objects and arrays to json by default.
12
+ this._toJson = isObject(value);
13
+ this._toArray = false;
14
+ this._alias = null;
92
15
  }
93
-
94
- const mysql = isMySql(builder.unsafeKnex());
95
-
96
- if (this._toJson && !this._cast && mysql) {
97
- // MySQL compares strings and JSON values as strings, so `{}` is never
98
- // equal to a JSON column without the cast. Postgres casts it implicitly.
99
- sql = `CAST(${sql} AS JSON)`;
100
- } else if (this._cast && mysql) {
101
- // MySQL can't cast to a boolean.
102
- sql = isBooleanType(this._cast)
103
- ? `(${sql} <> 0)`
104
- : `CAST(${sql} AS ${toMySqlCastType(this._cast)})`;
105
- } else if (this._cast) {
106
- sql = `CAST(${sql} AS ${this._cast})`;
16
+ get cast() {
17
+ return this._cast;
107
18
  }
108
-
109
- if (this._alias) {
110
- bindings.push(this._alias);
111
- sql = `${sql} as ??`;
19
+ castText() {
20
+ return this.castTo('text');
21
+ }
22
+ castInt() {
23
+ return this.castTo('integer');
24
+ }
25
+ castBigInt() {
26
+ return this.castTo('bigint');
27
+ }
28
+ castFloat() {
29
+ return this.castTo('float');
30
+ }
31
+ castDecimal() {
32
+ return this.castTo('decimal');
33
+ }
34
+ castReal() {
35
+ return this.castTo('real');
36
+ }
37
+ castBool() {
38
+ return this.castTo('boolean');
39
+ }
40
+ castJson() {
41
+ this._toArray = false;
42
+ this._toJson = true;
43
+ this._cast = 'jsonb';
44
+ return this;
45
+ }
46
+ castTo(sqlType) {
47
+ this._cast = sqlType;
48
+ return this;
49
+ }
50
+ asArray() {
51
+ this._toJson = false;
52
+ this._toArray = true;
53
+ return this;
54
+ }
55
+ as(alias) {
56
+ this._alias = alias;
57
+ return this;
58
+ }
59
+ toKnexRaw(builder) {
60
+ return builder.knex().raw(...this._createRawArgs(builder));
61
+ }
62
+ _createRawArgs(builder) {
63
+ let sql = null;
64
+ const bindings = [];
65
+ if (this._toJson) {
66
+ bindings.push(JSON.stringify(this._value));
67
+ sql = '?';
68
+ }
69
+ else if (this._toArray) {
70
+ const values = asArray(this._value);
71
+ bindings.push(...values.map((it) => buildArg(it, builder)));
72
+ sql = `ARRAY[${values.map(() => '?').join(', ')}]`;
73
+ }
74
+ else {
75
+ bindings.push(this._value);
76
+ sql = '?';
77
+ }
78
+ const knex = builder.unsafeKnex();
79
+ const mysql = isMySql(knex);
80
+ if (this._toJson && !this._cast && mysql) {
81
+ // MySQL compares strings and JSON values as strings, so `{}` is never
82
+ // equal to a JSON column without the cast. Postgres casts it implicitly.
83
+ sql = toJsonSql(sql, knex);
84
+ }
85
+ else if (this._cast && mysql) {
86
+ const type = toMySqlCastType(this._cast);
87
+ // MySQL can't cast to a boolean.
88
+ if (isBooleanType(this._cast)) {
89
+ sql = `(${sql} <> 0)`;
90
+ }
91
+ else if (type === 'JSON') {
92
+ sql = toJsonSql(sql, knex);
93
+ }
94
+ else {
95
+ sql = `CAST(${sql} AS ${type})`;
96
+ }
97
+ }
98
+ else if (this._cast) {
99
+ sql = `CAST(${sql} AS ${this._cast})`;
100
+ }
101
+ if (this._alias) {
102
+ bindings.push(this._alias);
103
+ sql = `${sql} as ??`;
104
+ }
105
+ return [sql, bindings];
112
106
  }
113
-
114
- return [sql, bindings];
115
- }
116
107
  }
117
-
118
108
  addExpressionMethods(ValueBuilder.prototype);
119
-
120
109
  function val(val) {
121
- return new ValueBuilder(val);
110
+ return new ValueBuilder(val);
122
111
  }
123
-
124
112
  module.exports = {
125
- ValueBuilder,
126
- val,
113
+ ValueBuilder,
114
+ val,
127
115
  };
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
-
3
2
  const { isObject } = require('../utils/objectUtils');
4
-
5
3
  // Comparison, logic and arithmetic methods for `ref()`, `val()`, `fn()` and
6
4
  // `raw()`, so that expressions can be written without raw sql:
7
5
  //
@@ -13,139 +11,111 @@ const { isObject } = require('../utils/objectUtils');
13
11
  // so expressions can be nested without thinking about operator precedence. The
14
12
  // arguments are bindings like the arguments of `fn()`: strings are values and
15
13
  // columns are passed with `ref()` or `Model.ref()`.
16
-
17
14
  const COMPARISONS = {
18
- eq: '=',
19
- ne: '<>',
20
- gt: '>',
21
- gte: '>=',
22
- lt: '<',
23
- lte: '<=',
15
+ eq: '=',
16
+ ne: '<>',
17
+ gt: '>',
18
+ gte: '>=',
19
+ lt: '<',
20
+ lte: '<=',
24
21
  };
25
-
26
22
  const ARITHMETIC = {
27
- plus: '+',
28
- minus: '-',
29
- times: '*',
30
- div: '/',
23
+ plus: '+',
24
+ minus: '-',
25
+ times: '*',
26
+ div: '/',
31
27
  };
32
-
33
28
  const methods = {
34
- // `eq(null)` and `ne(null)` are `IS NULL` and `IS NOT NULL`, like `where(col, null)`.
35
- eq(value) {
36
- return value === null ? this.isNull() : expression('(? = ?)', [this, value]);
37
- },
38
-
39
- ne(value) {
40
- return value === null ? this.isNotNull() : expression('(? <> ?)', [this, value]);
41
- },
42
-
43
- in(values) {
44
- return createIn(this, values, 'IN');
45
- },
46
-
47
- notIn(values) {
48
- return createIn(this, values, 'NOT IN');
49
- },
50
-
51
- like(pattern) {
52
- return expression('(? LIKE ?)', [this, pattern]);
53
- },
54
-
55
- between(min, max) {
56
- return expression('(? BETWEEN ? AND ?)', [this, min, max]);
57
- },
58
-
59
- isNull() {
60
- return expression('(? IS NULL)', [this]);
61
- },
62
-
63
- isNotNull() {
64
- return expression('(? IS NOT NULL)', [this]);
65
- },
66
-
67
- // NULL, an empty string or a string of only spaces.
68
- isBlank() {
69
- return expression("(COALESCE(TRIM(?), '') = '')", [this]);
70
- },
71
-
72
- isNotBlank() {
73
- return expression("(COALESCE(TRIM(?), '') <> '')", [this]);
74
- },
75
-
76
- and(...conditions) {
77
- return createLogic(this, conditions, 'AND');
78
- },
79
-
80
- or(...conditions) {
81
- return createLogic(this, conditions, 'OR');
82
- },
83
-
84
- not() {
85
- return expression('(NOT ?)', [this]);
86
- },
29
+ // `eq(null)` and `ne(null)` are `IS NULL` and `IS NOT NULL`, like `where(col, null)`.
30
+ eq(value) {
31
+ return value === null ? this.isNull() : expression('(? = ?)', [this, value]);
32
+ },
33
+ ne(value) {
34
+ return value === null ? this.isNotNull() : expression('(? <> ?)', [this, value]);
35
+ },
36
+ in(values) {
37
+ return createIn(this, values, 'IN');
38
+ },
39
+ notIn(values) {
40
+ return createIn(this, values, 'NOT IN');
41
+ },
42
+ like(pattern) {
43
+ return expression('(? LIKE ?)', [this, pattern]);
44
+ },
45
+ between(min, max) {
46
+ return expression('(? BETWEEN ? AND ?)', [this, min, max]);
47
+ },
48
+ isNull() {
49
+ return expression('(? IS NULL)', [this]);
50
+ },
51
+ isNotNull() {
52
+ return expression('(? IS NOT NULL)', [this]);
53
+ },
54
+ // NULL, an empty string or a string of only spaces.
55
+ isBlank() {
56
+ return expression("(COALESCE(TRIM(?), '') = '')", [this]);
57
+ },
58
+ isNotBlank() {
59
+ return expression("(COALESCE(TRIM(?), '') <> '')", [this]);
60
+ },
61
+ and(...conditions) {
62
+ return createLogic(this, conditions, 'AND');
63
+ },
64
+ or(...conditions) {
65
+ return createLogic(this, conditions, 'OR');
66
+ },
67
+ not() {
68
+ return expression('(NOT ?)', [this]);
69
+ },
87
70
  };
88
-
89
71
  for (const [name, operator] of Object.entries(COMPARISONS)) {
90
- if (!methods[name]) {
91
- methods[name] = function (value) {
92
- return expression(`(? ${operator} ?)`, [this, value]);
93
- };
94
- }
72
+ if (!methods[name]) {
73
+ methods[name] = function (value) {
74
+ return expression(`(? ${operator} ?)`, [this, value]);
75
+ };
76
+ }
95
77
  }
96
-
97
78
  for (const [name, operator] of Object.entries(ARITHMETIC)) {
98
- methods[name] = function (value) {
99
- return expression(`(? ${operator} ?)`, [this, value]);
100
- };
79
+ methods[name] = function (value) {
80
+ return expression(`(? ${operator} ?)`, [this, value]);
81
+ };
101
82
  }
102
-
103
83
  function createIn(left, values, operator) {
104
- if (isSubquery(values)) {
105
- return expression(`(? ${operator} ?)`, [left, values]);
106
- }
107
-
108
- if (!Array.isArray(values)) {
109
- throw new Error(`${operator.toLowerCase()}() takes an array or a subquery.`);
110
- }
111
-
112
- if (values.length === 0) {
113
- // Like knex's `whereIn(col, [])`.
114
- return expression(operator === 'IN' ? '(1 = 0)' : '(1 = 1)', []);
115
- }
116
-
117
- return expression(`(? ${operator} (${values.map(() => '?').join(', ')}))`, [left, ...values]);
84
+ if (isSubquery(values)) {
85
+ return expression(`(? ${operator} ?)`, [left, values]);
86
+ }
87
+ if (!Array.isArray(values)) {
88
+ throw new Error(`${operator.toLowerCase()}() takes an array or a subquery.`);
89
+ }
90
+ if (values.length === 0) {
91
+ // Like knex's `whereIn(col, [])`.
92
+ return expression(operator === 'IN' ? '(1 = 0)' : '(1 = 1)', []);
93
+ }
94
+ return expression(`(? ${operator} (${values.map(() => '?').join(', ')}))`, [left, ...values]);
118
95
  }
119
-
120
96
  function createLogic(first, rest, operator) {
121
- const conditions = [first, ...rest];
122
- return expression(`(${conditions.map(() => '?').join(` ${operator} `)})`, conditions);
97
+ const conditions = [first, ...rest];
98
+ return expression(`(${conditions.map(() => '?').join(` ${operator} `)})`, conditions);
123
99
  }
124
-
125
100
  function isSubquery(value) {
126
- return (
127
- isObject(value) && (value.isObjectionQueryBuilderBase || typeof value.toSQL === 'function')
128
- );
101
+ return (isObject(value) && (value.isObjectionQueryBuilderBase || typeof value.toSQL === 'function'));
129
102
  }
130
-
131
103
  function expression(sql, args) {
132
- // Required here because `FunctionBuilder` itself gets these methods.
133
- const { FunctionBuilder } = require('./FunctionBuilder');
134
- return new FunctionBuilder(sql, args);
104
+ // Required here because `FunctionBuilder` itself gets these methods.
105
+ const { FunctionBuilder } = require('./FunctionBuilder');
106
+ return new FunctionBuilder(sql, args);
135
107
  }
136
-
137
108
  function addExpressionMethods(prototype) {
138
- for (const [name, method] of Object.entries(methods)) {
139
- Object.defineProperty(prototype, name, {
140
- configurable: true,
141
- enumerable: false,
142
- writable: true,
143
- value: method,
144
- });
145
- }
109
+ for (const [name, method] of Object.entries(methods)) {
110
+ Object.defineProperty(prototype, name, {
111
+ configurable: true,
112
+ enumerable: false,
113
+ writable: true,
114
+ value: method,
115
+ });
116
+ }
146
117
  }
147
-
148
118
  module.exports = {
149
- addExpressionMethods,
150
- expression,
119
+ addExpressionMethods,
120
+ expression,
151
121
  };