71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
import path from 'node:path';
|
|
import { openSqlite, type SqlDatabase } from '../sqlite';
|
|
|
|
export type { SqlDatabase };
|
|
|
|
const dataDirectory = path.resolve(process.env.LIBRARY_DATA_DIR ?? 'data/library');
|
|
const databasePath = path.join(dataDirectory, 'library.db');
|
|
|
|
const schema = `
|
|
CREATE TABLE IF NOT EXISTS media (
|
|
imdb_id TEXT PRIMARY KEY,
|
|
kind TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'watched',
|
|
rating INTEGER,
|
|
collection TEXT,
|
|
year TEXT,
|
|
genre TEXT,
|
|
runtime TEXT,
|
|
plot TEXT,
|
|
poster_source TEXT,
|
|
added TEXT,
|
|
started TEXT,
|
|
finished TEXT,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
CREATE TABLE IF NOT EXISTS books (
|
|
goodreads_id TEXT PRIMARY KEY,
|
|
title TEXT NOT NULL,
|
|
authors TEXT NOT NULL DEFAULT '[]',
|
|
description TEXT,
|
|
pages INTEGER,
|
|
published TEXT,
|
|
genres TEXT NOT NULL DEFAULT '[]',
|
|
average_rating REAL,
|
|
rating_count INTEGER,
|
|
cover_source TEXT,
|
|
shelf TEXT NOT NULL DEFAULT 'read',
|
|
rating INTEGER,
|
|
series_name TEXT,
|
|
series_url TEXT,
|
|
series_position TEXT,
|
|
added TEXT,
|
|
started TEXT,
|
|
finished TEXT,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
CREATE TABLE IF NOT EXISTS images (
|
|
id TEXT PRIMARY KEY,
|
|
source TEXT NOT NULL,
|
|
content_type TEXT NOT NULL,
|
|
data BLOB NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
`;
|
|
|
|
let opening: Promise<SqlDatabase> | null = null;
|
|
|
|
export function libraryDatabase(): Promise<SqlDatabase> {
|
|
opening ??= openSqlite(databasePath, schema);
|
|
return opening;
|
|
}
|
|
|
|
export function timestamp(): string {
|
|
return new Date().toISOString();
|
|
}
|
|
|
|
export function today(): string {
|
|
return timestamp().slice(0, 10);
|
|
}
|