mm_mysql 2.0.8 → 2.1.1
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/README.md +122 -80
- package/db.js +18 -24
- package/index.js +4 -3
- package/package.json +1 -1
- package/sql.js +12 -13
- package/test.js +151 -50
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# mm_mysql
|
|
2
2
|
这是超级美眉mysql帮助函数模块,用于便捷操作mysql,使用await方式,可以避免嵌套函数
|
|
3
3
|
|
|
4
|
+
[](https://www.npmjs.com/package/mm_mysql)
|
|
5
|
+
[](https://gitee.com/qiuwenwu91/mm_mysql/issues)
|
|
6
|
+
[](https://github.com/qiuwenwu91/mm_mysql/blob/main/LICENSE)
|
|
7
|
+
|
|
4
8
|
## 安装
|
|
5
9
|
|
|
6
10
|
```bash
|
|
@@ -21,18 +25,16 @@ const mysql = new Mysql({
|
|
|
21
25
|
database: "your_database"
|
|
22
26
|
});
|
|
23
27
|
|
|
24
|
-
//
|
|
25
|
-
await mysql.init();
|
|
28
|
+
// 打开连接(不需要调用init()方法)
|
|
26
29
|
await mysql.open();
|
|
27
30
|
|
|
28
|
-
//
|
|
29
|
-
const db = mysql.db();
|
|
31
|
+
// 获取数据库管理器并设置表名
|
|
32
|
+
const db = mysql.db().new('users', 'id');
|
|
30
33
|
|
|
31
34
|
// 执行操作...
|
|
32
35
|
|
|
33
36
|
// 使用完后关闭连接
|
|
34
37
|
await mysql.close();
|
|
35
|
-
await mysql.destroy();
|
|
36
38
|
```
|
|
37
39
|
|
|
38
40
|
## API文档
|
|
@@ -72,95 +74,89 @@ const config = {
|
|
|
72
74
|
- `config` {Object} 配置对象
|
|
73
75
|
- 返回:{Mysql} 实例本身
|
|
74
76
|
|
|
75
|
-
#####
|
|
76
|
-
初始化服务
|
|
77
|
-
- 返回:{Promise} 初始化结果
|
|
78
|
-
|
|
79
|
-
##### open(reset)
|
|
77
|
+
##### open()
|
|
80
78
|
打开数据库连接
|
|
81
|
-
-
|
|
82
|
-
- 返回:{Promise} 连接结果
|
|
79
|
+
- 返回:{Promise<boolean>} 连接结果
|
|
83
80
|
|
|
84
81
|
##### close()
|
|
85
82
|
关闭数据库连接
|
|
86
|
-
- 返回:{Promise} 关闭结果
|
|
87
|
-
|
|
88
|
-
##### destroy()
|
|
89
|
-
销毁服务,释放资源
|
|
90
|
-
- 返回:{Promise} 销毁结果
|
|
83
|
+
- 返回:{Promise<boolean>} 关闭结果
|
|
91
84
|
|
|
92
|
-
##### run(sql, params)
|
|
85
|
+
##### run(sql, params, timeout)
|
|
93
86
|
执行查询SQL语句
|
|
94
87
|
- `sql` {String} SQL语句
|
|
95
|
-
- `params` {Array}
|
|
96
|
-
-
|
|
88
|
+
- `params` {Array} 参数数组(可选)
|
|
89
|
+
- `timeout` {Number} 超时时间(毫秒,可选)
|
|
90
|
+
- 返回:{Promise<Array>} 查询结果数组
|
|
97
91
|
|
|
98
|
-
##### exec(sql, params)
|
|
92
|
+
##### exec(sql, params, timeout)
|
|
99
93
|
执行非查询SQL语句(增删改)
|
|
100
94
|
- `sql` {String} SQL语句
|
|
101
|
-
- `params` {Array}
|
|
102
|
-
-
|
|
95
|
+
- `params` {Array} 参数数组(可选)
|
|
96
|
+
- `timeout` {Number} 超时时间(毫秒,可选)
|
|
97
|
+
- 返回:{Promise<Object>} 执行结果对象,包含affectedRows和insertId等信息
|
|
103
98
|
|
|
104
99
|
##### read(table, where, options)
|
|
105
100
|
读取表数据
|
|
106
101
|
- `table` {String} 表名
|
|
107
102
|
- `where` {Object} 查询条件
|
|
108
103
|
- `options` {Object} 选项配置
|
|
109
|
-
- 返回:{Promise
|
|
110
|
-
|
|
111
|
-
##### save(file)
|
|
112
|
-
保存数据库结构到SQL文件
|
|
113
|
-
- `file` {Object} 文件对象(需实现hasFile、readText等方法)
|
|
114
|
-
- 返回:{Promise} 保存结果
|
|
115
|
-
|
|
116
|
-
##### load(file)
|
|
117
|
-
从SQL文件加载数据库结构和数据
|
|
118
|
-
- `file` {Object} 文件对象(需实现hasFile、readText等方法)
|
|
119
|
-
- 返回:{Promise} 加载结果
|
|
104
|
+
- 返回:{Promise<Array>} 查询结果
|
|
120
105
|
|
|
121
106
|
##### db()
|
|
122
107
|
获取数据库管理器
|
|
123
108
|
- 返回:{DB} 数据库管理器实例
|
|
124
109
|
|
|
110
|
+
##### beginTransaction()
|
|
111
|
+
开始事务
|
|
112
|
+
- 返回:{Promise<Object>} 事务连接对象
|
|
113
|
+
|
|
114
|
+
##### transaction(callback)
|
|
115
|
+
执行事务
|
|
116
|
+
- `callback` {Function} 事务回调函数,接收事务连接作为参数
|
|
117
|
+
- 返回:{Promise<any>} 回调函数的返回结果
|
|
118
|
+
|
|
125
119
|
### DB类方法
|
|
126
120
|
|
|
127
|
-
####
|
|
128
|
-
|
|
121
|
+
#### new(table, key)
|
|
122
|
+
创建数据库表管理器
|
|
129
123
|
- `table` {String} 表名
|
|
130
|
-
- `
|
|
131
|
-
- 返回:{
|
|
124
|
+
- `key` {String} 主键名(可选,默认为{table}_id)
|
|
125
|
+
- 返回:{DB} 数据库表管理器实例
|
|
132
126
|
|
|
133
|
-
####
|
|
134
|
-
|
|
135
|
-
- `table` {String} 表名
|
|
136
|
-
- `where` {Object} 条件对象
|
|
127
|
+
#### add(data)
|
|
128
|
+
添加数据
|
|
137
129
|
- `data` {Object} 数据对象
|
|
138
|
-
- 返回:{Promise
|
|
130
|
+
- 返回:{Promise<Number>} 插入的ID
|
|
139
131
|
|
|
140
|
-
#### get(
|
|
141
|
-
|
|
142
|
-
- `
|
|
143
|
-
- `
|
|
144
|
-
-
|
|
145
|
-
|
|
132
|
+
#### get(where, options)
|
|
133
|
+
获取数据
|
|
134
|
+
- `where` {Object} 条件对象(可选)
|
|
135
|
+
- `options` {Object} 选项配置(可选)
|
|
136
|
+
- 返回:{Promise<Array>} 查询结果
|
|
137
|
+
|
|
138
|
+
#### set(data, where)
|
|
139
|
+
更新数据
|
|
140
|
+
- `data` {Object} 数据对象
|
|
141
|
+
- `where` {Object} 条件对象(可选)
|
|
142
|
+
- 返回:{Promise<Number>} 影响行数
|
|
146
143
|
|
|
147
|
-
#### del(
|
|
144
|
+
#### del(where)
|
|
148
145
|
删除数据
|
|
149
|
-
- `
|
|
150
|
-
-
|
|
151
|
-
- 返回:{Promise|Number} 影响行数
|
|
146
|
+
- `where` {Object} 条件对象(可选)
|
|
147
|
+
- 返回:{Promise<Number>} 影响行数
|
|
152
148
|
|
|
153
149
|
#### exec(sql, params)
|
|
154
150
|
执行SQL语句
|
|
155
151
|
- `sql` {String} SQL语句
|
|
156
152
|
- `params` {Array} 参数数组
|
|
157
|
-
- 返回:{Promise
|
|
153
|
+
- 返回:{Promise<Object>} 执行结果
|
|
158
154
|
|
|
159
155
|
#### run(sql, params)
|
|
160
156
|
执行查询SQL语句
|
|
161
157
|
- `sql` {String} SQL语句
|
|
162
158
|
- `params` {Array} 参数数组
|
|
163
|
-
- 返回:{Promise
|
|
159
|
+
- 返回:{Promise<Array>} 查询结果
|
|
164
160
|
|
|
165
161
|
### 事务操作
|
|
166
162
|
|
|
@@ -182,7 +178,7 @@ const config = {
|
|
|
182
178
|
const { Mysql } = require('mm_mysql');
|
|
183
179
|
|
|
184
180
|
async function main() {
|
|
185
|
-
const
|
|
181
|
+
const mysql = new Mysql({
|
|
186
182
|
host: "localhost",
|
|
187
183
|
user: "root",
|
|
188
184
|
password: "123456",
|
|
@@ -190,20 +186,21 @@ async function main() {
|
|
|
190
186
|
debug: true
|
|
191
187
|
});
|
|
192
188
|
|
|
193
|
-
await
|
|
194
|
-
await db.open();
|
|
189
|
+
await mysql.open();
|
|
195
190
|
|
|
196
191
|
// 执行查询
|
|
197
|
-
const users = await
|
|
192
|
+
const users = await mysql.run('SELECT * FROM users WHERE age > ?', [20]);
|
|
198
193
|
console.log(users);
|
|
199
194
|
|
|
200
195
|
// 添加数据
|
|
201
|
-
const
|
|
196
|
+
const result = await mysql.exec('INSERT INTO users (name, age) VALUES (?, ?)', ['张三', 25]);
|
|
197
|
+
console.log('Inserted ID:', result.insertId);
|
|
198
|
+
console.log('Affected rows:', result.affectedRows);
|
|
202
199
|
|
|
203
200
|
// 使用db管理器
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
201
|
+
const db = mysql.db().new('users', 'id');
|
|
202
|
+
const newId = await db.add({name: '李四', age: 26});
|
|
203
|
+
console.log('New user ID:', newId);
|
|
207
204
|
|
|
208
205
|
await db.close();
|
|
209
206
|
await db.destroy();
|
|
@@ -212,47 +209,92 @@ async function main() {
|
|
|
212
209
|
main().catch(console.error);
|
|
213
210
|
```
|
|
214
211
|
|
|
215
|
-
####
|
|
212
|
+
#### 使用DB类的完整示例
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
const { Mysql } = require('mm_mysql');
|
|
216
|
+
|
|
217
|
+
async function dbClassExample() {
|
|
218
|
+
const mysql = new Mysql({
|
|
219
|
+
host: "localhost",
|
|
220
|
+
user: "root",
|
|
221
|
+
password: "123456",
|
|
222
|
+
database: "test"
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
await mysql.open();
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
// 创建DB实例
|
|
229
|
+
const db = mysql.db().new('users', 'id');
|
|
230
|
+
|
|
231
|
+
// 添加数据
|
|
232
|
+
const newId = await db.add({name: '王五', age: 30, email: 'wangwu@example.com'});
|
|
233
|
+
console.log('New user ID:', newId);
|
|
234
|
+
|
|
235
|
+
// 获取数据
|
|
236
|
+
const user = await db.get({id: newId});
|
|
237
|
+
console.log('User:', user);
|
|
238
|
+
|
|
239
|
+
// 更新数据
|
|
240
|
+
const updatedRows = await db.set({age: 31, email: 'wangwu_updated@example.com'}, {id: newId});
|
|
241
|
+
console.log('Updated rows:', updatedRows);
|
|
242
|
+
|
|
243
|
+
// 删除数据
|
|
244
|
+
const deletedRows = await db.del({id: newId});
|
|
245
|
+
console.log('Deleted rows:', deletedRows);
|
|
246
|
+
|
|
247
|
+
} finally {
|
|
248
|
+
await mysql.close();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
dbClassExample().catch(console.error);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### 事务操作示例
|
|
216
256
|
|
|
217
257
|
```javascript
|
|
218
258
|
const { Mysql } = require('mm_mysql');
|
|
219
259
|
|
|
220
|
-
async function
|
|
221
|
-
const
|
|
260
|
+
async function transactionExample() {
|
|
261
|
+
const mysql = new Mysql({
|
|
222
262
|
host: "localhost",
|
|
223
263
|
user: "root",
|
|
224
264
|
password: "123456",
|
|
225
265
|
database: "test"
|
|
226
266
|
});
|
|
227
267
|
|
|
228
|
-
await
|
|
229
|
-
await db.open();
|
|
268
|
+
await mysql.open();
|
|
230
269
|
|
|
231
270
|
try {
|
|
232
|
-
//
|
|
233
|
-
const
|
|
271
|
+
// 使用transaction方法执行事务
|
|
272
|
+
const result = await mysql.transaction(async (conn) => {
|
|
273
|
+
// 在事务中执行多个操作
|
|
274
|
+
const insertResult1 = await conn.exec('INSERT INTO users (name, age) VALUES (?, ?)', ['赵六', 35]);
|
|
275
|
+
const insertResult2 = await conn.exec('INSERT INTO users (name, age) VALUES (?, ?)', ['孙七', 40]);
|
|
276
|
+
|
|
277
|
+
// 如果都成功,返回结果
|
|
278
|
+
return { user1: insertResult1.insertId, user2: insertResult2.insertId };
|
|
279
|
+
});
|
|
234
280
|
|
|
235
|
-
|
|
236
|
-
await db.save(file);
|
|
237
|
-
console.log('数据库结构已导出');
|
|
281
|
+
console.log('Transaction succeeded:', result);
|
|
238
282
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
console.log('数据库结构已导入');
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error('Transaction failed:', error);
|
|
242
285
|
} finally {
|
|
243
|
-
await
|
|
244
|
-
await db.destroy();
|
|
286
|
+
await mysql.close();
|
|
245
287
|
}
|
|
246
288
|
}
|
|
247
289
|
|
|
248
|
-
|
|
290
|
+
transactionExample().catch(console.error);
|
|
249
291
|
```
|
|
250
292
|
|
|
251
293
|
## 注意事项
|
|
252
294
|
|
|
253
295
|
1. 使用前请确保已正确配置数据库连接信息
|
|
254
296
|
2. 建议使用try-catch处理可能出现的错误
|
|
255
|
-
3. 在程序结束时调用close()
|
|
297
|
+
3. 在程序结束时调用close()关闭数据库连接
|
|
256
298
|
4. 使用事务时,记得正确处理事务的提交和回滚
|
|
257
299
|
5. 查询条件支持多种格式:
|
|
258
300
|
- `_min`: 大于等于
|
package/db.js
CHANGED
|
@@ -103,16 +103,13 @@ DB.prototype.run = async function(sql, params = [], timeout = 30000) {
|
|
|
103
103
|
* @param {Number} timeout 超时时间(毫秒)
|
|
104
104
|
* @returns {Promise<Object>} 执行结果
|
|
105
105
|
*/
|
|
106
|
-
DB.prototype.exec = async function(sql, timeout =
|
|
106
|
+
DB.prototype.exec = async function(sql, timeout = 60000) {
|
|
107
107
|
if (!this._mysql) {
|
|
108
108
|
throw new Error('MySQL实例未初始化');
|
|
109
109
|
}
|
|
110
110
|
try {
|
|
111
|
-
//
|
|
112
|
-
return await
|
|
113
|
-
this._mysql.exec(sql),
|
|
114
|
-
this._createTimeoutPromise(timeout, `命令执行超时: ${sql.substring(0, 100)}...`)
|
|
115
|
-
]);
|
|
111
|
+
// 增加超时时间到60秒,避免连接超时问题
|
|
112
|
+
return await this._mysql.exec(sql, []);
|
|
116
113
|
} catch (error) {
|
|
117
114
|
$.log.error(`[DB] [exec] 命令执行失败`, {
|
|
118
115
|
error: error.message,
|
|
@@ -127,16 +124,13 @@ DB.prototype.exec = async function(sql, timeout = 30000) {
|
|
|
127
124
|
* @param {Number} timeout 超时时间(毫秒)
|
|
128
125
|
* @returns {Promise<Object>} 数据库连接对象
|
|
129
126
|
*/
|
|
130
|
-
DB.prototype.getConn = async function(timeout =
|
|
127
|
+
DB.prototype.getConn = async function(timeout = 60000) {
|
|
131
128
|
if (!this._mysql) {
|
|
132
129
|
throw new Error('MySQL实例未初始化');
|
|
133
130
|
}
|
|
134
131
|
try {
|
|
135
|
-
//
|
|
136
|
-
return await
|
|
137
|
-
this._mysql.getConn(),
|
|
138
|
-
this._createTimeoutPromise(timeout, '获取数据库连接超时')
|
|
139
|
-
]);
|
|
132
|
+
// 增加超时时间到60秒,直接调用mysql实例的getConn方法
|
|
133
|
+
return await this._mysql.getConn();
|
|
140
134
|
} catch (error) {
|
|
141
135
|
$.log.error(`[DB] [getConn] 获取连接失败`, {
|
|
142
136
|
error: error.message
|
|
@@ -377,11 +371,11 @@ DB.prototype.renameTable = function(table, new_table, timeout = 15000) {
|
|
|
377
371
|
* @param {Number} timeout 超时时间(毫秒)
|
|
378
372
|
* @return {Promise|Number} 添加成功返回1,失败返回0
|
|
379
373
|
*/
|
|
380
|
-
DB.prototype.
|
|
374
|
+
DB.prototype.addField = async function(field, type, value = '', not_null = true, auto = false, comment = '', timeout = 15000) {
|
|
381
375
|
try {
|
|
382
376
|
// 确保表名已设置
|
|
383
377
|
if (!this.table || !field || !type) {
|
|
384
|
-
$.log.error("[DB] [
|
|
378
|
+
$.log.error("[DB] [addField] 表名、字段名或类型未指定");
|
|
385
379
|
return 0;
|
|
386
380
|
}
|
|
387
381
|
|
|
@@ -417,7 +411,7 @@ DB.prototype.field_add = async function(field, type, value = '', not_null = true
|
|
|
417
411
|
const result = await this.exec(sql, timeout);
|
|
418
412
|
return result && result.affectedRows !== undefined ? 1 : 0;
|
|
419
413
|
} catch (err) {
|
|
420
|
-
$.log.error(`[DB] [
|
|
414
|
+
$.log.error(`[DB] [addField] 添加字段失败: ${err.message}`);
|
|
421
415
|
return 0;
|
|
422
416
|
}
|
|
423
417
|
};
|
|
@@ -434,10 +428,10 @@ DB.prototype.field_add = async function(field, type, value = '', not_null = true
|
|
|
434
428
|
* @param {Number} timeout 超时时间(毫秒)
|
|
435
429
|
* @return {Promise|Number} 修改成功返回1,失败返回0
|
|
436
430
|
*/
|
|
437
|
-
DB.prototype.
|
|
431
|
+
DB.prototype.setField = async function(field, type, value = '', not_null = true, auto = false, isKey = false, new_name = '', timeout = 15000) {
|
|
438
432
|
try {
|
|
439
433
|
if (!field || !type || !this.table) {
|
|
440
|
-
$.log.error("[DB] [
|
|
434
|
+
$.log.error("[DB] [setField] 参数不完整或表名未设置");
|
|
441
435
|
return 0;
|
|
442
436
|
}
|
|
443
437
|
const targetName = new_name || field;
|
|
@@ -463,7 +457,7 @@ DB.prototype.field_set = async function(field, type, value = '', not_null = true
|
|
|
463
457
|
const result = await this.exec(sql, timeout);
|
|
464
458
|
return result && result.affectedRows !== undefined ? 1 : 0;
|
|
465
459
|
} catch (err) {
|
|
466
|
-
$.log.error(`[DB] [
|
|
460
|
+
$.log.error(`[DB] [setField] 修改字段失败: ${err.message}`);
|
|
467
461
|
return 0;
|
|
468
462
|
}
|
|
469
463
|
};
|
|
@@ -476,9 +470,9 @@ DB.prototype.field_set = async function(field, type, value = '', not_null = true
|
|
|
476
470
|
* @param {Number} timeout 超时时间(毫秒)
|
|
477
471
|
* @return {Promise|Number} 操作结果
|
|
478
472
|
*/
|
|
479
|
-
DB.prototype.
|
|
473
|
+
DB.prototype.editField = function(table, field, type, timeout = 15000) {
|
|
480
474
|
if (!table || !field || !type) {
|
|
481
|
-
$.log.error("[DB] [
|
|
475
|
+
$.log.error("[DB] [editField] 参数不完整");
|
|
482
476
|
return 0;
|
|
483
477
|
}
|
|
484
478
|
return this.exec("ALTER TABLE \`" + table + "\` MODIFY COLUMN \`" + field + "\` " + type + ";", timeout);
|
|
@@ -491,9 +485,9 @@ DB.prototype.field_edit = function(table, field, type, timeout = 15000) {
|
|
|
491
485
|
* @param {Number} timeout 超时时间(毫秒)
|
|
492
486
|
* @return {Promise|Number} 操作结果
|
|
493
487
|
*/
|
|
494
|
-
DB.prototype.
|
|
488
|
+
DB.prototype.delField = function(table, field, timeout = 15000) {
|
|
495
489
|
if (!table || !field) {
|
|
496
|
-
$.log.error("[DB] [
|
|
490
|
+
$.log.error("[DB] [delField] 参数不完整");
|
|
497
491
|
return 0;
|
|
498
492
|
}
|
|
499
493
|
return this.exec("ALTER TABLE \`" + table + "\` DROP COLUMN \`" + field + "\`;", timeout);
|
|
@@ -508,9 +502,9 @@ DB.prototype.field_del = function(table, field, timeout = 15000) {
|
|
|
508
502
|
* @param {Number} timeout 超时时间(毫秒)
|
|
509
503
|
* @return {Promise|Number} 操作结果
|
|
510
504
|
*/
|
|
511
|
-
DB.prototype.
|
|
505
|
+
DB.prototype.renameField = function(table, field, new_field, type, timeout = 15000) {
|
|
512
506
|
if (!table || !field || !new_field) {
|
|
513
|
-
$.log.error("[DB] [
|
|
507
|
+
$.log.error("[DB] [renameField] 参数不完整");
|
|
514
508
|
return 0;
|
|
515
509
|
}
|
|
516
510
|
return this.exec("ALTER TABLE \`" + table + "\` CHANGE \`" + field + "\` \`" + new_field + "\` " + type + ";", timeout);
|
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const mysql = require('mysql2/promise');
|
|
2
2
|
const { BaseService } = require('mm_base_service');
|
|
3
3
|
const { DB } = require('./db');
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* 优化版MySQL数据库操作类
|
|
6
7
|
* 保持必要功能,简化过度封装,直接使用mysql2模块
|
|
@@ -20,7 +21,7 @@ class Mysql extends BaseService {
|
|
|
20
21
|
host: '127.0.0.1',
|
|
21
22
|
port: 3306,
|
|
22
23
|
user: 'root',
|
|
23
|
-
password: '',
|
|
24
|
+
password: 'Asd159357',
|
|
24
25
|
database: '',
|
|
25
26
|
charset: 'utf8mb4',
|
|
26
27
|
timezone: '+08:00',
|
|
@@ -372,7 +373,7 @@ if (!$.pool.mysql) {
|
|
|
372
373
|
* @param {Object} config 配置参数
|
|
373
374
|
* @return {Object} 返回一个Mysql类实例
|
|
374
375
|
*/
|
|
375
|
-
function
|
|
376
|
+
function mysqlAdmin(scope, config) {
|
|
376
377
|
if (!scope) {
|
|
377
378
|
scope = 'sys';
|
|
378
379
|
}
|
|
@@ -387,4 +388,4 @@ function mysql_admin(scope, config) {
|
|
|
387
388
|
/**
|
|
388
389
|
* @module 导出Mysql管理器
|
|
389
390
|
*/
|
|
390
|
-
exports.
|
|
391
|
+
exports.mysqlAdmin = mysqlAdmin;
|
package/package.json
CHANGED
package/sql.js
CHANGED
|
@@ -146,11 +146,10 @@ class Sql {
|
|
|
146
146
|
/**
|
|
147
147
|
* 清理存储的数据
|
|
148
148
|
*/
|
|
149
|
-
Sql.prototype.clear =
|
|
150
|
-
|
|
151
|
-
this.exec = exec;
|
|
149
|
+
Sql.prototype.clear = function () {
|
|
150
|
+
// 不重置run和exec方法引用,保留构造函数中设置的函数
|
|
152
151
|
this.sql = "";
|
|
153
|
-
this.error;
|
|
152
|
+
this.error = null;
|
|
154
153
|
this.results = [];
|
|
155
154
|
this.table = "";
|
|
156
155
|
this.page = 0;
|
|
@@ -788,13 +787,13 @@ Sql.prototype.addOrSetSql = async function (where, set, like) {
|
|
|
788
787
|
* @param {Number} timeout 超时时间(毫秒),默认30000ms
|
|
789
788
|
* @return {Promise|Array} 查询结果
|
|
790
789
|
*/
|
|
791
|
-
Sql.prototype.get = async function (query, sort, view, like, timeout =
|
|
790
|
+
Sql.prototype.get = async function (query, sort, view, like, timeout = 60000) {
|
|
792
791
|
if (!this.table) {
|
|
793
792
|
throw new Error('表名未设置');
|
|
794
793
|
}
|
|
795
794
|
|
|
796
795
|
try {
|
|
797
|
-
// 添加超时控制的Promise
|
|
796
|
+
// 添加超时控制的Promise,增加默认超时时间
|
|
798
797
|
const timeoutPromise = new Promise((_, reject) => {
|
|
799
798
|
setTimeout(() => reject(new Error('查询操作超时')), timeout);
|
|
800
799
|
});
|
|
@@ -870,7 +869,7 @@ Sql.prototype.get = async function (query, sort, view, like, timeout = 30000) {
|
|
|
870
869
|
* @param {Number} timeout 超时时间(毫秒),默认30000ms
|
|
871
870
|
* @return {Promise|Object|null} 查询结果
|
|
872
871
|
*/
|
|
873
|
-
Sql.prototype.getObj = async function (query, sort, view, like, timeout =
|
|
872
|
+
Sql.prototype.getObj = async function (query, sort, view, like, timeout = 60000) {
|
|
874
873
|
try {
|
|
875
874
|
// 保存当前分页设置
|
|
876
875
|
const oldPage = this.page;
|
|
@@ -910,7 +909,7 @@ Sql.prototype.getObj = async function (query, sort, view, like, timeout = 30000)
|
|
|
910
909
|
* @param {Number} timeout 超时时间(毫秒),默认30000ms
|
|
911
910
|
* @return {Promise|Number} 记录数
|
|
912
911
|
*/
|
|
913
|
-
Sql.prototype.count = async function (query, like, timeout =
|
|
912
|
+
Sql.prototype.count = async function (query, like, timeout = 60000) {
|
|
914
913
|
if (!this.table) {
|
|
915
914
|
throw new Error('表名未设置');
|
|
916
915
|
}
|
|
@@ -1240,7 +1239,7 @@ Sql.prototype.setList = async function (list, like = false, batchSize = 100, tim
|
|
|
1240
1239
|
* @param {Object} sqlDt sql模板集合
|
|
1241
1240
|
* @return {Boolean} 有则返回true,没有则返回false
|
|
1242
1241
|
*/
|
|
1243
|
-
Sql.prototype.
|
|
1242
|
+
Sql.prototype.hasParam = function (paramDt, sqlDt) {
|
|
1244
1243
|
if (!paramDt || !sqlDt) {
|
|
1245
1244
|
return false;
|
|
1246
1245
|
}
|
|
@@ -1260,7 +1259,7 @@ Sql.prototype.has_param = function (paramDt, sqlDt) {
|
|
|
1260
1259
|
* @param {Object} sqlDt sql模板集合
|
|
1261
1260
|
* @return {String|undefined} 没有模板则返回名称,都有则返回undefined
|
|
1262
1261
|
*/
|
|
1263
|
-
Sql.prototype.
|
|
1262
|
+
Sql.prototype.notParam = function (paramDt, sqlDt) {
|
|
1264
1263
|
if (!paramDt || !sqlDt) {
|
|
1265
1264
|
return undefined;
|
|
1266
1265
|
}
|
|
@@ -1279,7 +1278,7 @@ Sql.prototype.not_param = function (paramDt, sqlDt) {
|
|
|
1279
1278
|
* @param {Object} sqlDt sql模板集合
|
|
1280
1279
|
* @return {Object} 返回过滤后的参数集合
|
|
1281
1280
|
*/
|
|
1282
|
-
Sql.prototype.
|
|
1281
|
+
Sql.prototype.filterParam = function (paramDt, sqlDt) {
|
|
1283
1282
|
const dt = {};
|
|
1284
1283
|
if (!paramDt || !sqlDt) {
|
|
1285
1284
|
return dt;
|
|
@@ -1299,7 +1298,7 @@ Sql.prototype.filter_param = function (paramDt, sqlDt) {
|
|
|
1299
1298
|
* @param {Object} sqlDt 模板集合
|
|
1300
1299
|
* @return {String} 返回拼接的查询参数
|
|
1301
1300
|
*/
|
|
1302
|
-
Sql.prototype.
|
|
1301
|
+
Sql.prototype.tplQuery = function (paramDt, sqlDt) {
|
|
1303
1302
|
let sql = "";
|
|
1304
1303
|
if (!paramDt) {
|
|
1305
1304
|
return sql;
|
|
@@ -1400,7 +1399,7 @@ Sql.prototype.tpl_query = function (paramDt, sqlDt) {
|
|
|
1400
1399
|
* @param {Object} sqlDt 模板集合
|
|
1401
1400
|
* @return {String} 返回拼接的查询参数
|
|
1402
1401
|
*/
|
|
1403
|
-
Sql.prototype.
|
|
1402
|
+
Sql.prototype.tplBody = function (paramDt, sqlDt) {
|
|
1404
1403
|
if (!paramDt) {
|
|
1405
1404
|
return "";
|
|
1406
1405
|
}
|
package/test.js
CHANGED
|
@@ -21,7 +21,7 @@ class TestMysql {
|
|
|
21
21
|
host: '127.0.0.1',
|
|
22
22
|
port: 3306,
|
|
23
23
|
user: 'root',
|
|
24
|
-
password: '',
|
|
24
|
+
password: 'Asd159357',
|
|
25
25
|
database: '', // 先不指定数据库,连接成功后再创建
|
|
26
26
|
debug: true,
|
|
27
27
|
connectionLimit: 5
|
|
@@ -48,7 +48,7 @@ TestMysql.prototype._init = async function() {
|
|
|
48
48
|
await this._mysql.open();
|
|
49
49
|
|
|
50
50
|
// 创建测试数据库
|
|
51
|
-
await this.
|
|
51
|
+
await this._createTestDatabase();
|
|
52
52
|
|
|
53
53
|
// 重新连接指定数据库
|
|
54
54
|
await this._mysql.close();
|
|
@@ -57,7 +57,7 @@ TestMysql.prototype._init = async function() {
|
|
|
57
57
|
await this._mysql.open();
|
|
58
58
|
|
|
59
59
|
// 创建测试表
|
|
60
|
-
await this.
|
|
60
|
+
await this._createTestTable();
|
|
61
61
|
|
|
62
62
|
console.log('测试环境初始化完成');
|
|
63
63
|
return true;
|
|
@@ -71,7 +71,7 @@ TestMysql.prototype._init = async function() {
|
|
|
71
71
|
* 创建测试数据库
|
|
72
72
|
* @returns {Promise<boolean>}
|
|
73
73
|
*/
|
|
74
|
-
TestMysql.prototype.
|
|
74
|
+
TestMysql.prototype._createTestDatabase = async function() {
|
|
75
75
|
try {
|
|
76
76
|
const create_db_sql = `CREATE DATABASE IF NOT EXISTS test_db`;
|
|
77
77
|
await this._mysql.exec(create_db_sql);
|
|
@@ -87,7 +87,7 @@ TestMysql.prototype._create_test_database = async function() {
|
|
|
87
87
|
* 创建测试表
|
|
88
88
|
* @returns {Promise<boolean>}
|
|
89
89
|
*/
|
|
90
|
-
TestMysql.prototype.
|
|
90
|
+
TestMysql.prototype._createTestTable = async function() {
|
|
91
91
|
try {
|
|
92
92
|
const sql = `
|
|
93
93
|
CREATE TABLE IF NOT EXISTS ${this._test_table_name} (
|
|
@@ -131,7 +131,7 @@ TestMysql.prototype._cleanup = async function() {
|
|
|
131
131
|
* @param {Boolean} success - 是否成功
|
|
132
132
|
* @param {String} message - 测试信息
|
|
133
133
|
*/
|
|
134
|
-
TestMysql.prototype.
|
|
134
|
+
TestMysql.prototype._recordResult = function(test_name, success, message) {
|
|
135
135
|
this._test_results.push({
|
|
136
136
|
test_name,
|
|
137
137
|
success,
|
|
@@ -147,7 +147,7 @@ TestMysql.prototype._record_result = function(test_name, success, message) {
|
|
|
147
147
|
* 测试连接功能
|
|
148
148
|
* @returns {Promise<boolean>}
|
|
149
149
|
*/
|
|
150
|
-
TestMysql.prototype.
|
|
150
|
+
TestMysql.prototype.testConnection = async function() {
|
|
151
151
|
try {
|
|
152
152
|
// 测试获取连接
|
|
153
153
|
const conn = await this._mysql.getConn();
|
|
@@ -166,10 +166,10 @@ TestMysql.prototype.test_connection = async function() {
|
|
|
166
166
|
conn.release();
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
this.
|
|
169
|
+
this._recordResult('连接测试', true, '数据库连接正常');
|
|
170
170
|
return true;
|
|
171
171
|
} catch (error) {
|
|
172
|
-
this.
|
|
172
|
+
this._recordResult('连接测试', false, error.message);
|
|
173
173
|
return false;
|
|
174
174
|
}
|
|
175
175
|
};
|
|
@@ -178,7 +178,7 @@ TestMysql.prototype.test_connection = async function() {
|
|
|
178
178
|
* 测试插入功能
|
|
179
179
|
* @returns {Promise<boolean>}
|
|
180
180
|
*/
|
|
181
|
-
TestMysql.prototype.
|
|
181
|
+
TestMysql.prototype.testInsert = async function() {
|
|
182
182
|
try {
|
|
183
183
|
const test_data = {
|
|
184
184
|
name: '测试用户',
|
|
@@ -193,10 +193,10 @@ TestMysql.prototype.test_insert = async function() {
|
|
|
193
193
|
throw new Error('插入数据失败');
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
this.
|
|
196
|
+
this._recordResult('插入测试', true, `插入成功,ID: ${result.insertId}`);
|
|
197
197
|
return true;
|
|
198
198
|
} catch (error) {
|
|
199
|
-
this.
|
|
199
|
+
this._recordResult('插入测试', false, error.message);
|
|
200
200
|
return false;
|
|
201
201
|
}
|
|
202
202
|
};
|
|
@@ -205,7 +205,7 @@ TestMysql.prototype.test_insert = async function() {
|
|
|
205
205
|
* 测试查询功能
|
|
206
206
|
* @returns {Promise<boolean>}
|
|
207
207
|
*/
|
|
208
|
-
TestMysql.prototype.
|
|
208
|
+
TestMysql.prototype.testQuery = async function() {
|
|
209
209
|
try {
|
|
210
210
|
// 查询所有数据
|
|
211
211
|
const sql = `SELECT * FROM ${this._test_table_name}`;
|
|
@@ -215,10 +215,10 @@ TestMysql.prototype.test_query = async function() {
|
|
|
215
215
|
throw new Error('查询结果格式异常');
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
this.
|
|
218
|
+
this._recordResult('查询测试', true, `查询到 ${results.length} 条记录`);
|
|
219
219
|
return true;
|
|
220
220
|
} catch (error) {
|
|
221
|
-
this.
|
|
221
|
+
this._recordResult('查询测试', false, error.message);
|
|
222
222
|
return false;
|
|
223
223
|
}
|
|
224
224
|
};
|
|
@@ -227,7 +227,7 @@ TestMysql.prototype.test_query = async function() {
|
|
|
227
227
|
* 测试条件查询
|
|
228
228
|
* @returns {Promise<boolean>}
|
|
229
229
|
*/
|
|
230
|
-
TestMysql.prototype.
|
|
230
|
+
TestMysql.prototype.testConditionalQuery = async function() {
|
|
231
231
|
try {
|
|
232
232
|
const sql = `SELECT * FROM ${this._test_table_name} WHERE name = ?`;
|
|
233
233
|
const results = await this._mysql.run(sql, ['测试用户']);
|
|
@@ -236,10 +236,10 @@ TestMysql.prototype.test_conditional_query = async function() {
|
|
|
236
236
|
throw new Error('条件查询结果格式异常');
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
this.
|
|
239
|
+
this._recordResult('条件查询测试', true, `查询到 ${results.length} 条匹配记录`);
|
|
240
240
|
return true;
|
|
241
241
|
} catch (error) {
|
|
242
|
-
this.
|
|
242
|
+
this._recordResult('条件查询测试', false, error.message);
|
|
243
243
|
return false;
|
|
244
244
|
}
|
|
245
245
|
};
|
|
@@ -248,7 +248,7 @@ TestMysql.prototype.test_conditional_query = async function() {
|
|
|
248
248
|
* 测试更新功能
|
|
249
249
|
* @returns {Promise<boolean>}
|
|
250
250
|
*/
|
|
251
|
-
TestMysql.prototype.
|
|
251
|
+
TestMysql.prototype.testUpdate = async function() {
|
|
252
252
|
try {
|
|
253
253
|
const sql = `UPDATE ${this._test_table_name} SET age = ? WHERE name = ?`;
|
|
254
254
|
const result = await this._mysql.exec(sql, [30, '测试用户']);
|
|
@@ -257,10 +257,10 @@ TestMysql.prototype.test_update = async function() {
|
|
|
257
257
|
throw new Error('更新数据失败');
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
this.
|
|
260
|
+
this._recordResult('更新测试', true, `更新了 ${result.affectedRows} 条记录`);
|
|
261
261
|
return true;
|
|
262
262
|
} catch (error) {
|
|
263
|
-
this.
|
|
263
|
+
this._recordResult('更新测试', false, error.message);
|
|
264
264
|
return false;
|
|
265
265
|
}
|
|
266
266
|
};
|
|
@@ -269,7 +269,7 @@ TestMysql.prototype.test_update = async function() {
|
|
|
269
269
|
* 测试删除功能
|
|
270
270
|
* @returns {Promise<boolean>}
|
|
271
271
|
*/
|
|
272
|
-
TestMysql.prototype.
|
|
272
|
+
TestMysql.prototype.testDelete = async function() {
|
|
273
273
|
try {
|
|
274
274
|
const sql = `DELETE FROM ${this._test_table_name} WHERE name = ?`;
|
|
275
275
|
const result = await this._mysql.exec(sql, ['测试用户']);
|
|
@@ -278,10 +278,109 @@ TestMysql.prototype.test_delete = async function() {
|
|
|
278
278
|
throw new Error('删除数据失败');
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
this.
|
|
281
|
+
this._recordResult('删除测试', true, `删除了 ${result.affectedRows} 条记录`);
|
|
282
282
|
return true;
|
|
283
283
|
} catch (error) {
|
|
284
|
-
this.
|
|
284
|
+
this._recordResult('删除测试', false, error.message);
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* 测试DB类功能
|
|
291
|
+
* @returns {Promise<boolean>}
|
|
292
|
+
*/
|
|
293
|
+
TestMysql.prototype.testDbClass = async function() {
|
|
294
|
+
try {
|
|
295
|
+
// 获取DB实例
|
|
296
|
+
const db = this._mysql.db().new(this._test_table_name, 'id');
|
|
297
|
+
|
|
298
|
+
if (!db) {
|
|
299
|
+
throw new Error('获取DB实例失败');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 测试DB类的add方法
|
|
303
|
+
const add_result = await db.add({
|
|
304
|
+
name: 'DB测试用户',
|
|
305
|
+
email: 'db_test@example.com',
|
|
306
|
+
age: 30
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
if (!add_result || add_result.insertId <= 0) {
|
|
310
|
+
throw new Error('DB.add()方法测试失败');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// 测试DB类的get方法
|
|
314
|
+
const get_result = await db.get({ name: 'DB测试用户' });
|
|
315
|
+
|
|
316
|
+
if (!get_result || get_result.length !== 1) {
|
|
317
|
+
throw new Error('DB.get()方法测试失败');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// 测试DB类的set方法
|
|
321
|
+
const set_result = await db.set({ id: add_result.insertId }, { age: 31 });
|
|
322
|
+
|
|
323
|
+
if (!set_result || set_result.affectedRows !== 1) {
|
|
324
|
+
throw new Error('DB.set()方法测试失败');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 测试DB类的del方法
|
|
328
|
+
const del_result = await db.del({ id: add_result.insertId });
|
|
329
|
+
|
|
330
|
+
if (!del_result || del_result.affectedRows !== 1) {
|
|
331
|
+
throw new Error('DB.del()方法测试失败');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
this._recordResult('DB类测试', true, 'DB类方法测试通过');
|
|
335
|
+
return true;
|
|
336
|
+
} catch (error) {
|
|
337
|
+
this._recordResult('DB类测试', false, error.message);
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* 测试Sql类功能
|
|
344
|
+
* @returns {Promise<boolean>}
|
|
345
|
+
*/
|
|
346
|
+
TestMysql.prototype.testSqlClass = async function() {
|
|
347
|
+
try {
|
|
348
|
+
// 获取DB实例(Sql类的子类)
|
|
349
|
+
const db = this._mysql.db().new(this._test_table_name, 'id');
|
|
350
|
+
|
|
351
|
+
if (!db) {
|
|
352
|
+
throw new Error('获取Sql实例失败');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// 测试Sql类的addSql方法
|
|
356
|
+
const add_sql = db.toAddSql({
|
|
357
|
+
name: 'Sql测试用户',
|
|
358
|
+
email: 'sql_test@example.com',
|
|
359
|
+
age: 28
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
if (!add_sql || typeof add_sql !== 'string') {
|
|
363
|
+
throw new Error('Sql.toAddSql()方法测试失败');
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// 测试Sql类的getSql方法
|
|
367
|
+
const get_sql = db.toGetSql({ name: 'Sql测试用户' });
|
|
368
|
+
|
|
369
|
+
if (!get_sql || typeof get_sql !== 'string') {
|
|
370
|
+
throw new Error('Sql.toGetSql()方法测试失败');
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// 测试Sql类的escape方法
|
|
374
|
+
const escaped_value = db.escape("test' OR '1'='1");
|
|
375
|
+
|
|
376
|
+
if (!escaped_value || escaped_value === "test' OR '1'='1") {
|
|
377
|
+
throw new Error('Sql.escape()方法测试失败');
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
this._recordResult('Sql类测试', true, 'Sql类方法测试通过');
|
|
381
|
+
return true;
|
|
382
|
+
} catch (error) {
|
|
383
|
+
this._recordResult('Sql类测试', false, error.message);
|
|
285
384
|
return false;
|
|
286
385
|
}
|
|
287
386
|
};
|
|
@@ -290,7 +389,7 @@ TestMysql.prototype.test_delete = async function() {
|
|
|
290
389
|
* 测试事务功能
|
|
291
390
|
* @returns {Promise<boolean>}
|
|
292
391
|
*/
|
|
293
|
-
TestMysql.prototype.
|
|
392
|
+
TestMysql.prototype.testTransaction = async function() {
|
|
294
393
|
try {
|
|
295
394
|
const result = await this._mysql.transaction(async (tx) => {
|
|
296
395
|
// 在事务中插入数据 - 使用Mysql类的exec方法
|
|
@@ -304,10 +403,10 @@ TestMysql.prototype.test_transaction = async function() {
|
|
|
304
403
|
return results;
|
|
305
404
|
});
|
|
306
405
|
|
|
307
|
-
this.
|
|
406
|
+
this._recordResult('事务测试', true, '事务执行成功');
|
|
308
407
|
return true;
|
|
309
408
|
} catch (error) {
|
|
310
|
-
this.
|
|
409
|
+
this._recordResult('事务测试', false, error.message);
|
|
311
410
|
return false;
|
|
312
411
|
}
|
|
313
412
|
};
|
|
@@ -316,10 +415,10 @@ TestMysql.prototype.test_transaction = async function() {
|
|
|
316
415
|
* 测试连接池功能
|
|
317
416
|
* @returns {Promise<boolean>}
|
|
318
417
|
*/
|
|
319
|
-
TestMysql.prototype.
|
|
418
|
+
TestMysql.prototype.testConnectionPool = async function() {
|
|
320
419
|
try {
|
|
321
420
|
if (!this._mysql._pool) {
|
|
322
|
-
this.
|
|
421
|
+
this._recordResult('连接池测试', true, '连接池未启用(单连接模式)');
|
|
323
422
|
return true;
|
|
324
423
|
}
|
|
325
424
|
|
|
@@ -338,10 +437,10 @@ TestMysql.prototype.test_connection_pool = async function() {
|
|
|
338
437
|
}
|
|
339
438
|
});
|
|
340
439
|
|
|
341
|
-
this.
|
|
440
|
+
this._recordResult('连接池测试', true, `并发获取 ${connections.length} 个连接成功`);
|
|
342
441
|
return true;
|
|
343
442
|
} catch (error) {
|
|
344
|
-
this.
|
|
443
|
+
this._recordResult('连接池测试', false, error.message);
|
|
345
444
|
return false;
|
|
346
445
|
}
|
|
347
446
|
};
|
|
@@ -350,20 +449,20 @@ TestMysql.prototype.test_connection_pool = async function() {
|
|
|
350
449
|
* 测试错误处理
|
|
351
450
|
* @returns {Promise<boolean>}
|
|
352
451
|
*/
|
|
353
|
-
TestMysql.prototype.
|
|
452
|
+
TestMysql.prototype.testErrorHandling = async function() {
|
|
354
453
|
try {
|
|
355
454
|
// 测试无效SQL
|
|
356
455
|
const invalid_sql = 'SELECT * FROM non_existent_table';
|
|
357
456
|
await this._mysql.run(invalid_sql);
|
|
358
457
|
|
|
359
|
-
this.
|
|
458
|
+
this._recordResult('错误处理测试', false, '应该抛出错误但未抛出');
|
|
360
459
|
return false;
|
|
361
460
|
} catch (error) {
|
|
362
461
|
if (error.code && error.code.startsWith('ER_')) {
|
|
363
|
-
this.
|
|
462
|
+
this._recordResult('错误处理测试', true, `正确捕获SQL错误: ${error.message}`);
|
|
364
463
|
return true;
|
|
365
464
|
} else {
|
|
366
|
-
this.
|
|
465
|
+
this._recordResult('错误处理测试', false, `捕获到非预期错误: ${error.message}`);
|
|
367
466
|
return false;
|
|
368
467
|
}
|
|
369
468
|
}
|
|
@@ -373,27 +472,29 @@ TestMysql.prototype.test_error_handling = async function() {
|
|
|
373
472
|
* 运行所有测试
|
|
374
473
|
* @returns {Promise<Object>}
|
|
375
474
|
*/
|
|
376
|
-
TestMysql.prototype.
|
|
475
|
+
TestMysql.prototype.runAllTests = async function() {
|
|
377
476
|
console.log('\n=== 开始运行MySQL功能测试 ===\n');
|
|
378
477
|
|
|
379
478
|
// 初始化测试环境
|
|
380
479
|
const init_success = await this._init();
|
|
381
480
|
if (!init_success) {
|
|
382
481
|
console.log('测试环境初始化失败,跳过所有测试');
|
|
383
|
-
return this.
|
|
482
|
+
return this._getTestSummary();
|
|
384
483
|
}
|
|
385
484
|
|
|
386
485
|
// 定义测试用例
|
|
387
486
|
const test_cases = [
|
|
388
|
-
{ name: '连接测试', method: '
|
|
389
|
-
{ name: '插入测试', method: '
|
|
390
|
-
{ name: '查询测试', method: '
|
|
391
|
-
{ name: '条件查询测试', method: '
|
|
392
|
-
{ name: '更新测试', method: '
|
|
393
|
-
{ name: '删除测试', method: '
|
|
394
|
-
{ name: '
|
|
395
|
-
{ name: '
|
|
396
|
-
{ name: '
|
|
487
|
+
{ name: '连接测试', method: 'testConnection' },
|
|
488
|
+
{ name: '插入测试', method: 'testInsert' },
|
|
489
|
+
{ name: '查询测试', method: 'testQuery' },
|
|
490
|
+
{ name: '条件查询测试', method: 'testConditionalQuery' },
|
|
491
|
+
{ name: '更新测试', method: 'testUpdate' },
|
|
492
|
+
{ name: '删除测试', method: 'testDelete' },
|
|
493
|
+
{ name: 'DB类测试', method: 'testDbClass' },
|
|
494
|
+
{ name: 'Sql类测试', method: 'testSqlClass' },
|
|
495
|
+
{ name: '事务测试', method: 'testTransaction' },
|
|
496
|
+
{ name: '连接池测试', method: 'testConnectionPool' },
|
|
497
|
+
{ name: '错误处理测试', method: 'testErrorHandling' }
|
|
397
498
|
];
|
|
398
499
|
|
|
399
500
|
// 顺序执行测试用例
|
|
@@ -401,7 +502,7 @@ TestMysql.prototype.run_all_tests = async function() {
|
|
|
401
502
|
try {
|
|
402
503
|
await this[test_case.method]();
|
|
403
504
|
} catch (error) {
|
|
404
|
-
this.
|
|
505
|
+
this._recordResult(test_case.name, false, `测试执行异常: ${error.message}`);
|
|
405
506
|
}
|
|
406
507
|
|
|
407
508
|
// 添加短暂延迟,避免数据库压力
|
|
@@ -417,14 +518,14 @@ TestMysql.prototype.run_all_tests = async function() {
|
|
|
417
518
|
}
|
|
418
519
|
|
|
419
520
|
console.log('\n=== 测试完成 ===\n');
|
|
420
|
-
return this.
|
|
521
|
+
return this._getTestSummary();
|
|
421
522
|
};
|
|
422
523
|
|
|
423
524
|
/**
|
|
424
525
|
* 获取测试摘要
|
|
425
526
|
* @returns {Object}
|
|
426
527
|
*/
|
|
427
|
-
TestMysql.prototype.
|
|
528
|
+
TestMysql.prototype._getTestSummary = function() {
|
|
428
529
|
const total = this._test_results.length;
|
|
429
530
|
const passed = this._test_results.filter(r => r.success).length;
|
|
430
531
|
const failed = total - passed;
|
|
@@ -466,7 +567,7 @@ TestMysql.prototype._sleep = function(ms) {
|
|
|
466
567
|
*/
|
|
467
568
|
TestMysql.prototype.main = async function() {
|
|
468
569
|
try {
|
|
469
|
-
const summary = await this.
|
|
570
|
+
const summary = await this.runAllTests();
|
|
470
571
|
|
|
471
572
|
if (summary.failed > 0) {
|
|
472
573
|
console.log('\n❌ 部分测试失败,请检查数据库配置和连接');
|