// 数据库管理器模块 import { Pool } from 'pg'; class DatabaseManager { constructor(config) { this.config = config; this.pool = null; } async connect() { try { // 创建数据库连接池 this.pool = new Pool(this.config); // 测试连接 await this.pool.connect(); console.log('数据库连接池创建成功'); // 初始化表结构 await this.initTables(); } catch (error) { console.error('数据库连接失败:', error); throw error; } } async disconnect() { try { if (this.pool) { await this.pool.end(); console.log('数据库连接池已关闭'); } } catch (error) { console.error('关闭数据库连接池失败:', error); throw error; } } async initTables() { try { const createTableQuery = ` CREATE TABLE IF NOT EXISTS heartbeat ( id SERIAL PRIMARY KEY, component_id VARCHAR(50) NOT NULL, status VARCHAR(20) NOT NULL, timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, data JSONB, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_heartbeat_component_id ON heartbeat(component_id); CREATE INDEX IF NOT EXISTS idx_heartbeat_timestamp ON heartbeat(timestamp); `; await this.pool.query(createTableQuery); console.log('数据库表初始化成功'); } catch (error) { console.error('数据库表初始化失败:', error); throw error; } } async insertHeartbeatData(data) { try { if (!Array.isArray(data)) { data = [data]; } if (data.length === 0) { return; } // 构建批量插入语句 const values = data.map(item => [ item.component_id, item.status, item.timestamp, item.data ]); const query = { text: ` INSERT INTO heartbeat (component_id, status, timestamp, data) VALUES ${values.map((_, index) => `($${index * 4 + 1}, $${index * 4 + 2}, $${index * 4 + 3}, $${index * 4 + 4})`).join(', ')} `, values: values.flat() }; await this.pool.query(query); console.log(`成功插入 ${data.length} 条心跳数据`); } catch (error) { console.error('插入心跳数据失败:', error); throw error; } } async getLatestHeartbeat(componentId) { try { const query = { text: ` SELECT * FROM heartbeat WHERE component_id = $1 ORDER BY timestamp DESC LIMIT 1 `, values: [componentId] }; const result = await this.pool.query(query); return result.rows[0] || null; } catch (error) { console.error('查询最新心跳数据失败:', error); throw error; } } async getHeartbeatHistory(componentId, startTime, endTime) { try { const query = { text: ` SELECT * FROM heartbeat WHERE component_id = $1 AND timestamp BETWEEN $2 AND $3 ORDER BY timestamp DESC `, values: [componentId, startTime, endTime] }; const result = await this.pool.query(query); return result.rows; } catch (error) { console.error('查询心跳历史数据失败:', error); throw error; } } } export { DatabaseManager };