Replace DB-backed instrument upserts with app.yaml-driven config loading, matching, and translator application in the ingestion workflow. Also add serial-port connector support, startup validation tooling, and migration tracking updates to keep runtime behavior and docs aligned.
84 lines
2.1 KiB
JavaScript
84 lines
2.1 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const DatabaseClient = require('./db');
|
|
const config = require('../../config/app');
|
|
|
|
const LOCK_MIGRATION_FILE = '002_outbox_locks.sql';
|
|
|
|
async function ensureMigrationTable(db) {
|
|
await db.exec(`
|
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
filename TEXT PRIMARY KEY,
|
|
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
`);
|
|
}
|
|
|
|
async function migrationIsApplied(db, filename) {
|
|
const row = await db.get(
|
|
'SELECT filename FROM schema_migrations WHERE filename = ? LIMIT 1',
|
|
[filename]
|
|
);
|
|
return Boolean(row);
|
|
}
|
|
|
|
async function markMigrationApplied(db, filename) {
|
|
await db.run(
|
|
'INSERT OR IGNORE INTO schema_migrations (filename) VALUES (?)',
|
|
[filename]
|
|
);
|
|
}
|
|
|
|
async function applyOutboxLockMigration(db) {
|
|
const columns = await db.all('PRAGMA table_info(outbox_result)');
|
|
const columnNames = new Set(columns.map((column) => column.name));
|
|
|
|
if (!columnNames.has('locked_at')) {
|
|
await db.exec('ALTER TABLE outbox_result ADD COLUMN locked_at INTEGER NULL;');
|
|
}
|
|
|
|
if (!columnNames.has('locked_by')) {
|
|
await db.exec('ALTER TABLE outbox_result ADD COLUMN locked_by TEXT NULL;');
|
|
}
|
|
}
|
|
|
|
async function migrate() {
|
|
const db = new DatabaseClient(config.db);
|
|
const migrationsDir = path.join(__dirname, '..', '..', 'db', 'migrations');
|
|
const files = fs
|
|
.readdirSync(migrationsDir)
|
|
.filter((name) => name.endsWith('.sql'))
|
|
.sort();
|
|
|
|
await ensureMigrationTable(db);
|
|
|
|
for (const file of files) {
|
|
if (await migrationIsApplied(db, file)) {
|
|
continue;
|
|
}
|
|
|
|
if (file === LOCK_MIGRATION_FILE) {
|
|
await applyOutboxLockMigration(db);
|
|
await markMigrationApplied(db, file);
|
|
continue;
|
|
}
|
|
|
|
const payload = fs.readFileSync(path.join(migrationsDir, file), 'utf8');
|
|
await db.exec(payload);
|
|
await markMigrationApplied(db, file);
|
|
}
|
|
|
|
await db.close();
|
|
}
|
|
|
|
if (require.main === module) {
|
|
migrate()
|
|
.then(() => console.log('migrations applied'))
|
|
.catch((err) => {
|
|
console.error('migration failed', err);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
module.exports = migrate;
|