From 73a17bb58e87013c5ca6c32cc4406e02502886e1 Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 2 Dec 2025 13:54:55 +0000 Subject: [PATCH] chore: generate SQL --- server/src/queries/asset.job.repository.sql | 78 -------- server/src/queries/integrity.repository.sql | 179 ++++++++++++++++++ .../src/repositories/integrity.repository.ts | 85 ++++----- server/src/services/maintenance.service.ts | 8 +- 4 files changed, 226 insertions(+), 124 deletions(-) create mode 100644 server/src/queries/integrity.repository.sql diff --git a/server/src/queries/asset.job.repository.sql b/server/src/queries/asset.job.repository.sql index cf416cd5f1..ebfd1a08c9 100644 --- a/server/src/queries/asset.job.repository.sql +++ b/server/src/queries/asset.job.repository.sql @@ -386,84 +386,6 @@ from where "asset"."id" = $2 --- AssetJobRepository.getAssetPathsByPaths -select - "originalPath", - "encodedVideoPath" -from - "asset" -where - ( - "originalPath" in $1 - or "encodedVideoPath" in $2 - ) - --- AssetJobRepository.getAssetFilePathsByPaths -select - "path" -from - "asset_file" -where - "path" in $1 - --- AssetJobRepository.getAssetCount -select - count(*) as "count" -from - "asset" - --- AssetJobRepository.streamAssetPaths -select - "allPaths"."path" as "path", - "integrity_report"."path" as "reportId" -from - ( - select - "originalPath" as "path" - from - "asset" - union all - select - "encodedVideoPath" as "path" - from - "asset" - where - "encodedVideoPath" is not null - and "encodedVideoPath" != $1 - union all - select - "path" - from - "asset_file" - ) as "allPaths" - left join "integrity_report" on "integrity_report"."path" = "allPaths"."path" - and "integrity_report"."type" = $2 - --- AssetJobRepository.streamAssetChecksums -select - "asset"."originalPath", - "asset"."checksum", - "asset"."createdAt", - "integrity_report"."id" as "reportId" -from - "asset" - left join "integrity_report" on "integrity_report"."path" = "asset"."originalPath" - and "integrity_report"."type" = $1 -where - "createdAt" >= $2 - and "createdAt" <= $3 -order by - "createdAt" asc - --- AssetJobRepository.streamIntegrityReports -select - "integrity_report"."id" as "reportId", - "integrity_report"."path" -from - "integrity_report" -where - "integrity_report"."type" = $1 - -- AssetJobRepository.streamForVideoConversion select "asset"."id" diff --git a/server/src/queries/integrity.repository.sql b/server/src/queries/integrity.repository.sql new file mode 100644 index 0000000000..72def33dc5 --- /dev/null +++ b/server/src/queries/integrity.repository.sql @@ -0,0 +1,179 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- IntegrityRepository.getById +select + "integrity_report".* +from + "integrity_report" +where + "id" = $1 + +-- IntegrityRepository.getIntegrityReportSummary +select + count(*) filter ( + where + "type" = $1 + ) as "checksum_mismatch", + count(*) filter ( + where + "type" = $2 + ) as "missing_file", + count(*) filter ( + where + "type" = $3 + ) as "orphan_file" +from + "integrity_report" + +-- IntegrityRepository.getIntegrityReports +select + "id", + "type", + "path", + "assetId", + "fileAssetId" +from + "integrity_report" +where + "type" = $1 +order by + "createdAt" desc + +-- IntegrityRepository.getAssetPathsByPaths +select + "originalPath", + "encodedVideoPath" +from + "asset" +where + ( + "originalPath" in $1 + or "encodedVideoPath" in $2 + ) + +-- IntegrityRepository.getAssetFilePathsByPaths +select + "path" +from + "asset_file" +where + "path" in $1 + +-- IntegrityRepository.getAssetCount +select + count(*) as "count" +from + "asset" + +-- IntegrityRepository.streamAllAssetPaths +select + "id", + "type", + "path", + "assetId", + "fileAssetId" +from + "integrity_report" +where + "type" = $1 +order by + "createdAt" desc +select + "originalPath", + "encodedVideoPath" +from + "asset" + +-- IntegrityRepository.streamAllAssetFilePaths +select + "path" +from + "asset_file" + +-- IntegrityRepository.streamAssetPaths +select + "allPaths"."path" as "path", + "allPaths"."assetId", + "allPaths"."fileAssetId", + "integrity_report"."path" as "reportId" +from + ( + select + "asset"."originalPath" as "path", + "asset"."id" as "assetId", + null::uuid as "fileAssetId" + from + "asset" + where + "asset"."deletedAt" is not null + union all + select + "asset"."encodedVideoPath" as "path", + "asset"."id" as "assetId", + null::uuid as "fileAssetId" + from + "asset" + where + "asset"."deletedAt" is not null + and "asset"."encodedVideoPath" is not null + and "asset"."encodedVideoPath" != '' + union all + select + "path", + null::uuid as "assetId", + "asset_file"."id" as "fileAssetId" + from + "asset_file" + ) as "allPaths" + left join "integrity_report" on "integrity_report"."type" = $1 + and ( + "integrity_report"."assetId" = "allPaths"."assetId" + or "integrity_report"."fileAssetId" = "allPaths"."fileAssetId" + ) + +-- IntegrityRepository.streamAssetChecksums +select + "asset"."originalPath", + "asset"."checksum", + "asset"."createdAt", + "asset"."id" as "assetId", + "integrity_report"."id" as "reportId" +from + "asset" + left join "integrity_report" on "integrity_report"."assetId" = "asset"."id" + and "integrity_report"."type" = $1 +where + "createdAt" >= $2 + and "createdAt" <= $3 +order by + "createdAt" asc + +-- IntegrityRepository.streamIntegrityReports +select + "integrity_report"."id" as "reportId", + "integrity_report"."path" +from + "integrity_report" +where + "integrity_report"."type" = $1 + +-- IntegrityRepository.streamIntegrityReportsByProperty +select + "id", + "path", + "assetId", + "fileAssetId" +from + "integrity_report" +where + "abcdefghi" is not null + +-- IntegrityRepository.deleteById +delete from "integrity_report" +where + "id" = $1 + +-- IntegrityRepository.deleteByIds +delete from "integrity_report" +where + "id" in $1 diff --git a/server/src/repositories/integrity.repository.ts b/server/src/repositories/integrity.repository.ts index 3daebf2a1d..9f035b342b 100644 --- a/server/src/repositories/integrity.repository.ts +++ b/server/src/repositories/integrity.repository.ts @@ -3,11 +3,6 @@ import { Insertable, Kysely, sql } from 'kysely'; import { InjectKysely } from 'nestjs-kysely'; import { Readable } from 'node:stream'; import { DummyValue, GenerateSql } from 'src/decorators'; -import { - MaintenanceGetIntegrityReportDto, - MaintenanceIntegrityReportResponseDto, - MaintenanceIntegrityReportSummaryResponseDto, -} from 'src/dtos/maintenance.dto'; import { IntegrityReportType } from 'src/enum'; import { DB } from 'src/schema'; import { IntegrityReportTable } from 'src/schema/tables/integrity-report.table'; @@ -30,6 +25,7 @@ export class IntegrityRepository { .executeTakeFirst(); } + @GenerateSql({ params: [DummyValue.STRING] }) getById(id: string) { return this.db .selectFrom('integrity_report') @@ -38,7 +34,8 @@ export class IntegrityRepository { .executeTakeFirstOrThrow(); } - getIntegrityReportSummary(): Promise { + @GenerateSql({ params: [] }) + getIntegrityReportSummary() { return this.db .selectFrom('integrity_report') .select((eb) => @@ -62,47 +59,14 @@ export class IntegrityRepository { .executeTakeFirstOrThrow(); } - async getIntegrityReport(dto: MaintenanceGetIntegrityReportDto): Promise { - return { - items: await this.db - .selectFrom('integrity_report') - .select(['id', 'type', 'path', 'assetId', 'fileAssetId']) - .where('type', '=', dto.type) - .orderBy('createdAt', 'desc') - .execute(), - }; - } - - getIntegrityReportCsv(type: IntegrityReportType): Readable { - const items = this.db + @GenerateSql({ params: [DummyValue.STRING] }) + getIntegrityReports(type: IntegrityReportType) { + return this.db .selectFrom('integrity_report') .select(['id', 'type', 'path', 'assetId', 'fileAssetId']) .where('type', '=', type) .orderBy('createdAt', 'desc') - .stream(); - - // very rudimentary csv serialiser - async function* generator() { - yield 'id,type,assetId,fileAssetId,path\n'; - - for await (const item of items) { - // no expectation of particularly bad filenames - // but they could potentially have a newline or quote character - yield `${item.id},${item.type},${item.assetId},${item.fileAssetId},"${item.path.replace(/"/g, '""')}"\n`; - } - } - - return Readable.from(generator()); - } - - @GenerateSql({ params: [] }) - getAllAssetPaths() { - return this.db.selectFrom('asset').select(['originalPath', 'encodedVideoPath']).stream(); - } - - @GenerateSql({ params: [] }) - getAllAssetFilePaths() { - return this.db.selectFrom('asset_file').select(['path']).stream(); + .execute(); } @GenerateSql({ params: [DummyValue.STRING] }) @@ -127,6 +91,39 @@ export class IntegrityRepository { .executeTakeFirstOrThrow(); } + @GenerateSql({ params: [DummyValue.STRING], stream: true }) + streamIntegrityReportsCSV(type: IntegrityReportType): Readable { + const items = this.db + .selectFrom('integrity_report') + .select(['id', 'type', 'path', 'assetId', 'fileAssetId']) + .where('type', '=', type) + .orderBy('createdAt', 'desc') + .stream(); + + // very rudimentary csv serialiser + async function* generator() { + yield 'id,type,assetId,fileAssetId,path\n'; + + for await (const item of items) { + // no expectation of particularly bad filenames + // but they could potentially have a newline or quote character + yield `${item.id},${item.type},${item.assetId},${item.fileAssetId},"${item.path.replace(/"/g, '""')}"\n`; + } + } + + return Readable.from(generator()); + } + + @GenerateSql({ params: [], stream: true }) + streamAllAssetPaths() { + return this.db.selectFrom('asset').select(['originalPath', 'encodedVideoPath']).stream(); + } + + @GenerateSql({ params: [], stream: true }) + streamAllAssetFilePaths() { + return this.db.selectFrom('asset_file').select(['path']).stream(); + } + @GenerateSql({ params: [], stream: true }) streamAssetPaths() { return this.db @@ -230,10 +227,12 @@ export class IntegrityRepository { .stream(); } + @GenerateSql({ params: [DummyValue.STRING] }) deleteById(id: string) { return this.db.deleteFrom('integrity_report').where('id', '=', id).execute(); } + @GenerateSql({ params: [DummyValue.STRING] }) deleteByIds(ids: string[]) { return this.db.deleteFrom('integrity_report').where('id', 'in', ids).execute(); } diff --git a/server/src/services/maintenance.service.ts b/server/src/services/maintenance.service.ts index d05a1f06b6..75ce1583ae 100644 --- a/server/src/services/maintenance.service.ts +++ b/server/src/services/maintenance.service.ts @@ -64,12 +64,14 @@ export class MaintenanceService extends BaseService { return this.integrityRepository.getIntegrityReportSummary(); } - getIntegrityReport(dto: MaintenanceGetIntegrityReportDto): Promise { - return this.integrityRepository.getIntegrityReport(dto); + async getIntegrityReport(dto: MaintenanceGetIntegrityReportDto): Promise { + return { + items: await this.integrityRepository.getIntegrityReports(dto.type), + }; } getIntegrityReportCsv(type: IntegrityReportType): Readable { - return this.integrityRepository.getIntegrityReportCsv(type); + return this.integrityRepository.streamIntegrityReportsCSV(type); } async getIntegrityReportFile(id: string): Promise {