56 lines
1.5 KiB
JavaScript
56 lines
1.5 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import process from 'node:process'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
import { closeDb, query, withTransaction } from './client.js'
|
|
|
|
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url))
|
|
const MIGRATIONS_DIR = path.join(CURRENT_DIR, 'migrations')
|
|
|
|
export async function runDatabaseMigrations() {
|
|
const files = fs.readdirSync(MIGRATIONS_DIR)
|
|
.filter((name) => name.endsWith('.sql'))
|
|
.sort()
|
|
|
|
await query(`
|
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
filename TEXT NOT NULL UNIQUE,
|
|
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
)
|
|
`)
|
|
|
|
const appliedRows = await query('SELECT filename FROM schema_migrations')
|
|
const applied = new Set(appliedRows.rows.map((row) => String(row.filename)))
|
|
|
|
for (const filename of files) {
|
|
if (applied.has(filename)) {
|
|
continue
|
|
}
|
|
|
|
const sql = fs.readFileSync(path.join(MIGRATIONS_DIR, filename), 'utf8')
|
|
await withTransaction(async (client) => {
|
|
await client.query(sql)
|
|
await client.query(
|
|
'INSERT INTO schema_migrations (filename, applied_at) VALUES ($1, NOW())',
|
|
[filename],
|
|
)
|
|
})
|
|
}
|
|
}
|
|
|
|
const currentFilePath = fileURLToPath(import.meta.url)
|
|
|
|
if (process.argv[1] && path.resolve(process.argv[1]) === currentFilePath) {
|
|
runDatabaseMigrations()
|
|
.then(async () => {
|
|
await closeDb()
|
|
})
|
|
.catch(async (error) => {
|
|
console.error(error)
|
|
await closeDb()
|
|
process.exit(1)
|
|
})
|
|
}
|