stock-management-demo/src-ssr/database.js
2025-04-23 15:55:28 +01:00

110 lines
3.5 KiB
JavaScript

import Database from 'better-sqlite3';
import { join } from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs'; // Needed to check if db file exists
// Determine the database path relative to this file
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const dbPath = join(__dirname, 'forms.db');
let db = null;
export function initializeDatabase() {
if (db) {
return db;
}
try {
// Check if the directory exists, create if not (better-sqlite3 might need this)
const dbDir = join(__dirname);
if (!fs.existsSync(dbDir)) {
fs.mkdirSync(dbDir, { recursive: true });
}
// better-sqlite3 constructor opens/creates the database file
db = new Database(dbPath, { verbose: console.log }); // Enable verbose logging
console.log('Connected to the SQLite database using better-sqlite3.');
// Ensure WAL mode is enabled for better concurrency
db.pragma('journal_mode = WAL');
// Create tables if they don't exist (run sequentially)
db.exec(`
CREATE TABLE IF NOT EXISTS forms (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
formId INTEGER NOT NULL,
name TEXT NOT NULL,
sortOrder INTEGER DEFAULT 0,
FOREIGN KEY (formId) REFERENCES forms (id) ON DELETE CASCADE
);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS fields (
id INTEGER PRIMARY KEY AUTOINCREMENT,
categoryId INTEGER NOT NULL,
label TEXT NOT NULL,
type TEXT NOT NULL CHECK(type IN ('text', 'number', 'date', 'textarea', 'boolean')),
description TEXT,
sortOrder INTEGER NOT NULL,
FOREIGN KEY (categoryId) REFERENCES categories(id) ON DELETE CASCADE
);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS responses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
formId INTEGER NOT NULL,
submittedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (formId) REFERENCES forms (id) ON DELETE CASCADE
);
`);
db.exec(`
CREATE TABLE IF NOT EXISTS response_values (
id INTEGER PRIMARY KEY AUTOINCREMENT,
responseId INTEGER NOT NULL,
fieldId INTEGER NOT NULL,
value TEXT,
FOREIGN KEY (responseId) REFERENCES responses (id) ON DELETE CASCADE,
FOREIGN KEY (fieldId) REFERENCES fields (id) ON DELETE CASCADE
);
`);
console.log('Database tables ensured.');
return db;
} catch (err) {
console.error('Error initializing database with better-sqlite3:', err.message);
throw err; // Re-throw the error
}
}
export function getDb() {
if (!db) {
// Try to initialize if not already done (e.g., during hot reload)
try {
initializeDatabase();
} catch (err) {
throw new Error('Database not initialized and initialization failed.');
}
if (!db) { // Check again after trying to initialize
throw new Error('Database not initialized. Call initializeDatabase first.');
}
}
return db;
}
// Optional: Add a function to close the database gracefully on server shutdown
export function closeDatabase() {
if (db) {
db.close();
db = null;
console.log('Database connection closed.');
}
}