import type { Database } from "sql.js"; const migrations = [m01_initial]; export default async function executeMigrations(db: Database) { // Check last migration status const migrationsWithNames = migrations.map< [string, (_: Database) => Promise] >((func) => [func.name, func]); let startMigrationAt = 0; try { const rows = await db.exec("SELECT name FROM _migrations LIMIT 1"); if (rows.length < 1) throw new Error("wtf"); const migrationStatus = rows?.[0]; const lastMigrationName = migrationStatus.values[0][0]; console.log("status", migrationStatus); if (lastMigrationName) { const foundIndex = migrationsWithNames.findIndex( ([name]) => name === migrationStatus.values[0][0], ); if (foundIndex >= 0) startMigrationAt = foundIndex + 1; } } catch (e) { // Don't have the table await db.run("BEGIN TRANSACTION"); await db.run(` CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY); INSERT INTO _migrations (name) VALUES (NULL); CREATE TABLE IF NOT EXISTS _appDataVersion (version INTEGER PRIMARY KEY); INSERT INTO _appDataVersion (version) VALUES (NULL); `); await db.exec("COMMIT TRANSACTION"); console.log("Created table."); } console.log(migrationsWithNames); console.log(startMigrationAt); const migrationsToRun = migrationsWithNames.slice(startMigrationAt); console.log(`Running ${migrationsToRun.length} migrations...`); for (const [name, migration] of migrationsToRun) { console.log("Running migration", name); await db.exec("BEGIN TRANSACTION"); await migration(db); await db.exec("UPDATE _migrations SET name = $name", { $name: name }); await db.exec("COMMIT TRANSACTION"); } } async function m01_initial(db: Database) { db.exec(` CREATE TABLE charts ( chart_id INTEGER PRIMARY KEY AUTOINCREMENT ); CREATE TABLE scores ( score_id INTEGER PRIMARY KEY AUTOINCREMENT ); CREATE TABLE banners ( hash TEXT PRIMARY KEY ) `); }