diff --git a/server/src/database.ts b/server/src/database.ts index 030a8c71df..39792c503d 100644 --- a/server/src/database.ts +++ b/server/src/database.ts @@ -438,21 +438,21 @@ export const columns = { 'asset_exif.fps', ], syncAssetOcr: [ - 'id', - 'assetId', - 'x1', - 'y1', - 'x2', - 'y2', - 'x3', - 'y3', - 'x4', - 'y4', - 'text', - 'boxScore', - 'textScore', - 'updateId', - 'isVisible', + 'asset_ocr.id', + 'asset_ocr.assetId', + 'asset_ocr.x1', + 'asset_ocr.y1', + 'asset_ocr.x2', + 'asset_ocr.y2', + 'asset_ocr.x3', + 'asset_ocr.y3', + 'asset_ocr.x4', + 'asset_ocr.y4', + 'asset_ocr.text', + 'asset_ocr.boxScore', + 'asset_ocr.textScore', + 'asset_ocr.updateId', + 'asset_ocr.isVisible', ], exif: [ 'asset_exif.assetId', diff --git a/server/src/repositories/sync.repository.ts b/server/src/repositories/sync.repository.ts index 3d9de4081a..9288633d01 100644 --- a/server/src/repositories/sync.repository.ts +++ b/server/src/repositories/sync.repository.ts @@ -779,7 +779,7 @@ class AssetOcrSync extends BaseSync { @GenerateSql({ params: [dummyQueryOptions, DummyValue.UUID], stream: true }) getDeletes(options: SyncQueryOptions, userId: string) { return this.auditQuery('asset_ocr_audit', options) - .select(['asset_ocr_audit.id', 'assetId', 'deletedAt']) + .select(['asset_ocr_audit.id', 'asset_ocr_audit.assetId', 'asset_ocr_audit.deletedAt']) .leftJoin('asset', 'asset.id', 'asset_ocr_audit.assetId') .where('asset.ownerId', '=', userId) .stream(); diff --git a/server/src/schema/index.ts b/server/src/schema/index.ts index bc2aff6415..5c580bee4b 100644 --- a/server/src/schema/index.ts +++ b/server/src/schema/index.ts @@ -96,6 +96,7 @@ export class ImmichDatabase { AssetMetadataAuditTable, AssetJobStatusTable, AssetOcrTable, + AssetOcrAuditTable, AssetTable, AssetFileTable, AuditTable, diff --git a/server/src/schema/migrations/1772019080456-AssetOcrSync.ts b/server/src/schema/migrations/1772025522559-AssetOcrSync.ts similarity index 88% rename from server/src/schema/migrations/1772019080456-AssetOcrSync.ts rename to server/src/schema/migrations/1772025522559-AssetOcrSync.ts index 3b457ba5b4..38ab13d259 100644 --- a/server/src/schema/migrations/1772019080456-AssetOcrSync.ts +++ b/server/src/schema/migrations/1772025522559-AssetOcrSync.ts @@ -25,6 +25,14 @@ export async function up(db: Kysely): Promise { RETURN NULL; END $$;`.execute(db); + await sql`CREATE TABLE "asset_ocr_audit" ( + "id" uuid NOT NULL DEFAULT immich_uuid_v7(), + "assetId" uuid NOT NULL, + "deletedAt" timestamp with time zone NOT NULL DEFAULT clock_timestamp(), + CONSTRAINT "asset_ocr_audit_pkey" PRIMARY KEY ("id") +);`.execute(db); + await sql`CREATE INDEX "asset_ocr_audit_assetId_idx" ON "asset_ocr_audit" ("assetId");`.execute(db); + await sql`CREATE INDEX "asset_ocr_audit_deletedAt_idx" ON "asset_ocr_audit" ("deletedAt");`.execute(db); await sql`ALTER TABLE "asset_ocr" ADD "updateId" uuid NOT NULL DEFAULT immich_uuid_v7();`.execute(db); await sql`CREATE INDEX "asset_ocr_updateId_idx" ON "asset_ocr" ("updateId");`.execute(db); await sql`CREATE OR REPLACE TRIGGER "asset_ocr_delete_audit" @@ -56,6 +64,7 @@ AS $function$ await sql`DROP TRIGGER "asset_ocr_delete_audit" ON "asset_ocr";`.execute(db); await sql`DROP INDEX "asset_ocr_updateId_idx";`.execute(db); await sql`ALTER TABLE "asset_ocr" DROP COLUMN "updateId";`.execute(db); + await sql`DROP TABLE "asset_ocr_audit";`.execute(db); await sql`DROP FUNCTION asset_ocr_delete_audit;`.execute(db); await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE OR REPLACE FUNCTION asset_edit_delete()\\n RETURNS TRIGGER\\n LANGUAGE PLPGSQL\\n AS $$\\n BEGIN\\n UPDATE asset\\n SET \\"isEdited\\" = false\\n FROM deleted_edit\\n WHERE asset.id = deleted_edit.\\"assetId\\" AND asset.\\"isEdited\\" \\n AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit.\\"assetId\\" = asset.id);\\n RETURN NULL;\\n END\\n $$;","name":"asset_edit_delete","type":"function"}'::jsonb WHERE "name" = 'function_asset_edit_delete';`.execute(db); await sql`DELETE FROM "migration_overrides" WHERE "name" = 'function_asset_ocr_delete_audit';`.execute(db); diff --git a/server/src/services/sync.service.ts b/server/src/services/sync.service.ts index 9acd1caf41..1ea357850a 100644 --- a/server/src/services/sync.service.ts +++ b/server/src/services/sync.service.ts @@ -2,6 +2,7 @@ import { BadRequestException, ForbiddenException, Injectable } from '@nestjs/com import { Insertable } from 'kysely'; import { DateTime, Duration } from 'luxon'; import { Writable } from 'node:stream'; +import { ConnectableObservable } from 'rxjs'; import { AUDIT_LOG_MAX_DURATION } from 'src/constants'; import { OnJob } from 'src/decorators'; import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto'; @@ -81,6 +82,7 @@ export const SYNC_TYPES_ORDER = [ SyncRequestType.AlbumToAssetsV1, SyncRequestType.AssetExifsV1, SyncRequestType.AlbumAssetExifsV1, + SyncRequestType.AssetOcrV1, SyncRequestType.PartnerAssetExifsV1, SyncRequestType.MemoriesV1, SyncRequestType.MemoryToAssetsV1,