ddstats-server/libs/database/generate.js

185 lines
7.4 KiB
JavaScript

import { sqlite, skinDB } from './init.js'
import tasks from './tasks.js'
import { execMany } from './helper.js'
import initLog from '../utils/log.js'
const log = initLog("DB Generation")
/**
* This constructs the DB with indexes and rankings...
* @module db/generateDB
*/
export function generateDB() {
if (process.env.GENERATE_DB !== "enabled")
return log("Won't generate the database since 'GENERATE_DB' is not set to \"enabled\" in '.env'!")
const exists = sqlite.prepare(`SELECT count(*) as a FROM sqlite_master WHERE type='table' AND name='points'`).get()
if(exists.a === 1)
return log("Database already generated!")
/* Check if columns are already renamed */
const renamed = sqlite.prepare(`SELECT COUNT(*) AS a FROM pragma_table_info('race') WHERE name='date'`).get()
if(renamed.a === 0) {
log("Renaming columns...")
execMany([
`ALTER TABLE race RENAME COLUMN Map TO map`,
`ALTER TABLE race RENAME COLUMN Name TO player`,
`ALTER TABLE race RENAME COLUMN Time TO time`,
`ALTER TABLE race RENAME COLUMN Timestamp TO date`,
`ALTER TABLE race RENAME COLUMN Server TO server`,
`ALTER TABLE teamrace RENAME COLUMN Map TO map`,
`ALTER TABLE teamrace RENAME COLUMN Name TO player`,
`ALTER TABLE teamrace RENAME COLUMN Time TO time`,
`ALTER TABLE teamrace RENAME COLUMN ID TO id`,
`ALTER TABLE teamrace RENAME COLUMN Timestamp TO date`,
`ALTER TABLE maps RENAME COLUMN Map TO map`,
`ALTER TABLE maps RENAME COLUMN Server TO category`,
`ALTER TABLE maps RENAME COLUMN Points TO points`,
`ALTER TABLE maps RENAME COLUMN Stars TO stars`,
`ALTER TABLE maps RENAME COLUMN Mapper TO mapper`,
`ALTER TABLE maps RENAME COLUMN Timestamp TO release`
])
}
log("Generating race index...")
execMany([
`CREATE INDEX IF NOT EXISTS "idx_race_player" ON "race" ("player")`,
`CREATE INDEX IF NOT EXISTS "idx_race_name" ON "race" ("player", "date")`,
`CREATE INDEX IF NOT EXISTS "idx_race_server" ON "race" ("server")`,
`CREATE INDEX IF NOT EXISTS "idx_race_mapTimestamp" ON "race" ("map", "date")`,
`CREATE INDEX IF NOT EXISTS "idx_race_timestamp" ON "race" ("date")`,
`CREATE INDEX IF NOT EXISTS "idx_race_mapNameTime" ON "race" ("map", "player", "time")`
])
log("Creating rankings table...")
sqlite.exec(`
CREATE TABLE IF NOT EXISTS "rankings" (
"category" varchar(32) NOT NULL,
"points" integer NOT NULL DEFAULT 0,
"map" varchar(128) NOT NULL,
"player" varchar(16) NOT NULL,
"time" float NOT NULL DEFAULT 0,
"date" timestamp NOT NULL DEFAULT current_timestamp,
"server" char(4) NOT NULL DEFAULT '',
"rank" INTEGER NOT NULL,
"finishes" INTEGER NOT NULL DEFAULT 0
)
`)
log("Calculating rankings for each map...")
tasks.processRankings()
log("Generating rankings index...")
execMany([
`CREATE INDEX IF NOT EXISTS "idx_rankings_map" ON "rankings" ("map")`,
`CREATE INDEX IF NOT EXISTS "idx_rankings_rank" ON "rankings" ("rank")`,
`CREATE INDEX IF NOT EXISTS "idx_rankings_player" ON "rankings" ("player")`,
`CREATE INDEX IF NOT EXISTS "idx_rankings_finishes" ON "rankings" ("finishes")`,
`CREATE INDEX IF NOT EXISTS "idx_rankings_mapRank" ON "rankings" ("map", "rank")`
])
log("Generating teamrace index...")
execMany([
`CREATE INDEX IF NOT EXISTS "idx_teamrace_map" ON "teamrace" ("map")`,
`CREATE INDEX IF NOT EXISTS "idx_teamrace_id" ON "teamrace" ("id")`,
`CREATE INDEX IF NOT EXISTS "idx_teamrace_mapID" ON "teamrace" ("map", "id")`
])
log("Creating teamrankings table...")
sqlite.exec(`
CREATE TABLE IF NOT EXISTS "teamrankings" (
"category" varchar(32) NOT NULL,
"points" integer NOT NULL DEFAULT 0,
"map" varchar(128) NOT NULL,
"id" varbinary(16) NOT NULL,
"player" varchar(16) NOT NULL,
"time" float NOT NULL DEFAULT 0,
"date" timestamp NOT NULL DEFAULT current_timestamp,
"server" char(4) NOT NULL DEFAULT '',
"teamrank" INTEGER NOT NULL
)
`)
log("Calculating teamrankings for each map...")
tasks.processTeamRankings()
log("Generating teamrankings index...")
execMany([
`CREATE INDEX IF NOT EXISTS "idx_teamrankings_map" ON "teamrankings" ("map")`,
`CREATE INDEX IF NOT EXISTS "idx_teamrankings_rank" ON "teamrankings" ("teamrank")`,
`CREATE INDEX IF NOT EXISTS "idx_teamrankings_player" ON "teamrankings" ("player")`,
`CREATE INDEX IF NOT EXISTS "idx_teamrankings_playerCategoryMap" ON "teamrankings" ("player", "category", "map")`,
`CREATE INDEX IF NOT EXISTS "idx_teamrankings_mapTeamrank" ON "teamrankings" ("map", "teamrank")`
])
log("Generating graphRecordCache...")
sqlite.exec(`
CREATE TABLE IF NOT EXISTS "graphRecordCache" (
"map" varchar(128) NOT NULL,
"player" varchar(16) NOT NULL,
"time" float NOT NULL DEFAULT 0,
"date" timestamp NOT NULL DEFAULT current_timestamp,
"server" char(4) NOT NULL DEFAULT ''
)
`)
tasks.processTimeGraph()
execMany([
`CREATE INDEX IF NOT EXISTS "idx_graphCache_player" ON "graphRecordCache" ("player")`,
`CREATE INDEX IF NOT EXISTS "idx_graphCache_map" ON "graphRecordCache" ("map")`
])
log("Inserting points to DB...")
tasks.processAllPoints()
log("Generating a new maps table...")
/* Rename the old one as we wanna use that name for the new one*/
sqlite.exec(`ALTER TABLE maps RENAME TO oldmaps`)
sqlite.exec(`
CREATE TABLE IF NOT EXISTS "maps" (
"map" varchar(128) NOT NULL,
"category" varchar(32) NOT NULL,
"points" integer NOT NULL DEFAULT 0,
"stars" integer NOT NULL DEFAULT 0,
"mapper" char(128) NOT NULL,
"release" timestamp NOT NULL DEFAULT current_timestamp,
"avgTime" FLOAT NOT NULL DEFAULT 0,
"medianTime" FLOAT NOT NULL DEFAULT 0,
"topTime" FLOAT NOT NULL DEFAULT 0,
"topTeamTime" FLOAT NOT NULL DEFAULT 0,
"finishesUnique" INTEGER NOT NULL DEFAULT 0,
"finishesTotal" INTEGER NOT NULL DEFAULT 0,
"finishesTeam" INTEGER NOT NULL DEFAULT 0
)
`)
tasks.processMaps()
log("Generating map index...")
execMany([
`CREATE INDEX IF NOT EXISTS "idx_maps_map" ON "maps" ("map")`,
`CREATE INDEX IF NOT EXISTS "idx_maps_category" ON "maps" ("category")`,
`CREATE INDEX IF NOT EXISTS "idx_maps_categoryMap" ON "maps" ("category", "map")`
])
skinDB.exec(`
CREATE TABLE IF NOT EXISTS "skindata" (
"timestamp" INTEGER NOT NULL,
"player" varchar(16) NOT NULL,
"clan" varchar(12) NOT NULL,
"flag" varchar(16) NOT NULL DEFAULT 'default',
"twFlag" INTEGER NOT NULL,
"skin" varchar(16) NOT NULL,
"useColor" INTEGER NOT NULL,
"colorBodyRaw" INTEGER NOT NULL,
"colorBodyHex" varchar(8) NOT NULL,
"colorFeetRaw" INTEGER NOT NULL,
"colorFeetHex" varchar(8) NOT NULL
)
`)
}