feat: schema versioning with v2 migration (loans, last_played_at)
This commit is contained in:
@@ -5,6 +5,7 @@ import crypto from 'node:crypto'
|
||||
export interface Config {
|
||||
dataDir: string
|
||||
artworkDir: string
|
||||
backupsDir: string
|
||||
dbPath: string
|
||||
port: number
|
||||
sessionSecret: string
|
||||
@@ -15,9 +16,12 @@ export function loadConfig(env: Record<string, string | undefined> = process.env
|
||||
mkdirSync(dataDir, { recursive: true })
|
||||
const artworkDir = path.join(dataDir, 'artwork-cache')
|
||||
mkdirSync(artworkDir, { recursive: true })
|
||||
const backupsDir = path.join(dataDir, 'backups')
|
||||
mkdirSync(backupsDir, { recursive: true })
|
||||
return {
|
||||
dataDir,
|
||||
artworkDir,
|
||||
backupsDir,
|
||||
dbPath: path.join(dataDir, 'record-shop.db'),
|
||||
port: Number(env.PORT ?? 3000),
|
||||
sessionSecret: getOrCreateSecret(dataDir),
|
||||
|
||||
@@ -10,8 +10,7 @@ export function openDatabase(path: string): DB {
|
||||
return db
|
||||
}
|
||||
|
||||
export function migrate(db: DB): void {
|
||||
db.exec(`
|
||||
const BASE_SCHEMA = `
|
||||
CREATE TABLE IF NOT EXISTS app_meta (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
@@ -76,5 +75,42 @@ export function migrate(db: DB): void {
|
||||
album_id INTEGER NOT NULL REFERENCES digital_albums(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (user_id, item_id)
|
||||
);
|
||||
`)
|
||||
`
|
||||
|
||||
function getSchemaVersion(db: DB): number {
|
||||
const row = db.prepare("SELECT value FROM app_meta WHERE key = 'schema_version'").get() as
|
||||
| { value: string }
|
||||
| undefined
|
||||
return row ? Number(row.value) : 0
|
||||
}
|
||||
|
||||
function setSchemaVersion(db: DB, version: number): void {
|
||||
db.prepare(
|
||||
`INSERT INTO app_meta (key, value) VALUES ('schema_version', ?)
|
||||
ON CONFLICT(key) DO UPDATE SET value = excluded.value`
|
||||
).run(String(version))
|
||||
}
|
||||
|
||||
/** Upgrade steps for databases created before schema versioning existed. */
|
||||
export function migrateUpgrades(db: DB): void {
|
||||
const version = getSchemaVersion(db)
|
||||
if (version < 2) {
|
||||
db.exec(`
|
||||
ALTER TABLE digital_albums ADD COLUMN last_played_at TEXT;
|
||||
CREATE TABLE IF NOT EXISTS loans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
item_id INTEGER NOT NULL REFERENCES collection_items(id) ON DELETE CASCADE,
|
||||
borrower TEXT NOT NULL,
|
||||
lent_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
returned_at TEXT
|
||||
);
|
||||
`)
|
||||
setSchemaVersion(db, 2)
|
||||
}
|
||||
}
|
||||
|
||||
export function migrate(db: DB): void {
|
||||
db.exec(BASE_SCHEMA)
|
||||
migrateUpgrades(db)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user