refactor: migrate library spec to factories (#16711)

This commit is contained in:
Jason Rasmussen 2025-03-08 13:44:36 -05:00 committed by GitHub
parent fd46d43726
commit 1e127ae3a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 407 additions and 535 deletions

View file

@ -10,6 +10,20 @@ export type AuthUser = {
quotaSizeInBytes: number | null;
};
export type Library = {
id: string;
ownerId: string;
createdAt: Date;
updatedAt: Date;
updateId: string;
name: string;
importPaths: string[];
exclusionPatterns: string[];
deletedAt: Date | null;
refreshedAt: Date | null;
assets?: Asset[];
};
export type AuthApiKey = {
id: string;
permissions: Permission[];

View file

@ -1,6 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { ArrayMaxSize, ArrayUnique, IsNotEmpty, IsString } from 'class-validator';
import { LibraryEntity } from 'src/entities/library.entity';
import { Library } from 'src/database';
import { Optional, ValidateUUID } from 'src/validation';
export class CreateLibraryDto {
@ -120,7 +120,7 @@ export class LibraryStatsResponseDto {
usage = 0;
}
export function mapLibrary(entity: LibraryEntity): LibraryResponseDto {
export function mapLibrary(entity: Library): LibraryResponseDto {
let assetCount = 0;
if (entity.assets) {
assetCount = entity.assets.length;

View file

@ -26,7 +26,7 @@ export class LibraryEntity {
assets!: AssetEntity[];
@ManyToOne(() => UserEntity, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
owner!: UserEntity;
owner?: UserEntity;
@Column()
ownerId!: string;

View file

@ -2,34 +2,7 @@
-- LibraryRepository.get
select
"libraries".*,
(
select
to_json(obj)
from
(
select
"users"."id",
"users"."email",
"users"."createdAt",
"users"."profileImagePath",
"users"."isAdmin",
"users"."shouldChangePassword",
"users"."deletedAt",
"users"."oauthId",
"users"."updatedAt",
"users"."storageLabel",
"users"."name",
"users"."quotaSizeInBytes",
"users"."quotaUsageInBytes",
"users"."status",
"users"."profileChangedAt"
from
"users"
where
"users"."id" = "libraries"."ownerId"
) as obj
) as "owner"
"libraries".*
from
"libraries"
where
@ -38,34 +11,7 @@ where
-- LibraryRepository.getAll
select
"libraries".*,
(
select
to_json(obj)
from
(
select
"users"."id",
"users"."email",
"users"."createdAt",
"users"."profileImagePath",
"users"."isAdmin",
"users"."shouldChangePassword",
"users"."deletedAt",
"users"."oauthId",
"users"."updatedAt",
"users"."storageLabel",
"users"."name",
"users"."quotaSizeInBytes",
"users"."quotaUsageInBytes",
"users"."status",
"users"."profileChangedAt"
from
"users"
where
"users"."id" = "libraries"."ownerId"
) as obj
) as "owner"
"libraries".*
from
"libraries"
where
@ -75,34 +21,7 @@ order by
-- LibraryRepository.getAllDeleted
select
"libraries".*,
(
select
to_json(obj)
from
(
select
"users"."id",
"users"."email",
"users"."createdAt",
"users"."profileImagePath",
"users"."isAdmin",
"users"."shouldChangePassword",
"users"."deletedAt",
"users"."oauthId",
"users"."updatedAt",
"users"."storageLabel",
"users"."name",
"users"."quotaSizeInBytes",
"users"."quotaUsageInBytes",
"users"."status",
"users"."profileChangedAt"
from
"users"
where
"users"."id" = "libraries"."ownerId"
) as obj
) as "owner"
"libraries".*
from
"libraries"
where

View file

@ -1,31 +1,11 @@
import { Injectable } from '@nestjs/common';
import { ExpressionBuilder, Insertable, Kysely, sql, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB, Libraries } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { LibraryStatsResponseDto } from 'src/dtos/library.dto';
import { LibraryEntity } from 'src/entities/library.entity';
import { AssetType } from 'src/enum';
const userColumns = [
'users.id',
'users.email',
'users.createdAt',
'users.profileImagePath',
'users.isAdmin',
'users.shouldChangePassword',
'users.deletedAt',
'users.oauthId',
'users.updatedAt',
'users.storageLabel',
'users.name',
'users.quotaSizeInBytes',
'users.quotaUsageInBytes',
'users.status',
'users.profileChangedAt',
] as const;
export enum AssetSyncResult {
DO_NOTHING,
UPDATE,
@ -33,72 +13,59 @@ export enum AssetSyncResult {
CHECK_OFFLINE,
}
const withOwner = (eb: ExpressionBuilder<DB, 'libraries'>) => {
return jsonObjectFrom(eb.selectFrom('users').whereRef('users.id', '=', 'libraries.ownerId').select(userColumns)).as(
'owner',
);
};
@Injectable()
export class LibraryRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
@GenerateSql({ params: [DummyValue.UUID] })
get(id: string, withDeleted = false): Promise<LibraryEntity | undefined> {
get(id: string, withDeleted = false) {
return this.db
.selectFrom('libraries')
.selectAll('libraries')
.select(withOwner)
.where('libraries.id', '=', id)
.$if(!withDeleted, (qb) => qb.where('libraries.deletedAt', 'is', null))
.executeTakeFirst() as Promise<LibraryEntity | undefined>;
.executeTakeFirst();
}
@GenerateSql({ params: [] })
getAll(withDeleted = false): Promise<LibraryEntity[]> {
getAll(withDeleted = false) {
return this.db
.selectFrom('libraries')
.selectAll('libraries')
.select(withOwner)
.orderBy('createdAt', 'asc')
.$if(!withDeleted, (qb) => qb.where('libraries.deletedAt', 'is', null))
.execute() as unknown as Promise<LibraryEntity[]>;
.execute();
}
@GenerateSql()
getAllDeleted(): Promise<LibraryEntity[]> {
getAllDeleted() {
return this.db
.selectFrom('libraries')
.selectAll('libraries')
.select(withOwner)
.where('libraries.deletedAt', 'is not', null)
.orderBy('createdAt', 'asc')
.execute() as unknown as Promise<LibraryEntity[]>;
.execute();
}
create(library: Insertable<Libraries>): Promise<LibraryEntity> {
return this.db
.insertInto('libraries')
.values(library)
.returningAll()
.executeTakeFirstOrThrow() as Promise<LibraryEntity>;
create(library: Insertable<Libraries>) {
return this.db.insertInto('libraries').values(library).returningAll().executeTakeFirstOrThrow();
}
async delete(id: string): Promise<void> {
async delete(id: string) {
await this.db.deleteFrom('libraries').where('libraries.id', '=', id).execute();
}
async softDelete(id: string): Promise<void> {
async softDelete(id: string) {
await this.db.updateTable('libraries').set({ deletedAt: new Date() }).where('libraries.id', '=', id).execute();
}
update(id: string, library: Updateable<Libraries>): Promise<LibraryEntity> {
update(id: string, library: Updateable<Libraries>) {
return this.db
.updateTable('libraries')
.set(library)
.where('libraries.id', '=', id)
.returningAll()
.executeTakeFirstOrThrow() as Promise<LibraryEntity>;
.executeTakeFirstOrThrow();
}
@GenerateSql({ params: [DummyValue.UUID] })

File diff suppressed because it is too large Load diff