1
0

Game import from JSON and listing working

This commit is contained in:
James Ketr 2025-10-06 12:27:26 -07:00
parent 1469282199
commit b3386bab1d
2 changed files with 51 additions and 32 deletions

View File

@ -27,8 +27,8 @@ async function main() {
} }
for (const f of files) { for (const f of files) {
// ignore dotfiles and keep only .json or numeric filenames // ignore dotfiles and .bk backup files (we don't want to import backups)
if (f.startsWith('.')) continue; if (f.startsWith('.') || f.endsWith('.bk')) continue;
const full = path.join(gamesDir, f); const full = path.join(gamesDir, f);
try { try {
const stat = await fs.stat(full); const stat = await fs.stat(full);
@ -38,45 +38,64 @@ async function main() {
// Derive id from filename (strip .json if present) // Derive id from filename (strip .json if present)
const idStr = f.endsWith('.json') ? f.slice(0, -5) : f; const idStr = f.endsWith('.json') ? f.slice(0, -5) : f;
const id = isNaN(Number(idStr)) ? idStr : Number(idStr); const id = isNaN(Number(idStr)) ? idStr : Number(idStr);
const payload = JSON.stringify(state);
// Ensure state column exists; attempt a safe ALTER if needed. // derive a friendly name from the saved state when present
try { const nameCandidate = (state && (state.name || state.id)) ? String(state.name || state.id) : undefined;
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 { try {
if (typeof id === 'number') { if (typeof id === 'number') {
const rows: any[] = await db.sequelize.query('SELECT id FROM games WHERE id=:id', { // numeric filename: use the typed helper
replacements: { id }, await db.saveGameState(id, state);
type: db.Sequelize.QueryTypes.SELECT console.log(`Saved game id=${id}`);
}); if (nameCandidate) {
if (rows && rows.length) { try {
await db.sequelize.query('UPDATE games SET state=:state WHERE id=:id', { replacements: { id, state: payload } }); await db.sequelize.query('UPDATE games SET name=:name WHERE id=:id', { replacements: { id, name: nameCandidate } });
console.log(`Updated game id=${id}`); } catch (_) {
} else { // ignore name update failure
await db.sequelize.query('INSERT INTO games (id, state) VALUES(:id, :state)', { replacements: { id, state: payload } }); }
console.log(`Inserted game id=${id}`);
} }
} else { } else {
// use path column to record the filename identifier // string filename: try to find an existing row by path and save via id;
const rows: any[] = await db.sequelize.query('SELECT id FROM games WHERE path=:path', { // otherwise insert a new row with path and the JSON state.
let found: any[] = [];
try {
found = await db.sequelize.query('SELECT id FROM games WHERE path=:path', {
replacements: { path: idStr }, replacements: { path: idStr },
type: db.Sequelize.QueryTypes.SELECT type: db.Sequelize.QueryTypes.SELECT
}); });
if (rows && rows.length) { } catch (qe) {
await db.sequelize.query('UPDATE games SET state=:state WHERE path=:path', { replacements: { path: idStr, state: payload } }); found = [];
console.log(`Updated game path=${idStr}`); }
if (found && found.length) {
const foundId = found[0].id;
await db.saveGameState(foundId, state);
console.log(`Saved game path=${idStr} -> id=${foundId}`);
if (nameCandidate) {
try {
await db.sequelize.query('UPDATE games SET name=:name WHERE id=:id', { replacements: { id: foundId, name: nameCandidate } });
} catch (_) {
// ignore
}
}
} else {
// ensure state column exists before inserting a new row
try {
await db.sequelize.query('ALTER TABLE games ADD COLUMN state TEXT');
} catch (_) {
// ignore
}
const payload = JSON.stringify(state);
if (nameCandidate) {
await db.sequelize.query('INSERT INTO games (path, state, name) VALUES(:path, :state, :name)', { replacements: { path: idStr, state: payload, name: nameCandidate } });
} else { } else {
await db.sequelize.query('INSERT INTO games (path, state) VALUES(:path, :state)', { replacements: { path: idStr, state: payload } }); await db.sequelize.query('INSERT INTO games (path, state) VALUES(:path, :state)', { replacements: { path: idStr, state: payload } });
}
console.log(`Inserted game path=${idStr}`); console.log(`Inserted game path=${idStr}`);
} }
} }
} catch (e) { } catch (e) {
console.error('Failed to insert/update game', idStr, e); console.error('Failed to save game', idStr, e);
} }
} catch (e) { } catch (e) {
console.error('Failed to read/parse', full, e); console.error('Failed to read/parse', full, e);

View File

@ -37,13 +37,13 @@ async function main() {
if (!gameId) { if (!gameId) {
// List all game ids // List all game ids
try { try {
const rows: any[] = await db.sequelize.query('SELECT id FROM games', { type: db.Sequelize.QueryTypes.SELECT }); const rows: any[] = await db.sequelize.query('SELECT id, name FROM games', { type: db.Sequelize.QueryTypes.SELECT });
if (!rows || rows.length === 0) { if (!rows || rows.length === 0) {
console.log('No games found.'); console.log('No games found.');
return; return;
} }
console.log('Games:'); console.log('Games:');
rows.forEach(r => console.log(` - ${r.id}`)); rows.forEach(r => console.log(`${r.id} - ${r.name}`));
} catch (e) { } catch (e) {
console.error('Failed to list games:', e); console.error('Failed to list games:', e);
process.exit(1); process.exit(1);