feat: schema-check (#25904)

This commit is contained in:
Jason Rasmussen
2026-02-12 17:59:00 -05:00
committed by GitHub
parent 7413356a2f
commit 8ef4e4d452
37 changed files with 449 additions and 213 deletions
@@ -19,7 +19,9 @@ import { GenerateSql } from 'src/decorators';
import { DatabaseExtension, DatabaseLock, VectorIndex } from 'src/enum';
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 { schemaDiff, schemaFromCode, schemaFromDatabase } from 'src/sql-tools';
import { ExtensionVersion, VectorExtension, VectorUpdateResult } from 'src/types';
import { vectorIndexQuery } from 'src/utils/database';
import { isValidInteger } from 'src/validation';
@@ -281,6 +283,27 @@ export class DatabaseRepository {
return rows[0].db;
}
getMigrations() {
return this.db.selectFrom('kysely_migrations').select(['name', 'timestamp']).orderBy('name', 'asc').execute();
}
async getSchemaDrift() {
const source = schemaFromCode({ overrides: true, namingStrategy: 'default' });
const target = await schemaFromDatabase(this.db, {});
const drift = schemaDiff(source, target, {
tables: { ignoreExtra: true },
constraints: { ignoreExtra: false },
indexes: { ignoreExtra: true },
triggers: { ignoreExtra: true },
columns: { ignoreExtra: true },
functions: { ignoreExtra: false },
parameters: { ignoreExtra: true },
});
return drift;
}
async getDimensionSize(table: string, column = 'embedding'): Promise<number> {
const { rows } = await sql<{ dimsize: number }>`
SELECT atttypmod as dimsize
@@ -106,7 +106,7 @@ export class MetadataRepository {
readTags(path: string): Promise<ImmichTags> {
const args = mimeTypes.isVideo(path) ? ['-ee'] : [];
return this.exiftool.read(path, args).catch((error) => {
return this.exiftool.read(path, { readArgs: args }).catch((error) => {
this.logger.warn(`Error reading exif data (${path}): ${error}\n${error?.stack}`);
return {};
}) as Promise<ImmichTags>;