forked from jsnbuchanan/crowd-funder-for-time-pwa
fix Capacitor to use the same migrations (migrations run but accounts aren't created)
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
import { logger } from "@/utils/logger";
|
||||
import { QueryExecResult } from "../interfaces/database";
|
||||
|
||||
interface Migration {
|
||||
name: string;
|
||||
sql: string;
|
||||
@@ -19,46 +16,55 @@ export class MigrationService {
|
||||
return MigrationService.instance;
|
||||
}
|
||||
|
||||
async registerMigration(migration: Migration): Promise<void> {
|
||||
registerMigration(migration: Migration) {
|
||||
this.migrations.push(migration);
|
||||
}
|
||||
|
||||
async runMigrations(
|
||||
sqlExec: (
|
||||
sql: string,
|
||||
params?: unknown[],
|
||||
) => Promise<Array<QueryExecResult>>,
|
||||
/**
|
||||
* @param sqlExec - A function that executes a SQL statement and returns some update result
|
||||
* @param sqlQuery - A function that executes a SQL query and returns the result in some format
|
||||
* @param extractMigrationNames - A function that extracts the names (string array) from a "select name from migrations" query
|
||||
*/
|
||||
async runMigrations<T>(
|
||||
// note that this does not take parameters because the Capacitor SQLite 'execute' is different
|
||||
sqlExec: (sql: string) => Promise<unknown>,
|
||||
sqlQuery: (sql: string) => Promise<T>,
|
||||
extractMigrationNames: (result: T) => Set<string>,
|
||||
): Promise<void> {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("Will run migrations");
|
||||
|
||||
// Create migrations table if it doesn't exist
|
||||
await sqlExec(`
|
||||
const result0 = await sqlExec(`
|
||||
CREATE TABLE IF NOT EXISTS migrations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
`);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("Created migrations table", JSON.stringify(result0));
|
||||
|
||||
// Get list of executed migrations
|
||||
const result: QueryExecResult[] = await sqlExec(
|
||||
"SELECT name FROM migrations;",
|
||||
const result1: T = await sqlQuery("SELECT name FROM migrations;");
|
||||
const executedMigrations = extractMigrationNames(result1);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
"Executed migration select",
|
||||
JSON.stringify(executedMigrations),
|
||||
);
|
||||
let executedMigrations: Set<unknown> = new Set();
|
||||
// Even with that query, the QueryExecResult may be [] (which doesn't make sense to me).
|
||||
if (result.length > 0) {
|
||||
const singleResult = result[0];
|
||||
executedMigrations = new Set(
|
||||
singleResult.values.map((row: unknown[]) => row[0]),
|
||||
);
|
||||
}
|
||||
|
||||
// Run pending migrations in order
|
||||
for (const migration of this.migrations) {
|
||||
if (!executedMigrations.has(migration.name)) {
|
||||
await sqlExec(migration.sql);
|
||||
await sqlExec("INSERT INTO migrations (name) VALUES (?)", [
|
||||
migration.name,
|
||||
]);
|
||||
logger.log(`Migration ${migration.name} executed successfully`);
|
||||
const result2 = await sqlExec(migration.sql);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("Executed migration", JSON.stringify(result2));
|
||||
const result3 = await sqlExec(
|
||||
`INSERT INTO migrations (name) VALUES ('${migration.name}')`,
|
||||
);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("Updated migrations table", JSON.stringify(result3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user