@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,61 @@
1
+ 'use strict';
2
+
3
+ const { UnrelateOperation } = require('../../queryBuilder/operations/UnrelateOperation');
4
+
5
+ class BelongsToOneUnrelateOperation extends UnrelateOperation {
6
+ onAdd() {
7
+ const ids = new Array(this.relation.ownerProp.size);
8
+
9
+ this.relation.ownerProp.forEach((i) => {
10
+ ids[i] = null;
11
+ });
12
+
13
+ this.ids = [ids];
14
+ return true;
15
+ }
16
+
17
+ queryExecutor(builder) {
18
+ const patch = {};
19
+ const ownerProp = this.relation.ownerProp;
20
+
21
+ ownerProp.forEach((i) => {
22
+ const relatedValue = this.ids[0][i];
23
+
24
+ if (this.owner.isModels) {
25
+ for (const owner of this.owner.modelArray) {
26
+ ownerProp.setProp(owner, i, relatedValue);
27
+ }
28
+ }
29
+
30
+ ownerProp.patch(patch, i, relatedValue);
31
+ });
32
+
33
+ const ownerIdProp = this.relation.ownerModelClass.getIdRelationProperty();
34
+ const ownerRefs = ownerIdProp.refs(builder);
35
+ const ownerIds = this.owner.getProps(this.relation, ownerIdProp);
36
+
37
+ const query = this.relation.ownerModelClass
38
+ .query()
39
+ .childQueryOf(builder)
40
+ .patch(patch)
41
+ .whereInComposite(ownerRefs, ownerIds);
42
+
43
+ // We are creating a query to the related items. So any `where` statements
44
+ // must filter the *related* items, not the root query above, which is actually
45
+ // for the owners.
46
+ if (builder.has(builder.constructor.WhereSelector)) {
47
+ query.whereExists(
48
+ this.relation.ownerModelClass
49
+ .relatedQuery(this.relation.name)
50
+ .copyFrom(builder, builder.constructor.JoinSelector)
51
+ .copyFrom(builder, builder.constructor.WhereSelector),
52
+ );
53
+ }
54
+
55
+ return query;
56
+ }
57
+ }
58
+
59
+ module.exports = {
60
+ BelongsToOneUnrelateOperation,
61
+ };
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const { RelationInsertOperation } = require('../RelationInsertOperation');
4
+
5
+ class HasManyInsertOperation extends RelationInsertOperation {
6
+ onAdd(builder, args) {
7
+ const retVal = super.onAdd(builder, args);
8
+ assertOwnerIsSingleItem(this.owner, this.relation);
9
+
10
+ const ownerValues = this.owner.getSplitProps(builder, this.relation);
11
+ const relatedProp = this.relation.relatedProp;
12
+
13
+ for (const model of this.models) {
14
+ for (let j = 0, lp = relatedProp.size; j < lp; ++j) {
15
+ relatedProp.setProp(model, j, ownerValues[0][j]);
16
+ }
17
+ }
18
+
19
+ return retVal;
20
+ }
21
+
22
+ async onAfter1(builder, ret) {
23
+ const inserted = await super.onAfter1(builder, ret);
24
+
25
+ if (!this.assignResultToOwner) {
26
+ return inserted;
27
+ }
28
+
29
+ if (this.owner.isModels) {
30
+ for (const owner of this.owner.modelArray) {
31
+ owner.$appendRelated(this.relation, inserted);
32
+ }
33
+ }
34
+
35
+ return inserted;
36
+ }
37
+ }
38
+
39
+ function assertOwnerIsSingleItem(owner, relation) {
40
+ const { isModels, isIdentifiers, isQueryBuilder } = owner;
41
+ const { ownerProp } = relation;
42
+
43
+ const singleModel = isModels && owner.modelArray.length === 1;
44
+ const singleId = isIdentifiers && owner.getNormalizedIdentifiers(ownerProp).length === 1;
45
+
46
+ if (!singleModel && !singleId && !isQueryBuilder) {
47
+ throw new Error(
48
+ [
49
+ 'Can only insert items for one parent at a time in case of HasManyRelation.',
50
+ 'Otherwise multiple insert queries would need to be created.',
51
+
52
+ 'If you need to insert items for multiple parents, simply loop through them.',
53
+ `That's the most performant way.`,
54
+ ].join(' '),
55
+ );
56
+ }
57
+ }
58
+
59
+ module.exports = {
60
+ HasManyInsertOperation,
61
+ };
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ const { withWhereScope } = require('../../queryBuilder/whereScopes');
4
+ const { normalizeIds } = require('../../utils/normalizeIds');
5
+ const { RelateOperation } = require('../../queryBuilder/operations/RelateOperation');
6
+
7
+ class HasManyRelateOperation extends RelateOperation {
8
+ onAdd(_, args) {
9
+ this.input = args[0];
10
+
11
+ this.ids = normalizeIds(args[0], this.relation.relatedModelClass.getIdRelationProperty(), {
12
+ arrayOutput: true,
13
+ });
14
+
15
+ assertOwnerIsSingleItem(this.owner, this.relation);
16
+ return true;
17
+ }
18
+
19
+ queryExecutor(builder) {
20
+ const patch = {};
21
+ const relatedProp = this.relation.relatedProp;
22
+ const ownerValues = this.owner.getSplitProps(builder, this.relation);
23
+
24
+ relatedProp.forEach((i) => {
25
+ relatedProp.patch(patch, i, ownerValues[0][i]);
26
+ });
27
+
28
+ const query = this.relation.relatedModelClass
29
+ .query()
30
+ .childQueryOf(builder)
31
+ .patch(patch)
32
+ .copyFrom(builder, builder.constructor.JoinSelector)
33
+ .copyFrom(builder, builder.constructor.WhereSelector);
34
+
35
+ withWhereScope(query, () => query.findByIds(this.ids));
36
+ withWhereScope(query, () => query.modify(this.relation.modify));
37
+
38
+ return query;
39
+ }
40
+ }
41
+
42
+ function assertOwnerIsSingleItem(owner, relation) {
43
+ const { isModels, isIdentifiers, isQueryBuilder } = owner;
44
+ const { ownerProp } = relation;
45
+
46
+ const singleModel = isModels && owner.modelArray.length === 1;
47
+ const singleId = isIdentifiers && owner.getNormalizedIdentifiers(ownerProp).length === 1;
48
+
49
+ if (!singleModel && !singleId && !isQueryBuilder) {
50
+ throw new Error(
51
+ [
52
+ 'Can only relate items for one parent at a time in case of HasManyRelation.',
53
+ 'Otherwise multiple update queries would need to be created.',
54
+
55
+ 'If you need to relate items for multiple parents, simply loop through them.',
56
+ `That's the most performant way.`,
57
+ ].join(' '),
58
+ );
59
+ }
60
+ }
61
+
62
+ module.exports = {
63
+ HasManyRelateOperation,
64
+ };
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const { Relation } = require('../Relation');
4
+ const { HasManyInsertOperation } = require('./HasManyInsertOperation');
5
+ const { HasManyRelateOperation } = require('./HasManyRelateOperation');
6
+ const { HasManyUnrelateOperation } = require('./HasManyUnrelateOperation');
7
+
8
+ class HasManyRelation extends Relation {
9
+ insert(_, owner) {
10
+ return new HasManyInsertOperation('insert', {
11
+ relation: this,
12
+ owner: owner,
13
+ });
14
+ }
15
+
16
+ relate(_, owner) {
17
+ return new HasManyRelateOperation('relate', {
18
+ relation: this,
19
+ owner: owner,
20
+ });
21
+ }
22
+
23
+ unrelate(_, owner) {
24
+ return new HasManyUnrelateOperation('unrelate', {
25
+ relation: this,
26
+ owner: owner,
27
+ });
28
+ }
29
+
30
+ hasRelateProp(model) {
31
+ return model.$hasId();
32
+ }
33
+
34
+ setRelateProp(model, values) {
35
+ model.$id(values);
36
+ }
37
+ }
38
+
39
+ Object.defineProperties(HasManyRelation.prototype, {
40
+ isObjectionHasManyRelation: {
41
+ enumerable: false,
42
+ writable: false,
43
+ value: true,
44
+ },
45
+ });
46
+
47
+ module.exports = {
48
+ HasManyRelation,
49
+ };
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ const { withWhereScope } = require('../../queryBuilder/whereScopes');
4
+ const { UnrelateOperation } = require('../../queryBuilder/operations/UnrelateOperation');
5
+
6
+ class HasManyUnrelateOperation extends UnrelateOperation {
7
+ queryExecutor(builder) {
8
+ const patch = {};
9
+ const relatedProp = this.relation.relatedProp;
10
+ const ownerValues = this.owner.getProps(this.relation);
11
+ const relatedRefs = relatedProp.refs(builder);
12
+
13
+ relatedProp.forEach((i) => {
14
+ relatedProp.patch(patch, i, null);
15
+ });
16
+
17
+ const query = this.relation.relatedModelClass
18
+ .query()
19
+ .childQueryOf(builder)
20
+ .patch(patch)
21
+ .copyFrom(builder, builder.constructor.JoinSelector)
22
+ .copyFrom(builder, builder.constructor.WhereSelector);
23
+
24
+ withWhereScope(query, () => query.whereInComposite(relatedRefs, ownerValues));
25
+ withWhereScope(query, () => query.modify(this.relation.modify));
26
+
27
+ return query;
28
+ }
29
+ }
30
+
31
+ module.exports = {
32
+ HasManyUnrelateOperation,
33
+ };
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const { HasManyRelation } = require('../hasMany/HasManyRelation');
4
+
5
+ class HasOneRelation extends HasManyRelation {
6
+ isOneToOne() {
7
+ return true;
8
+ }
9
+ }
10
+
11
+ module.exports = {
12
+ HasOneRelation,
13
+ };
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const { ManyToManyRelation } = require('../manyToMany/ManyToManyRelation');
4
+
5
+ class HasOneThroughRelation extends ManyToManyRelation {
6
+ isOneToOne() {
7
+ return true;
8
+ }
9
+ }
10
+
11
+ module.exports = {
12
+ HasOneThroughRelation,
13
+ };
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ const { withWhereScope } = require('../../queryBuilder/whereScopes');
4
+ const { ManyToManyFindOperation } = require('./find/ManyToManyFindOperation');
5
+
6
+ // This mixin contains the shared code for all modify operations (update, delete, relate, unrelate)
7
+ // for ManyToManyRelation operations.
8
+ //
9
+ // The most important thing this mixin does is that it moves the filters from the main query
10
+ // into a subquery and then adds a single where clause that uses the subquery. This is done so
11
+ // that we are able to `innerJoin` the join table to the query. Most SQL engines don't allow
12
+ // joins in updates or deletes. Join table is joined so that queries can reference the join
13
+ // table columns.
14
+ const ManyToManyModifyMixin = (Operation) => {
15
+ return class extends Operation {
16
+ constructor(...args) {
17
+ super(...args);
18
+ this.modifyFilterSubquery = null;
19
+ }
20
+
21
+ get modifyMainQuery() {
22
+ return true;
23
+ }
24
+
25
+ // At this point `builder` should only have the user's own wheres and joins. There can
26
+ // be other operations (like orderBy) too, but those are meaningless with modify operations.
27
+ onBuild(builder) {
28
+ this.modifyFilterSubquery = this.createModifyFilterSubquery(builder);
29
+
30
+ if (this.modifyMainQuery) {
31
+ // We can now remove the where and join statements from the main query.
32
+ this.removeFiltersFromMainQuery(builder);
33
+
34
+ // Add a single where clause that uses the created subquery.
35
+ withWhereScope(builder, () => this.applyModifyFilterForRelatedTable(builder));
36
+ }
37
+
38
+ return super.onBuild(builder);
39
+ }
40
+
41
+ createModifyFilterSubquery(builder) {
42
+ const relatedModelClass = this.relation.relatedModelClass;
43
+ const builderClass = builder.constructor;
44
+
45
+ // Create an empty subquery.
46
+ const modifyFilterSubquery = relatedModelClass.query().childQueryOf(builder);
47
+
48
+ // Add the necessary joins and wheres so that only rows related to
49
+ // `this.owner` are selected.
50
+ this.relation.findQuery(modifyFilterSubquery, this.owner);
51
+
52
+ // Copy all where and join statements from the main query to the subquery.
53
+ modifyFilterSubquery
54
+ .copyFrom(builder, builderClass.WhereSelector)
55
+ .copyFrom(builder, builderClass.JoinSelector);
56
+
57
+ return modifyFilterSubquery.clearSelect();
58
+ }
59
+
60
+ removeFiltersFromMainQuery(builder) {
61
+ const builderClass = builder.constructor;
62
+
63
+ builder.clear(builderClass.WhereSelector);
64
+ builder.clear(builderClass.JoinSelector);
65
+ }
66
+
67
+ applyModifyFilterForRelatedTable(builder) {
68
+ const idRefs = this.relation.relatedModelClass.getIdRelationProperty().refs(builder);
69
+ const subquery = this.modifyFilterSubquery.clone().select(idRefs);
70
+
71
+ return builder.whereInComposite(idRefs, subquery);
72
+ }
73
+
74
+ applyModifyFilterForJoinTable(builder) {
75
+ const joinTableOwnerRefs = this.relation.joinTableOwnerProp.refs(builder);
76
+ const joinTableRelatedRefs = this.relation.joinTableRelatedProp.refs(builder);
77
+
78
+ const relatedRefs = this.relation.relatedProp.refs(builder);
79
+ const ownerValues = this.owner.getProps(this.relation);
80
+
81
+ const subquery = this.modifyFilterSubquery.clone().select(relatedRefs);
82
+
83
+ return builder
84
+ .whereInComposite(joinTableRelatedRefs, subquery)
85
+ .whereInComposite(joinTableOwnerRefs, ownerValues);
86
+ }
87
+
88
+ toFindOperation() {
89
+ return new ManyToManyFindOperation('find', {
90
+ relation: this.relation,
91
+ owner: this.owner,
92
+ });
93
+ }
94
+
95
+ clone() {
96
+ const clone = super.clone();
97
+ clone.modifyFilterSubquery = this.modifyFilterSubquery;
98
+ return clone;
99
+ }
100
+ };
101
+ };
102
+
103
+ module.exports = {
104
+ ManyToManyModifyMixin,
105
+ };