From 7b40c20ea576cb881016da8020cd592ee37bbdf8 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Wed, 3 Jan 2024 23:32:52 -0500 Subject: [PATCH] chore(server): time bucket sql (#6156) --- server/src/infra/infra.util.ts | 1 + .../infra/repositories/asset.repository.ts | 2 + server/src/infra/sql/asset.repository.sql | 148 ++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/server/src/infra/infra.util.ts b/server/src/infra/infra.util.ts index 8b2cd7efa7..35ed7c4b4a 100644 --- a/server/src/infra/infra.util.ts +++ b/server/src/infra/infra.util.ts @@ -17,4 +17,5 @@ export const DummyValue = { STRING: 'abcdefghi', BUFFER: Buffer.from('abcdefghi'), DATE: new Date(), + TIME_BUCKET: '2024-01-01T00:00:00.000Z', }; diff --git a/server/src/infra/repositories/asset.repository.ts b/server/src/infra/repositories/asset.repository.ts index e56a2827bc..be6c0374ad 100644 --- a/server/src/infra/repositories/asset.repository.ts +++ b/server/src/infra/repositories/asset.repository.ts @@ -674,6 +674,7 @@ export class AssetRepository implements IAssetRepository { ); } + @GenerateSql({ params: [{ size: TimeBucketSize.MONTH }] }) getTimeBuckets(options: TimeBucketOptions): Promise { const truncated = dateTrunc(options); return this.getBuilder(options) @@ -684,6 +685,7 @@ export class AssetRepository implements IAssetRepository { .getRawMany(); } + @GenerateSql({ params: [DummyValue.TIME_BUCKET, { size: TimeBucketSize.MONTH }] }) getTimeBucket(timeBucket: string, options: TimeBucketOptions): Promise { const truncated = dateTrunc(options); return ( diff --git a/server/src/infra/sql/asset.repository.sql b/server/src/infra/sql/asset.repository.sql index 8a38c475e6..1c033ccb7d 100644 --- a/server/src/infra/sql/asset.repository.sql +++ b/server/src/infra/sql/asset.repository.sql @@ -607,6 +607,154 @@ ORDER BY LIMIT 11 +-- AssetRepository.getTimeBuckets +SELECT + COUNT("asset"."id")::int AS "count", + ( + date_trunc( + 'month', + (asset."localDateTime" at time zone 'UTC') + ) at time zone 'UTC' + )::timestamptz AS "timeBucket" +FROM + "assets" "asset" + LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "asset"."id" + LEFT JOIN "assets" "stack" ON "stack"."stackParentId" = "asset"."id" + AND ("stack"."deletedAt" IS NULL) +WHERE + ( + "asset"."isVisible" = true + AND "asset"."fileCreatedAt" < NOW() + ) + AND ("asset"."deletedAt" IS NULL) +GROUP BY + ( + date_trunc( + 'month', + (asset."localDateTime" at time zone 'UTC') + ) at time zone 'UTC' + )::timestamptz +ORDER BY + ( + date_trunc( + 'month', + (asset."localDateTime" at time zone 'UTC') + ) at time zone 'UTC' + )::timestamptz DESC + +-- AssetRepository.getTimeBucket +SELECT + "asset"."id" AS "asset_id", + "asset"."deviceAssetId" AS "asset_deviceAssetId", + "asset"."ownerId" AS "asset_ownerId", + "asset"."libraryId" AS "asset_libraryId", + "asset"."deviceId" AS "asset_deviceId", + "asset"."type" AS "asset_type", + "asset"."originalPath" AS "asset_originalPath", + "asset"."resizePath" AS "asset_resizePath", + "asset"."webpPath" AS "asset_webpPath", + "asset"."thumbhash" AS "asset_thumbhash", + "asset"."encodedVideoPath" AS "asset_encodedVideoPath", + "asset"."createdAt" AS "asset_createdAt", + "asset"."updatedAt" AS "asset_updatedAt", + "asset"."deletedAt" AS "asset_deletedAt", + "asset"."fileCreatedAt" AS "asset_fileCreatedAt", + "asset"."localDateTime" AS "asset_localDateTime", + "asset"."fileModifiedAt" AS "asset_fileModifiedAt", + "asset"."isFavorite" AS "asset_isFavorite", + "asset"."isArchived" AS "asset_isArchived", + "asset"."isExternal" AS "asset_isExternal", + "asset"."isReadOnly" AS "asset_isReadOnly", + "asset"."isOffline" AS "asset_isOffline", + "asset"."checksum" AS "asset_checksum", + "asset"."duration" AS "asset_duration", + "asset"."isVisible" AS "asset_isVisible", + "asset"."livePhotoVideoId" AS "asset_livePhotoVideoId", + "asset"."originalFileName" AS "asset_originalFileName", + "asset"."sidecarPath" AS "asset_sidecarPath", + "asset"."stackParentId" AS "asset_stackParentId", + "exifInfo"."assetId" AS "exifInfo_assetId", + "exifInfo"."description" AS "exifInfo_description", + "exifInfo"."exifImageWidth" AS "exifInfo_exifImageWidth", + "exifInfo"."exifImageHeight" AS "exifInfo_exifImageHeight", + "exifInfo"."fileSizeInByte" AS "exifInfo_fileSizeInByte", + "exifInfo"."orientation" AS "exifInfo_orientation", + "exifInfo"."dateTimeOriginal" AS "exifInfo_dateTimeOriginal", + "exifInfo"."modifyDate" AS "exifInfo_modifyDate", + "exifInfo"."timeZone" AS "exifInfo_timeZone", + "exifInfo"."latitude" AS "exifInfo_latitude", + "exifInfo"."longitude" AS "exifInfo_longitude", + "exifInfo"."projectionType" AS "exifInfo_projectionType", + "exifInfo"."city" AS "exifInfo_city", + "exifInfo"."livePhotoCID" AS "exifInfo_livePhotoCID", + "exifInfo"."state" AS "exifInfo_state", + "exifInfo"."country" AS "exifInfo_country", + "exifInfo"."make" AS "exifInfo_make", + "exifInfo"."model" AS "exifInfo_model", + "exifInfo"."lensModel" AS "exifInfo_lensModel", + "exifInfo"."fNumber" AS "exifInfo_fNumber", + "exifInfo"."focalLength" AS "exifInfo_focalLength", + "exifInfo"."iso" AS "exifInfo_iso", + "exifInfo"."exposureTime" AS "exifInfo_exposureTime", + "exifInfo"."profileDescription" AS "exifInfo_profileDescription", + "exifInfo"."colorspace" AS "exifInfo_colorspace", + "exifInfo"."bitsPerSample" AS "exifInfo_bitsPerSample", + "exifInfo"."fps" AS "exifInfo_fps", + "stack"."id" AS "stack_id", + "stack"."deviceAssetId" AS "stack_deviceAssetId", + "stack"."ownerId" AS "stack_ownerId", + "stack"."libraryId" AS "stack_libraryId", + "stack"."deviceId" AS "stack_deviceId", + "stack"."type" AS "stack_type", + "stack"."originalPath" AS "stack_originalPath", + "stack"."resizePath" AS "stack_resizePath", + "stack"."webpPath" AS "stack_webpPath", + "stack"."thumbhash" AS "stack_thumbhash", + "stack"."encodedVideoPath" AS "stack_encodedVideoPath", + "stack"."createdAt" AS "stack_createdAt", + "stack"."updatedAt" AS "stack_updatedAt", + "stack"."deletedAt" AS "stack_deletedAt", + "stack"."fileCreatedAt" AS "stack_fileCreatedAt", + "stack"."localDateTime" AS "stack_localDateTime", + "stack"."fileModifiedAt" AS "stack_fileModifiedAt", + "stack"."isFavorite" AS "stack_isFavorite", + "stack"."isArchived" AS "stack_isArchived", + "stack"."isExternal" AS "stack_isExternal", + "stack"."isReadOnly" AS "stack_isReadOnly", + "stack"."isOffline" AS "stack_isOffline", + "stack"."checksum" AS "stack_checksum", + "stack"."duration" AS "stack_duration", + "stack"."isVisible" AS "stack_isVisible", + "stack"."livePhotoVideoId" AS "stack_livePhotoVideoId", + "stack"."originalFileName" AS "stack_originalFileName", + "stack"."sidecarPath" AS "stack_sidecarPath", + "stack"."stackParentId" AS "stack_stackParentId" +FROM + "assets" "asset" + LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "asset"."id" + LEFT JOIN "assets" "stack" ON "stack"."stackParentId" = "asset"."id" + AND ("stack"."deletedAt" IS NULL) +WHERE + ( + "asset"."isVisible" = true + AND "asset"."fileCreatedAt" < NOW() + AND ( + date_trunc( + 'month', + (asset."localDateTime" at time zone 'UTC') + ) at time zone 'UTC' + )::timestamptz = $1 + ) + AND ("asset"."deletedAt" IS NULL) +ORDER BY + ( + date_trunc( + 'month', + (asset."localDateTime" at time zone 'UTC') + ) at time zone 'UTC' + )::timestamptz DESC, + "asset"."fileCreatedAt" DESC + -- AssetRepository.getAssetIdByCity WITH "cities" AS (