فهرست منبع

e2e fix attempt

mertalev 1 سال پیش
والد
کامیت
90bc801c3e

+ 1 - 2
docker/docker-compose.test.yml

@@ -23,8 +23,7 @@ services:
       - database
 
   database:
-    image: postgres:14-alpine@sha256:6a0e35296341e676fe6bd8d236c72afffe2dfe3d7eb9c2405c0f3fc04500cd07
-    command: -c fsync=off
+    image: tensorchord/pgvecto-rs:pg14-v0.1.10
     environment:
       POSTGRES_PASSWORD: postgres
       POSTGRES_USER: postgres

+ 1 - 1
server/src/domain/system-config/system-config.core.ts

@@ -210,7 +210,7 @@ export class SystemConfigCore {
       [FeatureFlag.MAP]: config.map.enabled,
       [FeatureFlag.REVERSE_GEOCODING]: config.reverseGeocoding.enabled,
       [FeatureFlag.SIDECAR]: true,
-      [FeatureFlag.SEARCH]: process.env.TYPESENSE_ENABLED !== 'false',
+      [FeatureFlag.SEARCH]: true,
       [FeatureFlag.TRASH]: config.trash.enabled,
 
       // TODO: use these instead of `POST oauth/config`

+ 2 - 2
server/src/immich/main.ts

@@ -1,5 +1,5 @@
 import { envName, getLogLevels, isDev, serverVersion } from '@app/domain';
-import { RedisIoAdapter, runVectorMigrations } from '@app/infra';
+import { RedisIoAdapter, dataSource } from '@app/infra';
 import { Logger } from '@nestjs/common';
 import { NestFactory } from '@nestjs/core';
 import { NestExpressApplication } from '@nestjs/platform-express';
@@ -29,7 +29,7 @@ export async function bootstrap() {
   app.useStaticAssets('www');
   app.use(indexFallback(excludePaths));
 
-  await runVectorMigrations();
+  await dataSource.query(`SET vectors.enable_prefilter = on`);
 
   const server = await app.listen(port);
   server.requestTimeout = 30 * 60 * 1000;

+ 1 - 26
server/src/infra/database.config.ts

@@ -23,30 +23,5 @@ export const databaseConfig: PostgresConnectionOptions = {
   ...urlOrParts,
 };
 
-export const databaseConfigVector: PostgresConnectionOptions = {
-  ...databaseConfig,
-  migrationsRun: false,
-  migrations: [__dirname + '/migrations/vector/*.{js,ts}'],
-};
-
 // this export is used by TypeORM commands in package.json#scripts
-export let dataSource = new DataSource(databaseConfig);
-
-export async function runVectorMigrations(): Promise<void> {
-  if (!dataSource.isInitialized) {
-    dataSource = await dataSource.initialize();
-  }
-  
-  const hasVectorExtension = (await dataSource.query(
-    `SELECT * FROM pg_available_extensions WHERE name = 'vectors'`,
-  )).length > 0;
-
-  if (hasVectorExtension) {
-    const dataSourceVector = await new DataSource(databaseConfigVector).initialize();
-    await dataSourceVector.runMigrations();
-
-    await dataSourceVector.query(`SET vectors.enable_prefilter = on`);
-
-    await dataSourceVector.destroy();
-  }
-}
+export const dataSource = new DataSource(databaseConfig);

+ 0 - 0
server/src/infra/migrations/vector/1699746198141-UsePgVectors.ts → server/src/infra/migrations/1699746198141-UsePgVectors.ts


+ 0 - 0
server/src/infra/migrations/vector/1699746301742-AddCLIPEmbeddingIndex.ts → server/src/infra/migrations/1699746301742-AddCLIPEmbeddingIndex.ts


+ 0 - 0
server/src/infra/migrations/vector/1699746444644-AddFaceEmbeddingIndex.ts → server/src/infra/migrations/1699746444644-AddFaceEmbeddingIndex.ts


+ 4 - 2
server/src/infra/repositories/person.repository.ts

@@ -227,8 +227,10 @@ export class PersonRepository implements IPersonRepository {
     if (!entity.personId) {
       throw new Error('Person ID is required to create a face');
     }
-    const { embedding, ...face } = entity;
-    await this.assetFaceRepository.insert({ ...face, embedding: () => asVector(embedding, true) });
+    if (!entity.embedding) {
+      throw new Error('Embedding is required to create a face');
+    }
+    await this.assetFaceRepository.insert({ ...entity, embedding: () => asVector(entity.embedding, true) });
     return this.assetFaceRepository.findOneByOrFail({ assetId: entity.assetId, personId: entity.personId });
   }
 

+ 2 - 2
server/test/e2e/asset.e2e-spec.ts

@@ -764,7 +764,7 @@ describe(`${AssetController.name} (e2e)`, () => {
       const personRepository = app.get<IPersonRepository>(IPersonRepository);
       const person = await personRepository.create({ ownerId: asset1.ownerId, name: 'Test Person' });
 
-      await personRepository.createFace({ assetId: asset1.id, personId: person.id });
+      await personRepository.createFace({ assetId: asset1.id, personId: person.id, embedding: Array.from({length: 512}, Math.random) });
 
       const { status, body } = await request(server)
         .put(`/asset/${asset1.id}`)
@@ -1339,7 +1339,7 @@ describe(`${AssetController.name} (e2e)`, () => {
           beforeEach(async () => {
             const personRepository = app.get<IPersonRepository>(IPersonRepository);
             const person = await personRepository.create({ ownerId: asset1.ownerId, name: 'Test Person' });
-            await personRepository.createFace({ assetId: asset1.id, personId: person.id });
+            await personRepository.createFace({ assetId: asset1.id, personId: person.id, embedding: Array.from({length: 512}, Math.random) });
           });
 
           it('should not return asset with facesRecognizedAt unset', async () => {

+ 2 - 2
server/test/e2e/person.e2e-spec.ts

@@ -37,7 +37,7 @@ describe(`${PersonController.name}`, () => {
       name: 'visible_person',
       thumbnailPath: '/thumbnail/face_asset',
     });
-    await personRepository.createFace({ assetId: faceAsset.id, personId: visiblePerson.id });
+    await personRepository.createFace({ assetId: faceAsset.id, personId: visiblePerson.id, embedding: Array.from({length: 512}, Math.random) });
 
     hiddenPerson = await personRepository.create({
       ownerId: loginResponse.userId,
@@ -45,7 +45,7 @@ describe(`${PersonController.name}`, () => {
       isHidden: true,
       thumbnailPath: '/thumbnail/face_asset',
     });
-    await personRepository.createFace({ assetId: faceAsset.id, personId: hiddenPerson.id });
+    await personRepository.createFace({ assetId: faceAsset.id, personId: hiddenPerson.id, embedding: Array.from({length: 512}, Math.random) });
   });
 
   describe('GET /person', () => {

+ 1 - 1
server/test/e2e/server-info.e2e-spec.ts

@@ -81,7 +81,7 @@ describe(`${ServerInfoController.name} (e2e)`, () => {
         oauth: false,
         oauthAutoLaunch: false,
         passwordLogin: true,
-        search: false,
+        search: true,
         sidecar: true,
         tagImage: false,
         trash: true,

+ 1 - 0
server/test/test-utils.ts

@@ -20,6 +20,7 @@ export const db = {
       await dataSource.initialize();
     }
 
+    await dataSource.query(`SET vectors.enable_prefilter = on`);
     await dataSource.transaction(async (em) => {
       const entities = options?.entities || [];
       const tableNames =