87 lines
2.7 KiB
JavaScript
87 lines
2.7 KiB
JavaScript
import Database from 'better-sqlite3';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join } from 'path';
|
|
import { existsSync, mkdirSync } from 'fs';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
/**
|
|
* Initialize the SQLite database with all required tables
|
|
* @param {string} dbPath - Path to the SQLite database file
|
|
* @returns {Database} - The initialized database instance
|
|
*/
|
|
export function initDatabase(dbPath) {
|
|
// Ensure data directory exists
|
|
const dataDir = dirname(dbPath);
|
|
if (!existsSync(dataDir)) {
|
|
mkdirSync(dataDir, { recursive: true });
|
|
}
|
|
|
|
const db = new Database(dbPath);
|
|
|
|
// Enable WAL mode for better concurrent performance
|
|
db.pragma('journal_mode = WAL');
|
|
|
|
// Create tables
|
|
// API keys for agent authentication
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS api_keys (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
key TEXT UNIQUE NOT NULL,
|
|
name TEXT NOT NULL,
|
|
device_prefix TEXT NOT NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
last_used_at DATETIME
|
|
);
|
|
`);
|
|
|
|
// --- MIGRATION: Drop old tables if they exist ---
|
|
// User requested deleting old sensor data but keeping keys.
|
|
db.exec(`
|
|
DROP TABLE IF EXISTS sensor_data;
|
|
DROP TABLE IF EXISTS sensor_data_10m;
|
|
DROP TABLE IF EXISTS sensor_data_1h;
|
|
`);
|
|
|
|
// --- NEW SCHEMA: Sensor Events with RLE support ---
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS sensor_events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
timestamp DATETIME NOT NULL,
|
|
until DATETIME, -- NULL if point, Time if duplicated range end
|
|
device TEXT NOT NULL,
|
|
channel TEXT NOT NULL,
|
|
value REAL, -- Nullable
|
|
data TEXT, -- Nullable (JSON)
|
|
data_type TEXT NOT NULL -- 'number' or 'json'
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sensor_events_search
|
|
ON sensor_events(device, channel, timestamp);
|
|
|
|
-- Phase 2: Authentication & Views
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT UNIQUE NOT NULL,
|
|
password_hash TEXT NOT NULL,
|
|
role TEXT NOT NULL CHECK(role IN ('admin', 'normal')),
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS views (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT UNIQUE NOT NULL,
|
|
config TEXT NOT NULL, -- JSON string of view configuration
|
|
created_by INTEGER,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY(created_by) REFERENCES users(id)
|
|
);
|
|
`);
|
|
|
|
console.log('[DB] Database initialized successfully');
|
|
return db;
|
|
}
|
|
|
|
export default { initDatabase };
|