@rvoh/dream 0.44.7 → 0.44.8

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 (191) hide show
  1. package/dist/cjs/src/bin/index.js +7 -87
  2. package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +1 -1
  3. package/dist/cjs/src/dream/LoadBuilder.js +1 -1
  4. package/dist/cjs/src/dream/Query.js +46 -1417
  5. package/dist/cjs/src/dream/QueryDriver/Base.js +311 -0
  6. package/dist/cjs/src/dream/QueryDriver/Kysely.js +1771 -0
  7. package/dist/cjs/src/dream/QueryDriver/Postgres.js +6 -0
  8. package/dist/cjs/src/dream/internal/saveDream.js +4 -17
  9. package/dist/esm/src/bin/index.js +7 -87
  10. package/dist/esm/src/dream/LeftJoinLoadBuilder.js +1 -1
  11. package/dist/esm/src/dream/LoadBuilder.js +1 -1
  12. package/dist/esm/src/dream/Query.js +46 -1417
  13. package/dist/esm/src/dream/QueryDriver/Base.js +308 -0
  14. package/dist/esm/src/dream/QueryDriver/Kysely.js +1768 -0
  15. package/dist/esm/src/dream/QueryDriver/Postgres.js +3 -0
  16. package/dist/esm/src/dream/internal/saveDream.js +4 -17
  17. package/dist/types/src/bin/index.d.ts +0 -2
  18. package/dist/types/src/dream/Query.d.ts +27 -155
  19. package/dist/types/src/dream/QueryDriver/Base.d.ts +242 -0
  20. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +354 -0
  21. package/dist/types/src/dream/QueryDriver/Postgres.d.ts +4 -0
  22. package/dist/types/src/dream/internal/executeDatabaseQuery.d.ts +2 -1
  23. package/docs/assets/search.js +1 -1
  24. package/docs/classes/Benchmark.html +2 -2
  25. package/docs/classes/CalendarDate.html +2 -2
  26. package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +3 -3
  27. package/docs/classes/Decorators.html +19 -19
  28. package/docs/classes/Dream.html +131 -131
  29. package/docs/classes/DreamApp.html +4 -4
  30. package/docs/classes/DreamBin.html +3 -4
  31. package/docs/classes/DreamCLI.html +4 -4
  32. package/docs/classes/DreamImporter.html +2 -2
  33. package/docs/classes/DreamLogos.html +2 -2
  34. package/docs/classes/DreamMigrationHelpers.html +7 -7
  35. package/docs/classes/DreamSerializerBuilder.html +2 -2
  36. package/docs/classes/DreamTransaction.html +2 -2
  37. package/docs/classes/Encrypt.html +2 -2
  38. package/docs/classes/Env.html +2 -2
  39. package/docs/classes/GlobalNameNotSet.html +3 -3
  40. package/docs/classes/NonLoadedAssociation.html +3 -3
  41. package/docs/classes/ObjectSerializerBuilder.html +2 -2
  42. package/docs/classes/Query.html +86 -57
  43. package/docs/classes/Range.html +2 -2
  44. package/docs/classes/RecordNotFound.html +3 -3
  45. package/docs/classes/ValidationError.html +3 -3
  46. package/docs/functions/DreamSerializer.html +1 -1
  47. package/docs/functions/ObjectSerializer.html +1 -1
  48. package/docs/functions/ReplicaSafe.html +1 -1
  49. package/docs/functions/STI.html +1 -1
  50. package/docs/functions/SoftDelete.html +1 -1
  51. package/docs/functions/camelize.html +1 -1
  52. package/docs/functions/capitalize.html +1 -1
  53. package/docs/functions/cloneDeepSafe.html +1 -1
  54. package/docs/functions/closeAllDbConnections.html +1 -1
  55. package/docs/functions/compact.html +1 -1
  56. package/docs/functions/dreamDbConnections.html +1 -1
  57. package/docs/functions/dreamPath.html +1 -1
  58. package/docs/functions/expandStiClasses.html +1 -1
  59. package/docs/functions/generateDream.html +1 -1
  60. package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
  61. package/docs/functions/groupBy.html +1 -1
  62. package/docs/functions/hyphenize.html +1 -1
  63. package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
  64. package/docs/functions/inferSerializersFromDreamClassOrViewModelClass.html +1 -1
  65. package/docs/functions/intersection.html +1 -1
  66. package/docs/functions/isDreamSerializer.html +1 -1
  67. package/docs/functions/isEmpty.html +1 -1
  68. package/docs/functions/loadRepl.html +1 -1
  69. package/docs/functions/lookupClassByGlobalName.html +1 -1
  70. package/docs/functions/normalizeUnicode.html +1 -1
  71. package/docs/functions/pascalize.html +1 -1
  72. package/docs/functions/pgErrorType.html +1 -1
  73. package/docs/functions/range-1.html +1 -1
  74. package/docs/functions/relativeDreamPath.html +1 -1
  75. package/docs/functions/round.html +1 -1
  76. package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
  77. package/docs/functions/sharedPathPrefix.html +1 -1
  78. package/docs/functions/snakeify.html +1 -1
  79. package/docs/functions/sort.html +1 -1
  80. package/docs/functions/sortBy.html +1 -1
  81. package/docs/functions/sortObjectByKey.html +1 -1
  82. package/docs/functions/sortObjectByValue.html +1 -1
  83. package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
  84. package/docs/functions/uncapitalize.html +1 -1
  85. package/docs/functions/uniq.html +1 -1
  86. package/docs/functions/untypedDb.html +1 -1
  87. package/docs/functions/validateColumn.html +1 -1
  88. package/docs/functions/validateTable.html +1 -1
  89. package/docs/interfaces/BelongsToStatement.html +2 -2
  90. package/docs/interfaces/DecoratorContext.html +2 -2
  91. package/docs/interfaces/DreamAppInitOptions.html +2 -2
  92. package/docs/interfaces/DreamAppOpts.html +2 -2
  93. package/docs/interfaces/EncryptOptions.html +2 -2
  94. package/docs/interfaces/InternalAnyTypedSerializerRendersMany.html +2 -2
  95. package/docs/interfaces/InternalAnyTypedSerializerRendersOne.html +2 -2
  96. package/docs/interfaces/OpenapiDescription.html +2 -2
  97. package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
  98. package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
  99. package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
  100. package/docs/interfaces/SerializerRendererOpts.html +2 -2
  101. package/docs/types/Camelized.html +1 -1
  102. package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
  103. package/docs/types/DateTime.html +1 -1
  104. package/docs/types/DbConnectionType.html +1 -1
  105. package/docs/types/DbTypes.html +1 -1
  106. package/docs/types/DreamAssociationMetadata.html +1 -1
  107. package/docs/types/DreamAttributes.html +1 -1
  108. package/docs/types/DreamClassColumn.html +1 -1
  109. package/docs/types/DreamColumn.html +1 -1
  110. package/docs/types/DreamColumnNames.html +1 -1
  111. package/docs/types/DreamLogLevel.html +1 -1
  112. package/docs/types/DreamLogger.html +1 -1
  113. package/docs/types/DreamModelSerializerType.html +1 -1
  114. package/docs/types/DreamOrViewModelClassSerializerKey.html +1 -1
  115. package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
  116. package/docs/types/DreamParamSafeAttributes.html +1 -1
  117. package/docs/types/DreamParamSafeColumnNames.html +1 -1
  118. package/docs/types/DreamSerializable.html +1 -1
  119. package/docs/types/DreamSerializableArray.html +1 -1
  120. package/docs/types/DreamSerializerKey.html +1 -1
  121. package/docs/types/DreamSerializers.html +1 -1
  122. package/docs/types/DreamTableSchema.html +1 -1
  123. package/docs/types/DreamVirtualColumns.html +1 -1
  124. package/docs/types/EncryptAlgorithm.html +1 -1
  125. package/docs/types/HasManyStatement.html +1 -1
  126. package/docs/types/HasOneStatement.html +1 -1
  127. package/docs/types/Hyphenized.html +1 -1
  128. package/docs/types/IdType.html +1 -1
  129. package/docs/types/OpenapiAllTypes.html +1 -1
  130. package/docs/types/OpenapiFormats.html +1 -1
  131. package/docs/types/OpenapiNumberFormats.html +1 -1
  132. package/docs/types/OpenapiPrimitiveBaseTypes.html +1 -1
  133. package/docs/types/OpenapiPrimitiveTypes.html +1 -1
  134. package/docs/types/OpenapiSchemaArray.html +1 -1
  135. package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
  136. package/docs/types/OpenapiSchemaBase.html +1 -1
  137. package/docs/types/OpenapiSchemaBody.html +1 -1
  138. package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
  139. package/docs/types/OpenapiSchemaCommonFields.html +1 -1
  140. package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
  141. package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
  142. package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
  143. package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
  144. package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  145. package/docs/types/OpenapiSchemaInteger.html +1 -1
  146. package/docs/types/OpenapiSchemaNull.html +1 -1
  147. package/docs/types/OpenapiSchemaNumber.html +1 -1
  148. package/docs/types/OpenapiSchemaObject.html +1 -1
  149. package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
  150. package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
  151. package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
  152. package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  153. package/docs/types/OpenapiSchemaObjectBase.html +1 -1
  154. package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
  155. package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
  156. package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
  157. package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
  158. package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
  159. package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  160. package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  161. package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  162. package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  163. package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  164. package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  165. package/docs/types/OpenapiSchemaString.html +1 -1
  166. package/docs/types/OpenapiShorthandAllTypes.html +1 -1
  167. package/docs/types/OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  168. package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
  169. package/docs/types/OpenapiTypeField.html +1 -1
  170. package/docs/types/Pascalized.html +1 -1
  171. package/docs/types/PrimaryKeyType.html +1 -1
  172. package/docs/types/RoundingPrecision.html +1 -1
  173. package/docs/types/SerializerCasing.html +1 -1
  174. package/docs/types/SimpleObjectSerializerType.html +1 -1
  175. package/docs/types/Snakeified.html +1 -1
  176. package/docs/types/Timestamp.html +1 -1
  177. package/docs/types/UpdateableAssociationProperties.html +1 -1
  178. package/docs/types/UpdateableProperties.html +1 -1
  179. package/docs/types/ValidationType.html +1 -1
  180. package/docs/types/ViewModel.html +1 -1
  181. package/docs/types/ViewModelClass.html +1 -1
  182. package/docs/types/WhereStatementForDream.html +1 -1
  183. package/docs/types/WhereStatementForDreamClass.html +1 -1
  184. package/docs/variables/DateTime-1.html +1 -1
  185. package/docs/variables/DreamConst.html +1 -1
  186. package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
  187. package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
  188. package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
  189. package/docs/variables/ops.html +1 -1
  190. package/docs/variables/primaryKeyTypes.html +1 -1
  191. package/package.json +2 -2
@@ -1,23 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const kysely_1 = require("kysely");
4
- const pluralize_esm_1 = require("pluralize-esm");
5
- const ConnectedToDB_js_1 = require("../db/ConnectedToDB.js");
6
3
  const SoftDelete_js_1 = require("../decorators/class/SoftDelete.js");
7
- const associationToGetterSetterProp_js_1 = require("../decorators/field/association/associationToGetterSetterProp.js");
8
4
  const index_js_1 = require("../dream-app/index.js");
9
5
  const AssociationDeclaredWithoutAssociatedDreamClass_js_1 = require("../errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.js");
10
- const CannotAssociateThroughPolymorphic_js_1 = require("../errors/associations/CannotAssociateThroughPolymorphic.js");
11
- const CannotJoinPolymorphicBelongsToError_js_1 = require("../errors/associations/CannotJoinPolymorphicBelongsToError.js");
12
- const JoinAttemptedOnMissingAssociation_js_1 = require("../errors/associations/JoinAttemptedOnMissingAssociation.js");
13
- const MissingRequiredAssociationAndClause_js_1 = require("../errors/associations/MissingRequiredAssociationAndClause.js");
14
- const MissingRequiredPassthroughForAssociationAndClause_js_1 = require("../errors/associations/MissingRequiredPassthroughForAssociationAndClause.js");
15
- const MissingThroughAssociation_js_1 = require("../errors/associations/MissingThroughAssociation.js");
16
- const MissingThroughAssociationSource_js_1 = require("../errors/associations/MissingThroughAssociationSource.js");
17
6
  const CannotCallUndestroyOnANonSoftDeleteModel_js_1 = require("../errors/CannotCallUndestroyOnANonSoftDeleteModel.js");
18
- const CannotNegateSimilarityClause_js_1 = require("../errors/CannotNegateSimilarityClause.js");
19
7
  const CannotPassAdditionalFieldsToPluckEachAfterCallback_js_1 = require("../errors/CannotPassAdditionalFieldsToPluckEachAfterCallback.js");
20
- const CannotPassUndefinedAsAValueToAWhereClause_js_1 = require("../errors/CannotPassUndefinedAsAValueToAWhereClause.js");
21
8
  const LeftJoinPreloadIncompatibleWithFindEach_js_1 = require("../errors/LeftJoinPreloadIncompatibleWithFindEach.js");
22
9
  const MissingRequiredCallbackFunctionToPluckEach_js_1 = require("../errors/MissingRequiredCallbackFunctionToPluckEach.js");
23
10
  const NoUpdateAllOnJoins_js_1 = require("../errors/NoUpdateAllOnJoins.js");
@@ -25,33 +12,14 @@ const NoUpdateOnAssociationQuery_js_1 = require("../errors/NoUpdateOnAssociation
25
12
  const CannotPaginateWithLimit_js_1 = require("../errors/pagination/CannotPaginateWithLimit.js");
26
13
  const CannotPaginateWithOffset_js_1 = require("../errors/pagination/CannotPaginateWithOffset.js");
27
14
  const RecordNotFound_js_1 = require("../errors/RecordNotFound.js");
28
- const UnexpectedUndefined_js_1 = require("../errors/UnexpectedUndefined.js");
29
- const CalendarDate_js_1 = require("../helpers/CalendarDate.js");
30
- const camelize_js_1 = require("../helpers/camelize.js");
31
15
  const cloneDeepSafe_js_1 = require("../helpers/cloneDeepSafe.js");
32
- const compact_js_1 = require("../helpers/compact.js");
33
- const DateTime_js_1 = require("../helpers/DateTime.js");
34
- const isEmpty_js_1 = require("../helpers/isEmpty.js");
35
16
  const isObject_js_1 = require("../helpers/isObject.js");
36
17
  const namespaceColumn_js_1 = require("../helpers/namespaceColumn.js");
37
- const normalizeUnicode_js_1 = require("../helpers/normalizeUnicode.js");
38
- const objectPathsToArrays_js_1 = require("../helpers/objectPathsToArrays.js");
39
18
  const protectAgainstPollutingAssignment_js_1 = require("../helpers/protectAgainstPollutingAssignment.js");
40
- const range_js_1 = require("../helpers/range.js");
41
- const snakeify_js_1 = require("../helpers/snakeify.js");
42
- const uniq_js_1 = require("../helpers/uniq.js");
43
- const curried_ops_statement_js_1 = require("../ops/curried-ops-statement.js");
44
19
  const index_js_2 = require("../ops/index.js");
45
- const ops_statement_js_1 = require("../ops/ops-statement.js");
46
- const constants_js_1 = require("./constants.js");
47
20
  const computedPaginatePage_js_1 = require("./internal/computedPaginatePage.js");
48
- const executeDatabaseQuery_js_1 = require("./internal/executeDatabaseQuery.js");
49
- const extractAssociationMetadataFromAssociationName_js_1 = require("./internal/extractAssociationMetadataFromAssociationName.js");
50
- const orderByDirection_js_1 = require("./internal/orderByDirection.js");
51
- const shouldBypassDefaultScope_js_1 = require("./internal/shouldBypassDefaultScope.js");
52
- const SimilarityBuilder_js_1 = require("./internal/similarity/SimilarityBuilder.js");
53
- const sqlResultToDreamInstance_js_1 = require("./internal/sqlResultToDreamInstance.js");
54
- class Query extends ConnectedToDB_js_1.default {
21
+ const Postgres_js_1 = require("./QueryDriver/Postgres.js");
22
+ class Query {
55
23
  /**
56
24
  * @internal
57
25
  *
@@ -230,8 +198,26 @@ class Query extends ConnectedToDB_js_1.default {
230
198
  * baseSelectQuery.
231
199
  */
232
200
  baseSelectQuery;
201
+ /*
202
+ * Store the original opts, so we can hand them off succinctly to the
203
+ * query executor. TODO: Should we do this?
204
+ * */
205
+ originalOpts;
206
+ dreamClass;
207
+ dreamInstance;
208
+ connectionOverride;
209
+ /**
210
+ * @internal
211
+ *
212
+ * stores the Dream models joined in this Query instance
213
+ */
214
+ innerJoinDreamClasses = Object.freeze([]);
233
215
  constructor(dreamInstance, opts = {}) {
234
- super(dreamInstance, opts);
216
+ this.dreamInstance = dreamInstance;
217
+ this.dreamClass = dreamInstance.constructor;
218
+ this.dreamTransaction = opts.transaction || null;
219
+ this.connectionOverride = opts.connection;
220
+ this.innerJoinDreamClasses = Object.freeze(opts.innerJoinDreamClasses || []);
235
221
  this.passthroughOnStatement = Object.freeze(opts.passthroughOnStatement || {});
236
222
  this.whereStatements = Object.freeze(opts.where || []);
237
223
  this.whereNotStatements = Object.freeze(opts.whereNot || []);
@@ -256,6 +242,7 @@ class Query extends ConnectedToDB_js_1.default {
256
242
  this.distinctColumn = opts.distinctColumn || null;
257
243
  this.connectionOverride = opts.connection;
258
244
  this.shouldReallyDestroy = opts.shouldReallyDestroy || false;
245
+ this.originalOpts = Object.freeze(opts);
259
246
  }
260
247
  /**
261
248
  * Returns true. Useful for distinguishing Query instances
@@ -266,23 +253,6 @@ class Query extends ConnectedToDB_js_1.default {
266
253
  get isDreamQuery() {
267
254
  return true;
268
255
  }
269
- /**
270
- * @internal
271
- *
272
- * Used for applying preload and load statements
273
- *
274
- * @returns An associated Query
275
- */
276
- dreamClassQueryWithScopeBypasses(dreamClass, { bypassAllDefaultScopesExceptOnAssociations = false, defaultScopesToBypassExceptOnAssociations = [], } = {}) {
277
- const associationQuery = dreamClass.query().clone({
278
- passthroughOnStatement: this.passthroughOnStatement,
279
- bypassAllDefaultScopes: this.bypassAllDefaultScopes,
280
- bypassAllDefaultScopesExceptOnAssociations,
281
- defaultScopesToBypass: this.defaultScopesToBypass,
282
- defaultScopesToBypassExceptOnAssociations,
283
- });
284
- return (this.dreamTransaction ? associationQuery.txn(this.dreamTransaction) : associationQuery);
285
- }
286
256
  /**
287
257
  * @internal
288
258
  *
@@ -582,92 +552,6 @@ class Query extends ConnectedToDB_js_1.default {
582
552
  this.fleshOutJoinStatements(innerJoinDreamClasses, joinStatements, joinAndStatements, previousAssociationName, associationStatements, previousDreamClass);
583
553
  }
584
554
  }
585
- /**
586
- * @internal
587
- *
588
- *
589
- */
590
- associationNamesToDreamClassesMap(associationNames, associationsToDreamClassesMap = {}) {
591
- const namesToAssociationsAndDreamClasses = this.associationNamesToAssociationDataAndDreamClassesMap(associationNames);
592
- return Object.keys(namesToAssociationsAndDreamClasses).reduce((remap, associationName) => {
593
- const associationAndDreamClass = namesToAssociationsAndDreamClasses[associationName];
594
- if (associationAndDreamClass === undefined)
595
- throw new UnexpectedUndefined_js_1.default();
596
- remap[associationName] = associationAndDreamClass.dreamClass;
597
- return remap;
598
- }, associationsToDreamClassesMap);
599
- }
600
- /**
601
- * @internal
602
- *
603
- *
604
- */
605
- associationNamesToAssociationsMap(associationNames, associationsToAssociations = {}) {
606
- const namesToAssociationsAndDreamClasses = this.associationNamesToAssociationDataAndDreamClassesMap(associationNames);
607
- return Object.keys(namesToAssociationsAndDreamClasses).reduce((remap, associationName) => {
608
- const associationAndDreamClass = namesToAssociationsAndDreamClasses[associationName];
609
- if (associationAndDreamClass === undefined)
610
- throw new UnexpectedUndefined_js_1.default();
611
- remap[associationName] = associationAndDreamClass.association;
612
- return remap;
613
- }, associationsToAssociations);
614
- }
615
- /**
616
- * @internal
617
- */
618
- associationNamesToAssociationDataAndDreamClassesMap(associationNames) {
619
- const associationsToDreamClassesMap = {};
620
- associationNames.reduce((dreamClass, associationName) => {
621
- const { name, alias } = (0, extractAssociationMetadataFromAssociationName_js_1.default)(associationName);
622
- const association = dreamClass['getAssociationMetadata'](name);
623
- if (association === undefined)
624
- throw new UnexpectedUndefined_js_1.default();
625
- const through = association.through;
626
- if (through) {
627
- const { throughAssociation, throughAssociationDreamClass } = this.throughAssociationDetails(dreamClass, through);
628
- associationsToDreamClassesMap[through] = {
629
- association: throughAssociation,
630
- dreamClass: throughAssociationDreamClass,
631
- };
632
- }
633
- const nextDreamClass = association.modelCB();
634
- if (alias === undefined)
635
- throw new UnexpectedUndefined_js_1.default();
636
- associationsToDreamClassesMap[alias] = { association, dreamClass: nextDreamClass };
637
- return nextDreamClass;
638
- }, this.dreamClass);
639
- return associationsToDreamClassesMap;
640
- }
641
- /**
642
- * @internal
643
- */
644
- throughAssociationDetails(dreamClass, through) {
645
- const throughAssociation = dreamClass['getAssociationMetadata'](through);
646
- if (throughAssociation === undefined)
647
- throw new UnexpectedUndefined_js_1.default();
648
- const throughAssociationDreamClass = throughAssociation.modelCB();
649
- return { throughAssociation, throughAssociationDreamClass };
650
- }
651
- /**
652
- * @internal
653
- *
654
- *
655
- */
656
- joinStatementsToDreamClassesMap(joinStatements) {
657
- const associationsToDreamClassesMap = {};
658
- (0, objectPathsToArrays_js_1.default)(joinStatements).forEach(associationChain => this.associationNamesToDreamClassesMap(associationChain, associationsToDreamClassesMap));
659
- return associationsToDreamClassesMap;
660
- }
661
- /**
662
- * @internal
663
- *
664
- *
665
- */
666
- joinStatementsToAssociationsMap(joinStatements) {
667
- const associationsToAssociationsMap = {};
668
- (0, objectPathsToArrays_js_1.default)(joinStatements).forEach(associationChain => this.associationNamesToAssociationsMap(associationChain, associationsToAssociationsMap));
669
- return associationsToAssociationsMap;
670
- }
671
555
  /**
672
556
  * @internal
673
557
  *
@@ -885,8 +769,7 @@ class Query extends ConnectedToDB_js_1.default {
885
769
  * @returns A Kysely SelectQueryBuilder instance
886
770
  */
887
771
  nestedSelect(selection) {
888
- const query = this.buildSelect({ bypassSelectAll: true, bypassOrder: true });
889
- return query.select(this.namespaceColumn(selection));
772
+ return this.dbDriverInstance().nestedSelect(selection);
890
773
  }
891
774
  /**
892
775
  * Returns a new Query instance, attaching the provided
@@ -979,8 +862,7 @@ class Query extends ConnectedToDB_js_1.default {
979
862
  *
980
863
  */
981
864
  sql() {
982
- const kyselyQuery = this.buildSelect();
983
- return kyselyQuery.compile();
865
+ return this.dbDriverInstance().sql();
984
866
  }
985
867
  /**
986
868
  * Converts the given dream class into a Kysely query, enabling
@@ -994,21 +876,7 @@ class Query extends ConnectedToDB_js_1.default {
994
876
  * @returns A Kysely query. Depending on the type passed, it will return either a SelectQueryBuilder, DeleteQueryBuilder, or an UpdateQueryBuilder
995
877
  */
996
878
  toKysely(type) {
997
- switch (type) {
998
- case 'select':
999
- return this.buildSelect();
1000
- case 'delete':
1001
- return this.buildDelete();
1002
- case 'update':
1003
- return this.buildUpdate({});
1004
- // TODO: in the future, we should support insert type, but don't yet, since inserts are done outside
1005
- // the query class for some reason.
1006
- default: {
1007
- // protection so that if a new QueryType is ever added, this will throw a type error at build time
1008
- const _never = type;
1009
- throw new Error(`Unhandled QueryType: ${_never}`);
1010
- }
1011
- }
879
+ return this.dbDriverInstance().toKysely(type);
1012
880
  }
1013
881
  /**
1014
882
  * Applies transaction to the Query instance
@@ -1036,17 +904,7 @@ class Query extends ConnectedToDB_js_1.default {
1036
904
  * @returns The number of records in the database
1037
905
  */
1038
906
  async count() {
1039
- // eslint-disable-next-line @typescript-eslint/unbound-method
1040
- const { count } = this.dbFor('select').fn;
1041
- const distinctColumn = this.distinctColumn;
1042
- const query = this.clone({ distinctColumn: null });
1043
- let kyselyQuery = query.buildSelect({ bypassSelectAll: true, bypassOrder: true });
1044
- const countClause = distinctColumn
1045
- ? count((0, kysely_1.sql) `DISTINCT ${distinctColumn}`)
1046
- : count(query.namespaceColumn(query.dreamInstance.primaryKey));
1047
- kyselyQuery = kyselyQuery.select(countClause.as('tablecount'));
1048
- const data = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'executeTakeFirstOrThrow');
1049
- return parseInt(data.tablecount.toString());
907
+ return await this.dbDriverInstance().count();
1050
908
  }
1051
909
  /**
1052
910
  * Returns new Query with distinct clause applied
@@ -1094,12 +952,7 @@ class Query extends ConnectedToDB_js_1.default {
1094
952
  *
1095
953
  */
1096
954
  async max(columnName) {
1097
- // eslint-disable-next-line @typescript-eslint/unbound-method
1098
- const { max } = this.dbFor('select').fn;
1099
- let kyselyQuery = this.buildSelect({ bypassSelectAll: true, bypassOrder: true });
1100
- kyselyQuery = kyselyQuery.select(max(columnName));
1101
- const data = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'executeTakeFirstOrThrow');
1102
- return data.max;
955
+ return await this.dbDriverInstance().max(columnName);
1103
956
  }
1104
957
  /**
1105
958
  * Retrieves the min value of the specified column
@@ -1114,218 +967,7 @@ class Query extends ConnectedToDB_js_1.default {
1114
967
  * @returns the min value of the specified column for this Query
1115
968
  */
1116
969
  async min(columnName) {
1117
- // eslint-disable-next-line @typescript-eslint/unbound-method
1118
- const { min } = this.dbFor('select').fn;
1119
- let kyselyQuery = this.buildSelect({ bypassSelectAll: true, bypassOrder: true });
1120
- kyselyQuery = kyselyQuery.select(min(columnName));
1121
- const data = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'executeTakeFirstOrThrow');
1122
- return data.min;
1123
- }
1124
- /**
1125
- * @internal
1126
- *
1127
- * Runs the query and extracts plucked values
1128
- *
1129
- * @returns An array of plucked values
1130
- */
1131
- async executePluck(...fields) {
1132
- let kyselyQuery = this.removeAllDefaultScopesExceptOnAssociations().buildSelect({ bypassSelectAll: true });
1133
- const aliases = [];
1134
- fields.forEach((field) => {
1135
- // field will already be namespaced in a join situation, but when the field to pluck is on the
1136
- // base model, it will be underscored (to match the table name), but when the selected column
1137
- // comes back from Kysely camelCased
1138
- aliases.push(field.includes('_') ? (0, camelize_js_1.default)(field) : field);
1139
- // namespace the selection so that when plucking the same column name from
1140
- // multpile tables, they don't get saved as the same name (e.g. select results with two `id` columns,
1141
- // which the pg package then returns in an object with a single `id` key)
1142
- kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(field)} as ${field}`);
1143
- });
1144
- return (await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'execute')).map(singleResult => aliases.map(alias => singleResult[alias]));
1145
- }
1146
- /**
1147
- * @internal
1148
- *
1149
- */
1150
- async executeJoinLoad(options = {}) {
1151
- const query = this.limit(null).offset(null);
1152
- let kyselyQuery = query.buildSelect({ bypassSelectAll: true });
1153
- const aliasToDreamClassesMap = {
1154
- [this.baseSqlAlias]: this.dreamClass,
1155
- ...this.joinStatementsToDreamClassesMap(this.leftJoinStatements),
1156
- };
1157
- const associationAliasToColumnAliasMap = {};
1158
- const aliasToAssociationsMap = this.joinStatementsToAssociationsMap(this.leftJoinStatements);
1159
- const aliases = Object.keys(aliasToDreamClassesMap);
1160
- let nextColumnAliasCounter = 0;
1161
- aliases.forEach((aliasOrExpression) => {
1162
- const alias = (0, extractAssociationMetadataFromAssociationName_js_1.default)(aliasOrExpression).alias;
1163
- if (alias === undefined)
1164
- throw new UnexpectedUndefined_js_1.default();
1165
- associationAliasToColumnAliasMap[alias] ||= {};
1166
- const aliasedDreamClass = aliasToDreamClassesMap[alias];
1167
- if (aliasedDreamClass === undefined)
1168
- throw new UnexpectedUndefined_js_1.default();
1169
- const association = aliasToAssociationsMap[alias];
1170
- const columns = alias === this.baseSqlAlias
1171
- ? options.columns
1172
- ? this.columnsWithRequiredLoadColumns(options.columns)
1173
- : this.dreamClass.columns()
1174
- : aliasedDreamClass.columns();
1175
- columns.forEach((column) => {
1176
- const columnAlias = `dr${nextColumnAliasCounter++}`;
1177
- kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(column, alias)} as ${columnAlias}`);
1178
- const columnAliasMap = associationAliasToColumnAliasMap[alias];
1179
- if (columnAliasMap === undefined)
1180
- throw new UnexpectedUndefined_js_1.default();
1181
- columnAliasMap[column] = columnAlias;
1182
- });
1183
- if (association?.type === 'HasOne' || association?.type === 'HasMany') {
1184
- const setupPreloadData = (dbColumnName) => {
1185
- const columnAlias = `dr${nextColumnAliasCounter++}`;
1186
- const columnAliasMap = associationAliasToColumnAliasMap[association.through];
1187
- if (columnAliasMap === undefined)
1188
- throw new UnexpectedUndefined_js_1.default();
1189
- columnAliasMap[dbColumnName] = columnAlias;
1190
- kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(dbColumnName, association.through)} as ${columnAlias}`);
1191
- };
1192
- if (association.through && association.preloadThroughColumns) {
1193
- if ((0, isObject_js_1.default)(association.preloadThroughColumns)) {
1194
- const preloadMap = association.preloadThroughColumns;
1195
- Object.keys(preloadMap).forEach(columnName => setupPreloadData(columnName));
1196
- }
1197
- else {
1198
- const preloadArray = association.preloadThroughColumns;
1199
- preloadArray.forEach(columnName => setupPreloadData(columnName));
1200
- }
1201
- }
1202
- }
1203
- });
1204
- const queryResults = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'execute');
1205
- const aliasToDreamIdMap = queryResults.reduce((aliasToDreamIdMap, singleSqlResult) => {
1206
- this.fleshOutJoinLoadExecutionResults({
1207
- currentAlias: this.baseSqlAlias,
1208
- singleSqlResult,
1209
- aliasToDreamIdMap,
1210
- associationAliasToColumnAliasMap,
1211
- aliasToAssociationsMap,
1212
- aliasToDreamClassesMap,
1213
- leftJoinStatements: this.leftJoinStatements,
1214
- });
1215
- return aliasToDreamIdMap;
1216
- }, {});
1217
- const baseModelIdToDreamMap = aliasToDreamIdMap[this.baseSqlAlias] || new Map();
1218
- return (0, compact_js_1.default)(Array.from(baseModelIdToDreamMap.values()));
1219
- }
1220
- fleshOutJoinLoadExecutionResults({ currentAlias, singleSqlResult, aliasToDreamIdMap, associationAliasToColumnAliasMap, aliasToAssociationsMap, aliasToDreamClassesMap, leftJoinStatements, }) {
1221
- const dreamClass = aliasToDreamClassesMap[currentAlias];
1222
- if (dreamClass === undefined)
1223
- throw new UnexpectedUndefined_js_1.default();
1224
- const columnToColumnAliasMap = associationAliasToColumnAliasMap[currentAlias];
1225
- if (columnToColumnAliasMap === undefined)
1226
- throw new UnexpectedUndefined_js_1.default();
1227
- const primaryKeyName = dreamClass.primaryKey;
1228
- if (primaryKeyName === undefined)
1229
- throw new UnexpectedUndefined_js_1.default();
1230
- const columnAlias = columnToColumnAliasMap[primaryKeyName];
1231
- if (columnAlias === undefined)
1232
- throw new UnexpectedUndefined_js_1.default();
1233
- const primaryKeyValue = singleSqlResult[columnAlias];
1234
- if (!primaryKeyValue)
1235
- return null;
1236
- aliasToDreamIdMap[currentAlias] ||= new Map();
1237
- if (!aliasToDreamIdMap[currentAlias].get(primaryKeyValue)) {
1238
- const columnValueMap = Object.keys(columnToColumnAliasMap).reduce((columnNameValueMap, columnName) => {
1239
- const columnAlias = columnToColumnAliasMap[columnName];
1240
- if (columnAlias === undefined)
1241
- throw new UnexpectedUndefined_js_1.default();
1242
- columnNameValueMap[columnName] = singleSqlResult[columnAlias];
1243
- return columnNameValueMap;
1244
- }, {});
1245
- const dream = (0, sqlResultToDreamInstance_js_1.default)(dreamClass, columnValueMap);
1246
- const association = aliasToAssociationsMap[currentAlias];
1247
- if (association && association.through && association.preloadThroughColumns) {
1248
- const throughAssociationColumnToColumnAliasMap = associationAliasToColumnAliasMap[association.through];
1249
- if (throughAssociationColumnToColumnAliasMap === undefined)
1250
- throw new UnexpectedUndefined_js_1.default();
1251
- this.hydratePreloadedThroughColumns({
1252
- association,
1253
- columnToColumnAliasMap: throughAssociationColumnToColumnAliasMap,
1254
- dream,
1255
- singleSqlResult,
1256
- });
1257
- }
1258
- aliasToDreamIdMap[(0, protectAgainstPollutingAssignment_js_1.default)(currentAlias)]?.set(primaryKeyValue, dream);
1259
- }
1260
- const dream = aliasToDreamIdMap[currentAlias].get(primaryKeyValue);
1261
- Object.keys(leftJoinStatements).forEach(nextAlias => {
1262
- const { name: associationName, alias } = (0, extractAssociationMetadataFromAssociationName_js_1.default)(nextAlias);
1263
- const association = dreamClass['getAssociationMetadata'](associationName);
1264
- if (association === undefined)
1265
- throw new UnexpectedUndefined_js_1.default();
1266
- const associatedDream = this.fleshOutJoinLoadExecutionResults({
1267
- currentAlias: alias,
1268
- singleSqlResult,
1269
- aliasToDreamIdMap,
1270
- associationAliasToColumnAliasMap,
1271
- aliasToAssociationsMap,
1272
- aliasToDreamClassesMap,
1273
- leftJoinStatements: leftJoinStatements[nextAlias],
1274
- });
1275
- const hasMany = association.type === 'HasMany';
1276
- // initialize by trying to access the association, which throws an exception if not yet initialized
1277
- try {
1278
- ;
1279
- dream[association.as];
1280
- }
1281
- catch {
1282
- if (hasMany)
1283
- dream[association.as] = [];
1284
- else
1285
- dream[(0, associationToGetterSetterProp_js_1.default)(association)] = null;
1286
- }
1287
- if (!associatedDream)
1288
- return;
1289
- if (hasMany) {
1290
- if (!dream[association.as].includes(associatedDream))
1291
- dream[association.as].push(associatedDream);
1292
- }
1293
- else
1294
- dream[(0, associationToGetterSetterProp_js_1.default)(association)] = associatedDream;
1295
- });
1296
- return dream;
1297
- }
1298
- hydratePreloadedThroughColumns({ association, columnToColumnAliasMap, dream, singleSqlResult, }) {
1299
- if (!association.through)
1300
- return;
1301
- if (!dream.preloadedThroughColumns)
1302
- return;
1303
- let columnNames = [];
1304
- const columnNameToPreloadedThroughColumnNameMap = {};
1305
- if ((0, isObject_js_1.default)(association.preloadThroughColumns)) {
1306
- const preloadMap = association.preloadThroughColumns;
1307
- columnNames = Object.keys(preloadMap).map(columnName => {
1308
- columnNameToPreloadedThroughColumnNameMap[columnName] = preloadMap[columnName];
1309
- return columnName;
1310
- });
1311
- }
1312
- else if (Array.isArray(association.preloadThroughColumns)) {
1313
- columnNames = association.preloadThroughColumns.map(columnName => {
1314
- columnNameToPreloadedThroughColumnNameMap[columnName] = columnName;
1315
- return columnName;
1316
- });
1317
- }
1318
- columnNames.forEach(columnName => {
1319
- const preloadedThroughColumnName = columnNameToPreloadedThroughColumnNameMap[columnName];
1320
- if (preloadedThroughColumnName === undefined)
1321
- throw new UnexpectedUndefined_js_1.default();
1322
- const columnAlias = columnToColumnAliasMap[columnName];
1323
- if (columnAlias === undefined) {
1324
- throw new UnexpectedUndefined_js_1.default();
1325
- }
1326
- ;
1327
- dream.preloadedThroughColumns[preloadedThroughColumnName] = singleSqlResult[columnAlias];
1328
- });
970
+ return await this.dbDriverInstance().min(columnName);
1329
971
  }
1330
972
  /**
1331
973
  * Plucks the provided fields from the given dream class table
@@ -1347,7 +989,7 @@ class Query extends ConnectedToDB_js_1.default {
1347
989
  * @returns An array of pluck results
1348
990
  */
1349
991
  async pluck(...columnNames) {
1350
- const vals = await this.executePluck(...columnNames);
992
+ const vals = await this.dbDriverInstance().pluck(...columnNames);
1351
993
  return (columnNames.length > 1 ? vals : vals.flat());
1352
994
  }
1353
995
  /**
@@ -1384,11 +1026,11 @@ class Query extends ConnectedToDB_js_1.default {
1384
1026
  const columnsIncludingPrimaryKey = onlyIncludesPrimaryKey
1385
1027
  ? onlyColumns
1386
1028
  : [this.namespacedPrimaryKey, ...onlyColumns];
1387
- records = await this.offset(offset)
1029
+ const query = this.offset(offset)
1388
1030
  .order(null)
1389
1031
  .order(this.namespacedPrimaryKey)
1390
- .limit(batchSize)
1391
- .executePluck(...columnsIncludingPrimaryKey);
1032
+ .limit(batchSize);
1033
+ records = await this.dbDriverInstance(query).pluck(...columnsIncludingPrimaryKey);
1392
1034
  // In order to batch, we need to order by primary key, so the primary key must be plucked.
1393
1035
  // If the developer did not include the primary key in the columns to pluck, then we prepended it above
1394
1036
  // and need to remove it from each group of plucked columns prior to passing them into the callback functions
@@ -1413,13 +1055,14 @@ class Query extends ConnectedToDB_js_1.default {
1413
1055
  * @returns an array of dreams
1414
1056
  */
1415
1057
  async all(options = {}) {
1416
- if (this.joinLoadActivated)
1417
- return await this.executeJoinLoad(options);
1418
- const kyselyQuery = this.buildSelect(options);
1419
- const results = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'execute');
1420
- const theAll = results.map(r => (0, sqlResultToDreamInstance_js_1.default)(this.dreamClass, r));
1421
- await this.applyPreload(this.preloadStatements, this.preloadOnStatements, theAll);
1422
- return theAll;
1058
+ return await this.dbDriverInstance().takeAll(options);
1059
+ }
1060
+ static dbDriverClass() {
1061
+ return Postgres_js_1.default;
1062
+ }
1063
+ dbDriverInstance(query = this) {
1064
+ const driverClass = Query.dbDriverClass();
1065
+ return new driverClass(query);
1423
1066
  }
1424
1067
  /**
1425
1068
  * Paginates the results of your query, accepting a pageSize and page argument,
@@ -1524,7 +1167,8 @@ class Query extends ConnectedToDB_js_1.default {
1524
1167
  const query = this.orderStatements.length
1525
1168
  ? this
1526
1169
  : this.order({ [this.namespacedPrimaryKey]: 'asc' });
1527
- return await query.takeOne();
1170
+ const dbDriverClass = Query.dbDriverClass();
1171
+ return await new dbDriverClass(query).takeOne();
1528
1172
  }
1529
1173
  /**
1530
1174
  * Returns the first record in the database
@@ -1563,7 +1207,8 @@ class Query extends ConnectedToDB_js_1.default {
1563
1207
  const query = this.orderStatements.length
1564
1208
  ? this.invertOrder()
1565
1209
  : this.order({ [this.namespacedPrimaryKey]: 'desc' });
1566
- return await query.takeOne();
1210
+ const dbDriverClass = Query.dbDriverClass();
1211
+ return await new dbDriverClass(query).takeOne();
1567
1212
  }
1568
1213
  /**
1569
1214
  * Returns the last record in the database
@@ -1713,8 +1358,7 @@ class Query extends ConnectedToDB_js_1.default {
1713
1358
  * @returns The number of records that were removed
1714
1359
  */
1715
1360
  async delete() {
1716
- const deletionResult = await (0, executeDatabaseQuery_js_1.default)(this.buildDelete(), 'executeTakeFirst');
1717
- return Number(deletionResult?.numDeletedRows || 0);
1361
+ return await this.dbDriverInstance().delete();
1718
1362
  }
1719
1363
  /**
1720
1364
  * Updates all records matching the Query
@@ -1748,1014 +1392,7 @@ class Query extends ConnectedToDB_js_1.default {
1748
1392
  return counter;
1749
1393
  }
1750
1394
  async updateWithoutCallingModelHooks(attributes) {
1751
- const kyselyQuery = this.buildUpdate(attributes);
1752
- const res = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'execute');
1753
- const resultData = Array.from(res.entries())?.[0]?.[1];
1754
- return Number(resultData?.numUpdatedRows || 0);
1755
- }
1756
- /**
1757
- * @internal
1758
- *
1759
- * Used for applying first and last queries
1760
- *
1761
- * @returns A dream instance or null
1762
- */
1763
- async takeOne() {
1764
- if (this.joinLoadActivated) {
1765
- let query;
1766
- if (this.whereStatements.find(whereStatement => whereStatement[this.dreamClass.primaryKey] ||
1767
- whereStatement[this.namespacedPrimaryKey])) {
1768
- // the query already includes a primary key where statement
1769
- query = this;
1770
- }
1771
- else {
1772
- // otherwise find the primary key and apply it to the query
1773
- const primaryKeyValue = (await this.limit(1).pluck(this.namespacedPrimaryKey))[0];
1774
- if (primaryKeyValue === undefined)
1775
- return null;
1776
- query = this.where({ [this.namespacedPrimaryKey]: primaryKeyValue });
1777
- }
1778
- return (await query.executeJoinLoad())[0] || null;
1779
- }
1780
- const kyselyQuery = this.limit(1).buildSelect();
1781
- const results = await (0, executeDatabaseQuery_js_1.default)(kyselyQuery, 'executeTakeFirst');
1782
- if (results) {
1783
- const theFirst = (0, sqlResultToDreamInstance_js_1.default)(this.dreamClass, results);
1784
- if (theFirst)
1785
- await this.applyPreload(this.preloadStatements, this.preloadOnStatements, [theFirst]);
1786
- return theFirst;
1787
- }
1788
- else
1789
- return null;
1790
- }
1791
- /**
1792
- * @internal
1793
- *
1794
- * Used to hydrate dreams with the provided associations
1795
- */
1796
- hydrateAssociation(dreams, association, preloadedDreamsAndWhatTheyPointTo) {
1797
- switch (association.type) {
1798
- case 'HasMany':
1799
- dreams.forEach((dream) => {
1800
- dream[association.as] = [];
1801
- });
1802
- break;
1803
- default:
1804
- dreams.forEach((dream) => {
1805
- dream[(0, associationToGetterSetterProp_js_1.default)(association)] = null;
1806
- });
1807
- }
1808
- // dreams is a Rating
1809
- // Rating belongs to: rateables (Posts / Compositions)
1810
- // loadedAssociations is an array of Posts and Compositions
1811
- // if rating.rateable_id === loadedAssociation.primaryKeyvalue
1812
- // rating.rateable = loadedAssociation
1813
- preloadedDreamsAndWhatTheyPointTo.forEach(preloadedDreamAndWhatItPointsTo => {
1814
- dreams
1815
- .filter(dream => dream.primaryKeyValue === preloadedDreamAndWhatItPointsTo.pointsToPrimaryKey)
1816
- .forEach((dream) => {
1817
- if (association.type === 'HasMany') {
1818
- dream[association.as].push(preloadedDreamAndWhatItPointsTo.dream);
1819
- }
1820
- else {
1821
- // in a HasOne context, order clauses will be applied in advance,
1822
- // prior to hydration. Considering, we only want to set the first
1823
- // result and ignore other results, so we will use ||= to set.
1824
- dream[association.as] ||= preloadedDreamAndWhatItPointsTo.dream;
1825
- }
1826
- });
1827
- });
1828
- if (association.type === 'HasMany') {
1829
- dreams.forEach((dream) => Object.freeze(dream[association.as]));
1830
- }
1831
- }
1832
- /**
1833
- * @internal
1834
- *
1835
- * Used to bridge through associations
1836
- */
1837
- followThroughAssociation(dreamClass, association) {
1838
- const throughAssociation = association.through && dreamClass['getAssociationMetadata'](association.through);
1839
- if (!throughAssociation)
1840
- throw new MissingThroughAssociation_js_1.default({
1841
- dreamClass,
1842
- association,
1843
- });
1844
- const throughClass = throughAssociation.modelCB();
1845
- if (Array.isArray(throughClass))
1846
- throw new CannotAssociateThroughPolymorphic_js_1.default({
1847
- dreamClass,
1848
- association,
1849
- });
1850
- const newAssociation = getSourceAssociation(throughClass, association.source);
1851
- if (!newAssociation)
1852
- throw new MissingThroughAssociationSource_js_1.default({
1853
- dreamClass,
1854
- throughClass,
1855
- association,
1856
- });
1857
- return { throughAssociation, throughClass, newAssociation };
1858
- }
1859
- /**
1860
- * @internal
1861
- *
1862
- * Polymorphic BelongsTo. Since polymorphic associations may point to multiple tables,
1863
- * preload by loading each target class separately.
1864
- *
1865
- * Used to preload polymorphic belongs to associations
1866
- */
1867
- async preloadPolymorphicBelongsTo(association, dreams) {
1868
- if (!association.polymorphic)
1869
- throw new Error(`Association ${association.as} points to an array of models but is not designated polymorphic`);
1870
- if (association.type !== 'BelongsTo')
1871
- throw new Error(`Polymorphic association ${association.as} points to an array of models but is ${association.type}. Only BelongsTo associations may point to an array of models.`);
1872
- const associatedDreams = [];
1873
- for (const associatedModel of association.modelCB()) {
1874
- await this.preloadPolymorphicAssociationModel(dreams, association, associatedModel, associatedDreams);
1875
- }
1876
- return associatedDreams;
1877
- }
1878
- async preloadPolymorphicAssociationModel(dreams, association, associatedDreamClass, associatedDreams) {
1879
- const relevantAssociatedModels = dreams.filter((dream) => {
1880
- const field = association.foreignKeyTypeField();
1881
- return dream[field] === associatedDreamClass['stiBaseClassOrOwnClassName'] || dream[field] === null;
1882
- });
1883
- if (relevantAssociatedModels.length) {
1884
- dreams.forEach((dream) => {
1885
- dream[(0, associationToGetterSetterProp_js_1.default)(association)] = null;
1886
- });
1887
- // Load all models of type associated that are associated with any of the already loaded Dream models
1888
- const loadedAssociations = await this.dreamClassQueryWithScopeBypasses(associatedDreamClass, {
1889
- // The association may remove specific default scopes that would otherwise preclude
1890
- // certain instances of the associated class from being found.
1891
- defaultScopesToBypassExceptOnAssociations: association.withoutDefaultScopes,
1892
- })
1893
- .where({
1894
- [associatedDreamClass.primaryKey]: relevantAssociatedModels.map((dream) => dream[association.foreignKey()]),
1895
- })
1896
- .all();
1897
- loadedAssociations.forEach((loadedAssociation) => associatedDreams.push(loadedAssociation));
1898
- //////////////////////////////////////////////////////////////////////////////////////////////
1899
- // Associate each loaded association with each dream based on primary key and foreign key type
1900
- //////////////////////////////////////////////////////////////////////////////////////////////
1901
- for (const loadedAssociation of loadedAssociations) {
1902
- dreams
1903
- .filter((dream) => {
1904
- return (dream[association.foreignKeyTypeField()] === loadedAssociation['stiBaseClassOrOwnClassName'] &&
1905
- dream[association.foreignKey()] === association.primaryKeyValue(loadedAssociation));
1906
- })
1907
- .forEach((dream) => {
1908
- dream[association.as] = loadedAssociation;
1909
- });
1910
- }
1911
- ///////////////////////////////////////////////////////////////////////////////////////////////////
1912
- // end: Associate each loaded association with each dream based on primary key and foreign key type
1913
- ///////////////////////////////////////////////////////////////////////////////////////////////////
1914
- }
1915
- }
1916
- /**
1917
- * @internal
1918
- *
1919
- * Applies a preload statement
1920
- */
1921
- async applyOnePreload(associationName, dreams, onStatement = {}) {
1922
- if (!Array.isArray(dreams))
1923
- dreams = [dreams];
1924
- const dream = dreams.find(dream => dream['getAssociationMetadata'](associationName));
1925
- if (!dream)
1926
- return;
1927
- const { name, alias } = (0, extractAssociationMetadataFromAssociationName_js_1.default)(associationName);
1928
- const association = dream['getAssociationMetadata'](name);
1929
- if (association === undefined)
1930
- throw new UnexpectedUndefined_js_1.default();
1931
- const dreamClass = dream.constructor;
1932
- const dreamClassToHydrate = association.modelCB();
1933
- if ((association.polymorphic && association.type === 'BelongsTo') || Array.isArray(dreamClassToHydrate))
1934
- return this.preloadPolymorphicBelongsTo(association, dreams);
1935
- const dreamClassToHydrateColumns = [...dreamClassToHydrate.columns()];
1936
- const throughColumnsToHydrate = [];
1937
- const columnsToPluck = dreamClassToHydrateColumns.map(column => this.namespaceColumn(column.toString(), alias));
1938
- const asHasAssociation = association;
1939
- if (asHasAssociation.through && asHasAssociation.preloadThroughColumns) {
1940
- if ((0, isObject_js_1.default)(asHasAssociation.preloadThroughColumns)) {
1941
- const preloadMap = asHasAssociation.preloadThroughColumns;
1942
- Object.keys(preloadMap).forEach(preloadThroughColumn => {
1943
- throughColumnsToHydrate.push(preloadMap[preloadThroughColumn]);
1944
- columnsToPluck.push(this.namespaceColumn(preloadThroughColumn, asHasAssociation.through));
1945
- });
1946
- }
1947
- else {
1948
- const preloadArray = asHasAssociation.preloadThroughColumns;
1949
- preloadArray.forEach(preloadThroughColumn => {
1950
- throughColumnsToHydrate.push(preloadThroughColumn);
1951
- columnsToPluck.push(this.namespaceColumn(preloadThroughColumn, asHasAssociation.through));
1952
- });
1953
- }
1954
- }
1955
- columnsToPluck.push(this.namespaceColumn(dreamClass.primaryKey, dreamClass.table));
1956
- const baseClass = dreamClass['stiBaseClassOrOwnClass']['getAssociationMetadata'](associationName)
1957
- ? dreamClass['stiBaseClassOrOwnClass']
1958
- : dreamClass;
1959
- const associationDataScope = this.dreamClassQueryWithScopeBypasses(baseClass, {
1960
- // In order to stay DRY, preloading leverages the association logic built into
1961
- // `joins` (by using `pluck`, which calls `joins`). However, baseClass may have
1962
- // default scopes that would preclude finding that instance. We remove all
1963
- // default scopes on baseClass, but not subsequent associations, so that the
1964
- // single query will be able to find each row corresponding to a Dream in `dreams`,
1965
- // regardless of default scopes on that Dream's class.
1966
- bypassAllDefaultScopesExceptOnAssociations: true,
1967
- }).where({
1968
- [dreamClass.primaryKey]: dreams.map(obj => obj.primaryKeyValue),
1969
- });
1970
- const hydrationData = await associationDataScope
1971
- ._connection(this.connectionOverride)
1972
- .innerJoin(associationName, (onStatement || {}))
1973
- .pluck(...columnsToPluck);
1974
- const preloadedDreamsAndWhatTheyPointTo = hydrationData.map(pluckedData => {
1975
- const attributes = {};
1976
- dreamClassToHydrateColumns.forEach((columnName, index) => (attributes[(0, protectAgainstPollutingAssignment_js_1.default)(columnName)] = pluckedData[index]));
1977
- const hydratedDream = (0, sqlResultToDreamInstance_js_1.default)(dreamClassToHydrate, attributes);
1978
- throughColumnsToHydrate.forEach((throughAssociationColumn, index) => (hydratedDream.preloadedThroughColumns[throughAssociationColumn] =
1979
- pluckedData[dreamClassToHydrateColumns.length + index]));
1980
- return {
1981
- dream: hydratedDream,
1982
- pointsToPrimaryKey: pluckedData.at(-1),
1983
- };
1984
- });
1985
- this.hydrateAssociation(dreams, association, preloadedDreamsAndWhatTheyPointTo);
1986
- return preloadedDreamsAndWhatTheyPointTo.map(obj => obj.dream);
1987
- }
1988
- /**
1989
- * @internal
1990
- *
1991
- * Used by loadBuider
1992
- */
1993
- async hydratePreload(dream) {
1994
- await this.applyPreload(this.preloadStatements, this.preloadOnStatements, dream);
1995
- }
1996
- /**
1997
- * @internal
1998
- *
1999
- * Applies a preload statement
2000
- */
2001
- async applyPreload(preloadStatement, preloadOnStatements, dream) {
2002
- const keys = Object.keys(preloadStatement);
2003
- for (const key of keys) {
2004
- const nestedDreams = await this.applyOnePreload(key, dream, this.applyablePreloadOnStatements(preloadOnStatements[key]));
2005
- if (nestedDreams) {
2006
- await this.applyPreload(preloadStatement[key], preloadOnStatements[key], nestedDreams);
2007
- }
2008
- }
2009
- }
2010
- /**
2011
- * @internal
2012
- *
2013
- * retrieves on statements that can be applied to a preload
2014
- */
2015
- applyablePreloadOnStatements(preloadOnStatements) {
2016
- if (preloadOnStatements === undefined)
2017
- return undefined;
2018
- return Object.keys(preloadOnStatements).reduce((agg, key) => {
2019
- const value = preloadOnStatements[key];
2020
- if (value === undefined)
2021
- throw new UnexpectedUndefined_js_1.default();
2022
- // filter out plain objects, but not ops and not and/andNot/andAny statements
2023
- // because plain objects are just the next level of nested preload
2024
- if (key === 'and' ||
2025
- key === 'andNot' ||
2026
- key === 'andAny' ||
2027
- value === null ||
2028
- value.constructor !== Object) {
2029
- agg[key] = value;
2030
- }
2031
- return agg;
2032
- }, {});
2033
- }
2034
- conditionallyApplyDefaultScopes() {
2035
- if (this.bypassAllDefaultScopes || this.bypassAllDefaultScopesExceptOnAssociations)
2036
- return this;
2037
- const thisScopes = this.dreamClass['scopes'].default;
2038
- let query = this;
2039
- for (const scope of thisScopes) {
2040
- if (!(0, shouldBypassDefaultScope_js_1.default)(scope.method, {
2041
- defaultScopesToBypass: [
2042
- ...this.defaultScopesToBypass,
2043
- ...this.defaultScopesToBypassExceptOnAssociations,
2044
- ],
2045
- })) {
2046
- query = this.dreamClass[scope.method](query);
2047
- }
2048
- }
2049
- return query;
2050
- }
2051
- /**
2052
- * Each association in the chain is pushed onto `throughAssociations`
2053
- * and `applyOneJoin` is recursively called. The trick is that the
2054
- * through associations don't get written into the SQL; they
2055
- * locate the next association we need to build into the SQL,
2056
- * which is only run by the association that started the `through`
2057
- * chain. The final association at the end of the `through` chain _is_
2058
- * written into the SQL as a full association, but the modifications from
2059
- * the `through` association are only added when the recursion returns
2060
- * back to the association that kicked off the through associations.
2061
- */
2062
- joinsBridgeThroughAssociations({ query, dreamClass, association, previousAssociationTableOrAlias, throughAssociations, joinType, }) {
2063
- if (association.type === 'BelongsTo' || !association.through) {
2064
- return {
2065
- query,
2066
- dreamClass,
2067
- association,
2068
- previousAssociationTableOrAlias,
2069
- };
2070
- }
2071
- else {
2072
- throughAssociations.push(association);
2073
- // We have entered joinsBridgeThroughAssociations with the
2074
- // CompositionAssetAudits HasOne User association, which
2075
- // is through compositionAsset
2076
- // We now apply the compositionAsset association (a BelongsTo)
2077
- // to the query
2078
- const { query: queryWithThroughAssociationApplied } = this.applyOneJoin({
2079
- query,
2080
- dreamClass,
2081
- previousAssociationTableOrAlias,
2082
- currentAssociationTableOrAlias: association.through,
2083
- throughAssociations,
2084
- joinType,
2085
- });
2086
- // The through association has both a `through` and a `source`. The `source`
2087
- // is the association on the model that has now been joined. In our example,
2088
- // the `source` is the `user` association on the CompositionAsset model
2089
- const { newAssociation, throughAssociation, throughClass } = this.followThroughAssociation(dreamClass, association);
2090
- if (newAssociation.through) {
2091
- // This new association is itself a through association, so we recursively
2092
- // call joinsBridgeThroughAssociations
2093
- return this.joinsBridgeThroughAssociations({
2094
- query: queryWithThroughAssociationApplied,
2095
- dreamClass: throughClass,
2096
- association: newAssociation,
2097
- previousAssociationTableOrAlias: throughAssociation.as,
2098
- throughAssociations,
2099
- joinType,
2100
- });
2101
- }
2102
- else {
2103
- // This new association is not a through association, so
2104
- // this is the target association we were looking for
2105
- return {
2106
- query: queryWithThroughAssociationApplied,
2107
- dreamClass: association.modelCB(),
2108
- association: newAssociation,
2109
- throughClass,
2110
- previousAssociationTableOrAlias: association.through,
2111
- };
2112
- }
2113
- }
2114
- }
2115
- applyOneJoin({ query, dreamClass, previousAssociationTableOrAlias, currentAssociationTableOrAlias, joinAndStatements = {}, throughAssociations = [], joinType, }) {
2116
- const { name, alias } = (0, extractAssociationMetadataFromAssociationName_js_1.default)(currentAssociationTableOrAlias);
2117
- const joinAndStatement = joinAndStatements[currentAssociationTableOrAlias];
2118
- previousAssociationTableOrAlias = (0, extractAssociationMetadataFromAssociationName_js_1.default)(previousAssociationTableOrAlias).alias;
2119
- currentAssociationTableOrAlias = alias;
2120
- let association = dreamClass['getAssociationMetadata'](name);
2121
- if (!association) {
2122
- throw new JoinAttemptedOnMissingAssociation_js_1.default({
2123
- dreamClass,
2124
- associationName: currentAssociationTableOrAlias,
2125
- });
2126
- }
2127
- const results = this.joinsBridgeThroughAssociations({
2128
- query,
2129
- dreamClass,
2130
- association,
2131
- previousAssociationTableOrAlias,
2132
- throughAssociations,
2133
- joinType,
2134
- });
2135
- query = results.query;
2136
- dreamClass = results.dreamClass;
2137
- association = results.association;
2138
- const timeToApplyThroughAssociations = throughAssociations.length && throughAssociations[0]?.source === association.as;
2139
- const originalPreviousAssociationTableOrAlias = previousAssociationTableOrAlias;
2140
- previousAssociationTableOrAlias = results.previousAssociationTableOrAlias;
2141
- const throughClass = results.throughClass;
2142
- if (timeToApplyThroughAssociations) {
2143
- /**
2144
- * Each association in the chain is pushed onto `throughAssociations`
2145
- * and `applyOneJoin` is recursively called. The trick is that the
2146
- * through associations don't get written into the SQL; they
2147
- * locate the next association we need to build into the SQL,
2148
- * which is only run by the association that started the `through`
2149
- * chain (thus the
2150
- * `throughAssociations.length && throughAssociations[0].source === association.as`
2151
- * above). The final association at the end of the `through` chain _is_
2152
- * written into the SQL as a full association, but the modifications from
2153
- * the `through` association are only added when the recursion returns
2154
- * back to the association that kicked off the through associations.
2155
- */
2156
- throughAssociations.forEach((throughAssociation) => {
2157
- if (throughAssociation.type === 'HasMany') {
2158
- if (query?.distinctOn && throughAssociation.distinct) {
2159
- query = query.distinctOn(this.distinctColumnNameForAssociation({
2160
- association: throughAssociation,
2161
- tableNameOrAlias: currentAssociationTableOrAlias,
2162
- foreignKey: throughAssociation.primaryKey(),
2163
- }));
2164
- }
2165
- if (throughAssociation.order) {
2166
- query = this.applyOrderStatementForAssociation({
2167
- query,
2168
- association: throughAssociation,
2169
- tableNameOrAlias: currentAssociationTableOrAlias,
2170
- });
2171
- }
2172
- }
2173
- });
2174
- }
2175
- if (association.type === 'BelongsTo') {
2176
- if (Array.isArray(association.modelCB()))
2177
- throw new CannotJoinPolymorphicBelongsToError_js_1.default({
2178
- dreamClass,
2179
- association,
2180
- innerJoinStatements: this.innerJoinStatements,
2181
- leftJoinStatements: this.leftJoinStatements,
2182
- });
2183
- const to = association.modelCB().table;
2184
- const joinTableExpression = currentAssociationTableOrAlias === to
2185
- ? currentAssociationTableOrAlias
2186
- : `${to} as ${currentAssociationTableOrAlias}`;
2187
- query = query[(joinType === 'inner' ? 'innerJoin' : 'leftJoin')](joinTableExpression, (join) => {
2188
- join = join.onRef(this.namespaceColumn(association.foreignKey(), previousAssociationTableOrAlias), '=', this.namespaceColumn(association.primaryKey(), currentAssociationTableOrAlias));
2189
- if (timeToApplyThroughAssociations) {
2190
- throughAssociations.forEach((throughAssociation) => {
2191
- join = this.applyAssociationAndStatementsToJoinStatement({
2192
- join,
2193
- association: throughAssociation,
2194
- currentAssociationTableOrAlias,
2195
- previousAssociationTableOrAlias: originalPreviousAssociationTableOrAlias,
2196
- joinAndStatements,
2197
- });
2198
- });
2199
- }
2200
- join = this.conditionallyApplyDefaultScopesDependentOnAssociation({
2201
- join,
2202
- tableNameOrAlias: currentAssociationTableOrAlias,
2203
- association,
2204
- });
2205
- join = this.applyJoinAndStatement(join, joinAndStatement, currentAssociationTableOrAlias);
2206
- return join;
2207
- });
2208
- }
2209
- else {
2210
- const to = association.modelCB().table;
2211
- const joinTableExpression = currentAssociationTableOrAlias === to
2212
- ? currentAssociationTableOrAlias
2213
- : `${to} as ${currentAssociationTableOrAlias}`;
2214
- query = query[(joinType === 'inner' ? 'innerJoin' : 'leftJoin')](joinTableExpression, (join) => {
2215
- join = join.onRef(this.namespaceColumn(association.primaryKey(), previousAssociationTableOrAlias), '=', this.namespaceColumn(association.foreignKey(), currentAssociationTableOrAlias));
2216
- if (association.polymorphic) {
2217
- join = join.on((eb) => this.whereStatementToExpressionWrapper(eb, this.aliasWhereStatement({
2218
- [association.foreignKeyTypeField()]: throughClass
2219
- ? throughClass['stiBaseClassOrOwnClassName']
2220
- : dreamClass['stiBaseClassOrOwnClassName'],
2221
- }, currentAssociationTableOrAlias)));
2222
- }
2223
- if (timeToApplyThroughAssociations) {
2224
- throughAssociations.forEach((throughAssociation) => {
2225
- join = this.applyAssociationAndStatementsToJoinStatement({
2226
- join,
2227
- association: throughAssociation,
2228
- currentAssociationTableOrAlias,
2229
- previousAssociationTableOrAlias: originalPreviousAssociationTableOrAlias,
2230
- joinAndStatements,
2231
- });
2232
- });
2233
- }
2234
- join = this.applyAssociationAndStatementsToJoinStatement({
2235
- join,
2236
- association,
2237
- currentAssociationTableOrAlias,
2238
- previousAssociationTableOrAlias,
2239
- joinAndStatements,
2240
- });
2241
- join = this.conditionallyApplyDefaultScopesDependentOnAssociation({
2242
- join,
2243
- tableNameOrAlias: currentAssociationTableOrAlias,
2244
- association,
2245
- });
2246
- join = this.applyJoinAndStatement(join, joinAndStatement, currentAssociationTableOrAlias);
2247
- return join;
2248
- });
2249
- if (association.type === 'HasMany') {
2250
- if (association.order) {
2251
- query = this.applyOrderStatementForAssociation({
2252
- query,
2253
- tableNameOrAlias: currentAssociationTableOrAlias,
2254
- association,
2255
- });
2256
- }
2257
- if (query.distinctOn && association.distinct) {
2258
- query = query.distinctOn(this.distinctColumnNameForAssociation({
2259
- association,
2260
- tableNameOrAlias: currentAssociationTableOrAlias,
2261
- foreignKey: association.foreignKey(),
2262
- }));
2263
- }
2264
- }
2265
- }
2266
- return {
2267
- query,
2268
- association,
2269
- previousAssociationTableOrAlias,
2270
- currentAssociationTableOrAlias,
2271
- };
2272
- }
2273
- applyAssociationAndStatementsToJoinStatement({ join, currentAssociationTableOrAlias, previousAssociationTableOrAlias, association, joinAndStatements, }) {
2274
- if (association.and) {
2275
- this.throwUnlessAllRequiredWhereClausesProvided(association, currentAssociationTableOrAlias, joinAndStatements);
2276
- join = join.on((eb) => this.whereStatementToExpressionWrapper(eb, this.aliasWhereStatement(association.and, currentAssociationTableOrAlias), { disallowSimilarityOperator: false }));
2277
- }
2278
- if (association.andNot) {
2279
- join = join.on((eb) => this.whereStatementToExpressionWrapper(eb, this.aliasWhereStatement(association.andNot, currentAssociationTableOrAlias), { negate: true }));
2280
- }
2281
- if (association.andAny) {
2282
- join = join.on((eb) => eb.or(association.andAny.map(whereAnyStatement => this.whereStatementToExpressionWrapper(eb, this.aliasWhereStatement(whereAnyStatement, currentAssociationTableOrAlias), { disallowSimilarityOperator: false }))));
2283
- }
2284
- if (association.selfAnd) {
2285
- join = join.on((eb) => this.whereStatementToExpressionWrapper(eb, this.rawifiedSelfOnClause({
2286
- associationAlias: association.as,
2287
- selfAlias: previousAssociationTableOrAlias,
2288
- selfAndClause: association.selfAnd,
2289
- })));
2290
- }
2291
- if (association.selfAndNot) {
2292
- join = join.on((eb) => this.whereStatementToExpressionWrapper(eb, this.rawifiedSelfOnClause({
2293
- associationAlias: association.as,
2294
- selfAlias: previousAssociationTableOrAlias,
2295
- selfAndClause: association.selfAndNot,
2296
- }), { negate: true }));
2297
- }
2298
- return join;
2299
- }
2300
- conditionallyApplyDefaultScopesDependentOnAssociation({ join, tableNameOrAlias, association, }) {
2301
- let scopesQuery = new Query(this.dreamInstance);
2302
- const associationClass = association.modelCB();
2303
- const associationScopes = associationClass['scopes'].default;
2304
- for (const scope of associationScopes) {
2305
- if (!(0, shouldBypassDefaultScope_js_1.default)(scope.method, {
2306
- bypassAllDefaultScopes: this.bypassAllDefaultScopes,
2307
- defaultScopesToBypass: [...this.defaultScopesToBypass, ...(association.withoutDefaultScopes || [])],
2308
- })) {
2309
- const tempQuery = associationClass[scope.method](scopesQuery);
2310
- // The scope method on a Dream model should return a clone of the Query it receives
2311
- // (e.g. by returning `scope.where(...)`), but in case the function doesn't return,
2312
- // or returns the wrong thing, we check before overriding `scopesQuery` with what the
2313
- // method returned.
2314
- if (tempQuery && tempQuery.constructor === scopesQuery.constructor)
2315
- scopesQuery = tempQuery;
2316
- }
2317
- }
2318
- if (scopesQuery.whereStatements.length) {
2319
- join = join.on((eb) => eb.and(scopesQuery.whereStatements.flatMap(whereStatement => this.whereStatementToExpressionWrapper(eb, this.aliasWhereStatement(whereStatement, tableNameOrAlias), { disallowSimilarityOperator: false }))));
2320
- }
2321
- return join;
2322
- }
2323
- distinctColumnNameForAssociation({ association, tableNameOrAlias, foreignKey, }) {
2324
- if (!association.distinct)
2325
- return null;
2326
- if (association.distinct === true)
2327
- return this.namespaceColumn(foreignKey, tableNameOrAlias);
2328
- return this.namespaceColumn(association.distinct, tableNameOrAlias);
2329
- }
2330
- recursivelyJoin({ query, joinStatement, joinAndStatements, dreamClass, previousAssociationTableOrAlias, joinType, }) {
2331
- for (const currentAssociationTableOrAlias of Object.keys(joinStatement)) {
2332
- const results = this.applyOneJoin({
2333
- query,
2334
- dreamClass,
2335
- previousAssociationTableOrAlias,
2336
- currentAssociationTableOrAlias,
2337
- joinAndStatements,
2338
- joinType,
2339
- });
2340
- query = results.query;
2341
- const association = results.association;
2342
- query = this.recursivelyJoin({
2343
- query,
2344
- joinStatement: joinStatement[currentAssociationTableOrAlias],
2345
- joinAndStatements: joinAndStatements[currentAssociationTableOrAlias],
2346
- dreamClass: association.modelCB(),
2347
- previousAssociationTableOrAlias: currentAssociationTableOrAlias,
2348
- joinType,
2349
- });
2350
- }
2351
- return query;
2352
- }
2353
- throwUnlessAllRequiredWhereClausesProvided(association, namespace, joinAndStatements) {
2354
- const andClause = association.and;
2355
- const columnsRequiringAndStatements = Object.keys(andClause).reduce((agg, column) => {
2356
- if (andClause[column] === constants_js_1.DreamConst.required)
2357
- agg.push(column);
2358
- return agg;
2359
- }, []);
2360
- const missingRequiredWhereStatements = columnsRequiringAndStatements.filter(column => joinAndStatements[namespace]?.and?.[column] === undefined);
2361
- if (missingRequiredWhereStatements.length)
2362
- throw new MissingRequiredAssociationAndClause_js_1.default(association, missingRequiredWhereStatements[0]);
2363
- }
2364
- applyOrderStatementForAssociation({ query, tableNameOrAlias, association, }) {
2365
- if (!query.orderBy)
2366
- return query;
2367
- let selectQuery = query;
2368
- const orderStatement = association.order;
2369
- if (typeof orderStatement === 'string') {
2370
- selectQuery = selectQuery.orderBy(this.namespaceColumn(orderStatement, tableNameOrAlias), 'asc');
2371
- }
2372
- else {
2373
- Object.keys(orderStatement).forEach(column => {
2374
- const direction = orderStatement[column];
2375
- selectQuery = selectQuery.orderBy(this.namespaceColumn(column, tableNameOrAlias), direction);
2376
- });
2377
- }
2378
- return selectQuery;
2379
- }
2380
- inArrayWithNull_or_notInArrayWithoutNull_ExpressionBuilder(eb, a, b, c) {
2381
- const isNullStatement = eb(a, 'is', null);
2382
- const compactedC = (0, compact_js_1.default)(c);
2383
- if (compactedC.length)
2384
- return eb.or([eb(a, b, compactedC), isNullStatement]);
2385
- // not in an empty array means match everything
2386
- if (b === 'not in')
2387
- return (0, kysely_1.sql) `TRUE`;
2388
- return isNullStatement;
2389
- }
2390
- inArrayWithoutNullExpressionBuilder(eb, a, b, c) {
2391
- const isNotNullStatement = eb(a, 'is not', null);
2392
- const compactedC = (0, compact_js_1.default)(c);
2393
- if (compactedC.length)
2394
- return eb.and([eb(a, 'in', compactedC), isNotNullStatement]);
2395
- // in an empty array means match nothing
2396
- return (0, kysely_1.sql) `FALSE`;
2397
- }
2398
- notInArrayWithNullExpressionBuilder(eb, a, b, c) {
2399
- const isNullStatement = eb(a, 'is not', null);
2400
- const compactedC = (0, compact_js_1.default)(c);
2401
- if (compactedC.length)
2402
- return eb.and([eb(a, 'not in', compactedC), isNullStatement]);
2403
- return isNullStatement;
2404
- }
2405
- whereStatementToExpressionWrapper(eb, whereStatement, { negate = false, disallowSimilarityOperator = true, } = {}) {
2406
- const clauses = (0, compact_js_1.default)(Object.keys(whereStatement)
2407
- .filter(key => whereStatement[key] !== constants_js_1.DreamConst.required)
2408
- .map(attr => {
2409
- const val = whereStatement[attr];
2410
- if (val?.isOpsStatement &&
2411
- val.shouldBypassWhereStatement) {
2412
- if (disallowSimilarityOperator)
2413
- throw new Error('Similarity operator may not be used in whereAny');
2414
- // some ops statements are handled specifically in the select portion of the query,
2415
- // and should be ommited from the where clause directly
2416
- return;
2417
- }
2418
- const { a, b, c, a2, b2, c2 } = this.dreamWhereStatementToExpressionBuilderParts(attr, val);
2419
- // postgres is unable to handle WHERE IN statements with blank arrays, such as in
2420
- // "WHERE id IN ()", meaning that:
2421
- // 1. If we receive a blank array during an IN comparison,
2422
- // then we need to simply regurgitate a where statement which
2423
- // guarantees no records.
2424
- // 2. If we receive a blank array during a NOT IN comparison,
2425
- // then it is the same as the where statement not being present at all,
2426
- // resulting in a noop on our end
2427
- //
2428
- if (Array.isArray(c)) {
2429
- if ((b === 'in' && c.includes(null)) || (b === 'not in' && !c.includes(null))) {
2430
- return this.inArrayWithNull_or_notInArrayWithoutNull_ExpressionBuilder(eb, a, b, c);
2431
- }
2432
- else if (negate && b === 'in' && !c.includes(null)) {
2433
- return this.inArrayWithoutNullExpressionBuilder(eb, a, b, c);
2434
- }
2435
- else if (b === 'not in' && c.includes(null)) {
2436
- return this.notInArrayWithNullExpressionBuilder(eb, a, b, c);
2437
- }
2438
- const compactedC = (0, compact_js_1.default)(c);
2439
- if (b === 'in' && compactedC.length === 0) {
2440
- // in an empty array means match nothing
2441
- return (0, kysely_1.sql) `FALSE`;
2442
- }
2443
- else if (b === 'not in' && compactedC.length === 0) {
2444
- // not in an empty array means match everything
2445
- return (0, kysely_1.sql) `TRUE`;
2446
- }
2447
- else {
2448
- return eb(a, b, compactedC);
2449
- }
2450
- //
2451
- }
2452
- else if (b === '=' && c === null) {
2453
- return eb(a, 'is', null);
2454
- //
2455
- }
2456
- else if (b === '!=' && c === null) {
2457
- return eb(a, 'is not', null);
2458
- //
2459
- }
2460
- else if (b === '=' && negate) {
2461
- return eb.and([eb(a, '=', c), eb(a, 'is not', null)]);
2462
- //
2463
- }
2464
- else if (b === '!=' && c !== null) {
2465
- return eb.or([eb(a, '!=', c), eb(a, 'is', null)]);
2466
- //
2467
- }
2468
- else {
2469
- const expression = eb(a, b, c);
2470
- if (b2)
2471
- return expression.and(eb(a2, b2, c2));
2472
- return expression;
2473
- }
2474
- }));
2475
- return negate ? eb.not(eb.parens(eb.and(clauses))) : eb.and(clauses);
2476
- }
2477
- dreamWhereStatementToExpressionBuilderParts(attr, val) {
2478
- let a;
2479
- let b;
2480
- let c;
2481
- let a2 = null;
2482
- let b2 = null;
2483
- let c2 = null;
2484
- if (val instanceof Function && val !== constants_js_1.DreamConst.passthrough) {
2485
- val = val();
2486
- }
2487
- else if (val === constants_js_1.DreamConst.passthrough) {
2488
- const column = attr.split('.').at(-1);
2489
- if (this.passthroughOnStatement[column] === undefined)
2490
- throw new MissingRequiredPassthroughForAssociationAndClause_js_1.default(column);
2491
- val = this.passthroughOnStatement[column];
2492
- }
2493
- if (val === null) {
2494
- a = attr;
2495
- b = 'is';
2496
- c = val;
2497
- }
2498
- else if (['SelectQueryBuilder', 'SelectQueryBuilderImpl'].includes(val?.constructor?.name)) {
2499
- a = attr;
2500
- b = 'in';
2501
- c = val;
2502
- }
2503
- else if (Array.isArray(val)) {
2504
- a = attr;
2505
- b = 'in';
2506
- c = val.map(v => v instanceof DateTime_js_1.DateTime || v instanceof CalendarDate_js_1.default
2507
- ? v.toSQL()
2508
- : typeof v === 'string'
2509
- ? (0, normalizeUnicode_js_1.default)(v)
2510
- : v);
2511
- }
2512
- else if (val instanceof curried_ops_statement_js_1.default) {
2513
- val = val.toOpsStatement(this.dreamClass, attr);
2514
- a = attr;
2515
- b = val.operator;
2516
- c = val.value;
2517
- }
2518
- else if (val instanceof ops_statement_js_1.default) {
2519
- a = attr;
2520
- b = val.operator;
2521
- c = val.value;
2522
- }
2523
- else if (val instanceof range_js_1.Range) {
2524
- const rangeStart = val.begin;
2525
- const rangeEnd = val.end;
2526
- const excludeEnd = val.excludeEnd;
2527
- if (rangeStart && rangeEnd) {
2528
- a = attr;
2529
- b = '>=';
2530
- c = rangeStart;
2531
- a2 = attr;
2532
- b2 = excludeEnd ? '<' : '<=';
2533
- c2 = rangeEnd;
2534
- }
2535
- else if (rangeStart) {
2536
- a = attr;
2537
- b = '>=';
2538
- c = rangeStart;
2539
- }
2540
- else {
2541
- a = attr;
2542
- b = excludeEnd ? '<' : '<=';
2543
- c = rangeEnd;
2544
- }
2545
- }
2546
- else {
2547
- a = attr;
2548
- b = '=';
2549
- c = val;
2550
- }
2551
- if (c instanceof DateTime_js_1.DateTime || c instanceof CalendarDate_js_1.default)
2552
- c = c.toSQL();
2553
- else if (typeof c === 'string')
2554
- c = (0, normalizeUnicode_js_1.default)(c);
2555
- if (c2 instanceof DateTime_js_1.DateTime || c2 instanceof CalendarDate_js_1.default)
2556
- c2 = c2.toSQL();
2557
- else if (typeof c2 === 'string')
2558
- c2 = (0, normalizeUnicode_js_1.default)(c2);
2559
- if (a && c === undefined)
2560
- throw new CannotPassUndefinedAsAValueToAWhereClause_js_1.default(this.dreamClass, a);
2561
- if (a2 && c2 === undefined)
2562
- throw new CannotPassUndefinedAsAValueToAWhereClause_js_1.default(this.dreamClass, a2);
2563
- return { a, b, c, a2, b2, c2 };
2564
- }
2565
- applyJoinAndStatement(join, joinAndStatement, rootTableOrAssociationAlias) {
2566
- if (!joinAndStatement)
2567
- return join;
2568
- join = this._applyJoinAndStatements(join, joinAndStatement.and, rootTableOrAssociationAlias);
2569
- join = this._applyJoinAndStatements(join, joinAndStatement.andNot, rootTableOrAssociationAlias, {
2570
- negate: true,
2571
- });
2572
- join = this._applyJoinAndAnyStatements(join, joinAndStatement.andAny, rootTableOrAssociationAlias);
2573
- return join;
2574
- }
2575
- _applyJoinAndStatements(join, joinAndStatement, rootTableOrAssociationAlias, { negate = false, } = {}) {
2576
- if (!joinAndStatement)
2577
- return join;
2578
- return join.on((eb) => this.joinAndStatementToExpressionWrapper(joinAndStatement, rootTableOrAssociationAlias, eb, {
2579
- negate,
2580
- disallowSimilarityOperator: negate,
2581
- }));
2582
- }
2583
- _applyJoinAndAnyStatements(join, joinAndAnyStatement, rootTableOrAssociationAlias) {
2584
- if (!joinAndAnyStatement)
2585
- return join;
2586
- if (!joinAndAnyStatement.length)
2587
- return join;
2588
- return join.on((eb) => {
2589
- return eb.or(joinAndAnyStatement.map(joinAndStatement => this.joinAndStatementToExpressionWrapper(joinAndStatement, rootTableOrAssociationAlias, eb)));
2590
- });
2591
- }
2592
- joinAndStatementToExpressionWrapper(joinAndStatement, rootTableOrAssociationAlias, eb, { negate = false, disallowSimilarityOperator = true, } = {}) {
2593
- return this.whereStatementToExpressionWrapper(eb, Object.keys(joinAndStatement).reduce((agg, key) => {
2594
- agg[this.namespaceColumn(key.toString(), rootTableOrAssociationAlias)] = joinAndStatement[key];
2595
- return agg;
2596
- }, {}), {
2597
- negate,
2598
- disallowSimilarityOperator,
2599
- });
2600
- }
2601
- buildCommon(kyselyQuery) {
2602
- this.checkForQueryViolations();
2603
- const query = this.conditionallyApplyDefaultScopes();
2604
- if (!(0, isEmpty_js_1.default)(query.innerJoinStatements)) {
2605
- kyselyQuery = query.recursivelyJoin({
2606
- query: kyselyQuery,
2607
- joinStatement: query.innerJoinStatements,
2608
- joinAndStatements: query.innerJoinAndStatements,
2609
- dreamClass: query.dreamClass,
2610
- previousAssociationTableOrAlias: this.baseSqlAlias,
2611
- joinType: 'inner',
2612
- });
2613
- }
2614
- if (!(0, isEmpty_js_1.default)(query.leftJoinStatements)) {
2615
- kyselyQuery = query.recursivelyJoin({
2616
- query: kyselyQuery,
2617
- joinStatement: query.leftJoinStatements,
2618
- joinAndStatements: query.leftJoinAndStatements,
2619
- dreamClass: query.dreamClass,
2620
- previousAssociationTableOrAlias: this.baseSqlAlias,
2621
- joinType: 'left',
2622
- });
2623
- }
2624
- if (query.whereStatements.length || query.whereNotStatements.length || query.whereAnyStatements.length) {
2625
- kyselyQuery = kyselyQuery.where((eb) => eb.and([
2626
- ...this.aliasWhereStatements(query.whereStatements, query.baseSqlAlias).map(whereStatement => this.whereStatementToExpressionWrapper(eb, whereStatement, {
2627
- disallowSimilarityOperator: false,
2628
- })),
2629
- ...this.aliasWhereStatements(query.whereNotStatements, query.baseSqlAlias).map(whereNotStatement => this.whereStatementToExpressionWrapper(eb, whereNotStatement, { negate: true })),
2630
- ...query.whereAnyStatements.map(whereAnyStatements => eb.or(this.aliasWhereStatements(whereAnyStatements, query.baseSqlAlias).map(whereAnyStatement => this.whereStatementToExpressionWrapper(eb, whereAnyStatement)))),
2631
- ]));
2632
- }
2633
- return kyselyQuery;
2634
- }
2635
- checkForQueryViolations() {
2636
- const invalidWhereNotClauses = this.similarityStatementBuilder().whereNotStatementsWithSimilarityClauses();
2637
- if (invalidWhereNotClauses.length) {
2638
- const invalidWhereNotClause = invalidWhereNotClauses[0];
2639
- if (invalidWhereNotClause === undefined)
2640
- throw new UnexpectedUndefined_js_1.default();
2641
- const { tableName, columnName, opsStatement } = invalidWhereNotClause;
2642
- throw new CannotNegateSimilarityClause_js_1.default(tableName, columnName, opsStatement.value);
2643
- }
2644
- }
2645
- aliasWhereStatements(whereStatements, alias) {
2646
- return whereStatements.map(whereStatement => this.aliasWhereStatement(whereStatement, alias));
2647
- }
2648
- aliasWhereStatement(whereStatement, alias) {
2649
- return Object.keys(whereStatement).reduce((aliasedWhere, key) => {
2650
- aliasedWhere[this.namespaceColumn(key, alias)] = whereStatement[key];
2651
- return aliasedWhere;
2652
- }, {});
2653
- }
2654
- rawifiedSelfOnClause({ associationAlias, selfAlias, selfAndClause, }) {
2655
- const alphanumericUnderscoreRegexp = /[^a-zA-Z0-9_]/g;
2656
- selfAlias = selfAlias.replace(alphanumericUnderscoreRegexp, '');
2657
- return Object.keys(selfAndClause).reduce((acc, key) => {
2658
- const selfColumn = selfAndClause[key]?.replace(alphanumericUnderscoreRegexp, '');
2659
- if (!selfColumn)
2660
- return acc;
2661
- acc[this.namespaceColumn(key, associationAlias)] = kysely_1.sql.raw(`"${(0, snakeify_js_1.default)(selfAlias)}"."${(0, snakeify_js_1.default)(selfColumn)}"`);
2662
- return acc;
2663
- }, {});
2664
- }
2665
- buildDelete() {
2666
- const kyselyQuery = this.dbFor('delete').deleteFrom(this.baseSqlAlias);
2667
- const results = this.attachLimitAndOrderStatementsToNonSelectQuery(kyselyQuery);
2668
- return results.clone.buildCommon(results.kyselyQuery);
2669
- }
2670
- buildSelect({ bypassSelectAll = false, bypassOrder = false, columns, } = {}) {
2671
- let kyselyQuery;
2672
- if (this.baseSelectQuery) {
2673
- kyselyQuery = (this.connectionOverride
2674
- ? this.baseSelectQuery.connection(this.connectionOverride)
2675
- : this.baseSelectQuery).buildSelect({ bypassSelectAll: true });
2676
- }
2677
- else {
2678
- const from = this.baseSqlAlias === this.tableName ? this.tableName : `${this.tableName} as ${this.baseSqlAlias}`;
2679
- kyselyQuery = this.dbFor('select').selectFrom(from);
2680
- }
2681
- if (this.distinctColumn) {
2682
- kyselyQuery = kyselyQuery.distinctOn(this.distinctColumn);
2683
- }
2684
- kyselyQuery = this.buildCommon(kyselyQuery);
2685
- kyselyQuery = this.conditionallyAttachSimilarityColumnsToSelect(kyselyQuery, {
2686
- bypassOrder: bypassOrder || !!this.distinctColumn,
2687
- });
2688
- if (this.orderStatements.length && !bypassOrder) {
2689
- this.orderStatements.forEach(orderStatement => {
2690
- kyselyQuery = kyselyQuery.orderBy(this.namespaceColumn(orderStatement.column), (0, orderByDirection_js_1.default)(orderStatement.direction));
2691
- });
2692
- }
2693
- if (this.limitStatement)
2694
- kyselyQuery = kyselyQuery.limit(this.limitStatement);
2695
- if (this.offsetStatement)
2696
- kyselyQuery = kyselyQuery.offset(this.offsetStatement);
2697
- if (columns) {
2698
- kyselyQuery = kyselyQuery.select(this.columnsWithRequiredLoadColumns(columns).map(column => this.namespaceColumn(column)));
2699
- }
2700
- else if (!bypassSelectAll) {
2701
- kyselyQuery = kyselyQuery.selectAll(this.baseSqlAlias);
2702
- }
2703
- // even though we manually bypass explicit order statements above,
2704
- // associations can contain their own ordering systems. If we do not
2705
- // escape all orders, we can mistakenly allow an order clause to sneak in.
2706
- if (bypassOrder)
2707
- kyselyQuery = kyselyQuery.clearOrderBy();
2708
- return kyselyQuery;
2709
- }
2710
- columnsWithRequiredLoadColumns(columns) {
2711
- return (0, uniq_js_1.default)((0, compact_js_1.default)([this.dreamClass.primaryKey, this.dreamClass['isSTIBase'] ? 'type' : null, ...columns]));
2712
- }
2713
- buildUpdate(attributes) {
2714
- let kyselyQuery = this.dbFor('update')
2715
- .updateTable(this.tableName)
2716
- .set(attributes);
2717
- kyselyQuery = this.conditionallyAttachSimilarityColumnsToUpdate(kyselyQuery);
2718
- const results = this.attachLimitAndOrderStatementsToNonSelectQuery(kyselyQuery);
2719
- return results.clone.buildCommon(results.kyselyQuery);
2720
- }
2721
- attachLimitAndOrderStatementsToNonSelectQuery(kyselyQuery) {
2722
- if (this.limitStatement || this.orderStatements.length) {
2723
- kyselyQuery = kyselyQuery.where((eb) => {
2724
- const subquery = this.nestedSelect(this.dreamInstance.primaryKey);
2725
- return eb(this.dreamInstance.primaryKey, 'in', subquery);
2726
- });
2727
- return {
2728
- kyselyQuery,
2729
- clone: this.clone({ where: null, whereNot: null, order: null, limit: null }),
2730
- };
2731
- }
2732
- return { kyselyQuery, clone: this };
2733
- }
2734
- get hasSimilarityClauses() {
2735
- return this.similarityStatementBuilder().hasSimilarityClauses;
2736
- }
2737
- similarityStatementBuilder() {
2738
- return new SimilarityBuilder_js_1.default(this.dreamInstance, {
2739
- where: [...this.whereStatements],
2740
- whereNot: [...this.whereNotStatements],
2741
- joinAndStatements: this.innerJoinAndStatements,
2742
- transaction: this.dreamTransaction,
2743
- connection: this.connectionOverride,
2744
- });
2745
- }
2746
- conditionallyAttachSimilarityColumnsToSelect(kyselyQuery, { bypassOrder = false } = {}) {
2747
- const similarityBuilder = this.similarityStatementBuilder();
2748
- if (similarityBuilder.hasSimilarityClauses) {
2749
- kyselyQuery = similarityBuilder.select(kyselyQuery, { bypassOrder });
2750
- }
2751
- return kyselyQuery;
2752
- }
2753
- conditionallyAttachSimilarityColumnsToUpdate(kyselyQuery) {
2754
- const similarityBuilder = this.similarityStatementBuilder();
2755
- if (similarityBuilder.hasSimilarityClauses) {
2756
- kyselyQuery = similarityBuilder.update(kyselyQuery);
2757
- }
2758
- return kyselyQuery;
1395
+ return await this.dbDriverInstance().update(attributes);
2759
1396
  }
2760
1397
  invertOrder() {
2761
1398
  let query = this.clone({ order: null });
@@ -2768,11 +1405,3 @@ class Query extends ConnectedToDB_js_1.default {
2768
1405
  }
2769
1406
  }
2770
1407
  exports.default = Query;
2771
- function getSourceAssociation(dream, sourceName) {
2772
- if (!dream)
2773
- return;
2774
- if (!sourceName)
2775
- return;
2776
- return (dream['getAssociationMetadata'](sourceName) ||
2777
- dream['getAssociationMetadata'](pluralize_esm_1.default.singular(sourceName)));
2778
- }