duplicated placement data in the attribution table and the ledger scores table. Means that setting placement in the attribution table is meaningless. Probably best to remove the placement in the attribution, or have it reference the placement in the ledger, else return 0. That would mean that the only way to change the scores is in the ledger, which is basically what I want, but also if the db dies then there's not really anything that I can do to recover the scores (same is true for the attribute table, but I can seed that so it doesn't matter as much). To get around that, I would need to add seeding the ledger to a seperate command, which defeats the point of a ledger. Just add a way to import and export the whole ledger to csv, dumbass.
180 lines
5.6 KiB
TypeScript
180 lines
5.6 KiB
TypeScript
import { drizzle } from 'drizzle-orm/libsql';
|
|
import { createClient } from '@libsql/client';
|
|
import * as schema from '../src/lib/server/db/schema.js';
|
|
import { parse } from 'csv-parse/sync';
|
|
import { readFileSync } from 'fs';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join } from 'path';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
const dataDir = join(__dirname, 'data');
|
|
|
|
if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');
|
|
|
|
const client = createClient({ url: process.env.DATABASE_URL });
|
|
const db = drizzle(client, { schema });
|
|
|
|
function readCSV(filename: string): Record<string, string>[] {
|
|
const content = readFileSync(join(dataDir, filename), 'utf-8');
|
|
return parse(content, { columns: true, skip_empty_lines: true });
|
|
}
|
|
|
|
async function seed() {
|
|
console.log('Resetting database...');
|
|
|
|
await client.execute('PRAGMA foreign_keys = OFF');
|
|
|
|
await db.delete(schema.eventAttributions);
|
|
await db.delete(schema.ledgerScores);
|
|
await db.delete(schema.ledger);
|
|
await db.delete(schema.events);
|
|
await db.delete(schema.players);
|
|
await db.delete(schema.scorers);
|
|
await db.delete(schema.scoringPresets);
|
|
await db.delete(schema.divisions);
|
|
await db.delete(schema.teams);
|
|
|
|
await client.execute('DELETE FROM sqlite_sequence');
|
|
|
|
console.log('Database reset complete.');
|
|
|
|
console.log('Seeding teams...');
|
|
const teamsCSV = readCSV('teams.csv');
|
|
for (const row of teamsCSV) {
|
|
const result = await db
|
|
.insert(schema.teams)
|
|
.values({ name: row.name, color: row.color })
|
|
.returning();
|
|
console.log(` Inserted team: ${result[0].name} (id: ${result[0].id})`);
|
|
}
|
|
|
|
console.log('Seeding divisions...');
|
|
const divisionsCSV = readCSV('divisions.csv');
|
|
for (const row of divisionsCSV) {
|
|
const result = await db.insert(schema.divisions).values({ name: row.name }).returning();
|
|
console.log(` Inserted division: ${result[0].name} (id: ${result[0].id})`);
|
|
}
|
|
|
|
console.log('Seeding scoring presets...');
|
|
const scoringPresetsCSV = readCSV('scoringPresets.csv');
|
|
for (const row of scoringPresetsCSV) {
|
|
const result = await db
|
|
.insert(schema.scoringPresets)
|
|
.values({
|
|
presetID: parseInt(row.presetID),
|
|
placement: parseInt(row.placement),
|
|
points: parseInt(row.points)
|
|
})
|
|
.returning();
|
|
console.log(
|
|
` Inserted preset: ${result[0].presetID} placement ${result[0].placement} = ${result[0].points}pts`
|
|
);
|
|
}
|
|
|
|
console.log('Seeding scorers...');
|
|
const scorersCSV = readCSV('scorers.csv');
|
|
for (const row of scorersCSV) {
|
|
const result = await db
|
|
.insert(schema.scorers)
|
|
.values({
|
|
firstName: row.firstName,
|
|
lastName: row.lastName,
|
|
email: row.email,
|
|
password: row.password,
|
|
displayName: row.displayName,
|
|
role: row.role
|
|
})
|
|
.returning();
|
|
console.log(` Inserted scorer: ${result[0].displayName}`);
|
|
}
|
|
|
|
console.log('Seeding players...');
|
|
const teams = await db.select().from(schema.teams);
|
|
const divisions = await db.select().from(schema.divisions);
|
|
const teamMap = new Map(teams.map((t) => [t.name, t.id]));
|
|
const divisionMap = new Map(divisions.map((d) => [d.name, d.id]));
|
|
|
|
const playersCSV = readCSV('players.csv');
|
|
for (const row of playersCSV) {
|
|
const teamId = teamMap.get(row.team);
|
|
const divisionId = divisionMap.get(row.division);
|
|
if (!teamId) throw new Error(`Team "${row.team}" not found`);
|
|
if (!divisionId) throw new Error(`Division "${row.division}" not found`);
|
|
|
|
const result = await db
|
|
.insert(schema.players)
|
|
.values({
|
|
firstName: row.firstName,
|
|
lastName: row.lastName,
|
|
team: teamId,
|
|
division: divisionId
|
|
})
|
|
.returning();
|
|
console.log(` Inserted player: ${result[0].firstName} ${result[0].lastName}`);
|
|
}
|
|
|
|
console.log('Seeding events...');
|
|
const scoringPresets = await db.select().from(schema.scoringPresets);
|
|
const presetMap = new Map(scoringPresets.map((p) => [p.presetID, p.presetID]));
|
|
const divisionMapForEvents = new Map(divisions.map((d) => [d.name, d.id]));
|
|
|
|
const eventsCSV = readCSV('events.csv');
|
|
for (const row of eventsCSV) {
|
|
const preset = parseInt(row.preset);
|
|
const divisionId = divisionMapForEvents.get(row.division);
|
|
if (!divisionId) throw new Error(`Division "${row.division}" not found`);
|
|
|
|
const result = await db
|
|
.insert(schema.events)
|
|
.values({
|
|
name: row.name,
|
|
preset,
|
|
division: divisionId,
|
|
order: parseInt(row.order),
|
|
state: parseInt(row.state)
|
|
})
|
|
.returning();
|
|
console.log(` Inserted event: ${result[0].name}`);
|
|
}
|
|
|
|
console.log('Seeding event attributions...');
|
|
const events = await db.select().from(schema.events);
|
|
const players = await db.select().from(schema.players);
|
|
const eventMap = new Map(events.map((e) => [e.name, e.id]));
|
|
const playerMap = new Map(players.map((p) => [`${p.firstName} ${p.lastName}`, p.id]));
|
|
|
|
const eventAttributionsCSV = readCSV('eventAttributions.csv');
|
|
for (const row of eventAttributionsCSV) {
|
|
const eventId = eventMap.get(row.eventID);
|
|
const playerId = playerMap.get(row.playerID);
|
|
const placement = parseInt(row.placement);
|
|
|
|
if (!eventId) throw new Error(`Event "${row.eventID}" not found`);
|
|
if (!playerId) throw new Error(`Player "${row.playerID}" not found`);
|
|
if (placement <= 0) continue;
|
|
|
|
const result = await db
|
|
.insert(schema.eventAttributions)
|
|
.values({
|
|
eventID: eventId,
|
|
playerID: playerId,
|
|
placement
|
|
})
|
|
.returning();
|
|
console.log(
|
|
` Inserted attribution: event=${row.eventID}, player=${row.playerID}, placement=${placement}`
|
|
);
|
|
}
|
|
|
|
console.log('\nSeeding complete!');
|
|
console.log('Ledger and ledgerScores tables are empty (reset).');
|
|
|
|
await client.close();
|
|
}
|
|
|
|
seed().catch((err) => {
|
|
console.error('Seed failed:', err);
|
|
process.exit(1);
|
|
});
|