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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/README.md +103 -67
  2. package/lib/index.mjs +6 -0
  3. package/lib/initialize.js +6 -9
  4. package/lib/model/AjvValidator.js +235 -282
  5. package/lib/model/Model.js +653 -823
  6. package/lib/model/ModifierNotFoundError.js +5 -7
  7. package/lib/model/NotFoundError.js +14 -18
  8. package/lib/model/RelationDoesNotExistError.js +6 -9
  9. package/lib/model/ValidationError.js +33 -41
  10. package/lib/model/Validator.js +15 -21
  11. package/lib/model/getModel.js +1 -3
  12. package/lib/model/graph/ModelGraph.js +44 -64
  13. package/lib/model/graph/ModelGraphBuilder.js +164 -217
  14. package/lib/model/graph/ModelGraphEdge.js +31 -43
  15. package/lib/model/graph/ModelGraphNode.js +192 -231
  16. package/lib/model/inheritModel.js +9 -18
  17. package/lib/model/modelBindKnex.js +48 -62
  18. package/lib/model/modelClone.js +79 -98
  19. package/lib/model/modelColPropMap.js +16 -26
  20. package/lib/model/modelConcurrency.js +24 -0
  21. package/lib/model/modelId.js +44 -49
  22. package/lib/model/modelJsonAttributes.js +56 -76
  23. package/lib/model/modelParseRelations.js +68 -67
  24. package/lib/model/modelQueryProps.js +76 -107
  25. package/lib/model/modelSet.js +92 -112
  26. package/lib/model/modelTableMetadata.js +60 -72
  27. package/lib/model/modelToJson.js +120 -150
  28. package/lib/model/modelUtils.js +30 -37
  29. package/lib/model/modelValidate.js +34 -42
  30. package/lib/model/modelValues.js +78 -91
  31. package/lib/model/modelVisitor.js +22 -29
  32. package/lib/objection.js +42 -67
  33. package/lib/queryBuilder/FunctionBuilder.js +231 -279
  34. package/lib/queryBuilder/InternalOptions.js +19 -24
  35. package/lib/queryBuilder/JoinBuilder.js +116 -149
  36. package/lib/queryBuilder/QueryBuilder.js +1009 -1271
  37. package/lib/queryBuilder/QueryBuilderBase.js +647 -865
  38. package/lib/queryBuilder/QueryBuilderContext.js +14 -21
  39. package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
  40. package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
  41. package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
  42. package/lib/queryBuilder/RawBuilder.js +58 -73
  43. package/lib/queryBuilder/ReferenceBuilder.js +232 -270
  44. package/lib/queryBuilder/RelationExpression.js +322 -380
  45. package/lib/queryBuilder/StaticHookArguments.js +94 -106
  46. package/lib/queryBuilder/ValueBuilder.js +100 -112
  47. package/lib/queryBuilder/expressions.js +86 -116
  48. package/lib/queryBuilder/functions/mysql.js +642 -697
  49. package/lib/queryBuilder/graph/GraphAction.js +44 -59
  50. package/lib/queryBuilder/graph/GraphData.js +7 -9
  51. package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
  52. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
  53. package/lib/queryBuilder/graph/GraphOperation.js +16 -22
  54. package/lib/queryBuilder/graph/GraphOptions.js +143 -185
  55. package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
  56. package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
  57. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
  58. package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
  59. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
  60. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
  61. package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
  62. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
  63. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
  65. package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
  66. package/lib/queryBuilder/join/JoinResultParser.js +88 -101
  67. package/lib/queryBuilder/join/RelationJoiner.js +205 -288
  68. package/lib/queryBuilder/join/TableNode.js +117 -144
  69. package/lib/queryBuilder/join/TableTree.js +60 -76
  70. package/lib/queryBuilder/join/utils.js +10 -16
  71. package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
  72. package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
  73. package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
  74. package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
  75. package/lib/queryBuilder/operations/FindOperation.js +114 -131
  76. package/lib/queryBuilder/operations/FirstOperation.js +14 -19
  77. package/lib/queryBuilder/operations/FromOperation.js +69 -88
  78. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
  79. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
  80. package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
  81. package/lib/queryBuilder/operations/InsertOperation.js +132 -165
  82. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
  83. package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
  84. package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
  85. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
  86. package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
  87. package/lib/queryBuilder/operations/KnexOperation.js +4 -7
  88. package/lib/queryBuilder/operations/MergeOperation.js +32 -45
  89. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
  90. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
  91. package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
  92. package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
  93. package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
  94. package/lib/queryBuilder/operations/RangeOperation.js +30 -40
  95. package/lib/queryBuilder/operations/RelateOperation.js +14 -21
  96. package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
  97. package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
  98. package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
  99. package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
  100. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
  101. package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
  102. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
  103. package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
  104. package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
  105. package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
  106. package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
  107. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
  108. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
  109. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
  110. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
  114. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
  115. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
  116. package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
  117. package/lib/queryBuilder/operations/select/Selection.js +94 -105
  118. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
  121. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
  122. package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
  123. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
  124. package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
  125. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
  126. package/lib/queryBuilder/transformations/index.js +3 -9
  127. package/lib/queryBuilder/whereScopes.js +158 -186
  128. package/lib/relations/Relation.js +279 -363
  129. package/lib/relations/RelationDeleteOperation.js +16 -22
  130. package/lib/relations/RelationFindOperation.js +100 -133
  131. package/lib/relations/RelationInsertOperation.js +19 -27
  132. package/lib/relations/RelationOwner.js +167 -204
  133. package/lib/relations/RelationProperty.js +177 -217
  134. package/lib/relations/RelationUpdateOperation.js +16 -23
  135. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +11 -16
  136. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +24 -35
  137. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +30 -41
  138. package/lib/relations/belongsToOne/BelongsToOneRelation.js +33 -41
  139. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +38 -53
  140. package/lib/relations/hasMany/HasManyInsertOperation.js +35 -51
  141. package/lib/relations/hasMany/HasManyRelateOperation.js +38 -54
  142. package/lib/relations/hasMany/HasManyRelation.js +30 -38
  143. package/lib/relations/hasMany/HasManyUnrelateOperation.js +19 -26
  144. package/lib/relations/hasOne/HasOneRelation.js +4 -7
  145. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +4 -7
  146. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +67 -90
  147. package/lib/relations/manyToMany/ManyToManyRelation.js +349 -451
  148. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +19 -26
  149. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +3 -5
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +14 -20
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -7
  152. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +71 -94
  153. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +31 -43
  154. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +50 -67
  155. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +4 -7
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +20 -27
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +5 -10
  158. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +3 -5
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +55 -72
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -7
  161. package/lib/transaction.js +53 -83
  162. package/lib/utils/assert.js +15 -21
  163. package/lib/utils/buildUtils.js +17 -19
  164. package/lib/utils/classUtils.js +7 -11
  165. package/lib/utils/cloneDeep.js +365 -0
  166. package/lib/utils/createModifier.js +36 -41
  167. package/lib/utils/deprecate.js +8 -12
  168. package/lib/utils/identifierMapping.js +153 -192
  169. package/lib/utils/internalPropUtils.js +4 -8
  170. package/lib/utils/knexUtils.js +61 -56
  171. package/lib/utils/mixin.js +16 -23
  172. package/lib/utils/mysqlJsonPath.js +55 -40
  173. package/lib/utils/normalizeIds.js +110 -127
  174. package/lib/utils/objectUtils.js +236 -338
  175. package/lib/utils/parseFieldExpression.js +66 -44
  176. package/lib/utils/postgresJsonPath.js +48 -62
  177. package/lib/utils/promiseUtils/after.js +10 -13
  178. package/lib/utils/promiseUtils/afterReturn.js +10 -13
  179. package/lib/utils/promiseUtils/index.js +15 -17
  180. package/lib/utils/promiseUtils/isPromise.js +6 -9
  181. package/lib/utils/promiseUtils/map.js +75 -89
  182. package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
  183. package/lib/utils/promiseUtils/try.js +15 -18
  184. package/lib/utils/resolveModel.js +91 -94
  185. package/lib/utils/tmpColumnUtils.js +4 -13
  186. package/package.json +50 -23
  187. package/typings/objection/index.d.mts +362 -0
  188. package/typings/objection/index.d.ts +36 -9
  189. package/lib/.eslintrc.json +0 -8
  190. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
  191. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
  192. package/lib/utils/clone.js +0 -2329
@@ -1,29 +1,23 @@
1
1
  'use strict';
2
-
3
2
  const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
-
5
3
  class RunAfterOperation extends QueryBuilderOperation {
6
- constructor(name, opt) {
7
- super(name, opt);
8
- this.func = null;
9
- }
10
-
11
- onAdd(_, args) {
12
- this.func = args[0];
13
- return true;
14
- }
15
-
16
- onAfter3(builder, result) {
17
- return this.func.call(builder, result, builder);
18
- }
19
-
20
- clone() {
21
- const clone = super.clone();
22
- clone.func = this.func;
23
- return clone;
24
- }
4
+ constructor(name, opt) {
5
+ super(name, opt);
6
+ this.func = null;
7
+ }
8
+ onAdd(_, args) {
9
+ this.func = args[0];
10
+ return true;
11
+ }
12
+ onAfter3(builder, result) {
13
+ return this.func.call(builder, result, builder);
14
+ }
15
+ clone() {
16
+ const clone = super.clone();
17
+ clone.func = this.func;
18
+ return clone;
19
+ }
25
20
  }
26
-
27
21
  module.exports = {
28
- RunAfterOperation,
22
+ RunAfterOperation,
29
23
  };
@@ -1,29 +1,23 @@
1
1
  'use strict';
2
-
3
2
  const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
-
5
3
  class RunBeforeOperation extends QueryBuilderOperation {
6
- constructor(name, opt) {
7
- super(name, opt);
8
- this.func = null;
9
- }
10
-
11
- onAdd(_, args) {
12
- this.func = args[0];
13
- return true;
14
- }
15
-
16
- onBefore1(builder, result) {
17
- return this.func.call(builder, result, builder);
18
- }
19
-
20
- clone() {
21
- const clone = super.clone();
22
- clone.func = this.func;
23
- return clone;
24
- }
4
+ constructor(name, opt) {
5
+ super(name, opt);
6
+ this.func = null;
7
+ }
8
+ onAdd(_, args) {
9
+ this.func = args[0];
10
+ return true;
11
+ }
12
+ onBefore1(builder, result) {
13
+ return this.func.call(builder, result, builder);
14
+ }
15
+ clone() {
16
+ const clone = super.clone();
17
+ clone.func = this.func;
18
+ return clone;
19
+ }
25
20
  }
26
-
27
21
  module.exports = {
28
- RunBeforeOperation,
22
+ RunBeforeOperation,
29
23
  };
@@ -1,23 +1,18 @@
1
1
  'use strict';
2
-
3
2
  const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
-
5
3
  class UnrelateOperation extends QueryBuilderOperation {
6
- constructor(name, opt) {
7
- super(name, opt);
8
-
9
- this.relation = opt.relation;
10
- this.owner = opt.owner;
11
- this.ids = null;
12
- }
13
-
14
- clone() {
15
- const clone = super.clone();
16
- clone.ids = this.ids;
17
- return clone;
18
- }
4
+ constructor(name, opt) {
5
+ super(name, opt);
6
+ this.relation = opt.relation;
7
+ this.owner = opt.owner;
8
+ this.ids = null;
9
+ }
10
+ clone() {
11
+ const clone = super.clone();
12
+ clone.ids = this.ids;
13
+ return clone;
14
+ }
19
15
  }
20
-
21
16
  module.exports = {
22
- UnrelateOperation,
17
+ UnrelateOperation,
23
18
  };
@@ -1,80 +1,63 @@
1
1
  'use strict';
2
-
3
2
  const { withWhereScope } = require('../whereScopes');
4
3
  const { DelegateOperation } = require('./DelegateOperation');
5
4
  const { FindByIdOperation } = require('./FindByIdOperation');
6
5
  const { UpdateOperation } = require('./UpdateOperation');
7
-
8
6
  class UpdateAndFetchOperation extends DelegateOperation {
9
- constructor(name, opt) {
10
- super(name, opt);
11
-
12
- if (!this.delegate.is(UpdateOperation)) {
13
- throw new Error('Invalid delegate');
7
+ constructor(name, opt) {
8
+ super(name, opt);
9
+ if (!this.delegate.is(UpdateOperation)) {
10
+ throw new Error('Invalid delegate');
11
+ }
12
+ this.id = null;
13
+ this.skipIdWhere = false;
14
14
  }
15
-
16
- this.id = null;
17
- this.skipIdWhere = false;
18
- }
19
-
20
- get model() {
21
- return this.delegate.model;
22
- }
23
-
24
- onAdd(builder, args) {
25
- this.id = args[0];
26
- return this.delegate.onAdd(builder, args.slice(1));
27
- }
28
-
29
- onBuild(builder) {
30
- if (!this.skipIdWhere) {
31
- withWhereScope(builder, () => builder.findById(this.id));
15
+ get model() {
16
+ return this.delegate.model;
32
17
  }
33
-
34
- super.onBuild(builder);
35
- }
36
-
37
- async onAfter2(builder, numUpdated) {
38
- if (numUpdated == 0) {
39
- // If nothing was updated, we should fetch nothing.
40
- await super.onAfter2(builder, numUpdated);
41
- return undefined;
18
+ onAdd(builder, args) {
19
+ this.id = args[0];
20
+ return this.delegate.onAdd(builder, args.slice(1));
42
21
  }
43
-
44
- const fetched = await builder
45
- .emptyInstance()
46
- .childQueryOf(builder)
47
- .modify((builder) => {
22
+ onBuild(builder) {
48
23
  if (!this.skipIdWhere) {
49
- builder.findById(this.id);
24
+ withWhereScope(builder, () => builder.findById(this.id));
25
+ }
26
+ super.onBuild(builder);
27
+ }
28
+ async onAfter2(builder, numUpdated) {
29
+ if (numUpdated == 0) {
30
+ // If nothing was updated, we should fetch nothing.
31
+ await super.onAfter2(builder, numUpdated);
32
+ return undefined;
50
33
  }
51
- })
52
- .castTo(builder.resultModelClass());
53
-
54
- if (fetched) {
55
- this.model.$set(fetched);
34
+ const fetched = await builder
35
+ .emptyInstance()
36
+ .childQueryOf(builder)
37
+ .modify((builder) => {
38
+ if (!this.skipIdWhere) {
39
+ builder.findById(this.id);
40
+ }
41
+ })
42
+ .castTo(builder.resultModelClass());
43
+ if (fetched) {
44
+ this.model.$set(fetched);
45
+ }
46
+ await super.onAfter2(builder, numUpdated);
47
+ return fetched ? this.model : undefined;
48
+ }
49
+ toFindOperation() {
50
+ return new FindByIdOperation('findById', {
51
+ id: this.id,
52
+ });
53
+ }
54
+ clone() {
55
+ const clone = super.clone();
56
+ clone.id = this.id;
57
+ clone.skipIdWhere = this.skipIdWhere;
58
+ return clone;
56
59
  }
57
-
58
- await super.onAfter2(builder, numUpdated);
59
- return fetched ? this.model : undefined;
60
- }
61
-
62
- toFindOperation() {
63
- return new FindByIdOperation('findById', {
64
- id: this.id,
65
- });
66
- }
67
-
68
- clone() {
69
- const clone = super.clone();
70
-
71
- clone.id = this.id;
72
- clone.skipIdWhere = this.skipIdWhere;
73
-
74
- return clone;
75
- }
76
60
  }
77
-
78
61
  module.exports = {
79
- UpdateAndFetchOperation,
62
+ UpdateAndFetchOperation,
80
63
  };
@@ -1,155 +1,130 @@
1
1
  'use strict';
2
-
3
2
  const { ref } = require('../../queryBuilder/ReferenceBuilder');
4
3
  const { isEmpty } = require('../../utils/objectUtils');
5
4
  const { isKnexRaw, isKnexQueryBuilder } = require('../../utils/knexUtils');
6
5
  const { toPgJsonPathLiteral, getJsonDialect } = require('../../utils/postgresJsonPath');
7
- const { toMySqlJsonPath } = require('../../utils/mysqlJsonPath');
6
+ const { toMySqlJsonPath, toJsonSql } = require('../../utils/mysqlJsonPath');
8
7
  const { QueryBuilderOperation } = require('./QueryBuilderOperation');
9
- const { StaticHookArguments } = require('../StaticHookArguments');
10
-
8
+ const { StaticHookArguments, hasStaticHook } = require('../StaticHookArguments');
11
9
  class UpdateOperation extends QueryBuilderOperation {
12
- constructor(name, opt) {
13
- super(name, opt);
14
-
15
- this.model = null;
16
- this.modelOptions = Object.assign({}, this.opt.modelOptions || {});
17
- }
18
-
19
- onAdd(builder, args) {
20
- const json = args[0];
21
- const modelClass = builder.modelClass();
22
-
23
- this.model = modelClass.ensureModel(json, this.modelOptions);
24
- return true;
25
- }
26
-
27
- async onBefore2(builder, result) {
28
- await callBeforeUpdate(builder, this.model, this.modelOptions);
29
- return result;
30
- }
31
-
32
- onBefore3(builder) {
33
- const row = this.model.$toDatabaseJson(builder);
34
-
35
- if (isEmpty(row)) {
36
- // Resolve the query if there is nothing to update.
37
- builder.resolve(0);
10
+ constructor(name, opt) {
11
+ super(name, opt);
12
+ this.model = null;
13
+ this.modelOptions = Object.assign({}, this.opt.modelOptions || {});
14
+ }
15
+ onAdd(builder, args) {
16
+ const json = args[0];
17
+ const modelClass = builder.modelClass();
18
+ this.model = modelClass.ensureModel(json, this.modelOptions);
19
+ return true;
20
+ }
21
+ async onBefore2(builder, result) {
22
+ await callBeforeUpdate(builder, this.model, this.modelOptions);
23
+ return result;
24
+ }
25
+ onBefore3(builder) {
26
+ const row = this.model.$toDatabaseJson(builder);
27
+ if (isEmpty(row)) {
28
+ // Resolve the query if there is nothing to update.
29
+ builder.resolve(0);
30
+ }
31
+ }
32
+ onBuildKnex(knexBuilder, builder) {
33
+ const json = this.model.$toDatabaseJson(builder);
34
+ const convertedJson = convertFieldExpressionsToRaw(builder, this.model, json);
35
+ return knexBuilder.update(convertedJson);
36
+ }
37
+ onAfter2(builder, numUpdated) {
38
+ return callAfterUpdate(builder, this.model, this.modelOptions, numUpdated);
39
+ }
40
+ toFindOperation() {
41
+ return null;
42
+ }
43
+ clone() {
44
+ const clone = super.clone();
45
+ clone.model = this.model;
46
+ return clone;
38
47
  }
39
- }
40
-
41
- onBuildKnex(knexBuilder, builder) {
42
- const json = this.model.$toDatabaseJson(builder);
43
- const convertedJson = convertFieldExpressionsToRaw(builder, this.model, json);
44
-
45
- return knexBuilder.update(convertedJson);
46
- }
47
-
48
- onAfter2(builder, numUpdated) {
49
- return callAfterUpdate(builder, this.model, this.modelOptions, numUpdated);
50
- }
51
-
52
- toFindOperation() {
53
- return null;
54
- }
55
-
56
- clone() {
57
- const clone = super.clone();
58
- clone.model = this.model;
59
- return clone;
60
- }
61
48
  }
62
-
63
49
  async function callBeforeUpdate(builder, model, modelOptions) {
64
- await callInstanceBeforeUpdate(builder, model, modelOptions);
65
- return callStaticBeforeUpdate(builder);
50
+ await callInstanceBeforeUpdate(builder, model, modelOptions);
51
+ return callStaticBeforeUpdate(builder);
66
52
  }
67
-
68
53
  function callInstanceBeforeUpdate(builder, model, modelOptions) {
69
- return model.$beforeUpdate(modelOptions, builder.context());
54
+ return model.$beforeUpdate(modelOptions, builder.context());
70
55
  }
71
-
72
56
  function callStaticBeforeUpdate(builder) {
73
- const args = StaticHookArguments.create({ builder });
74
- return builder.modelClass().beforeUpdate(args);
57
+ if (!hasStaticHook(builder.modelClass(), 'beforeUpdate')) {
58
+ return undefined;
59
+ }
60
+ const args = StaticHookArguments.create({ builder });
61
+ return builder.modelClass().beforeUpdate(args);
75
62
  }
76
-
77
63
  async function callAfterUpdate(builder, model, modelOptions, result) {
78
- await callInstanceAfterUpdate(builder, model, modelOptions);
79
- return callStaticAfterUpdate(builder, result);
64
+ await callInstanceAfterUpdate(builder, model, modelOptions);
65
+ return callStaticAfterUpdate(builder, result);
80
66
  }
81
-
82
67
  function callInstanceAfterUpdate(builder, model, modelOptions) {
83
- return model.$afterUpdate(modelOptions, builder.context());
68
+ return model.$afterUpdate(modelOptions, builder.context());
84
69
  }
85
-
86
70
  async function callStaticAfterUpdate(builder, result) {
87
- const args = StaticHookArguments.create({ builder, result });
88
- const maybeResult = await builder.modelClass().afterUpdate(args);
89
-
90
- if (maybeResult === undefined) {
91
- return result;
92
- } else {
93
- return maybeResult;
94
- }
71
+ if (!hasStaticHook(builder.modelClass(), 'afterUpdate')) {
72
+ return result;
73
+ }
74
+ const args = StaticHookArguments.create({ builder, result });
75
+ const maybeResult = await builder.modelClass().afterUpdate(args);
76
+ if (maybeResult === undefined) {
77
+ return result;
78
+ }
79
+ else {
80
+ return maybeResult;
81
+ }
95
82
  }
96
-
97
83
  function convertFieldExpressionsToRaw(builder, model, json) {
98
- const knex = builder.knex();
99
- const convertedJson = {};
100
-
101
- for (const key of Object.keys(json)) {
102
- let val = json[key];
103
-
104
- if (key.indexOf(':') > -1) {
105
- // 'col:attr' : ref('other:lol') is transformed to
106
- // "col" : raw(`jsonb_set(COALESCE("col", '{}'), '{attr}', to_jsonb("other"#>'{lol}'), true)`)
107
- // on postgres and to
108
- // `col` : raw("JSON_SET(COALESCE(`col`, JSON_OBJECT()), '$.\"attr\"', JSON_EXTRACT(`other`, '$.\"lol\"'))")
109
- // on mysql. A NULL column is treated as an empty object (or array).
110
-
111
- const parsed = ref(key);
112
- const access = parsed.parsedExpr.access;
113
- const isSqlValue = isKnexQueryBuilder(val) || isKnexRaw(val);
114
- // When the column is set by an earlier key, that expression is used instead.
115
- const target = convertedJson[parsed.column] || parsed.column;
116
- const isFirstSet = !convertedJson[parsed.column];
117
-
118
- if (!isSqlValue) {
119
- val = JSON.stringify(val);
120
- }
121
-
122
- if (getJsonDialect(knex, key) === 'mysql') {
123
- const empty = access[0].type === 'array' ? 'JSON_ARRAY()' : 'JSON_OBJECT()';
124
- const column = isFirstSet ? `COALESCE(??, ${empty})` : '??';
125
- const value = isSqlValue ? '?' : 'CAST(? AS JSON)';
126
-
127
- convertedJson[parsed.column] = knex.raw(`JSON_SET(${column}, ?, ${value})`, [
128
- target,
129
- toMySqlJsonPath(access),
130
- val,
131
- ]);
132
- } else {
133
- const empty = access[0].type === 'array' ? `'[]'::jsonb` : `'{}'::jsonb`;
134
- const column = isFirstSet ? `COALESCE(??, ${empty})` : '??';
135
- const value = isSqlValue ? 'to_jsonb(?)' : '?';
136
-
137
- convertedJson[parsed.column] = knex.raw(
138
- `jsonb_set(${column}, ${toPgJsonPathLiteral(access)}, ${value}, true)`,
139
- [target, val],
140
- );
141
- }
142
-
143
- delete model[key];
144
- } else {
145
- convertedJson[key] = val;
84
+ const knex = builder.knex();
85
+ const convertedJson = {};
86
+ for (const key of Object.keys(json)) {
87
+ let val = json[key];
88
+ if (key.indexOf(':') > -1) {
89
+ // 'col:attr' : ref('other:lol') is transformed to
90
+ // "col" : raw(`jsonb_set(COALESCE("col", '{}'), '{attr}', to_jsonb("other"#>'{lol}'), true)`)
91
+ // on postgres and to
92
+ // `col` : raw("JSON_SET(COALESCE(`col`, JSON_OBJECT()), '$.\"attr\"', JSON_EXTRACT(`other`, '$.\"lol\"'))")
93
+ // on mysql. A NULL column is treated as an empty object (or array).
94
+ const parsed = ref(key);
95
+ const access = parsed.parsedExpr.access;
96
+ const isSqlValue = isKnexQueryBuilder(val) || isKnexRaw(val);
97
+ // When the column is set by an earlier key, that expression is used instead.
98
+ const target = convertedJson[parsed.column] || parsed.column;
99
+ const isFirstSet = !convertedJson[parsed.column];
100
+ if (!isSqlValue) {
101
+ val = JSON.stringify(val);
102
+ }
103
+ if (getJsonDialect(knex, key) === 'mysql') {
104
+ const empty = access[0].type === 'array' ? 'JSON_ARRAY()' : 'JSON_OBJECT()';
105
+ const column = isFirstSet ? `COALESCE(??, ${empty})` : '??';
106
+ const value = isSqlValue ? '?' : toJsonSql('?', knex);
107
+ convertedJson[parsed.column] = knex.raw(`JSON_SET(${column}, ?, ${value})`, [
108
+ target,
109
+ toMySqlJsonPath(access),
110
+ val,
111
+ ]);
112
+ }
113
+ else {
114
+ const empty = access[0].type === 'array' ? `'[]'::jsonb` : `'{}'::jsonb`;
115
+ const column = isFirstSet ? `COALESCE(??, ${empty})` : '??';
116
+ const value = isSqlValue ? 'to_jsonb(?)' : '?';
117
+ convertedJson[parsed.column] = knex.raw(`jsonb_set(${column}, ${toPgJsonPathLiteral(access)}, ${value}, true)`, [target, val]);
118
+ }
119
+ delete model[key];
120
+ }
121
+ else {
122
+ convertedJson[key] = val;
123
+ }
146
124
  }
147
- }
148
-
149
- return convertedJson;
125
+ return convertedJson;
150
126
  }
151
-
152
127
  module.exports = {
153
- UpdateOperation,
154
- convertFieldExpressionsToRaw,
128
+ UpdateOperation,
129
+ convertFieldExpressionsToRaw,
155
130
  };
@@ -1,45 +1,35 @@
1
1
  'use strict';
2
-
3
2
  const { DelegateOperation } = require('./DelegateOperation');
4
3
  const { UpsertGraphOperation } = require('./UpsertGraphOperation');
5
4
  const { RelationExpression } = require('../RelationExpression');
6
-
7
5
  class UpsertGraphAndFetchOperation extends DelegateOperation {
8
- constructor(name, opt) {
9
- super(name, opt);
10
-
11
- if (!this.delegate.is(UpsertGraphOperation)) {
12
- throw new Error('Invalid delegate');
6
+ constructor(name, opt) {
7
+ super(name, opt);
8
+ if (!this.delegate.is(UpsertGraphOperation)) {
9
+ throw new Error('Invalid delegate');
10
+ }
13
11
  }
14
- }
15
-
16
- get models() {
17
- return this.delegate.models;
18
- }
19
-
20
- get isArray() {
21
- return this.delegate.isArray;
22
- }
23
-
24
- async onAfter3(builder) {
25
- if (this.models.length === 0) {
26
- return this.isArray ? [] : null;
12
+ get models() {
13
+ return this.delegate.models;
14
+ }
15
+ get isArray() {
16
+ return this.delegate.isArray;
17
+ }
18
+ async onAfter3(builder) {
19
+ if (this.models.length === 0) {
20
+ return this.isArray ? [] : null;
21
+ }
22
+ const eager = RelationExpression.fromModelGraph(this.models);
23
+ const modelClass = this.models[0].constructor;
24
+ const ids = this.models.map((model) => model.$id());
25
+ const models = await modelClass
26
+ .query()
27
+ .childQueryOf(builder)
28
+ .findByIds(ids)
29
+ .withGraphFetched(eager);
30
+ return this.isArray ? models : models[0] || null;
27
31
  }
28
-
29
- const eager = RelationExpression.fromModelGraph(this.models);
30
- const modelClass = this.models[0].constructor;
31
- const ids = this.models.map((model) => model.$id());
32
-
33
- const models = await modelClass
34
- .query()
35
- .childQueryOf(builder)
36
- .findByIds(ids)
37
- .withGraphFetched(eager);
38
-
39
- return this.isArray ? models : models[0] || null;
40
- }
41
32
  }
42
-
43
33
  module.exports = {
44
- UpsertGraphAndFetchOperation,
34
+ UpsertGraphAndFetchOperation,
45
35
  };