101 lines
2.7 KiB
TypeScript
101 lines
2.7 KiB
TypeScript
import 'dotenv/config';
|
|
import { closeSync, existsSync, mkdirSync, openSync } from 'fs';
|
|
import { dirname, resolve } from 'path';
|
|
import { spawnSync } from 'child_process';
|
|
import Database from 'better-sqlite3';
|
|
|
|
const dbType = process.env.DB_TYPE || 'sqlite';
|
|
const dbPath = process.env.DATABASE_URL || './data/spanglish.db';
|
|
const BACKUP_DIR = resolve(process.cwd(), 'data', 'backups');
|
|
|
|
function parseArgs(): { output?: string } {
|
|
const args = process.argv.slice(2);
|
|
const result: { output?: string } = {};
|
|
for (let i = 0; i < args.length; i++) {
|
|
if (args[i] === '-o' || args[i] === '--output') {
|
|
result.output = args[i + 1];
|
|
i++;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function getTimestamp(): string {
|
|
const now = new Date();
|
|
const y = now.getFullYear();
|
|
const m = String(now.getMonth() + 1).padStart(2, '0');
|
|
const d = String(now.getDate()).padStart(2, '0');
|
|
const h = String(now.getHours()).padStart(2, '0');
|
|
const min = String(now.getMinutes()).padStart(2, '0');
|
|
const s = String(now.getSeconds()).padStart(2, '0');
|
|
return `${y}-${m}-${d}-${h}${min}${s}`;
|
|
}
|
|
|
|
function exportSqlite(outputPath: string): void {
|
|
const db = new Database(resolve(process.cwd(), dbPath), { readonly: true });
|
|
try {
|
|
db.backup(outputPath);
|
|
console.log(`Exported to ${outputPath}`);
|
|
} finally {
|
|
db.close();
|
|
}
|
|
}
|
|
|
|
function exportPostgres(outputPath: string): void {
|
|
const connString = process.env.DATABASE_URL || 'postgresql://localhost:5432/spanglish';
|
|
const outFd = openSync(outputPath, 'w');
|
|
try {
|
|
const result = spawnSync(
|
|
'pg_dump',
|
|
['--clean', '--if-exists', connString],
|
|
{
|
|
stdio: ['ignore', outFd, 'pipe'],
|
|
encoding: 'utf-8',
|
|
}
|
|
);
|
|
|
|
if (result.error) {
|
|
console.error('pg_dump failed. Ensure pg_dump is installed and in PATH.');
|
|
console.error(result.error.message);
|
|
process.exit(1);
|
|
}
|
|
|
|
if (result.status !== 0) {
|
|
console.error('pg_dump failed:', result.stderr);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(`Exported to ${outputPath}`);
|
|
} finally {
|
|
closeSync(outFd);
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const { output } = parseArgs();
|
|
const ext = dbType === 'postgres' ? '.sql' : '.db';
|
|
const defaultName = `spanglish-${getTimestamp()}${ext}`;
|
|
|
|
const outputPath = output
|
|
? resolve(process.cwd(), output)
|
|
: resolve(BACKUP_DIR, defaultName);
|
|
|
|
const dir = dirname(outputPath);
|
|
if (!existsSync(dir)) {
|
|
mkdirSync(dir, { recursive: true });
|
|
}
|
|
|
|
console.log(`Database type: ${dbType}`);
|
|
if (dbType === 'sqlite') {
|
|
exportSqlite(outputPath);
|
|
} else {
|
|
exportPostgres(outputPath);
|
|
}
|
|
process.exit(0);
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('Export failed:', err);
|
|
process.exit(1);
|
|
});
|