Initial commit: Price Hunter — self-hosted price comparison engine
Complete application scaffolding with: - Backend: Node.js + Fastify + sql.js (SQLite) - Frontend: SvelteKit + Tailwind CSS - Scraper engine with parallel fan-out, rate limiting, cheerio-based parsing - Store management with CSS selector config and per-store test pages - Docker setup for single-command deployment Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
51
src/server/db/migrate.ts
Normal file
51
src/server/db/migrate.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { getDatabase, saveDatabase } from './connection.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export function runMigrations(): void {
|
||||
const db = getDatabase();
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS _migrations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
applied_at TEXT DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
|
||||
const migrationsDir = path.join(__dirname, 'migrations');
|
||||
|
||||
// In production (compiled), migrations may be alongside the compiled JS
|
||||
const altMigrationsDir = path.join(__dirname, '..', '..', '..', 'src', 'server', 'db', 'migrations');
|
||||
const dir = fs.existsSync(migrationsDir) ? migrationsDir : (fs.existsSync(altMigrationsDir) ? altMigrationsDir : null);
|
||||
|
||||
if (!dir) {
|
||||
console.warn('No migrations directory found');
|
||||
return;
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(dir)
|
||||
.filter((f) => f.endsWith('.sql'))
|
||||
.sort();
|
||||
|
||||
const appliedStmt = db.prepare('SELECT name FROM _migrations');
|
||||
const applied = new Set<string>();
|
||||
while (appliedStmt.step()) {
|
||||
applied.add(appliedStmt.getAsObject().name as string);
|
||||
}
|
||||
appliedStmt.free();
|
||||
|
||||
for (const file of files) {
|
||||
if (applied.has(file)) continue;
|
||||
|
||||
const sql = fs.readFileSync(path.join(dir, file), 'utf-8');
|
||||
db.run(sql);
|
||||
db.run('INSERT INTO _migrations (name) VALUES (?)', [file]);
|
||||
console.log(`Migration applied: ${file}`);
|
||||
}
|
||||
|
||||
saveDatabase();
|
||||
}
|
||||
Reference in New Issue
Block a user