104 lines
3.1 KiB
JavaScript
104 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Migration script to add MQTT credentials and ACL tables
|
|
* This extends the existing database with MQTT provisioning capabilities
|
|
*/
|
|
|
|
const Database = require('better-sqlite3');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
const dataDir = path.join(__dirname, '..', 'data');
|
|
const dbPath = path.join(dataDir, 'database.sqlite');
|
|
|
|
// Check if database exists
|
|
if (!fs.existsSync(dbPath)) {
|
|
console.error('❌ Database not found. Run npm run db:init:app first');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Open database
|
|
const db = new Database(dbPath);
|
|
db.pragma('journal_mode = WAL');
|
|
|
|
console.log('Starting MQTT tables migration...\n');
|
|
|
|
// Create mqtt_credentials table
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS mqtt_credentials (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
device_id TEXT NOT NULL UNIQUE,
|
|
mqtt_username TEXT NOT NULL UNIQUE,
|
|
mqtt_password_hash TEXT NOT NULL,
|
|
enabled INTEGER DEFAULT 1,
|
|
created_at TEXT DEFAULT (datetime('now')),
|
|
updated_at TEXT DEFAULT (datetime('now')),
|
|
|
|
FOREIGN KEY (device_id) REFERENCES Device(id) ON DELETE CASCADE,
|
|
CHECK (enabled IN (0, 1))
|
|
);
|
|
`);
|
|
console.log('✓ Created mqtt_credentials table');
|
|
|
|
// Create mqtt_acl_rules table
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS mqtt_acl_rules (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
device_id TEXT NOT NULL,
|
|
topic_pattern TEXT NOT NULL,
|
|
permission TEXT NOT NULL CHECK(permission IN ('read', 'write', 'readwrite')),
|
|
created_at TEXT DEFAULT (datetime('now')),
|
|
|
|
FOREIGN KEY (device_id) REFERENCES Device(id) ON DELETE CASCADE
|
|
);
|
|
`);
|
|
console.log('✓ Created mqtt_acl_rules table');
|
|
|
|
// Create indexes for performance
|
|
db.exec(`
|
|
CREATE INDEX IF NOT EXISTS idx_mqtt_credentials_device
|
|
ON mqtt_credentials(device_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_mqtt_credentials_username
|
|
ON mqtt_credentials(mqtt_username);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_mqtt_acl_device
|
|
ON mqtt_acl_rules(device_id);
|
|
`);
|
|
console.log('✓ Created indexes');
|
|
|
|
// Create mqtt_sync_status table to track pending changes
|
|
db.exec(`
|
|
CREATE TABLE IF NOT EXISTS mqtt_sync_status (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
pending_changes INTEGER DEFAULT 0,
|
|
last_sync_at TEXT,
|
|
last_sync_status TEXT,
|
|
created_at TEXT DEFAULT (datetime('now')),
|
|
updated_at TEXT DEFAULT (datetime('now'))
|
|
);
|
|
`);
|
|
console.log('✓ Created mqtt_sync_status table');
|
|
|
|
// Initialize sync status
|
|
const syncStatus = db.prepare('SELECT * FROM mqtt_sync_status WHERE id = 1').get();
|
|
if (!syncStatus) {
|
|
db.prepare(`
|
|
INSERT INTO mqtt_sync_status (id, pending_changes, last_sync_status)
|
|
VALUES (1, 0, 'never_synced')
|
|
`).run();
|
|
console.log('✓ Initialized sync status');
|
|
} else {
|
|
console.log('✓ Sync status already exists');
|
|
}
|
|
|
|
// Get stats
|
|
const mqttCredsCount = db.prepare('SELECT COUNT(*) as count FROM mqtt_credentials').get();
|
|
const aclRulesCount = db.prepare('SELECT COUNT(*) as count FROM mqtt_acl_rules').get();
|
|
|
|
console.log(`\n✓ MQTT tables migration completed successfully!`);
|
|
console.log(` MQTT Credentials: ${mqttCredsCount.count}`);
|
|
console.log(` ACL Rules: ${aclRulesCount.count}`);
|
|
|
|
db.close();
|