mirror of
https://github.com/immich-app/immich.git
synced 2026-03-07 02:27:23 +03:00
feat: rename schema (#19891)
This commit is contained in:
@@ -21,47 +21,47 @@ export interface AlbumInfoOptions {
|
||||
withAssets: boolean;
|
||||
}
|
||||
|
||||
const withOwner = (eb: ExpressionBuilder<DB, 'albums'>) => {
|
||||
return jsonObjectFrom(eb.selectFrom('users').select(columns.user).whereRef('users.id', '=', 'albums.ownerId'))
|
||||
const withOwner = (eb: ExpressionBuilder<DB, 'album'>) => {
|
||||
return jsonObjectFrom(eb.selectFrom('user').select(columns.user).whereRef('user.id', '=', 'album.ownerId'))
|
||||
.$notNull()
|
||||
.as('owner');
|
||||
};
|
||||
|
||||
const withAlbumUsers = (eb: ExpressionBuilder<DB, 'albums'>) => {
|
||||
const withAlbumUsers = (eb: ExpressionBuilder<DB, 'album'>) => {
|
||||
return jsonArrayFrom(
|
||||
eb
|
||||
.selectFrom('albums_shared_users_users as album_users')
|
||||
.select('album_users.role')
|
||||
.selectFrom('album_user')
|
||||
.select('album_user.role')
|
||||
.select((eb) =>
|
||||
jsonObjectFrom(eb.selectFrom('users').select(columns.user).whereRef('users.id', '=', 'album_users.usersId'))
|
||||
jsonObjectFrom(eb.selectFrom('user').select(columns.user).whereRef('user.id', '=', 'album_user.usersId'))
|
||||
.$notNull()
|
||||
.as('user'),
|
||||
)
|
||||
.whereRef('album_users.albumsId', '=', 'albums.id'),
|
||||
.whereRef('album_user.albumsId', '=', 'album.id'),
|
||||
)
|
||||
.$notNull()
|
||||
.as('albumUsers');
|
||||
};
|
||||
|
||||
const withSharedLink = (eb: ExpressionBuilder<DB, 'albums'>) => {
|
||||
return jsonArrayFrom(eb.selectFrom('shared_links').selectAll().whereRef('shared_links.albumId', '=', 'albums.id')).as(
|
||||
const withSharedLink = (eb: ExpressionBuilder<DB, 'album'>) => {
|
||||
return jsonArrayFrom(eb.selectFrom('shared_link').selectAll().whereRef('shared_link.albumId', '=', 'album.id')).as(
|
||||
'sharedLinks',
|
||||
);
|
||||
};
|
||||
|
||||
const withAssets = (eb: ExpressionBuilder<DB, 'albums'>) => {
|
||||
const withAssets = (eb: ExpressionBuilder<DB, 'album'>) => {
|
||||
return eb
|
||||
.selectFrom((eb) =>
|
||||
eb
|
||||
.selectFrom('assets')
|
||||
.selectAll('assets')
|
||||
.leftJoin('exif', 'assets.id', 'exif.assetId')
|
||||
.select((eb) => eb.table('exif').$castTo<Exif>().as('exifInfo'))
|
||||
.innerJoin('albums_assets_assets', 'albums_assets_assets.assetsId', 'assets.id')
|
||||
.whereRef('albums_assets_assets.albumsId', '=', 'albums.id')
|
||||
.where('assets.deletedAt', 'is', null)
|
||||
.selectFrom('asset')
|
||||
.selectAll('asset')
|
||||
.leftJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
|
||||
.select((eb) => eb.table('asset_exif').$castTo<Exif>().as('exifInfo'))
|
||||
.innerJoin('album_asset', 'album_asset.assetsId', 'asset.id')
|
||||
.whereRef('album_asset.albumsId', '=', 'album.id')
|
||||
.where('asset.deletedAt', 'is', null)
|
||||
.$call(withDefaultVisibility)
|
||||
.orderBy('assets.fileCreatedAt', 'desc')
|
||||
.orderBy('asset.fileCreatedAt', 'desc')
|
||||
.as('asset'),
|
||||
)
|
||||
.select((eb) => eb.fn.jsonAgg('asset').as('assets'))
|
||||
@@ -75,10 +75,10 @@ export class AlbumRepository {
|
||||
@GenerateSql({ params: [DummyValue.UUID, { withAssets: true }] })
|
||||
async getById(id: string, options: AlbumInfoOptions) {
|
||||
return this.db
|
||||
.selectFrom('albums')
|
||||
.selectAll('albums')
|
||||
.where('albums.id', '=', id)
|
||||
.where('albums.deletedAt', 'is', null)
|
||||
.selectFrom('album')
|
||||
.selectAll('album')
|
||||
.where('album.id', '=', id)
|
||||
.where('album.deletedAt', 'is', null)
|
||||
.select(withOwner)
|
||||
.select(withAlbumUsers)
|
||||
.select(withSharedLink)
|
||||
@@ -90,26 +90,26 @@ export class AlbumRepository {
|
||||
@GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] })
|
||||
async getByAssetId(ownerId: string, assetId: string) {
|
||||
return this.db
|
||||
.selectFrom('albums')
|
||||
.selectAll('albums')
|
||||
.innerJoin('albums_assets_assets as album_assets', 'album_assets.albumsId', 'albums.id')
|
||||
.selectFrom('album')
|
||||
.selectAll('album')
|
||||
.innerJoin('album_asset', 'album_asset.albumsId', 'album.id')
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb('albums.ownerId', '=', ownerId),
|
||||
eb('album.ownerId', '=', ownerId),
|
||||
eb.exists(
|
||||
eb
|
||||
.selectFrom('albums_shared_users_users as album_users')
|
||||
.whereRef('album_users.albumsId', '=', 'albums.id')
|
||||
.where('album_users.usersId', '=', ownerId),
|
||||
.selectFrom('album_user')
|
||||
.whereRef('album_user.albumsId', '=', 'album.id')
|
||||
.where('album_user.usersId', '=', ownerId),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.where('album_assets.assetsId', '=', assetId)
|
||||
.where('albums.deletedAt', 'is', null)
|
||||
.orderBy('albums.createdAt', 'desc')
|
||||
.where('album_asset.assetsId', '=', assetId)
|
||||
.where('album.deletedAt', 'is', null)
|
||||
.orderBy('album.createdAt', 'desc')
|
||||
.select(withOwner)
|
||||
.select(withAlbumUsers)
|
||||
.orderBy('albums.createdAt', 'desc')
|
||||
.orderBy('album.createdAt', 'desc')
|
||||
.execute();
|
||||
}
|
||||
|
||||
@@ -123,18 +123,18 @@ export class AlbumRepository {
|
||||
|
||||
return (
|
||||
this.db
|
||||
.selectFrom('assets')
|
||||
.selectFrom('asset')
|
||||
.$call(withDefaultVisibility)
|
||||
.innerJoin('albums_assets_assets as album_assets', 'album_assets.assetsId', 'assets.id')
|
||||
.select('album_assets.albumsId as albumId')
|
||||
.select((eb) => eb.fn.min(sql<Date>`("assets"."localDateTime" AT TIME ZONE 'UTC'::text)::date`).as('startDate'))
|
||||
.select((eb) => eb.fn.max(sql<Date>`("assets"."localDateTime" AT TIME ZONE 'UTC'::text)::date`).as('endDate'))
|
||||
.innerJoin('album_asset', 'album_asset.assetsId', 'asset.id')
|
||||
.select('album_asset.albumsId as albumId')
|
||||
.select((eb) => eb.fn.min(sql<Date>`("asset"."localDateTime" AT TIME ZONE 'UTC'::text)::date`).as('startDate'))
|
||||
.select((eb) => eb.fn.max(sql<Date>`("asset"."localDateTime" AT TIME ZONE 'UTC'::text)::date`).as('endDate'))
|
||||
// lastModifiedAssetTimestamp is only used in mobile app, please remove if not need
|
||||
.select((eb) => eb.fn.max('assets.updatedAt').as('lastModifiedAssetTimestamp'))
|
||||
.select((eb) => sql<number>`${eb.fn.count('assets.id')}::int`.as('assetCount'))
|
||||
.where('album_assets.albumsId', 'in', ids)
|
||||
.where('assets.deletedAt', 'is', null)
|
||||
.groupBy('album_assets.albumsId')
|
||||
.select((eb) => eb.fn.max('asset.updatedAt').as('lastModifiedAssetTimestamp'))
|
||||
.select((eb) => sql<number>`${eb.fn.count('asset.id')}::int`.as('assetCount'))
|
||||
.where('album_asset.albumsId', 'in', ids)
|
||||
.where('asset.deletedAt', 'is', null)
|
||||
.groupBy('album_asset.albumsId')
|
||||
.execute()
|
||||
);
|
||||
}
|
||||
@@ -142,14 +142,14 @@ export class AlbumRepository {
|
||||
@GenerateSql({ params: [DummyValue.UUID] })
|
||||
async getOwned(ownerId: string) {
|
||||
return this.db
|
||||
.selectFrom('albums')
|
||||
.selectAll('albums')
|
||||
.selectFrom('album')
|
||||
.selectAll('album')
|
||||
.select(withOwner)
|
||||
.select(withAlbumUsers)
|
||||
.select(withSharedLink)
|
||||
.where('albums.ownerId', '=', ownerId)
|
||||
.where('albums.deletedAt', 'is', null)
|
||||
.orderBy('albums.createdAt', 'desc')
|
||||
.where('album.ownerId', '=', ownerId)
|
||||
.where('album.deletedAt', 'is', null)
|
||||
.orderBy('album.createdAt', 'desc')
|
||||
.execute();
|
||||
}
|
||||
|
||||
@@ -159,29 +159,29 @@ export class AlbumRepository {
|
||||
@GenerateSql({ params: [DummyValue.UUID] })
|
||||
async getShared(ownerId: string) {
|
||||
return this.db
|
||||
.selectFrom('albums')
|
||||
.selectAll('albums')
|
||||
.selectFrom('album')
|
||||
.selectAll('album')
|
||||
.where((eb) =>
|
||||
eb.or([
|
||||
eb.exists(
|
||||
eb
|
||||
.selectFrom('albums_shared_users_users as album_users')
|
||||
.whereRef('album_users.albumsId', '=', 'albums.id')
|
||||
.where((eb) => eb.or([eb('albums.ownerId', '=', ownerId), eb('album_users.usersId', '=', ownerId)])),
|
||||
.selectFrom('album_user')
|
||||
.whereRef('album_user.albumsId', '=', 'album.id')
|
||||
.where((eb) => eb.or([eb('album.ownerId', '=', ownerId), eb('album_user.usersId', '=', ownerId)])),
|
||||
),
|
||||
eb.exists(
|
||||
eb
|
||||
.selectFrom('shared_links')
|
||||
.whereRef('shared_links.albumId', '=', 'albums.id')
|
||||
.where('shared_links.userId', '=', ownerId),
|
||||
.selectFrom('shared_link')
|
||||
.whereRef('shared_link.albumId', '=', 'album.id')
|
||||
.where('shared_link.userId', '=', ownerId),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.where('albums.deletedAt', 'is', null)
|
||||
.where('album.deletedAt', 'is', null)
|
||||
.select(withAlbumUsers)
|
||||
.select(withOwner)
|
||||
.select(withSharedLink)
|
||||
.orderBy('albums.createdAt', 'desc')
|
||||
.orderBy('album.createdAt', 'desc')
|
||||
.execute();
|
||||
}
|
||||
|
||||
@@ -191,43 +191,33 @@ export class AlbumRepository {
|
||||
@GenerateSql({ params: [DummyValue.UUID] })
|
||||
async getNotShared(ownerId: string) {
|
||||
return this.db
|
||||
.selectFrom('albums')
|
||||
.selectAll('albums')
|
||||
.where('albums.ownerId', '=', ownerId)
|
||||
.where('albums.deletedAt', 'is', null)
|
||||
.where((eb) =>
|
||||
eb.not(
|
||||
eb.exists(
|
||||
eb
|
||||
.selectFrom('albums_shared_users_users as album_users')
|
||||
.whereRef('album_users.albumsId', '=', 'albums.id'),
|
||||
),
|
||||
),
|
||||
)
|
||||
.where((eb) =>
|
||||
eb.not(eb.exists(eb.selectFrom('shared_links').whereRef('shared_links.albumId', '=', 'albums.id'))),
|
||||
)
|
||||
.selectFrom('album')
|
||||
.selectAll('album')
|
||||
.where('album.ownerId', '=', ownerId)
|
||||
.where('album.deletedAt', 'is', null)
|
||||
.where((eb) => eb.not(eb.exists(eb.selectFrom('album_user').whereRef('album_user.albumsId', '=', 'album.id'))))
|
||||
.where((eb) => eb.not(eb.exists(eb.selectFrom('shared_link').whereRef('shared_link.albumId', '=', 'album.id'))))
|
||||
.select(withOwner)
|
||||
.orderBy('albums.createdAt', 'desc')
|
||||
.orderBy('album.createdAt', 'desc')
|
||||
.execute();
|
||||
}
|
||||
|
||||
async restoreAll(userId: string): Promise<void> {
|
||||
await this.db.updateTable('albums').set({ deletedAt: null }).where('ownerId', '=', userId).execute();
|
||||
await this.db.updateTable('album').set({ deletedAt: null }).where('ownerId', '=', userId).execute();
|
||||
}
|
||||
|
||||
async softDeleteAll(userId: string): Promise<void> {
|
||||
await this.db.updateTable('albums').set({ deletedAt: new Date() }).where('ownerId', '=', userId).execute();
|
||||
await this.db.updateTable('album').set({ deletedAt: new Date() }).where('ownerId', '=', userId).execute();
|
||||
}
|
||||
|
||||
async deleteAll(userId: string): Promise<void> {
|
||||
await this.db.deleteFrom('albums').where('ownerId', '=', userId).execute();
|
||||
await this.db.deleteFrom('album').where('ownerId', '=', userId).execute();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [[DummyValue.UUID]] })
|
||||
@Chunked()
|
||||
async removeAssetsFromAll(assetIds: string[]): Promise<void> {
|
||||
await this.db.deleteFrom('albums_assets_assets').where('albums_assets_assets.assetsId', 'in', assetIds).execute();
|
||||
await this.db.deleteFrom('album_asset').where('album_asset.assetsId', 'in', assetIds).execute();
|
||||
}
|
||||
|
||||
@Chunked({ paramIndex: 1 })
|
||||
@@ -237,9 +227,9 @@ export class AlbumRepository {
|
||||
}
|
||||
|
||||
await this.db
|
||||
.deleteFrom('albums_assets_assets')
|
||||
.where('albums_assets_assets.albumsId', '=', albumId)
|
||||
.where('albums_assets_assets.assetsId', 'in', assetIds)
|
||||
.deleteFrom('album_asset')
|
||||
.where('album_asset.albumsId', '=', albumId)
|
||||
.where('album_asset.assetsId', 'in', assetIds)
|
||||
.execute();
|
||||
}
|
||||
|
||||
@@ -258,10 +248,10 @@ export class AlbumRepository {
|
||||
}
|
||||
|
||||
return this.db
|
||||
.selectFrom('albums_assets_assets')
|
||||
.selectFrom('album_asset')
|
||||
.selectAll()
|
||||
.where('albums_assets_assets.albumsId', '=', albumId)
|
||||
.where('albums_assets_assets.assetsId', 'in', assetIds)
|
||||
.where('album_asset.albumsId', '=', albumId)
|
||||
.where('album_asset.assetsId', 'in', assetIds)
|
||||
.execute()
|
||||
.then((results) => new Set(results.map(({ assetsId }) => assetsId)));
|
||||
}
|
||||
@@ -272,7 +262,7 @@ export class AlbumRepository {
|
||||
|
||||
create(album: Insertable<AlbumTable>, assetIds: string[], albumUsers: AlbumUserCreateDto[]) {
|
||||
return this.db.transaction().execute(async (tx) => {
|
||||
const newAlbum = await tx.insertInto('albums').values(album).returning('albums.id').executeTakeFirst();
|
||||
const newAlbum = await tx.insertInto('album').values(album).returning('album.id').executeTakeFirst();
|
||||
|
||||
if (!newAlbum) {
|
||||
throw new Error('Failed to create album');
|
||||
@@ -284,7 +274,7 @@ export class AlbumRepository {
|
||||
|
||||
if (albumUsers.length > 0) {
|
||||
await tx
|
||||
.insertInto('albums_shared_users_users')
|
||||
.insertInto('album_user')
|
||||
.values(
|
||||
albumUsers.map((albumUser) => ({ albumsId: newAlbum.id, usersId: albumUser.userId, role: albumUser.role })),
|
||||
)
|
||||
@@ -292,7 +282,7 @@ export class AlbumRepository {
|
||||
}
|
||||
|
||||
return tx
|
||||
.selectFrom('albums')
|
||||
.selectFrom('album')
|
||||
.selectAll()
|
||||
.where('id', '=', newAlbum.id)
|
||||
.select(withOwner)
|
||||
@@ -305,10 +295,10 @@ export class AlbumRepository {
|
||||
|
||||
update(id: string, album: Updateable<AlbumTable>) {
|
||||
return this.db
|
||||
.updateTable('albums')
|
||||
.updateTable('album')
|
||||
.set(album)
|
||||
.where('id', '=', id)
|
||||
.returningAll('albums')
|
||||
.returningAll('album')
|
||||
.returning(withOwner)
|
||||
.returning(withSharedLink)
|
||||
.returning(withAlbumUsers)
|
||||
@@ -316,7 +306,7 @@ export class AlbumRepository {
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<void> {
|
||||
await this.db.deleteFrom('albums').where('id', '=', id).execute();
|
||||
await this.db.deleteFrom('album').where('id', '=', id).execute();
|
||||
}
|
||||
|
||||
@Chunked({ paramIndex: 2, chunkSize: 30_000 })
|
||||
@@ -326,7 +316,7 @@ export class AlbumRepository {
|
||||
}
|
||||
|
||||
await db
|
||||
.insertInto('albums_assets_assets')
|
||||
.insertInto('album_asset')
|
||||
.values(assetIds.map((assetId) => ({ albumsId: albumId, assetsId: assetId })))
|
||||
.execute();
|
||||
}
|
||||
@@ -343,11 +333,11 @@ export class AlbumRepository {
|
||||
// Subquery for getting a new thumbnail.
|
||||
|
||||
const result = await this.db
|
||||
.updateTable('albums')
|
||||
.updateTable('album')
|
||||
.set((eb) => ({
|
||||
albumThumbnailAssetId: this.updateThumbnailBuilder(eb)
|
||||
.select('album_assets.assetsId')
|
||||
.orderBy('assets.fileCreatedAt', 'desc')
|
||||
.select('album_asset.assetsId')
|
||||
.orderBy('asset.fileCreatedAt', 'desc')
|
||||
.limit(1),
|
||||
}))
|
||||
.where((eb) =>
|
||||
@@ -362,7 +352,7 @@ export class AlbumRepository {
|
||||
eb.exists(
|
||||
this.updateThumbnailBuilder(eb)
|
||||
.select(sql`1`.as('1'))
|
||||
.whereRef('albums.albumThumbnailAssetId', '=', 'album_assets.assetsId'), // Has invalid assets
|
||||
.whereRef('album.albumThumbnailAssetId', '=', 'album_asset.assetsId'), // Has invalid assets
|
||||
),
|
||||
),
|
||||
]),
|
||||
@@ -373,12 +363,12 @@ export class AlbumRepository {
|
||||
return Number(result[0].numUpdatedRows);
|
||||
}
|
||||
|
||||
private updateThumbnailBuilder(eb: ExpressionBuilder<DB, 'albums'>) {
|
||||
private updateThumbnailBuilder(eb: ExpressionBuilder<DB, 'album'>) {
|
||||
return eb
|
||||
.selectFrom('albums_assets_assets as album_assets')
|
||||
.innerJoin('assets', (join) =>
|
||||
join.onRef('album_assets.assetsId', '=', 'assets.id').on('assets.deletedAt', 'is', null),
|
||||
.selectFrom('album_asset')
|
||||
.innerJoin('asset', (join) =>
|
||||
join.onRef('album_asset.assetsId', '=', 'asset.id').on('asset.deletedAt', 'is', null),
|
||||
)
|
||||
.whereRef('album_assets.albumsId', '=', 'albums.id');
|
||||
.whereRef('album_asset.albumsId', '=', 'album.id');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user