diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d855c312b..a270bb1ff3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -345,8 +345,8 @@ importers: specifier: 2.0.0-rc13 version: 2.0.0-rc13 '@immich/sql-tools': - specifier: ^0.3.2 - version: 0.3.4 + specifier: ^0.5.1 + version: 0.5.1 '@nestjs/bullmq': specifier: ^11.0.1 version: 11.0.4(@nestjs/common@11.1.19(class-transformer@0.5.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.19)(bullmq@5.74.1) @@ -3171,8 +3171,8 @@ packages: '@immich/justified-layout-wasm@0.4.3': resolution: {integrity: sha512-fpcQ7zPhP3Cp1bEXhONVYSUeIANa2uzaQFGKufUZQo5FO7aFT77szTVChhlCy4XaVy5R4ZvgSkA/1TJmeORz7Q==} - '@immich/sql-tools@0.3.4': - resolution: {integrity: sha512-lsJaFELmBEEd3VtsPGXGT8HCBLkthra3k4EalH6MQeCZv9+iTpK7WT2vJLA5a/ndo+cCbcgm+jxsceqZKCuyRQ==} + '@immich/sql-tools@0.5.1': + resolution: {integrity: sha512-1yb5w8IS0PIVgTZ75fAsbaH1JowNNB7d6h0h8ZLQt32Y35xBzmZef/IL9LVAWnWBObzwWi12+RLcg0gkMS6dpA==} hasBin: true '@immich/svelte-markdown-preprocess@0.4.1': @@ -8060,6 +8060,9 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graph-data-structure@4.5.0: + resolution: {integrity: sha512-OCeIzpK9JnV5js4gtDJgwebRbcOsZpoN9CNIwEooHkV/FNol+OykWPOugSTXBH/QICEW2N6U+6L2d9DcK4YBcw==} + gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -15546,9 +15549,10 @@ snapshots: '@immich/justified-layout-wasm@0.4.3': {} - '@immich/sql-tools@0.3.4': + '@immich/sql-tools@0.5.1': dependencies: commander: 14.0.3 + graph-data-structure: 4.5.0 kysely: 0.28.16 kysely-postgres-js: 3.0.0(kysely@0.28.16)(postgres@3.4.9) pg-connection-string: 2.12.0 @@ -21061,6 +21065,8 @@ snapshots: graceful-fs@4.2.11: {} + graph-data-structure@4.5.0: {} + gray-matter@4.0.3: dependencies: js-yaml: 3.14.2 diff --git a/server/package.json b/server/package.json index b8e400b7e5..65c056dfef 100644 --- a/server/package.json +++ b/server/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@extism/extism": "2.0.0-rc13", - "@immich/sql-tools": "^0.3.2", + "@immich/sql-tools": "^0.5.1", "@nestjs/bullmq": "^11.0.1", "@nestjs/common": "^11.0.4", "@nestjs/core": "^11.0.4", diff --git a/server/src/schema/migrations/1776792304485-ReconcileSqlToolsUpgradeChanges.ts b/server/src/schema/migrations/1776792304485-ReconcileSqlToolsUpgradeChanges.ts new file mode 100644 index 0000000000..d60114fa0f --- /dev/null +++ b/server/src/schema/migrations/1776792304485-ReconcileSqlToolsUpgradeChanges.ts @@ -0,0 +1,17 @@ +import { Kysely, sql } from 'kysely'; + +export async function up(db: Kysely): Promise { + await sql`UPDATE "migration_overrides" SET "value" = '{"type":"index","name":"asset_id_timeline_notDeleted_idx","sql":"CREATE INDEX \\"asset_id_timeline_notDeleted_idx\\" ON \\"asset\\" (\\"id\\") WHERE (visibility = ''timeline'' AND \\"deletedAt\\" IS NULL);"}'::jsonb WHERE "name" = 'index_asset_id_timeline_notDeleted_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"type":"index","name":"asset_localDateTime_month_idx","sql":"CREATE INDEX \\"asset_localDateTime_month_idx\\" ON \\"asset\\" (date_trunc(''MONTH''::text, (\\"localDateTime\\" AT TIME ZONE ''UTC''::text)) AT TIME ZONE ''UTC''::text);"}'::jsonb WHERE "name" = 'index_asset_localDateTime_month_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"type":"index","name":"asset_localDateTime_idx","sql":"CREATE INDEX \\"asset_localDateTime_idx\\" ON \\"asset\\" ((\\"localDateTime\\" at time zone ''UTC'')::date);"}'::jsonb WHERE "name" = 'index_asset_localDateTime_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"type":"index","name":"activity_like_idx","sql":"CREATE UNIQUE INDEX \\"activity_like_idx\\" ON \\"activity\\" (\\"assetId\\", \\"userId\\", \\"albumId\\") WHERE ((\\"isLiked\\" = true));"}'::jsonb WHERE "name" = 'index_activity_like_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"type":"index","name":"asset_face_personId_assetId_notDeleted_isVisible_idx","sql":"CREATE INDEX \\"asset_face_personId_assetId_notDeleted_isVisible_idx\\" ON \\"asset_face\\" (\\"personId\\", \\"assetId\\") WHERE (\\"deletedAt\\" IS NULL AND \\"isVisible\\" IS TRUE);"}'::jsonb WHERE "name" = 'index_asset_face_personId_assetId_notDeleted_isVisible_idx';`.execute(db); +} + +export async function down(db: Kysely): Promise { + await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE INDEX \\"asset_localDateTime_month_idx\\" ON \\"asset\\" ((date_trunc(''MONTH''::text, (\\"localDateTime\\" AT TIME ZONE ''UTC''::text)) AT TIME ZONE ''UTC''::text));","name":"asset_localDateTime_month_idx","type":"index"}'::jsonb WHERE "name" = 'index_asset_localDateTime_month_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE INDEX \\"asset_localDateTime_idx\\" ON \\"asset\\" (((\\"localDateTime\\" at time zone ''UTC'')::date));","name":"asset_localDateTime_idx","type":"index"}'::jsonb WHERE "name" = 'index_asset_localDateTime_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE UNIQUE INDEX \\"activity_like_idx\\" ON \\"activity\\" (\\"assetId\\", \\"userId\\", \\"albumId\\") WHERE (\\"isLiked\\" = true);","name":"activity_like_idx","type":"index"}'::jsonb WHERE "name" = 'index_activity_like_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE INDEX \\"asset_id_timeline_notDeleted_idx\\" ON \\"asset\\" (\\"id\\") WHERE visibility = ''timeline'' AND \\"deletedAt\\" IS NULL;","name":"asset_id_timeline_notDeleted_idx","type":"index"}'::jsonb WHERE "name" = 'index_asset_id_timeline_notDeleted_idx';`.execute(db); + await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE INDEX \\"asset_face_personId_assetId_notDeleted_isVisible_idx\\" ON \\"asset_face\\" (\\"personId\\", \\"assetId\\") WHERE \\"deletedAt\\" IS NULL AND \\"isVisible\\" IS TRUE;","name":"asset_face_personId_assetId_notDeleted_isVisible_idx","type":"index"}'::jsonb WHERE "name" = 'index_asset_face_personId_assetId_notDeleted_isVisible_idx';`.execute(db); +} diff --git a/server/src/schema/tables/asset.table.ts b/server/src/schema/tables/asset.table.ts index e19a52af9c..718c19be5a 100644 --- a/server/src/schema/tables/asset.table.ts +++ b/server/src/schema/tables/asset.table.ts @@ -33,20 +33,20 @@ import { ASSET_CHECKSUM_CONSTRAINT } from 'src/utils/database'; name: ASSET_CHECKSUM_CONSTRAINT, columns: ['ownerId', 'checksum'], unique: true, - where: '("libraryId" IS NULL)', + where: '"libraryId" IS NULL', }) @Index({ columns: ['ownerId', 'libraryId', 'checksum'], unique: true, - where: '("libraryId" IS NOT NULL)', + where: '"libraryId" IS NOT NULL', }) @Index({ name: 'asset_localDateTime_idx', - expression: `(("localDateTime" at time zone 'UTC')::date)`, + expression: `("localDateTime" at time zone 'UTC')::date`, }) @Index({ name: 'asset_localDateTime_month_idx', - expression: `(date_trunc('MONTH'::text, ("localDateTime" AT TIME ZONE 'UTC'::text)) AT TIME ZONE 'UTC'::text)`, + expression: `date_trunc('MONTH'::text, ("localDateTime" AT TIME ZONE 'UTC'::text)) AT TIME ZONE 'UTC'::text`, }) @Index({ columns: ['originalPath', 'libraryId'] }) @Index({ columns: ['id', 'stackId'] }) diff --git a/server/tsconfig.json b/server/tsconfig.json index 51d57a0dbc..e087544f6b 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -27,5 +27,6 @@ "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo", "noErrorTruncation": true }, + "include": ["src", "test"], "exclude": ["dist", "node_modules", "upload"] }