From 32dc64f5704d45b3819b9983b01bfbc7af1f26d4 Mon Sep 17 00:00:00 2001 From: Jonathan Jogenfors Date: Thu, 6 Feb 2025 00:14:25 +0100 Subject: [PATCH] Add placeholder type --- server/src/db.d.ts | 24 ----------- server/src/dtos/album.dto.ts | 4 +- server/src/dtos/asset-response.dto.ts | 10 ----- server/src/dtos/asset.dto.ts | 7 ---- server/src/entities/asset.entity.ts | 12 ++++-- server/src/queries/activity.repository.sql | 3 -- server/src/queries/album.repository.sql | 6 --- server/src/queries/asset.repository.sql | 21 +--------- server/src/queries/memory.repository.sql | 6 --- server/src/queries/person.repository.sql | 6 --- server/src/queries/search.repository.sql | 12 ------ server/src/queries/shared.link.repository.sql | 9 ---- server/src/queries/stack.repository.sql | 9 ---- server/src/queries/view.repository.sql | 6 +++ server/src/repositories/access.repository.ts | 28 ++----------- .../src/repositories/activity.repository.ts | 9 +--- server/src/repositories/album.repository.ts | 13 +----- server/src/repositories/asset.repository.ts | 41 +++++-------------- server/src/repositories/memory.repository.ts | 5 +-- server/src/repositories/person.repository.ts | 11 +---- server/src/repositories/search.repository.ts | 12 ------ .../repositories/shared-link.repository.ts | 9 ---- server/src/repositories/stack.repository.ts | 8 +--- server/src/repositories/view-repository.ts | 6 +++ .../src/services/asset-media.service.spec.ts | 8 ---- server/src/services/metadata.service.ts | 9 +++- .../services/storage-template.service.spec.ts | 8 ---- 27 files changed, 51 insertions(+), 251 deletions(-) diff --git a/server/src/db.d.ts b/server/src/db.d.ts index 76fe6a0ce3748..ebe96f148253a 100644 --- a/server/src/db.d.ts +++ b/server/src/db.d.ts @@ -214,20 +214,6 @@ export interface GeodataPlaces { name: string; } -export interface GeodataPlacesTmp { - admin1Code: string | null; - admin1Name: string | null; - admin2Code: string | null; - admin2Name: string | null; - alternateNames: string | null; - countryCode: string; - id: number; - latitude: number; - longitude: number; - modificationDate: Timestamp; - name: string; -} - export interface Libraries { createdAt: Generated; deletedAt: Timestamp | null; @@ -280,14 +266,6 @@ export interface NaturalearthCountries { type: string; } -export interface NaturalearthCountriesTmp { - admin: string; - admin_a3: string; - coordinates: string; - id: Generated; - type: string; -} - export interface Partners { createdAt: Generated; inTimeline: Generated; @@ -445,14 +423,12 @@ export interface DB { exif: Exif; face_search: FaceSearch; geodata_places: GeodataPlaces; - geodata_places_tmp: GeodataPlacesTmp; libraries: Libraries; memories: Memories; memories_assets_assets: MemoriesAssetsAssets; migrations: Migrations; move_history: MoveHistory; naturalearth_countries: NaturalearthCountries; - naturalearth_countries_tmp: NaturalearthCountriesTmp; partners: Partners; person: Person; sessions: Sessions; diff --git a/server/src/dtos/album.dto.ts b/server/src/dtos/album.dto.ts index c3658cf7cdf3d..14db0ab1e8e82 100644 --- a/server/src/dtos/album.dto.ts +++ b/server/src/dtos/album.dto.ts @@ -164,8 +164,8 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean, auth?: AuthDt const hasSharedLink = entity.sharedLinks?.length > 0; const hasSharedUser = sharedUsers.length > 0; - let startDate = assets.at(0)?.localDateTime || undefined; - let endDate = assets.at(-1)?.localDateTime || undefined; + let startDate = assets.at(0)?.localDateTime; + let endDate = assets.at(-1)?.localDateTime; // Swap dates if start date is greater than end date. if (startDate && endDate && startDate > endDate) { [startDate, endDate] = [endDate, startDate]; diff --git a/server/src/dtos/asset-response.dto.ts b/server/src/dtos/asset-response.dto.ts index 2a8cbbb426b77..9a963e1e98097 100644 --- a/server/src/dtos/asset-response.dto.ts +++ b/server/src/dtos/asset-response.dto.ts @@ -113,16 +113,6 @@ const hexOrBufferToBase64 = (encoded: string | Buffer) => { export function mapAsset(entity: AssetEntity, options: AssetMapOptions = {}): AssetResponseDto { const { stripMetadata = false, withStack = false } = options; - if (entity.localDateTime === null) { - throw new Error(`Asset ${entity.id} has no localDateTime`); - } - if (entity.fileCreatedAt === null) { - throw new Error(`Asset ${entity.id} has no fileCreatedAt`); - } - if (entity.fileModifiedAt === null) { - throw new Error(`Asset ${entity.id} has no fileModifiedAt`); - } - if (stripMetadata) { const sanitizedAssetResponse: SanitizedAssetResponseDto = { id: entity.id, diff --git a/server/src/dtos/asset.dto.ts b/server/src/dtos/asset.dto.ts index 25bb5f4f9eb02..8aa63f2f6924c 100644 --- a/server/src/dtos/asset.dto.ts +++ b/server/src/dtos/asset.dto.ts @@ -126,13 +126,6 @@ export class AssetStatsResponseDto { total!: number; } -export class AssetDatesDto { - dateTimeOriginal!: Date; - timeZone!: string | null; - localDateTime!: Date; - modifyDate!: Date; -} - export const mapStats = (stats: AssetStats): AssetStatsResponseDto => { return { images: stats[AssetType.IMAGE], diff --git a/server/src/entities/asset.entity.ts b/server/src/entities/asset.entity.ts index 742ff67b2d7e3..0677675fdd307 100644 --- a/server/src/entities/asset.entity.ts +++ b/server/src/entities/asset.entity.ts @@ -101,13 +101,13 @@ export class AssetEntity { @Index('idx_asset_file_created_at') @Column({ type: 'timestamptz', nullable: true, default: null }) - fileCreatedAt!: Date | null; + fileCreatedAt!: Date; @Column({ type: 'timestamptz', nullable: true, default: null }) - localDateTime!: Date | null; + localDateTime!: Date; @Column({ type: 'timestamptz', nullable: true, default: null }) - fileModifiedAt!: Date | null; + fileModifiedAt!: Date; @Column({ type: 'boolean', default: false }) isFavorite!: boolean; @@ -180,6 +180,12 @@ export class AssetEntity { duplicateId!: string | null; } +export type AssetEntityPlaceholder = AssetEntity & { + fileCreatedAt: Date | null; + fileModifiedAt: Date | null; + localDateTime: Date | null; +}; + export function withExif(qb: SelectQueryBuilder) { return qb.leftJoin('exif', 'assets.id', 'exif.assetId').select((eb) => eb.fn.toJson(eb.table('exif')).as('exifInfo')); } diff --git a/server/src/queries/activity.repository.sql b/server/src/queries/activity.repository.sql index 782d4fb160a30..0ddb91c6924e3 100644 --- a/server/src/queries/activity.repository.sql +++ b/server/src/queries/activity.repository.sql @@ -25,9 +25,6 @@ from "activity" left join "assets" on "assets"."id" = "activity"."assetId" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null where "activity"."albumId" = $1 order by diff --git a/server/src/queries/album.repository.sql b/server/src/queries/album.repository.sql index 77417ad3d5fdb..dbf27866be722 100644 --- a/server/src/queries/album.repository.sql +++ b/server/src/queries/album.repository.sql @@ -98,9 +98,6 @@ select where "albums_assets_assets"."albumsId" = "albums"."id" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null order by "assets"."fileCreatedAt" desc ) as "asset" @@ -215,9 +212,6 @@ from where "albums"."id" in ($1) and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null group by "albums"."id" diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index 11b5e56d5ae7e..bfaf5966cec0f 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -47,9 +47,6 @@ with and "asset_files"."type" = $6 ) and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null order by (assets."localDateTime" at time zone 'UTC')::date desc limit @@ -164,6 +161,7 @@ where and "isVisible" = $3 and "assets"."fileCreatedAt" is not null and "assets"."fileModifiedAt" is not null + and "assets"."localDateTime" is not null and "deletedAt" is null -- AssetRepository.getLivePhotoCount @@ -246,8 +244,6 @@ where "assets"."sidecarPath" = $1 or "assets"."sidecarPath" is null ) - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null and "assets"."isVisible" = $2 and "deletedAt" is null order by @@ -267,9 +263,6 @@ with where "assets"."deletedAt" is null and "assets"."isVisible" = $2 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null ) select "timeBucket", @@ -310,9 +303,6 @@ where ) and "assets"."deletedAt" is null and "assets"."isVisible" = $2 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and date_trunc($3, "localDateTime" at time zone 'UTC') at time zone 'UTC' = $4 order by "assets"."localDateTime" desc @@ -339,9 +329,6 @@ with and "assets"."duplicateId" is not null and "assets"."deletedAt" is null and "assets"."isVisible" = $2 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null group by "assets"."duplicateId" ), @@ -399,8 +386,6 @@ from where "ownerId" = $2::uuid and "isVisible" = $3 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null and "isArchived" = $4 and "type" = $5 and "deletedAt" is null @@ -430,8 +415,6 @@ from where "assets"."ownerId" = $1::uuid and "isVisible" = $2 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null and "updatedAt" <= $3 and "assets"."id" > $4 order by @@ -462,8 +445,6 @@ from where "assets"."ownerId" = any ($1::uuid[]) and "isVisible" = $2 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null and "updatedAt" > $3 limit $4 diff --git a/server/src/queries/memory.repository.sql b/server/src/queries/memory.repository.sql index 98b4b206dfe32..3144f314dde7b 100644 --- a/server/src/queries/memory.repository.sql +++ b/server/src/queries/memory.repository.sql @@ -26,9 +26,6 @@ select where "memories_assets_assets"."memoriesId" = "memories"."id" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null ) as agg ) as "assets" from @@ -59,9 +56,6 @@ select where "memories_assets_assets"."memoriesId" = "memories"."id" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null ) as agg ) as "assets" from diff --git a/server/src/queries/person.repository.sql b/server/src/queries/person.repository.sql index f89fe7b342e55..2c06d7c3f2c27 100644 --- a/server/src/queries/person.repository.sql +++ b/server/src/queries/person.repository.sql @@ -169,9 +169,6 @@ from and "asset_faces"."personId" = $1 and "assets"."isArchived" = $2 and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "assets"."livePhotoVideoId" is null -- PersonRepository.getNumberOfPeople @@ -186,9 +183,6 @@ from inner join "asset_faces" on "asset_faces"."personId" = "person"."id" inner join "assets" on "assets"."id" = "asset_faces"."assetId" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "assets"."isArchived" = $2 where "person"."ownerId" = $3 diff --git a/server/src/queries/search.repository.sql b/server/src/queries/search.repository.sql index ecc8df4e12135..9400700e56794 100644 --- a/server/src/queries/search.repository.sql +++ b/server/src/queries/search.repository.sql @@ -110,9 +110,6 @@ with "assets"."ownerId" = any ($2::uuid[]) and "assets"."deletedAt" is null and "assets"."isVisible" = $3 - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "assets"."type" = $4 and "assets"."id" != $5::uuid order by @@ -141,9 +138,6 @@ with where "assets"."ownerId" = any ($2::uuid[]) and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null order by face_search.embedding <=> $3 limit @@ -196,9 +190,6 @@ with recursive and "assets"."isArchived" = $3 and "assets"."type" = $4 and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null order by "city" limit @@ -224,9 +215,6 @@ with recursive and "assets"."isArchived" = $8 and "assets"."type" = $9 and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "exif"."city" > "cte"."city" order by "city" diff --git a/server/src/queries/shared.link.repository.sql b/server/src/queries/shared.link.repository.sql index 326d368dd2273..e1f6af33830f2 100644 --- a/server/src/queries/shared.link.repository.sql +++ b/server/src/queries/shared.link.repository.sql @@ -31,9 +31,6 @@ from where "shared_links"."id" = "shared_link__asset"."sharedLinksId" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null order by "assets"."fileCreatedAt" asc ) as "a" on true @@ -68,9 +65,6 @@ from where "albums_assets_assets"."assetsId" = "assets"."id" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null order by "assets"."fileCreatedAt" asc ) as "assets" on true @@ -119,9 +113,6 @@ from where "assets"."id" = "shared_link__asset"."assetsId" and "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null ) as "assets" on true left join lateral ( select diff --git a/server/src/queries/stack.repository.sql b/server/src/queries/stack.repository.sql index 8a95109f4d076..0fd1b233be413 100644 --- a/server/src/queries/stack.repository.sql +++ b/server/src/queries/stack.repository.sql @@ -23,9 +23,6 @@ select ) as "exifInfo" on true where "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "assets"."stackId" = "asset_stack"."id" ) as agg ) as "assets" @@ -71,9 +68,6 @@ select ) as "exifInfo" on true where "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "assets"."stackId" = "asset_stack"."id" ) as agg ) as "assets" @@ -119,9 +113,6 @@ select ) as "exifInfo" on true where "assets"."deletedAt" is null - and "assets"."fileCreatedAt" is not null - and "assets"."fileModifiedAt" is not null - and "assets"."localDateTime" is not null and "assets"."stackId" = "asset_stack"."id" ) as agg ) as "assets" diff --git a/server/src/queries/view.repository.sql b/server/src/queries/view.repository.sql index b368684caeb80..daa4159ea0477 100644 --- a/server/src/queries/view.repository.sql +++ b/server/src/queries/view.repository.sql @@ -10,6 +10,9 @@ where and "isVisible" = $3 and "isArchived" = $4 and "deletedAt" is null + and "fileModifiedAt" is not null + and "fileModifiedAt" is not null + and "localDateTime" is not null -- ViewRepository.getAssetsByOriginalPath select @@ -23,6 +26,9 @@ where and "isVisible" = $2 and "isArchived" = $3 and "deletedAt" is null + and "fileModifiedAt" is not null + and "fileModifiedAt" is not null + and "localDateTime" is not null and "originalPath" like $4 and "originalPath" not like $5 order by diff --git a/server/src/repositories/access.repository.ts b/server/src/repositories/access.repository.ts index ebee1194f16c3..9fa8b6243c892 100644 --- a/server/src/repositories/access.repository.ts +++ b/server/src/repositories/access.repository.ts @@ -138,12 +138,7 @@ class AssetAccess { .selectFrom('albums') .innerJoin('albums_assets_assets as albumAssets', 'albums.id', 'albumAssets.albumsId') .innerJoin('assets', (join) => - join - .onRef('assets.id', '=', 'albumAssets.assetsId') - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), + join.onRef('assets.id', '=', 'albumAssets.assetsId').on('assets.deletedAt', 'is', null), ) .leftJoin('albums_shared_users_users as albumUsers', 'albumUsers.albumsId', 'albums.id') .leftJoin('users', (join) => join.onRef('users.id', '=', 'albumUsers.usersId').on('users.deletedAt', 'is', null)) @@ -199,12 +194,7 @@ class AssetAccess { join.onRef('sharedBy.id', '=', 'partner.sharedById').on('sharedBy.deletedAt', 'is', null), ) .innerJoin('assets', (join) => - join - .onRef('assets.ownerId', '=', 'sharedBy.id') - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), + join.onRef('assets.ownerId', '=', 'sharedBy.id').on('assets.deletedAt', 'is', null), ) .select('assets.id') .where('partner.sharedWithId', '=', userId) @@ -228,12 +218,7 @@ class AssetAccess { ) .leftJoin('shared_link__asset', 'shared_link__asset.sharedLinksId', 'shared_links.id') .leftJoin('assets', (join) => - join - .onRef('assets.id', '=', 'shared_link__asset.assetsId') - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), + join.onRef('assets.id', '=', 'shared_link__asset.assetsId').on('assets.deletedAt', 'is', null), ) .leftJoin('albums_assets_assets', 'albums_assets_assets.albumsId', 'albums.id') .leftJoin('assets as albumAssets', (join) => @@ -384,12 +369,7 @@ class PersonAccess { .selectFrom('asset_faces') .select('asset_faces.id') .leftJoin('assets', (join) => - join - .onRef('assets.id', '=', 'asset_faces.assetId') - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), + join.onRef('assets.id', '=', 'asset_faces.assetId').on('assets.deletedAt', 'is', null), ) .where('asset_faces.id', 'in', [...assetFaceIds]) .where('assets.ownerId', '=', userId) diff --git a/server/src/repositories/activity.repository.ts b/server/src/repositories/activity.repository.ts index dd4fd41bc07ec..d998fea23cf3b 100644 --- a/server/src/repositories/activity.repository.ts +++ b/server/src/repositories/activity.repository.ts @@ -36,14 +36,7 @@ export class ActivityRepository { .selectFrom('activity') .selectAll('activity') .select(withUser) - .leftJoin('assets', (join) => - join - .onRef('assets.id', '=', 'activity.assetId') - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), - ) + .leftJoin('assets', (join) => join.onRef('assets.id', '=', 'activity.assetId').on('assets.deletedAt', 'is', null)) .$if(!!userId, (qb) => qb.where('activity.userId', '=', userId!)) .$if(assetId === null, (qb) => qb.where('assetId', 'is', null)) .$if(!!assetId, (qb) => qb.where('activity.assetId', '=', assetId!)) diff --git a/server/src/repositories/album.repository.ts b/server/src/repositories/album.repository.ts index f22d3a12727af..c09a13750e0c7 100644 --- a/server/src/repositories/album.repository.ts +++ b/server/src/repositories/album.repository.ts @@ -63,9 +63,6 @@ const withAssets = (eb: ExpressionBuilder) => { .innerJoin('albums_assets_assets', 'albums_assets_assets.assetsId', 'assets.id') .whereRef('albums_assets_assets.albumsId', '=', 'albums.id') .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .orderBy('assets.fileCreatedAt', 'desc') .as('asset'), ) @@ -135,9 +132,6 @@ export class AlbumRepository implements IAlbumRepository { .select((eb) => sql`${eb.fn.count('assets.id')}::int`.as('assetCount')) .where('albums.id', 'in', ids) .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .groupBy('albums.id') .execute(); } @@ -377,12 +371,7 @@ export class AlbumRepository implements IAlbumRepository { return eb .selectFrom('albums_assets_assets as album_assets') .innerJoin('assets', (join) => - join - .onRef('album_assets.assetsId', '=', 'assets.id') - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), + join.onRef('album_assets.assetsId', '=', 'assets.id').on('assets.deletedAt', 'is', null), ) .whereRef('album_assets.albumsId', '=', 'albums.id'); } diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index b6bbee83523c3..a65d5505967dd 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -7,6 +7,7 @@ import { AssetFiles, AssetJobStatus, Assets, DB, Exif } from 'src/db'; import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators'; import { AssetEntity, + AssetEntityPlaceholder, hasPeople, searchAssetBuilder, truncatedDate, @@ -79,8 +80,12 @@ export class AssetRepository implements IAssetRepository { .execute(); } - create(asset: Insertable): Promise { - return this.db.insertInto('assets').values(asset).returningAll().executeTakeFirst() as any as Promise; + create(asset: Insertable): Promise { + return this.db + .insertInto('assets') + .values(asset) + .returningAll() + .executeTakeFirst() as any as Promise; } @GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] }) @@ -121,9 +126,6 @@ export class AssetRepository implements IAssetRepository { ), ) .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .orderBy(sql`(assets."localDateTime" at time zone 'UTC')::date`, 'desc') .limit(20) .as('a'), @@ -296,6 +298,7 @@ export class AssetRepository implements IAssetRepository { .where('isVisible', '=', true) .where('assets.fileCreatedAt', 'is not', null) .where('assets.fileModifiedAt', 'is not', null) + .where('assets.localDateTime', 'is not', null) .where('deletedAt', 'is', null) .execute(); @@ -465,7 +468,8 @@ export class AssetRepository implements IAssetRepository { .where((eb) => eb.exists(eb.selectFrom('smart_search').where('assetId', '=', eb.ref('assets.id')))) .where('assets.isVisible', '=', true) .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null), + .where('assets.fileModifiedAt', 'is not', null) + .where('assets.localDateTime', 'is not', null), ) .$if(property === WithoutProperty.ENCODED_VIDEO, (qb) => qb @@ -483,23 +487,17 @@ export class AssetRepository implements IAssetRepository { .innerJoin('asset_job_status as job_status', 'assetId', 'assets.id') .where('job_status.previewAt', 'is not', null) .where('job_status.facesRecognizedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('assets.isVisible', '=', true), ) .$if(property === WithoutProperty.SIDECAR, (qb) => qb .where((eb) => eb.or([eb('assets.sidecarPath', '=', ''), eb('assets.sidecarPath', 'is', null)])) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('assets.isVisible', '=', true), ) .$if(property === WithoutProperty.SMART_SEARCH, (qb) => qb .innerJoin('asset_job_status as job_status', 'assetId', 'assets.id') .where('job_status.previewAt', 'is not', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('assets.isVisible', '=', true) .where((eb) => eb.not((eb) => eb.exists(eb.selectFrom('smart_search').whereRef('assetId', '=', 'assets.id'))), @@ -508,8 +506,6 @@ export class AssetRepository implements IAssetRepository { .$if(property === WithoutProperty.THUMBNAIL, (qb) => qb .innerJoin('asset_job_status as job_status', 'assetId', 'assets.id') - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('assets.isVisible', '=', true) .where((eb) => eb.or([ @@ -549,8 +545,6 @@ export class AssetRepository implements IAssetRepository { .where('ownerId', '=', anyUuid(ownerIds)) .where('latitude', 'is not', null) .where('longitude', 'is not', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('isVisible', '=', true) .where('deletedAt', 'is', null) .$if(!!isArchived, (qb) => qb.where('isArchived', '=', isArchived!)) @@ -571,6 +565,7 @@ export class AssetRepository implements IAssetRepository { .where('ownerId', '=', asUuid(ownerId)) .where('assets.fileCreatedAt', 'is not', null) .where('assets.fileModifiedAt', 'is not', null) + .where('assets.localDateTime', 'is not', null) .where('isVisible', '=', true) .$if(isArchived !== undefined, (qb) => qb.where('isArchived', '=', isArchived!)) .$if(isFavorite !== undefined, (qb) => qb.where('isFavorite', '=', isFavorite!)) @@ -586,8 +581,6 @@ export class AssetRepository implements IAssetRepository { .$call(withExif) .where('ownerId', '=', anyUuid(userIds)) .where('isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('deletedAt', 'is', null) .orderBy((eb) => eb.fn('random')) .limit(take) @@ -686,9 +679,6 @@ export class AssetRepository implements IAssetRepository { .$if(!!options.tagId, (qb) => withTagId(qb, options.tagId!)) .where('assets.deletedAt', options.isTrashed ? 'is not' : 'is', null) .where('assets.isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .where(truncatedDate(options.size), '=', timeBucket.replace(/^[+-]/, '')) .orderBy('assets.localDateTime', options.order ?? 'desc') .execute() as any as Promise; @@ -717,9 +707,6 @@ export class AssetRepository implements IAssetRepository { .where('assets.duplicateId', 'is not', null) .where('assets.deletedAt', 'is', null) .where('assets.isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .groupBy('assets.duplicateId'), ) .with('unique', (qb) => @@ -766,8 +753,6 @@ export class AssetRepository implements IAssetRepository { .select(['assetId as data', 'exif.city as value']) .where('ownerId', '=', asUuid(ownerId)) .where('isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('isArchived', '=', false) .where('type', '=', AssetType.IMAGE) .where('deletedAt', 'is', null) @@ -808,8 +793,6 @@ export class AssetRepository implements IAssetRepository { .select((eb) => eb.fn.toJson(eb.table('stacked_assets')).as('stack')) .where('assets.ownerId', '=', asUuid(ownerId)) .where('isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('updatedAt', '<=', updatedUntil) .$if(!!lastId, (qb) => qb.where('assets.id', '>', lastId!)) .orderBy('assets.id') @@ -838,8 +821,6 @@ export class AssetRepository implements IAssetRepository { .select((eb) => eb.fn.toJson(eb.table('stacked_assets')).as('stack')) .where('assets.ownerId', '=', anyUuid(options.userIds)) .where('isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) .where('updatedAt', '>', options.updatedAfter) .limit(options.limit) .execute() as any as Promise; diff --git a/server/src/repositories/memory.repository.ts b/server/src/repositories/memory.repository.ts index ba8b4eca68a9d..042738fe4c0f6 100644 --- a/server/src/repositories/memory.repository.ts +++ b/server/src/repositories/memory.repository.ts @@ -105,10 +105,7 @@ export class MemoryRepository implements IBulkAsset { .selectAll('assets') .innerJoin('memories_assets_assets', 'assets.id', 'memories_assets_assets.assetsId') .whereRef('memories_assets_assets.memoriesId', '=', 'memories.id') - .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null), + .where('assets.deletedAt', 'is', null), ).as('assets'), ) .where('id', '=', id) diff --git a/server/src/repositories/person.repository.ts b/server/src/repositories/person.repository.ts index 759c0d0def57d..73fb8313d299e 100644 --- a/server/src/repositories/person.repository.ts +++ b/server/src/repositories/person.repository.ts @@ -128,10 +128,7 @@ export class PersonRepository implements IPersonRepository { join .onRef('asset_faces.assetId', '=', 'assets.id') .on('assets.isArchived', '=', false) - .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null), + .on('assets.deletedAt', 'is', null), ) .where('person.ownerId', '=', userId) .orderBy('person.isHidden', 'asc') @@ -288,9 +285,6 @@ export class PersonRepository implements IPersonRepository { .on('asset_faces.personId', '=', personId) .on('assets.isArchived', '=', false) .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null) .on('assets.livePhotoVideoId', 'is', null), ) .select((eb) => eb.fn.count(eb.fn('distinct', ['assets.id'])).as('count')) @@ -311,9 +305,6 @@ export class PersonRepository implements IPersonRepository { join .onRef('assets.id', '=', 'asset_faces.assetId') .on('assets.deletedAt', 'is', null) - .on('assets.fileCreatedAt', 'is not', null) - .on('assets.fileModifiedAt', 'is not', null) - .on('assets.localDateTime', 'is not', null) .on('assets.isArchived', '=', false), ) .select((eb) => eb.fn.count(eb.fn('distinct', ['person.id'])).as('total')) diff --git a/server/src/repositories/search.repository.ts b/server/src/repositories/search.repository.ts index 613ab37629ae9..76b6653e3d73e 100644 --- a/server/src/repositories/search.repository.ts +++ b/server/src/repositories/search.repository.ts @@ -139,9 +139,6 @@ export class SearchRepository implements ISearchRepository { .where('assets.ownerId', '=', anyUuid(userIds)) .where('assets.deletedAt', 'is', null) .where('assets.isVisible', '=', true) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .where('assets.type', '=', type) .where('assets.id', '!=', asUuid(assetId)) .orderBy(sql`smart_search.embedding <=> ${embedding}`) @@ -181,9 +178,6 @@ export class SearchRepository implements ISearchRepository { .innerJoin('face_search', 'face_search.faceId', 'asset_faces.id') .where('assets.ownerId', '=', anyUuid(userIds)) .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .$if(!!hasPerson, (qb) => qb.where('asset_faces.personId', 'is not', null)) .orderBy(sql`face_search.embedding <=> ${embedding}`) .limit(numResults), @@ -234,9 +228,6 @@ export class SearchRepository implements ISearchRepository { .where('assets.isArchived', '=', false) .where('assets.type', '=', 'IMAGE') .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .orderBy('city') .limit(1); @@ -254,9 +245,6 @@ export class SearchRepository implements ISearchRepository { .where('assets.isArchived', '=', false) .where('assets.type', '=', 'IMAGE') .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .whereRef('exif.city', '>', 'cte.city') .orderBy('city') .limit(1) diff --git a/server/src/repositories/shared-link.repository.ts b/server/src/repositories/shared-link.repository.ts index d5f8aa796df50..3ffae4f0676ce 100644 --- a/server/src/repositories/shared-link.repository.ts +++ b/server/src/repositories/shared-link.repository.ts @@ -25,9 +25,6 @@ export class SharedLinkRepository implements ISharedLinkRepository { .whereRef('shared_links.id', '=', 'shared_link__asset.sharedLinksId') .innerJoin('assets', 'assets.id', 'shared_link__asset.assetsId') .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .selectAll('assets') .innerJoinLateral( (eb) => eb.selectFrom('exif').selectAll('exif').whereRef('exif.assetId', '=', 'assets.id').as('exifInfo'), @@ -53,9 +50,6 @@ export class SharedLinkRepository implements ISharedLinkRepository { .selectAll('assets') .whereRef('albums_assets_assets.assetsId', '=', 'assets.id') .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .innerJoinLateral( (eb) => eb @@ -112,9 +106,6 @@ export class SharedLinkRepository implements ISharedLinkRepository { .select((eb) => eb.fn.jsonAgg('assets').as('assets')) .whereRef('assets.id', '=', 'shared_link__asset.assetsId') .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .as('assets'), (join) => join.onTrue(), ) diff --git a/server/src/repositories/stack.repository.ts b/server/src/repositories/stack.repository.ts index 02bf5b9a66775..018d7e77a459a 100644 --- a/server/src/repositories/stack.repository.ts +++ b/server/src/repositories/stack.repository.ts @@ -30,9 +30,6 @@ const withAssets = (eb: ExpressionBuilder, withTags = false) ) .select((eb) => eb.fn.toJson('exifInfo').as('exifInfo')) .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null) .whereRef('assets.stackId', '=', 'asset_stack.id'), ).as('assets'); }; @@ -65,10 +62,7 @@ export class StackRepository implements IStackRepository { .selectFrom('assets') .select('assets.id') .whereRef('assets.stackId', '=', 'asset_stack.id') - .where('assets.deletedAt', 'is', null) - .where('assets.fileCreatedAt', 'is not', null) - .where('assets.fileModifiedAt', 'is not', null) - .where('assets.localDateTime', 'is not', null), + .where('assets.deletedAt', 'is', null), ).as('assets'), ) .execute(); diff --git a/server/src/repositories/view-repository.ts b/server/src/repositories/view-repository.ts index f24b1bac6e4d0..4fa670339e42a 100644 --- a/server/src/repositories/view-repository.ts +++ b/server/src/repositories/view-repository.ts @@ -18,6 +18,9 @@ export class ViewRepository { .where('isVisible', '=', true) .where('isArchived', '=', false) .where('deletedAt', 'is', null) + .where('fileModifiedAt', 'is not', null) + .where('fileModifiedAt', 'is not', null) + .where('localDateTime', 'is not', null) .execute(); return results.map((row) => row.directoryPath.replaceAll(/^\/|\/$/g, '')); @@ -35,6 +38,9 @@ export class ViewRepository { .where('isVisible', '=', true) .where('isArchived', '=', false) .where('deletedAt', 'is', null) + .where('fileModifiedAt', 'is not', null) + .where('fileModifiedAt', 'is not', null) + .where('localDateTime', 'is not', null) .where('originalPath', 'like', `%${normalizedPath}/%`) .where('originalPath', 'not like', `%${normalizedPath}/%/%`) .orderBy( diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index 8ee5889abee62..a581f36818d26 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -543,10 +543,6 @@ describe(AssetMediaService.name, () => { it('should throw an error if the requested preview file does not exist', async () => { accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set([assetStub.image.id])); - if (!assetStub.image.fileCreatedAt) { - throw new Error('fileCreatedAt is missing'); - } - assetMock.getById.mockResolvedValue({ ...assetStub.image, files: [ @@ -568,10 +564,6 @@ describe(AssetMediaService.name, () => { it('should fall back to preview if the requested thumbnail file does not exist', async () => { accessMock.asset.checkOwnerAccess.mockResolvedValue(new Set([assetStub.image.id])); - if (!assetStub.image.fileCreatedAt) { - throw new Error('fileCreatedAt is missing'); - } - assetMock.getById.mockResolvedValue({ ...assetStub.image, files: [ diff --git a/server/src/services/metadata.service.ts b/server/src/services/metadata.service.ts index 247c26831b45a..a060f45a3f5a3 100644 --- a/server/src/services/metadata.service.ts +++ b/server/src/services/metadata.service.ts @@ -10,7 +10,6 @@ import { SystemConfig } from 'src/config'; import { StorageCore } from 'src/cores/storage.core'; import { Exif } from 'src/db'; import { OnEvent, OnJob } from 'src/decorators'; -import { AssetDatesDto } from 'src/dtos/asset.dto'; import { AssetFaceEntity } from 'src/entities/asset-face.entity'; import { AssetEntity } from 'src/entities/asset.entity'; import { PersonEntity } from 'src/entities/person.entity'; @@ -38,6 +37,13 @@ const EXIF_DATE_TAGS: Array = [ 'DateTimeCreated', ]; +class AssetDatesDto { + dateTimeOriginal!: Date; + timeZone!: string | null; + localDateTime!: Date; + modifyDate!: Date; +} + const validate = (value: T): NonNullable | null => { // handle lists of numbers if (Array.isArray(value)) { @@ -460,7 +466,6 @@ export class MetadataService extends BaseService { } } else { const motionAssetId = this.cryptoRepository.randomUUID(); - const dates = this.getDates(asset, tags); motionAsset = await this.assetRepository.create({ id: motionAssetId, diff --git a/server/src/services/storage-template.service.spec.ts b/server/src/services/storage-template.service.spec.ts index 6f2a640b1fe79..46ec4f53e1531 100644 --- a/server/src/services/storage-template.service.spec.ts +++ b/server/src/services/storage-template.service.spec.ts @@ -179,10 +179,6 @@ describe(StorageTemplateService.name, () => { expect(await sut.handleMigrationSingle({ id: asset.id })).toBe(JobStatus.SUCCESS); - if (asset.fileCreatedAt == null) { - throw new Error('fileCreatedAt must be set'); - } - expect(moveMock.create).toHaveBeenCalledWith({ entityId: asset.id, newPath: `upload/library/${user.id}/${asset.fileCreatedAt.getFullYear()}/${album.albumName}/${asset.originalFileName}`, @@ -203,10 +199,6 @@ describe(StorageTemplateService.name, () => { expect(await sut.handleMigrationSingle({ id: asset.id })).toBe(JobStatus.SUCCESS); - if (asset.fileCreatedAt == null) { - throw new Error('fileCreatedAt must be set'); - } - const month = (asset.fileCreatedAt.getMonth() + 1).toString().padStart(2, '0'); expect(moveMock.create).toHaveBeenCalledWith({ entityId: asset.id,