mm_mysql 2.2.4 → 2.2.6

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.
Files changed (8) hide show
  1. package/README.md +3 -4
  2. package/README_EN.md +478 -0
  3. package/db.js +497 -496
  4. package/eslint.config.js +235 -0
  5. package/index.js +601 -601
  6. package/package.json +12 -5
  7. package/sql.js +1390 -1276
  8. package/test.js +481 -485
package/test.js CHANGED
@@ -6,104 +6,101 @@
6
6
 
7
7
  // 引入依赖
8
8
  const { Mysql } = require('./index.js');
9
- const { Sql } = require('../mm_sql/index.js');
10
9
 
11
10
  /**
12
11
  * 测试类
13
12
  * @class TestMysql
14
13
  */
15
14
  class TestMysql {
16
- /**
17
- * 构造函数
18
- * @param {Object} config - 数据库配置
19
- */
20
- constructor(config) {
21
- this.config = Object.assign({
22
- host: '127.0.0.1',
23
- port: 3306,
24
- user: 'root',
25
- password: 'Asd159357',
26
- database: '', // 先不指定数据库,连接成功后再创建
27
- debug: true,
28
- connection_limit: 5
29
- }, config || {});
30
-
31
- this._mysql = null;
32
- this._test_results = [];
33
- this._test_table_name = 'test_users';
34
- }
15
+ /**
16
+ * 构造函数
17
+ * @param {object} config - 数据库配置
18
+ */
19
+ constructor(config) {
20
+ this.config = {host: '127.0.0.1',
21
+ port: 3306,
22
+ user: 'root',
23
+ password: 'Asd159357',
24
+ database: '', // 先不指定数据库,连接成功后再创建
25
+ debug: true,
26
+ connection_limit: 5, ...config || {}};
27
+
28
+ this._mysql = null;
29
+ this._test_results = [];
30
+ this._test_table_name = 'test_users';
31
+ }
35
32
  }
36
33
 
37
34
  /**
38
35
  * 初始化测试环境(优化版)
39
- * @returns {Promise<boolean>}
36
+ * @returns {Promise<boolean>} 初始化是否成功
40
37
  */
41
38
  TestMysql.prototype._init = async function() {
42
- try {
43
- console.log('=== 初始化测试环境(优化版) ===');
39
+ try {
40
+ console.log('=== 初始化测试环境(优化版) ===');
44
41
 
45
- // 直接使用指定数据库,避免重复连接
46
- if (!this.config.database) {
47
- this.config.database = 'test_db';
48
- }
42
+ // 直接使用指定数据库,避免重复连接
43
+ if (!this.config.database) {
44
+ this.config.database = 'test_db';
45
+ }
49
46
 
50
- // 创建Mysql实例
51
- this._mysql = new Mysql(this.config);
47
+ // 创建Mysql实例
48
+ this._mysql = new Mysql(this.config);
52
49
 
53
- // 连接数据库
54
- await this._mysql.open();
50
+ // 连接数据库
51
+ await this._mysql.open();
55
52
 
56
- // 创建测试数据库(如果不存在)
57
- await this._createTestDatabase();
53
+ // 创建测试数据库(如果不存在)
54
+ await this._createTestDatabase();
58
55
 
59
- // 创建测试表
60
- await this._createTestTable();
56
+ // 创建测试表
57
+ await this._createTestTable();
61
58
 
62
- console.log('测试环境初始化完成');
63
- return true;
64
- } catch (error) {
65
- console.error('初始化测试环境失败:', error.message);
66
- return false;
67
- }
59
+ console.log('测试环境初始化完成');
60
+ return true;
61
+ } catch (error) {
62
+ console.error('初始化测试环境失败:', error.message);
63
+ return false;
64
+ }
68
65
  };
69
66
 
70
67
  /**
71
68
  * 创建测试数据库(优化版)
72
- * @returns {Promise<boolean>}
69
+ * @returns {Promise<boolean>} 数据库创建是否成功
73
70
  */
74
71
  TestMysql.prototype._createTestDatabase = async function() {
75
- try {
76
- // 检查数据库是否已存在,避免重复创建
77
- const check_db_sql = `SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?`;
78
- const existing_dbs = await this._mysql.run(check_db_sql, [this.config.database]);
79
-
80
- if (existing_dbs.length === 0) {
81
- const create_db_sql = `CREATE DATABASE ${this.config.database}`;
82
- await this._mysql.exec(create_db_sql);
83
- console.log('测试数据库创建成功');
84
- } else {
85
- console.log('测试数据库已存在,跳过创建');
86
- }
87
-
88
- return true;
89
- } catch (error) {
90
- console.error('创建测试数据库失败:', error.message);
91
- return false;
72
+ try {
73
+ // 检查数据库是否已存在,避免重复创建
74
+ const check_db_sql = `SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?`;
75
+ const existing_dbs = await this._mysql.run(check_db_sql, [this.config.database]);
76
+
77
+ if (existing_dbs.length === 0) {
78
+ const create_db_sql = `CREATE DATABASE ${this.config.database}`;
79
+ await this._mysql.exec(create_db_sql);
80
+ console.log('测试数据库创建成功');
81
+ } else {
82
+ console.log('测试数据库已存在,跳过创建');
92
83
  }
84
+
85
+ return true;
86
+ } catch (error) {
87
+ console.error('创建测试数据库失败:', error.message);
88
+ return false;
89
+ }
93
90
  };
94
91
 
95
92
  /**
96
93
  * 创建测试表(优化版)
97
- * @returns {Promise<boolean>}
94
+ * @returns {Promise<boolean>} 测试表创建是否成功
98
95
  */
99
96
  TestMysql.prototype._createTestTable = async function() {
100
- try {
101
- // 检查表是否已存在
102
- const check_table_sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`;
103
- const existing_tables = await this._mysql.run(check_table_sql, [this.config.database, 'test_users']);
97
+ try {
98
+ // 检查表是否已存在
99
+ const check_table_sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`;
100
+ const existing_tables = await this._mysql.run(check_table_sql, [this.config.database, 'test_users']);
104
101
 
105
- if (existing_tables.length === 0) {
106
- const sql = `
102
+ if (existing_tables.length === 0) {
103
+ const sql = `
107
104
  CREATE TABLE ${this._test_table_name} (
108
105
  id INT AUTO_INCREMENT PRIMARY KEY,
109
106
  name VARCHAR(100) NOT NULL,
@@ -113,562 +110,561 @@ TestMysql.prototype._createTestTable = async function() {
113
110
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
114
111
  )
115
112
  `;
116
- await this._mysql.exec(sql);
117
- console.log('测试表创建成功');
118
- } else {
119
- console.log('测试表已存在,跳过创建');
120
- }
121
-
122
- return true;
123
- } catch (error) {
124
- console.error('创建测试表失败:', error.message);
125
- return false;
113
+ await this._mysql.exec(sql);
114
+ console.log('测试表创建成功');
115
+ } else {
116
+ console.log('测试表已存在,跳过创建');
126
117
  }
118
+
119
+ return true;
120
+ } catch (error) {
121
+ console.error('创建测试表失败:', error.message);
122
+ return false;
123
+ }
127
124
  };
128
125
 
129
126
  /**
130
127
  * 预加载测试数据
131
- * @returns {Promise<boolean>}
128
+ * @returns {Promise<boolean>} 数据预加载是否成功
132
129
  */
133
130
  TestMysql.prototype._preloadTestData = async function() {
134
- try {
135
- console.log('=== 预加载测试数据 ===');
136
-
137
- // 清空现有数据
138
- await this._mysql.exec('TRUNCATE TABLE test_users');
139
-
140
- // 批量插入测试数据 - 使用多个VALUES子句
141
- const insert_sql = `INSERT INTO test_users (name, age, email) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?)`;
142
- const test_data = [
143
- '张三', 25, 'zhangsan@example.com',
144
- '李四', 30, 'lisi@example.com',
145
- '王五', 28, 'wangwu@example.com',
146
- '赵六', 35, 'zhaoliu@example.com',
147
- '钱七', 22, 'qianqi@example.com'
148
- ];
149
-
150
- await this._mysql.exec(insert_sql, test_data);
151
- console.log('测试数据预加载完成');
152
- return true;
153
- } catch (error) {
154
- console.error('预加载测试数据失败:', error.message);
155
- return false;
156
- }
131
+ try {
132
+ console.log('=== 预加载测试数据 ===');
133
+
134
+ // 清空现有数据
135
+ await this._mysql.exec('TRUNCATE TABLE test_users');
136
+
137
+ // 批量插入测试数据 - 使用多个VALUES子句
138
+ const insert_sql = `INSERT INTO test_users (name, age, email) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?), (?, ?, ?)`;
139
+ const data = [
140
+ '张三', 25, 'zhangsan@example.com',
141
+ '李四', 30, 'lisi@example.com',
142
+ '王五', 28, 'wangwu@example.com',
143
+ '赵六', 35, 'zhaoliu@example.com',
144
+ '钱七', 22, 'qianqi@example.com'
145
+ ];
146
+
147
+ await this._mysql.exec(insert_sql, data);
148
+ console.log('测试数据预加载完成');
149
+ return true;
150
+ } catch (error) {
151
+ console.error('预加载测试数据失败:', error.message);
152
+ return false;
153
+ }
157
154
  };
158
155
 
159
156
  /**
160
157
  * 清理测试数据
161
- * @returns {Promise<boolean>}
158
+ * @returns {Promise<boolean>} 清理是否成功
162
159
  */
163
160
  TestMysql.prototype._cleanup = async function() {
164
- try {
165
- const sql = `DROP TABLE IF EXISTS ${this._test_table_name}`;
166
- await this._mysql.exec(sql);
167
- console.log('测试数据清理完成');
168
- return true;
169
- } catch (error) {
170
- console.error('清理测试数据失败:', error.message);
171
- return false;
172
- }
161
+ try {
162
+ const sql = `DROP TABLE IF EXISTS ${this._test_table_name}`;
163
+ await this._mysql.exec(sql);
164
+ console.log('测试数据清理完成');
165
+ return true;
166
+ } catch (error) {
167
+ console.error('清理测试数据失败:', error.message);
168
+ return false;
169
+ }
173
170
  };
174
171
 
175
172
  /**
176
173
  * 记录测试结果
177
- * @param {String} test_name - 测试名称
178
- * @param {Boolean} success - 是否成功
179
- * @param {String} message - 测试信息
174
+ * @param {string} test_name - 测试名称
175
+ * @param {boolean} success - 是否成功
176
+ * @param {string} message - 测试信息
180
177
  */
181
178
  TestMysql.prototype._recordResult = function(test_name, success, message) {
182
- this._test_results.push({
183
- test_name,
184
- success,
185
- message,
186
- timestamp: new Date().toISOString()
187
- });
179
+ this._test_results.push({
180
+ test_name,
181
+ success,
182
+ message,
183
+ timestamp: new Date().toISOString()
184
+ });
188
185
 
189
- const status = success ? '✓' : '✗';
190
- console.log(`${status} ${test_name}: ${message}`);
186
+ const status = success ? '✓' : '✗';
187
+ console.log(`${status} ${test_name}: ${message}`);
191
188
  };
192
189
 
193
190
  /**
194
- * 测试连接功能
195
- * @returns {Promise<boolean>}
191
+ * 连接测试
192
+ * @returns {Promise<boolean>} 连接测试是否成功
196
193
  */
197
- TestMysql.prototype.testConnection = async function() {
198
- try {
199
- // 测试获取连接
200
- const conn = await this._mysql.getConn();
201
- if (!conn) {
202
- throw new Error('获取连接失败');
203
- }
204
-
205
- // 测试连接是否可用
206
- const [result] = await conn.execute('SELECT 1 as test_value');
207
- if (!result || !Array.isArray(result) || result.length === 0) {
208
- throw new Error('连接测试查询失败');
209
- }
194
+ TestMysql.prototype.testConn = async function() {
195
+ try {
196
+ // 测试获取连接
197
+ const conn = await this._mysql.getConn();
198
+ if (!conn) {
199
+ throw new Error('获取连接失败');
200
+ }
210
201
 
211
- // 如果是连接池连接,需要释放
212
- if (this._mysql._pool) {
213
- conn.release();
214
- }
202
+ // 测试连接是否可用
203
+ const [result] = await conn.execute('SELECT 1 as test_value');
204
+ if (!result || !Array.isArray(result) || result.length === 0) {
205
+ throw new Error('连接测试查询失败');
206
+ }
215
207
 
216
- this._recordResult('连接测试', true, '数据库连接正常');
217
- return true;
218
- } catch (error) {
219
- this._recordResult('连接测试', false, error.message);
220
- return false;
208
+ // 如果是连接池连接,需要释放
209
+ if (this._mysql._pool) {
210
+ conn.release();
221
211
  }
212
+
213
+ this._recordResult('连接测试', true, '数据库连接正常');
214
+ return true;
215
+ } catch (error) {
216
+ this._recordResult('连接测试', false, error.message);
217
+ return false;
218
+ }
222
219
  };
223
220
 
224
221
  /**
225
222
  * 测试插入功能(优化版)
226
- * @returns {Promise<boolean>}
223
+ * @returns {Promise<boolean>} 插入测试是否成功
227
224
  */
228
225
  TestMysql.prototype.testInsert = async function() {
229
- try {
230
- console.log('\n--- 插入测试(优化版) ---');
231
-
232
- // 使用预加载的数据进行查询验证,避免重复插入
233
- const query_sql = `SELECT COUNT(*) as count FROM ${this._test_table_name}`;
234
- const count_result = await this._mysql.run(query_sql);
235
-
236
- if (count_result && count_result[0].count > 0) {
237
- console.log('插入测试通过(使用预加载数据验证)');
238
- this._recordResult('插入测试', true, `数据插入验证成功,当前记录数: ${count_result[0].count}`);
239
- return true;
240
- } else {
241
- throw new Error('预加载数据验证失败');
242
- }
243
- } catch (error) {
244
- console.error('插入测试失败:', error.message);
245
- this._recordResult('插入测试', false, error.message);
246
- return false;
226
+ try {
227
+ console.log('\n--- 插入测试(优化版) ---');
228
+
229
+ // 使用预加载的数据进行查询验证,避免重复插入
230
+ const query_sql = `SELECT COUNT(*) as count FROM ${this._test_table_name}`;
231
+ const count = await this._mysql.run(query_sql);
232
+
233
+ if (count && count[0].count > 0) {
234
+ console.log('插入测试通过(使用预加载数据验证)');
235
+ this._recordResult('插入测试', true, `数据插入验证成功,当前记录数: ${count[0].count}`);
236
+ return true;
237
+ } else {
238
+ throw new Error('预加载数据验证失败');
247
239
  }
240
+ } catch (error) {
241
+ console.error('插入测试失败:', error.message);
242
+ this._recordResult('插入测试', false, error.message);
243
+ return false;
244
+ }
248
245
  };
249
246
 
250
247
  /**
251
248
  * 测试查询功能
252
- * @returns {Promise<boolean>}
249
+ * @returns {Promise<boolean>} 查询测试是否成功
253
250
  */
254
251
  TestMysql.prototype.testQuery = async function() {
255
- try {
256
- // 查询所有数据
257
- const sql = `SELECT * FROM ${this._test_table_name}`;
258
- const results = await this._mysql.run(sql);
259
-
260
- if (!Array.isArray(results)) {
261
- throw new Error('查询结果格式异常');
262
- }
252
+ try {
253
+ // 查询所有数据
254
+ const sql = `SELECT * FROM ${this._test_table_name}`;
255
+ const results = await this._mysql.run(sql);
263
256
 
264
- this._recordResult('查询测试', true, `查询到 ${results.length} 条记录`);
265
- return true;
266
- } catch (error) {
267
- this._recordResult('查询测试', false, error.message);
268
- return false;
257
+ if (!Array.isArray(results)) {
258
+ throw new Error('查询结果格式异常');
269
259
  }
260
+
261
+ this._recordResult('查询测试', true, `查询到 ${results.length} 条记录`);
262
+ return true;
263
+ } catch (error) {
264
+ this._recordResult('查询测试', false, error.message);
265
+ return false;
266
+ }
270
267
  };
271
268
 
272
269
  /**
273
270
  * 测试条件查询
274
- * @returns {Promise<boolean>}
271
+ * @returns {Promise<boolean>} 条件查询测试是否成功
275
272
  */
276
- TestMysql.prototype.testConditionalQuery = async function() {
277
- try {
278
- // 使用预加载数据中的特定名称进行查询
279
- const sql = `SELECT * FROM ${this._test_table_name} WHERE name = ?`;
280
- const results = await this._mysql.run(sql, ['张三']);
281
-
282
- if (!Array.isArray(results)) {
283
- throw new Error('条件查询结果格式异常');
284
- }
285
-
286
- this._recordResult('条件查询测试', true, `查询到 ${results.length} 条匹配记录`);
287
- return true;
288
- } catch (error) {
289
- this._recordResult('条件查询测试', false, error.message);
290
- return false;
273
+ TestMysql.prototype.testCondQuery = async function() {
274
+ try {
275
+ // 使用预加载数据中的特定名称进行查询
276
+ const sql = `SELECT * FROM ${this._test_table_name} WHERE name = ?`;
277
+ const results = await this._mysql.run(sql, ['张三']);
278
+
279
+ if (!Array.isArray(results)) {
280
+ throw new Error('条件查询结果格式异常');
291
281
  }
282
+
283
+ this._recordResult('条件查询测试', true, `查询到 ${results.length} 条匹配记录`);
284
+ return true;
285
+ } catch (error) {
286
+ this._recordResult('条件查询测试', false, error.message);
287
+ return false;
288
+ }
292
289
  };
293
290
 
294
291
  /**
295
292
  * 测试更新功能
296
- * @returns {Promise<boolean>}
293
+ * @returns {Promise<boolean>} 更新测试是否成功
297
294
  */
298
295
  TestMysql.prototype.testUpdate = async function() {
299
- try {
300
- // 先插入独立的测试数据用于更新测试
301
- const test_user_name = '更新测试用户';
302
- const insert_sql = `INSERT INTO ${this._test_table_name} (name, email, age) VALUES (?, ?, ?)`;
303
- const insert_result = await this._mysql.exec(insert_sql, [test_user_name, 'update_test@example.com', 25]);
304
-
305
- if (insert_result < 1) {
306
- throw new Error('插入测试数据失败');
307
- }
308
-
309
- // 更新独立的测试数据
310
- const update_sql = `UPDATE ${this._test_table_name} SET age = ? WHERE name = ?`;
311
- const result = await this._mysql.exec(update_sql, [30, test_user_name]);
296
+ try {
297
+ // 先插入独立的测试数据用于更新测试
298
+ const test_user_name = '更新测试用户';
299
+ const insert_sql = `INSERT INTO ${this._test_table_name} (name, email, age) VALUES (?, ?, ?)`;
300
+ const res = await this._mysql.exec(insert_sql, [test_user_name, 'update_test@example.com', 25]);
301
+
302
+ if (res < 1) {
303
+ throw new Error('插入测试数据失败');
304
+ }
312
305
 
313
- if (result < 1) {
314
- throw new Error('更新数据失败');
315
- }
306
+ // 更新独立的测试数据
307
+ const update_sql = `UPDATE ${this._test_table_name} SET age = ? WHERE name = ?`;
308
+ const result = await this._mysql.exec(update_sql, [30, test_user_name]);
316
309
 
317
- this._recordResult('更新测试', true, `更新了 ${result} 条记录`);
318
- return true;
319
- } catch (error) {
320
- this._recordResult('更新测试', false, error.message);
321
- return false;
310
+ if (result < 1) {
311
+ throw new Error('更新数据失败');
322
312
  }
313
+
314
+ this._recordResult('更新测试', true, `更新了 ${result} 条记录`);
315
+ return true;
316
+ } catch (error) {
317
+ this._recordResult('更新测试', false, error.message);
318
+ return false;
319
+ }
323
320
  };
324
321
 
325
322
  /**
326
323
  * 测试删除功能
327
- * @returns {Promise<boolean>}
324
+ * @returns {Promise<boolean>} 删除测试是否成功
328
325
  */
329
326
  TestMysql.prototype.testDelete = async function() {
330
- try {
331
- // 先插入独立的测试数据用于删除测试
332
- const test_user_name = '删除测试用户';
333
- const insert_sql = `INSERT INTO ${this._test_table_name} (name, email, age) VALUES (?, ?, ?)`;
334
- const insert_result = await this._mysql.exec(insert_sql, [test_user_name, 'delete_test@example.com', 25]);
335
-
336
- if (insert_result < 1) {
337
- throw new Error('插入测试数据失败');
338
- }
327
+ try {
328
+ // 先插入独立的测试数据用于删除测试
329
+ const test_user_name = '删除测试用户';
330
+ const insert_sql = `INSERT INTO ${this._test_table_name} (name, email, age) VALUES (?, ?, ?)`;
331
+ const res = await this._mysql.exec(insert_sql, [test_user_name, 'delete_test@example.com', 25]);
332
+
333
+ if (res < 1) {
334
+ throw new Error('插入测试数据失败');
335
+ }
339
336
 
340
- // 删除独立的测试数据
341
- const delete_sql = `DELETE FROM ${this._test_table_name} WHERE name = ?`;
342
- const result = await this._mysql.exec(delete_sql, [test_user_name]);
337
+ // 删除独立的测试数据
338
+ const delete_sql = `DELETE FROM ${this._test_table_name} WHERE name = ?`;
339
+ const result = await this._mysql.exec(delete_sql, [test_user_name]);
343
340
 
344
- if (result < 1) {
345
- throw new Error('删除数据失败');
346
- }
347
-
348
- this._recordResult('删除测试', true, `删除了 ${result} 条记录`);
349
- return true;
350
- } catch (error) {
351
- this._recordResult('删除测试', false, error.message);
352
- return false;
341
+ if (result < 1) {
342
+ throw new Error('删除数据失败');
353
343
  }
344
+
345
+ this._recordResult('删除测试', true, `删除了 ${result} 条记录`);
346
+ return true;
347
+ } catch (error) {
348
+ this._recordResult('删除测试', false, error.message);
349
+ return false;
350
+ }
354
351
  };
355
352
 
356
353
  /**
357
354
  * 测试DB类功能
358
- * @returns {Promise<boolean>}
355
+ * @returns {Promise<boolean>} DB类测试是否成功
359
356
  */
360
357
  TestMysql.prototype.testDbClass = async function() {
361
- try {
362
- // 获取DB实例
363
- const db = this._mysql.db().new(this._test_table_name, 'id');
358
+ try {
359
+ // 获取DB实例
360
+ const db = this._mysql.db().new(this._test_table_name, 'id');
364
361
 
365
- if (!db) {
366
- throw new Error('获取DB实例失败');
367
- }
362
+ if (!db) {
363
+ throw new Error('获取DB实例失败');
364
+ }
368
365
 
369
- // 使用独立的测试数据,避免影响预加载数据
370
- const test_user_name = 'DB独立测试用户';
371
-
372
- // 测试DB类的add方法
373
- const add_result = await db.add({
374
- name: test_user_name,
375
- email: 'db_test@example.com',
376
- age: 30
377
- });
378
- if (add_result < 1) {
379
- throw new Error('DB.add()方法测试失败');
380
- }
366
+ // 使用独立的测试数据,避免影响预加载数据
367
+ const test_user_name = 'DB独立测试用户';
381
368
 
382
- // 测试DB类的get方法
383
- const get_result = await db.get({ name: test_user_name });
384
- if (get_result.length < 1) {
385
- throw new Error('DB.get()方法测试失败');
386
- }
369
+ // 测试DB类的add方法
370
+ const id = await db.add({
371
+ name: test_user_name,
372
+ email: 'db_test@example.com',
373
+ age: 30
374
+ });
375
+ if (id < 1) {
376
+ throw new Error('DB.add()方法测试失败');
377
+ }
387
378
 
388
- // 测试DB类的set方法
389
- const set_result = await db.set({ id: add_result }, { age: 31 });
379
+ // 测试DB类的get方法
380
+ const user = await db.get({ name: test_user_name });
381
+ if (user.length < 1) {
382
+ throw new Error('DB.get()方法测试失败');
383
+ }
390
384
 
391
- if (set_result < 1) {
392
- throw new Error('DB.set()方法测试失败');
393
- }
385
+ // 测试DB类的set方法
386
+ const updated = await db.set({ id: id }, { age: 31 });
394
387
 
395
- // 测试DB类的del方法
396
- const del_result = await db.del({ id: add_result });
388
+ if (updated < 1) {
389
+ throw new Error('DB.set()方法测试失败');
390
+ }
397
391
 
398
- if (del_result < 1) {
399
- throw new Error('DB.del()方法测试失败');
400
- }
392
+ // 测试DB类的del方法
393
+ const deleted = await db.del({ id: id });
401
394
 
402
- this._recordResult('DB类测试', true, 'DB类方法测试通过');
403
- return true;
404
- } catch (error) {
405
- this._recordResult('DB类测试', false, error.message);
406
- return false;
395
+ if (deleted < 1) {
396
+ throw new Error('DB.del()方法测试失败');
407
397
  }
398
+
399
+ this._recordResult('DB类测试', true, 'DB类方法测试通过');
400
+ return true;
401
+ } catch (error) {
402
+ this._recordResult('DB类测试', false, error.message);
403
+ return false;
404
+ }
408
405
  };
409
406
 
410
407
  /**
411
408
  * 测试Sql类功能(优化版)
412
- * @returns {Promise<boolean>}
409
+ * @returns {Promise<boolean>} Sql类测试是否成功
413
410
  */
414
411
  TestMysql.prototype.testSqlClass = async function() {
415
- try {
416
- console.log('\n--- Sql类测试(优化版) ---');
412
+ try {
413
+ console.log('\n--- Sql类测试(优化版) ---');
417
414
 
418
- // 直接使用mysql2的escape函数测试SQL转义功能,避免创建新的数据库连接
419
- const mysql2 = require('mysql2');
415
+ // 直接使用mysql2的escape函数测试SQL转义功能,避免创建新的数据库连接
416
+ const mysql2 = require('mysql2');
420
417
 
421
- // 测试escape方法
422
- const escaped_value = mysql2.escape("test'value");
423
- console.log('escape结果:', escaped_value);
418
+ // 测试escape方法
419
+ const escaped = mysql2.escape("test'value");
420
+ console.log('escape结果:', escaped);
424
421
 
425
- // 测试toAddSql方法逻辑(手动实现)
426
- const test_data = { name: 'Sql测试用户', age: 30, email: 'sql_test@example.com' };
427
- let keys = '';
428
- let values = '';
422
+ // 测试toAddSql方法逻辑(手动实现)
423
+ const data = { name: 'Sql测试用户', age: 30, email: 'sql_test@example.com' };
424
+ let keys = '';
425
+ let values = '';
429
426
 
430
- for (const key in test_data) {
431
- keys += `, \`${key}\``;
432
- values += `, ${mysql2.escape(test_data[key])}`;
433
- }
427
+ for (const key in data) {
428
+ keys += `, \`${key}\``;
429
+ values += `, ${mysql2.escape(data[key])}`;
430
+ }
434
431
 
435
- const add_sql = `INSERT INTO test_users (${keys.replace(', ', '')}) VALUES (${values.replace(', ', '')})`;
436
- console.log('toAddSql结果:', add_sql);
432
+ const add_sql = `INSERT INTO test_users (${keys.replace(', ', '')}) VALUES (${values.replace(', ', '')})`;
433
+ console.log('toAddSql结果:', add_sql);
437
434
 
438
- // 测试toGetSql方法逻辑(手动实现)
439
- const get_sql = `SELECT * FROM test_users WHERE id = ${mysql2.escape(1)}`;
440
- console.log('toGetSql结果:', get_sql);
435
+ // 测试toGetSql方法逻辑(手动实现)
436
+ const get_sql = `SELECT * FROM test_users WHERE id = ${mysql2.escape(1)}`;
437
+ console.log('toGetSql结果:', get_sql);
441
438
 
442
- // 使用预加载的数据进行查询,避免重复插入
443
- const query_result = await this._mysql.run(get_sql);
444
- console.log('查询结果:', query_result);
439
+ // 使用预加载的数据进行查询,避免重复插入
440
+ const rows = await this._mysql.run(get_sql);
441
+ console.log('查询结果:', rows);
445
442
 
446
- this._recordResult('Sql类测试', true, 'Sql类方法逻辑测试通过');
447
- return true;
448
- } catch (error) {
449
- console.error('Sql类测试失败:', error.message);
450
- this._recordResult('Sql类测试', false, error.message);
451
- return false;
452
- }
443
+ this._recordResult('Sql类测试', true, 'Sql类方法逻辑测试通过');
444
+ return true;
445
+ } catch (error) {
446
+ console.error('Sql类测试失败:', error.message);
447
+ this._recordResult('Sql类测试', false, error.message);
448
+ return false;
449
+ }
453
450
  };
454
451
 
455
452
  /**
456
453
  * 测试事务功能
457
- * @returns {Promise<boolean>}
454
+ * @returns {Promise<boolean>} 事务测试是否成功
458
455
  */
459
- TestMysql.prototype.testTransaction = async function() {
460
- try {
461
- // 测试事务基本功能 - 不执行实际SQL操作
462
- const result = await this._mysql.transaction(async (tx) => {
463
- // 简单的事务测试,只验证事务对象存在
464
- if (tx && tx.commit && tx.rollback) {
465
- return { success: true, message: '事务对象正确创建' };
466
- } else {
467
- throw new Error('事务对象缺少必要方法');
468
- }
469
- });
470
-
471
- console.log("事务测试结果", result);
472
- this._recordResult('事务测试', true, '事务执行成功');
473
- return true;
474
- } catch (error) {
475
- this._recordResult('事务测试', false, error.message);
476
- return false;
477
- }
456
+ TestMysql.prototype.testTrans = async function() {
457
+ try {
458
+ // 测试事务基本功能 - 不执行实际SQL操作
459
+ const result = await this._mysql.transaction(async (tx) => {
460
+ // 简单的事务测试,只验证事务对象存在
461
+ if (tx && tx.commit && tx.rollback) {
462
+ return { success: true, message: '事务对象正确创建' };
463
+ } else {
464
+ throw new Error('事务对象缺少必要方法');
465
+ }
466
+ });
467
+
468
+ console.log('事务测试结果', result);
469
+ this._recordResult('事务测试', true, '事务执行成功');
470
+ return true;
471
+ } catch (error) {
472
+ this._recordResult('事务测试', false, error.message);
473
+ return false;
474
+ }
478
475
  };
479
476
 
480
477
  /**
481
478
  * 测试连接池功能
482
- * @returns {Promise<boolean>}
479
+ * @returns {Promise<boolean>} 连接池测试是否成功
483
480
  */
484
- TestMysql.prototype.testConnectionPool = async function() {
485
- try {
486
- if (!this._mysql._pool) {
487
- this._recordResult('连接池测试', true, '连接池未启用(单连接模式)');
488
- return true;
489
- }
481
+ TestMysql.prototype.testConnPool = async function() {
482
+ try {
483
+ if (!this._mysql._pool) {
484
+ this._recordResult('连接池测试', true, '连接池未启用(单连接模式)');
485
+ return true;
486
+ }
490
487
 
491
- // 使用更安全的方式测试连接池 - 顺序获取和释放连接
492
- const connections = [];
493
-
494
- // 顺序获取连接,避免并发问题
495
- for (let i = 0; i < 2; i++) {
496
- const conn = await this._mysql.getConn();
497
- if (conn) {
498
- connections.push(conn);
499
- // 立即释放连接,避免资源占用
500
- if (conn.release) {
501
- conn.release();
502
- }
503
- }
488
+ // 使用更安全的方式测试连接池 - 顺序获取和释放连接
489
+ const conns = [];
490
+
491
+ // 顺序获取连接,避免并发问题
492
+ for (let i = 0; i < 2; i++) {
493
+ const conn = await this._mysql.getConn();
494
+ if (conn) {
495
+ conns.push(conn);
496
+ // 立即释放连接,避免资源占用
497
+ if (conn.release) {
498
+ conn.release();
504
499
  }
505
-
506
- this._recordResult('连接池测试', true, `顺序获取 ${connections.length} 个连接成功`);
507
- return true;
508
- } catch (error) {
509
- this._recordResult('连接池测试', false, error.message);
510
- return false;
500
+ }
511
501
  }
502
+
503
+ this._recordResult('连接池测试', true, `顺序获取 ${conns.length} 个连接成功`);
504
+ return true;
505
+ } catch (error) {
506
+ this._recordResult('连接池测试', false, error.message);
507
+ return false;
508
+ }
512
509
  };
513
510
 
514
511
  /**
515
512
  * 测试错误处理
516
- * @returns {Promise<boolean>}
513
+ * @returns {Promise<boolean>} 错误处理测试是否成功
517
514
  */
518
515
  TestMysql.prototype.testErrorHandling = async function() {
516
+ try {
517
+ // 测试无效SQL - 使用更安全的错误测试方式
518
+ const invalid_sql = 'SELECT * FROM non_existent_table';
519
+
520
+ // 临时禁用错误输出
521
+ const debug = this._mysql._debug;
522
+ this._mysql._debug = false;
523
+
524
+ // 使用try-catch捕获可能的异常
519
525
  try {
520
- // 测试无效SQL - 使用更安全的错误测试方式
521
- const invalid_sql = 'SELECT * FROM non_existent_table';
522
-
523
- // 临时禁用错误输出
524
- const originalDebug = this._mysql._debug;
525
- this._mysql._debug = false;
526
-
527
- // 使用try-catch捕获可能的异常
528
- let result;
529
- try {
530
- result = await this._mysql.run(invalid_sql);
531
- } catch (error) {
532
- // 预期中的错误,继续处理
533
- result = null;
534
- }
526
+ await this._mysql.run(invalid_sql);
527
+ } catch {
528
+ // 预期中的错误,继续处理
529
+ }
535
530
 
536
- // 恢复调试设置
537
- this._mysql._debug = originalDebug;
531
+ // 恢复调试设置
532
+ this._mysql._debug = debug;
538
533
 
539
- // 检查是否设置了错误信息
540
- if (this._mysql.error && this._mysql.error.code) {
541
- this._recordResult('错误处理测试', true, `正确捕获SQL错误: ${this._mysql.error.message}`);
542
- return true;
543
- } else {
544
- this._recordResult('错误处理测试', false, '未正确捕获SQL错误');
545
- return false;
546
- }
547
- } catch (error) {
548
- this._recordResult('错误处理测试', false, `发生非预期错误: ${error.message}`);
549
- return false;
534
+ // 检查是否设置了错误信息
535
+ if (this._mysql.error && this._mysql.error.code) {
536
+ this._recordResult('错误处理测试', true, `正确捕获SQL错误: ${this._mysql.error.message}`);
537
+ return true;
538
+ } else {
539
+ this._recordResult('错误处理测试', false, '未正确捕获SQL错误');
540
+ return false;
550
541
  }
542
+ } catch (error) {
543
+ this._recordResult('错误处理测试', false, `发生非预期错误: ${error.message}`);
544
+ return false;
545
+ }
551
546
  };
552
547
 
553
548
  /**
554
549
  * 运行所有测试(优化版)
555
- * @returns {Promise<Object>}
550
+ * @returns {Promise<object>} 测试结果汇总
556
551
  */
557
552
  TestMysql.prototype.runAllTests = async function() {
558
- console.log('\n=== 开始运行MySQL功能测试(优化版) ===\n');
553
+ console.log('\n=== 开始运行MySQL功能测试(优化版) ===\n');
559
554
 
560
- // 记录开始时间
561
- const start_time = Date.now();
555
+ // 记录开始时间
556
+ const start_time = Date.now();
562
557
 
563
- // 初始化测试环境
564
- const init_success = await this._init();
565
- if (!init_success) {
566
- console.log('测试环境初始化失败,跳过所有测试');
567
- return this._getTestSummary();
568
- }
558
+ // 初始化测试环境
559
+ const init_success = await this._init();
560
+ if (!init_success) {
561
+ console.log('测试环境初始化失败,跳过所有测试');
562
+ return this._getTestSummary();
563
+ }
569
564
 
570
- // 预插入测试数据,避免每个测试单独插入
571
- await this._preloadTestData();
565
+ // 预插入测试数据,避免每个测试单独插入
566
+ await this._preloadTestData();
572
567
 
573
- // 定义测试用例(重新排序,将耗时较少的测试放在前面)
574
- const test_cases = [
575
- { name: '连接测试', method: 'testConnection' },
576
- { name: '查询测试', method: 'testQuery' },
577
- { name: '条件查询测试', method: 'testConditionalQuery' },
578
- { name: '插入测试', method: 'testInsert' },
579
- { name: 'DB类测试', method: 'testDbClass' },
580
- { name: 'Sql类测试', method: 'testSqlClass' },
581
- { name: '更新测试', method: 'testUpdate' },
582
- { name: '删除测试', method: 'testDelete' },
583
- { name: '事务测试', method: 'testTransaction' },
584
- { name: '连接池测试', method: 'testConnectionPool' },
585
- { name: '错误处理测试', method: 'testErrorHandling' }
586
- ];
568
+ // 定义测试用例(重新排序,将耗时较少的测试放在前面)
569
+ const test_cases = [
570
+ { name: '连接测试', method: 'testConn' },
571
+ { name: '查询测试', method: 'testQuery' },
572
+ { name: '条件查询测试', method: 'testCondQuery' },
573
+ { name: '插入测试', method: 'testInsert' },
574
+ { name: 'DB类测试', method: 'testDbClass' },
575
+ { name: 'Sql类测试', method: 'testSqlClass' },
576
+ { name: '更新测试', method: 'testUpdate' },
577
+ { name: '删除测试', method: 'testDelete' },
578
+ { name: '事务测试', method: 'testTrans' },
579
+ { name: '连接池测试', method: 'testConnPool' },
580
+ { name: '错误处理测试', method: 'testErrorHandling' }
581
+ ];
587
582
 
588
- // 顺序执行测试用例(移除延迟,提高测试速度)
589
- for (const test_case of test_cases) {
590
- try {
591
- console.log(`执行测试: ${test_case.name}`);
592
- await this[test_case.method]();
593
- console.log(`测试完成: ${test_case.name}`);
594
- } catch (error) {
595
- console.error(`测试异常: ${test_case.name}`, error);
596
- this._recordResult(test_case.name, false, `测试执行异常: ${error.message}`);
597
- }
583
+ // 顺序执行测试用例(移除延迟,提高测试速度)
584
+ for (const test_case of test_cases) {
585
+ try {
586
+ console.log(`执行测试: ${test_case.name}`);
587
+ await this[test_case.method]();
588
+ console.log(`测试完成: ${test_case.name}`);
589
+ } catch (error) {
590
+ console.error(`测试异常: ${test_case.name}`, error);
591
+ this._recordResult(test_case.name, false, `测试执行异常: ${error.message}`);
598
592
  }
593
+ }
599
594
 
600
- // 清理测试环境
601
- await this._cleanup();
595
+ // 清理测试环境
596
+ await this._cleanup();
602
597
 
603
- // 关闭数据库连接
604
- if (this._mysql) {
605
- await this._mysql.close();
606
- }
598
+ // 关闭数据库连接
599
+ if (this._mysql) {
600
+ await this._mysql.close();
601
+ }
607
602
 
608
- const total_time = Date.now() - start_time;
609
- console.log(`\n=== 测试完成,总耗时: ${total_time}ms ===\n`);
610
- return this._getTestSummary();
603
+ const time = Date.now() - start_time;
604
+ console.log(`\n=== 测试完成,总耗时: ${time}ms ===\n`);
605
+ return this._getTestSummary();
611
606
  };
612
607
 
613
608
  /**
614
609
  * 获取测试摘要
615
- * @returns {Object}
610
+ * @returns {object} 测试结果摘要信息
616
611
  */
617
612
  TestMysql.prototype._getTestSummary = function() {
618
- const total = this._test_results.length;
619
- const passed = this._test_results.filter(r => r.success).length;
620
- const failed = total - passed;
613
+ const total = this._test_results.length;
614
+ const passed = this._test_results.filter(r => r.success).length;
615
+ const failed = total - passed;
621
616
 
622
- console.log(`测试摘要:`);
623
- console.log(`总测试数: ${total}`);
624
- console.log(`通过: ${passed}`);
625
- console.log(`失败: ${failed}`);
626
- console.log(`通过率: ${((passed / total) * 100).toFixed(1)}%`);
617
+ console.log(`测试摘要:`);
618
+ console.log(`总测试数: ${total}`);
619
+ console.log(`通过: ${passed}`);
620
+ console.log(`失败: ${failed}`);
621
+ console.log(`通过率: ${((passed / total) * 100).toFixed(1)}%`);
627
622
 
628
- // 显示失败的测试
629
- const failed_tests = this._test_results.filter(r => !r.success);
630
- if (failed_tests.length > 0) {
631
- console.log('\n失败的测试:');
632
- failed_tests.forEach(test => {
633
- console.log(` ✗ ${test.test_name}: ${test.message}`);
634
- });
635
- }
623
+ // 显示失败的测试
624
+ const failed_tests = this._test_results.filter(r => !r.success);
625
+ if (failed_tests.length > 0) {
626
+ console.log('\n失败的测试:');
627
+ failed_tests.forEach(test => {
628
+ console.log(` ✗ ${test.test_name}: ${test.message}`);
629
+ });
630
+ }
636
631
 
637
- return {
638
- total,
639
- passed,
640
- failed,
641
- results: this._test_results
642
- };
632
+ return {
633
+ total,
634
+ passed,
635
+ failed,
636
+ results: this._test_results
637
+ };
643
638
  };
644
639
 
645
640
  /**
646
641
  * 休眠函数
647
- * @param {Number} ms - 毫秒数
648
- * @returns {Promise}
642
+ * @param {number} ms - 毫秒数
643
+ * @returns {Promise<void>} 休眠完成的Promise
649
644
  */
650
645
  TestMysql.prototype._sleep = function(ms) {
651
- return new Promise(resolve => setTimeout(resolve, ms));
646
+ return new Promise(resolve => setTimeout(resolve, ms));
652
647
  };
653
648
 
654
649
  /**
655
650
  * 主测试函数
651
+ * @returns {Promise<void>}
656
652
  */
657
653
  TestMysql.prototype.main = async function() {
658
- try {
659
- const summary = await this.runAllTests();
660
-
661
- if (summary.failed > 0) {
662
- console.log('\n❌ 部分测试失败,请检查数据库配置和连接');
663
- process.exit(1);
664
- } else {
665
- console.log('\n✅ 所有测试通过!');
666
- process.exit(0);
667
- }
668
- } catch (error) {
669
- console.error('测试执行异常:', error);
670
- process.exit(1);
654
+ try {
655
+ const summary = await this.runAllTests();
656
+
657
+ if (summary.failed > 0) {
658
+ console.log('\n❌ 部分测试失败,请检查数据库配置和连接');
659
+ process.exit(1);
660
+ } else {
661
+ console.log('\n✅ 所有测试通过!');
662
+ process.exit(0);
671
663
  }
664
+ } catch (error) {
665
+ console.error('测试执行异常:', error);
666
+ process.exit(1);
667
+ }
672
668
  };
673
669
 
674
670
  // 模块导出
@@ -676,32 +672,32 @@ exports.TestMysql = TestMysql;
676
672
 
677
673
  /**
678
674
  * 快速测试函数
679
- * @param {Object} config - 数据库配置
675
+ * @param {object} config - 数据库配置
680
676
  */
681
677
  const quick_test = async function(config) {
682
- const tester = new TestMysql(config);
683
- await tester.main();
678
+ const tester = new TestMysql(config);
679
+ await tester.main();
684
680
  };
685
681
 
686
682
  // 如果直接运行此文件,执行测试
687
683
  if (require.main === module) {
688
- // 从环境变量或默认配置获取数据库连接信息
689
- const test_config = {
690
- host: process.env.DB_HOST || '127.0.0.1',
691
- port: parseInt(process.env.DB_PORT) || 3306,
692
- user: process.env.DB_USER || 'root',
693
- password: process.env.DB_PASSWORD || 'Asd159357',
694
- database: process.env.DB_NAME || 'test_db',
695
- debug: process.env.DEBUG === 'true',
696
- connection_limit: parseInt(process.env.DB_CONNECTION_LIMIT) || 5
697
- };
684
+ // 从环境变量或默认配置获取数据库连接信息
685
+ const test_config = {
686
+ host: process.env.DB_HOST || '127.0.0.1',
687
+ port: parseInt(process.env.DB_PORT) || 3306,
688
+ user: process.env.DB_USER || 'root',
689
+ password: process.env.DB_PASSWORD || 'Asd159357',
690
+ database: process.env.DB_NAME || 'test_db',
691
+ debug: process.env.DEBUG === 'true',
692
+ connection_limit: parseInt(process.env.DB_CONNECTION_LIMIT) || 5
693
+ };
698
694
 
699
- console.log('使用配置:', {
700
- ...test_config,
701
- password: '***' // 隐藏密码
702
- });
695
+ console.log('使用配置:', {
696
+ ...test_config,
697
+ password: '***' // 隐藏密码
698
+ });
703
699
 
704
- quick_test(test_config);
700
+ quick_test(test_config);
705
701
  }
706
702
 
707
703
  // 导出快速测试函数