File size: 1,935 Bytes
5c5b371 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import Database from 'better-sqlite3';
import { config } from '../config';
import { logger } from '../logger';
const log = logger.child({ module: 'sqlite-db' });
let db: Database.Database;
export function initSQLiteDB(): Database.Database {
if (db) {
return db;
}
const dbPath = config.sqliteUserStorePath;
if (!dbPath) {
log.error('SQLite user store DB path (SQLITE_USER_STORE_PATH) is not configured.');
throw new Error('SQLite user store DB path is not configured.');
}
log.info({ path: dbPath }, 'Initializing SQLite database for user store...');
db = new Database(dbPath);
// Enable WAL mode for better concurrency and performance.
db.pragma('journal_mode = WAL');
// Create users table
// Note: JSON fields (ip, tokenCounts, etc.) are stored as TEXT.
// Timestamps are stored as INTEGER (Unix epoch milliseconds).
db.exec(`
CREATE TABLE IF NOT EXISTS users (
token TEXT PRIMARY KEY,
ip TEXT, /* JSON string array */
nickname TEXT,
type TEXT NOT NULL CHECK(type IN ('normal', 'special', 'temporary')),
promptCount INTEGER NOT NULL DEFAULT 0,
tokenCounts TEXT, /* JSON string object */
tokenLimits TEXT, /* JSON string object */
tokenRefresh TEXT, /* JSON string object */
createdAt INTEGER NOT NULL,
lastUsedAt INTEGER,
disabledAt INTEGER,
disabledReason TEXT,
expiresAt INTEGER,
maxIps INTEGER,
adminNote TEXT,
meta TEXT /* JSON string object */
);
`);
log.info('SQLite database initialized and `users` table created/verified.');
return db;
}
export function getDB(): Database.Database {
if (!db) {
// This might happen if getDB is called before initSQLiteDB,
// though user-store should ensure init is called first.
log.warn('SQLite DB instance requested before initialization. Attempting to initialize now.');
return initSQLiteDB();
}
return db;
}
|