import type { DuckDBConnection } from "@duckdb/node-api"; import type { Manager } from "../manager.ts"; import type { Migration } from "./migration.ts"; import { V001_AddAgents } from "./migrations/V001_AddAgents.ts"; import { V002_AddApplicationWorkers } from "./migrations/V002_AddApplicationWorkers.ts"; import { V003_AddServiceProviders } from "./migrations/V003_AddServiceProviders.ts"; import { V004_AddSoftwares } from "./migrations/V004_AddSoftwares.ts"; export class Migrations { protected connection: Promise; constructor(protected manager: Manager) { this.connection = this.manager.newDatabaseConnection(); } /** * Create migrations table if it does not exist. * @protected */ protected async setupMigrationsTable() { await ( await this.connection ).run(` CREATE OR REPLACE TABLE migrations( id VARCHAR(255) PRIMARY KEY, migrated_at TIMESTAMPTZ DEFAULT NOW() ); `); } /** * Check if the provided migration is executed or not. * @param migrationIdentifier The migration identifier to check for. * @protected */ protected async isExecuted(migrationIdentifier: string): Promise { return ( ( await ( await this.connection ).runAndRead("SELECT id FROM migrations WHERE id = $id", { id: migrationIdentifier, }) ).columnCount > 0 ); } /** * Register the provided migration. * @param MigrationClass Migration class to register. * @protected */ protected async register(MigrationClass: { new (): Migration }) { const migration = new MigrationClass(); if (!(await this.isExecuted(migration.getIdentifier()))) { await migration.execute(await this.connection); } } async execute() { await this.setupMigrationsTable(); await this.register(V001_AddAgents); await this.register(V002_AddApplicationWorkers); await this.register(V003_AddServiceProviders); await this.register(V004_AddSoftwares); } async close() { (await this.connection).closeSync(); } }