From 9f9569c152475ef047b0b37cbdd0fac8e704e671 Mon Sep 17 00:00:00 2001 From: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com> Date: Thu, 26 Feb 2026 19:27:50 +0100 Subject: [PATCH] fix: schema check (#26543) --- .../src/repositories/database.repository.ts | 7 +++- server/src/schema/functions.ts | 2 +- .../1772129818245-FixStupidWhiteSpace.ts | 36 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 server/src/schema/migrations/1772129818245-FixStupidWhiteSpace.ts diff --git a/server/src/repositories/database.repository.ts b/server/src/repositories/database.repository.ts index 06bdef5abf..4ffb37c79c 100644 --- a/server/src/repositories/database.repository.ts +++ b/server/src/repositories/database.repository.ts @@ -22,6 +22,7 @@ import { ConfigRepository } from 'src/repositories/config.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; import 'src/schema'; // make sure all schema definitions are imported for schemaFromCode import { DB } from 'src/schema'; +import { immich_uuid_v7 } from 'src/schema/functions'; import { ExtensionVersion, VectorExtension, VectorUpdateResult } from 'src/types'; import { vectorIndexQuery } from 'src/utils/database'; import { isValidInteger } from 'src/validation'; @@ -288,7 +289,11 @@ export class DatabaseRepository { } async getSchemaDrift() { - const source = schemaFromCode({ overrides: true, namingStrategy: 'default' }); + const source = schemaFromCode({ + overrides: true, + namingStrategy: 'default', + uuidFunction: (version) => (version === 7 ? `${immich_uuid_v7.name}()` : 'uuid_generate_v4()'), + }); const { database } = this.configRepository.getEnv(); const target = await schemaFromDatabase({ connection: database.config }); diff --git a/server/src/schema/functions.ts b/server/src/schema/functions.ts index d143e582ca..6dbbd28b1a 100644 --- a/server/src/schema/functions.ts +++ b/server/src/schema/functions.ts @@ -280,7 +280,7 @@ export const asset_edit_delete = registerFunction({ UPDATE asset SET "isEdited" = false FROM deleted_edit - WHERE asset.id = deleted_edit."assetId" AND asset."isEdited" + WHERE asset.id = deleted_edit."assetId" AND asset."isEdited" AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit."assetId" = asset.id); RETURN NULL; END diff --git a/server/src/schema/migrations/1772129818245-FixStupidWhiteSpace.ts b/server/src/schema/migrations/1772129818245-FixStupidWhiteSpace.ts new file mode 100644 index 0000000000..7dc2c5c72f --- /dev/null +++ b/server/src/schema/migrations/1772129818245-FixStupidWhiteSpace.ts @@ -0,0 +1,36 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`CREATE OR REPLACE FUNCTION asset_edit_delete() + RETURNS TRIGGER + LANGUAGE PLPGSQL + AS $$ + BEGIN + UPDATE asset + SET "isEdited" = false + FROM deleted_edit + WHERE asset.id = deleted_edit."assetId" AND asset."isEdited" + AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit."assetId" = asset.id); + RETURN NULL; + END + $$;`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"type":"function","name":"asset_edit_delete","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 $$;"}'::jsonb WHERE "name" = 'function_asset_edit_delete';`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`CREATE OR REPLACE FUNCTION public.asset_edit_delete() + RETURNS trigger + LANGUAGE plpgsql +AS $function$ + BEGIN + UPDATE asset + SET "isEdited" = false + FROM deleted_edit + WHERE asset.id = deleted_edit."assetId" AND asset."isEdited" + AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit."assetId" = asset.id); + RETURN NULL; + END + $function$ +`.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); +}