mm_mysql 2.4.1 → 2.4.2

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 (4) hide show
  1. package/db.js +152 -223
  2. package/index.js +19 -24
  3. package/package.json +2 -2
  4. package/sql.js +303 -421
package/db.js CHANGED
@@ -79,13 +79,7 @@ DB.prototype.new = function (table = '', key = '') {
79
79
  * @returns {Promise<object>}
80
80
  */
81
81
  DB.prototype.getConn = async function () {
82
- try {
83
- return await this.getParent().getConn();
84
- } catch (error) {
85
- this.log('error', '获取连接失败', error);
86
- // 返回null作为默认值,保持返回值类型一致
87
- return null;
88
- }
82
+ return await this.getParent().getConn();
89
83
  };
90
84
 
91
85
  /**
@@ -93,13 +87,7 @@ DB.prototype.getConn = async function () {
93
87
  * @returns {Promise<object>}
94
88
  */
95
89
  DB.prototype.start = async function () {
96
- try {
97
- return await this.getParent().beginTransaction();
98
- } catch (error) {
99
- this.log('error', '开始事务失败', error);
100
- // 返回null作为默认值,保持返回值类型一致
101
- return null;
102
- }
90
+ return await this.getParent().beginTransaction();
103
91
  };
104
92
 
105
93
  /**
@@ -114,11 +102,7 @@ DB.prototype.commit = async function (transaction) {
114
102
  throw new TypeError('transaction must be object');
115
103
  }
116
104
 
117
- try {
118
- await transaction.commit();
119
- } catch (error) {
120
- this.log('error', '提交事务失败', error);
121
- }
105
+ await transaction.commit();
122
106
  };
123
107
 
124
108
  /**
@@ -133,11 +117,7 @@ DB.prototype.back = async function (transaction) {
133
117
  throw new TypeError('transaction must be object');
134
118
  }
135
119
 
136
- try {
137
- await transaction.rollback();
138
- } catch (error) {
139
- this.log('error', '回滚事务失败', error);
140
- }
120
+ await transaction.rollback();
141
121
  };
142
122
 
143
123
  /**
@@ -152,13 +132,7 @@ DB.prototype.transaction = async function (callback) {
152
132
  throw new TypeError('callback must be function');
153
133
  }
154
134
 
155
- try {
156
- return await this.getParent().transaction(callback);
157
- } catch (error) {
158
- this.log('error', '事务执行失败', error);
159
- // 返回null作为默认值,保持返回值类型一致
160
- return null;
161
- }
135
+ return await this.getParent().transaction(callback);
162
136
  };
163
137
 
164
138
  /**
@@ -168,26 +142,21 @@ DB.prototype.transaction = async function (callback) {
168
142
  * @returns {Promise|Array} 表名数组
169
143
  */
170
144
  DB.prototype.tables = async function (table, timeout = 15000) {
171
- try {
172
- const list = await this.run('show tables', [], timeout);
173
- const key = 'Tables_in_' + this.database();
174
- if (table) {
175
- // 简单的过滤实现
176
- const filtered = [];
177
- for (const item of list) {
178
- const value = item[key];
179
- if (value && value.includes(table)) {
180
- filtered.push(item);
181
- }
145
+ const list = await this.run('show tables', [], timeout);
146
+ const key = 'Tables_in_' + this.database();
147
+ if (table) {
148
+ // 简单的过滤实现
149
+ const filtered = [];
150
+ for (const item of list) {
151
+ const value = item[key];
152
+ if (value && value.includes(table)) {
153
+ filtered.push(item);
182
154
  }
183
- return filtered.map(item => item[key]);
184
155
  }
185
- // 使用原生方法提取表名
186
- return list.map(item => item[key]);
187
- } catch (err) {
188
- this.log('error', '获取表名失败', err);
189
- return [];
156
+ return filtered.map(item => item[key]);
190
157
  }
158
+ // 使用原生方法提取表名
159
+ return list.map(item => item[key]);
191
160
  };
192
161
 
193
162
  /**
@@ -198,28 +167,23 @@ DB.prototype.tables = async function (table, timeout = 15000) {
198
167
  * @returns {Promise|Array} 字段信息列表
199
168
  */
200
169
  DB.prototype.fields = async function (table, field_name, timeout = 15000) {
201
- try {
202
- const targetTable = table || this.table;
203
- if (!targetTable) {
204
- throw new TypeError('table must be specified');
205
- }
206
- const field = 'COLUMN_NAME as `name`,ORDINAL_POSITION as `cid`,COLUMN_DEFAULT as `default_value`,IS_NULLABLE as `not_null`,COLUMN_TYPE as `type`,COLUMN_KEY as `pk`,EXTRA as `auto`,COLUMN_COMMENT as `note`';
207
- let sql = 'select ' + field + " from information_schema.COLUMNS where `table_name` = '" + targetTable +
208
- "' and `table_schema` = '" + this.database() + "'";
209
- if (field_name) {
210
- sql += " AND COLUMN_NAME='" + field_name + "'";
211
- }
212
- const list = await this.run(sql, [], timeout);
213
- const len = list.length;
214
- for (let i = 0; i < len; i++) {
215
- list[i].pk = !!list[i].pk;
216
- list[i].not_null = list[i].not_null === 'NO';
217
- }
218
- return list;
219
- } catch (err) {
220
- this.log('error', '获取字段信息失败', err);
221
- return [];
170
+ const targetTable = table || this.table;
171
+ if (!targetTable) {
172
+ throw new TypeError('table must be specified');
173
+ }
174
+ const field = 'COLUMN_NAME as `name`,ORDINAL_POSITION as `cid`,COLUMN_DEFAULT as `default_value`,IS_NULLABLE as `not_null`,COLUMN_TYPE as `type`,COLUMN_KEY as `pk`,EXTRA as `auto`,COLUMN_COMMENT as `note`';
175
+ let sql = 'select ' + field + " from information_schema.COLUMNS where `table_name` = '" + targetTable +
176
+ "' and `table_schema` = '" + this.database() + "'";
177
+ if (field_name) {
178
+ sql += " AND COLUMN_NAME='" + field_name + "'";
222
179
  }
180
+ const list = await this.run(sql, [], timeout);
181
+ const len = list.length;
182
+ for (let i = 0; i < len; i++) {
183
+ list[i].pk = !!list[i].pk;
184
+ list[i].not_null = list[i].not_null === 'NO';
185
+ }
186
+ return list;
223
187
  };
224
188
 
225
189
  /**
@@ -233,36 +197,31 @@ DB.prototype.fields = async function (table, field_name, timeout = 15000) {
233
197
  * @returns {Promise | number} 创建成功返回1,失败返回0
234
198
  */
235
199
  DB.prototype.addTable = async function (table, field, type = 'int', auto = true, commit = '', timeout = 15000) {
236
- try {
237
- if (!table || typeof table !== 'string') {
238
- throw new TypeError('table must be a valid string');
239
- }
240
- if (!field) {
241
- field = 'id';
242
- }
243
- // 构建完整的字段定义
244
- let fieldDef = `\`${field}\` ${type}(11)`;
245
- fieldDef += ' NOT NULL';
246
- if (auto) {
247
- fieldDef += ' AUTO_INCREMENT';
248
- }
249
- if (commit) {
250
- fieldDef += " COMMENT '" + commit + "'";
251
- }
252
- fieldDef += ' PRIMARY KEY';
200
+ if (!table || typeof table !== 'string') {
201
+ throw new TypeError('table must be a valid string');
202
+ }
203
+ if (!field) {
204
+ field = 'id';
205
+ }
206
+ // 构建完整的字段定义
207
+ let fieldDef = `\`${field}\` ${type}(11)`;
208
+ fieldDef += ' NOT NULL';
209
+ if (auto) {
210
+ fieldDef += ' AUTO_INCREMENT';
211
+ }
212
+ if (commit) {
213
+ fieldDef += " COMMENT '" + commit + "'";
214
+ }
215
+ fieldDef += ' PRIMARY KEY';
253
216
 
254
- let sql = 'CREATE TABLE IF NOT EXISTS \`' + table + '\` (' + fieldDef + ')';
255
- sql += ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;';
217
+ let sql = 'CREATE TABLE IF NOT EXISTS \`' + table + '\` (' + fieldDef + ')';
218
+ sql += ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;';
256
219
 
257
- // 执行SQL并设置表名
258
- const result = await this.exec(sql, [], timeout);
259
- // 设置实例的表名属性,以便后续操作使用
260
- this.table = table;
261
- return result;
262
- } catch (err) {
263
- this.log('error', '创建表失败', err);
264
- return 0;
265
- }
220
+ // 执行SQL并设置表名
221
+ const result = await this.exec(sql, [], timeout);
222
+ // 设置实例的表名属性,以便后续操作使用
223
+ this.table = table;
224
+ return result;
266
225
  };
267
226
 
268
227
  /**
@@ -304,47 +263,42 @@ DB.prototype.renameTable = function (table, new_table, timeout = 15000) {
304
263
  * @returns {Promise | number} 添加成功返回1,失败返回0
305
264
  */
306
265
  DB.prototype.addField = async function (field, type, value = '', not_null = true, auto = false, comment = '', timeout = 15000) {
307
- try {
308
- // 确保表名已设置
309
- if (!this.table || !field || !type) {
310
- throw new TypeError('table, field, and type must be specified');
311
- }
312
-
313
- // 构建字段定义
314
- let fieldDef = `\`${field}\` ${type}`;
266
+ // 确保表名已设置
267
+ if (!this.table || !field || !type) {
268
+ throw new TypeError('table, field, and type must be specified');
269
+ }
315
270
 
316
- // 添加非空约束
317
- if (not_null) {
318
- fieldDef += ' NOT NULL';
319
- }
271
+ // 构建字段定义
272
+ let fieldDef = `\`${field}\` ${type}`;
320
273
 
321
- // 添加自增属性
322
- if (auto) {
323
- fieldDef += ' AUTO_INCREMENT';
324
- }
274
+ // 添加非空约束
275
+ if (not_null) {
276
+ fieldDef += ' NOT NULL';
277
+ }
325
278
 
326
- // 添加默认值
327
- if (value !== undefined && value !== null && value !== '') {
328
- if (typeof value === 'string') {
329
- fieldDef += " DEFAULT '" + value + "'";
330
- } else {
331
- fieldDef += ' DEFAULT ' + value;
332
- }
333
- }
279
+ // 添加自增属性
280
+ if (auto) {
281
+ fieldDef += ' AUTO_INCREMENT';
282
+ }
334
283
 
335
- // 添加注释
336
- if (comment) {
337
- fieldDef += " COMMENT '" + comment + "'";
284
+ // 添加默认值
285
+ if (value !== undefined && value !== null && value !== '') {
286
+ if (typeof value === 'string') {
287
+ fieldDef += " DEFAULT '" + value + "'";
288
+ } else {
289
+ fieldDef += ' DEFAULT ' + value;
338
290
  }
291
+ }
339
292
 
340
- // 使用ADD COLUMN而不是CHANGE COLUMN
341
- const sql = `ALTER TABLE \`${this.table}\` ADD COLUMN ${fieldDef};`;
342
- const result = await this.exec(sql, [], timeout);
343
- return result;
344
- } catch (err) {
345
- this.log('error', '添加字段失败', err);
346
- return 0;
293
+ // 添加注释
294
+ if (comment) {
295
+ fieldDef += " COMMENT '" + comment + "'";
347
296
  }
297
+
298
+ // 使用ADD COLUMN而不是CHANGE COLUMN
299
+ const sql = `ALTER TABLE \`${this.table}\` ADD COLUMN ${fieldDef};`;
300
+ const result = await this.exec(sql, [], timeout);
301
+ return result;
348
302
  };
349
303
 
350
304
  /**
@@ -360,36 +314,31 @@ DB.prototype.addField = async function (field, type, value = '', not_null = true
360
314
  * @returns {Promise | number} 修改成功返回1,失败返回0
361
315
  */
362
316
  DB.prototype.setField = async function (field, type, value = '', not_null = true, auto = false, isKey = false, new_name = '', timeout = 15000) {
363
- try {
364
- if (!field || !type || !this.table) {
365
- throw new TypeError('field, type, and table must be specified');
366
- }
367
- const targetName = new_name || field;
368
- let fieldDef = `\`${targetName}\` ${type}`;
369
- if (not_null) {
370
- fieldDef += ' NOT NULL';
371
- }
372
- if (auto) {
373
- fieldDef += ' AUTO_INCREMENT';
374
- }
375
- if (value !== undefined && value !== null && value !== '') {
376
- if (typeof value === 'string') {
377
- fieldDef += " DEFAULT '" + value + "'";
378
- } else {
379
- fieldDef += ' DEFAULT ' + value;
380
- }
381
- }
382
- let sql = `ALTER TABLE \`${this.table}\` CHANGE COLUMN \`${field}\` ${fieldDef}`;
383
- if (isKey) {
384
- sql += ', ADD PRIMARY KEY (\`' + targetName + '\`)';
317
+ if (!field || !type || !this.table) {
318
+ throw new TypeError('field, type, and table must be specified');
319
+ }
320
+ const targetName = new_name || field;
321
+ let fieldDef = `\`${targetName}\` ${type}`;
322
+ if (not_null) {
323
+ fieldDef += ' NOT NULL';
324
+ }
325
+ if (auto) {
326
+ fieldDef += ' AUTO_INCREMENT';
327
+ }
328
+ if (value !== undefined && value !== null && value !== '') {
329
+ if (typeof value === 'string') {
330
+ fieldDef += " DEFAULT '" + value + "'";
331
+ } else {
332
+ fieldDef += ' DEFAULT ' + value;
385
333
  }
386
- sql += ';';
387
- const result = await this.exec(sql, [], timeout);
388
- return result;
389
- } catch (err) {
390
- this.log('error', '修改字段失败', err);
391
- return 0;
392
334
  }
335
+ let sql = `ALTER TABLE \`${this.table}\` CHANGE COLUMN \`${field}\` ${fieldDef}`;
336
+ if (isKey) {
337
+ sql += ', ADD PRIMARY KEY (\`' + targetName + '\`)';
338
+ }
339
+ sql += ';';
340
+ const result = await this.exec(sql, [], timeout);
341
+ return result;
393
342
  };
394
343
 
395
344
  /**
@@ -447,16 +396,11 @@ DB.prototype.getCreateTable = async function (table, timeout = 15000) {
447
396
  if (!table) {
448
397
  throw new TypeError('table must be specified');
449
398
  }
450
- try {
451
- const list = await this.run('SHOW CREATE TABLE \`' + table + '\`;', [], timeout);
452
- if (list && list.length > 0) {
453
- return list[0]['Create Table'] || list[0]['create table'];
454
- }
455
- return '';
456
- } catch (err) {
457
- this.log('error', '获取表结构失败', err);
458
- return '';
399
+ const list = await this.run('SHOW CREATE TABLE \`' + table + '\`;', [], timeout);
400
+ if (list && list.length > 0) {
401
+ return list[0]['Create Table'] || list[0]['create table'];
459
402
  }
403
+ return '';
460
404
  };
461
405
 
462
406
  /**
@@ -470,51 +414,46 @@ DB.prototype.getTableData = async function (table, batchSize = 100, timeout = 60
470
414
  if (!table) {
471
415
  throw new TypeError('table must be specified');
472
416
  }
473
- try {
474
- // 获取表数据
475
- const rows = await this.run(`SELECT * FROM \`${table}\``, [], timeout);
476
- let sql = '';
477
-
478
- if (rows && rows.length > 0) {
479
- sql += `-- 表数据: ${table}\n`;
480
-
481
- // 批量处理大数据量
482
- for (let j = 0; j < rows.length; j += batchSize) {
483
- const batch = rows.slice(j, j + batchSize);
484
- for (const row of batch) {
485
- try {
486
- const rowValues = Object.values(row)
487
- .map(value => {
488
- if (value === null) return 'NULL';
489
- if (typeof value === 'boolean') return value ? 1 : 0;
490
- if (typeof value === 'number') return value;
491
- if (value instanceof Date) {
492
- return "'" + value.toISOString().slice(0, 19).replace('T', ' ') + "'";
493
- }
494
- // 处理字符串,转义特殊字符
495
- if (typeof value === 'string') {
496
- return "'" + value
497
- .replace(/[\\']/g, '\\$&')
498
- .replace(/\n/g, '\\n')
499
- .replace(/\r/g, '\\r')
500
- .replace(/\t/g, '\\t')
501
- .replace(/\u0000/g, '\\0') + "'";
502
- }
503
- return "'" + String(value || '') + "'";
504
- }).join(',');
505
- sql += `INSERT INTO \`${table}\` VALUES (${rowValues});\n`;
506
- } catch (rowErr) {
507
- this.log('error', '处理行数据失败', rowErr);
508
- }
417
+ // 获取表数据
418
+ const rows = await this.run(`SELECT * FROM \`${table}\``, [], timeout);
419
+ let sql = '';
420
+
421
+ if (rows && rows.length > 0) {
422
+ sql += `-- 表数据: ${table}\n`;
423
+
424
+ // 批量处理大数据量
425
+ for (let j = 0; j < rows.length; j += batchSize) {
426
+ const batch = rows.slice(j, j + batchSize);
427
+ for (const row of batch) {
428
+ try {
429
+ const rowValues = Object.values(row)
430
+ .map(value => {
431
+ if (value === null) return 'NULL';
432
+ if (typeof value === 'boolean') return value ? 1 : 0;
433
+ if (typeof value === 'number') return value;
434
+ if (value instanceof Date) {
435
+ return "'" + value.toISOString().slice(0, 19).replace('T', ' ') + "'";
436
+ }
437
+ // 处理字符串,转义特殊字符
438
+ if (typeof value === 'string') {
439
+ return "'" + value
440
+ .replace(/[\\']/g, '\\$&')
441
+ .replace(/\n/g, '\\n')
442
+ .replace(/\r/g, '\\r')
443
+ .replace(/\t/g, '\\t')
444
+ .replace(/\u0000/g, '\\0') + "'";
445
+ }
446
+ return "'" + String(value || '') + "'";
447
+ }).join(',');
448
+ sql += `INSERT INTO \`${table}\` VALUES (${rowValues});\n`;
449
+ } catch (rowErr) {
450
+ this.log('error', '处理行数据失败', rowErr);
509
451
  }
510
452
  }
511
- sql += '\n';
512
453
  }
513
- return sql;
514
- } catch (err) {
515
- this.log('error', '获取表数据失败', err);
516
- return '';
454
+ sql += '\n';
517
455
  }
456
+ return sql;
518
457
  };
519
458
 
520
459
  /**
@@ -540,13 +479,8 @@ DB.prototype.hasTable = async function (table, timeout = 15000) {
540
479
  if (!table || typeof table !== 'string') {
541
480
  return false;
542
481
  }
543
- try {
544
- const list = await this.run("SHOW TABLES LIKE '" + table + "'", [], timeout);
545
- return list && list.length > 0;
546
- } catch (err) {
547
- this.log('error', '检查表是否存在失败', err);
548
- return false;
549
- }
482
+ const list = await this.run("SHOW TABLES LIKE '" + table + "'", [], timeout);
483
+ return list && list.length > 0;
550
484
  };
551
485
 
552
486
  /**
@@ -560,13 +494,8 @@ DB.prototype.hasField = async function (table, field, timeout = 15000) {
560
494
  if (!table || !field) {
561
495
  return false;
562
496
  }
563
- try {
564
- const list = await this.fields(table, field, timeout);
565
- return list && list.length > 0;
566
- } catch (err) {
567
- this.log('error', '检查字段是否存在失败', err);
568
- return false;
569
- }
497
+ const list = await this.fields(table, field, timeout);
498
+ return list && list.length > 0;
570
499
  };
571
500
 
572
501
  /**
package/index.js CHANGED
@@ -153,23 +153,6 @@ Mysql.prototype.close = async function () {
153
153
  }
154
154
  };
155
155
 
156
- /**
157
- * 安全释放数据库连接
158
- * @param {object} conn - 数据库连接对象
159
- * @returns {Promise<void>}
160
- */
161
- async function releaseConn(conn) {
162
- if (!conn) return;
163
-
164
- try {
165
- if (typeof conn.release === 'function') {
166
- await conn.release();
167
- }
168
- } catch (release_err) {
169
- $.log.error('释放连接失败', release_err);
170
- }
171
- };
172
-
173
156
  /**
174
157
  * 获取数据库连接(统一使用连接池)
175
158
  * @returns {Promise<object>}
@@ -181,13 +164,8 @@ Mysql.prototype.getConn = async function () {
181
164
  await this.open();
182
165
  }
183
166
 
184
- try {
185
- // 统一从连接池获取连接
186
- return await this._pool.getConnection();
187
- } catch (error) {
188
- this.log('error', '从连接池获取连接失败', error);
189
- throw error; // 重新抛出错误,让调用方处理
190
- }
167
+ // 统一从连接池获取连接
168
+ return await this._pool.getConnection();
191
169
  };
192
170
 
193
171
  /**
@@ -503,6 +481,23 @@ function mysqlAdmin(scope, config) {
503
481
  return $.pool.mysql[scope];
504
482
  }
505
483
 
484
+ /**
485
+ * 安全释放数据库连接
486
+ * @param {object} conn - 数据库连接对象
487
+ * @returns {Promise<void>}
488
+ */
489
+ async function releaseConn(conn) {
490
+ if (!conn) return;
491
+
492
+ try {
493
+ if (typeof conn.release === 'function') {
494
+ await conn.release();
495
+ }
496
+ } catch (release_err) {
497
+ $.log.error('释放连接失败', release_err);
498
+ }
499
+ };
500
+
506
501
  /**
507
502
  * @module 导出Mysql管理器
508
503
  */
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "mm_mysql",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "description": "这是超级美眉mysql帮助函数模块,用于便捷操作mysql,使用await方式,可以避免嵌套函数",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
- "mm_expand": "^2.2.9",
7
+ "mm_expand": "^2.3.1",
8
8
  "mysql2": "^3.22.3",
9
9
  "sqlstring": "^2.3.3"
10
10
  },