mm_mysql 2.3.4 → 2.3.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 (3) hide show
  1. package/db.js +14 -16
  2. package/package.json +1 -1
  3. package/sql.js +115 -166
package/db.js CHANGED
@@ -17,8 +17,6 @@ class DB extends Sql {
17
17
  mysql.run,
18
18
  mysql.exec
19
19
  );
20
- // 保存mysql实例引用
21
- this._mysql = mysql;
22
20
  // 事务中
23
21
  this.task = 0;
24
22
 
@@ -82,7 +80,7 @@ DB.prototype.new = function (table, key) {
82
80
  */
83
81
  DB.prototype.getConn = async function() {
84
82
  try {
85
- return await this._mysql.getConn();
83
+ return await this.parent().getConn();
86
84
  } catch (error) {
87
85
  this.log('error', '获取连接失败', error);
88
86
  // 返回null作为默认值,保持返回值类型一致
@@ -96,7 +94,7 @@ DB.prototype.getConn = async function() {
96
94
  */
97
95
  DB.prototype.start = async function() {
98
96
  try {
99
- return await this._mysql.beginTransaction();
97
+ return await this.parent().beginTransaction();
100
98
  } catch (error) {
101
99
  this.log('error', '开始事务失败', error);
102
100
  // 返回null作为默认值,保持返回值类型一致
@@ -155,7 +153,7 @@ DB.prototype.transaction = async function(callback) {
155
153
  }
156
154
 
157
155
  try {
158
- return await this._mysql.transaction(callback);
156
+ return await this.parent().transaction(callback);
159
157
  } catch (error) {
160
158
  this.log('error', '事务执行失败', error);
161
159
  // 返回null作为默认值,保持返回值类型一致
@@ -257,7 +255,7 @@ DB.prototype.addTable = async function (table, field, type = 'int', auto = true,
257
255
  sql += ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;';
258
256
 
259
257
  // 执行SQL并设置表名
260
- const result = await this.exec(sql, timeout);
258
+ const result = await this.exec(sql, [], timeout);
261
259
  // 设置实例的表名属性,以便后续操作使用
262
260
  this.table = table;
263
261
  return result;
@@ -277,7 +275,7 @@ DB.prototype.dropTable = function (table, timeout = 15000) {
277
275
  if (!table || typeof table !== 'string') {
278
276
  throw new TypeError('table must be a valid string');
279
277
  }
280
- return this.exec('DROP TABLE IF EXISTS \`' + table + '\`;', timeout);
278
+ return this.exec('DROP TABLE IF EXISTS \`' + table + '\`;', [], timeout);
281
279
  };
282
280
 
283
281
  /**
@@ -291,7 +289,7 @@ DB.prototype.renameTable = function (table, new_table, timeout = 15000) {
291
289
  if (!table || !new_table) {
292
290
  throw new TypeError('table and new_table must be specified');
293
291
  }
294
- return this.exec('RENAME TABLE \`' + table + '\` TO \`' + new_table + '\`;', timeout);
292
+ return this.exec('RENAME TABLE \`' + table + '\` TO \`' + new_table + '\`;', [], timeout);
295
293
  };
296
294
 
297
295
  /**
@@ -341,7 +339,7 @@ DB.prototype.addField = async function (field, type, value = '', not_null = true
341
339
 
342
340
  // 使用ADD COLUMN而不是CHANGE COLUMN
343
341
  const sql = `ALTER TABLE \`${this.table}\` ADD COLUMN ${fieldDef};`;
344
- const result = await this.exec(sql, timeout);
342
+ const result = await this.exec(sql, [], timeout);
345
343
  return result;
346
344
  } catch (err) {
347
345
  this.log('error', '添加字段失败', err);
@@ -386,7 +384,7 @@ DB.prototype.setField = async function (field, type, value = '', not_null = true
386
384
  sql += ', ADD PRIMARY KEY (\`' + targetName + '\`)';
387
385
  }
388
386
  sql += ';';
389
- const result = await this.exec(sql, timeout);
387
+ const result = await this.exec(sql, [], timeout);
390
388
  return result;
391
389
  } catch (err) {
392
390
  this.log('error', '修改字段失败', err);
@@ -406,7 +404,7 @@ DB.prototype.editField = function (table, field, type, timeout = 15000) {
406
404
  if (!table || !field || !type) {
407
405
  throw new TypeError('table, field, and type must be specified');
408
406
  }
409
- return this.exec('ALTER TABLE \`' + table + '\` MODIFY COLUMN \`' + field + '\` ' + type + ';', timeout);
407
+ return this.exec('ALTER TABLE \`' + table + '\` MODIFY COLUMN \`' + field + '\` ' + type + ';', [], timeout);
410
408
  };
411
409
 
412
410
  /**
@@ -420,7 +418,7 @@ DB.prototype.delField = function (table, field, timeout = 15000) {
420
418
  if (!table || !field) {
421
419
  throw new TypeError('table and field must be specified');
422
420
  }
423
- return this.exec('ALTER TABLE \`' + table + '\` DROP COLUMN \`' + field + '\`;', timeout);
421
+ return this.exec('ALTER TABLE \`' + table + '\` DROP COLUMN \`' + field + '\`;', [], timeout);
424
422
  };
425
423
 
426
424
  /**
@@ -436,7 +434,7 @@ DB.prototype.renameField = function (table, field, new_field, type, timeout = 15
436
434
  if (!table || !field || !new_field) {
437
435
  throw new TypeError('table, field, and new_field must be specified');
438
436
  }
439
- return this.exec('ALTER TABLE \`' + table + '\` CHANGE \`' + field + '\` \`' + new_field + '\` ' + type + ';', timeout);
437
+ return this.exec('ALTER TABLE \`' + table + '\` CHANGE \`' + field + '\` \`' + new_field + '\` ' + type + ';', [], timeout);
440
438
  };
441
439
 
442
440
  /**
@@ -529,7 +527,7 @@ DB.prototype.emptyTable = function (table, timeout = 15000) {
529
527
  if (!table || typeof table !== 'string') {
530
528
  throw new TypeError('table must be a valid string');
531
529
  }
532
- return this.exec('TRUNCATE TABLE \`' + table + '\`;', timeout);
530
+ return this.exec('TRUNCATE TABLE \`' + table + '\`;', [], timeout);
533
531
  };
534
532
 
535
533
  /**
@@ -582,7 +580,7 @@ DB.prototype.backupTable = function (table, backup, timeout = 60000) {
582
580
  if (!table || !backup) {
583
581
  throw new TypeError('table and backup must be specified');
584
582
  }
585
- return this.exec('CREATE TABLE \`' + backup + '\` LIKE \`' + table + '\`; INSERT INTO \`' + backup + '\` SELECT * FROM \`' + table + '\`;', timeout);
583
+ return this.exec('CREATE TABLE \`' + backup + '\` LIKE \`' + table + '\`; INSERT INTO \`' + backup + '\` SELECT * FROM \`' + table + '\`;', [], timeout);
586
584
  };
587
585
 
588
586
 
@@ -591,7 +589,7 @@ DB.prototype.backupTable = function (table, backup, timeout = 60000) {
591
589
  * @param {string} table 表名
592
590
  * @param {object} model 表模型,键值对,根据值类型创建字段类型,根据键名创建字段名
593
591
  * @param {string} key 主键
594
- * @param timeout
592
+ * @param {number} timeout 超时时间(毫秒)
595
593
  * @returns {Promise | number} 操作结果
596
594
  */
597
595
  DB.prototype.createTable = function (table, model, key = 'id', timeout = 15000) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_mysql",
3
- "version": "2.3.4",
3
+ "version": "2.3.6",
4
4
  "description": "这是超级美眉mysql帮助函数模块,用于便捷操作mysql,使用await方式,可以避免嵌套函数",
5
5
  "main": "index.js",
6
6
  "dependencies": {
package/sql.js CHANGED
@@ -750,19 +750,10 @@ Sql.prototype.get = async function (query, sort, view, like, timeout = 20000) {
750
750
  }
751
751
 
752
752
  try {
753
- // 使用Promise.race实现超时控制
754
- return await Promise.race([
755
- (async () => {
756
- // 生成SQL并执行
757
- const sql = this.toGetSql(query, sort, view, like);
758
- this.sql = sql;
759
- const list = await this.run(sql);
760
- return list;
761
- })(),
762
- new Promise((resolve, reject) => {
763
- setTimeout(() => reject(new Error('查询操作超时')), timeout);
764
- })
765
- ]);
753
+ const sql = this.toGetSql(query, sort, view, like);
754
+ this.sql = sql;
755
+ const list = await this.run(sql);
756
+ return list;
766
757
  } catch (err) {
767
758
  this.error = err.message;
768
759
  this.log('error', '查询数据失败', err);
@@ -825,23 +816,12 @@ Sql.prototype.count = async function (query, like, timeout = 20000) {
825
816
  }
826
817
 
827
818
  try {
828
- // 添加超时控制
829
- const timeout_promise = new Promise((_, reject) => {
830
- setTimeout(() => reject(new Error('统计操作超时')), timeout);
831
- });
832
-
833
- return await Promise.race([
834
- (async () => {
835
- // 正确生成count SQL
836
- const where = typeof query === 'string' ? query : await this.toWhere(query, like);
837
- const sql = 'SELECT COUNT(*) as num FROM `' + this.table + '`' + (where ? ' WHERE ' + where : '');
838
- this.sql = sql;
839
- const list = await this.run(sql);
840
- const total = list && list[0] && list[0].num ? parseInt(list[0].num) : 0;
841
- return total;
842
- })(),
843
- timeout_promise
844
- ]);
819
+ const where = typeof query === 'string' ? query : await this.toWhere(query, like);
820
+ const sql = 'SELECT COUNT(*) as num FROM `' + this.table + '`' + (where ? ' WHERE ' + where : '');
821
+ this.sql = sql;
822
+ const list = await this.run(sql);
823
+ const total = list && list[0] && list[0].num ? parseInt(list[0].num) : 0;
824
+ return total;
845
825
  } catch (err) {
846
826
  this.error = err.message;
847
827
  this.log('error', '统计数据失败', err);
@@ -865,57 +845,40 @@ Sql.prototype.getCount = async function (query, like, timeout = 30000) {
865
845
  * 添加多条数据
866
846
  * @param {Array} list 对象数组
867
847
  * @param {boolean} lock 是否锁定
868
- * @param {number} batchSize 每批处理数量,默认100
848
+ * @param {number} batch_size 每批处理数量,默认100
869
849
  * @param {number} timeout 超时时间(毫秒),默认60000
870
850
  * @returns {Promise<object>} 执行结果
871
851
  */
872
- Sql.prototype.addList = async function (list, batchSize = 100, timeout = 60000) {
852
+ Sql.prototype.addList = async function (list, batch_size = 100, timeout = 60000) {
873
853
  if (!this.table || !Array.isArray(list) || list.length === 0) {
874
854
  throw new Error('表名或数据列表未设置');
875
855
  }
876
856
  try {
877
- // 添加整体操作超时控制
878
- const timeout_promise = new Promise((resolve, reject) => {
879
- setTimeout(() => reject(new Error('批量添加数据操作超时')), timeout);
880
- });
857
+ // 如果数据量较小,
858
+ if (list.length <= batch_size) {
859
+ // 使用批量插入语法,不使用事务包装
860
+ this.sql = this.toBatchAddSql(list);
861
+ return await this.exec(this.sql, [], timeout);
862
+ }
881
863
 
882
- return await Promise.race([
883
- (async () => {
884
- // 如果数据量较小,直接处理
885
- if (list.length <= batchSize) {
886
- // 使用批量插入语法,不使用事务包装
887
- this.sql = this.toBatchAddSql(list);
888
- return await this.exec(this.sql);
889
- }
864
+ // 分批处理大数据量
865
+ const batches = Math.ceil(list.length / batch_size);
866
+ this.log('info', `开始分批添加数据,共${batches}批,每批${batch_size}条`);
890
867
 
891
- // 分批处理大数据量
892
- const batches = Math.ceil(list.length / batchSize);
893
- this.log('info', `开始分批添加数据,共${batches}批,每批${batchSize}条`);
894
-
895
- // 分批执行,每批一个单独的批量插入语句
896
- let final_res = null;
897
- for (let i = 0; i < batches; i++) {
898
- const batch = list.slice(i * batchSize, (i + 1) * batchSize);
899
- this.log('debug', `处理第${i + 1}/${batches}批数据,${batch.length}条`);
900
-
901
- // 生成批量插入SQL
902
- const batch_sql = this.toBatchAddSql(batch);
903
- this.sql = batch_sql;
904
-
905
- // 为每批操作添加超时控制
906
- final_res = await Promise.race([
907
- this.exec(batch_sql),
908
- new Promise((_, reject) => {
909
- setTimeout(() => reject(new Error(`第${i + 1}批数据处理超时`)), timeout / batches);
910
- })
911
- ]);
912
- }
868
+ // 分批执行,每批一个单独的批量插入语句
869
+ let final_res = null;
870
+ for (let i = 0; i < batches; i++) {
871
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
872
+ this.log('debug', `处理第${i + 1}/${batches}批数据,${batch.length}条`);
913
873
 
914
- this.log('info', `批量添加数据完成,共${list.length}条`);
915
- return final_res;
916
- })(),
917
- timeout_promise
918
- ]);
874
+ // 生成批量插入SQL
875
+ const batch_sql = this.toBatchAddSql(batch);
876
+ this.sql = batch_sql;
877
+ final_res = await this.exec(batch_sql);
878
+ }
879
+
880
+ this.log('info', `批量添加数据完成,共${list.length}条`);
881
+ return final_res;
919
882
  } catch (error) {
920
883
  this.log('error', '批量添加数据失败', error);
921
884
  }
@@ -970,78 +933,62 @@ Sql.prototype._buildValueList = function (list, keys) {
970
933
  * 删除多条数据
971
934
  * @param {Array} list 对象数组
972
935
  * @param {boolean} like 是否使用like匹配, 为空使用默认方式
973
- * @param {number} batchSize 每批处理数量,默认100
936
+ * @param {number} batch_size 每批处理数量,默认100
974
937
  * @param {number} timeout 超时时间(毫秒),默认60000
975
938
  * @returns {Promise<object>} 执行结果
976
939
  */
977
- Sql.prototype.delList = async function (list, like, batchSize = 100, timeout = 60000) {
940
+ Sql.prototype.delList = async function (list, like, batch_size = 100, timeout = 60000) {
978
941
  if (!this.table || !Array.isArray(list) || list.length === 0) {
979
942
  throw new Error('表名或数据列表未设置');
980
943
  }
981
944
  try {
982
- // 添加整体操作超时控制
983
- const timeout_promise = new Promise((resolve, reject) => {
984
- setTimeout(() => reject(new Error('批量删除数据操作超时')), timeout);
985
- });
945
+ // 如果数据量较小,直接处理
946
+ if (list.length <= batch_size) {
947
+ let sql = '';
948
+ for (const item of list) {
949
+ sql += this.toDelSql(item.query, like);
950
+ }
951
+ this.sql = sql;
952
+ return await this.exec(sql);
953
+ }
986
954
 
987
- return await Promise.race([
988
- (async () => {
989
- // 如果数据量较小,直接处理
990
- if (list.length <= batchSize) {
991
- let sql = '';
992
- for (const item of list) {
993
- sql += this.toDelSql(item.query, like);
994
- }
995
- this.sql = sql;
996
- return await this.exec(sql);
997
- }
955
+ // 分批处理大数据量
956
+ const batches = Math.ceil(list.length / batch_size);
957
+ this.log('info', `开始分批删除数据,共${batches}批,每批${batch_size}条`);
998
958
 
999
- // 分批处理大数据量
1000
- const batches = Math.ceil(list.length / batchSize);
1001
- this.log('info', `开始分批删除数据,共${batches}批,每批${batchSize}条`);
1002
-
1003
- // 使用事务包装整个操作以保证原子性
1004
- let final_res = null;
1005
- try {
1006
- // 开始事务
1007
- await this.exec('BEGIN;', 15000);
1008
-
1009
- // 分批处理
1010
- for (let i = 0; i < batches; i++) {
1011
- const batch = list.slice(i * batchSize, (i + 1) * batchSize);
1012
- this.log('debug', `处理第${i + 1}/${batches}批数据,${batch.length}条`);
1013
-
1014
- let batch_sql = '';
1015
- for (const item of batch) {
1016
- batch_sql += this.toDelSql(item.query, like);
1017
- }
1018
-
1019
- // 为每批操作添加超时控制
1020
- final_res = await Promise.race([
1021
- this.exec(batch_sql),
1022
- new Promise((_, reject) => {
1023
- setTimeout(() => reject(new Error(`第${i + 1}批数据删除超时`)), timeout / batches);
1024
- })
1025
- ]);
1026
- }
959
+ // 使用事务包装整个操作以保证原子性
960
+ let final_res = null;
961
+ try {
962
+ // 开始事务
963
+ await this.exec('BEGIN;');
1027
964
 
1028
- // 提交事务
1029
- await this.exec('COMMIT;', 15000);
1030
- } catch (error) {
1031
- // 发生错误时回滚事务
1032
- try {
1033
- await this.exec('ROLLBACK;', 15000);
1034
- this.log('error', '批量删除数据失败,事务已回滚', error);
1035
- } catch (rollbackError) {
1036
- this.log('error', '批量删除数据失败,事务回滚也失败', rollbackError);
1037
- }
965
+ // 分批处理exec删除语句
966
+ for (let i = 0; i < batches; i++) {
967
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
968
+ this.log('debug', `处理第${i + 1}/${batches}批数据,${batch.length}条`);
969
+
970
+ let batch_sql = '';
971
+ for (const item of batch) {
972
+ batch_sql += this.toDelSql(item.query, like);
1038
973
  }
974
+ final_res = await this.exec(batch_sql);
975
+ }
976
+
977
+ // 提交事务
978
+ await this.exec('COMMIT;');
979
+ } catch (error) {
980
+ // 发生错误时回滚事务
981
+ try {
982
+ await this.exec('ROLLBACK;', [], timeout);
983
+ this.log('error', '批量删除数据失败,事务已回滚', error);
984
+ } catch (rollbackError) {
985
+ this.log('error', '批量删除数据失败,事务回滚也失败', rollbackError);
986
+ }
987
+ throw error; // 重新抛出错误
988
+ }
1039
989
 
1040
- this.log('info', `批量删除数据完成,共${list.length}条`);
1041
- return final_res;
1042
- })(),
1043
- timeoutPromise
1044
- ]);
990
+ this.log('info', `批量删除数据完成,共${list.length}条`);
991
+ return final_res;
1045
992
  } catch (err) {
1046
993
  this.error = err.message;
1047
994
  this.log('error', '批量删除数据失败', err);
@@ -1053,50 +1000,52 @@ Sql.prototype.delList = async function (list, like, batchSize = 100, timeout = 6
1053
1000
  * 修改多条数据
1054
1001
  * @param {Array} list 对象数组
1055
1002
  * @param {boolean} like 是否使用like匹配, 为空使用默认方式
1056
- * @param {number} batchSize 每批处理数量,默认100
1003
+ * @param {number} batch_size 每批处理数量,默认100
1057
1004
  * @param {number} timeout 超时时间(毫秒),默认60000
1058
1005
  * @returns {Promise<object>} 执行结果
1059
1006
  */
1060
- Sql.prototype.setList = async function (list, like = false, batchSize = 100, timeout = 60000) {
1007
+ Sql.prototype.setList = async function (list, like = false, batch_size = 100, timeout = 60000) {
1061
1008
  if (!this.table || !Array.isArray(list) || list.length === 0) {
1062
1009
  throw new Error('表名或数据列表未设置');
1063
1010
  }
1064
1011
  try {
1065
- // 添加整体操作超时控制
1066
- const timeout_promise = new Promise((resolve, reject) => {
1067
- setTimeout(() => reject(new Error('批量修改数据操作超时')), timeout);
1068
- });
1012
+ // 分批处理大数据量
1013
+ const batches = Math.ceil(list.length / batch_size);
1014
+ this.log('info', `开始分批修改数据,共${batches}批,每批${batch_size}条`);
1069
1015
 
1070
- return await Promise.race([
1071
- (async () => {
1072
- // 分批处理大数据量
1073
- const batches = Math.ceil(list.length / batchSize);
1074
- this.log('info', `开始分批修改数据,共${batches}批,每批${batchSize}条`);
1075
-
1076
- let final_res = null;
1077
-
1078
- // 逐条处理记录,保持简单可靠
1079
- for (let i = 0; i < list.length; i++) {
1080
- const item = list[i];
1081
- this.log('debug', `处理第${i + 1}/${list.length}条记录`);
1082
-
1083
- // 生成单个更新SQL
1084
- const sql = this.toSetSql(item.query, item.item, like);
1085
- this.sql = sql;
1086
-
1087
- // 为每条操作添加超时控制
1088
- final_res = await Promise.race([
1089
- this.exec(sql),
1090
- new Promise((_, reject) => {
1091
- setTimeout(() => reject(new Error(`第${i + 1}条数据修改超时`)), 5000); // 固定超时时间
1092
- })
1093
- ]);
1094
- }
1016
+ let final_res = null;
1017
+
1018
+ // 使用事务包装整个操作以保证原子性
1019
+ try {
1020
+ // 开始事务
1021
+ await this.exec('BEGIN;');
1022
+
1023
+ // 逐条处理记录,保持简单可靠
1024
+ for (let i = 0; i < list.length; i++) {
1025
+ const item = list[i];
1026
+ this.log('debug', `处理第${i + 1}/${list.length}条记录`);
1027
+
1028
+ // 生成单个更新SQL
1029
+ const sql = this.toSetSql(item.query, item.item, like);
1030
+ this.sql = sql;
1031
+
1032
+ final_res = await this.exec(sql, [], timeout);
1033
+ }
1034
+
1035
+ // 提交事务
1036
+ await this.exec('COMMIT;');
1037
+ } catch (error) {
1038
+ // 发生错误时回滚事务
1039
+ try {
1040
+ await this.exec('ROLLBACK;', [], timeout);
1041
+ this.log('error', '批量修改数据失败,事务已回滚', error);
1042
+ } catch (rollbackError) {
1043
+ this.log('error', '批量修改数据失败,事务回滚也失败', rollbackError);
1044
+ }
1045
+ throw error; // 重新抛出错误
1046
+ }
1095
1047
 
1096
- return final_res;
1097
- })(),
1098
- timeoutPromise
1099
- ]);
1048
+ return final_res;
1100
1049
  } catch (error) {
1101
1050
  this.error = error.message;
1102
1051
  this.log('error', '批量修改数据失败', error);