Skip to content

Commit

Permalink
chore: remove unused album repository methods (immich-app#12758)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 authored Sep 17, 2024
1 parent 1e6ef5c commit efe45fd
Show file tree
Hide file tree
Showing 12 changed files with 1 addition and 251 deletions.
3 changes: 0 additions & 3 deletions server/src/interfaces/album.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,15 @@ export interface AlbumInfoOptions {

export interface IAlbumRepository extends IBulkAsset {
getById(id: string, options: AlbumInfoOptions): Promise<AlbumEntity | null>;
getByIds(ids: string[]): Promise<AlbumEntity[]>;
getByAssetId(ownerId: string, assetId: string): Promise<AlbumEntity[]>;
removeAsset(assetId: string): Promise<void>;
getMetadataForIds(ids: string[]): Promise<AlbumAssetCount[]>;
getInvalidThumbnail(): Promise<string[]>;
getOwned(ownerId: string): Promise<AlbumEntity[]>;
getShared(ownerId: string): Promise<AlbumEntity[]>;
getNotShared(ownerId: string): Promise<AlbumEntity[]>;
restoreAll(userId: string): Promise<void>;
softDeleteAll(userId: string): Promise<void>;
deleteAll(userId: string): Promise<void>;
getAll(): Promise<AlbumEntity[]>;
create(album: Partial<AlbumEntity>): Promise<AlbumEntity>;
update(album: Partial<AlbumEntity>): Promise<AlbumEntity>;
delete(id: string): Promise<void>;
Expand Down
1 change: 0 additions & 1 deletion server/src/interfaces/asset.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ export interface IAssetRepository {
withDeleted?: boolean,
): Paginated<AssetEntity>;
getRandom(userIds: string[], count: number): Promise<AssetEntity[]>;
getFirstAssetForAlbumId(albumId: string): Promise<AssetEntity | null>;
getLastUpdatedAssetForAlbumId(albumId: string): Promise<AssetEntity | null>;
getExternalLibraryAssetPaths(pagination: PaginationOptions, libraryId: string): Paginated<AssetPathEntity>;
getByLibraryIdAndOriginalPath(libraryId: string, originalPath: string): Promise<AssetEntity | null>;
Expand Down
1 change: 0 additions & 1 deletion server/src/interfaces/job.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ export interface IJobRepository {
addHandler(queueName: QueueName, concurrency: number, handler: JobItemHandler): void;
addCronJob(name: string, expression: string, onTick: () => void, start?: boolean): void;
updateCronJob(name: string, expression?: string, start?: boolean): void;
deleteCronJob(name: string): void;
setConcurrency(queueName: QueueName, concurrency: number): void;
queue(item: JobItem): Promise<void>;
queueAll(items: JobItem[]): Promise<void>;
Expand Down
125 changes: 0 additions & 125 deletions server/src/queries/album.repository.sql
Original file line number Diff line number Diff line change
Expand Up @@ -82,66 +82,6 @@ ORDER BY
LIMIT
1

-- AlbumRepository.getByIds
SELECT
"AlbumEntity"."id" AS "AlbumEntity_id",
"AlbumEntity"."ownerId" AS "AlbumEntity_ownerId",
"AlbumEntity"."albumName" AS "AlbumEntity_albumName",
"AlbumEntity"."description" AS "AlbumEntity_description",
"AlbumEntity"."createdAt" AS "AlbumEntity_createdAt",
"AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt",
"AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt",
"AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId",
"AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled",
"AlbumEntity"."order" AS "AlbumEntity_order",
"AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id",
"AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name",
"AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin",
"AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email",
"AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel",
"AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId",
"AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath",
"AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword",
"AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt",
"AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt",
"AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status",
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt",
"AlbumEntity__AlbumEntity_albumUsers"."albumsId" AS "AlbumEntity__AlbumEntity_albumUsers_albumsId",
"AlbumEntity__AlbumEntity_albumUsers"."usersId" AS "AlbumEntity__AlbumEntity_albumUsers_usersId",
"AlbumEntity__AlbumEntity_albumUsers"."role" AS "AlbumEntity__AlbumEntity_albumUsers_role",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."id" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_id",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."name" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_name",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."isAdmin" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_isAdmin",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."email" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_email",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."storageLabel" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_storageLabel",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."oauthId" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_oauthId",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileImagePath" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileImagePath",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."shouldChangePassword" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_shouldChangePassword",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."createdAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_createdAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."deletedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_deletedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."status" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_status",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."updatedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_updatedAt",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaSizeInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaSizeInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."quotaUsageInBytes" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_quotaUsageInBytes",
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."profileChangedAt" AS "a641d58cf46d4a391ba060ac4dc337665c69ffea_profileChangedAt"
FROM
"albums" "AlbumEntity"
LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"
AND (
"AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL
)
LEFT JOIN "albums_shared_users_users" "AlbumEntity__AlbumEntity_albumUsers" ON "AlbumEntity__AlbumEntity_albumUsers"."albumsId" = "AlbumEntity"."id"
LEFT JOIN "users" "a641d58cf46d4a391ba060ac4dc337665c69ffea" ON "a641d58cf46d4a391ba060ac4dc337665c69ffea"."id" = "AlbumEntity__AlbumEntity_albumUsers"."usersId"
AND (
"a641d58cf46d4a391ba060ac4dc337665c69ffea"."deletedAt" IS NULL
)
WHERE
((("AlbumEntity"."id" IN ($1))))
AND ("AlbumEntity"."deletedAt" IS NULL)

-- AlbumRepository.getByAssetId
SELECT
"AlbumEntity"."id" AS "AlbumEntity_id",
Expand Down Expand Up @@ -247,35 +187,6 @@ WHERE
GROUP BY
"album"."id"

-- AlbumRepository.getInvalidThumbnail
SELECT
"albums"."id" AS "albums_id"
FROM
"albums" "albums"
WHERE
(
"albums"."albumThumbnailAssetId" IS NULL
AND EXISTS (
SELECT
1
FROM
"albums_assets_assets" "albums_assets"
WHERE
"albums"."id" = "albums_assets"."albumsId"
)
OR "albums"."albumThumbnailAssetId" IS NOT NULL
AND NOT EXISTS (
SELECT
1
FROM
"albums_assets_assets" "albums_assets"
WHERE
"albums"."id" = "albums_assets"."albumsId"
AND "albums"."albumThumbnailAssetId" = "albums_assets"."assetsId"
)
)
AND ("albums"."deletedAt" IS NULL)

-- AlbumRepository.getOwned
SELECT
"AlbumEntity"."id" AS "AlbumEntity_id",
Expand Down Expand Up @@ -539,42 +450,6 @@ WHERE
ORDER BY
"AlbumEntity"."createdAt" DESC

-- AlbumRepository.getAll
SELECT
"AlbumEntity"."id" AS "AlbumEntity_id",
"AlbumEntity"."ownerId" AS "AlbumEntity_ownerId",
"AlbumEntity"."albumName" AS "AlbumEntity_albumName",
"AlbumEntity"."description" AS "AlbumEntity_description",
"AlbumEntity"."createdAt" AS "AlbumEntity_createdAt",
"AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt",
"AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt",
"AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId",
"AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled",
"AlbumEntity"."order" AS "AlbumEntity_order",
"AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id",
"AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name",
"AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin",
"AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email",
"AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel",
"AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId",
"AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath",
"AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword",
"AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt",
"AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt",
"AlbumEntity__AlbumEntity_owner"."status" AS "AlbumEntity__AlbumEntity_owner_status",
"AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt",
"AlbumEntity__AlbumEntity_owner"."quotaSizeInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaSizeInBytes",
"AlbumEntity__AlbumEntity_owner"."quotaUsageInBytes" AS "AlbumEntity__AlbumEntity_owner_quotaUsageInBytes",
"AlbumEntity__AlbumEntity_owner"."profileChangedAt" AS "AlbumEntity__AlbumEntity_owner_profileChangedAt"
FROM
"albums" "AlbumEntity"
LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"
AND (
"AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL
)
WHERE
"AlbumEntity"."deletedAt" IS NULL

-- AlbumRepository.removeAsset
DELETE FROM "albums_assets_assets"
WHERE
Expand Down
53 changes: 0 additions & 53 deletions server/src/repositories/album.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,6 @@ export class AlbumRepository implements IAlbumRepository {
return withoutDeletedUsers(album);
}

@GenerateSql({ params: [[DummyValue.UUID]] })
@ChunkedArray()
async getByIds(ids: string[]): Promise<AlbumEntity[]> {
const albums = await this.repository.find({
where: {
id: In(ids),
},
relations: {
owner: true,
albumUsers: { user: true },
},
});

return albums.map((album) => withoutDeletedUsers(album));
}

@GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] })
async getByAssetId(ownerId: string, assetId: string): Promise<AlbumEntity[]> {
const albums = await this.repository.find({
Expand Down Expand Up @@ -116,34 +100,6 @@ export class AlbumRepository implements IAlbumRepository {
}));
}

/**
* Returns the album IDs that have an invalid thumbnail, when:
* - Thumbnail references an asset outside the album
* - Empty album still has a thumbnail set
*/
@GenerateSql()
async getInvalidThumbnail(): Promise<string[]> {
// Using dataSource, because there is no direct access to albums_assets_assets.
const albumHasAssets = this.dataSource
.createQueryBuilder()
.select('1')
.from('albums_assets_assets', 'albums_assets')
.where('"albums"."id" = "albums_assets"."albumsId"');

const albumContainsThumbnail = albumHasAssets
.clone()
.andWhere('"albums"."albumThumbnailAssetId" = "albums_assets"."assetsId"');

const albums = await this.repository
.createQueryBuilder('albums')
.select('albums.id')
.where(`"albums"."albumThumbnailAssetId" IS NULL AND EXISTS (${albumHasAssets.getQuery()})`)
.orWhere(`"albums"."albumThumbnailAssetId" IS NOT NULL AND NOT EXISTS (${albumContainsThumbnail.getQuery()})`)
.getMany();

return albums.map((album) => album.id);
}

@GenerateSql({ params: [DummyValue.UUID] })
async getOwned(ownerId: string): Promise<AlbumEntity[]> {
const albums = await this.repository.find({
Expand Down Expand Up @@ -199,15 +155,6 @@ export class AlbumRepository implements IAlbumRepository {
await this.repository.delete({ ownerId: userId });
}

@GenerateSql()
getAll(): Promise<AlbumEntity[]> {
return this.repository.find({
relations: {
owner: true,
},
});
}

@GenerateSql({ params: [DummyValue.UUID] })
async removeAsset(assetId: string): Promise<void> {
// Using dataSource, because there is no direct access to albums_assets_assets.
Expand Down
7 changes: 0 additions & 7 deletions server/src/repositories/asset.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,13 +571,6 @@ export class AssetRepository implements IAssetRepository {
});
}

getFirstAssetForAlbumId(albumId: string): Promise<AssetEntity | null> {
return this.repository.findOne({
where: { albums: { id: albumId } },
order: { fileCreatedAt: 'DESC' },
});
}

getLastUpdatedAssetForAlbumId(albumId: string): Promise<AssetEntity | null> {
return this.repository.findOne({
where: { albums: { id: albumId } },
Expand Down
4 changes: 0 additions & 4 deletions server/src/repositories/job.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,6 @@ export class JobRepository implements IJobRepository {
}
}

deleteCronJob(name: string): void {
this.schedulerReqistry.deleteCronJob(name);
}

setConcurrency(queueName: QueueName, concurrency: number) {
const worker = this.workers[queueName];
if (!worker) {
Expand Down
47 changes: 0 additions & 47 deletions server/src/services/album.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ describe(AlbumService.name, () => {
{ albumId: albumStub.empty.id, assetCount: 0, startDate: undefined, endDate: undefined },
{ albumId: albumStub.sharedWithUser.id, assetCount: 0, startDate: undefined, endDate: undefined },
]);
albumMock.getInvalidThumbnail.mockResolvedValue([]);

const result = await sut.getAll(authStub.admin, {});
expect(result).toHaveLength(2);
Expand All @@ -85,7 +84,6 @@ describe(AlbumService.name, () => {
endDate: new Date('1970-01-01'),
},
]);
albumMock.getInvalidThumbnail.mockResolvedValue([]);

const result = await sut.getAll(authStub.admin, { assetId: albumStub.oneAsset.id });
expect(result).toHaveLength(1);
Expand All @@ -98,7 +96,6 @@ describe(AlbumService.name, () => {
albumMock.getMetadataForIds.mockResolvedValue([
{ albumId: albumStub.sharedWithUser.id, assetCount: 0, startDate: undefined, endDate: undefined },
]);
albumMock.getInvalidThumbnail.mockResolvedValue([]);

const result = await sut.getAll(authStub.admin, { shared: true });
expect(result).toHaveLength(1);
Expand All @@ -111,7 +108,6 @@ describe(AlbumService.name, () => {
albumMock.getMetadataForIds.mockResolvedValue([
{ albumId: albumStub.empty.id, assetCount: 0, startDate: undefined, endDate: undefined },
]);
albumMock.getInvalidThumbnail.mockResolvedValue([]);

const result = await sut.getAll(authStub.admin, { shared: false });
expect(result).toHaveLength(1);
Expand All @@ -130,7 +126,6 @@ describe(AlbumService.name, () => {
endDate: new Date('1970-01-01'),
},
]);
albumMock.getInvalidThumbnail.mockResolvedValue([]);

const result = await sut.getAll(authStub.admin, {});

Expand All @@ -139,48 +134,6 @@ describe(AlbumService.name, () => {
expect(albumMock.getOwned).toHaveBeenCalledTimes(1);
});

it('updates the album thumbnail by listing all albums', async () => {
albumMock.getOwned.mockResolvedValue([albumStub.oneAssetInvalidThumbnail]);
albumMock.getMetadataForIds.mockResolvedValue([
{
albumId: albumStub.oneAssetInvalidThumbnail.id,
assetCount: 1,
startDate: new Date('1970-01-01'),
endDate: new Date('1970-01-01'),
},
]);
albumMock.getInvalidThumbnail.mockResolvedValue([albumStub.oneAssetInvalidThumbnail.id]);
albumMock.update.mockResolvedValue(albumStub.oneAssetValidThumbnail);
assetMock.getFirstAssetForAlbumId.mockResolvedValue(albumStub.oneAssetInvalidThumbnail.assets[0]);

const result = await sut.getAll(authStub.admin, {});

expect(result).toHaveLength(1);
expect(albumMock.getInvalidThumbnail).toHaveBeenCalledTimes(1);
expect(albumMock.update).toHaveBeenCalledTimes(1);
});

it('removes the thumbnail for an empty album', async () => {
albumMock.getOwned.mockResolvedValue([albumStub.emptyWithInvalidThumbnail]);
albumMock.getMetadataForIds.mockResolvedValue([
{
albumId: albumStub.emptyWithInvalidThumbnail.id,
assetCount: 1,
startDate: new Date('1970-01-01'),
endDate: new Date('1970-01-01'),
},
]);
albumMock.getInvalidThumbnail.mockResolvedValue([albumStub.emptyWithInvalidThumbnail.id]);
albumMock.update.mockResolvedValue(albumStub.emptyWithValidThumbnail);
assetMock.getFirstAssetForAlbumId.mockResolvedValue(null);

const result = await sut.getAll(authStub.admin, {});

expect(result).toHaveLength(1);
expect(albumMock.getInvalidThumbnail).toHaveBeenCalledTimes(1);
expect(albumMock.update).toHaveBeenCalledTimes(1);
});

describe('create', () => {
it('creates album', async () => {
albumMock.create.mockResolvedValue(albumStub.empty);
Expand Down
6 changes: 1 addition & 5 deletions server/src/services/album.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ export class AlbumService {
}

async getAll({ user: { id: ownerId } }: AuthDto, { assetId, shared }: GetAlbumsDto): Promise<AlbumResponseDto[]> {
const invalidAlbumIds = await this.albumRepository.getInvalidThumbnail();
for (const albumId of invalidAlbumIds) {
const newThumbnail = await this.assetRepository.getFirstAssetForAlbumId(albumId);
await this.albumRepository.update({ id: albumId, albumThumbnailAsset: newThumbnail });
}
await this.albumRepository.updateThumbnails();

let albums: AlbumEntity[];
if (assetId) {
Expand Down
3 changes: 0 additions & 3 deletions server/test/repositories/album.repository.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import { Mocked, vitest } from 'vitest';
export const newAlbumRepositoryMock = (): Mocked<IAlbumRepository> => {
return {
getById: vitest.fn(),
getByIds: vitest.fn(),
getByAssetId: vitest.fn(),
getMetadataForIds: vitest.fn(),
getInvalidThumbnail: vitest.fn(),
getOwned: vitest.fn(),
getShared: vitest.fn(),
getNotShared: vitest.fn(),
restoreAll: vitest.fn(),
softDeleteAll: vitest.fn(),
deleteAll: vitest.fn(),
getAll: vitest.fn(),
addAssetIds: vitest.fn(),
removeAsset: vitest.fn(),
removeAssetIds: vitest.fn(),
Expand Down
Loading

0 comments on commit efe45fd

Please sign in to comment.