()
| 125 | |
| 126 | /** Run pending migrations */ |
| 127 | export async function runMigrations(): Promise<void> { |
| 128 | const platform = getPlatformService(); |
| 129 | const db: IDatabase = await platform.loadDatabase( |
| 130 | `sqlite:${await getDatabaseFilePath("readany.db")}`, |
| 131 | ); |
| 132 | |
| 133 | // Create migrations table if not exists |
| 134 | await db.execute(` |
| 135 | CREATE TABLE IF NOT EXISTS schema_migrations ( |
| 136 | version INTEGER PRIMARY KEY, |
| 137 | description TEXT NOT NULL DEFAULT '', |
| 138 | applied_at INTEGER NOT NULL |
| 139 | ) |
| 140 | `); |
| 141 | |
| 142 | // Get current version |
| 143 | const currentVersion = await getSchemaVersion(); |
| 144 | |
| 145 | // Run pending migrations in order |
| 146 | for (const migration of migrations) { |
| 147 | if (migration.version > currentVersion && migration.up) { |
| 148 | const statements = Array.isArray(migration.up) ? migration.up : [migration.up]; |
| 149 | for (const sql of statements) { |
| 150 | try { |
| 151 | await db.execute(sql); |
| 152 | } catch { |
| 153 | // Migration SQL may fail if already applied (e.g., column already exists) |
| 154 | } |
| 155 | } |
| 156 | await db.execute( |
| 157 | "INSERT OR REPLACE INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)", |
| 158 | [migration.version, migration.description, Date.now()], |
| 159 | ); |
| 160 | } |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | /** Get current schema version */ |
| 165 | export async function getSchemaVersion(): Promise<number> { |
nothing calls this directly
no test coverage detected