91 lines
3.2 KiB
TypeScript
91 lines
3.2 KiB
TypeScript
#!/usr/bin/env ts-node
|
|
import path from 'path';
|
|
import fs from 'fs/promises';
|
|
import { initGameDB } from '../routes/games/store';
|
|
|
|
async function main() {
|
|
const gamesDir = path.resolve(__dirname, '../../db/games');
|
|
let files: string[] = [];
|
|
try {
|
|
files = await fs.readdir(gamesDir);
|
|
} catch (e) {
|
|
console.error('Failed to read games dir', gamesDir, e);
|
|
process.exit(2);
|
|
}
|
|
|
|
let db: any;
|
|
try {
|
|
db = await initGameDB();
|
|
} catch (e) {
|
|
console.error('Failed to initialize DB', e);
|
|
process.exit(3);
|
|
}
|
|
|
|
if (!db || !db.sequelize) {
|
|
console.error('DB did not expose sequelize; cannot proceed.');
|
|
process.exit(4);
|
|
}
|
|
|
|
for (const f of files) {
|
|
// ignore dotfiles and keep only .json or numeric filenames
|
|
if (f.startsWith('.')) continue;
|
|
const full = path.join(gamesDir, f);
|
|
try {
|
|
const stat = await fs.stat(full);
|
|
if (!stat.isFile()) continue;
|
|
const raw = await fs.readFile(full, 'utf8');
|
|
const state = JSON.parse(raw);
|
|
// Derive id from filename (strip .json if present)
|
|
const idStr = f.endsWith('.json') ? f.slice(0, -5) : f;
|
|
const id = isNaN(Number(idStr)) ? idStr : Number(idStr);
|
|
const payload = JSON.stringify(state);
|
|
|
|
// Ensure state column exists; attempt a safe ALTER if needed.
|
|
try {
|
|
await db.sequelize.query('ALTER TABLE games ADD COLUMN state TEXT');
|
|
} catch (e) {
|
|
/* ignore: may already exist */
|
|
}
|
|
|
|
// If filename is numeric use id column; otherwise use path column so we don't write strings into an INTEGER id.
|
|
try {
|
|
if (typeof id === 'number') {
|
|
const rows: any[] = await db.sequelize.query('SELECT id FROM games WHERE id=:id', {
|
|
replacements: { id },
|
|
type: db.Sequelize.QueryTypes.SELECT
|
|
});
|
|
if (rows && rows.length) {
|
|
await db.sequelize.query('UPDATE games SET state=:state WHERE id=:id', { replacements: { id, state: payload } });
|
|
console.log(`Updated game id=${id}`);
|
|
} else {
|
|
await db.sequelize.query('INSERT INTO games (id, state) VALUES(:id, :state)', { replacements: { id, state: payload } });
|
|
console.log(`Inserted game id=${id}`);
|
|
}
|
|
} else {
|
|
// use path column to record the filename identifier
|
|
const rows: any[] = await db.sequelize.query('SELECT id FROM games WHERE path=:path', {
|
|
replacements: { path: idStr },
|
|
type: db.Sequelize.QueryTypes.SELECT
|
|
});
|
|
if (rows && rows.length) {
|
|
await db.sequelize.query('UPDATE games SET state=:state WHERE path=:path', { replacements: { path: idStr, state: payload } });
|
|
console.log(`Updated game path=${idStr}`);
|
|
} else {
|
|
await db.sequelize.query('INSERT INTO games (path, state) VALUES(:path, :state)', { replacements: { path: idStr, state: payload } });
|
|
console.log(`Inserted game path=${idStr}`);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to insert/update game', idStr, e);
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to read/parse', full, e);
|
|
}
|
|
}
|
|
|
|
console.log('Import complete');
|
|
process.exit(0);
|
|
}
|
|
|
|
main();
|