@rvoh/dream 2.34.0 → 2.36.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.
- package/README.md +2 -2
- package/dist/cjs/src/Dream.js +270 -69
- package/dist/cjs/src/bin/index.js +13 -0
- package/dist/cjs/src/cli/index.js +28 -17
- package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
- package/dist/cjs/src/decorators/Decorators.js +26 -4
- package/dist/cjs/src/decorators/field/Encrypted.js +30 -6
- package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +6 -6
- package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +63 -27
- package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +3 -3
- package/dist/cjs/src/dream/LoadBuilder.js +1 -1
- package/dist/cjs/src/dream/Query.js +542 -167
- package/dist/cjs/src/dream/QueryDriver/Base.js +72 -0
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +216 -50
- package/dist/cjs/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
- package/dist/cjs/src/dream/internal/associations/associationQuery.js +4 -0
- package/dist/cjs/src/dream/internal/reload.js +6 -1
- package/dist/cjs/src/dream/internal/saveDream.js +8 -2
- package/dist/cjs/src/dream/internal/sqlResultToDreamInstance.js +2 -0
- package/dist/cjs/src/dream/internal/undestroyDream.js +1 -1
- package/dist/cjs/src/dream-app/index.js +38 -0
- package/dist/cjs/src/encrypt/InternalEncrypt.js +49 -4
- package/dist/cjs/src/encrypt/defaultEncryptedColumnName.js +10 -0
- package/dist/cjs/src/encrypt/index.js +76 -9
- package/dist/cjs/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
- package/dist/cjs/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
- package/dist/cjs/src/helpers/Env.js +28 -0
- package/dist/cjs/src/helpers/cli/generateDreamContent.js +2 -1
- package/dist/cjs/src/helpers/cli/generateFactoryContent.js +1 -1
- package/dist/cjs/src/helpers/cli/generateMigrationContent.js +9 -9
- package/dist/cjs/src/helpers/cli/generateSerializerContent.js +21 -8
- package/dist/cjs/src/serializer/SerializerRenderer.js +65 -13
- package/dist/cjs/src/serializer/builders/DreamSerializerBuilder.js +54 -38
- package/dist/cjs/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
- package/dist/cjs/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
- package/dist/esm/src/Dream.js +270 -69
- package/dist/esm/src/bin/index.js +13 -0
- package/dist/esm/src/cli/index.js +28 -17
- package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
- package/dist/esm/src/decorators/Decorators.js +26 -4
- package/dist/esm/src/decorators/field/Encrypted.js +30 -6
- package/dist/esm/src/dream/DreamClassTransactionBuilder.js +6 -6
- package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +63 -27
- package/dist/esm/src/dream/LeftJoinLoadBuilder.js +3 -3
- package/dist/esm/src/dream/LoadBuilder.js +1 -1
- package/dist/esm/src/dream/Query.js +542 -167
- package/dist/esm/src/dream/QueryDriver/Base.js +72 -0
- package/dist/esm/src/dream/QueryDriver/Kysely.js +216 -50
- package/dist/esm/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
- package/dist/esm/src/dream/internal/associations/associationQuery.js +4 -0
- package/dist/esm/src/dream/internal/reload.js +6 -1
- package/dist/esm/src/dream/internal/saveDream.js +8 -2
- package/dist/esm/src/dream/internal/sqlResultToDreamInstance.js +2 -0
- package/dist/esm/src/dream/internal/undestroyDream.js +1 -1
- package/dist/esm/src/dream-app/index.js +38 -0
- package/dist/esm/src/encrypt/InternalEncrypt.js +49 -4
- package/dist/esm/src/encrypt/defaultEncryptedColumnName.js +10 -0
- package/dist/esm/src/encrypt/index.js +76 -9
- package/dist/esm/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
- package/dist/esm/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
- package/dist/esm/src/helpers/Env.js +28 -0
- package/dist/esm/src/helpers/cli/generateDreamContent.js +2 -1
- package/dist/esm/src/helpers/cli/generateFactoryContent.js +1 -1
- package/dist/esm/src/helpers/cli/generateMigrationContent.js +9 -9
- package/dist/esm/src/helpers/cli/generateSerializerContent.js +21 -8
- package/dist/esm/src/serializer/SerializerRenderer.js +65 -13
- package/dist/esm/src/serializer/builders/DreamSerializerBuilder.js +54 -38
- package/dist/esm/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
- package/dist/esm/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
- package/dist/types/src/Dream.d.ts +217 -55
- package/dist/types/src/bin/index.d.ts +7 -1
- package/dist/types/src/cli/index.d.ts +13 -0
- package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +2 -2
- package/dist/types/src/decorators/Decorators.d.ts +26 -3
- package/dist/types/src/decorators/field/Encrypted.d.ts +6 -1
- package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +9 -9
- package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +52 -25
- package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +4 -4
- package/dist/types/src/dream/LoadBuilder.d.ts +1 -1
- package/dist/types/src/dream/Query.d.ts +272 -33
- package/dist/types/src/dream/QueryDriver/Base.d.ts +63 -1
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +85 -1
- package/dist/types/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.d.ts +29 -0
- package/dist/types/src/dream-app/index.d.ts +56 -2
- package/dist/types/src/encrypt/InternalEncrypt.d.ts +20 -1
- package/dist/types/src/encrypt/defaultEncryptedColumnName.d.ts +7 -0
- package/dist/types/src/encrypt/index.d.ts +75 -6
- package/dist/types/src/errors/associations/UnrecognizedAssociationConditionKeys.d.ts +8 -0
- package/dist/types/src/helpers/Env.d.ts +28 -0
- package/dist/types/src/package-exports/openapi.d.ts +1 -1
- package/dist/types/src/package-exports/types.d.ts +2 -2
- package/dist/types/src/serializer/SerializerRenderer.d.ts +13 -0
- package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +59 -55
- package/dist/types/src/serializer/builders/ObjectSerializerBuilder.d.ts +40 -19
- package/dist/types/src/serializer/helpers/serializersForAssociatedClass.d.ts +17 -0
- package/dist/types/src/types/lifecycle.d.ts +6 -0
- package/dist/types/src/types/openapi.d.ts +52 -29
- package/dist/types/src/types/serializer.d.ts +43 -2
- package/dist/types/src/types/types/lifecycle.ts +6 -0
- package/dist/types/src/types/types/openapi.ts +51 -37
- package/dist/types/src/types/types/serializer.ts +62 -2
- package/dist/types/src/types/types/variadic.ts +99 -43
- package/dist/types/src/types/variadic.d.ts +29 -3
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/highlight.css +4 -11
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/db.DreamMigrationHelpers.html +13 -13
- package/docs/classes/db.KyselyQueryDriver.html +85 -46
- package/docs/classes/db.PostgresQueryDriver.html +86 -47
- package/docs/classes/db.QueryDriverBase.html +84 -45
- package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
- package/docs/classes/errors.CheckConstraintViolation.html +3 -3
- package/docs/classes/errors.ColumnOverflow.html +3 -3
- package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
- package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
- package/docs/classes/errors.DecryptionError.html +2 -2
- package/docs/classes/errors.DecryptionParseError.html +2 -2
- package/docs/classes/errors.DecryptionRotationError.html +3 -3
- package/docs/classes/errors.GlobalNameNotSet.html +3 -3
- package/docs/classes/errors.InvalidCalendarDate.html +2 -2
- package/docs/classes/errors.InvalidClockTime.html +2 -2
- package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
- package/docs/classes/errors.InvalidDateTime.html +2 -2
- package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
- package/docs/classes/errors.NonLoadedAssociation.html +3 -3
- package/docs/classes/errors.NotNullViolation.html +3 -3
- package/docs/classes/errors.RecordNotFound.html +3 -3
- package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
- package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
- package/docs/classes/errors.ValidationError.html +3 -3
- package/docs/classes/index.CalendarDate.html +33 -33
- package/docs/classes/index.ClockTime.html +32 -32
- package/docs/classes/index.ClockTimeTz.html +35 -35
- package/docs/classes/index.DateTime.html +86 -86
- package/docs/classes/index.Decorators.html +37 -23
- package/docs/classes/index.Dream.html +281 -155
- package/docs/classes/index.DreamApp.html +40 -10
- package/docs/classes/index.DreamTransaction.html +3 -3
- package/docs/classes/index.Env.html +16 -2
- package/docs/classes/index.Query.html +331 -129
- package/docs/classes/system.CliFileWriter.html +4 -4
- package/docs/classes/system.DreamBin.html +6 -2
- package/docs/classes/system.DreamCLI.html +7 -7
- package/docs/classes/system.DreamImporter.html +2 -2
- package/docs/classes/system.DreamLogos.html +2 -2
- package/docs/classes/system.DreamSerializerBuilder.html +52 -34
- package/docs/classes/system.ObjectSerializerBuilder.html +41 -22
- package/docs/classes/system.PathHelpers.html +4 -4
- package/docs/classes/utils.Encrypt.html +54 -10
- package/docs/classes/utils.Range.html +2 -2
- package/docs/functions/db.closeAllDbConnections.html +1 -1
- package/docs/functions/db.dreamDbConnections.html +1 -1
- package/docs/functions/db.untypedDb.html +1 -1
- package/docs/functions/db.validateColumn.html +1 -1
- package/docs/functions/db.validateTable.html +1 -1
- package/docs/functions/errors.pgErrorType.html +1 -1
- package/docs/functions/index.DreamSerializer.html +1 -1
- package/docs/functions/index.ObjectSerializer.html +1 -1
- package/docs/functions/index.ReplicaSafe.html +1 -1
- package/docs/functions/index.STI.html +1 -1
- package/docs/functions/index.SoftDelete.html +1 -1
- package/docs/functions/utils.camelize.html +1 -1
- package/docs/functions/utils.capitalize.html +1 -1
- package/docs/functions/utils.cloneDeepSafe.html +1 -1
- package/docs/functions/utils.compact.html +1 -1
- package/docs/functions/utils.groupBy.html +1 -1
- package/docs/functions/utils.hyphenize.html +1 -1
- package/docs/functions/utils.intersection.html +1 -1
- package/docs/functions/utils.isEmpty.html +1 -1
- package/docs/functions/utils.normalizeUnicode.html +1 -1
- package/docs/functions/utils.pascalize.html +1 -1
- package/docs/functions/utils.percent.html +1 -1
- package/docs/functions/utils.range.html +1 -1
- package/docs/functions/utils.round.html +1 -1
- package/docs/functions/utils.sanitizeString.html +1 -1
- package/docs/functions/utils.snakeify.html +1 -1
- package/docs/functions/utils.sort.html +1 -1
- package/docs/functions/utils.sortBy.html +1 -1
- package/docs/functions/utils.sortObjectByKey.html +1 -1
- package/docs/functions/utils.sortObjectByValue.html +1 -1
- package/docs/functions/utils.uncapitalize.html +1 -1
- package/docs/functions/utils.uniq.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +1 -1
- package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
- package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
- package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
- package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
- package/docs/interfaces/types.BelongsToStatement.html +2 -2
- package/docs/interfaces/types.DecoratorContext.html +2 -2
- package/docs/interfaces/types.DecryptCallbacks.html +6 -0
- package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
- package/docs/interfaces/types.DreamAppOpts.html +2 -2
- package/docs/interfaces/types.DreamDbConfig.html +6 -6
- package/docs/interfaces/types.DurationObject.html +2 -2
- package/docs/interfaces/types.EncryptOptions.html +2 -2
- package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +10 -0
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
- package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
- package/docs/modules/openapi.html +1 -1
- package/docs/modules/types.html +1 -1
- package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
- package/docs/types/openapi.OpenapiAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiFormats.html +1 -1
- package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +4 -0
- package/docs/types/openapi.OpenapiSchemaCommonFields.html +5 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -2
- package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -2
- package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -2
- package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
- package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
- package/docs/types/openapi.OpenapiSchemaNull.html +4 -2
- package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +5 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +2 -1
- package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
- package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaString.html +1 -1
- package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiTypeField.html +1 -1
- package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
- package/docs/types/types.CalendarDateDurationUnit.html +1 -1
- package/docs/types/types.CalendarDateObject.html +1 -1
- package/docs/types/types.Camelized.html +1 -1
- package/docs/types/types.ClockTimeObject.html +1 -1
- package/docs/types/types.DbConnectionType.html +1 -1
- package/docs/types/types.DbTypes.html +1 -1
- package/docs/types/types.DreamAssociationMetadata.html +1 -1
- package/docs/types/types.DreamAttributes.html +1 -1
- package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
- package/docs/types/types.DreamClassColumn.html +1 -1
- package/docs/types/types.DreamColumn.html +1 -1
- package/docs/types/types.DreamColumnNames.html +1 -1
- package/docs/types/types.DreamLogLevel.html +1 -1
- package/docs/types/types.DreamLogger.html +2 -2
- package/docs/types/types.DreamModelSerializerType.html +1 -1
- package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
- package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
- package/docs/types/types.DreamParamSafeAttributes.html +1 -1
- package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
- package/docs/types/types.DreamSerializable.html +1 -1
- package/docs/types/types.DreamSerializableArray.html +1 -1
- package/docs/types/types.DreamSerializerKey.html +1 -1
- package/docs/types/types.DreamSerializers.html +1 -1
- package/docs/types/types.DreamVirtualColumns.html +1 -1
- package/docs/types/types.DurationUnit.html +1 -1
- package/docs/types/types.EncryptAlgorithm.html +1 -1
- package/docs/types/types.HasManyStatement.html +1 -1
- package/docs/types/types.HasOneStatement.html +1 -1
- package/docs/types/types.Hyphenized.html +1 -1
- package/docs/types/types.Pascalized.html +1 -1
- package/docs/types/types.PrimaryKeyType.html +1 -1
- package/docs/types/types.RoundingPrecision.html +1 -1
- package/docs/types/types.SerializerCasing.html +1 -1
- package/docs/types/types.SimpleObjectSerializerType.html +1 -1
- package/docs/types/types.Snakeified.html +1 -1
- package/docs/types/types.StrictInterface.html +1 -1
- package/docs/types/types.UpdateableAssociationProperties.html +1 -1
- package/docs/types/types.UpdateableProperties.html +1 -1
- package/docs/types/types.ValidationType.html +1 -1
- package/docs/types/types.ViewModel.html +2 -2
- package/docs/types/types.ViewModelClass.html +1 -1
- package/docs/types/types.WeekdayName.html +1 -1
- package/docs/types/types.WhereStatementForDream.html +1 -1
- package/docs/types/types.WhereStatementForDreamClass.html +1 -1
- package/docs/variables/index.DreamConst.html +1 -1
- package/docs/variables/index.ops.html +1 -1
- package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
- package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
- package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
- package/docs/variables/system.primaryKeyTypes.html +1 -1
- package/package.json +1 -1
- package/dist/cjs/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
- package/dist/esm/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
- package/dist/types/src/serializer/helpers/serializerForAssociatedClass.d.ts +0 -9
- package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +0 -1
- package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +0 -1
- package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +0 -1
- package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +0 -1
|
@@ -177,6 +177,16 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
177
177
|
* The distinct column to apply to the Query
|
|
178
178
|
*/
|
|
179
179
|
private readonly distinctColumn;
|
|
180
|
+
/**
|
|
181
|
+
* @internal
|
|
182
|
+
*
|
|
183
|
+
* Whether the Query is ordered by its own order statements alone. The
|
|
184
|
+
* driver otherwise sorts by a similarity condition's rank, and by the
|
|
185
|
+
* declared `order` of the associations the Query is built on or joins,
|
|
186
|
+
* ahead of those statements. The keyset walks and cursor pagination set
|
|
187
|
+
* this, since their cursors compare only the Query's order statements.
|
|
188
|
+
*/
|
|
189
|
+
private readonly bypassImplicitOrder;
|
|
180
190
|
/**
|
|
181
191
|
* @internal
|
|
182
192
|
*
|
|
@@ -303,25 +313,49 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
303
313
|
*
|
|
304
314
|
* IMPORTANT: `findEach` always iterates in ascending primary key order.
|
|
305
315
|
* Any `order` applied to the Query is discarded; passing one has no effect
|
|
306
|
-
* on the order records are visited in.
|
|
316
|
+
* on the order records are visited in. The same goes for the `order` an
|
|
317
|
+
* association declares, when the Query is an `associationQuery` or joins
|
|
318
|
+
* that association, and for the relevance ranking of a similarity condition
|
|
319
|
+
* (`ops.similarity`, `ops.wordSimilarity`, `ops.strictWordSimilarity`),
|
|
320
|
+
* which still decides which records are visited, but not in what order.
|
|
321
|
+
* `findEach` visits the records {@link Query.all} returns: a Query that
|
|
322
|
+
* joins a HasOne or HasMany association (directly, through an association
|
|
323
|
+
* it joins, or as the association an `associationQuery` goes through)
|
|
324
|
+
* returns a record once for each row the join matches, and `findEach`
|
|
325
|
+
* visits it once for each of those rows, the rows of one record in
|
|
326
|
+
* ascending order of the joined rows' primary keys. Call `distinct()` to
|
|
327
|
+
* visit each record once.
|
|
307
328
|
*
|
|
308
329
|
* This is not a limitation that can be lifted. `findEach` guarantees that
|
|
309
|
-
* every matching
|
|
310
|
-
* paginating on a keyset: each batch selects the next `batchSize`
|
|
311
|
-
*
|
|
312
|
-
* That guarantee only holds over a stable,
|
|
313
|
-
* mutable, non-unique column would mean a record
|
|
314
|
-
* partway through the iteration could be skipped
|
|
315
|
-
* ({@link Query.cursorPaginate} can honor an
|
|
316
|
-
* because a paginated UI tolerates that anomaly;
|
|
330
|
+
* every matching row is visited exactly once, and it delivers that by
|
|
331
|
+
* paginating on a keyset: each batch selects the next `batchSize` rows
|
|
332
|
+
* whose primary keys (the record's, then the joined rows') sort after the
|
|
333
|
+
* last row of the previous batch. That guarantee only holds over a stable,
|
|
334
|
+
* unique key. Ordering by a mutable, non-unique column would mean a record
|
|
335
|
+
* whose sort value changed partway through the iteration could be skipped
|
|
336
|
+
* entirely or visited twice. ({@link Query.cursorPaginate} can honor an
|
|
337
|
+
* arbitrary order precisely because a paginated UI tolerates that anomaly;
|
|
338
|
+
* a full traversal cannot.)
|
|
339
|
+
*
|
|
340
|
+
* A Query that keeps one record of each group (one that calls `distinct`,
|
|
341
|
+
* or an `associationQuery` of an association that declares `distinct`, or
|
|
342
|
+
* a Query that joins one) cannot be paginated that way: its own `order`, or
|
|
343
|
+
* the association's, chooses which record of each group it returns, and a
|
|
344
|
+
* batch that narrowed it to the rows after the previous batch would let it
|
|
345
|
+
* choose another. So `findEach` reads the keys of all of its rows before
|
|
346
|
+
* visiting the first, and visits those whose rows still match when their
|
|
347
|
+
* batch is read. It visits the rows the Query returned when the walk began,
|
|
348
|
+
* less any destroyed or changed so that they no longer match the Query's
|
|
349
|
+
* conditions, and not a row the Query returns only after the walk began,
|
|
350
|
+
* such as the next record of a group whose record the callback destroyed.
|
|
317
351
|
*
|
|
318
352
|
* If you need records processed in a particular order, load them with a
|
|
319
353
|
* regular ordered query instead of `findEach`.
|
|
320
354
|
*
|
|
321
|
-
* A `limit` or `offset` on the Query cannot compose with the
|
|
322
|
-
*
|
|
355
|
+
* A `limit` or `offset` on the Query cannot compose with the batches —
|
|
356
|
+
* each batch re-applies the Query's conditions, so the limit would be
|
|
323
357
|
* silently replaced by `batchSize` and the offset re-applied to every
|
|
324
|
-
*
|
|
358
|
+
* batch — so a limit- or offset-carrying Query throws at runtime.
|
|
325
359
|
*
|
|
326
360
|
* @param cb - The callback to call for each found record
|
|
327
361
|
* @param __namedParameters - Options for batch processing
|
|
@@ -332,6 +366,80 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
332
366
|
findEach(this: Query<DreamInstance, QueryTypeOpts>, cb: (instance: DreamInstance) => void | Promise<void>, { batchSize }?: {
|
|
333
367
|
batchSize?: number;
|
|
334
368
|
}): Promise<void>;
|
|
369
|
+
/**
|
|
370
|
+
* @internal
|
|
371
|
+
*
|
|
372
|
+
* `findEach`, visiting each record once rather than once for each row a
|
|
373
|
+
* HasOne or HasMany join returns it in, for the operations that act on each
|
|
374
|
+
* record it visits (`destroy`, `reallyDestroy`, `undestroy` and `update`
|
|
375
|
+
* without `lock: true`).
|
|
376
|
+
*/
|
|
377
|
+
private findEachRecordOnce;
|
|
378
|
+
/**
|
|
379
|
+
* @internal
|
|
380
|
+
*
|
|
381
|
+
* Calls `cb` with the record of each row this Query returns, telling its
|
|
382
|
+
* rows apart by `rowKeyColumns` (see `walkRowBatches`).
|
|
383
|
+
*/
|
|
384
|
+
private findEachRow;
|
|
385
|
+
/**
|
|
386
|
+
* @internal
|
|
387
|
+
*
|
|
388
|
+
* The columns that tell apart the rows this Query returns: its primary key,
|
|
389
|
+
* then the primary keys of the rows HasOne and HasMany joins add (see
|
|
390
|
+
* `rowKeyColumnsOfJoinedRows`).
|
|
391
|
+
*/
|
|
392
|
+
private rowKeyColumns;
|
|
393
|
+
/**
|
|
394
|
+
* @internal
|
|
395
|
+
*
|
|
396
|
+
* A HasOne or HasMany join returns a record once for each row it matches,
|
|
397
|
+
* and the primary keys of the joined rows, with the Query's own, tell those
|
|
398
|
+
* rows apart. These are those primary keys, namespaced, other than the
|
|
399
|
+
* Query's own. A Query that calls `distinct` returns one row for each value
|
|
400
|
+
* of its distinct column rather than one for each row the join matches, so
|
|
401
|
+
* it has none.
|
|
402
|
+
*/
|
|
403
|
+
private rowKeyColumnsOfJoinedRows;
|
|
404
|
+
/**
|
|
405
|
+
* @internal
|
|
406
|
+
*
|
|
407
|
+
* Walks the rows this Query returns in batches, for `findEach` and
|
|
408
|
+
* `pluckEach`, and calls `visit` with what `readBatch` reads for each row,
|
|
409
|
+
* in ascending order of `rowKeyColumns`, the columns that tell its rows
|
|
410
|
+
* apart. `readBatch` reads a Query that returns a batch's rows, and returns
|
|
411
|
+
* each row's values of `rowKeyColumns` with what to visit for it, if
|
|
412
|
+
* anything. A row whose keys appear again in the same batch is visited once.
|
|
413
|
+
*
|
|
414
|
+
* A select that keeps one row of each group (DISTINCT ON) is walked from the
|
|
415
|
+
* keys of all of its rows, read before the first batch (see
|
|
416
|
+
* `walkRowBatchesFromKeys`); any other, by a cursor (see
|
|
417
|
+
* `walkRowBatchesByCursor`).
|
|
418
|
+
*/
|
|
419
|
+
private walkRowBatches;
|
|
420
|
+
/**
|
|
421
|
+
* @internal
|
|
422
|
+
*
|
|
423
|
+
* Walks the rows this Query returns in batches of the next `batchSize` rows
|
|
424
|
+
* after the last row of the batch before, compared on `rowKeyColumns` by a
|
|
425
|
+
* where clause, which every driver applies (see `walkRowBatches`).
|
|
426
|
+
*/
|
|
427
|
+
private walkRowBatchesByCursor;
|
|
428
|
+
/**
|
|
429
|
+
* @internal
|
|
430
|
+
*
|
|
431
|
+
* Walks a select that keeps one row of each group (DISTINCT ON), whose rows'
|
|
432
|
+
* values of `rowKeyColumns` are `distinctOnRowKeys`, read before the first
|
|
433
|
+
* batch (see `walkRowBatches`). Such a select cannot be walked by a cursor:
|
|
434
|
+
* narrowing it to the rows after the cursor before it chooses each group's
|
|
435
|
+
* row would let it choose a row it does not return. So each batch reads the
|
|
436
|
+
* rows of the next of those keys that still match, by their keys alone and
|
|
437
|
+
* unordered, since each group's row is chosen already, and puts them back
|
|
438
|
+
* in the order of those keys. The walk visits the rows the select returned
|
|
439
|
+
* when it began, less any destroyed or changed so that they no longer match;
|
|
440
|
+
* a row the select returns only after the walk began is not visited.
|
|
441
|
+
*/
|
|
442
|
+
private walkRowBatchesFromKeys;
|
|
335
443
|
/**
|
|
336
444
|
* Load each specified association using a single SQL query.
|
|
337
445
|
* See {@link Query.preload} for preloading in separate queries.
|
|
@@ -357,7 +465,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
357
465
|
*
|
|
358
466
|
*
|
|
359
467
|
* ```ts
|
|
360
|
-
* const posts = await user.associationQuery('posts').leftJoinPreload('comments', {
|
|
468
|
+
* const posts = await user.associationQuery('posts').leftJoinPreload('comments', { and: { visibility: 'public' } }, 'replies').all()
|
|
361
469
|
* console.log(posts[0].comments[0].replies[0])
|
|
362
470
|
* // [Reply{id: 1}, Reply{id: 2}]
|
|
363
471
|
* ```
|
|
@@ -365,7 +473,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
365
473
|
* @param args - A chain of association names and and/andNot/andAny clauses
|
|
366
474
|
* @returns A cloned Query with the joinLoad statement applied
|
|
367
475
|
*/
|
|
368
|
-
leftJoinPreload<Q extends Query<DreamInstance, any>, DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr>, Incompatible extends Q['queryTypeOpts'] extends Readonly<{
|
|
476
|
+
leftJoinPreload<Q extends Query<DreamInstance, any>, DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, Incompatible extends Q['queryTypeOpts'] extends Readonly<{
|
|
369
477
|
allowLeftJoinPreload: false;
|
|
370
478
|
}> ? true : false, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, Incompatible extends true ? [] : [...Arr, LastArg]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = Query<DreamInstance, ExtendQueryType<QueryTypeOpts, Readonly<{
|
|
371
479
|
joinedAssociations: JoinedAssociations;
|
|
@@ -379,7 +487,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
379
487
|
* See {@link Query.leftJoinPreload} for preloading in a single query.
|
|
380
488
|
*
|
|
381
489
|
* ```ts
|
|
382
|
-
* const user = await User.query().preload('posts', 'comments', {
|
|
490
|
+
* const user = await User.query().preload('posts', 'comments', { and: { visibility: 'public' } }, 'replies').first()
|
|
383
491
|
* console.log(user.posts[0].comments[0].replies[0])
|
|
384
492
|
* // [Reply{id: 1}, Reply{id: 2}]
|
|
385
493
|
* ```
|
|
@@ -450,7 +558,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
450
558
|
* @param args - A chain of association names and and/andNot/andAny clauses
|
|
451
559
|
* @returns A cloned Query with the joins clause applied
|
|
452
560
|
*/
|
|
453
|
-
innerJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
|
|
561
|
+
innerJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
|
|
454
562
|
...Arr,
|
|
455
563
|
LastArg
|
|
456
564
|
]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = Query<DreamInstance, ExtendQueryType<QueryTypeOpts, Readonly<{
|
|
@@ -462,7 +570,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
462
570
|
* @param args - A chain of association names and and/andNot/andAny clauses
|
|
463
571
|
* @returns A cloned Query with the joins clause applied
|
|
464
572
|
*/
|
|
465
|
-
leftJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
|
|
573
|
+
leftJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
|
|
466
574
|
...Arr,
|
|
467
575
|
LastArg
|
|
468
576
|
]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = Query<DreamInstance, ExtendQueryType<QueryTypeOpts, Readonly<{
|
|
@@ -1007,10 +1115,20 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1007
1115
|
* // 3
|
|
1008
1116
|
* ```
|
|
1009
1117
|
*
|
|
1010
|
-
*
|
|
1011
|
-
*
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1118
|
+
* `pluckEach` reads the rows {@link Query.findEach} visits, in the same
|
|
1119
|
+
* batches and the same order: ascending primary key, then, for a Query
|
|
1120
|
+
* that joins a HasOne or HasMany association, the joined rows' primary
|
|
1121
|
+
* keys, so each row the join returns is plucked once. Like `findEach`, it
|
|
1122
|
+
* discards the Query's `order`, an association's declared `order` and the
|
|
1123
|
+
* relevance ranking of a similarity condition, and it reads a Query that
|
|
1124
|
+
* keeps one record of each group (one that calls `distinct`, or over an
|
|
1125
|
+
* association that declares `distinct`) from the keys of all of its rows,
|
|
1126
|
+
* read before the first batch.
|
|
1127
|
+
*
|
|
1128
|
+
* A `limit` or `offset` on the Query cannot compose with the batches —
|
|
1129
|
+
* each batch re-applies the Query's conditions, so the limit would be
|
|
1130
|
+
* silently replaced by the batch size and the offset re-applied to every
|
|
1131
|
+
* batch — so a limit- or offset-carrying Query throws at runtime.
|
|
1014
1132
|
*
|
|
1015
1133
|
* @param args - a list of column names to pluck, followed by a callback function to call for each set of found fields
|
|
1016
1134
|
* @returns void
|
|
@@ -1077,6 +1195,13 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1077
1195
|
* // 2
|
|
1078
1196
|
* ```
|
|
1079
1197
|
*
|
|
1198
|
+
* Under a similarity condition (`ops.similarity`, `ops.wordSimilarity`,
|
|
1199
|
+
* `ops.strictWordSimilarity`), pages come best match first: records are
|
|
1200
|
+
* ordered by relevance ahead of the Query's `order` (or, without one, the
|
|
1201
|
+
* descending primary key). For best-match-first pages, use `paginate`
|
|
1202
|
+
* rather than {@link Query.cursorPaginate}, which does not order by
|
|
1203
|
+
* relevance.
|
|
1204
|
+
*
|
|
1080
1205
|
* @param opts - Pagination options
|
|
1081
1206
|
* @param opts.page - the page number that you want to fetch results for
|
|
1082
1207
|
* @param opts.pageSize - the number of results per page (optional)
|
|
@@ -1096,9 +1221,47 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1096
1221
|
* provides better performance for large datasets by using cursor-based
|
|
1097
1222
|
* pagination instead of offset-based pagination.
|
|
1098
1223
|
*
|
|
1099
|
-
*
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1224
|
+
* Pages follow the Query's `order`, preceded by the `order` declared on any
|
|
1225
|
+
* association the Query is built on or joins (so an `associationQuery` of
|
|
1226
|
+
* an ordered association pages in that association's order), with
|
|
1227
|
+
* ascending primary key as the final tiebreaker; with neither, pages run in
|
|
1228
|
+
* ascending primary key order. If those orders already include the primary
|
|
1229
|
+
* key (e.g.: `id: 'asc'`), the implicit primary key ordering is omitted.
|
|
1230
|
+
*
|
|
1231
|
+
* A Query that joins a HasOne or HasMany association (directly, through an
|
|
1232
|
+
* association it joins, or as the association an `associationQuery` goes
|
|
1233
|
+
* through) returns a record once for each row the join matches, as
|
|
1234
|
+
* {@link Query.all} does, and the pages return each of those rows once,
|
|
1235
|
+
* sorting the rows of one record by the joined rows' primary keys after the
|
|
1236
|
+
* primary key. The cursor of such a Query is an opaque string that names
|
|
1237
|
+
* its last row by primary keys, the record's and the joined rows' (readable
|
|
1238
|
+
* by whoever holds it; it is not encrypted), and the next page starts after
|
|
1239
|
+
* that row, or, if the row is gone, after the record's first row. Any other
|
|
1240
|
+
* Query's cursor is its last record's primary key. A record's primary key
|
|
1241
|
+
* is always accepted as a cursor: the next page starts after that record's
|
|
1242
|
+
* first row. A cursor carries no other value its row sorts by: those are
|
|
1243
|
+
* read from the database when the next page is.
|
|
1244
|
+
*
|
|
1245
|
+
* A Query that calls `distinct` on its primary key (as `distinct()` does,
|
|
1246
|
+
* e.g.: `User.innerJoin('posts').distinct()`) returns each record once, as
|
|
1247
|
+
* {@link Query.all} does, and so do its pages, whose cursor is the last
|
|
1248
|
+
* record's primary key. A Query that calls `distinct` on another column has
|
|
1249
|
+
* to be ordered by that column first (e.g.:
|
|
1250
|
+
* `Post.distinct('category').order({ category: 'asc', createdAt: 'desc' })`),
|
|
1251
|
+
* or the database rejects its pages. Its pages return the records
|
|
1252
|
+
* {@link Query.all} returns, the one its order keeps for each value of that
|
|
1253
|
+
* column (the newest post of each category), and its cursor is also the
|
|
1254
|
+
* last record's primary key. Over an association that declares `distinct`
|
|
1255
|
+
* and an `order` led by its distinct column (an `associationQuery` of it, or
|
|
1256
|
+
* a Query that joins it), the pages return the rows {@link Query.all}
|
|
1257
|
+
* returns: the row the association's `order` keeps for each value of its
|
|
1258
|
+
* distinct column.
|
|
1259
|
+
*
|
|
1260
|
+
* A similarity condition (`ops.similarity`, `ops.wordSimilarity`,
|
|
1261
|
+
* `ops.strictWordSimilarity`) still decides which records match, but its
|
|
1262
|
+
* relevance ranking does not order the pages: a cursor can only resume from
|
|
1263
|
+
* values it compares, and the rank is not one of them. For best-match-first
|
|
1264
|
+
* pages, use {@link Query.paginate}.
|
|
1102
1265
|
*
|
|
1103
1266
|
* ```ts
|
|
1104
1267
|
* // First page (using undefined to start from beginning)
|
|
@@ -1131,9 +1294,48 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1131
1294
|
* provides better performance for large datasets by using cursor-based
|
|
1132
1295
|
* pagination instead of offset-based pagination.
|
|
1133
1296
|
*
|
|
1134
|
-
*
|
|
1135
|
-
*
|
|
1136
|
-
*
|
|
1297
|
+
* Pages follow the Query's `order`, preceded by the `order` declared on any
|
|
1298
|
+
* association the Query is built on or joins (so an `associationQuery` of
|
|
1299
|
+
* an ordered association pages in that association's order), with
|
|
1300
|
+
* descending primary key as the final tiebreaker; with neither, pages run
|
|
1301
|
+
* in descending primary key order. If those orders already include the
|
|
1302
|
+
* primary key (e.g.: `id: 'asc'`), the implicit primary key ordering is
|
|
1303
|
+
* omitted.
|
|
1304
|
+
*
|
|
1305
|
+
* A Query that joins a HasOne or HasMany association (directly, through an
|
|
1306
|
+
* association it joins, or as the association an `associationQuery` goes
|
|
1307
|
+
* through) returns a record once for each row the join matches, as
|
|
1308
|
+
* {@link Query.all} does, and the pages return each of those rows once,
|
|
1309
|
+
* sorting the rows of one record by the joined rows' primary keys after the
|
|
1310
|
+
* primary key. The cursor of such a Query is an opaque string that names
|
|
1311
|
+
* its last row by primary keys, the record's and the joined rows' (readable
|
|
1312
|
+
* by whoever holds it; it is not encrypted), and the next page starts after
|
|
1313
|
+
* that row, or, if the row is gone, after the record's first row. Any other
|
|
1314
|
+
* Query's cursor is its last record's primary key. A record's primary key
|
|
1315
|
+
* is always accepted as a cursor: the next page starts after that record's
|
|
1316
|
+
* first row. A cursor carries no other value its row sorts by: those are
|
|
1317
|
+
* read from the database when the next page is.
|
|
1318
|
+
*
|
|
1319
|
+
* A Query that calls `distinct` on its primary key (as `distinct()` does,
|
|
1320
|
+
* e.g.: `User.innerJoin('posts').distinct()`) returns each record once, as
|
|
1321
|
+
* {@link Query.all} does, and so do its pages, whose cursor is the last
|
|
1322
|
+
* record's primary key. A Query that calls `distinct` on another column has
|
|
1323
|
+
* to be ordered by that column first (e.g.:
|
|
1324
|
+
* `Post.distinct('category').order({ category: 'asc', createdAt: 'desc' })`),
|
|
1325
|
+
* or the database rejects its pages. Its pages return the records
|
|
1326
|
+
* {@link Query.all} returns, the one its order keeps for each value of that
|
|
1327
|
+
* column (the newest post of each category), and its cursor is also the
|
|
1328
|
+
* last record's primary key. Over an association that declares `distinct`
|
|
1329
|
+
* and an `order` led by its distinct column (an `associationQuery` of it, or
|
|
1330
|
+
* a Query that joins it), the pages return the rows {@link Query.all}
|
|
1331
|
+
* returns: the row the association's `order` keeps for each value of its
|
|
1332
|
+
* distinct column.
|
|
1333
|
+
*
|
|
1334
|
+
* A similarity condition (`ops.similarity`, `ops.wordSimilarity`,
|
|
1335
|
+
* `ops.strictWordSimilarity`) still decides which records match, but its
|
|
1336
|
+
* relevance ranking does not order the pages: a cursor can only resume from
|
|
1337
|
+
* values it compares, and the rank is not one of them. For best-match-first
|
|
1338
|
+
* pages, use {@link Query.paginate}.
|
|
1137
1339
|
*
|
|
1138
1340
|
* ```ts
|
|
1139
1341
|
* // First page (using undefined to start from beginning)
|
|
@@ -1160,6 +1362,21 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1160
1362
|
cursorPaginate<Q extends Query<DreamInstance, any>, Incompatible extends Q['queryTypeOpts'] extends Readonly<{
|
|
1161
1363
|
allowPaginate: false;
|
|
1162
1364
|
}> ? true : false>(this: Q, opts: Incompatible extends true ? 'scrollPaginate is incompatible with limit, offset, and leftJoinPreload'[] : CursorPaginatedDreamQueryOptions): Promise<CursorPaginatedDreamQueryResult<DreamInstance>>;
|
|
1365
|
+
/**
|
|
1366
|
+
* @internal
|
|
1367
|
+
*
|
|
1368
|
+
* The values the row a cursor names sorts by now, in the order of
|
|
1369
|
+
* `orderStatements`, or undefined when no such row is found.
|
|
1370
|
+
*
|
|
1371
|
+
* Unless the primary key is the only order statement, the values are read
|
|
1372
|
+
* from the database, a soft-deleted record included, so that a page can
|
|
1373
|
+
* follow a record removed since the cursor was issued. A cursor that names its row by keys this Query's rows carry is
|
|
1374
|
+
* resumed from that row. Any other cursor (a primary key, as every cursor
|
|
1375
|
+
* issued before 2.36.0 is, or a cursor from a Query that joins other
|
|
1376
|
+
* associations), and a cursor whose row is gone, is resumed from the first
|
|
1377
|
+
* row of the record whose primary key it is or carries.
|
|
1378
|
+
*/
|
|
1379
|
+
private cursorBoundaryValues;
|
|
1163
1380
|
/**
|
|
1164
1381
|
* Forces use of a database connection (e.g. 'primary') during the query.
|
|
1165
1382
|
*
|
|
@@ -1700,12 +1917,32 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1700
1917
|
* record (`reload`, `associationQuery`, ...) likewise run on a separate
|
|
1701
1918
|
* connection and snapshot. Derive the attributes and return them; Dream
|
|
1702
1919
|
* performs the write inside the batch's transaction.
|
|
1703
|
-
* -
|
|
1704
|
-
*
|
|
1705
|
-
*
|
|
1706
|
-
*
|
|
1707
|
-
*
|
|
1708
|
-
*
|
|
1920
|
+
* - **Without `lock: true`, a record is not re-checked before it is
|
|
1921
|
+
* written.** The unlocked per-record paths — an attributes object without
|
|
1922
|
+
* `lock: true` or `skipHooks: true`, and a callback under `lock: false` —
|
|
1923
|
+
* read a batch, then write each record by its primary key alone, with no
|
|
1924
|
+
* compare-and-set. What a concurrent delete between that read and a
|
|
1925
|
+
* record's write does depends on what the delete leaves behind. A soft
|
|
1926
|
+
* delete (`destroy()` on a `@SoftDelete` model, which generated models are
|
|
1927
|
+
* by default) leaves the row in place, so the write lands on the
|
|
1928
|
+
* soft-deleted record: its update hooks run, it is counted, and its
|
|
1929
|
+
* `deletedAt` stays set. A hard delete (`reallyDestroy()`, a Query's
|
|
1930
|
+
* `delete()`, or `destroy()` on a model without `@SoftDelete`) removes the
|
|
1931
|
+
* row, so that record's write throws `CannotSaveMissingDream` — after its
|
|
1932
|
+
* `beforeUpdate` and `beforeSave` hooks have run — and the run rejects
|
|
1933
|
+
* without returning a count. Every record written before it, in its own
|
|
1934
|
+
* batch as well as earlier ones, stays committed, unless the Query carries
|
|
1935
|
+
* `.txn(txn)`, which puts those writes in the caller's transaction. (A
|
|
1936
|
+
* record whose write turns out to be a no-op emits no SQL, so it does not
|
|
1937
|
+
* throw even if its row is gone, and it is counted.) The single-statement
|
|
1938
|
+
* `skipHooks` attributes form is one `UPDATE ... WHERE` that carries the
|
|
1939
|
+
* Query's default scopes, so it never writes a soft-deleted record and
|
|
1940
|
+
* cannot fail part-way through. Use `lock: true` when deleters may race
|
|
1941
|
+
* the update: its locked re-read re-applies the Query's conditions and
|
|
1942
|
+
* default scopes, so a soft- or hard-deleted record drops out of the run,
|
|
1943
|
+
* neither written nor counted. (A Query that removes the
|
|
1944
|
+
* `dream:SoftDelete` default scope reads and writes soft-deleted records
|
|
1945
|
+
* on every path.)
|
|
1709
1946
|
* - **A `limit` or `offset` on the Query is incompatible with `update` on
|
|
1710
1947
|
* every path.** The batched paths re-apply the Query's conditions to each
|
|
1711
1948
|
* batch window, where a limit or offset would skip or truncate rows
|
|
@@ -1753,6 +1990,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
|
|
|
1753
1990
|
* @throws MissingRequiredLockOptionForUpdateCallback if a callback is passed without an options object carrying a boolean `lock`
|
|
1754
1991
|
* @throws BatchingIncompatibleWithLimitOrOffset if the query carries a `limit` or `offset`
|
|
1755
1992
|
* @throws CannotSetEncryptedColumnInQueryUpdate if the single-statement `skipHooks` form's attributes name an `@Encrypted` backing column with anything other than `null`
|
|
1993
|
+
* @throws CannotSaveMissingDream if, on an unlocked per-record path, a record's row is hard-deleted between its batch's read and a write that is not a no-op
|
|
1756
1994
|
*/
|
|
1757
1995
|
update(cb: (record: DreamInstance) => UpdateableProperties<DreamInstance> | undefined | Promise<UpdateableProperties<DreamInstance> | undefined>, options: {
|
|
1758
1996
|
lock: boolean;
|
|
@@ -1830,4 +2068,5 @@ export interface QueryOpts<DreamInstance extends Dream, ColumnType extends Dream
|
|
|
1830
2068
|
transaction?: DreamTransaction<Dream> | null | undefined;
|
|
1831
2069
|
connection?: DbConnectionType | undefined;
|
|
1832
2070
|
shouldReallyDestroy?: boolean | undefined;
|
|
2071
|
+
bypassImplicitOrder?: boolean | undefined;
|
|
1833
2072
|
}
|
|
@@ -2,7 +2,7 @@ import { CompiledQuery, DeleteQueryBuilder, SelectQueryBuilder, UpdateQueryBuild
|
|
|
2
2
|
import type { DreamDbConfig } from '../../dream-app/index.js';
|
|
3
3
|
import Dream from '../../Dream.js';
|
|
4
4
|
import { SchemaBuilderAssociationData, SchemaBuilderColumnData } from '../../helpers/cli/ASTBuilder.js';
|
|
5
|
-
import { AssociationStatement } from '../../types/associations/shared.js';
|
|
5
|
+
import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
|
|
6
6
|
import { DbConnectionType, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
|
|
7
7
|
import { DreamColumnNames, DreamConstructorType, DreamTableSchema } from '../../types/dream.js';
|
|
8
8
|
import { PreloadedDreamsAndWhatTheyPointTo, QueryToKyselyDBType, QueryToKyselyTableNamesType } from '../../types/query.js';
|
|
@@ -435,6 +435,68 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
|
|
|
435
435
|
* @returns An array of plucked values
|
|
436
436
|
*/
|
|
437
437
|
pluck(...fields: DreamColumnNames<DreamInstance>[]): Promise<any[]>;
|
|
438
|
+
/**
|
|
439
|
+
* @internal
|
|
440
|
+
*
|
|
441
|
+
* The order statements that the declared `order` of the associations the
|
|
442
|
+
* Query is built on or joins contributes to its ORDER BY, in the order they
|
|
443
|
+
* sort, each column namespaced by the alias it is read from. Cursor
|
|
444
|
+
* pagination folds these into its cursor.
|
|
445
|
+
*
|
|
446
|
+
* @returns An array of namespaced order statements
|
|
447
|
+
*/
|
|
448
|
+
associationOrderStatements(): OrderQueryStatement<string>[];
|
|
449
|
+
/**
|
|
450
|
+
* @internal
|
|
451
|
+
*
|
|
452
|
+
* The primary key of each table the Query reaches through a HasOne or
|
|
453
|
+
* HasMany association (one it joins, one an association it joins goes
|
|
454
|
+
* through, or one its association query is built on), namespaced by the
|
|
455
|
+
* alias it is read from, in join order. Such a join can return a row of the
|
|
456
|
+
* Query's table once for each row it matches, and these keys, with the
|
|
457
|
+
* Query's own primary key, tell those rows apart. Cursor pagination pages by
|
|
458
|
+
* them after the Query's own primary key.
|
|
459
|
+
*
|
|
460
|
+
* @returns An array of namespaced primary key columns
|
|
461
|
+
*/
|
|
462
|
+
joinedRowKeyColumns(): string[];
|
|
463
|
+
/**
|
|
464
|
+
* @internal
|
|
465
|
+
*
|
|
466
|
+
* A page of a select that keeps one row of each group (DISTINCT ON, as a
|
|
467
|
+
* Query that calls `distinct`, or an association that declares `distinct`,
|
|
468
|
+
* produces), or null for any other select, whose pages cursor pagination
|
|
469
|
+
* reads as it reads any select's.
|
|
470
|
+
*
|
|
471
|
+
* The page is the values of the Query's order statement columns for each
|
|
472
|
+
* row the select returns that matches any of `rowsAfter` (every row when it
|
|
473
|
+
* is null), sorted by the Query's order statements and limited by its
|
|
474
|
+
* limit. The select chooses each group's row before `rowsAfter` narrows the
|
|
475
|
+
* rows, so that the page holds only rows the select returns.
|
|
476
|
+
*
|
|
477
|
+
* A driver whose selects never keep one row of each group returns null.
|
|
478
|
+
*
|
|
479
|
+
* @param rowsAfter - where statements, any of which a row of the page matches
|
|
480
|
+
* @returns The page's rows, each an array of its order statement columns' values, or null
|
|
481
|
+
*/
|
|
482
|
+
pluckDistinctOnPage(rowsAfter: Record<string, unknown>[] | null): Promise<unknown[][] | null>;
|
|
483
|
+
/**
|
|
484
|
+
* @internal
|
|
485
|
+
*
|
|
486
|
+
* For a select that keeps one row of each group (DISTINCT ON, as a Query
|
|
487
|
+
* that calls `distinct`, or an association that declares `distinct`,
|
|
488
|
+
* produces), the values of `rowKeyColumns` for every row it returns, sorted
|
|
489
|
+
* by those columns, ascending; null for any other select. `findEach` and
|
|
490
|
+
* `pluckEach` read a select that keeps one row of each group from these
|
|
491
|
+
* keys rather than by a cursor, which would narrow the select before it
|
|
492
|
+
* chooses each group's row.
|
|
493
|
+
*
|
|
494
|
+
* A driver whose selects never keep one row of each group returns null.
|
|
495
|
+
*
|
|
496
|
+
* @param rowKeyColumns - the namespaced columns that tell the select's rows apart
|
|
497
|
+
* @returns The rows' values of `rowKeyColumns`, or null
|
|
498
|
+
*/
|
|
499
|
+
pluckDistinctOnRowKeys(rowKeyColumns: string[]): Promise<unknown[][] | null>;
|
|
438
500
|
/**
|
|
439
501
|
* Returns a new Kysely SelectQueryBuilder instance to be used
|
|
440
502
|
* in a sub Query
|
|
@@ -4,7 +4,7 @@ import { DialectProviderCb } from '../../db/DreamDbConnection.js';
|
|
|
4
4
|
import { DreamDbConfig } from '../../dream-app/index.js';
|
|
5
5
|
import Dream from '../../Dream.js';
|
|
6
6
|
import { SchemaBuilderInformationSchemaRow } from '../../helpers/cli/ASTBuilder.js';
|
|
7
|
-
import { AssociationStatement } from '../../types/associations/shared.js';
|
|
7
|
+
import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
|
|
8
8
|
import { DbConnectionType, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
|
|
9
9
|
import { DreamColumnNames, DreamTableSchema, OrderDir, SqlCommandType } from '../../types/dream.js';
|
|
10
10
|
import { PreloadedDreamsAndWhatTheyPointTo, QueryToKyselyDBType, QueryToKyselyTableNamesType } from '../../types/query.js';
|
|
@@ -12,6 +12,21 @@ import DreamTransaction from '../DreamTransaction.js';
|
|
|
12
12
|
import Query from '../Query.js';
|
|
13
13
|
import QueryDriverBase from './Base.js';
|
|
14
14
|
export default class KyselyQueryDriver<DreamInstance extends Dream> extends QueryDriverBase<DreamInstance> {
|
|
15
|
+
/**
|
|
16
|
+
* @internal
|
|
17
|
+
*
|
|
18
|
+
* While `associationOrderStatements` builds a select, the order statements
|
|
19
|
+
* that association joins add to it, in the order they are added.
|
|
20
|
+
*/
|
|
21
|
+
private associationOrderCollector;
|
|
22
|
+
/**
|
|
23
|
+
* @internal
|
|
24
|
+
*
|
|
25
|
+
* While `joinedRowKeyColumns` builds a select, the namespaced primary keys of
|
|
26
|
+
* the tables that HasOne and HasMany joins add to it, in the order they are
|
|
27
|
+
* added.
|
|
28
|
+
*/
|
|
29
|
+
private joinedRowKeyCollector;
|
|
15
30
|
dbFor(sqlCommandType: SqlCommandType): Kysely<DreamInstance['DB']> | KyselyTransaction<DreamInstance['DB']>;
|
|
16
31
|
static dbFor<I extends Dream>(connectionName: string, dbConnectionType: DbConnectionType, dreamTransaction?: DreamTransaction<I> | null): Kysely<I['DB']> | KyselyTransaction<I['DB']>;
|
|
17
32
|
static dialectProvider(connectionName: string, dbConnectionType: DbConnectionType): DialectProviderCb;
|
|
@@ -400,6 +415,75 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
|
|
|
400
415
|
}>;
|
|
401
416
|
private buildDelete;
|
|
402
417
|
private buildSelect;
|
|
418
|
+
/**
|
|
419
|
+
* @internal
|
|
420
|
+
*
|
|
421
|
+
* The select's source, joins, conditions, DISTINCT ON and similarity
|
|
422
|
+
* ranking, before the Query's own order statements, limit, offset and
|
|
423
|
+
* selection are applied, together with the connection the select runs on.
|
|
424
|
+
*/
|
|
425
|
+
private buildSelectCore;
|
|
426
|
+
/**
|
|
427
|
+
* @internal
|
|
428
|
+
*
|
|
429
|
+
* The order statements that the declared `order` of the associations the
|
|
430
|
+
* Query is built on or joins contributes to its ORDER BY, in the order they
|
|
431
|
+
* sort, each column namespaced by the alias it is read from. They are read
|
|
432
|
+
* off the same join code that emits them, by building the select.
|
|
433
|
+
*
|
|
434
|
+
* @returns An array of namespaced order statements
|
|
435
|
+
*/
|
|
436
|
+
associationOrderStatements(): OrderQueryStatement<string>[];
|
|
437
|
+
/**
|
|
438
|
+
* @internal
|
|
439
|
+
*
|
|
440
|
+
* The primary key of each table the Query reaches through a HasOne or
|
|
441
|
+
* HasMany association (one it joins, one an association it joins goes
|
|
442
|
+
* through, or one its association query is built on), namespaced by the
|
|
443
|
+
* alias it is read from, in join order. They are read off the same join code
|
|
444
|
+
* that emits the joins, by building the select.
|
|
445
|
+
*
|
|
446
|
+
* @returns An array of namespaced primary key columns
|
|
447
|
+
*/
|
|
448
|
+
joinedRowKeyColumns(): string[];
|
|
449
|
+
/**
|
|
450
|
+
* @internal
|
|
451
|
+
*
|
|
452
|
+
* A page of a select that carries DISTINCT ON (as a Query that calls
|
|
453
|
+
* `distinct`, or an association that declares `distinct`, produces), or null
|
|
454
|
+
* for any other select.
|
|
455
|
+
*
|
|
456
|
+
* Such a select keeps the row of each group that sorts first in its ORDER
|
|
457
|
+
* BY, so narrowing it to the rows after a cursor would let it keep a row it
|
|
458
|
+
* does not return (a group's later row, once the cursor has passed the
|
|
459
|
+
* group's first). It is read as a derived table instead, and narrowed to
|
|
460
|
+
* `rowsAfter`, sorted and limited outside it. The Query's order statements
|
|
461
|
+
* follow the select's own ORDER BY, if it has one, so that the select keeps
|
|
462
|
+
* the same row of each group every time it runs, and each of their columns
|
|
463
|
+
* is read out of it under a short alias (as `pluck` reads them), since a
|
|
464
|
+
* joined table's column cannot be named outside it.
|
|
465
|
+
*
|
|
466
|
+
* @param rowsAfter - where statements, any of which a row of the page matches
|
|
467
|
+
* @returns The page's rows, each an array of its order statement columns' values, or null
|
|
468
|
+
*/
|
|
469
|
+
pluckDistinctOnPage(rowsAfter: Record<string, unknown>[] | null): Promise<unknown[][] | null>;
|
|
470
|
+
/**
|
|
471
|
+
* @internal
|
|
472
|
+
*
|
|
473
|
+
* For a select that carries DISTINCT ON (as a Query that calls `distinct`,
|
|
474
|
+
* or an association that declares `distinct`, produces), the values of
|
|
475
|
+
* `rowKeyColumns` for every row it returns, sorted by those columns,
|
|
476
|
+
* ascending; null for any other select.
|
|
477
|
+
*
|
|
478
|
+
* The select runs as `all()` runs it, with its own ORDER BY choosing each
|
|
479
|
+
* group's row, and is read as a derived table, sorted outside it. Each of
|
|
480
|
+
* `rowKeyColumns` is read out of it under a short alias (as `pluck` reads
|
|
481
|
+
* them), since a joined table's column cannot be named outside it.
|
|
482
|
+
*
|
|
483
|
+
* @param rowKeyColumns - the namespaced columns that tell the select's rows apart
|
|
484
|
+
* @returns The rows' values of `rowKeyColumns`, or null
|
|
485
|
+
*/
|
|
486
|
+
pluckDistinctOnRowKeys(rowKeyColumns: string[]): Promise<unknown[][] | null>;
|
|
403
487
|
orderByDirection(direction: OrderDir | null): (obj: OrderByItemBuilder) => OrderByItemBuilder;
|
|
404
488
|
private buildUpdate;
|
|
405
489
|
/**
|
package/dist/types/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys a condition object on an association accepts, whether it is
|
|
3
|
+
* passed in a chain (`preload('posts', { and: { ... } })`), returned from a
|
|
4
|
+
* `preloadFor`/`loadFor` modifier, or passed to `associationQuery`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ASSOCIATION_CONDITION_KEYS: readonly ["and", "andNot", "andAny"];
|
|
7
|
+
/**
|
|
8
|
+
* The keys accepted by `destroyAssociation`, `reallyDestroyAssociation`
|
|
9
|
+
* and `undestroyAssociation`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DESTROY_ASSOCIATION_OPTION_KEYS: readonly ["and", "andNot", "andAny", "bypassAllDefaultScopes", "defaultScopesToBypass", "cascade", "skipHooks"];
|
|
12
|
+
/**
|
|
13
|
+
* The keys accepted by `updateAssociation`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const UPDATE_ASSOCIATION_OPTION_KEYS: readonly ["and", "andNot", "andAny", "bypassAllDefaultScopes", "defaultScopesToBypass", "skipHooks"];
|
|
16
|
+
/**
|
|
17
|
+
* Throws UnrecognizedAssociationConditionKeys when `value` is an object
|
|
18
|
+
* carrying any own key outside `acceptedKeys`, including a key whose value
|
|
19
|
+
* is `undefined`. Dream reads only the accepted keys, so an unrecognized key
|
|
20
|
+
* would otherwise be silently ignored (and, for the destroy family, act on
|
|
21
|
+
* every associated row instead of the ones the caller meant to select).
|
|
22
|
+
* Non-object values (`undefined`, `null`) pass through untouched.
|
|
23
|
+
*
|
|
24
|
+
* @param value - The condition object or options object to check
|
|
25
|
+
* @param acceptedKeys - The keys `value` may carry
|
|
26
|
+
* @param associationName - The association the object applies to, for the error message
|
|
27
|
+
* @param methodName - The public method the options were passed to, or null for a chain condition
|
|
28
|
+
*/
|
|
29
|
+
export default function assertRecognizedAssociationConditionKeys(value: unknown, acceptedKeys: readonly string[], associationName: string | number | symbol, methodName?: string | null): void;
|