makerstash/server/database.js

254 lines
7.7 KiB
JavaScript

import sqlite3 from 'sqlite3';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import dotenv from 'dotenv';
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const dbPath = process.env.DATABASE_PATH || join(__dirname, '..', 'database.sqlite');
const db = new sqlite3.Database(dbPath, (err) => {
if (err) {
console.error('Error opening database:', err.message);
} else {
console.log('Connected to SQLite database');
initDatabase();
}
});
function initDatabase() {
db.serialize(() => {
// Users table
db.run(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
theme TEXT DEFAULT 'light',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Collections table (with nested support)
db.run(`
CREATE TABLE IF NOT EXISTS collections (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
parent_id INTEGER,
user_id INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (parent_id) REFERENCES collections(id) ON DELETE CASCADE
)
`);
// Tags table
db.run(`
CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
color TEXT DEFAULT '#6c757d'
)
`);
// Models table
db.run(`
CREATE TABLE IF NOT EXISTS models (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
file_path TEXT NOT NULL,
file_name TEXT NOT NULL,
file_size INTEGER,
file_type TEXT,
preview_image TEXT,
creator TEXT,
source_url TEXT,
notes TEXT,
is_supported BOOLEAN DEFAULT 0,
license TEXT DEFAULT 'Unknown',
user_id INTEGER,
collection_id INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (collection_id) REFERENCES collections(id)
)
`);
// Model tags junction table
db.run(`
CREATE TABLE IF NOT EXISTS model_tags (
model_id INTEGER,
tag_id INTEGER,
PRIMARY KEY (model_id, tag_id),
FOREIGN KEY (model_id) REFERENCES models(id) ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
)
`);
// Model files table (for multi-file models)
db.run(`
CREATE TABLE IF NOT EXISTS model_files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
model_id INTEGER,
file_path TEXT NOT NULL,
file_name TEXT NOT NULL,
file_size INTEGER,
file_type TEXT,
is_primary BOOLEAN DEFAULT 0,
FOREIGN KEY (model_id) REFERENCES models(id) ON DELETE CASCADE
)
`);
// Print queue table
db.run(`
CREATE TABLE IF NOT EXISTS print_queue (
id INTEGER PRIMARY KEY AUTOINCREMENT,
model_id INTEGER,
user_id INTEGER,
priority INTEGER DEFAULT 0,
status TEXT DEFAULT 'pending',
notes TEXT,
added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
completed_at DATETIME,
FOREIGN KEY (model_id) REFERENCES models(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id)
)
`);
// Printer settings table
db.run(`
CREATE TABLE IF NOT EXISTS printer_settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
printer_type TEXT,
printer_name TEXT,
access_token TEXT,
serial_number TEXT,
model_name TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)
`);
// Migration: Add is_primary column to model_files if it doesn't exist
db.all("PRAGMA table_info(model_files)", [], (err, columns) => {
if (err) {
console.error('Error checking model_files schema:', err);
return;
}
const hasIsPrimary = columns.some(col => col.name === 'is_primary');
if (!hasIsPrimary) {
db.run('ALTER TABLE model_files ADD COLUMN is_primary BOOLEAN DEFAULT 0', (err) => {
if (err) {
console.error('Error adding is_primary column:', err);
} else {
console.log('Added is_primary column to model_files table');
}
});
}
});
// Migration: Add parent_id column to collections if it doesn't exist
db.all("PRAGMA table_info(collections)", [], (err, columns) => {
if (err) {
console.error('Error checking collections schema:', err);
return;
}
const hasParentId = columns.some(col => col.name === 'parent_id');
if (!hasParentId) {
db.run('ALTER TABLE collections ADD COLUMN parent_id INTEGER REFERENCES collections(id) ON DELETE CASCADE', (err) => {
if (err) {
console.error('Error adding parent_id column:', err);
} else {
console.log('Added parent_id column to collections table');
}
});
}
});
// Migration: Add license column to models if it doesn't exist
db.all("PRAGMA table_info(models)", [], (err, columns) => {
if (err) {
console.error('Error checking models schema:', err);
return;
}
const hasLicense = columns.some(col => col.name === 'license');
if (!hasLicense) {
db.run('ALTER TABLE models ADD COLUMN license TEXT DEFAULT \'Unknown\'', (err) => {
if (err) {
console.error('Error adding license column:', err);
} else {
console.log('Added license column to models table');
}
});
}
});
// Migration: Add theme column to users if it doesn't exist
db.all("PRAGMA table_info(users)", [], (err, columns) => {
if (err) {
console.error('Error checking users schema:', err);
return;
}
const hasTheme = columns.some(col => col.name === 'theme');
if (!hasTheme) {
db.run('ALTER TABLE users ADD COLUMN theme TEXT DEFAULT \'light\'', (err) => {
if (err) {
console.error('Error adding theme column:', err);
} else {
console.log('Added theme column to users table');
}
});
}
});
// Migration: Add print specifications columns to print_queue if they don't exist
db.all("PRAGMA table_info(print_queue)", [], (err, columns) => {
if (err) {
console.error('Error checking print_queue schema:', err);
return;
}
const newColumns = {
quantity: 'INTEGER DEFAULT 1',
filament_type: 'TEXT',
color: 'TEXT',
print_temp: 'INTEGER',
bed_temp: 'INTEGER',
print_speed: 'TEXT DEFAULT \'normal\'',
support_structure: 'TEXT DEFAULT \'none\'',
infill_density: 'INTEGER DEFAULT 20',
layer_height: 'REAL DEFAULT 0.2',
special_instructions: 'TEXT'
};
Object.entries(newColumns).forEach(([colName, colDef]) => {
const hasColumn = columns.some(col => col.name === colName);
if (!hasColumn) {
db.run(`ALTER TABLE print_queue ADD COLUMN ${colName} ${colDef}`, (err) => {
if (err) {
console.error(`Error adding ${colName} column:`, err);
} else {
console.log(`Added ${colName} column to print_queue table`);
}
});
}
});
});
console.log('Database tables initialized');
});
}
export default db;