From f633612427b30662034822e3ee6acb5e24818173 Mon Sep 17 00:00:00 2001 From: mertalev <101130780+mertalev@users.noreply.github.com> Date: Fri, 3 Apr 2026 01:55:41 -0400 Subject: [PATCH] update job queries --- server/src/queries/asset.job.repository.sql | 7 ++ server/src/queries/asset.repository.sql | 57 ++++++++---- .../src/repositories/asset-job.repository.ts | 7 ++ server/src/repositories/asset.repository.ts | 90 ++++++++++--------- 4 files changed, 99 insertions(+), 62 deletions(-) diff --git a/server/src/queries/asset.job.repository.sql b/server/src/queries/asset.job.repository.sql index ee80a6fb4f..9ce5a7518b 100644 --- a/server/src/queries/asset.job.repository.sql +++ b/server/src/queries/asset.job.repository.sql @@ -315,8 +315,10 @@ select "asset_exif"."lockedProperties" from "asset_exif" + inner join "asset" on "asset"."id" = "asset_exif"."assetId" where "asset_exif"."assetId" = $1 + and "asset"."status" != 'partial' -- AssetJobRepository.getAlbumThumbnailFiles select @@ -326,8 +328,10 @@ select "asset_file"."isEdited" from "asset_file" + inner join "asset" on "asset"."id" = "asset_file"."assetId" where "asset_file"."assetId" = $1 + and "asset"."status" != 'partial' and "asset_file"."type" = $2 -- AssetJobRepository.streamForSearchDuplicates @@ -454,6 +458,7 @@ from "asset" where "asset"."id" = $2 + and "asset"."status" != 'partial' -- AssetJobRepository.getForSyncAssets select @@ -467,6 +472,7 @@ from "asset" where "asset"."id" = any ($1::uuid[]) + and "asset"."status" != 'partial' -- AssetJobRepository.getForAssetDeletion select @@ -733,6 +739,7 @@ where "asset_job_status"."ocrAt" is null and "asset"."deletedAt" is null and "asset"."visibility" != $1 + and "asset"."status" != 'partial' -- AssetJobRepository.streamForMigrationJob select diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index 24234e127d..52045850ab 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -117,25 +117,44 @@ where and "ownerId" = $2 -- AssetRepository.setComplete -update "asset" as "complete_asset" -set - "status" = 'active', - "visibility" = case - when ( - "complete_asset"."type" = 'VIDEO' - and exists ( - select - from - "asset" - where - "complete_asset"."id" = "asset"."livePhotoVideoId" - ) - ) then 'hidden'::asset_visibility_enum - else 'timeline'::asset_visibility_enum - end -where - "id" = $1 - and "status" = 'partial' +with + "completed_asset" as ( + update "asset" as "complete_asset" + set + "status" = 'active', + "visibility" = case + when ( + "complete_asset"."type" = 'VIDEO' + and exists ( + select + from + "asset" + where + "complete_asset"."id" = "asset"."livePhotoVideoId" + ) + ) then 'hidden'::asset_visibility_enum + else 'timeline'::asset_visibility_enum + end + where + "id" = $1 + and "status" = 'partial' + returning + * + ), + "shared_link" as ( + insert into + "album_asset" ("albumId", "assetId") + select + $2 as "albumId", + "completed_asset"."id" + from + "completed_asset" + on conflict do nothing + ) +select + * +from + "completed_asset" -- AssetRepository.removeAndDecrementQuota with diff --git a/server/src/repositories/asset-job.repository.ts b/server/src/repositories/asset-job.repository.ts index 5aa9b78907..60ebda1774 100644 --- a/server/src/repositories/asset-job.repository.ts +++ b/server/src/repositories/asset-job.repository.ts @@ -160,8 +160,10 @@ export class AssetJobRepository { async getLockedPropertiesForMetadataExtraction(assetId: string) { return this.db .selectFrom('asset_exif') + .innerJoin('asset', 'asset.id', 'asset_exif.assetId') .select('asset_exif.lockedProperties') .where('asset_exif.assetId', '=', assetId) + .where('asset.status', '!=', sql.lit(AssetStatus.Partial)) .executeTakeFirst() .then((row) => row?.lockedProperties ?? []); } @@ -170,8 +172,10 @@ export class AssetJobRepository { getAlbumThumbnailFiles(id: string, fileType?: AssetFileType) { return this.db .selectFrom('asset_file') + .innerJoin('asset', 'asset.id', 'asset_file.assetId') .select(columns.assetFiles) .where('asset_file.assetId', '=', id) + .where('asset.status', '!=', sql.lit(AssetStatus.Partial)) .$if(!!fileType, (qb) => qb.where('asset_file.type', '=', fileType!)) .execute(); } @@ -250,6 +254,7 @@ export class AssetJobRepository { .selectFrom('asset') .select((eb) => ['asset.visibility', withFilePath(eb, AssetFileType.Preview).as('previewFile')]) .where('asset.id', '=', id) + .where('asset.status', '!=', sql.lit(AssetStatus.Partial)) .executeTakeFirst(); } @@ -266,6 +271,7 @@ export class AssetJobRepository { 'asset.fileModifiedAt', ]) .where('asset.id', '=', anyUuid(ids)) + .where('asset.status', '!=', sql.lit(AssetStatus.Partial)) .execute(); } @@ -464,6 +470,7 @@ export class AssetJobRepository { ) .where('asset.deletedAt', 'is', null) .where('asset.visibility', '!=', AssetVisibility.Hidden) + .where('asset.status', '!=', sql.lit(AssetStatus.Partial)) .stream(); } diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index 66f89588e7..7c9d6d5439 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -439,53 +439,57 @@ export class AssetRepository { .executeTakeFirst(); } - @GenerateSql({ params: [DummyValue.UUID] }) + @GenerateSql({ params: [DummyValue.UUID, { albumId: DummyValue.UUID, id: DummyValue.UUID }] }) setComplete(assetId: string, sharedLink?: { albumId?: string | null; id: string }) { - let query = this.db.with('completed_asset', (qb) => - qb - .updateTable('asset as complete_asset') - .set((eb) => ({ - status: sql.lit(AssetStatus.Active), - visibility: eb - .case() - .when( - eb.and([ - eb('complete_asset.type', '=', sql.lit(AssetType.Video)), - eb.exists(eb.selectFrom('asset').whereRef('complete_asset.id', '=', 'asset.livePhotoVideoId')), - ]), - ) - .then(sql`'hidden'::asset_visibility_enum`) - .else(sql`'timeline'::asset_visibility_enum`) - .end(), - })) - .where('id', '=', assetId) - .where('status', '=', sql.lit(AssetStatus.Partial)) - .returningAll(), - ); - - if (sharedLink?.albumId) { - (query as any) = query.with('shared_link', (qb) => - qb - .insertInto('album_asset') - .columns(['albumId', 'assetId']) - .expression((eb) => - eb.selectFrom('completed_asset').select([eb.val(sharedLink.albumId).as('albumId'), 'completed_asset.id']), + const completedAsset = this.db + .updateTable('asset as complete_asset') + .set((eb) => ({ + status: sql.lit(AssetStatus.Active), + visibility: eb + .case() + .when( + eb.and([ + eb('complete_asset.type', '=', sql.lit(AssetType.Video)), + eb.exists(eb.selectFrom('asset').whereRef('complete_asset.id', '=', 'asset.livePhotoVideoId')), + ]), ) - .onConflict((oc) => oc.doNothing()), - ); - } else if (sharedLink) { - (query as any) = query.with('shared_link', (qb) => - qb - .insertInto('shared_link_asset') - .columns(['sharedLinkId', 'assetId']) - .expression((eb) => - eb.selectFrom('completed_asset').select([eb.val(sharedLink.id).as('sharedLinkId'), 'completed_asset.id']), - ) - .onConflict((oc) => oc.doNothing()), - ); + .then(sql`'hidden'::asset_visibility_enum`) + .else(sql`'timeline'::asset_visibility_enum`) + .end(), + })) + .where('id', '=', assetId) + .where('status', '=', sql.lit(AssetStatus.Partial)) + .returningAll(); + if (!sharedLink) { + return completedAsset.executeTakeFirst(); } - return query.selectFrom('completed_asset').selectAll().executeTakeFirst(); + return this.db + .with('completed_asset', () => completedAsset) + .with('shared_link', (qb) => + sharedLink?.albumId + ? qb + .insertInto('album_asset') + .columns(['albumId', 'assetId']) + .expression((eb) => + eb + .selectFrom('completed_asset') + .select([eb.val(sharedLink.albumId).as('albumId'), 'completed_asset.id']), + ) + .onConflict((oc) => oc.doNothing()) + : qb + .insertInto('shared_link_asset') + .columns(['sharedLinkId', 'assetId']) + .expression((eb) => + eb + .selectFrom('completed_asset') + .select([eb.val(sharedLink.id).as('sharedLinkId'), 'completed_asset.id']), + ) + .onConflict((oc) => oc.doNothing()), + ) + .selectFrom('completed_asset') + .selectAll() + .executeTakeFirst(); } @GenerateSql({ params: [DummyValue.UUID] })