import { CamelCasePlugin, Kysely, PostgresDialect } from "kysely"; import { Migrator, type MigrationProvider } from "kysely/migration"; import { Pool } from "pg"; import { readFile } from "node:fs/promises"; import type { CatalogDatabase } from "./repository.js"; import * as initialMigration from "./migrations/001_workspace_databases.js"; import * as catalogTablesMigration from "./migrations/002_catalog_tables.js"; import * as catalogSchemaSyncMigration from "./migrations/003_catalog_schema_sync.js"; import * as catalogRuntimeSequencePrivilegesMigration from "./migrations/004_catalog_runtime_sequence_privileges.js"; import * as descriptionGenerationRunsMigration from "./migrations/005_description_generation_runs.js"; import * as sensitiveDataFlagMigration from "./migrations/006_sensitive_data_flag.js"; import * as sensitivityAnalysisRunsMigration from "./migrations/007_sensitive_data_suggestion_runs.js"; import * as catalogLogicalRelationshipsMigration from "./migrations/008_catalog_logical_relationships.js"; import * as aiTokenUsageMigration from "./migrations/009_ai_token_usage.js"; import * as canonicalModelIdsMigration from "./migrations/010_canonical_model_ids.js"; import * as localSensitivityAnalysisMigration from "./migrations/011_local_sensitivity_analysis.js"; import * as sensitivityReasonMigration from "./migrations/012_sensitivity_reason.js"; import * as catalogPreprocessingStateMigration from "./migrations/013_catalog_preprocessing_state.js"; const connectionString = process.env.THT_CATALOG_MIGRATOR_DATABASE_URL; const host = process.env.THT_CATALOG_DB_HOST; const database = process.env.THT_CATALOG_DB_NAME; const user = process.env.THT_CATALOG_MIGRATOR_USER; const passwordFile = process.env.THT_CATALOG_MIGRATOR_PASSWORD_FILE; if (!connectionString && (!host || !database || !user || !passwordFile)) { throw new Error("catalog migrator database configuration is required"); } const pool = new Pool(connectionString ? { connectionString, max: 1 } : { host, port: Number(process.env.THT_CATALOG_DB_PORT ?? 5432), database, user, password: async () => (await readFile(passwordFile!, "utf8")).trim(), max: 1, }); const db = new Kysely({ dialect: new PostgresDialect({ pool }), plugins: [new CamelCasePlugin()], }); const provider: MigrationProvider = { async getMigrations() { return { "001_workspace_databases": initialMigration, "002_catalog_tables": catalogTablesMigration, "003_catalog_schema_sync": catalogSchemaSyncMigration, "004_catalog_runtime_sequence_privileges": catalogRuntimeSequencePrivilegesMigration, "005_description_generation_runs": descriptionGenerationRunsMigration, "006_sensitive_data_flag": sensitiveDataFlagMigration, "007_sensitive_data_suggestion_runs": sensitivityAnalysisRunsMigration, "008_catalog_logical_relationships": catalogLogicalRelationshipsMigration, "009_ai_token_usage": aiTokenUsageMigration, "010_canonical_model_ids": canonicalModelIdsMigration, "011_local_sensitivity_analysis": localSensitivityAnalysisMigration, "012_sensitivity_reason": sensitivityReasonMigration, "013_catalog_preprocessing_state": catalogPreprocessingStateMigration, }; }, }; try { const result = await new Migrator({ db, provider }).migrateToLatest(); for (const item of result.results ?? []) { process.stdout.write(`${item.migrationName}: ${item.status}\n`); } if (result.error) throw result.error; } finally { await db.destroy(); }