@abedmurrar/objection 0.0.0-stage → 4.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +69 -2
  3. package/lib/.eslintrc.json +8 -0
  4. package/lib/initialize.js +14 -0
  5. package/lib/model/AjvValidator.js +325 -0
  6. package/lib/model/Model.js +942 -0
  7. package/lib/model/ModifierNotFoundError.js +12 -0
  8. package/lib/model/NotFoundError.js +23 -0
  9. package/lib/model/RelationDoesNotExistError.js +14 -0
  10. package/lib/model/ValidationError.js +54 -0
  11. package/lib/model/Validator.js +26 -0
  12. package/lib/model/getModel.js +9 -0
  13. package/lib/model/graph/ModelGraph.js +80 -0
  14. package/lib/model/graph/ModelGraphBuilder.js +241 -0
  15. package/lib/model/graph/ModelGraphEdge.js +52 -0
  16. package/lib/model/graph/ModelGraphNode.js +240 -0
  17. package/lib/model/inheritModel.js +28 -0
  18. package/lib/model/modelBindKnex.js +83 -0
  19. package/lib/model/modelClone.js +121 -0
  20. package/lib/model/modelColPropMap.js +34 -0
  21. package/lib/model/modelId.js +62 -0
  22. package/lib/model/modelJsonAttributes.js +92 -0
  23. package/lib/model/modelParseRelations.js +82 -0
  24. package/lib/model/modelQueryProps.js +147 -0
  25. package/lib/model/modelSet.js +136 -0
  26. package/lib/model/modelTableMetadata.js +83 -0
  27. package/lib/model/modelToJson.js +187 -0
  28. package/lib/model/modelUtils.js +47 -0
  29. package/lib/model/modelValidate.js +48 -0
  30. package/lib/model/modelValues.js +126 -0
  31. package/lib/model/modelVisitor.js +41 -0
  32. package/lib/objection.js +114 -0
  33. package/lib/queryBuilder/FunctionBuilder.js +339 -0
  34. package/lib/queryBuilder/InternalOptions.js +29 -0
  35. package/lib/queryBuilder/JoinBuilder.js +157 -0
  36. package/lib/queryBuilder/QueryBuilder.js +1398 -0
  37. package/lib/queryBuilder/QueryBuilderBase.js +884 -0
  38. package/lib/queryBuilder/QueryBuilderContext.js +27 -0
  39. package/lib/queryBuilder/QueryBuilderContextBase.js +35 -0
  40. package/lib/queryBuilder/QueryBuilderOperationSupport.js +558 -0
  41. package/lib/queryBuilder/QueryBuilderUserContext.js +31 -0
  42. package/lib/queryBuilder/RawBuilder.js +93 -0
  43. package/lib/queryBuilder/ReferenceBuilder.js +284 -0
  44. package/lib/queryBuilder/RelationExpression.js +431 -0
  45. package/lib/queryBuilder/StaticHookArguments.js +134 -0
  46. package/lib/queryBuilder/ValueBuilder.js +127 -0
  47. package/lib/queryBuilder/expressions.js +151 -0
  48. package/lib/queryBuilder/functions/mysql.js +817 -0
  49. package/lib/queryBuilder/graph/GraphAction.js +69 -0
  50. package/lib/queryBuilder/graph/GraphData.js +14 -0
  51. package/lib/queryBuilder/graph/GraphFetcher.js +191 -0
  52. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +184 -0
  53. package/lib/queryBuilder/graph/GraphOperation.js +27 -0
  54. package/lib/queryBuilder/graph/GraphOptions.js +207 -0
  55. package/lib/queryBuilder/graph/GraphUpsert.js +305 -0
  56. package/lib/queryBuilder/graph/delete/GraphDelete.js +20 -0
  57. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +74 -0
  58. package/lib/queryBuilder/graph/insert/GraphInsert.js +145 -0
  59. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +225 -0
  60. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +92 -0
  61. package/lib/queryBuilder/graph/patch/GraphPatch.js +20 -0
  62. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +258 -0
  63. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +31 -0
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +126 -0
  65. package/lib/queryBuilder/join/JoinResultColumn.js +23 -0
  66. package/lib/queryBuilder/join/JoinResultParser.js +119 -0
  67. package/lib/queryBuilder/join/RelationJoiner.js +341 -0
  68. package/lib/queryBuilder/join/TableNode.js +163 -0
  69. package/lib/queryBuilder/join/TableTree.js +85 -0
  70. package/lib/queryBuilder/join/utils.js +25 -0
  71. package/lib/queryBuilder/operations/DelegateOperation.js +141 -0
  72. package/lib/queryBuilder/operations/DeleteOperation.js +51 -0
  73. package/lib/queryBuilder/operations/FindByIdOperation.js +37 -0
  74. package/lib/queryBuilder/operations/FindByIdsOperation.js +29 -0
  75. package/lib/queryBuilder/operations/FindOperation.js +164 -0
  76. package/lib/queryBuilder/operations/FirstOperation.js +27 -0
  77. package/lib/queryBuilder/operations/FromOperation.js +110 -0
  78. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +49 -0
  79. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +45 -0
  80. package/lib/queryBuilder/operations/InsertGraphOperation.js +108 -0
  81. package/lib/queryBuilder/operations/InsertOperation.js +206 -0
  82. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +46 -0
  83. package/lib/queryBuilder/operations/InstanceFindOperation.js +21 -0
  84. package/lib/queryBuilder/operations/InstanceInsertOperation.js +24 -0
  85. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +59 -0
  86. package/lib/queryBuilder/operations/JoinRelatedOperation.js +103 -0
  87. package/lib/queryBuilder/operations/KnexOperation.js +14 -0
  88. package/lib/queryBuilder/operations/MergeOperation.js +56 -0
  89. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +192 -0
  90. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +29 -0
  91. package/lib/queryBuilder/operations/OnBuildOperation.js +29 -0
  92. package/lib/queryBuilder/operations/OnErrorOperation.js +29 -0
  93. package/lib/queryBuilder/operations/QueryBuilderOperation.js +297 -0
  94. package/lib/queryBuilder/operations/RangeOperation.js +47 -0
  95. package/lib/queryBuilder/operations/RelateOperation.js +27 -0
  96. package/lib/queryBuilder/operations/ReturningOperation.js +30 -0
  97. package/lib/queryBuilder/operations/RunAfterOperation.js +29 -0
  98. package/lib/queryBuilder/operations/RunBeforeOperation.js +29 -0
  99. package/lib/queryBuilder/operations/UnrelateOperation.js +23 -0
  100. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +80 -0
  101. package/lib/queryBuilder/operations/UpdateOperation.js +155 -0
  102. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +45 -0
  103. package/lib/queryBuilder/operations/UpsertGraphOperation.js +66 -0
  104. package/lib/queryBuilder/operations/WhereCompositeOperation.js +57 -0
  105. package/lib/queryBuilder/operations/WhereInOperation.js +48 -0
  106. package/lib/queryBuilder/operations/eager/EagerOperation.js +61 -0
  107. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +51 -0
  108. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +13 -0
  109. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +285 -0
  110. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +36 -0
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +53 -0
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +31 -0
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +31 -0
  114. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +167 -0
  115. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +164 -0
  116. package/lib/queryBuilder/operations/select/SelectOperation.js +66 -0
  117. package/lib/queryBuilder/operations/select/Selection.js +123 -0
  118. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +117 -0
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +100 -0
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +104 -0
  121. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +886 -0
  122. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +97 -0
  123. package/lib/queryBuilder/parsers/relationExpressionParser.js +1042 -0
  124. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +141 -0
  125. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +22 -0
  126. package/lib/queryBuilder/transformations/QueryTransformation.js +11 -0
  127. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +71 -0
  128. package/lib/queryBuilder/transformations/index.js +15 -0
  129. package/lib/queryBuilder/whereScopes.js +227 -0
  130. package/lib/relations/Relation.js +401 -0
  131. package/lib/relations/RelationDeleteOperation.js +29 -0
  132. package/lib/relations/RelationFindOperation.js +149 -0
  133. package/lib/relations/RelationInsertOperation.js +33 -0
  134. package/lib/relations/RelationOwner.js +236 -0
  135. package/lib/relations/RelationProperty.js +247 -0
  136. package/lib/relations/RelationUpdateOperation.js +30 -0
  137. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +23 -0
  138. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +44 -0
  139. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +50 -0
  140. package/lib/relations/belongsToOne/BelongsToOneRelation.js +53 -0
  141. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +61 -0
  142. package/lib/relations/hasMany/HasManyInsertOperation.js +61 -0
  143. package/lib/relations/hasMany/HasManyRelateOperation.js +64 -0
  144. package/lib/relations/hasMany/HasManyRelation.js +49 -0
  145. package/lib/relations/hasMany/HasManyUnrelateOperation.js +33 -0
  146. package/lib/relations/hasOne/HasOneRelation.js +13 -0
  147. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +13 -0
  148. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +105 -0
  149. package/lib/relations/manyToMany/ManyToManyRelation.js +507 -0
  150. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +36 -0
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +10 -0
  152. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +26 -0
  153. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +12 -0
  154. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +105 -0
  155. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +52 -0
  156. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +81 -0
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +14 -0
  158. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +34 -0
  159. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +16 -0
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +10 -0
  161. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +82 -0
  162. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +12 -0
  163. package/lib/transaction.js +96 -0
  164. package/lib/utils/assert.js +25 -0
  165. package/lib/utils/buildUtils.js +21 -0
  166. package/lib/utils/classUtils.js +13 -0
  167. package/lib/utils/clone.js +2329 -0
  168. package/lib/utils/createModifier.js +42 -0
  169. package/lib/utils/deprecate.js +15 -0
  170. package/lib/utils/identifierMapping.js +227 -0
  171. package/lib/utils/internalPropUtils.js +11 -0
  172. package/lib/utils/knexUtils.js +76 -0
  173. package/lib/utils/mixin.js +25 -0
  174. package/lib/utils/mysqlJsonPath.js +55 -0
  175. package/lib/utils/normalizeIds.js +144 -0
  176. package/lib/utils/objectUtils.js +416 -0
  177. package/lib/utils/parseFieldExpression.js +51 -0
  178. package/lib/utils/postgresJsonPath.js +110 -0
  179. package/lib/utils/promiseUtils/after.js +17 -0
  180. package/lib/utils/promiseUtils/afterReturn.js +17 -0
  181. package/lib/utils/promiseUtils/index.js +17 -0
  182. package/lib/utils/promiseUtils/isPromise.js +11 -0
  183. package/lib/utils/promiseUtils/map.js +110 -0
  184. package/lib/utils/promiseUtils/mapAfterAllReturn.js +29 -0
  185. package/lib/utils/promiseUtils/try.js +22 -0
  186. package/lib/utils/resolveModel.js +107 -0
  187. package/lib/utils/tmpColumnUtils.js +16 -0
  188. package/package.json +86 -4
  189. package/typings/objection/index.d.ts +4104 -0
  190. package/typings/objection/relation-expression.d.ts +237 -0
@@ -0,0 +1,163 @@
1
+ 'use strict';
2
+
3
+ class TableNode {
4
+ constructor({ tableTree, modelClass, expression, parentNode = null, relation = null }) {
5
+ this.tableTree = tableTree;
6
+ this.modelClass = modelClass;
7
+ this.parentNode = parentNode;
8
+ this.relation = relation;
9
+ this.expression = expression;
10
+ this.childNodes = [];
11
+
12
+ this.alias = this._calculateAlias();
13
+ this.idGetter = this._createIdGetter();
14
+ }
15
+
16
+ static create(args) {
17
+ const node = new TableNode(args);
18
+
19
+ if (node.parentNode) {
20
+ node.parentNode.childNodes.push(node);
21
+ }
22
+
23
+ return node;
24
+ }
25
+
26
+ get options() {
27
+ return this.tableTree.options;
28
+ }
29
+
30
+ get relationProperty() {
31
+ return this.expression.node.$name;
32
+ }
33
+
34
+ getReferenceForColumn(column) {
35
+ return `${this.alias}.${column}`;
36
+ }
37
+
38
+ getColumnAliasForColumn(column) {
39
+ if (this.parentNode) {
40
+ return `${this.alias}${this.options.separator}${column}`;
41
+ } else {
42
+ return column;
43
+ }
44
+ }
45
+
46
+ getColumnForColumnAlias(columnAlias) {
47
+ const lastSepIndex = columnAlias.lastIndexOf(this.options.separator);
48
+
49
+ if (lastSepIndex === -1) {
50
+ return columnAlias;
51
+ } else {
52
+ return columnAlias.slice(lastSepIndex + this.options.separator.length);
53
+ }
54
+ }
55
+
56
+ getIdFromFlatRow(flatRow) {
57
+ return this.idGetter(flatRow);
58
+ }
59
+
60
+ getJoinTableAlias(builder) {
61
+ if (this.relation.isObjectionManyToManyRelation) {
62
+ return (
63
+ builder.aliasFor(this.relation.joinTableModelClass) ||
64
+ this.modelClass.joinTableAlias(this.alias)
65
+ );
66
+ } else {
67
+ return undefined;
68
+ }
69
+ }
70
+
71
+ _calculateAlias() {
72
+ if (this.parentNode) {
73
+ const relationName = this.expression.node.$name;
74
+ const alias = this.options.aliases[relationName] || relationName;
75
+
76
+ if (this.options.minimize) {
77
+ return `_t${this.tableTree.createNextUid()}`;
78
+ } else if (this.parentNode.parentNode) {
79
+ return `${this.parentNode.alias}${this.options.separator}${alias}`;
80
+ } else {
81
+ return alias;
82
+ }
83
+ } else {
84
+ return this.tableTree.rootTableAlias;
85
+ }
86
+ }
87
+
88
+ _createIdGetter() {
89
+ const idColumns = this.modelClass.getIdColumnArray();
90
+ const columnAliases = idColumns.map((column) => this.getColumnAliasForColumn(column));
91
+
92
+ if (idColumns.length === 1) {
93
+ return createIdGetter(columnAliases);
94
+ } else {
95
+ return createCompositeIdGetter(columnAliases);
96
+ }
97
+ }
98
+ }
99
+
100
+ function createIdGetter(columnAliases) {
101
+ const columnAlias = columnAliases[0];
102
+
103
+ return (flatRow) => {
104
+ const id = flatRow[columnAlias];
105
+
106
+ if (id === null) {
107
+ return null;
108
+ }
109
+
110
+ return `${id}`;
111
+ };
112
+ }
113
+
114
+ function createCompositeIdGetter(columnAliases) {
115
+ if (columnAliases.length === 2) {
116
+ return createTwoIdGetter(columnAliases);
117
+ } else {
118
+ return createMultiIdGetter(columnAliases);
119
+ }
120
+ }
121
+
122
+ function createTwoIdGetter(columnAliases) {
123
+ const columnAlias1 = columnAliases[0];
124
+ const columnAlias2 = columnAliases[1];
125
+
126
+ return (flatRow) => {
127
+ const id1 = flatRow[columnAlias1];
128
+ const id2 = flatRow[columnAlias2];
129
+
130
+ if (id1 === null || id2 === null) {
131
+ return null;
132
+ }
133
+
134
+ return `${id1},${id2}`;
135
+ };
136
+ }
137
+
138
+ function createMultiIdGetter(columnAliases) {
139
+ return (flatRow) => {
140
+ let idStr = '';
141
+
142
+ for (let i = 0, l = columnAliases.length; i < l; ++i) {
143
+ const columnAlias = columnAliases[i];
144
+ const id = flatRow[columnAlias];
145
+
146
+ if (id === null) {
147
+ return null;
148
+ }
149
+
150
+ idStr += id;
151
+
152
+ if (i !== l - 1) {
153
+ idStr += ',';
154
+ }
155
+ }
156
+
157
+ return idStr;
158
+ };
159
+ }
160
+
161
+ module.exports = {
162
+ TableNode,
163
+ };
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ const { forEachChildExpression } = require('./utils');
4
+ const { TableNode } = require('./TableNode');
5
+
6
+ class TableTree {
7
+ constructor({ expression, rootModelClass, rootTableAlias, options }) {
8
+ this.options = options;
9
+ this.rootModelClass = rootModelClass;
10
+ this.rootTableAlias = rootTableAlias;
11
+ this.nodes = [];
12
+ this.nodesByAlias = new Map();
13
+ this.uidCounter = 0;
14
+
15
+ this._createNodes({ expression, modelClass: rootModelClass });
16
+ }
17
+
18
+ static create(args) {
19
+ return new TableTree(args);
20
+ }
21
+
22
+ get rootNode() {
23
+ return this.nodes[0];
24
+ }
25
+
26
+ getNodeForColumnAlias(columnAlias) {
27
+ const lastSepIndex = columnAlias.lastIndexOf(this.options.separator);
28
+
29
+ if (lastSepIndex === -1) {
30
+ return this.rootNode;
31
+ } else {
32
+ const tableAlias = columnAlias.slice(0, lastSepIndex);
33
+ return this.nodesByAlias.get(tableAlias);
34
+ }
35
+ }
36
+
37
+ createNextUid() {
38
+ return this.uidCounter++;
39
+ }
40
+
41
+ _createNodes({ expression, modelClass }) {
42
+ const rootNode = this._createRootNode({ expression, modelClass });
43
+ this._createChildNodes({ expression, modelClass, parentNode: rootNode });
44
+
45
+ for (const node of this.nodes) {
46
+ this.nodesByAlias.set(node.alias, node);
47
+ }
48
+ }
49
+
50
+ _createRootNode({ expression, modelClass }) {
51
+ const node = TableNode.create({
52
+ tableTree: this,
53
+ modelClass,
54
+ expression,
55
+ });
56
+
57
+ this.nodes.push(node);
58
+ return node;
59
+ }
60
+
61
+ _createChildNodes({ expression, modelClass, parentNode }) {
62
+ forEachChildExpression(expression, modelClass, (childExpr, relation) => {
63
+ const node = TableNode.create({
64
+ tableTree: this,
65
+ modelClass: relation.relatedModelClass,
66
+ expression: childExpr,
67
+
68
+ parentNode,
69
+ relation,
70
+ });
71
+
72
+ this.nodes.push(node);
73
+
74
+ this._createChildNodes({
75
+ expression: childExpr,
76
+ modelClass: relation.relatedModelClass,
77
+ parentNode: node,
78
+ });
79
+ });
80
+ }
81
+ }
82
+
83
+ module.exports = {
84
+ TableTree,
85
+ };
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ const { ValidationErrorType } = require('../../model/ValidationError');
4
+
5
+ const ID_LENGTH_LIMIT = 63;
6
+ const RELATION_RECURSION_LIMIT = 64;
7
+
8
+ // Given a relation expression, goes through all first level children.
9
+ function forEachChildExpression(expr, modelClass, callback) {
10
+ if (expr.node.$allRecursive || expr.maxRecursionDepth > RELATION_RECURSION_LIMIT) {
11
+ throw modelClass.createValidationError({
12
+ type: ValidationErrorType.RelationExpression,
13
+ message: `recursion depth of eager expression ${expr.toString()} too big for JoinEagerAlgorithm`,
14
+ });
15
+ }
16
+
17
+ expr.forEachChildExpression(modelClass, callback);
18
+ }
19
+
20
+ module.exports = {
21
+ ID_LENGTH_LIMIT,
22
+ RELATION_RECURSION_LIMIT,
23
+
24
+ forEachChildExpression,
25
+ };
@@ -0,0 +1,141 @@
1
+ 'use strict';
2
+
3
+ const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
+
5
+ // Operation that simply delegates all calls to the operation passed
6
+ // to to the constructor in `opt.delegate`.
7
+ class DelegateOperation extends QueryBuilderOperation {
8
+ constructor(name, opt) {
9
+ super(name, opt);
10
+
11
+ this.delegate = opt.delegate;
12
+ }
13
+
14
+ get modelOptions() {
15
+ return this.delegate.modelOptions;
16
+ }
17
+
18
+ is(OperationClass) {
19
+ return super.is(OperationClass) || this.delegate.is(OperationClass);
20
+ }
21
+
22
+ onAdd(builder, args) {
23
+ return this.delegate.onAdd(builder, args);
24
+ }
25
+
26
+ onBefore1(builder, result) {
27
+ return this.delegate.onBefore1(builder, result);
28
+ }
29
+
30
+ hasOnBefore1() {
31
+ return this.onBefore1 !== DelegateOperation.prototype.onBefore1 || this.delegate.hasOnBefore1();
32
+ }
33
+
34
+ onBefore2(builder, result) {
35
+ return this.delegate.onBefore2(builder, result);
36
+ }
37
+
38
+ hasOnBefore2() {
39
+ return this.onBefore2 !== DelegateOperation.prototype.onBefore2 || this.delegate.hasOnBefore2();
40
+ }
41
+
42
+ onBefore3(builder, result) {
43
+ return this.delegate.onBefore3(builder, result);
44
+ }
45
+
46
+ hasOnBefore3() {
47
+ return this.onBefore3 !== DelegateOperation.prototype.onBefore3 || this.delegate.hasOnBefore3();
48
+ }
49
+
50
+ onBuild(builder) {
51
+ return this.delegate.onBuild(builder);
52
+ }
53
+
54
+ hasOnBuild() {
55
+ return this.onBuild !== DelegateOperation.prototype.onBuild || this.delegate.hasOnBuild();
56
+ }
57
+
58
+ onBuildKnex(knexBuilder, builder) {
59
+ return this.delegate.onBuildKnex(knexBuilder, builder);
60
+ }
61
+
62
+ hasOnBuildKnex() {
63
+ return (
64
+ this.onBuildKnex !== DelegateOperation.prototype.onBuildKnex || this.delegate.hasOnBuildKnex()
65
+ );
66
+ }
67
+
68
+ onRawResult(builder, result) {
69
+ return this.delegate.onRawResult(builder, result);
70
+ }
71
+
72
+ hasOnRawResult() {
73
+ return (
74
+ this.onRawResult !== DelegateOperation.prototype.onRawResult || this.delegate.hasOnRawResult()
75
+ );
76
+ }
77
+
78
+ onAfter1(builder, result) {
79
+ return this.delegate.onAfter1(builder, result);
80
+ }
81
+
82
+ hasOnAfter1() {
83
+ return this.onAfter1 !== DelegateOperation.prototype.onAfter1 || this.delegate.hasOnAfter1();
84
+ }
85
+
86
+ onAfter2(builder, result) {
87
+ return this.delegate.onAfter2(builder, result);
88
+ }
89
+
90
+ hasOnAfter2() {
91
+ return this.onAfter2 !== DelegateOperation.prototype.onAfter2 || this.delegate.hasOnAfter2();
92
+ }
93
+
94
+ onAfter3(builder, result) {
95
+ return this.delegate.onAfter3(builder, result);
96
+ }
97
+
98
+ hasOnAfter3() {
99
+ return this.onAfter3 !== DelegateOperation.prototype.onAfter3 || this.delegate.hasOnAfter3();
100
+ }
101
+
102
+ queryExecutor(builder) {
103
+ return this.delegate.queryExecutor(builder);
104
+ }
105
+
106
+ hasQueryExecutor() {
107
+ return (
108
+ this.queryExecutor !== DelegateOperation.prototype.queryExecutor ||
109
+ this.delegate.hasQueryExecutor()
110
+ );
111
+ }
112
+
113
+ onError(builder, error) {
114
+ return this.delegate.onError(builder, error);
115
+ }
116
+
117
+ hasOnError() {
118
+ return this.onError !== DelegateOperation.prototype.onError || this.delegate.hasOnError();
119
+ }
120
+
121
+ toFindOperation(builder) {
122
+ return this.delegate.toFindOperation(builder);
123
+ }
124
+
125
+ hasToFindOperation() {
126
+ return (
127
+ this.hasToFindOperation !== DelegateOperation.prototype.hasToFindOperation ||
128
+ this.delegate.hasToFindOperation()
129
+ );
130
+ }
131
+
132
+ clone() {
133
+ const clone = super.clone();
134
+ clone.delegate = this.delegate && this.delegate.clone();
135
+ return clone;
136
+ }
137
+ }
138
+
139
+ module.exports = {
140
+ DelegateOperation,
141
+ };
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
+ const { StaticHookArguments } = require('../StaticHookArguments');
5
+
6
+ class DeleteOperation extends QueryBuilderOperation {
7
+ async onBefore2(builder, result) {
8
+ await callBeforeDelete(builder);
9
+ return result;
10
+ }
11
+
12
+ onBuildKnex(knexBuilder) {
13
+ return knexBuilder.delete();
14
+ }
15
+
16
+ onAfter2(builder, result) {
17
+ return callAfterDelete(builder, result);
18
+ }
19
+
20
+ toFindOperation() {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ function callBeforeDelete(builder) {
26
+ return callStaticBeforeDelete(builder);
27
+ }
28
+
29
+ function callStaticBeforeDelete(builder) {
30
+ const args = StaticHookArguments.create({ builder });
31
+ return builder.modelClass().beforeDelete(args);
32
+ }
33
+
34
+ function callAfterDelete(builder, result) {
35
+ return callStaticAfterDelete(builder, result);
36
+ }
37
+
38
+ async function callStaticAfterDelete(builder, result) {
39
+ const args = StaticHookArguments.create({ builder, result });
40
+ const maybeResult = await builder.modelClass().afterDelete(args);
41
+
42
+ if (maybeResult === undefined) {
43
+ return result;
44
+ } else {
45
+ return maybeResult;
46
+ }
47
+ }
48
+
49
+ module.exports = {
50
+ DeleteOperation,
51
+ };
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
+ const { assertIdNotUndefined } = require('../../utils/assert');
5
+
6
+ class FindByIdOperation extends QueryBuilderOperation {
7
+ constructor(name, opt) {
8
+ super(name, opt);
9
+ this.id = this.opt.id;
10
+ }
11
+
12
+ onAdd(builder, args) {
13
+ if (this.id === null || this.id === undefined) {
14
+ this.id = args[0];
15
+ }
16
+
17
+ return super.onAdd(builder, args);
18
+ }
19
+
20
+ onBuild(builder) {
21
+ if (!builder.internalOptions().skipUndefined) {
22
+ assertIdNotUndefined(this.id, `undefined was passed to ${this.name}`);
23
+ }
24
+
25
+ builder.whereComposite(builder.fullIdColumn(), this.id);
26
+ }
27
+
28
+ clone() {
29
+ const clone = super.clone();
30
+ clone.id = this.id;
31
+ return clone;
32
+ }
33
+ }
34
+
35
+ module.exports = {
36
+ FindByIdOperation,
37
+ };
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
+
5
+ class FindByIdsOperation extends QueryBuilderOperation {
6
+ constructor(name, opt) {
7
+ super(name, opt);
8
+ this.ids = null;
9
+ }
10
+
11
+ onAdd(builder, args) {
12
+ this.ids = args[0];
13
+ return super.onAdd(builder, args);
14
+ }
15
+
16
+ onBuild(builder) {
17
+ builder.whereInComposite(builder.fullIdColumn(), this.ids);
18
+ }
19
+
20
+ clone() {
21
+ const clone = super.clone();
22
+ clone.ids = this.ids;
23
+ return clone;
24
+ }
25
+ }
26
+
27
+ module.exports = {
28
+ FindByIdsOperation,
29
+ };
@@ -0,0 +1,164 @@
1
+ 'use strict';
2
+
3
+ const { QueryBuilderOperation } = require('./QueryBuilderOperation');
4
+ const { StaticHookArguments } = require('../StaticHookArguments');
5
+ const { isPromise, after, afterReturn } = require('../../utils/promiseUtils');
6
+ const { isObject } = require('../../utils/objectUtils');
7
+
8
+ class FindOperation extends QueryBuilderOperation {
9
+ onBefore2(builder, result) {
10
+ return afterReturn(callStaticBeforeFind(builder), result);
11
+ }
12
+
13
+ onAfter3(builder, results) {
14
+ const opt = builder.findOptions();
15
+
16
+ if (opt.dontCallFindHooks) {
17
+ return results;
18
+ } else {
19
+ return callAfterFind(builder, results);
20
+ }
21
+ }
22
+ }
23
+
24
+ function callStaticBeforeFind(builder) {
25
+ const args = StaticHookArguments.create({ builder });
26
+ return builder.modelClass().beforeFind(args);
27
+ }
28
+
29
+ function callAfterFind(builder, result) {
30
+ const opt = builder.findOptions();
31
+ const maybePromise = callInstanceAfterFind(builder.context(), result, opt.callAfterFindDeeply);
32
+
33
+ return after(maybePromise, () => callStaticAfterFind(builder, result));
34
+ }
35
+
36
+ function callStaticAfterFind(builder, result) {
37
+ const args = StaticHookArguments.create({ builder, result });
38
+ const maybePromise = builder.modelClass().afterFind(args);
39
+
40
+ return after(maybePromise, (maybeResult) => {
41
+ if (maybeResult === undefined) {
42
+ return result;
43
+ } else {
44
+ return maybeResult;
45
+ }
46
+ });
47
+ }
48
+
49
+ function callInstanceAfterFind(ctx, results, deep) {
50
+ if (Array.isArray(results)) {
51
+ if (results.length === 1) {
52
+ return callAfterFindForOne(ctx, results[0], results, deep);
53
+ } else {
54
+ return callAfterFindArray(ctx, results, deep);
55
+ }
56
+ } else {
57
+ return callAfterFindForOne(ctx, results, results, deep);
58
+ }
59
+ }
60
+
61
+ function callAfterFindArray(ctx, results, deep) {
62
+ if (results.length === 0 || !isObject(results[0])) {
63
+ return results;
64
+ }
65
+
66
+ const mapped = new Array(results.length);
67
+ let containsPromise = false;
68
+
69
+ for (let i = 0, l = results.length; i < l; ++i) {
70
+ mapped[i] = callAfterFindForOne(ctx, results[i], results[i], deep);
71
+
72
+ if (isPromise(mapped[i])) {
73
+ containsPromise = true;
74
+ }
75
+ }
76
+
77
+ if (containsPromise) {
78
+ return Promise.all(mapped);
79
+ } else {
80
+ return mapped;
81
+ }
82
+ }
83
+
84
+ function callAfterFindForOne(ctx, model, result, deep) {
85
+ if (!isObject(model) || !model.$isObjectionModel) {
86
+ return result;
87
+ }
88
+
89
+ if (deep) {
90
+ const results = [];
91
+ const containsPromise = callAfterFindForRelations(ctx, model, results);
92
+
93
+ if (containsPromise) {
94
+ return Promise.all(results).then(() => {
95
+ return doCallAfterFind(ctx, model, result);
96
+ });
97
+ } else {
98
+ return doCallAfterFind(ctx, model, result);
99
+ }
100
+ } else {
101
+ return doCallAfterFind(ctx, model, result);
102
+ }
103
+ }
104
+
105
+ function callAfterFindForRelations(ctx, model, results) {
106
+ const keys = Object.keys(model);
107
+ let containsPromise = false;
108
+
109
+ for (let i = 0, l = keys.length; i < l; ++i) {
110
+ const key = keys[i];
111
+ const value = model[key];
112
+
113
+ if (isRelation(value)) {
114
+ const maybePromise = callInstanceAfterFind(ctx, value, true);
115
+
116
+ if (isPromise(maybePromise)) {
117
+ containsPromise = true;
118
+ }
119
+
120
+ results.push(maybePromise);
121
+ }
122
+ }
123
+
124
+ return containsPromise;
125
+ }
126
+
127
+ function isRelation(value) {
128
+ return (
129
+ (isObject(value) && value.$isObjectionModel) ||
130
+ (isNonEmptyObjectArray(value) && value[0].$isObjectionModel)
131
+ );
132
+ }
133
+
134
+ function isNonEmptyObjectArray(value) {
135
+ return Array.isArray(value) && value.length > 0 && isObject(value[0]);
136
+ }
137
+
138
+ function doCallAfterFind(ctx, model, result) {
139
+ const afterFind = getAfterFindHook(model);
140
+
141
+ if (afterFind !== null) {
142
+ const maybePromise = afterFind.call(model, ctx);
143
+
144
+ if (isPromise(maybePromise)) {
145
+ return maybePromise.then(() => result);
146
+ } else {
147
+ return result;
148
+ }
149
+ } else {
150
+ return result;
151
+ }
152
+ }
153
+
154
+ function getAfterFindHook(model) {
155
+ if (model.$afterFind !== model.$objectionModelClass.prototype.$afterFind) {
156
+ return model.$afterFind;
157
+ } else {
158
+ return null;
159
+ }
160
+ }
161
+
162
+ module.exports = {
163
+ FindOperation,
164
+ };