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/sql.js CHANGED
@@ -605,15 +605,9 @@ Sql.prototype.add = async function (body) {
605
605
  if (!this.table || !body || typeof body !== 'object') {
606
606
  throw new Error('表名或数据未设置');
607
607
  }
608
- try {
609
- const sql = this.toAddSql(body);
610
- this.sql = sql;
611
- return await this.exec(sql);
612
- } catch (err) {
613
- this.error = err.message;
614
- this.log('error', '添加数据失败', err);
615
- }
616
- return 0;
608
+ const sql = this.toAddSql(body);
609
+ this.sql = sql;
610
+ return await this.exec(sql);
617
611
  };
618
612
 
619
613
  /**
@@ -626,16 +620,10 @@ Sql.prototype.del = async function (query, like) {
626
620
  if (!this.table) {
627
621
  throw new Error('表名未设置');
628
622
  }
629
- try {
630
- const sql = this.toDelSql(query, like);
631
- this.sql = sql;
632
- const bl = await this.exec(sql);
633
- return bl;
634
- } catch (err) {
635
- this.error = err.message;
636
- this.log('error', '删除数据失败', err);
637
- }
638
- return 0;
623
+ const sql = this.toDelSql(query, like);
624
+ this.sql = sql;
625
+ const bl = await this.exec(sql);
626
+ return bl;
639
627
  };
640
628
 
641
629
  /**
@@ -649,16 +637,10 @@ Sql.prototype.set = async function (query, body, like) {
649
637
  if (!this.table || !body || typeof body !== 'object') {
650
638
  throw new Error('表名或数据未设置');
651
639
  }
652
- try {
653
- const sql = this.toSetSql(query, body, like);
654
- this.sql = sql;
655
- const bl = await this.exec(sql);
656
- return bl;
657
- } catch (err) {
658
- this.error = err.message;
659
- this.log('error', '修改数据失败', err);
660
- }
661
- return 0;
640
+ const sql = this.toSetSql(query, body, like);
641
+ this.sql = sql;
642
+ const bl = await this.exec(sql);
643
+ return bl;
662
644
  };
663
645
 
664
646
  /**
@@ -672,20 +654,14 @@ Sql.prototype.addOrSetSql = async function (where, set, like) {
672
654
  if (!this.table || !where || !set) {
673
655
  throw new Error('表名、条件或数据未设置');
674
656
  }
675
- try {
676
- const where_str = await this._getWhereStr(where, like);
677
- const count = await this.countSql(where_str);
657
+ const where_str = await this._getWhereStr(where, like);
658
+ const count = await this.countSql(where_str);
678
659
 
679
- if (count === 0) {
680
- return await this._addData(set);
681
- } else {
682
- return await this._updateData(where_str, set);
683
- }
684
- } catch (err) {
685
- this.error = err.message;
686
- this.log('error', '添加或修改数据失败', err);
660
+ if (count === 0) {
661
+ return await this._addData(set);
662
+ } else {
663
+ return await this._updateData(where_str, set);
687
664
  }
688
- return 0;
689
665
  };
690
666
 
691
667
  Sql.prototype._getWhereStr = async function (where, like) {
@@ -749,16 +725,10 @@ Sql.prototype.get = async function (query, sort, view, like, timeout = 20000) {
749
725
  throw new Error('表名未设置');
750
726
  }
751
727
 
752
- try {
753
- const sql = this.toGetSql(query, sort, view, like);
754
- this.sql = sql;
755
- const list = await this.run(sql);
756
- return list;
757
- } catch (err) {
758
- this.error = err.message;
759
- this.log('error', '查询数据失败', err);
760
- }
761
- return [];
728
+ const sql = this.toGetSql(query, sort, view, like);
729
+ this.sql = sql;
730
+ const list = await this.run(sql);
731
+ return list;
762
732
  };
763
733
 
764
734
  /**
@@ -771,36 +741,30 @@ Sql.prototype.get = async function (query, sort, view, like, timeout = 20000) {
771
741
  * @returns {Promise | object | null} 查询结果
772
742
  */
773
743
  Sql.prototype.getObj = async function (query, sort, view, like, timeout = 20000) {
774
- try {
775
- // 保存当前分页设置
776
- const old_page = this.page;
777
- const old_size = this.size;
778
-
779
- // 设置为只查询一条
780
- this.page = 1;
781
- this.size = 1;
782
-
783
- // 使用优化后的get方法
784
- const list = await this.get(query, sort, view, like, timeout);
785
-
786
- // 恢复分页设置
787
- this.page = old_page;
788
- this.size = old_size;
789
-
790
- var obj = null;
791
- if (list.length > 0) {
792
- obj = list[0];
793
- if (this.key) {
794
- obj = this.model(obj);
795
- }
744
+ // 保存当前分页设置
745
+ const old_page = this.page;
746
+ const old_size = this.size;
747
+
748
+ // 设置为只查询一条
749
+ this.page = 1;
750
+ this.size = 1;
751
+
752
+ // 使用优化后的get方法
753
+ const list = await this.get(query, sort, view, like, timeout);
754
+
755
+ // 恢复分页设置
756
+ this.page = old_page;
757
+ this.size = old_size;
758
+
759
+ var obj = null;
760
+ if (list.length > 0) {
761
+ obj = list[0];
762
+ if (this.key) {
763
+ obj = this.model(obj);
796
764
  }
797
-
798
- return obj;
799
- } catch (err) {
800
- this.error = err.message;
801
- this.log('error', '查询单条数据失败', err);
802
765
  }
803
- return null;
766
+
767
+ return obj;
804
768
  };
805
769
 
806
770
  /**
@@ -814,19 +778,12 @@ Sql.prototype.count = async function (query, like, timeout = 20000) {
814
778
  if (!this.table) {
815
779
  throw new Error('表名未设置');
816
780
  }
817
-
818
- try {
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;
825
- } catch (err) {
826
- this.error = err.message;
827
- this.log('error', '统计数据失败', err);
828
- }
829
- return 0;
781
+ const where = typeof query === 'string' ? query : await this.toWhere(query, like);
782
+ const sql = 'SELECT COUNT(*) as num FROM `' + this.table + '`' + (where ? ' WHERE ' + where : '');
783
+ this.sql = sql;
784
+ const list = await this.run(sql);
785
+ const total = list && list[0] && list[0].num ? parseInt(list[0].num) : 0;
786
+ return total;
830
787
  };
831
788
 
832
789
  /**
@@ -853,36 +810,31 @@ Sql.prototype.addList = async function (list, batch_size = 100, timeout = 60000)
853
810
  if (!this.table || !Array.isArray(list) || list.length === 0) {
854
811
  throw new Error('表名或数据列表未设置');
855
812
  }
856
- try {
857
- // 如果数据量较小,
858
- if (list.length <= batch_size) {
859
- // 使用批量插入语法,不使用事务包装
860
- this.sql = this.toBatchAddSql(list);
861
- return await this.exec(this.sql, [], timeout);
862
- }
863
-
864
- // 分批处理大数据量
865
- const batches = Math.ceil(list.length / batch_size);
866
- this.log('info', `开始分批添加数据,共${batches}批,每批${batch_size}条`);
813
+ // 如果数据量较小,
814
+ if (list.length <= batch_size) {
815
+ // 使用批量插入语法,不使用事务包装
816
+ this.sql = this.toBatchAddSql(list);
817
+ return await this.exec(this.sql, [], timeout);
818
+ }
867
819
 
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}条`);
820
+ // 分批处理大数据量
821
+ const batches = Math.ceil(list.length / batch_size);
822
+ this.log('info', `开始分批添加数据,共${batches}批,每批${batch_size}条`);
873
823
 
874
- // 生成批量插入SQL
875
- const batch_sql = this.toBatchAddSql(batch);
876
- this.sql = batch_sql;
877
- final_res = await this.exec(batch_sql);
878
- }
824
+ // 分批执行,每批一个单独的批量插入语句
825
+ let final_res = null;
826
+ for (let i = 0; i < batches; i++) {
827
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
828
+ this.log('debug', `处理第${i + 1}/${batches}批数据,${batch.length}条`);
879
829
 
880
- this.log('info', `批量添加数据完成,共${list.length}条`);
881
- return final_res;
882
- } catch (error) {
883
- this.log('error', '批量添加数据失败', error);
830
+ // 生成批量插入SQL
831
+ const batch_sql = this.toBatchAddSql(batch);
832
+ this.sql = batch_sql;
833
+ final_res = await this.exec(batch_sql);
884
834
  }
885
- return 0;
835
+
836
+ this.log('info', `批量添加数据完成,共${list.length}条`);
837
+ return final_res;
886
838
  };
887
839
 
888
840
  /**
@@ -941,59 +893,49 @@ Sql.prototype.delList = async function (list, like, batch_size = 100, timeout =
941
893
  if (!this.table || !Array.isArray(list) || list.length === 0) {
942
894
  throw new Error('表名或数据列表未设置');
943
895
  }
944
- try {
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);
896
+ // 如果数据量较小,直接处理
897
+ if (list.length <= batch_size) {
898
+ let sql = '';
899
+ for (const item of list) {
900
+ sql += this.toDelSql(item.query, like);
953
901
  }
902
+ this.sql = sql;
903
+ return await this.exec(sql);
904
+ }
954
905
 
955
- // 分批处理大数据量
956
- const batches = Math.ceil(list.length / batch_size);
957
- this.log('info', `开始分批删除数据,共${batches}批,每批${batch_size}条`);
958
-
959
- // 使用事务包装整个操作以保证原子性
960
- let final_res = null;
961
- try {
962
- // 开始事务
963
- await this.exec('BEGIN;');
906
+ // 分批处理大数据量
907
+ const batches = Math.ceil(list.length / batch_size);
908
+ this.log('info', `开始分批删除数据,共${batches}批,每批${batch_size}条`);
964
909
 
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}条`);
910
+ // 使用事务包装整个操作以保证原子性
911
+ let final_res = null;
912
+ try {
913
+ // 开始事务
914
+ await this.exec('BEGIN;');
969
915
 
970
- let batch_sql = '';
971
- for (const item of batch) {
972
- batch_sql += this.toDelSql(item.query, like);
973
- }
974
- final_res = await this.exec(batch_sql);
975
- }
916
+ // 分批处理exec删除语句
917
+ for (let i = 0; i < batches; i++) {
918
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
919
+ this.log('debug', `处理第${i + 1}/${batches}批数据,${batch.length}条`);
976
920
 
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);
921
+ let batch_sql = '';
922
+ for (const item of batch) {
923
+ batch_sql += this.toDelSql(item.query, like);
986
924
  }
987
- throw error; // 重新抛出错误
925
+ final_res = await this.exec(batch_sql);
988
926
  }
989
927
 
990
- this.log('info', `批量删除数据完成,共${list.length}条`);
991
- return final_res;
992
- } catch (err) {
993
- this.error = err.message;
994
- this.log('error', '批量删除数据失败', err);
928
+ // 提交事务
929
+ await this.exec('COMMIT;');
930
+ } catch (error) {
931
+ // 发生错误时回滚事务
932
+ await this.exec('ROLLBACK;', [], timeout);
933
+ this.log('error', '批量删除数据失败,事务已回滚', error);
934
+ throw error; // 重新抛出错误
995
935
  }
996
- return 0;
936
+
937
+ this.log('info', `批量删除数据完成,共${list.length}条`);
938
+ return final_res;
997
939
  };
998
940
 
999
941
  /**
@@ -1008,49 +950,38 @@ Sql.prototype.setList = async function (list, like = false, batch_size = 100, ti
1008
950
  if (!this.table || !Array.isArray(list) || list.length === 0) {
1009
951
  throw new Error('表名或数据列表未设置');
1010
952
  }
1011
- try {
1012
- // 分批处理大数据量
1013
- const batches = Math.ceil(list.length / batch_size);
1014
- this.log('info', `开始分批修改数据,共${batches}批,每批${batch_size}条`);
1015
-
1016
- let final_res = null;
953
+ // 分批处理大数据量
954
+ const batches = Math.ceil(list.length / batch_size);
955
+ this.log('info', `开始分批修改数据,共${batches}批,每批${batch_size}条`);
1017
956
 
1018
- // 使用事务包装整个操作以保证原子性
1019
- try {
1020
- // 开始事务
1021
- await this.exec('BEGIN;');
957
+ let final_res = null;
1022
958
 
1023
- // 逐条处理记录,保持简单可靠
1024
- for (let i = 0; i < list.length; i++) {
1025
- const item = list[i];
1026
- this.log('debug', `处理第${i + 1}/${list.length}条记录`);
959
+ // 使用事务包装整个操作以保证原子性
960
+ try {
961
+ // 开始事务
962
+ await this.exec('BEGIN;');
1027
963
 
1028
- // 生成单个更新SQL
1029
- const sql = this.toSetSql(item.query, item.item, like);
1030
- this.sql = sql;
964
+ // 逐条处理记录,保持简单可靠
965
+ for (let i = 0; i < list.length; i++) {
966
+ const item = list[i];
967
+ this.log('debug', `处理第${i + 1}/${list.length}条记录`);
1031
968
 
1032
- final_res = await this.exec(sql, [], timeout);
1033
- }
969
+ // 生成单个更新SQL
970
+ const sql = this.toSetSql(item.query, item.item, like);
971
+ this.sql = sql;
1034
972
 
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; // 重新抛出错误
973
+ final_res = await this.exec(sql, [], timeout);
1046
974
  }
1047
975
 
1048
- return final_res;
976
+ // 提交事务
977
+ await this.exec('COMMIT;');
1049
978
  } catch (error) {
1050
- this.error = error.message;
1051
- this.log('error', '批量修改数据失败', error);
979
+ await this.exec('ROLLBACK;', [], timeout);
980
+ this.log('error', '批量修改数据失败,事务已回滚', error);
981
+ throw error; // 重新抛出错误
1052
982
  }
1053
- return 0;
983
+
984
+ return final_res;
1054
985
  };
1055
986
 
1056
987
  /* 辅助类 */
@@ -1272,15 +1203,11 @@ Sql.prototype.tplBody = function (param_dt, sql_dt) {
1272
1203
  * @returns {Promise<boolean>} 是否加载成功
1273
1204
  */
1274
1205
  Sql.prototype.load = async function (file) {
1275
- try {
1276
- await this._logLoadStart(file);
1277
- await this._validateFile(file);
1278
- const sql_stmts = await this._readAndSplitSql(file);
1279
- return await this._execSqlStmts(file, sql_stmts);
1280
- } catch (error) {
1281
- this.log('error', '数据库加载失败', error);
1282
- }
1283
- return false;
1206
+
1207
+ await this._logLoadStart(file);
1208
+ await this._validateFile(file);
1209
+ const sql_stmts = await this._readAndSplitSql(file);
1210
+ return await this._execSqlStmts(file, sql_stmts);
1284
1211
  };
1285
1212
 
1286
1213
  /**
@@ -1565,20 +1492,14 @@ Sql.prototype.addOrSet = async function (where, set, like) {
1565
1492
  if (!this.table || !where || !set) {
1566
1493
  throw new Error('表名、条件或数据未设置');
1567
1494
  }
1568
- try {
1569
- const where_str = await this._getWhereStr(where, like);
1570
- const count = await this.countSql(where_str);
1495
+ const where_str = await this._getWhereStr(where, like);
1496
+ const count = await this.countSql(where_str);
1571
1497
 
1572
- if (count === 0) {
1573
- return await this._addData(set);
1574
- } else {
1575
- return await this._updateData(where_str, set);
1576
- }
1577
- } catch (err) {
1578
- this.error = err.message;
1579
- this.log('error', '添加或修改数据失败', err);
1498
+ if (count === 0) {
1499
+ return await this._addData(set);
1500
+ } else {
1501
+ return await this._updateData(where_str, set);
1580
1502
  }
1581
- return 0;
1582
1503
  };
1583
1504
 
1584
1505
  /**
@@ -1587,25 +1508,20 @@ Sql.prototype.addOrSet = async function (where, set, like) {
1587
1508
  * @private
1588
1509
  */
1589
1510
  Sql.prototype._getCreateTableSql = async function () {
1590
- try {
1591
- // 查询表结构信息(MySQL 使用 SHOW CREATE TABLE
1592
- const sql = `SHOW CREATE TABLE \`${this.table}\``;
1593
- const result = await this.run(sql);
1594
-
1595
- if (result && result.length > 0 && result[0]['Create Table']) {
1596
- // 在创建表语句中添加 IF NOT EXISTS 条件
1597
- let create_sql = result[0]['Create Table'];
1598
- if (create_sql.toUpperCase().startsWith('CREATE TABLE')) {
1599
- create_sql = create_sql.replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS');
1600
- }
1601
- return create_sql + ';';
1511
+ // 查询表结构信息(MySQL 使用 SHOW CREATE TABLE)
1512
+ const sql = `SHOW CREATE TABLE \`${this.table}\``;
1513
+ const result = await this.run(sql);
1514
+
1515
+ if (result && result.length > 0 && result[0]['Create Table']) {
1516
+ // 在创建表语句中添加 IF NOT EXISTS 条件
1517
+ let create_sql = result[0]['Create Table'];
1518
+ if (create_sql.toUpperCase().startsWith('CREATE TABLE')) {
1519
+ create_sql = create_sql.replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS');
1602
1520
  }
1603
-
1604
- return '';
1605
- } catch (err) {
1606
- this.log('warn', '获取表结构失败,将仅备份数据', err);
1607
- return '';
1521
+ return create_sql + ';';
1608
1522
  }
1523
+
1524
+ return '';
1609
1525
  };
1610
1526
 
1611
1527
  /**
@@ -1614,27 +1530,26 @@ Sql.prototype._getCreateTableSql = async function () {
1614
1530
  * @private
1615
1531
  */
1616
1532
  Sql.prototype._getTableComments = async function () {
1617
- try {
1618
- let commentSql = '';
1533
+ let commentSql = '';
1619
1534
 
1620
- // 获取表注释
1621
- const tableCommentSql = `
1535
+ // 获取表注释
1536
+ const tableCommentSql = `
1622
1537
  SELECT TABLE_COMMENT
1623
1538
  FROM information_schema.TABLES
1624
1539
  WHERE TABLE_SCHEMA = DATABASE()
1625
1540
  AND TABLE_NAME = '${this.table}'
1626
1541
  `;
1627
- const tableCommentResult = await this.run(tableCommentSql);
1542
+ const tableCommentResult = await this.run(tableCommentSql);
1628
1543
 
1629
- if (tableCommentResult && tableCommentResult.length > 0 && tableCommentResult[0].TABLE_COMMENT) {
1630
- const tableComment = tableCommentResult[0].TABLE_COMMENT;
1631
- if (tableComment && tableComment.trim() !== '') {
1632
- commentSql += `\n-- 表注释: ${tableComment}\n`;
1633
- }
1544
+ if (tableCommentResult && tableCommentResult.length > 0 && tableCommentResult[0].TABLE_COMMENT) {
1545
+ const tableComment = tableCommentResult[0].TABLE_COMMENT;
1546
+ if (tableComment && tableComment.trim() !== '') {
1547
+ commentSql += `\n-- 表注释: ${tableComment}\n`;
1634
1548
  }
1549
+ }
1635
1550
 
1636
- // 获取列注释
1637
- const columnCommentSql = `
1551
+ // 获取列注释
1552
+ const columnCommentSql = `
1638
1553
  SELECT COLUMN_NAME, COLUMN_COMMENT
1639
1554
  FROM information_schema.COLUMNS
1640
1555
  WHERE TABLE_SCHEMA = DATABASE()
@@ -1643,20 +1558,16 @@ Sql.prototype._getTableComments = async function () {
1643
1558
  AND COLUMN_COMMENT != ''
1644
1559
  ORDER BY ORDINAL_POSITION
1645
1560
  `;
1646
- const columnCommentResult = await this.run(columnCommentSql);
1561
+ const columnCommentResult = await this.run(columnCommentSql);
1647
1562
 
1648
- if (columnCommentResult && columnCommentResult.length > 0) {
1649
- commentSql += '\n-- 列注释:\n';
1650
- for (const column of columnCommentResult) {
1651
- commentSql += `-- ${column.COLUMN_NAME}: ${column.COLUMN_COMMENT}\n`;
1652
- }
1563
+ if (columnCommentResult && columnCommentResult.length > 0) {
1564
+ commentSql += '\n-- 列注释:\n';
1565
+ for (const column of columnCommentResult) {
1566
+ commentSql += `-- ${column.COLUMN_NAME}: ${column.COLUMN_COMMENT}\n`;
1653
1567
  }
1654
-
1655
- return commentSql;
1656
- } catch (err) {
1657
- this.log('warn', '获取表注释信息失败,将仅备份表结构', err);
1658
- return '';
1659
1568
  }
1569
+
1570
+ return commentSql;
1660
1571
  };
1661
1572
 
1662
1573
  /**
@@ -1674,60 +1585,54 @@ Sql.prototype.backup = async function (file, create = false) {
1674
1585
  throw new TypeError('表名未设置');
1675
1586
  }
1676
1587
 
1677
- try {
1678
- // 获取所有数据
1679
- const data = await this.getSql('', '', '*');
1588
+ // 获取所有数据
1589
+ const data = await this.getSql('', '', '*');
1680
1590
 
1681
- if (!data || !Array.isArray(data)) {
1682
- throw new Error('获取数据失败');
1683
- }
1591
+ if (!data || !Array.isArray(data)) {
1592
+ throw new Error('获取数据失败');
1593
+ }
1684
1594
 
1685
- // 构建 SQL 语句
1686
- let sqlContent = '';
1595
+ // 构建 SQL 语句
1596
+ let sqlContent = '';
1687
1597
 
1688
- // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
1689
- sqlContent += `-- 备份表: ${this.table}\n`;
1690
- sqlContent += `-- 备份时间: ${new Date().toISOString()}\n\n`;
1598
+ // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
1599
+ sqlContent += `-- 备份表: ${this.table}\n`;
1600
+ sqlContent += `-- 备份时间: ${new Date().toISOString()}\n\n`;
1691
1601
 
1692
- // 如果create为true,添加创建表语句
1693
- if (create) {
1694
- const createTableSql = await this._getCreateTableSql();
1695
- if (createTableSql) {
1696
- sqlContent += createTableSql + '\n\n';
1602
+ // 如果create为true,添加创建表语句
1603
+ if (create) {
1604
+ const createTableSql = await this._getCreateTableSql();
1605
+ if (createTableSql) {
1606
+ sqlContent += createTableSql + '\n\n';
1697
1607
 
1698
- // 添加表注释信息
1699
- const commentSql = await this._getTableComments();
1700
- if (commentSql) {
1701
- sqlContent += commentSql + '\n';
1702
- }
1608
+ // 添加表注释信息
1609
+ const commentSql = await this._getTableComments();
1610
+ if (commentSql) {
1611
+ sqlContent += commentSql + '\n';
1703
1612
  }
1704
1613
  }
1614
+ }
1705
1615
 
1706
- // 添加数据插入语句
1707
- for (const row of data) {
1708
- const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
1709
- const values = Object.values(row).map(value => this.escape(value)).join(', ');
1710
- sqlContent += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
1711
- }
1616
+ // 添加数据插入语句
1617
+ for (const row of data) {
1618
+ const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
1619
+ const values = Object.values(row).map(value => this.escape(value)).join(', ');
1620
+ sqlContent += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
1621
+ }
1712
1622
 
1713
- // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
1714
- const fs = require('fs');
1715
- const path = require('path');
1623
+ // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
1624
+ const fs = require('fs');
1625
+ const path = require('path');
1716
1626
 
1717
- // 确保目录存在
1718
- const dir = path.dirname(file);
1719
- if (!fs.existsSync(dir)) {
1720
- fs.mkdirSync(dir, { recursive: true });
1721
- }
1627
+ // 确保目录存在
1628
+ const dir = path.dirname(file);
1629
+ if (!fs.existsSync(dir)) {
1630
+ fs.mkdirSync(dir, { recursive: true });
1631
+ }
1722
1632
 
1723
- fs.writeFileSync(file, sql_content, 'utf8');
1633
+ fs.writeFileSync(file, sql_content, 'utf8');
1724
1634
 
1725
- return true;
1726
- } catch (err) {
1727
- this.error = err.message;
1728
- this.log('error', '备份数据库失败', err);
1729
- return false;
1730
- }
1635
+ return true;
1731
1636
  };
1732
1637
 
1733
1638
  /**
@@ -1744,32 +1649,26 @@ Sql.prototype.restore = async function (file) {
1744
1649
  throw new TypeError('表名未设置');
1745
1650
  }
1746
1651
 
1747
- try {
1748
- const fs = require('fs');
1652
+ const fs = require('fs');
1749
1653
 
1750
- if (!fs.existsSync(file)) {
1751
- throw new Error('备份文件不存在');
1752
- }
1654
+ if (!fs.existsSync(file)) {
1655
+ throw new Error('备份文件不存在');
1656
+ }
1753
1657
 
1754
- // 读取 SQL 文件
1755
- const sqlContent = fs.readFileSync(file, 'utf8');
1658
+ // 读取 SQL 文件
1659
+ const sqlContent = fs.readFileSync(file, 'utf8');
1756
1660
 
1757
- // 解析 SQL 语句
1758
- const statements = this._parseSqlStatements(sqlContent);
1661
+ // 解析 SQL 语句
1662
+ const statements = this._parseSqlStatements(sqlContent);
1759
1663
 
1760
- // 执行每个 SQL 语句
1761
- for (const stmt of statements) {
1762
- if (stmt.trim() && !stmt.startsWith('--')) {
1763
- await this.exec(stmt);
1764
- }
1664
+ // 执行每个 SQL 语句
1665
+ for (const stmt of statements) {
1666
+ if (stmt.trim() && !stmt.startsWith('--')) {
1667
+ await this.exec(stmt);
1765
1668
  }
1766
-
1767
- return true;
1768
- } catch (err) {
1769
- this.error = err.message;
1770
- this.log('error', '恢复数据库失败', err);
1771
- return false;
1772
1669
  }
1670
+
1671
+ return true;
1773
1672
  };
1774
1673
 
1775
1674
  /**
@@ -1865,54 +1764,48 @@ Sql.prototype.backup = async function (file, create = false) {
1865
1764
  throw new TypeError('表名未设置');
1866
1765
  }
1867
1766
 
1868
- try {
1869
- // 获取所有数据
1870
- const data = await this.getSql('', '', '*');
1767
+ // 获取所有数据
1768
+ const data = await this.getSql('', '', '*');
1871
1769
 
1872
- if (!data || !Array.isArray(data)) {
1873
- throw new Error('获取数据失败');
1874
- }
1770
+ if (!data || !Array.isArray(data)) {
1771
+ throw new Error('获取数据失败');
1772
+ }
1875
1773
 
1876
- // 构建 SQL 语句
1877
- let sql_content = '';
1774
+ // 构建 SQL 语句
1775
+ let sql_content = '';
1878
1776
 
1879
- // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
1880
- sql_content += `-- 备份表: ${this.table}\n`;
1881
- sql_content += `-- 备份时间: ${new Date().toISOString()}\n\n`;
1777
+ // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
1778
+ sql_content += `-- 备份表: ${this.table}\n`;
1779
+ sql_content += `-- 备份时间: ${new Date().toISOString()}\n\n`;
1882
1780
 
1883
- // 如果create为true,添加创建表语句
1884
- if (create) {
1885
- const create_table_sql = await this._getCreateTableSql();
1886
- if (create_table_sql) {
1887
- sql_content += create_table_sql + '\n\n';
1888
- }
1781
+ // 如果create为true,添加创建表语句
1782
+ if (create) {
1783
+ const create_table_sql = await this._getCreateTableSql();
1784
+ if (create_table_sql) {
1785
+ sql_content += create_table_sql + '\n\n';
1889
1786
  }
1787
+ }
1890
1788
 
1891
- // 添加数据插入语句
1892
- for (const row of data) {
1893
- const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
1894
- const values = Object.values(row).map(value => this.escape(value)).join(', ');
1895
- sql_content += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
1896
- }
1789
+ // 添加数据插入语句
1790
+ for (const row of data) {
1791
+ const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
1792
+ const values = Object.values(row).map(value => this.escape(value)).join(', ');
1793
+ sql_content += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
1794
+ }
1897
1795
 
1898
- // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
1899
- const fs = require('fs');
1900
- const path = require('path');
1796
+ // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
1797
+ const fs = require('fs');
1798
+ const path = require('path');
1901
1799
 
1902
- // 确保目录存在
1903
- const dir = path.dirname(file);
1904
- if (!fs.existsSync(dir)) {
1905
- fs.mkdirSync(dir, { recursive: true });
1906
- }
1800
+ // 确保目录存在
1801
+ const dir = path.dirname(file);
1802
+ if (!fs.existsSync(dir)) {
1803
+ fs.mkdirSync(dir, { recursive: true });
1804
+ }
1907
1805
 
1908
- fs.writeFileSync(file, sql_content, 'utf8');
1806
+ fs.writeFileSync(file, sql_content, 'utf8');
1909
1807
 
1910
- return true;
1911
- } catch (err) {
1912
- this.error = err.message;
1913
- this.log('error', '备份数据库失败', err);
1914
- return false;
1915
- }
1808
+ return true;
1916
1809
  };
1917
1810
 
1918
1811
  /**
@@ -1929,65 +1822,59 @@ Sql.prototype.restore = async function (file) {
1929
1822
  throw new TypeError('表名未设置');
1930
1823
  }
1931
1824
 
1932
- try {
1933
- const fs = require('fs');
1934
-
1935
- // 检查文件是否存在
1936
- if (!fs.existsSync(file)) {
1937
- throw new Error('备份文件不存在');
1938
- }
1825
+ const fs = require('fs');
1939
1826
 
1940
- // 读取文件内容
1941
- const sql_content = fs.readFileSync(file, 'utf8');
1827
+ // 检查文件是否存在
1828
+ if (!fs.existsSync(file)) {
1829
+ throw new Error('备份文件不存在');
1830
+ }
1942
1831
 
1943
- if (!sql_content) {
1944
- throw new Error('备份文件为空');
1945
- }
1832
+ // 读取文件内容
1833
+ const sql_content = fs.readFileSync(file, 'utf8');
1946
1834
 
1947
- // 解析 SQL 语句
1948
- const sql_stmts = this._parseSqlStatements(sql_content);
1835
+ if (!sql_content) {
1836
+ throw new Error('备份文件为空');
1837
+ }
1949
1838
 
1950
- if (!sql_stmts || sql_stmts.length === 0) {
1951
- throw new Error('未找到有效的 SQL 语句');
1952
- }
1839
+ // 解析 SQL 语句
1840
+ const sql_stmts = this._parseSqlStatements(sql_content);
1953
1841
 
1954
- // 开始事务
1955
- await this.exec('START TRANSACTION');
1956
-
1957
- try {
1958
- // 逐个执行SQL语句
1959
- for (const sql of sql_stmts) {
1960
- const trim_sql = sql.trim();
1961
- if (trim_sql) {
1962
- await this.exec(trim_sql);
1963
- }
1964
- }
1842
+ if (!sql_stmts || sql_stmts.length === 0) {
1843
+ throw new Error('未找到有效的 SQL 语句');
1844
+ }
1965
1845
 
1966
- // 提交事务
1967
- await this.exec('COMMIT');
1846
+ // 开始事务
1847
+ await this.exec('START TRANSACTION');
1968
1848
 
1969
- if (this.config && this.config.debug) {
1970
- this.log('info', '数据库恢复成功', {
1971
- file: file,
1972
- stmt_num: sql_stmts.length
1973
- });
1849
+ try {
1850
+ // 逐个执行SQL语句
1851
+ for (const sql of sql_stmts) {
1852
+ const trim_sql = sql.trim();
1853
+ if (trim_sql) {
1854
+ await this.exec(trim_sql);
1974
1855
  }
1856
+ }
1975
1857
 
1976
- return true;
1977
- } catch (err) {
1978
- // 回滚事务
1979
- await this.exec('ROLLBACK').catch(rollback_err => {
1980
- this.log('error', '事务回滚失败', rollback_err);
1981
- });
1858
+ // 提交事务
1859
+ await this.exec('COMMIT');
1982
1860
 
1983
- // 记录错误日志
1984
- this.log('error', 'SQL语句执行失败', err);
1985
- throw err;
1861
+ if (this.config && this.config.debug) {
1862
+ this.log('info', '数据库恢复成功', {
1863
+ file: file,
1864
+ stmt_num: sql_stmts.length
1865
+ });
1986
1866
  }
1867
+
1868
+ return true;
1987
1869
  } catch (err) {
1988
- this.error = err.message;
1989
- this.log('error', '数据库恢复失败', err);
1990
- return false;
1870
+ // 回滚事务
1871
+ await this.exec('ROLLBACK').catch(rollback_err => {
1872
+ this.log('error', '事务回滚失败', rollback_err);
1873
+ });
1874
+
1875
+ // 记录错误日志
1876
+ this.log('error', 'SQL语句执行失败', err);
1877
+ throw err;
1991
1878
  }
1992
1879
  };
1993
1880
 
@@ -1997,25 +1884,20 @@ Sql.prototype.restore = async function (file) {
1997
1884
  * @private
1998
1885
  */
1999
1886
  Sql.prototype._getCreateTableSql = async function () {
2000
- try {
2001
- // 查询表结构信息(MySQL 使用 SHOW CREATE TABLE
2002
- const sql = `SHOW CREATE TABLE \`${this.table}\``;
2003
- const result = await this.run(sql);
2004
-
2005
- if (result && result.length > 0 && result[0]['Create Table']) {
2006
- // 在创建表语句中添加 IF NOT EXISTS 条件
2007
- let create_sql = result[0]['Create Table'];
2008
- if (create_sql.toUpperCase().startsWith('CREATE TABLE')) {
2009
- create_sql = create_sql.replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS');
2010
- }
2011
- return create_sql + ';';
1887
+ // 查询表结构信息(MySQL 使用 SHOW CREATE TABLE)
1888
+ const sql = `SHOW CREATE TABLE \`${this.table}\``;
1889
+ const result = await this.run(sql);
1890
+
1891
+ if (result && result.length > 0 && result[0]['Create Table']) {
1892
+ // 在创建表语句中添加 IF NOT EXISTS 条件
1893
+ let create_sql = result[0]['Create Table'];
1894
+ if (create_sql.toUpperCase().startsWith('CREATE TABLE')) {
1895
+ create_sql = create_sql.replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS');
2012
1896
  }
2013
-
2014
- return '';
2015
- } catch (err) {
2016
- this.log('warn', '获取表结构失败,将仅备份数据', err);
2017
- return '';
1897
+ return create_sql + ';';
2018
1898
  }
1899
+
1900
+ return '';
2019
1901
  };
2020
1902
 
2021
1903
  module.exports = {