From a5cef78d30c16fd0e012a6087c493ab5fcf3b1b8 Mon Sep 17 00:00:00 2001 From: seb Date: Thu, 29 Oct 2026 03:39:07 +0100 Subject: [PATCH] u --- src/providers/mssql/index.js | 10 ++++++++-- src/providers/mssql/migrate.js | 6 +++++- src/providers/schemaMigrations.js | 13 ++++++++++++- src/providers/sqlite3/index.js | 6 ++++-- src/providers/sqlite3/migrate.js | 6 +++++- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/providers/mssql/index.js b/src/providers/mssql/index.js index 85b99ce..d4bbace 100644 --- a/src/providers/mssql/index.js +++ b/src/providers/mssql/index.js @@ -305,10 +305,16 @@ export class MssqlProvider { } } - async initialize() { + /** + * Initializes the MSSQL schema. + * @param {((message: string) => void) | { log?: (message: string) => void }} [options] + * @returns {Promise} + */ + async initialize(options = {}) { const pool = await this.ensurePool(); + const log = typeof options === 'function' ? options : options?.log; // Versioned upgrades first, so schema.js never meets an outdated table shape. - await upgradeSchema(this); + await upgradeSchema(this, log); const { SCHEMA_SCRIPTS } = await import('./schema.js'); for (const script of SCHEMA_SCRIPTS) { diff --git a/src/providers/mssql/migrate.js b/src/providers/mssql/migrate.js index 730b7e5..3d121d0 100644 --- a/src/providers/mssql/migrate.js +++ b/src/providers/mssql/migrate.js @@ -81,9 +81,13 @@ function makeRunStep(provider) { */ export async function upgradeSchema(provider, log) { const query = (sql, params) => provider.query(sql, params); - if (!(await hasAnyTable(query))) return 0; + if (!(await hasAnyTable(query))) { + log?.(`Fresh database detected; schema will initialize directly at version ${SCHEMA_VERSION}`); + return 0; + } let current = await readSchemaVersion(query); if (current === null) { + log?.(`Existing database has no version row; setting baseline version ${BASE_SCHEMA_VERSION}`); await query(` IF OBJECT_ID(N'dbo.meta', N'U') IS NULL CREATE TABLE meta ([key] NVARCHAR(255) NOT NULL, value NVARCHAR(MAX) NOT NULL, CONSTRAINT PK_meta PRIMARY KEY ([key])); diff --git a/src/providers/schemaMigrations.js b/src/providers/schemaMigrations.js index 770645d..94b7a2b 100644 --- a/src/providers/schemaMigrations.js +++ b/src/providers/schemaMigrations.js @@ -148,6 +148,11 @@ export async function migrateSchema({ direction, dirUrl, current, target, runSte throw new Error(`Cannot ${direction} schema below version ${BASE_SCHEMA_VERSION}`); } + if (current === target) { + log?.(`Schema version ${current} is up to date (no migrations needed)`); + return 0; + } + const byFrom = new Map(listSteps(dirUrl, direction).map((step) => [step.from, step])); const plan = []; for (let version = current; version !== target; ) { @@ -160,14 +165,20 @@ export async function migrateSchema({ direction, dirUrl, current, target, runSte version = step.to; } + log?.(`Starting schema ${direction}: version ${current} -> ${target} (${plan.length} step(s) pending)`); + for (const step of plan) { + const start = performance.now(); const mod = await import(step.url.href); if (typeof mod.default !== 'function') { throw new Error(`Schema ${direction} step ${step.file} must default-export a function`); } await runStep(step, mod.default); - log(`schema ${direction} ${step.from} -> ${step.to} (${step.file})`); + const duration = Math.round(performance.now() - start); + log?.(`Applied schema ${direction} ${step.from} -> ${step.to} (${step.file}) [${duration}ms]`); } + + log?.(`Schema ${direction} completed successfully: database now at version ${target}`); return plan.length; } diff --git a/src/providers/sqlite3/index.js b/src/providers/sqlite3/index.js index febf81e..0e3195e 100644 --- a/src/providers/sqlite3/index.js +++ b/src/providers/sqlite3/index.js @@ -357,11 +357,13 @@ export class BetterSqlite3Provider extends BetterSqlite3Executor { /** * Initializes the native SQLite schema. + * @param {((message: string) => void) | { log?: (message: string) => void }} [options] * @returns {Promise} */ - async initialize() { + async initialize(options = {}) { + const log = typeof options === 'function' ? options : options?.log; // Versioned upgrades first, so schema.js never meets an outdated table shape. - await upgradeSchema(this.db); + await upgradeSchema(this.db, log); for (const script of SCHEMA_SCRIPTS) { if (script && script.trim()) { diff --git a/src/providers/sqlite3/migrate.js b/src/providers/sqlite3/migrate.js index ac24d89..7e393f0 100644 --- a/src/providers/sqlite3/migrate.js +++ b/src/providers/sqlite3/migrate.js @@ -83,9 +83,13 @@ function makeRunStep(db) { * @param {(message: string) => void} [log] */ export async function upgradeSchema(db, log) { - if (!hasAnyTable(db)) return 0; + if (!hasAnyTable(db)) { + log?.(`Fresh database detected; schema will initialize directly at version ${SCHEMA_VERSION}`); + return 0; + } let current = readSchemaVersion(db); if (current === null) { + log?.(`Existing database has no version row; setting baseline version ${BASE_SCHEMA_VERSION}`); db.exec(`CREATE TABLE IF NOT EXISTS meta ("key" TEXT PRIMARY KEY, value TEXT NOT NULL)`); writeSchemaVersion(db, BASE_SCHEMA_VERSION); current = BASE_SCHEMA_VERSION;