Add AI DEV Node deployment foundation
This commit is contained in:
56
server/db/migrate.ts
Normal file
56
server/db/migrate.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { readdir, readFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { closePool, query } from './pool.js';
|
||||
|
||||
const migrationsDir = path.resolve(process.cwd(), 'migrations');
|
||||
|
||||
async function ensureMigrationTable(): Promise<void> {
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
filename VARCHAR(255) PRIMARY KEY,
|
||||
applied_at TIMESTAMP NOT NULL DEFAULT now()
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
async function appliedMigrations(): Promise<Set<string>> {
|
||||
const result = await query<{ filename: string }>('SELECT filename FROM schema_migrations');
|
||||
return new Set(result.rows.map((row) => row.filename));
|
||||
}
|
||||
|
||||
export async function runMigrations(): Promise<void> {
|
||||
await ensureMigrationTable();
|
||||
const applied = await appliedMigrations();
|
||||
const files = (await readdir(migrationsDir))
|
||||
.filter((file) => file.endsWith('.sql'))
|
||||
.sort();
|
||||
|
||||
for (const file of files) {
|
||||
if (applied.has(file)) continue;
|
||||
|
||||
const sql = await readFile(path.join(migrationsDir, file), 'utf8');
|
||||
await query('BEGIN');
|
||||
try {
|
||||
await query(sql);
|
||||
await query('INSERT INTO schema_migrations (filename) VALUES ($1)', [file]);
|
||||
await query('COMMIT');
|
||||
console.log(`Applied migration ${file}`);
|
||||
} catch (error) {
|
||||
await query('ROLLBACK');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
||||
runMigrations()
|
||||
.then(async () => {
|
||||
await closePool();
|
||||
})
|
||||
.catch(async (error: unknown) => {
|
||||
console.error(error);
|
||||
await closePool();
|
||||
process.exitCode = 1;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user