import { Kysely } from 'kysely'; import { InjectKysely } from 'nestjs-kysely'; import { DummyValue, GenerateSql } from 'src/decorators'; import { AssetVisibility } from 'src/enum'; import { DB } from 'src/schema'; import { asUuid, withExif } from 'src/utils/database'; export class ViewRepository { constructor(@InjectKysely() private db: Kysely) {} @GenerateSql({ params: [DummyValue.UUID] }) async getUniqueOriginalPaths(userId: string) { const results = await this.db .selectFrom('asset') .select((eb) => eb.fn('substring', ['asset.originalPath', eb.val('^(.*/)[^/]*$')]).as('directoryPath')) .distinct() .where('ownerId', '=', asUuid(userId)) .where('visibility', '=', AssetVisibility.Timeline) .where('deletedAt', 'is', null) .where('fileCreatedAt', 'is not', null) .where('fileModifiedAt', 'is not', null) .where('localDateTime', 'is not', null) .execute(); return results.map((row) => row.directoryPath.replaceAll(/\/$/g, '')); } @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] }) async getAssetsByOriginalPath(userId: string, partialPath: string) { const normalizedPath = partialPath.replaceAll(/\/$/g, ''); return this.db .selectFrom('asset') .selectAll('asset') .$call(withExif) .where('ownerId', '=', asUuid(userId)) .where('visibility', '=', AssetVisibility.Timeline) .where('deletedAt', 'is', null) .where('fileCreatedAt', 'is not', null) .where('fileModifiedAt', 'is not', null) .where('localDateTime', 'is not', null) .where('originalPath', 'like', `%${normalizedPath}/%`) .where('originalPath', 'not like', `%${normalizedPath}/%/%`) .orderBy( (eb) => eb.fn('regexp_replace', ['asset.originalPath', eb.val('.*/(.+)'), eb.val(String.raw`\1`)]), 'asc', ) .execute(); } }