1
0
mirror of https://github.com/immich-app/immich.git synced 2025-04-14 12:08:54 +02:00

refactor(server): repositories (#9119)

refactor repos
This commit is contained in:
Daniel Dietzler 2024-04-27 19:52:05 +02:00 committed by GitHub
parent 0b68cc2da6
commit 90882a9b26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 25 additions and 27 deletions

View File

@ -510,7 +510,7 @@ export class AssetRepository implements IAssetRepository {
} }
async getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats> { async getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats> {
let builder = this.repository const builder = this.repository
.createQueryBuilder('asset') .createQueryBuilder('asset')
.select(`COUNT(asset.id)`, 'count') .select(`COUNT(asset.id)`, 'count')
.addSelect(`asset.type`, 'type') .addSelect(`asset.type`, 'type')
@ -520,15 +520,15 @@ export class AssetRepository implements IAssetRepository {
const { isArchived, isFavorite, isTrashed } = options; const { isArchived, isFavorite, isTrashed } = options;
if (isArchived !== undefined) { if (isArchived !== undefined) {
builder = builder.andWhere(`asset.isArchived = :isArchived`, { isArchived }); builder.andWhere(`asset.isArchived = :isArchived`, { isArchived });
} }
if (isFavorite !== undefined) { if (isFavorite !== undefined) {
builder = builder.andWhere(`asset.isFavorite = :isFavorite`, { isFavorite }); builder.andWhere(`asset.isFavorite = :isFavorite`, { isFavorite });
} }
if (isTrashed !== undefined) { if (isTrashed !== undefined) {
builder = builder.withDeleted().andWhere(`asset.deletedAt is not null`); builder.withDeleted().andWhere(`asset.deletedAt is not null`);
} }
const items = await builder.getRawMany(); const items = await builder.getRawMany();
@ -644,43 +644,43 @@ export class AssetRepository implements IAssetRepository {
private getBuilder(options: AssetBuilderOptions) { private getBuilder(options: AssetBuilderOptions) {
const { isArchived, isFavorite, isTrashed, albumId, personId, userIds, withStacked, exifInfo, assetType } = options; const { isArchived, isFavorite, isTrashed, albumId, personId, userIds, withStacked, exifInfo, assetType } = options;
let builder = this.repository.createQueryBuilder('asset').where('asset.isVisible = true'); const builder = this.repository.createQueryBuilder('asset').where('asset.isVisible = true');
if (assetType !== undefined) { if (assetType !== undefined) {
builder = builder.andWhere('asset.type = :assetType', { assetType }); builder.andWhere('asset.type = :assetType', { assetType });
} }
let stackJoined = false; let stackJoined = false;
if (exifInfo !== false) { if (exifInfo !== false) {
stackJoined = true; stackJoined = true;
builder = builder builder
.leftJoinAndSelect('asset.exifInfo', 'exifInfo') .leftJoinAndSelect('asset.exifInfo', 'exifInfo')
.leftJoinAndSelect('asset.stack', 'stack') .leftJoinAndSelect('asset.stack', 'stack')
.leftJoinAndSelect('stack.assets', 'stackedAssets'); .leftJoinAndSelect('stack.assets', 'stackedAssets');
} }
if (albumId) { if (albumId) {
builder = builder.leftJoin('asset.albums', 'album').andWhere('album.id = :albumId', { albumId }); builder.leftJoin('asset.albums', 'album').andWhere('album.id = :albumId', { albumId });
} }
if (userIds) { if (userIds) {
builder = builder.andWhere('asset.ownerId IN (:...userIds )', { userIds }); builder.andWhere('asset.ownerId IN (:...userIds )', { userIds });
} }
if (isArchived !== undefined) { if (isArchived !== undefined) {
builder = builder.andWhere('asset.isArchived = :isArchived', { isArchived }); builder.andWhere('asset.isArchived = :isArchived', { isArchived });
} }
if (isFavorite !== undefined) { if (isFavorite !== undefined) {
builder = builder.andWhere('asset.isFavorite = :isFavorite', { isFavorite }); builder.andWhere('asset.isFavorite = :isFavorite', { isFavorite });
} }
if (isTrashed !== undefined) { if (isTrashed !== undefined) {
builder = builder.andWhere(`asset.deletedAt ${isTrashed ? 'IS NOT NULL' : 'IS NULL'}`).withDeleted(); builder.andWhere(`asset.deletedAt ${isTrashed ? 'IS NOT NULL' : 'IS NULL'}`).withDeleted();
} }
if (personId !== undefined) { if (personId !== undefined) {
builder = builder builder
.innerJoin('asset.faces', 'faces') .innerJoin('asset.faces', 'faces')
.innerJoin('faces.person', 'person') .innerJoin('faces.person', 'person')
.andWhere('person.id = :personId', { personId }); .andWhere('person.id = :personId', { personId });
@ -688,9 +688,9 @@ export class AssetRepository implements IAssetRepository {
if (withStacked) { if (withStacked) {
if (!stackJoined) { if (!stackJoined) {
builder = builder.leftJoinAndSelect('asset.stack', 'stack').leftJoinAndSelect('stack.assets', 'stackedAssets'); builder.leftJoinAndSelect('asset.stack', 'stack').leftJoinAndSelect('stack.assets', 'stackedAssets');
} }
builder = builder.andWhere( builder.andWhere(
new Brackets((qb) => qb.where('stack.primaryAssetId = asset.id').orWhere('asset.stackId IS NULL')), new Brackets((qb) => qb.where('stack.primaryAssetId = asset.id').orWhere('asset.stackId IS NULL')),
); );
} }
@ -711,13 +711,13 @@ export class AssetRepository implements IAssetRepository {
}) })
getAllForUserFullSync(options: AssetFullSyncOptions): Promise<AssetEntity[]> { getAllForUserFullSync(options: AssetFullSyncOptions): Promise<AssetEntity[]> {
const { ownerId, lastCreationDate, lastId, updatedUntil, limit } = options; const { ownerId, lastCreationDate, lastId, updatedUntil, limit } = options;
let builder = this.repository const builder = this.repository
.createQueryBuilder('asset') .createQueryBuilder('asset')
.leftJoinAndSelect('asset.exifInfo', 'exifInfo') .leftJoinAndSelect('asset.exifInfo', 'exifInfo')
.leftJoinAndSelect('asset.stack', 'stack') .leftJoinAndSelect('asset.stack', 'stack')
.where('asset.ownerId = :ownerId', { ownerId }); .where('asset.ownerId = :ownerId', { ownerId });
if (lastCreationDate !== undefined && lastId !== undefined) { if (lastCreationDate !== undefined && lastId !== undefined) {
builder = builder.andWhere('(asset.fileCreatedAt, asset.id) < (:lastCreationDate, :lastId)', { builder.andWhere('(asset.fileCreatedAt, asset.id) < (:lastCreationDate, :lastId)', {
lastCreationDate, lastCreationDate,
lastId, lastId,
}); });

View File

@ -173,18 +173,18 @@ export class LibraryRepository implements ILibraryRepository {
@GenerateSql({ params: [DummyValue.UUID] }) @GenerateSql({ params: [DummyValue.UUID] })
async getAssetIds(libraryId: string, withDeleted = false): Promise<string[]> { async getAssetIds(libraryId: string, withDeleted = false): Promise<string[]> {
let query = this.repository const builder = this.repository
.createQueryBuilder('library') .createQueryBuilder('library')
.innerJoinAndSelect('library.assets', 'assets') .innerJoinAndSelect('library.assets', 'assets')
.where('library.id = :id', { id: libraryId }) .where('library.id = :id', { id: libraryId })
.select('assets.id'); .select('assets.id');
if (withDeleted) { if (withDeleted) {
query = query.withDeleted(); builder.withDeleted();
} }
// Return all asset paths for a given library // Return all asset paths for a given library
const rawResults = await query.getRawMany(); const rawResults = await builder.getRawMany();
const results: string[] = []; const results: string[] = [];

View File

@ -1,7 +1,6 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators'; import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
import { AssetEntity } from 'src/entities/asset.entity';
import { MemoryEntity } from 'src/entities/memory.entity'; import { MemoryEntity } from 'src/entities/memory.entity';
import { IMemoryRepository } from 'src/interfaces/memory.interface'; import { IMemoryRepository } from 'src/interfaces/memory.interface';
import { Instrumentation } from 'src/utils/instrumentation'; import { Instrumentation } from 'src/utils/instrumentation';
@ -11,7 +10,6 @@ import { DataSource, In, Repository } from 'typeorm';
@Injectable() @Injectable()
export class MemoryRepository implements IMemoryRepository { export class MemoryRepository implements IMemoryRepository {
constructor( constructor(
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
@InjectRepository(MemoryEntity) private repository: Repository<MemoryEntity>, @InjectRepository(MemoryEntity) private repository: Repository<MemoryEntity>,
@InjectDataSource() private dataSource: DataSource, @InjectDataSource() private dataSource: DataSource,
) {} ) {}

View File

@ -96,7 +96,7 @@ export class TagRepository implements ITagRepository {
} }
hasAsset(userId: string, tagId: string, assetId: string): Promise<boolean> { hasAsset(userId: string, tagId: string, assetId: string): Promise<boolean> {
return this.repository.exist({ return this.repository.exists({
where: { where: {
id: tagId, id: tagId,
userId, userId,
@ -111,7 +111,7 @@ export class TagRepository implements ITagRepository {
} }
hasName(userId: string, name: string): Promise<boolean> { hasName(userId: string, name: string): Promise<boolean> {
return this.repository.exist({ return this.repository.exists({
where: { where: {
name, name,
userId, userId,

View File

@ -36,15 +36,15 @@ export class UserRepository implements IUserRepository {
@GenerateSql() @GenerateSql()
async hasAdmin(): Promise<boolean> { async hasAdmin(): Promise<boolean> {
return this.userRepository.exist({ where: { isAdmin: true } }); return this.userRepository.exists({ where: { isAdmin: true } });
} }
@GenerateSql({ params: [DummyValue.EMAIL] }) @GenerateSql({ params: [DummyValue.EMAIL] })
async getByEmail(email: string, withPassword?: boolean): Promise<UserEntity | null> { async getByEmail(email: string, withPassword?: boolean): Promise<UserEntity | null> {
let builder = this.userRepository.createQueryBuilder('user').where({ email }); const builder = this.userRepository.createQueryBuilder('user').where({ email });
if (withPassword) { if (withPassword) {
builder = builder.addSelect('user.password'); builder.addSelect('user.password');
} }
return builder.getOne(); return builder.getOne();