68 lines
2.2 KiB
JavaScript
68 lines
2.2 KiB
JavaScript
const { migrate } = require('drizzle-orm/better-sqlite3/migrator');
|
|
const { drizzle } = require('drizzle-orm/better-sqlite3');
|
|
const Database = require('better-sqlite3');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const dataDir = path.resolve(
|
|
process.env.LEISTUNGSBILANZ_DATA_DIR || 'data'
|
|
);
|
|
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir, { recursive: true });
|
|
|
|
const databasePath = path.join(dataDir, 'leistungsbilanz.db');
|
|
|
|
async function run() {
|
|
const sqlite = new Database(databasePath);
|
|
try {
|
|
if (requiresLinearXlsxBackup(sqlite)) {
|
|
const backupDir = path.join(dataDir, 'backups');
|
|
fs.mkdirSync(backupDir, { recursive: true });
|
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
const backupPath = path.join(
|
|
backupDir,
|
|
`leistungsbilanz-before-linear-xlsx-${timestamp}.db`
|
|
);
|
|
await sqlite.backup(backupPath);
|
|
verifyBackup(backupPath);
|
|
console.log(`Verified pre-migration backup created: ${backupPath}`);
|
|
}
|
|
|
|
migrate(drizzle(sqlite), {
|
|
migrationsFolder: path.resolve('src/db/migrations'),
|
|
});
|
|
} finally {
|
|
sqlite.close();
|
|
}
|
|
console.log('Migrations applied');
|
|
}
|
|
|
|
function requiresLinearXlsxBackup(sqlite) {
|
|
const tables = new Set(
|
|
sqlite.prepare("SELECT name FROM sqlite_master WHERE type = 'table'")
|
|
.all()
|
|
.map((row) => row.name)
|
|
);
|
|
return tables.has('external_csv_configurations') &&
|
|
!tables.has('external_model_configurations');
|
|
}
|
|
|
|
function verifyBackup(backupPath) {
|
|
const backup = new Database(backupPath, { readonly: true, fileMustExist: true });
|
|
try {
|
|
const integrity = backup.pragma('integrity_check', { simple: true });
|
|
const foreignKeyViolations = backup.pragma('foreign_key_check');
|
|
if (integrity !== 'ok' || foreignKeyViolations.length > 0) {
|
|
throw new Error(
|
|
`Pre-migration backup verification failed: integrity=${integrity}, ` +
|
|
`foreign-key violations=${foreignKeyViolations.length}`
|
|
);
|
|
}
|
|
} finally {
|
|
backup.close();
|
|
}
|
|
}
|
|
|
|
run().catch((error) => {
|
|
console.error('Migration failed:', error instanceof Error ? error.message : error);
|
|
process.exit(1);
|
|
});
|