db.js
3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import mysql from 'mysql2/promise'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const CONFIG_FILE = path.join(__dirname, '..', 'connections.json')
// 连接池缓存 { connId: pool }
const pools = new Map()
// 读取连接配置
function loadConnections() {
try {
if (fs.existsSync(CONFIG_FILE)) {
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'))
}
} catch (e) {
console.error('读取连接配置失败:', e.message)
}
return []
}
// 保存连接配置
function saveConnections(connections) {
fs.writeFileSync(CONFIG_FILE, JSON.stringify(connections, null, 2), 'utf-8')
}
// 获取所有连接
export function getConnections() {
return loadConnections()
}
// 新增连接
export function addConnection(conn) {
const connections = loadConnections()
const id = `conn_${Date.now()}`
const newConn = { id, ...conn, createdAt: new Date().toISOString() }
connections.push(newConn)
saveConnections(connections)
return newConn
}
// 删除连接
export function removeConnection(id) {
const connections = loadConnections()
const idx = connections.findIndex(c => c.id === id)
if (idx >= 0) connections.splice(idx, 1)
saveConnections(connections)
closePool(id)
return true
}
// 测试连接
export async function testConnection(conn) {
let connection
try {
connection = await mysql.createConnection({
host: conn.host,
port: Number(conn.port) || 3306,
user: conn.user,
password: conn.password,
database: conn.database,
connectTimeout: 5000,
})
await connection.ping()
return { success: true, message: '连接成功' }
} catch (e) {
return { success: false, message: e.message }
} finally {
if (connection) await connection.end().catch(() => {})
}
}
// 获取连接池
export function getPool(connId) {
if (pools.has(connId)) return pools.get(connId)
const connections = loadConnections()
const conn = connections.find(c => c.id === connId)
if (!conn) throw new Error('连接配置不存在')
const pool = mysql.createPool({
host: conn.host,
port: Number(conn.port) || 3306,
user: conn.user,
password: conn.password,
database: conn.database,
waitForConnections: true,
connectionLimit: 5,
queueLimit: 0,
connectTimeout: 10000,
})
pools.set(connId, pool)
return pool
}
// 关闭连接池
export function closePool(connId) {
const pool = pools.get(connId)
if (pool) {
pool.end().catch(() => {})
pools.delete(connId)
}
}
// 执行SQL查询
export async function executeQuery(connId, sql, params = []) {
const pool = getPool(connId)
const [rows] = await pool.query(sql, params)
return rows
}
// 执行EXPLAIN
export async function executeExplain(connId, sql) {
const pool = getPool(connId)
try {
const [rows] = await pool.query(`EXPLAIN ${sql}`)
return rows
} catch {
// 某些SQL不支持EXPLAIN,尝试EXPLAIN FORMAT=JSON
try {
const [rows] = await pool.query(`EXPLAIN FORMAT=JSON ${sql}`)
return rows
} catch {
return null
}
}
}