Initial commit
This commit is contained in:
124
server/db.js
Normal file
124
server/db.js
Normal file
@@ -0,0 +1,124 @@
|
||||
import Database from 'better-sqlite3';
|
||||
import bcrypt from 'bcrypt';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const DB_PATH = join(__dirname, 'kenteken.db');
|
||||
|
||||
let db;
|
||||
|
||||
export function initDb() {
|
||||
db = new Database(DB_PATH);
|
||||
db.pragma('journal_mode = WAL');
|
||||
db.pragma('foreign_keys = ON');
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS cars (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
width REAL NOT NULL,
|
||||
height REAL NOT NULL,
|
||||
rearWidth REAL,
|
||||
rearHeight REAL
|
||||
)
|
||||
`);
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Seed the database with default cars if empty
|
||||
const count = db.prepare('SELECT COUNT(*) as cnt FROM cars').get();
|
||||
if (count.cnt === 0) {
|
||||
seedDefaultCars();
|
||||
}
|
||||
|
||||
// Set default admin password if not set
|
||||
const pwd = db.prepare("SELECT value FROM settings WHERE key = 'admin_password'").get();
|
||||
if (!pwd) {
|
||||
const hash = bcrypt.hashSync('Rotterdam-010', 10);
|
||||
db.prepare("INSERT INTO settings (key, value) VALUES ('admin_password', ?)").run(hash);
|
||||
}
|
||||
}
|
||||
|
||||
function seedDefaultCars() {
|
||||
const defaultCarsPath = join(__dirname, '..', 'Kenteken-Gen-1-main', 'src', 'frontend', 'carOptions.json');
|
||||
let defaultCars;
|
||||
try {
|
||||
defaultCars = JSON.parse(readFileSync(defaultCarsPath, 'utf-8'));
|
||||
} catch {
|
||||
// Fallback: try from shared-cars.json
|
||||
try {
|
||||
const sharedPath = join(__dirname, '..', 'Kenteken-Gen-1-main', 'shared-cars.json');
|
||||
defaultCars = JSON.parse(readFileSync(sharedPath, 'utf-8'));
|
||||
} catch {
|
||||
defaultCars = [];
|
||||
}
|
||||
}
|
||||
|
||||
const insert = db.prepare(
|
||||
'INSERT INTO cars (name, width, height, rearWidth, rearHeight) VALUES (?, ?, ?, ?, ?)'
|
||||
);
|
||||
const insertMany = db.transaction((cars) => {
|
||||
for (const car of cars) {
|
||||
insert.run(car.name, car.width, car.height, car.rearWidth || null, car.rearHeight || null);
|
||||
}
|
||||
});
|
||||
insertMany(defaultCars);
|
||||
}
|
||||
|
||||
export function getAllCars() {
|
||||
return db.prepare('SELECT * FROM cars ORDER BY name COLLATE NOCASE').all();
|
||||
}
|
||||
|
||||
export function addCar({ name, width, height, rearWidth, rearHeight }) {
|
||||
const result = db.prepare(
|
||||
'INSERT INTO cars (name, width, height, rearWidth, rearHeight) VALUES (?, ?, ?, ?, ?)'
|
||||
).run(name, width, height, rearWidth, rearHeight);
|
||||
return db.prepare('SELECT * FROM cars WHERE id = ?').get(result.lastInsertRowid);
|
||||
}
|
||||
|
||||
export function updateCar(id, { name, width, height, rearWidth, rearHeight }) {
|
||||
const result = db.prepare(
|
||||
'UPDATE cars SET name = ?, width = ?, height = ?, rearWidth = ?, rearHeight = ? WHERE id = ?'
|
||||
).run(name, width, height, rearWidth, rearHeight, id);
|
||||
if (result.changes === 0) return null;
|
||||
return db.prepare('SELECT * FROM cars WHERE id = ?').get(id);
|
||||
}
|
||||
|
||||
export function deleteCar(id) {
|
||||
const result = db.prepare('DELETE FROM cars WHERE id = ?').run(id);
|
||||
return result.changes > 0;
|
||||
}
|
||||
|
||||
export function replaceAllCars(cars) {
|
||||
const tx = db.transaction(() => {
|
||||
db.prepare('DELETE FROM cars').run();
|
||||
const insert = db.prepare(
|
||||
'INSERT INTO cars (name, width, height, rearWidth, rearHeight) VALUES (?, ?, ?, ?, ?)'
|
||||
);
|
||||
for (const car of cars) {
|
||||
insert.run(
|
||||
String(car.name || '').trim(),
|
||||
Number(car.width) || 0,
|
||||
Number(car.height) || 0,
|
||||
car.rearWidth ? Number(car.rearWidth) : null,
|
||||
car.rearHeight ? Number(car.rearHeight) : null
|
||||
);
|
||||
}
|
||||
});
|
||||
tx();
|
||||
}
|
||||
|
||||
export function verifyPassword(password) {
|
||||
const row = db.prepare("SELECT value FROM settings WHERE key = 'admin_password'").get();
|
||||
if (!row) return false;
|
||||
return bcrypt.compareSync(password, row.value);
|
||||
}
|
||||
Reference in New Issue
Block a user