Move meshtastic mqtt project to meshcore usb project
This commit is contained in:
+38
-86
@@ -1,22 +1,19 @@
|
||||
const Database = require('better-sqlite3');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
import Database from 'better-sqlite3';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
// Ensure data directory exists
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const dataDir = path.join(__dirname, '..', '..', 'data');
|
||||
|
||||
if (!fs.existsSync(dataDir)) {
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
}
|
||||
|
||||
const dbPath = path.join(dataDir, 'meshtastic.db');
|
||||
const db = new Database(dbPath);
|
||||
|
||||
// Enable WAL mode for better performance
|
||||
const db = new Database(path.join(dataDir, 'meshcore.db'));
|
||||
db.pragma('journal_mode = WAL');
|
||||
|
||||
// Initialize database schema
|
||||
function initializeDatabase() {
|
||||
// Users table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -27,108 +24,64 @@ function initializeDatabase() {
|
||||
)
|
||||
`);
|
||||
|
||||
// Nodes table - stores information about Meshtastic nodes
|
||||
// Contacts — MeshCore peers identified by their Ed25519 public key (hex)
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
CREATE TABLE IF NOT EXISTS contacts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
node_id TEXT UNIQUE NOT NULL,
|
||||
short_name TEXT,
|
||||
long_name TEXT,
|
||||
hardware_model TEXT,
|
||||
role TEXT,
|
||||
firmware_version TEXT,
|
||||
last_heard DATETIME,
|
||||
battery_level INTEGER,
|
||||
voltage REAL,
|
||||
channel_utilization REAL,
|
||||
air_util_tx REAL,
|
||||
pubkey TEXT UNIQUE NOT NULL,
|
||||
name TEXT,
|
||||
contact_type INTEGER DEFAULT 0,
|
||||
flags INTEGER DEFAULT 0,
|
||||
path_length INTEGER DEFAULT 255,
|
||||
last_advert INTEGER,
|
||||
battery_mv INTEGER,
|
||||
uptime_seconds INTEGER,
|
||||
last_heard DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
|
||||
// Create index on node_id
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_nodes_node_id ON nodes(node_id)
|
||||
`);
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_contacts_pubkey ON contacts(pubkey)`);
|
||||
|
||||
// Positions table - stores GPS position data
|
||||
// Positions — GPS from contact advertisements
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS positions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
node_id TEXT NOT NULL,
|
||||
pubkey TEXT NOT NULL,
|
||||
latitude REAL NOT NULL,
|
||||
longitude REAL NOT NULL,
|
||||
altitude INTEGER,
|
||||
precision_bits INTEGER,
|
||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (node_id) REFERENCES nodes(node_id)
|
||||
FOREIGN KEY (pubkey) REFERENCES contacts(pubkey)
|
||||
)
|
||||
`);
|
||||
|
||||
// Create indexes for positions
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_positions_node_id ON positions(node_id)
|
||||
`);
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_positions_timestamp ON positions(timestamp)
|
||||
`);
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_positions_pubkey ON positions(pubkey)`);
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_positions_timestamp ON positions(timestamp)`);
|
||||
|
||||
// Messages table - stores text messages
|
||||
// Messages — direct (msg_type=0) and channel (msg_type=1)
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
message_id TEXT,
|
||||
from_node TEXT NOT NULL,
|
||||
to_node TEXT,
|
||||
channel INTEGER,
|
||||
from_pubkey TEXT NOT NULL,
|
||||
to_pubkey TEXT,
|
||||
channel_idx INTEGER,
|
||||
msg_type INTEGER NOT NULL DEFAULT 0,
|
||||
text TEXT,
|
||||
rx_time DATETIME,
|
||||
rx_snr REAL,
|
||||
rx_rssi INTEGER,
|
||||
hop_limit INTEGER,
|
||||
want_ack BOOLEAN,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (from_node) REFERENCES nodes(node_id)
|
||||
snr REAL,
|
||||
path_length INTEGER,
|
||||
ack_hash TEXT,
|
||||
delivered INTEGER DEFAULT 0,
|
||||
sender_ts INTEGER,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
|
||||
// Create indexes for messages
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_from_node ON messages(from_node)
|
||||
`);
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at)
|
||||
`);
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_messages_from ON messages(from_pubkey)`);
|
||||
db.exec(`CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at)`);
|
||||
|
||||
// Telemetry table - stores device telemetry data
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS telemetry (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
node_id TEXT NOT NULL,
|
||||
battery_level INTEGER,
|
||||
voltage REAL,
|
||||
channel_utilization REAL,
|
||||
air_util_tx REAL,
|
||||
uptime_seconds INTEGER,
|
||||
temperature REAL,
|
||||
relative_humidity REAL,
|
||||
barometric_pressure REAL,
|
||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (node_id) REFERENCES nodes(node_id)
|
||||
)
|
||||
`);
|
||||
|
||||
// Create indexes for telemetry
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_telemetry_node_id ON telemetry(node_id)
|
||||
`);
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_telemetry_timestamp ON telemetry(timestamp)
|
||||
`);
|
||||
|
||||
// Activity log table
|
||||
// Activity log
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS activity_log (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -144,7 +97,6 @@ function initializeDatabase() {
|
||||
console.log('Database initialized successfully');
|
||||
}
|
||||
|
||||
// Initialize the database
|
||||
initializeDatabase();
|
||||
|
||||
module.exports = db;
|
||||
export default db;
|
||||
|
||||
+97
-246
@@ -1,306 +1,157 @@
|
||||
const db = require('./db');
|
||||
import db from './db.js';
|
||||
|
||||
// User queries
|
||||
const userQueries = {
|
||||
createUser: db.prepare(`
|
||||
INSERT INTO users (username, password_hash)
|
||||
VALUES (?, ?)
|
||||
`),
|
||||
|
||||
getUserByUsername: db.prepare(`
|
||||
SELECT * FROM users WHERE username = ?
|
||||
`),
|
||||
|
||||
updateLastLogin: db.prepare(`
|
||||
UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?
|
||||
`),
|
||||
|
||||
getAllUsers: db.prepare(`
|
||||
SELECT id, username, created_at, last_login FROM users
|
||||
`)
|
||||
export const userQueries = {
|
||||
createUser: db.prepare(`INSERT INTO users (username, password_hash) VALUES (?, ?)`),
|
||||
getUserByUsername: db.prepare(`SELECT * FROM users WHERE username = ?`),
|
||||
updateLastLogin: db.prepare(`UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?`),
|
||||
};
|
||||
|
||||
// Node queries
|
||||
const nodeQueries = {
|
||||
upsertNode: db.prepare(`
|
||||
INSERT INTO nodes (
|
||||
node_id, short_name, long_name, hardware_model, role,
|
||||
firmware_version, last_heard, battery_level, voltage,
|
||||
channel_utilization, air_util_tx, uptime_seconds, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, COALESCE(?, CURRENT_TIMESTAMP), ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT(node_id) DO UPDATE SET
|
||||
short_name = COALESCE(excluded.short_name, short_name),
|
||||
long_name = COALESCE(excluded.long_name, long_name),
|
||||
hardware_model = COALESCE(excluded.hardware_model, hardware_model),
|
||||
role = COALESCE(excluded.role, role),
|
||||
firmware_version = COALESCE(excluded.firmware_version, firmware_version),
|
||||
export const contactQueries = {
|
||||
upsert: db.prepare(`
|
||||
INSERT INTO contacts (pubkey, name, contact_type, flags, path_length, last_advert, last_heard, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT(pubkey) DO UPDATE SET
|
||||
name = COALESCE(excluded.name, name),
|
||||
contact_type = COALESCE(excluded.contact_type, contact_type),
|
||||
flags = COALESCE(excluded.flags, flags),
|
||||
path_length = COALESCE(excluded.path_length, path_length),
|
||||
last_advert = COALESCE(excluded.last_advert, last_advert),
|
||||
last_heard = CURRENT_TIMESTAMP,
|
||||
battery_level = COALESCE(excluded.battery_level, battery_level),
|
||||
voltage = COALESCE(excluded.voltage, voltage),
|
||||
channel_utilization = COALESCE(excluded.channel_utilization, channel_utilization),
|
||||
air_util_tx = COALESCE(excluded.air_util_tx, air_util_tx),
|
||||
uptime_seconds = COALESCE(excluded.uptime_seconds, uptime_seconds),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
`),
|
||||
|
||||
getNodeById: db.prepare(`
|
||||
updateStats: db.prepare(`
|
||||
UPDATE contacts SET battery_mv = ?, uptime_seconds = ?, last_heard = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE pubkey = ?
|
||||
`),
|
||||
|
||||
updateLastHeard: db.prepare(`
|
||||
UPDATE contacts SET last_heard = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE pubkey = ?
|
||||
`),
|
||||
|
||||
getAll: db.prepare(`
|
||||
SELECT
|
||||
n.*,
|
||||
(SELECT latitude FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as latitude,
|
||||
(SELECT longitude FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as longitude,
|
||||
(SELECT altitude FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as altitude,
|
||||
(SELECT timestamp FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as position_timestamp
|
||||
FROM nodes n
|
||||
WHERE n.node_id = ?
|
||||
c.*,
|
||||
(SELECT latitude FROM positions WHERE pubkey = c.pubkey ORDER BY timestamp DESC LIMIT 1) as latitude,
|
||||
(SELECT longitude FROM positions WHERE pubkey = c.pubkey ORDER BY timestamp DESC LIMIT 1) as longitude,
|
||||
(SELECT timestamp FROM positions WHERE pubkey = c.pubkey ORDER BY timestamp DESC LIMIT 1) as position_timestamp
|
||||
FROM contacts c
|
||||
ORDER BY COALESCE(datetime(c.last_heard), datetime('1970-01-01')) DESC
|
||||
`),
|
||||
|
||||
getAllNodes: db.prepare(`
|
||||
getByPubkey: db.prepare(`
|
||||
SELECT
|
||||
n.*,
|
||||
(SELECT latitude FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as latitude,
|
||||
(SELECT longitude FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as longitude,
|
||||
(SELECT altitude FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as altitude,
|
||||
(SELECT timestamp FROM positions WHERE node_id = n.node_id ORDER BY timestamp DESC LIMIT 1) as position_timestamp
|
||||
FROM nodes n
|
||||
ORDER BY
|
||||
COALESCE(datetime(n.last_heard), datetime('1970-01-01')) DESC
|
||||
c.*,
|
||||
(SELECT latitude FROM positions WHERE pubkey = c.pubkey ORDER BY timestamp DESC LIMIT 1) as latitude,
|
||||
(SELECT longitude FROM positions WHERE pubkey = c.pubkey ORDER BY timestamp DESC LIMIT 1) as longitude,
|
||||
(SELECT timestamp FROM positions WHERE pubkey = c.pubkey ORDER BY timestamp DESC LIMIT 1) as position_timestamp
|
||||
FROM contacts c WHERE c.pubkey = ?
|
||||
`),
|
||||
|
||||
updateNodeLastHeard: db.prepare(`
|
||||
UPDATE nodes SET last_heard = CURRENT_TIMESTAMP WHERE node_id = ?
|
||||
deleteOld: db.prepare(`
|
||||
DELETE FROM contacts
|
||||
WHERE datetime(last_heard) < datetime('now', '-' || ? || ' hours')
|
||||
AND pubkey NOT IN (
|
||||
SELECT DISTINCT from_pubkey FROM messages
|
||||
WHERE datetime(created_at) >= datetime('now', '-' || ? || ' hours')
|
||||
)
|
||||
`),
|
||||
|
||||
updateNullLastHeard: db.prepare(`
|
||||
UPDATE nodes
|
||||
SET last_heard = COALESCE(
|
||||
(
|
||||
SELECT MAX(latest_time)
|
||||
FROM (
|
||||
SELECT MAX(created_at) as latest_time FROM messages WHERE from_node = nodes.node_id
|
||||
UNION ALL
|
||||
SELECT MAX(timestamp) as latest_time FROM positions WHERE node_id = nodes.node_id
|
||||
UNION ALL
|
||||
SELECT MAX(timestamp) as latest_time FROM telemetry WHERE node_id = nodes.node_id
|
||||
)
|
||||
),
|
||||
created_at
|
||||
)
|
||||
WHERE last_heard IS NULL
|
||||
`),
|
||||
|
||||
getOldNodesWithData: db.prepare(`
|
||||
SELECT
|
||||
n.node_id,
|
||||
n.last_heard,
|
||||
(SELECT COUNT(*) FROM messages WHERE from_node = n.node_id) as message_count,
|
||||
(SELECT COUNT(*) FROM positions WHERE node_id = n.node_id) as position_count,
|
||||
(SELECT COUNT(*) FROM telemetry WHERE node_id = n.node_id) as telemetry_count
|
||||
FROM nodes n
|
||||
WHERE datetime(last_heard) < datetime('now', '-' || ? || ' hours') OR last_heard IS NULL
|
||||
`),
|
||||
|
||||
deleteOldNodes: db.prepare(`
|
||||
DELETE FROM nodes
|
||||
WHERE (
|
||||
datetime(last_heard) < datetime('now', '-' || ? || ' hours')
|
||||
OR (
|
||||
last_heard IS NULL
|
||||
AND node_id NOT IN (
|
||||
SELECT DISTINCT from_node FROM messages WHERE from_node IS NOT NULL
|
||||
UNION
|
||||
SELECT DISTINCT node_id FROM positions WHERE node_id IS NOT NULL
|
||||
UNION
|
||||
SELECT DISTINCT node_id FROM telemetry WHERE node_id IS NOT NULL
|
||||
)
|
||||
)
|
||||
)
|
||||
AND node_id NOT IN (
|
||||
SELECT DISTINCT from_node FROM messages
|
||||
WHERE from_node IS NOT NULL
|
||||
AND datetime(created_at) >= datetime('now', '-' || ? || ' hours')
|
||||
)
|
||||
AND node_id NOT IN (
|
||||
SELECT DISTINCT node_id FROM positions
|
||||
WHERE node_id IS NOT NULL
|
||||
AND datetime(timestamp) >= datetime('now', '-' || ? || ' hours')
|
||||
)
|
||||
AND node_id NOT IN (
|
||||
SELECT DISTINCT node_id FROM telemetry
|
||||
WHERE node_id IS NOT NULL
|
||||
AND datetime(timestamp) >= datetime('now', '-' || ? || ' hours')
|
||||
)
|
||||
`)
|
||||
};
|
||||
|
||||
// Position queries
|
||||
const positionQueries = {
|
||||
insertPosition: db.prepare(`
|
||||
INSERT INTO positions (node_id, latitude, longitude, altitude, precision_bits)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
export const positionQueries = {
|
||||
insert: db.prepare(`
|
||||
INSERT INTO positions (pubkey, latitude, longitude, altitude) VALUES (?, ?, ?, ?)
|
||||
`),
|
||||
|
||||
getLatestPositions: db.prepare(`
|
||||
SELECT p.*, n.short_name, n.long_name, n.last_heard
|
||||
getLatest: db.prepare(`
|
||||
SELECT p.*, c.name, c.contact_type, c.last_heard
|
||||
FROM positions p
|
||||
LEFT JOIN nodes n ON p.node_id = n.node_id
|
||||
WHERE p.id IN (
|
||||
SELECT MAX(id) FROM positions GROUP BY node_id
|
||||
)
|
||||
LEFT JOIN contacts c ON p.pubkey = c.pubkey
|
||||
WHERE p.id IN (SELECT MAX(id) FROM positions GROUP BY pubkey)
|
||||
ORDER BY p.timestamp DESC
|
||||
`),
|
||||
|
||||
getPositionsByNode: db.prepare(`
|
||||
SELECT * FROM positions
|
||||
WHERE node_id = ?
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT ?
|
||||
getByPubkey: db.prepare(`
|
||||
SELECT * FROM positions WHERE pubkey = ? ORDER BY timestamp DESC LIMIT ?
|
||||
`),
|
||||
|
||||
deleteOldPositions: db.prepare(`
|
||||
DELETE FROM positions WHERE timestamp < datetime('now', '-' || ? || ' hours')
|
||||
`),
|
||||
|
||||
getPositionTrails: db.prepare(`
|
||||
SELECT
|
||||
node_id,
|
||||
latitude,
|
||||
longitude,
|
||||
altitude,
|
||||
timestamp,
|
||||
id
|
||||
getTrails: db.prepare(`
|
||||
SELECT pubkey, latitude, longitude, altitude, timestamp, id
|
||||
FROM (
|
||||
SELECT
|
||||
node_id,
|
||||
latitude,
|
||||
longitude,
|
||||
altitude,
|
||||
timestamp,
|
||||
id,
|
||||
ROW_NUMBER() OVER (PARTITION BY node_id ORDER BY timestamp DESC) as rn
|
||||
SELECT pubkey, latitude, longitude, altitude, timestamp, id,
|
||||
ROW_NUMBER() OVER (PARTITION BY pubkey ORDER BY timestamp DESC) as rn
|
||||
FROM positions
|
||||
) AS ranked
|
||||
WHERE rn <= ?
|
||||
ORDER BY node_id, timestamp DESC
|
||||
`)
|
||||
ORDER BY pubkey, timestamp DESC
|
||||
`),
|
||||
|
||||
deleteOld: db.prepare(`DELETE FROM positions WHERE timestamp < datetime('now', '-' || ? || ' hours')`),
|
||||
};
|
||||
|
||||
// Message queries
|
||||
const messageQueries = {
|
||||
insertMessage: db.prepare(`
|
||||
INSERT INTO messages (
|
||||
message_id, from_node, to_node, channel, text,
|
||||
rx_time, rx_snr, rx_rssi, hop_limit, want_ack
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
export const messageQueries = {
|
||||
insert: db.prepare(`
|
||||
INSERT INTO messages (from_pubkey, to_pubkey, channel_idx, msg_type, text, snr, path_length, ack_hash, sender_ts)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`),
|
||||
|
||||
getRecentMessages: db.prepare(`
|
||||
SELECT m.*,
|
||||
n1.short_name as from_short_name,
|
||||
n1.long_name as from_long_name,
|
||||
n2.short_name as to_short_name,
|
||||
n2.long_name as to_long_name
|
||||
FROM messages m
|
||||
LEFT JOIN nodes n1 ON m.from_node = n1.node_id
|
||||
LEFT JOIN nodes n2 ON m.to_node = n2.node_id
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT ?
|
||||
`),
|
||||
markDelivered: db.prepare(`UPDATE messages SET delivered = 1 WHERE ack_hash = ? AND delivered = 0`),
|
||||
|
||||
getRecentMessagesWithTimeLimit: db.prepare(`
|
||||
SELECT m.*,
|
||||
n1.short_name as from_short_name,
|
||||
n1.long_name as from_long_name,
|
||||
n2.short_name as to_short_name,
|
||||
n2.long_name as to_long_name
|
||||
getRecent: db.prepare(`
|
||||
SELECT m.*, c.name as from_name
|
||||
FROM messages m
|
||||
LEFT JOIN nodes n1 ON m.from_node = n1.node_id
|
||||
LEFT JOIN nodes n2 ON m.to_node = n2.node_id
|
||||
LEFT JOIN contacts c ON m.from_pubkey = c.pubkey
|
||||
WHERE m.created_at >= datetime('now', '-24 hours')
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT ?
|
||||
`),
|
||||
|
||||
getMessagesByNode: db.prepare(`
|
||||
SELECT m.*,
|
||||
n1.short_name as from_short_name,
|
||||
n1.long_name as from_long_name
|
||||
getRecentDirect: db.prepare(`
|
||||
SELECT m.*, c.name as from_name
|
||||
FROM messages m
|
||||
LEFT JOIN nodes n1 ON m.from_node = n1.node_id
|
||||
WHERE m.from_node = ? OR m.to_node = ?
|
||||
LEFT JOIN contacts c ON m.from_pubkey = c.pubkey
|
||||
WHERE m.created_at >= datetime('now', '-24 hours')
|
||||
AND m.msg_type = 0
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT ?
|
||||
`),
|
||||
|
||||
deleteOldMessages: db.prepare(`
|
||||
DELETE FROM messages WHERE created_at < datetime('now', '-' || ? || ' hours')
|
||||
`)
|
||||
};
|
||||
|
||||
// Telemetry queries
|
||||
const telemetryQueries = {
|
||||
insertTelemetry: db.prepare(`
|
||||
INSERT INTO telemetry (
|
||||
node_id, battery_level, voltage, channel_utilization,
|
||||
air_util_tx, uptime_seconds, temperature, relative_humidity,
|
||||
barometric_pressure
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`),
|
||||
|
||||
getLatestTelemetryByNode: db.prepare(`
|
||||
SELECT * FROM telemetry
|
||||
WHERE node_id = ?
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT 1
|
||||
`),
|
||||
|
||||
getTelemetryHistory: db.prepare(`
|
||||
SELECT * FROM telemetry
|
||||
WHERE node_id = ?
|
||||
ORDER BY timestamp DESC
|
||||
getRecentChannel: db.prepare(`
|
||||
SELECT m.*, c.name as from_name
|
||||
FROM messages m
|
||||
LEFT JOIN contacts c ON m.from_pubkey = c.pubkey
|
||||
WHERE m.created_at >= datetime('now', '-24 hours')
|
||||
AND m.msg_type = 1
|
||||
AND m.channel_idx = ?
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT ?
|
||||
`),
|
||||
|
||||
deleteOldTelemetry: db.prepare(`
|
||||
DELETE FROM telemetry WHERE timestamp < datetime('now', '-' || ? || ' hours')
|
||||
`)
|
||||
};
|
||||
|
||||
// Activity log queries
|
||||
const activityLogQueries = {
|
||||
logActivity: db.prepare(`
|
||||
INSERT INTO activity_log (user_id, action, details, ip_address)
|
||||
VALUES (?, ?, ?, ?)
|
||||
getByContact: db.prepare(`
|
||||
SELECT m.*, c.name as from_name
|
||||
FROM messages m
|
||||
LEFT JOIN contacts c ON m.from_pubkey = c.pubkey
|
||||
WHERE m.from_pubkey = ? OR m.to_pubkey = ?
|
||||
ORDER BY m.created_at DESC
|
||||
LIMIT ?
|
||||
`),
|
||||
|
||||
getRecentActivity: db.prepare(`
|
||||
SELECT a.*, u.username
|
||||
FROM activity_log a
|
||||
LEFT JOIN users u ON a.user_id = u.id
|
||||
ORDER BY a.timestamp DESC
|
||||
LIMIT ?
|
||||
`)
|
||||
deleteOld: db.prepare(`DELETE FROM messages WHERE created_at < datetime('now', '-' || ? || ' hours')`),
|
||||
};
|
||||
|
||||
// Statistics queries
|
||||
const statsQueries = {
|
||||
export const statsQueries = {
|
||||
getMessageCount: db.prepare(`SELECT COUNT(*) as count FROM messages`),
|
||||
getNodeCount: db.prepare(`SELECT COUNT(*) as count FROM nodes`),
|
||||
getContactCount: db.prepare(`SELECT COUNT(*) as count FROM contacts`),
|
||||
getPositionCount: db.prepare(`SELECT COUNT(*) as count FROM positions`),
|
||||
|
||||
getDbSize: () => {
|
||||
const result = db.prepare(`
|
||||
SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()
|
||||
`).get();
|
||||
const result = db.prepare(
|
||||
`SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()`
|
||||
).get();
|
||||
return result.size;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
userQueries,
|
||||
nodeQueries,
|
||||
positionQueries,
|
||||
messageQueries,
|
||||
telemetryQueries,
|
||||
activityLogQueries,
|
||||
statsQueries
|
||||
export const activityLogQueries = {
|
||||
log: db.prepare(`INSERT INTO activity_log (user_id, action, details, ip_address) VALUES (?, ?, ?, ?)`),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user