mm_mysql 2.2.3 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/db.js +2 -52
- package/index.js +15 -41
- package/package.json +1 -1
- package/test.js +0 -1
package/db.js
CHANGED
|
@@ -14,8 +14,8 @@ class DB extends Sql {
|
|
|
14
14
|
constructor(mysql) {
|
|
15
15
|
// 正确绑定run和exec方法的上下文
|
|
16
16
|
super(
|
|
17
|
-
mysql.run
|
|
18
|
-
mysql.exec
|
|
17
|
+
mysql.run,
|
|
18
|
+
mysql.exec
|
|
19
19
|
);
|
|
20
20
|
// 保存mysql实例引用
|
|
21
21
|
this._mysql = mysql;
|
|
@@ -76,56 +76,6 @@ DB.prototype.new = function (table, key) {
|
|
|
76
76
|
return db;
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
/**
|
|
80
|
-
* 执行SQL查询
|
|
81
|
-
* @param {String} sql - SQL语句
|
|
82
|
-
* @param {Array} params - 参数数组
|
|
83
|
-
* @returns {Promise<Array>}
|
|
84
|
-
* @throws {TypeError} 当sql参数无效时
|
|
85
|
-
*/
|
|
86
|
-
DB.prototype.run = async function(sql, params = []) {
|
|
87
|
-
// 参数校验
|
|
88
|
-
if (typeof sql !== 'string' || sql.trim() === '') {
|
|
89
|
-
throw new TypeError('sql must be non-empty string');
|
|
90
|
-
}
|
|
91
|
-
if (!Array.isArray(params)) {
|
|
92
|
-
throw new TypeError('params must be array');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
return await this._mysql.run(sql, params);
|
|
97
|
-
} catch (error) {
|
|
98
|
-
this.logger('error', 'SQL执行失败', error);
|
|
99
|
-
// 返回空数组作为默认值,保持返回值类型一致
|
|
100
|
-
return [];
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 执行SQL语句
|
|
106
|
-
* @param {String} sql - SQL语句
|
|
107
|
-
* @param {Array} params - 参数数组
|
|
108
|
-
* @returns {Promise<Object>}
|
|
109
|
-
* @throws {TypeError} 当sql参数无效时
|
|
110
|
-
*/
|
|
111
|
-
DB.prototype.exec = async function(sql, params = []) {
|
|
112
|
-
// 参数校验
|
|
113
|
-
if (typeof sql !== 'string' || sql.trim() === '') {
|
|
114
|
-
throw new TypeError('sql must be non-empty string');
|
|
115
|
-
}
|
|
116
|
-
if (!Array.isArray(params)) {
|
|
117
|
-
throw new TypeError('params must be array');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
return await this._mysql.exec(sql, params);
|
|
122
|
-
} catch (error) {
|
|
123
|
-
this.logger('error', 'SQL执行失败', error);
|
|
124
|
-
// 返回空数组作为默认值,保持返回值类型一致
|
|
125
|
-
return 0;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
79
|
/**
|
|
130
80
|
* 获取数据库连接
|
|
131
81
|
* @returns {Promise<Object>}
|
package/index.js
CHANGED
|
@@ -40,13 +40,6 @@ class Mysql extends Base {
|
|
|
40
40
|
this._pool = null;
|
|
41
41
|
this._connection = null;
|
|
42
42
|
this._usePool = this.config.connection_limit > 1;
|
|
43
|
-
this._pool_stats = {
|
|
44
|
-
total_connections: 0,
|
|
45
|
-
active_connections: 0,
|
|
46
|
-
idle_connections: 0,
|
|
47
|
-
connection_errors: 0,
|
|
48
|
-
last_health_check: null
|
|
49
|
-
};
|
|
50
43
|
}
|
|
51
44
|
}
|
|
52
45
|
|
|
@@ -168,21 +161,15 @@ Mysql.prototype.close = async function () {
|
|
|
168
161
|
* @param {boolean} is_pool_conn - 是否为连接池连接
|
|
169
162
|
* @returns {Promise<void>}
|
|
170
163
|
*/
|
|
171
|
-
|
|
164
|
+
async function safeReleaseConnection(conn, is_pool_conn) {
|
|
172
165
|
if (!conn) return;
|
|
173
166
|
|
|
174
167
|
try {
|
|
175
168
|
if (is_pool_conn && typeof conn.release === 'function') {
|
|
176
169
|
await conn.release();
|
|
177
|
-
// 更新统计信息
|
|
178
|
-
if (this._pool_stats.active_connections > 0) {
|
|
179
|
-
this._pool_stats.active_connections--;
|
|
180
|
-
}
|
|
181
|
-
this._pool_stats.idle_connections++;
|
|
182
170
|
}
|
|
183
171
|
} catch (release_err) {
|
|
184
|
-
|
|
185
|
-
this._pool_stats.connection_errors++;
|
|
172
|
+
$.log.error('释放连接失败', release_err);
|
|
186
173
|
}
|
|
187
174
|
};
|
|
188
175
|
|
|
@@ -200,19 +187,12 @@ Mysql.prototype.getConn = async function () {
|
|
|
200
187
|
try {
|
|
201
188
|
if (this._usePool) {
|
|
202
189
|
const conn = await this._pool.getConnection();
|
|
203
|
-
// 更新统计信息
|
|
204
|
-
this._pool_stats.total_connections++;
|
|
205
|
-
this._pool_stats.active_connections++;
|
|
206
|
-
if (this._pool_stats.idle_connections > 0) {
|
|
207
|
-
this._pool_stats.idle_connections--;
|
|
208
|
-
}
|
|
209
190
|
return conn;
|
|
210
191
|
} else {
|
|
211
192
|
return this._connection;
|
|
212
193
|
}
|
|
213
194
|
} catch (error) {
|
|
214
195
|
this.logger('error', '获取连接失败', error);
|
|
215
|
-
this._pool_stats.connection_errors++;
|
|
216
196
|
}
|
|
217
197
|
return null;
|
|
218
198
|
};
|
|
@@ -247,7 +227,6 @@ Mysql.prototype.run = async function (sql, params = []) {
|
|
|
247
227
|
const [rows] = await conn.query(sql, params);
|
|
248
228
|
return rows;
|
|
249
229
|
} catch (err) {
|
|
250
|
-
this.logger('error', 'SQL执行失败', err);
|
|
251
230
|
this.sql = err.sql;
|
|
252
231
|
this.error = {
|
|
253
232
|
code: err.errno,
|
|
@@ -255,7 +234,7 @@ Mysql.prototype.run = async function (sql, params = []) {
|
|
|
255
234
|
};
|
|
256
235
|
// 在错误情况下也要确保连接释放
|
|
257
236
|
try {
|
|
258
|
-
await
|
|
237
|
+
await safeReleaseConnection(conn, is_pool_conn);
|
|
259
238
|
} catch (release_err) {
|
|
260
239
|
this.logger('error', '释放连接失败', release_err);
|
|
261
240
|
}
|
|
@@ -264,7 +243,7 @@ Mysql.prototype.run = async function (sql, params = []) {
|
|
|
264
243
|
// 确保连接被释放,避免资源泄漏
|
|
265
244
|
if (!connection_released) {
|
|
266
245
|
try {
|
|
267
|
-
await
|
|
246
|
+
await safeReleaseConnection(conn, is_pool_conn);
|
|
268
247
|
} catch (release_err) {
|
|
269
248
|
this.logger('error', '释放连接失败', release_err);
|
|
270
249
|
}
|
|
@@ -310,7 +289,7 @@ Mysql.prototype.exec = async function (sql, params = []) {
|
|
|
310
289
|
};
|
|
311
290
|
// 在错误情况下也要确保连接释放
|
|
312
291
|
try {
|
|
313
|
-
await
|
|
292
|
+
await safeReleaseConnection(conn, is_pool_conn);
|
|
314
293
|
} catch (release_err) {
|
|
315
294
|
this.logger('error', '释放连接失败', release_err);
|
|
316
295
|
}
|
|
@@ -319,7 +298,7 @@ Mysql.prototype.exec = async function (sql, params = []) {
|
|
|
319
298
|
// 确保连接被释放,避免资源泄漏
|
|
320
299
|
if (!connection_released) {
|
|
321
300
|
try {
|
|
322
|
-
await
|
|
301
|
+
await safeReleaseConnection(conn, is_pool_conn);
|
|
323
302
|
} catch (release_err) {
|
|
324
303
|
this.logger('error', '释放连接失败', release_err);
|
|
325
304
|
}
|
|
@@ -351,7 +330,7 @@ Mysql.prototype.beginTransaction = async function () {
|
|
|
351
330
|
await conn.commit();
|
|
352
331
|
transaction_committed = true;
|
|
353
332
|
try {
|
|
354
|
-
await
|
|
333
|
+
await safeReleaseConnection(conn, this._usePool);
|
|
355
334
|
} catch (release_err) {
|
|
356
335
|
this.logger('error', '提交时释放连接失败', release_err);
|
|
357
336
|
}
|
|
@@ -364,7 +343,7 @@ Mysql.prototype.beginTransaction = async function () {
|
|
|
364
343
|
await conn.rollback();
|
|
365
344
|
transaction_rolled_back = true;
|
|
366
345
|
try {
|
|
367
|
-
await
|
|
346
|
+
await safeReleaseConnection(conn, this._usePool);
|
|
368
347
|
} catch (release_err) {
|
|
369
348
|
this.logger('error', '回滚时释放连接失败', release_err);
|
|
370
349
|
}
|
|
@@ -374,7 +353,7 @@ Mysql.prototype.beginTransaction = async function () {
|
|
|
374
353
|
} catch (error) {
|
|
375
354
|
// 如果事务开始失败,确保连接被释放
|
|
376
355
|
try {
|
|
377
|
-
await
|
|
356
|
+
await safeReleaseConnection(conn, this._usePool);
|
|
378
357
|
} catch (release_err) {
|
|
379
358
|
this.logger('error', '释放连接失败', release_err);
|
|
380
359
|
}
|
|
@@ -492,13 +471,8 @@ Mysql.prototype.getPoolStats = function () {
|
|
|
492
471
|
};
|
|
493
472
|
}
|
|
494
473
|
|
|
495
|
-
// 更新统计信息
|
|
496
|
-
this._pool_stats.last_health_check = new Date();
|
|
497
|
-
|
|
498
474
|
return {
|
|
499
|
-
status: 'healthy'
|
|
500
|
-
...this._pool_stats,
|
|
501
|
-
last_health_check: this._pool_stats.last_health_check
|
|
475
|
+
status: 'healthy'
|
|
502
476
|
};
|
|
503
477
|
};
|
|
504
478
|
|
|
@@ -586,14 +560,14 @@ function _acquireLock(key) {
|
|
|
586
560
|
if (!$.pool.mysql._locks[key]) {
|
|
587
561
|
$.pool.mysql._locks[key] = Promise.resolve();
|
|
588
562
|
}
|
|
589
|
-
|
|
563
|
+
|
|
590
564
|
let release;
|
|
591
565
|
const lockPromise = $.pool.mysql._locks[key].then(() => {
|
|
592
566
|
return new Promise(resolve => {
|
|
593
567
|
release = resolve;
|
|
594
568
|
});
|
|
595
569
|
});
|
|
596
|
-
|
|
570
|
+
|
|
597
571
|
$.pool.mysql._locks[key] = lockPromise;
|
|
598
572
|
return lockPromise.then(() => release);
|
|
599
573
|
}
|
|
@@ -608,17 +582,17 @@ function mysqlAdmin(scope, config) {
|
|
|
608
582
|
if (!scope) {
|
|
609
583
|
scope = 'sys';
|
|
610
584
|
}
|
|
611
|
-
|
|
585
|
+
|
|
612
586
|
// 检查是否已存在实例
|
|
613
587
|
if ($.pool.mysql[scope]) {
|
|
614
588
|
return $.pool.mysql[scope];
|
|
615
589
|
}
|
|
616
|
-
|
|
590
|
+
|
|
617
591
|
// 同步方式创建实例(无需锁,因为Node.js是单线程的)
|
|
618
592
|
if (!$.pool.mysql[scope]) {
|
|
619
593
|
$.pool.mysql[scope] = new Mysql(config);
|
|
620
594
|
}
|
|
621
|
-
|
|
595
|
+
|
|
622
596
|
return $.pool.mysql[scope];
|
|
623
597
|
}
|
|
624
598
|
|
package/package.json
CHANGED