refactor: move all new queries into integrity repository

This commit is contained in:
izzy
2025-12-02 13:15:48 +00:00
parent 6cfd1994c4
commit 64cc64dd56
9 changed files with 276 additions and 274 deletions
+3 -3
View File
@@ -22,7 +22,7 @@ import { DownloadRepository } from 'src/repositories/download.repository';
import { DuplicateRepository } from 'src/repositories/duplicate.repository';
import { EmailRepository } from 'src/repositories/email.repository';
import { EventRepository } from 'src/repositories/event.repository';
import { IntegrityReportRepository } from 'src/repositories/integrity-report.repository';
import { IntegrityRepository } from 'src/repositories/integrity.repository';
import { JobRepository } from 'src/repositories/job.repository';
import { LibraryRepository } from 'src/repositories/library.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
@@ -80,7 +80,7 @@ export const BASE_SERVICE_DEPENDENCIES = [
DuplicateRepository,
EmailRepository,
EventRepository,
IntegrityReportRepository,
IntegrityRepository,
JobRepository,
LibraryRepository,
MachineLearningRepository,
@@ -139,7 +139,7 @@ export class BaseService {
protected duplicateRepository: DuplicateRepository,
protected emailRepository: EmailRepository,
protected eventRepository: EventRepository,
protected integrityReportRepository: IntegrityReportRepository,
protected integrityRepository: IntegrityRepository,
protected jobRepository: JobRepository,
protected libraryRepository: LibraryRepository,
protected machineLearningRepository: MachineLearningRepository,
+20 -20
View File
@@ -149,7 +149,7 @@ export class IntegrityService extends BaseService {
async handleOrphanedFilesQueueAll({ refreshOnly }: IIntegrityJob = {}): Promise<JobStatus> {
this.logger.log(`Checking for out of date orphaned file reports...`);
const reports = this.assetJobRepository.streamIntegrityReports(IntegrityReportType.OrphanFile);
const reports = this.integrityRepository.streamIntegrityReports(IntegrityReportType.OrphanFile);
let total = 0;
for await (const batchReports of chunk(reports, JOBS_LIBRARY_PAGINATION_SIZE)) {
@@ -220,7 +220,7 @@ export class IntegrityService extends BaseService {
const orphanedFiles = new Set<string>(paths);
if (type === 'asset') {
const assets = await this.assetJobRepository.getAssetPathsByPaths(paths);
const assets = await this.integrityRepository.getAssetPathsByPaths(paths);
for (const { originalPath, encodedVideoPath } of assets) {
orphanedFiles.delete(originalPath);
@@ -229,14 +229,14 @@ export class IntegrityService extends BaseService {
}
}
} else {
const assets = await this.assetJobRepository.getAssetFilePathsByPaths(paths);
const assets = await this.integrityRepository.getAssetFilePathsByPaths(paths);
for (const { path } of assets) {
orphanedFiles.delete(path);
}
}
if (orphanedFiles.size > 0) {
await this.integrityReportRepository.create(
await this.integrityRepository.create(
[...orphanedFiles].map((path) => ({
type: IntegrityReportType.OrphanFile,
path,
@@ -263,7 +263,7 @@ export class IntegrityService extends BaseService {
const reportIds = results.filter(Boolean) as string[];
if (reportIds.length > 0) {
await this.integrityReportRepository.deleteByIds(reportIds);
await this.integrityRepository.deleteByIds(reportIds);
}
this.logger.log(`Processed ${items.length} paths and found ${reportIds.length} report(s) out of date.`);
@@ -275,7 +275,7 @@ export class IntegrityService extends BaseService {
if (refreshOnly) {
this.logger.log(`Checking for out of date missing file reports...`);
const reports = this.assetJobRepository.streamIntegrityReports(IntegrityReportType.MissingFile);
const reports = this.integrityRepository.streamIntegrityReports(IntegrityReportType.MissingFile);
let total = 0;
for await (const batchReports of chunk(reports, JOBS_LIBRARY_PAGINATION_SIZE)) {
@@ -296,7 +296,7 @@ export class IntegrityService extends BaseService {
this.logger.log(`Scanning for missing files...`);
const assetPaths = this.assetJobRepository.streamAssetPaths();
const assetPaths = this.integrityRepository.streamAssetPaths();
let total = 0;
for await (const batchPaths of chunk(assetPaths, JOBS_LIBRARY_PAGINATION_SIZE)) {
@@ -331,12 +331,12 @@ export class IntegrityService extends BaseService {
.map(({ reportId }) => reportId!);
if (outdatedReports.length > 0) {
await this.integrityReportRepository.deleteByIds(outdatedReports);
await this.integrityRepository.deleteByIds(outdatedReports);
}
const missingFiles = results.filter(({ exists }) => !exists);
if (missingFiles.length > 0) {
await this.integrityReportRepository.create(
await this.integrityRepository.create(
missingFiles.map(({ path, assetId, fileAssetId }) => ({
type: IntegrityReportType.MissingFile,
path,
@@ -365,7 +365,7 @@ export class IntegrityService extends BaseService {
const reportIds = results.filter(Boolean) as string[];
if (reportIds.length > 0) {
await this.integrityReportRepository.deleteByIds(reportIds);
await this.integrityRepository.deleteByIds(reportIds);
}
this.logger.log(`Processed ${paths.length} paths and found ${reportIds.length} report(s) out of date.`);
@@ -377,7 +377,7 @@ export class IntegrityService extends BaseService {
if (refreshOnly) {
this.logger.log(`Checking for out of date checksum file reports...`);
const reports = this.assetJobRepository.streamIntegrityReports(IntegrityReportType.ChecksumFail);
const reports = this.integrityRepository.streamIntegrityReports(IntegrityReportType.ChecksumFail);
let total = 0;
for await (const batchReports of chunk(reports, JOBS_LIBRARY_PAGINATION_SIZE)) {
@@ -414,7 +414,7 @@ export class IntegrityService extends BaseService {
let processed = 0;
const startedAt = Date.now();
const { count } = await this.assetJobRepository.getAssetCount();
const { count } = await this.integrityRepository.getAssetCount();
const checkpoint = await this.systemMetadataRepository.get(SystemMetadataKey.IntegrityChecksumCheckpoint);
let startMarker: Date | undefined = checkpoint?.date ? new Date(checkpoint.date) : undefined;
@@ -436,7 +436,7 @@ export class IntegrityService extends BaseService {
`Processing assets in range [${startMarker?.toISOString() ?? 'beginning'}, ${endMarker?.toISOString() ?? 'end'}]`,
);
const assets = this.assetJobRepository.streamAssetChecksums(startMarker, endMarker);
const assets = this.integrityRepository.streamAssetChecksums(startMarker, endMarker);
endMarker = startMarker;
startMarker = undefined;
@@ -458,7 +458,7 @@ export class IntegrityService extends BaseService {
if (checksum.equals(hash.digest())) {
if (reportId) {
await this.integrityReportRepository.deleteById(reportId);
await this.integrityRepository.deleteById(reportId);
}
} else {
throw new Error('File failed checksum');
@@ -466,14 +466,14 @@ export class IntegrityService extends BaseService {
} catch (error) {
if ((error as { code?: string }).code === 'ENOENT') {
if (reportId) {
await this.integrityReportRepository.deleteById(reportId);
await this.integrityRepository.deleteById(reportId);
}
// missing file; handled by the missing files job
continue;
}
this.logger.warn('Failed to process a file: ' + error);
await this.integrityReportRepository.create({
await this.integrityRepository.create({
path: originalPath,
type: IntegrityReportType.ChecksumFail,
assetId,
@@ -544,7 +544,7 @@ export class IntegrityService extends BaseService {
const reportIds = results.filter(Boolean) as string[];
if (reportIds.length > 0) {
await this.integrityReportRepository.deleteByIds(reportIds);
await this.integrityRepository.deleteByIds(reportIds);
}
this.logger.log(`Processed ${paths.length} paths and found ${reportIds.length} report(s) out of date.`);
@@ -576,7 +576,7 @@ export class IntegrityService extends BaseService {
}
for (const property of properties) {
const reports = this.integrityReportRepository.streamIntegrityReportsByProperty(property, type);
const reports = this.integrityRepository.streamIntegrityReportsByProperty(property, type);
for await (const report of chunk(reports, JOBS_LIBRARY_PAGINATION_SIZE)) {
// todo: queue sub-job here instead?
@@ -593,7 +593,7 @@ export class IntegrityService extends BaseService {
userId: '', // ???
});
await this.integrityReportRepository.deleteByIds(report.map(({ id }) => id));
await this.integrityRepository.deleteByIds(report.map(({ id }) => id));
break;
}
case 'fileAssetId': {
@@ -602,7 +602,7 @@ export class IntegrityService extends BaseService {
}
default: {
await Promise.all(report.map(({ path }) => this.storageRepository.unlink(path).catch(() => void 0)));
await this.integrityReportRepository.deleteByIds(report.map(({ id }) => id));
await this.integrityRepository.deleteByIds(report.map(({ id }) => id));
break;
}
}
+7 -7
View File
@@ -61,19 +61,19 @@ export class MaintenanceService extends BaseService {
}
getIntegrityReportSummary(): Promise<MaintenanceIntegrityReportSummaryResponseDto> {
return this.integrityReportRepository.getIntegrityReportSummary();
return this.integrityRepository.getIntegrityReportSummary();
}
getIntegrityReport(dto: MaintenanceGetIntegrityReportDto): Promise<MaintenanceIntegrityReportResponseDto> {
return this.integrityReportRepository.getIntegrityReport(dto);
return this.integrityRepository.getIntegrityReport(dto);
}
getIntegrityReportCsv(type: IntegrityReportType): Readable {
return this.integrityReportRepository.getIntegrityReportCsv(type);
return this.integrityRepository.getIntegrityReportCsv(type);
}
async getIntegrityReportFile(id: string): Promise<ImmichFileResponse> {
const { path } = await this.integrityReportRepository.getById(id);
const { path } = await this.integrityRepository.getById(id);
return new ImmichFileResponse({
path,
@@ -84,7 +84,7 @@ export class MaintenanceService extends BaseService {
}
async deleteIntegrityReport(auth: AuthDto, id: string): Promise<void> {
const { path, assetId, fileAssetId } = await this.integrityReportRepository.getById(id);
const { path, assetId, fileAssetId } = await this.integrityRepository.getById(id);
if (assetId) {
await this.assetRepository.updateAll([assetId], {
@@ -97,12 +97,12 @@ export class MaintenanceService extends BaseService {
userId: auth.user.id,
});
await this.integrityReportRepository.deleteById(id);
await this.integrityRepository.deleteById(id);
} else if (fileAssetId) {
await this.assetRepository.deleteFiles([{ id: fileAssetId }]);
} else {
await this.storageRepository.unlink(path);
await this.integrityReportRepository.deleteById(id);
await this.integrityRepository.deleteById(id);
}
}
}