mm_sqlite 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/sql.js CHANGED
@@ -149,21 +149,24 @@ class Sql {
149
149
  }
150
150
 
151
151
  /**
152
- * @description 清理存储的数据
152
+ * @description 清空查询条件
153
+ * @return {Object} 返回当前对象
153
154
  */
154
- Sql.prototype.clear = async function() {
155
- this.run = run;
156
- this.exec = exec;
155
+ Sql.prototype.clear = function() {
156
+ this.where = "";
157
+ this.set = "";
158
+ this.order = "";
159
+ this.view = "";
157
160
  this.sql = "";
158
- this.error;
159
- this.results = [];
160
- this.table = "";
161
+ this.error = "";
162
+ this.like = true;
163
+ this.config = {};
164
+ this.param = {};
161
165
  this.page = 0;
162
- this.size = 30;
163
- this.method = "";
164
- this.field = "";
165
- this.orderby = "";
166
- this.count_ret = "false";
166
+ this.size = 0;
167
+ this.run = null;
168
+ this.exec = null;
169
+ return this;
167
170
  };
168
171
 
169
172
  /**
@@ -257,7 +260,7 @@ Sql.prototype.getSql = function(where, sort, view) {
257
260
  * @param {String} set 修改的键值
258
261
  * @return {Promise|Object} 执行结果
259
262
  */
260
- Sql.prototype.addOrSetSql = async function(where, set) {
263
+ Sql.prototype.addOrSetSql = async function(where, set, like) {
261
264
  if (!where || !set) {
262
265
  return -1;
263
266
  }
@@ -333,20 +336,20 @@ Sql.prototype.groupMathSql = async function(where, groupby, view, sort, method)
333
336
  if (view.indexOf(",") !== -1) {
334
337
  var arr = view.split(",");
335
338
  for (var i = 0; i < arr.length; i++) {
336
- var str = this.escapeId(arr[i]);
339
+ var str = escapeId(arr[i]);
337
340
  viewStr += "," + method.toUpperCase() + "(" + str + ") " + method.toLowerCase() + "_" + str.replace(
338
341
  /`/g, "")
339
342
  }
340
343
  } else {
341
- viewStr = "," + method.toUpperCase() + "(" + this.escapeId(view) + ") " + method.toLowerCase() + "_" +
344
+ viewStr = "," + method.toUpperCase() + "(" + escapeId(view) + ") " + method.toLowerCase() + "_" +
342
345
  view.replace(/`/g, "")
343
346
  }
344
- var sql = "SELECT " + (groupby ? this.escapeId(groupby) : "") + viewStr + " FROM `" + this.table + "`";
347
+ var sql = "SELECT " + (groupby ? escapeId(groupby) : "") + viewStr + " FROM `" + this.table + "`";
345
348
  if (where) {
346
349
  sql += ' WHERE ' + where;
347
350
  }
348
351
  if (groupby) {
349
- sql += " GROUP BY " + this.escapeId(groupby);
352
+ sql += " GROUP BY " + escapeId(groupby);
350
353
  }
351
354
  if (sort) {
352
355
  sql += " ORDER BY " + sort;
@@ -458,34 +461,49 @@ Sql.prototype.toWhere = function(obj, like) {
458
461
  if (like) {
459
462
  for (var k in obj) {
460
463
  var val = obj[k];
464
+ if (val && typeof(val) === "string") {
465
+ val = val.trim("'");
466
+ }
467
+ val = escape(val);
461
468
  if (k.endWith('_min')) {
462
- where += " and " + this.escapeId(k.replace('_min', '')) + " >= " + this.escape(val);
469
+ where += " and " + escapeId(k.replace('_min', '')) + " >= " + val;
463
470
  } else if (k.endWith('_max')) {
464
- where += " and " + this.escapeId(k.replace('_max', '')) + " <= " + this.escape(val);
471
+ where += " and " + escapeId(k.replace('_max', '')) + " <= " + val;
465
472
  } else if (k.endWith('_not')) {
466
- where += " and " + this.escapeId(k.replace('_not', '')) + " != " + this.escape(val);
473
+ where += " and " + escapeId(k.replace('_not', '')) + " != " + val;
467
474
  } else if (k.endWith('_has')) {
468
- where += " and " + this.escapeId(k.replace('_has', '')) + " in (" + val + ")";
475
+ var vals = val.trim("'").split(',').map((o) => {
476
+ return "'" + o + "'"
477
+ });
478
+ where += " and " + escapeId(k.replace('_has', '')) + " in (" + vals.join(',') + ")";
479
+ } else if (k.endWith('_like')) {
480
+ where += " and " + escapeId(k.replace('_like', '')) + " LIKE '%" + val.trim("'") + "%'";
469
481
  } else if (typeof(val) === "string" && !/^[0-9]+$/.test(val)) {
470
- where += " and " + this.escapeId(k) + " LIKE '%" + this.escape(val).trim("'") + "%'"
482
+ where += " and " + escapeId(k) + " LIKE '%" + val.trim("'") + "%'"
471
483
  } else {
472
- where += " and " + this.escapeId(k) + " = " + val
484
+ where += " and " + escapeId(k) + " = " + val;
473
485
  }
474
486
  }
475
487
  } else {
476
488
  for (var k in obj) {
477
489
  var val = obj[k];
490
+ if (val && typeof(val) === "string") {
491
+ val = val.trim("'");
492
+ }
493
+ val = escape(val);
478
494
  if (k.endWith('_min')) {
479
- where += " and " + this.escapeId(k.replace('_min', '')) + " >= " + this.escape(val.replace('_min',
480
- ''));
495
+ where += " and " + escapeId(k.replace('_min', '')) + " >= " + val;
481
496
  } else if (k.endWith('_max')) {
482
- where += " and " + this.escapeId(k.replace('_max', '')) + " <= " + this.escape(val);
497
+ where += " and " + escapeId(k.replace('_max', '')) + " <= " + val;
483
498
  } else if (k.endWith('_not')) {
484
- where += " and " + this.escapeId(k.replace('_not', '')) + " != " + this.escape(val);
499
+ where += " and " + escapeId(k.replace('_not', '')) + " != " + val;
485
500
  } else if (k.endWith('_has')) {
486
- where += " and " + this.escapeId(k.replace('_has', '')) + " in (" + val.replace(/`/gi, "") + ")";
501
+ var vals = val.trim("'").split(',').map((o) => {
502
+ return "'" + o + "'"
503
+ });
504
+ where += " and " + escapeId(k.replace('_has', '')) + " in (" + vals.join(',') + ")";
487
505
  } else {
488
- where += " and " + this.escapeId(k) + "=" + this.escape(val);
506
+ where += " and " + escapeId(k) + " = " + val;
489
507
  }
490
508
  }
491
509
  }
@@ -500,15 +518,24 @@ Sql.prototype.toWhere = function(obj, like) {
500
518
  Sql.prototype.toSet = function(obj) {
501
519
  var set = "";
502
520
  for (var k in obj) {
503
- var val = this.escape(obj[k]);
521
+ if (!Object.prototype.hasOwnProperty.call(obj, k)) continue;
522
+
523
+ var val = obj[k];
524
+ if (val === undefined || val === null) continue;
525
+
526
+ if (typeof val === "string") {
527
+ val = val.trim("'");
528
+ }
529
+ val = escape(val);
530
+
504
531
  if (k.endWith('_add')) {
505
- var k2 = this.escapeId(k.replace('_add', ''));
532
+ var k2 = escapeId(k.replace('_add', ''));
506
533
  set += "," + k2 + " = " + k2 + " + " + val;
507
534
  } else if (k.endWith('_del')) {
508
- var k3 = this.escapeId(k.replace('_del', ''));
535
+ var k3 = escapeId(k.replace('_del', ''));
509
536
  set += "," + k3 + " = " + k3 + " - " + val;
510
537
  } else {
511
- set += "," + this.escapeId(k) + " = " + val;
538
+ set += "," + escapeId(k) + " = " + val;
512
539
  }
513
540
  }
514
541
  return set.replace(",", "");
@@ -520,11 +547,21 @@ Sql.prototype.toSet = function(obj) {
520
547
  * @return {String} sql语句
521
548
  */
522
549
  Sql.prototype.toAddSql = function(item) {
550
+ if (!this.table || !item || typeof item !== 'object') {
551
+ throw new Error('表名或数据未设置');
552
+ }
553
+
523
554
  var key = "";
524
555
  var val = "";
525
556
  for (var k in item) {
526
- key += "," + this.escapeId(k);
527
- val += "," + this.escape(item[k]);
557
+ if (!Object.prototype.hasOwnProperty.call(item, k)) continue;
558
+
559
+ key += "," + escapeId(k);
560
+ var value = item[k];
561
+ if (typeof value === "string") {
562
+ value = value.trim("'");
563
+ }
564
+ val += "," + escape(value);
528
565
  }
529
566
  var sql = "INSERT INTO `{0}` ({1}) VALUES ({2});";
530
567
  return sql.replace("{0}", this.table).replace("{1}", key.replace(",", "")).replace("{2}", val.replace(",", ""));
@@ -533,10 +570,14 @@ Sql.prototype.toAddSql = function(item) {
533
570
  /**
534
571
  * @description 转删除sql语句
535
572
  * @param {Object} query 查询键值
573
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
536
574
  * @return {String} sql语句
537
575
  */
538
- Sql.prototype.toDelSql = function(query) {
539
- var where = this.toWhere(query);
576
+ Sql.prototype.toDelSql = function(query, like) {
577
+ if (!this.table) {
578
+ throw new Error('表名未设置');
579
+ }
580
+ var where = this.toWhere(query, like);
540
581
  var sql = "DELETE FROM `{0}` WHERE {1};";
541
582
  return sql.replace("{0}", this.table).replace("{1}", where);
542
583
  };
@@ -545,10 +586,14 @@ Sql.prototype.toDelSql = function(query) {
545
586
  * @description 转修改sql语句
546
587
  * @param {Object} query 查询的键值集合
547
588
  * @param {Object} item 修改的键值集合
589
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
548
590
  * @return {String} sql语句
549
591
  */
550
- Sql.prototype.toSetSql = function(query, item) {
551
- var where = this.toWhere(query);
592
+ Sql.prototype.toSetSql = function(query, item, like) {
593
+ if (!this.table) {
594
+ throw new Error('表名未设置');
595
+ }
596
+ var where = this.toWhere(query, like);
552
597
  var set = this.toSet(item);
553
598
  var sql = "UPDATE `{0}` SET {1} WHERE {2};";
554
599
  return sql.replace("{0}", this.table).replace("{1}", set).replace("{2}", where);
@@ -559,43 +604,110 @@ Sql.prototype.toSetSql = function(query, item) {
559
604
  * @param {Object} query 查询键值集合
560
605
  * @param {String} sort 排序规则
561
606
  * @param {String} view 显示的字段
562
- * @param {Boolean} like 是否使用like匹配, 默认使用
607
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
563
608
  * @return {String} sql语句
564
609
  */
565
- Sql.prototype.toGetSql = function(query, sort, view, like = true) {
610
+ Sql.prototype.toGetSql = function(query, sort, view, like) {
566
611
  var where = this.toWhere(query, like);
567
- var sql = this.toQuery(where, sort, view);
568
- return sql;
612
+ return this.toQuery(where, sort, view);
569
613
  };
570
614
  /* === 传入对象操作 === */
571
615
  /**
572
616
  * @description 增加数据
573
- * @param {Object} item 添加的对象
617
+ * @param {Object} body 添加的对象
574
618
  * @return {Promise|Object} 执行结果
575
619
  */
576
- Sql.prototype.add = function(item) {
577
- var sql = this.toAddSql(item);
578
- return this.exec(sql);
620
+ Sql.prototype.add = async function(body) {
621
+ if (!this.table || !body || typeof body !== 'object') {
622
+ throw new Error('表名或数据未设置');
623
+ }
624
+ try {
625
+ // 触发前置事件
626
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
627
+ await $.eventer.run("sqlite_add_before:" + this.table, { body });
628
+ }
629
+
630
+ var sql = this.toAddSql(body);
631
+ this.sql = sql;
632
+ var bl = await this.exec(sql);
633
+
634
+ // 触发后置事件
635
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
636
+ await $.eventer.run("sqlite_add_after:" + this.table, { body, sql: this.sql, error: this.error, bl });
637
+ }
638
+
639
+ return bl;
640
+ } catch (err) {
641
+ this.error = err.message;
642
+ $.log.error(`添加数据失败: ${err.message}`);
643
+ throw err;
644
+ }
579
645
  };
580
646
  /**
581
647
  * @description 删除数据
582
648
  * @param {Object} query 查询条件集合
649
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
583
650
  * @return {Promise|Object} 执行结果
584
651
  */
585
- Sql.prototype.del = function(query) {
586
- var sql = this.toDelSql(query);
587
- return this.exec(sql);
652
+ Sql.prototype.del = async function(query, like) {
653
+ if (!this.table) {
654
+ throw new Error('表名未设置');
655
+ }
656
+ try {
657
+ // 触发前置事件
658
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
659
+ await $.eventer.run("sqlite_del_before:" + this.table, { query, like });
660
+ }
661
+
662
+ var sql = this.toDelSql(query, like);
663
+ this.sql = sql;
664
+ var bl = await this.exec(sql);
665
+
666
+ // 触发后置事件
667
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
668
+ await $.eventer.run("sqlite_del_after:" + this.table, { query, like, sql: this.sql, error: this.error, bl });
669
+ }
670
+
671
+ return bl;
672
+ } catch (err) {
673
+ this.error = err.message;
674
+ $.log.error(`删除数据失败: ${err.message}`);
675
+ throw err;
676
+ }
588
677
  };
589
678
 
590
679
  /**
591
680
  * @description 修改数据
592
681
  * @param {Object} query 查询条件集合
593
- * @param {Object} item 修改的键值集合
682
+ * @param {Object} body 修改的键值集合
683
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
594
684
  * @return {Promise|Object} 执行结果
595
685
  */
596
- Sql.prototype.set = function(query, item) {
597
- var sql = this.toSetSql(query, item);
598
- return this.exec(sql);
686
+ Sql.prototype.set = async function(query, body, like) {
687
+ if (!this.table || !body || typeof body !== 'object') {
688
+ throw new Error('表名或数据未设置');
689
+ }
690
+ try {
691
+ // 触发前置事件
692
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
693
+ await $.eventer.run("sqlite_set_before:" + this.table, { query, body, like, page: this.page, size: this.size });
694
+ }
695
+
696
+ var sql = this.toSetSql(query, body, like);
697
+ this.sql = sql;
698
+ var bl = await this.exec(sql);
699
+
700
+ // 触发后置事件
701
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
702
+ await $.eventer.run("sqlite_set_after:" + this.table, { query, body, like, page: this.page, size: this.size, sql: this.sql, error: this.error, bl });
703
+ }
704
+
705
+ return bl;
706
+ } catch (err) {
707
+ this.error = err.message;
708
+ $.log.error(`修改数据失败: ${err.message}`);
709
+ throw err;
710
+ }
599
711
  };
600
712
 
601
713
  /**
@@ -603,12 +715,81 @@ Sql.prototype.set = function(query, item) {
603
715
  * @param {Object} query 查询条件
604
716
  * @param {String} sort 排序
605
717
  * @param {String} view 返回的字段
606
- * @param {Boolean} like 是否使用like匹配, 默认使用
718
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
719
+ * @param {Number} timeout 超时时间(毫秒),默认30000ms
607
720
  * @return {Promise|Array} 查询结果
608
721
  */
609
- Sql.prototype.get = function(query, sort, view, like = true) {
610
- var sql = this.toGetSql(query, sort, view, like);
611
- return this.run(sql);
722
+ Sql.prototype.get = async function(query, sort, view, like, timeout = 30000) {
723
+ if (!this.table) {
724
+ throw new Error('表名未设置');
725
+ }
726
+
727
+ try {
728
+ // 添加超时控制的Promise
729
+ var timeoutPromise = new Promise((_, reject) => {
730
+ setTimeout(() => reject(new Error('查询操作超时')), timeout);
731
+ });
732
+
733
+ // 使用Promise.race实现超时控制
734
+ return await Promise.race([
735
+ (async () => {
736
+ // 安全触发事件,避免事件系统问题影响核心功能
737
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
738
+ try {
739
+ // 添加超时保护的事件触发
740
+ await Promise.race([
741
+ $.eventer.run("sqlite_get_before:" + this.table, {
742
+ query,
743
+ sort,
744
+ view,
745
+ like,
746
+ page: this.page,
747
+ size: this.size
748
+ }),
749
+ new Promise((_, reject) => setTimeout(() => reject(new Error('事件处理超时')), 5000))
750
+ ]);
751
+ } catch (eventError) {
752
+ $.log.warn(`事件处理失败,但不影响查询: ${eventError.message}`);
753
+ }
754
+ }
755
+
756
+ // 生成SQL并执行
757
+ var sql = this.toGetSql(query, sort, view, like);
758
+ this.sql = sql;
759
+ var list = await this.run(sql);
760
+
761
+ // 安全触发后置事件
762
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
763
+ try {
764
+ // 添加超时保护的事件触发
765
+ await Promise.race([
766
+ $.eventer.run("sqlite_get_after:" + this.table, {
767
+ query,
768
+ sort,
769
+ view,
770
+ like,
771
+ page: this.page,
772
+ size: this.size,
773
+ sql: this.sql,
774
+ error: this.error,
775
+ list
776
+ }),
777
+ new Promise((_, reject) => setTimeout(() => reject(new Error('事件处理超时')), 5000))
778
+ ]);
779
+ } catch (eventError) {
780
+ $.log.warn(`事件处理失败,但不影响查询返回: ${eventError.message}`);
781
+ }
782
+ }
783
+
784
+ return list;
785
+ })(),
786
+ timeoutPromise
787
+ ]);
788
+ } catch (err) {
789
+ this.error = err.message;
790
+ $.log.error(`查询数据失败: ${err.message}`);
791
+ throw err;
792
+ }
612
793
  };
613
794
 
614
795
  /**
@@ -618,30 +799,172 @@ Sql.prototype.get = function(query, sort, view, like = true) {
618
799
  * @param {Boolean} like 是否使用like匹配, 默认不使用
619
800
  * @return {Promise|Object} 执行结果
620
801
  */
802
+ /**
803
+ * 添加或修改数据(存在则修改,不存在则添加)
804
+ * @param {Object|String} where 查询条件
805
+ * @param {Object|String} set 要设置的数据
806
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
807
+ * @return {Promise<Object>} 执行结果
808
+ */
621
809
  Sql.prototype.addOrSet = async function(where, set, like) {
622
- return await this.addOrSetSql(this.toWhere(where, like), this.toSet(set));
810
+ if (!this.table || !where || !set) {
811
+ throw new Error('表名、条件或数据未设置');
812
+ }
813
+ try {
814
+ let query = where;
815
+ let body = set;
816
+ let whereStr;
817
+
818
+ if (typeof where === "object") {
819
+ whereStr = await this.toWhere(where, like);
820
+ } else {
821
+ whereStr = where;
822
+ }
823
+
824
+ const count = await this.countSql(whereStr);
825
+
826
+ if (count === 0) {
827
+ let key = "";
828
+ let value = "";
829
+
830
+ if (typeof set === "string") {
831
+ const arr = set.split(",");
832
+ for (const o of arr) {
833
+ const ar = o.split('=');
834
+ if (ar.length === 2) {
835
+ key += "," + ar[0];
836
+ value += "," + ar[1];
837
+ }
838
+ }
839
+ } else {
840
+ // 触发前置事件
841
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function' && typeof body === "object") {
842
+ await $.eventer.run("sqlite_add_before:" + this.table, { body });
843
+ }
844
+
845
+ for (const k in set) {
846
+ if (!Object.prototype.hasOwnProperty.call(set, k)) continue;
847
+
848
+ key += "," + this.escapeId(k);
849
+ let val = set[k];
850
+ if (typeof val === "string") {
851
+ val = val.trim("'");
852
+ }
853
+ value += "," + this.escape(val);
854
+ }
855
+ }
856
+
857
+ const bl = await this.addSql(key.replace(",", ""), value.replace(",", ""));
858
+
859
+ // 触发后置事件
860
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function' && typeof body === "object") {
861
+ await $.eventer.run("sqlite_add_after:" + this.table, { body, sql: this.sql, error: this.error, bl });
862
+ }
863
+
864
+ return bl;
865
+ } else {
866
+ // 触发前置事件
867
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function' && typeof set === "object") {
868
+ await $.eventer.run("sqlite_set_before:" + this.table, { query, body, like, page: this.page, size: this.size, sql: this.sql });
869
+ }
870
+
871
+ if (typeof set === "object") {
872
+ set = await this.toSet(set);
873
+ }
874
+
875
+ const bl1 = await this.setSql(whereStr, set);
876
+
877
+ // 触发后置事件
878
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function' && typeof body === "object") {
879
+ await $.eventer.run("sqlite_set_after:" + this.table, { query, body, like, page: this.page, size: this.size, sql: this.sql, error: this.error, bl: bl1 });
880
+ }
881
+
882
+ return bl1;
883
+ }
884
+ } catch (err) {
885
+ this.error = err.message;
886
+ $.log.error(`添加或修改数据失败: ${err.message}`);
887
+ throw err;
888
+ }
623
889
  };
624
890
 
625
891
  /**
626
- * @description 查询符合结果总数
627
- * @param {Object} query 查询条件集合
628
- * @param {Boolean} like 是否使用like匹配, 默认使用
629
- * @return {Promise|Number} 查询结果
892
+ * 统计记录数
893
+ * @param {Object} query 查询条件
894
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
895
+ * @param {Number} timeout 超时时间(毫秒),默认30000ms
896
+ * @return {Promise|Number} 记录数
630
897
  */
631
- Sql.prototype.count = function(query, like = true) {
632
- return this.countSql(this.toWhere(query, like));
898
+ Sql.prototype.count = async function(query, like, timeout = 30000) {
899
+ if (!this.table) {
900
+ throw new Error('表名未设置');
901
+ }
902
+
903
+ try {
904
+ // 添加超时控制
905
+ const timeoutPromise = new Promise((_, reject) => {
906
+ setTimeout(() => reject(new Error('统计操作超时')), timeout);
907
+ });
908
+
909
+ return await Promise.race([
910
+ (async () => {
911
+ // 安全触发事件
912
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
913
+ try {
914
+ await Promise.race([
915
+ $.eventer.run("sqlite_count_before:" + this.table, { query, like }),
916
+ new Promise((_, reject) => setTimeout(() => reject(new Error('事件处理超时')), 5000))
917
+ ]);
918
+ } catch (eventError) {
919
+ $.log.warn(`事件处理失败,但不影响统计: ${eventError.message}`);
920
+ }
921
+ }
922
+
923
+ // 正确生成count SQL
924
+ const where = typeof query === 'string' ? query : await this.toWhere(query, like);
925
+ const sql = "SELECT COUNT(*) as num FROM `" + this.table + "`" + (where ? " WHERE " + where : "");
926
+ this.sql = sql;
927
+ const list = await this.run(sql);
928
+ const total = list && list[0] && list[0].num ? parseInt(list[0].num) : 0;
929
+
930
+ // 安全触发事件
931
+ if (typeof $.eventer === 'object' && typeof $.eventer.run === 'function') {
932
+ try {
933
+ await Promise.race([
934
+ $.eventer.run("sqlite_count_after:" + this.table, {
935
+ query,
936
+ like,
937
+ sql: this.sql,
938
+ error: this.error,
939
+ total
940
+ }),
941
+ new Promise((_, reject) => setTimeout(() => reject(new Error('事件处理超时')), 5000))
942
+ ]);
943
+ } catch (eventError) {
944
+ $.log.warn(`事件处理失败,但不影响统计返回: ${eventError.message}`);
945
+ }
946
+ }
947
+
948
+ return total;
949
+ })(),
950
+ timeoutPromise
951
+ ]);
952
+ } catch (err) {
953
+ this.error = err.message;
954
+ $.log.error(`统计记录数失败: ${err.message}`, { sql: this.sql });
955
+ throw err;
956
+ }
633
957
  };
634
958
 
635
959
  /**
636
- * @description 查询数据并返回符合条件总数
960
+ * 查询数据并返回符合条件总数
637
961
  * @param {Object} query 查询条件
638
- * @param {String} sort 排序
639
- * @param {String} view 返回的字段
640
- * @param {Boolean} like 是否使用like匹配, 默认使用
641
- * @return {Promise|Object} 查询到的内容列表和符合条件总数
962
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
963
+ * @param {Number} timeout 超时时间(毫秒),默认30000ms
964
+ * @return {Promise<Number>} 记录数
642
965
  */
643
- Sql.prototype.getCount = async function(query, sort, view, like = true) {
644
- return this.getCountSql(this.toWhere(query, like), sort, view);
966
+ Sql.prototype.getCount = async function(query, like, timeout = 30000) {
967
+ return await this.count(query, like, timeout);
645
968
  };
646
969
 
647
970
  /* === 传入数组操作 === */
@@ -649,42 +972,278 @@ Sql.prototype.getCount = async function(query, sort, view, like = true) {
649
972
  * @description 添加多条数据
650
973
  * @param {Array} list 对象数组
651
974
  * @param {Boolean} lock 是否锁定
975
+ * @param {Number} batchSize 批量大小,默认100
976
+ * @param {Number} timeout 超时时间,默认60000毫秒
652
977
  * @return {Promise|Object} 执行结果
653
978
  */
654
- Sql.prototype.addList = function(list, lock = true) {
655
- var sql = lock ? "BEGIN;\r\n" : "\r\n";
656
- var len = list.length;
657
- for (var i = 0; i < len; i++) {
658
- sql += this.toAddSql(list[i]) + "\r\n";
979
+ Sql.prototype.addList = async function(list, lock = true, batchSize = 100, timeout = 60000) {
980
+ if (!this.table || !Array.isArray(list) || list.length === 0) {
981
+ throw new Error('表名或数据列表未设置');
659
982
  }
660
- sql += lock ? "COMMIT;" : "";
661
- return this.exec(sql);
983
+ try {
984
+ // 添加整体操作超时控制
985
+ const timeoutPromise = new Promise((_, reject) => {
986
+ setTimeout(() => reject(new Error('批量添加数据操作超时')), timeout);
987
+ });
988
+
989
+ return await Promise.race([
990
+ (async () => {
991
+ // 如果数据量较小,直接处理
992
+ if (list.length <= batchSize) {
993
+ // 使用批量插入语法,不使用事务包装
994
+ this.sql = this.toBatchAddSql(list);
995
+ return await this.exec(this.sql);
996
+ }
997
+
998
+ // 分批处理大数据量
999
+ const totalBatches = Math.ceil(list.length / batchSize);
1000
+ $.log.info(`开始分批添加数据,共${totalBatches}批,每批${batchSize}条`);
1001
+
1002
+ // 分批执行,每批一个单独的批量插入语句
1003
+ let finalResult = null;
1004
+ for (let i = 0; i < totalBatches; i++) {
1005
+ const batch = list.slice(i * batchSize, (i + 1) * batchSize);
1006
+ $.log.debug(`处理第${i + 1}/${totalBatches}批数据,${batch.length}条`);
1007
+
1008
+ // 生成批量插入SQL
1009
+ const batchSql = this.toBatchAddSql(batch);
1010
+ this.sql = batchSql;
1011
+
1012
+ // 为每批操作添加超时控制
1013
+ finalResult = await Promise.race([
1014
+ this.exec(batchSql),
1015
+ new Promise((_, reject) => {
1016
+ setTimeout(() => reject(new Error(`第${i + 1}批数据处理超时`)), timeout / totalBatches);
1017
+ })
1018
+ ]);
1019
+ }
1020
+
1021
+ $.log.success(`批量添加数据完成,共${list.length}条`);
1022
+ return finalResult;
1023
+ })(),
1024
+ timeoutPromise
1025
+ ]);
1026
+ } catch (error) {
1027
+ $.log.error(`[${this.constructor.name}] [addList]`, '批量添加数据失败', {
1028
+ error: error.message,
1029
+ table: this.table,
1030
+ list_length: list.length
1031
+ });
1032
+ throw error;
1033
+ }
1034
+ };
1035
+
1036
+ /**
1037
+ * 生成批量插入SQL语句
1038
+ * @param {Array} list 数据列表
1039
+ * @return {String} 批量插入SQL语句
1040
+ */
1041
+ Sql.prototype.toBatchAddSql = function(list) {
1042
+ if (!this.table || !Array.isArray(list) || list.length === 0) {
1043
+ throw new Error('表名或数据列表未设置');
1044
+ }
1045
+
1046
+ // 获取第一个对象的键名作为列名
1047
+ const firstItem = list[0];
1048
+ if (!firstItem || typeof firstItem !== 'object') {
1049
+ throw new Error('数据格式错误');
1050
+ }
1051
+
1052
+ let keys = [];
1053
+ for (const k in firstItem) {
1054
+ if (Object.prototype.hasOwnProperty.call(firstItem, k)) {
1055
+ keys.push(this.escapeId(k));
1056
+ }
1057
+ }
1058
+
1059
+ // 构建列名部分
1060
+ const columns = keys.join(',');
1061
+
1062
+ // 构建值部分
1063
+ const valuesList = [];
1064
+ for (const item of list) {
1065
+ const values = [];
1066
+ for (const k of keys) {
1067
+ const unescapedKey = k.replace(/`/g, '');
1068
+ let val = item[unescapedKey];
1069
+ if (typeof val === "string") {
1070
+ val = val.trim("'");
1071
+ }
1072
+ values.push(this.escape(val));
1073
+ }
1074
+ valuesList.push(`(${values.join(',')})`);
1075
+ }
1076
+
1077
+ // 生成最终SQL
1078
+ const sql = `INSERT INTO \`${this.table}\` (${columns}) VALUES ${valuesList.join(',')}`;
1079
+ return sql;
662
1080
  };
1081
+
663
1082
  /**
664
- * @description 删除多条数据
1083
+ * 删除多条数据
665
1084
  * @param {Array} list 对象数组
666
- * @return {Promise|Object} 执行结果
1085
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
1086
+ * @param {Number} batchSize 每批处理数量,默认100
1087
+ * @param {Number} timeout 超时时间(毫秒),默认60000
1088
+ * @return {Promise<Object>} 执行结果
667
1089
  */
668
- Sql.prototype.delList = function(list) {
669
- var sql = "";
670
- var len = list.length;
671
- for (var i = 0; i < len; i++) {
672
- sql += this.toDelSql(list[i].query);
1090
+ Sql.prototype.delList = async function(list, like, batchSize = 100, timeout = 60000) {
1091
+ if (!this.table || !Array.isArray(list) || list.length === 0) {
1092
+ throw new Error('表名或数据列表未设置');
1093
+ }
1094
+ try {
1095
+ // 添加整体操作超时控制
1096
+ const timeoutPromise = new Promise((_, reject) => {
1097
+ setTimeout(() => reject(new Error('批量删除数据操作超时')), timeout);
1098
+ });
1099
+
1100
+ return await Promise.race([
1101
+ (async () => {
1102
+ // 如果数据量较小,直接处理
1103
+ if (list.length <= batchSize) {
1104
+ let sql = "";
1105
+ for (const item of list) {
1106
+ sql += this.toDelSql(item.query, like);
1107
+ }
1108
+ this.sql = sql;
1109
+ return await this.exec(sql);
1110
+ }
1111
+
1112
+ // 分批处理大数据量
1113
+ const totalBatches = Math.ceil(list.length / batchSize);
1114
+ $.log.info(`开始分批删除数据,共${totalBatches}批,每批${batchSize}条`);
1115
+
1116
+ // 使用事务包装整个操作以保证原子性
1117
+ let finalResult = null;
1118
+ try {
1119
+ // 开始事务
1120
+ await this.exec("BEGIN;", 15000);
1121
+
1122
+ // 分批处理
1123
+ for (let i = 0; i < totalBatches; i++) {
1124
+ const batch = list.slice(i * batchSize, (i + 1) * batchSize);
1125
+ $.log.debug(`处理第${i + 1}/${totalBatches}批数据,${batch.length}条`);
1126
+
1127
+ let batchSql = "";
1128
+ for (const item of batch) {
1129
+ batchSql += this.toDelSql(item.query, like);
1130
+ }
1131
+
1132
+ // 为每批操作添加超时控制
1133
+ finalResult = await Promise.race([
1134
+ this.exec(batchSql),
1135
+ new Promise((_, reject) => {
1136
+ setTimeout(() => reject(new Error(`第${i + 1}批数据删除超时`)), timeout / totalBatches);
1137
+ })
1138
+ ]);
1139
+ }
1140
+
1141
+ // 提交事务
1142
+ await this.exec("COMMIT;", 15000);
1143
+ } catch (error) {
1144
+ // 发生错误时回滚事务
1145
+ try {
1146
+ await this.exec("ROLLBACK;", 15000);
1147
+ $.log.error(`批量删除数据失败,事务已回滚: ${error.message}`);
1148
+ } catch (rollbackError) {
1149
+ $.log.error(`批量删除数据失败,事务回滚也失败: ${rollbackError.message}`);
1150
+ }
1151
+ throw error;
1152
+ }
1153
+
1154
+ $.log.success(`批量删除数据完成,共${list.length}条`);
1155
+ return finalResult;
1156
+ })(),
1157
+ timeoutPromise
1158
+ ]);
1159
+ } catch (err) {
1160
+ this.error = err.message;
1161
+ $.log.error(`批量删除数据失败: ${err.message}`);
1162
+ throw err;
673
1163
  }
674
- return this.exec(sql);
675
1164
  };
676
1165
  /**
677
- * @description 修改多条数据
1166
+ * 更新多条数据
678
1167
  * @param {Array} list 对象数组
679
- * @return {Promise|Object} 执行结果
1168
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
1169
+ * @param {Number} batchSize 每批处理数量,默认100
1170
+ * @param {Number} timeout 超时时间(毫秒),默认60000
1171
+ * @return {Promise<Object>} 执行结果
680
1172
  */
681
- Sql.prototype.setList = function(list) {
682
- var sql = "";
683
- var len = list.length;
684
- for (var i = 0; i < len; i++) {
685
- sql += this.toSetSql(list[i].query, list[i].item);
1173
+ Sql.prototype.setList = async function(list, like = false, batchSize = 100, timeout = 60000) {
1174
+ if (!this.table || !Array.isArray(list) || list.length === 0) {
1175
+ throw new Error('表名或数据列表未设置');
1176
+ }
1177
+ try {
1178
+ // 添加整体操作超时控制
1179
+ const timeoutPromise = new Promise((_, reject) => {
1180
+ setTimeout(() => reject(new Error('批量更新数据操作超时')), timeout);
1181
+ });
1182
+
1183
+ return await Promise.race([
1184
+ (async () => {
1185
+ // 如果数据量较小,直接处理
1186
+ if (list.length <= batchSize) {
1187
+ let sql = "";
1188
+ for (const item of list) {
1189
+ sql += this.toSetSql(item.query, item.obj, like);
1190
+ }
1191
+ this.sql = sql;
1192
+ return await this.exec(sql);
1193
+ }
1194
+
1195
+ // 分批处理大数据量
1196
+ const totalBatches = Math.ceil(list.length / batchSize);
1197
+ $.log.info(`开始分批更新数据,共${totalBatches}批,每批${batchSize}条`);
1198
+
1199
+ // 使用事务包装整个操作以保证原子性
1200
+ let finalResult = null;
1201
+ try {
1202
+ // 开始事务
1203
+ await this.exec("BEGIN;", 15000);
1204
+
1205
+ // 分批处理
1206
+ for (let i = 0; i < totalBatches; i++) {
1207
+ const batch = list.slice(i * batchSize, (i + 1) * batchSize);
1208
+ $.log.debug(`处理第${i + 1}/${totalBatches}批数据,${batch.length}条`);
1209
+
1210
+ let batchSql = "";
1211
+ for (const item of batch) {
1212
+ batchSql += this.toSetSql(item.query, item.obj, like);
1213
+ }
1214
+
1215
+ // 为每批操作添加超时控制
1216
+ finalResult = await Promise.race([
1217
+ this.exec(batchSql),
1218
+ new Promise((_, reject) => {
1219
+ setTimeout(() => reject(new Error(`第${i + 1}批数据更新超时`)), timeout / totalBatches);
1220
+ })
1221
+ ]);
1222
+ }
1223
+
1224
+ // 提交事务
1225
+ await this.exec("COMMIT;", 15000);
1226
+ } catch (error) {
1227
+ // 发生错误时回滚事务
1228
+ try {
1229
+ await this.exec("ROLLBACK;", 15000);
1230
+ $.log.error(`批量更新数据失败,事务已回滚: ${error.message}`);
1231
+ } catch (rollbackError) {
1232
+ $.log.error(`批量更新数据失败,事务回滚也失败: ${rollbackError.message}`);
1233
+ }
1234
+ throw error;
1235
+ }
1236
+
1237
+ $.log.success(`批量更新数据完成,共${list.length}条`);
1238
+ return finalResult;
1239
+ })(),
1240
+ timeoutPromise
1241
+ ]);
1242
+ } catch (err) {
1243
+ this.error = err.message;
1244
+ $.log.error(`批量更新数据失败: ${err.message}`);
1245
+ throw err;
686
1246
  }
687
- return this.exec(sql);
688
1247
  };
689
1248
 
690
1249
  /* 辅助类 */
@@ -694,7 +1253,7 @@ Sql.prototype.setList = function(list) {
694
1253
  * @param {Object} sqlDt sql模板集合
695
1254
  * @return {Bool} 有则返回true,没有则返回false
696
1255
  */
697
- Sql.prototype.has_param = function(paramDt, sqlDt) {
1256
+ Sql.prototype.hasParam = function(paramDt, sqlDt) {
698
1257
  var bl = false;
699
1258
  for (var key in sqlDt) {
700
1259
  var value = paramDt[key];
@@ -712,7 +1271,7 @@ Sql.prototype.has_param = function(paramDt, sqlDt) {
712
1271
  * @param {Object} sqlDt sql模板集合
713
1272
  * @return {Bool} 没有模板则返回名称,都有则返回undefined
714
1273
  */
715
- Sql.prototype.not_param = function(paramDt, sqlDt) {
1274
+ Sql.prototype.notParam = function(paramDt, sqlDt) {
716
1275
  var name;
717
1276
  for (var key in paramDt) {
718
1277
  if (!sqlDt[key]) {
@@ -729,7 +1288,7 @@ Sql.prototype.not_param = function(paramDt, sqlDt) {
729
1288
  * @param {Object} sqlDt sql模板集合
730
1289
  * @return {Object} 返回过滤后的参数集合
731
1290
  */
732
- Sql.prototype.filter_param = function(paramDt, sqlDt) {
1291
+ Sql.prototype.filterParam = function(paramDt, sqlDt) {
733
1292
  var dt = [];
734
1293
  for (var key in paramDt) {
735
1294
  if (!sqlDt[key]) {
@@ -745,7 +1304,7 @@ Sql.prototype.filter_param = function(paramDt, sqlDt) {
745
1304
  * @param {Object} sqlDt 模板集合
746
1305
  * @return {String} 返回拼接的查询参数
747
1306
  */
748
- Sql.prototype.tpl_query = function(paramDt, sqlDt) {
1307
+ Sql.prototype.tplQuery = function(paramDt, sqlDt) {
749
1308
  var sql = "";
750
1309
  if (sqlDt) {
751
1310
  var l = this.config.separator;
@@ -829,7 +1388,7 @@ Sql.prototype.tpl_query = function(paramDt, sqlDt) {
829
1388
  * @param {Object} sqlDt 模板集合
830
1389
  * @return {String} 返回拼接的查询参数
831
1390
  */
832
- Sql.prototype.tpl_body = function(paramDt, sqlDt) {
1391
+ Sql.prototype.tplBody = function(paramDt, sqlDt) {
833
1392
  var sql = "";
834
1393
  if (!sqlDt || sqlDt.length === 0) {
835
1394
  for (var key in paramDt) {
@@ -884,37 +1443,207 @@ Sql.prototype.model = function(model) {
884
1443
  };
885
1444
 
886
1445
  /**
887
- * @description 查询一条数据
1446
+ * 查询单条数据
888
1447
  * @param {Object} query 查询条件
889
1448
  * @param {String} sort 排序
890
1449
  * @param {String} view 返回的字段
891
- * @param {Boolean} like 是否like匹配
892
- * @return {Promise|Array} 查询结果
1450
+ * @param {Boolean} like 是否使用like匹配, 为空使用默认方式
1451
+ * @param {Number} timeout 超时时间(毫秒),默认30000ms
1452
+ * @return {Promise|Object|null} 查询结果
893
1453
  */
894
- Sql.prototype.getObj = async function(query, sort, view, like) {
895
- this.page = 1;
896
- this.size = 1;
897
- var key = this.key;
898
- if (key) {
899
- if (view && view.indexOf(key) === -1 && view.indexOf('*') === -1) {
900
- view += "," + this.escapeId(key);
901
- }
902
- }
903
- if (like === undefined) {
904
- like = this.like;
905
- }
906
- var sql = this.toGetSql(query, sort, view, like);
907
- var list = await this.run(sql);
908
- if (list.length > 0) {
909
- var obj = list[0];
910
- if (key) {
911
- return this.model(obj);
912
- } else {
913
- return obj;
1454
+ Sql.prototype.getObj = async function(query, sort, view, like, timeout = 30000) {
1455
+ try {
1456
+ // 保存当前分页设置
1457
+ const oldPage = this.page;
1458
+ const oldSize = this.size;
1459
+
1460
+ // 设置为只查询一条
1461
+ this.page = 1;
1462
+ this.size = 1;
1463
+
1464
+ // 使用优化后的get方法
1465
+ const list = await this.get(query, sort, view, like, timeout);
1466
+
1467
+ // 恢复分页设置
1468
+ this.page = oldPage;
1469
+ this.size = oldSize;
1470
+
1471
+ var obj = null;
1472
+ if (list.length > 0) {
1473
+ obj = list[0];
1474
+ if (this.key) {
1475
+ obj = this.model(obj);
1476
+ }
914
1477
  }
915
- } else {
916
- return null;
1478
+
1479
+ return obj;
1480
+ } catch (err) {
1481
+ this.error = err.message;
1482
+ $.log.error(`查询单条数据失败: ${err.message}`, { sql: this.sql });
1483
+ throw err;
917
1484
  }
918
1485
  };
919
1486
 
1487
+
1488
+
1489
+ /**
1490
+ * 从SQL文件加载数据库
1491
+ * @param {String} file - SQL文件路径
1492
+ * @returns {Promise<boolean>} 是否加载成功
1493
+ */
1494
+ Sql.prototype.load = async function (file) {
1495
+ try {
1496
+ // 记录操作日志
1497
+ if (this.config && this.config.debug) {
1498
+ $.log.debug(`[${this.constructor.name}] [load] 开始从文件加载数据库`, {
1499
+ file: file
1500
+ });
1501
+ }
1502
+
1503
+ // 检查文件是否存在
1504
+ if (!file.hasFile()) {
1505
+ throw new Error(`SQL文件不存在: ${file}`);
1506
+ }
1507
+
1508
+ // 读取SQL文件内容
1509
+ const sqlContent = await $.file.readText(file);
1510
+
1511
+ if (!sqlContent || sqlContent.trim() === '') {
1512
+ throw new Error(`SQL文件内容为空: ${file}`);
1513
+ }
1514
+
1515
+ // 分割SQL语句(按分号分割,但需要注意处理字符串中的分号)
1516
+ const sqlStatements = this._splitSqlStatements(sqlContent);
1517
+
1518
+ // 开始事务执行SQL语句
1519
+ await this.exec('BEGIN TRANSACTION');
1520
+
1521
+ try {
1522
+ // 逐个执行SQL语句
1523
+ for (const sql of sqlStatements) {
1524
+ const trimmedSql = sql.trim();
1525
+ if (trimmedSql) {
1526
+ await this.exec(trimmedSql);
1527
+ }
1528
+ }
1529
+
1530
+ // 提交事务
1531
+ await this.exec('COMMIT');
1532
+
1533
+ if (this.config && this.config.debug) {
1534
+ $.log.info(`[${this.constructor.name}] [load] 数据库加载成功`, {
1535
+ file: file,
1536
+ statementCount: sqlStatements.length
1537
+ });
1538
+ }
1539
+
1540
+ return true;
1541
+ } catch (err) {
1542
+ // 回滚事务
1543
+ await this.exec('ROLLBACK').catch(rollbackErr => {
1544
+ $.log.error(`[${this.constructor.name}] [load] 事务回滚失败`, {
1545
+ error: rollbackErr.message
1546
+ });
1547
+ });
1548
+
1549
+ throw err;
1550
+ }
1551
+ } catch (error) {
1552
+ // 记录错误日志
1553
+ $.log.error(`[${this.constructor.name}] [load] 数据库加载失败`, {
1554
+ error: error.message,
1555
+ file: file
1556
+ });
1557
+
1558
+ // 抛出错误
1559
+ throw error;
1560
+ }
1561
+ };
1562
+
1563
+ /**
1564
+ * 分割SQL语句
1565
+ * @private
1566
+ * @param {String} sqlContent - SQL内容
1567
+ * @returns {Array} SQL语句数组
1568
+ */
1569
+ Sql.prototype._splitSqlStatements = function(sqlContent) {
1570
+ const statements = [];
1571
+ let inString = false;
1572
+ let stringChar = '';
1573
+ let inComment = false;
1574
+ let currentStatement = '';
1575
+
1576
+ for (let i = 0; i < sqlContent.length; i++) {
1577
+ const char = sqlContent[i];
1578
+ const nextChar = i + 1 < sqlContent.length ? sqlContent[i + 1] : '';
1579
+
1580
+ // 处理注释
1581
+ if (!inString && !inComment && char === '-' && nextChar === '-') {
1582
+ inComment = true;
1583
+ i++; // 跳过第二个'-'
1584
+ continue;
1585
+ }
1586
+
1587
+ if (inComment && char === '\n') {
1588
+ inComment = false;
1589
+ continue;
1590
+ }
1591
+
1592
+ if (inComment) {
1593
+ continue;
1594
+ }
1595
+
1596
+ // 处理多行注释
1597
+ if (!inString && !inComment && char === '/' && nextChar === '*') {
1598
+ inComment = true;
1599
+ i++; // 跳过'*'
1600
+ continue;
1601
+ }
1602
+
1603
+ if (inComment && char === '*' && nextChar === '/') {
1604
+ inComment = false;
1605
+ i++; // 跳过'/'
1606
+ continue;
1607
+ }
1608
+
1609
+ // 处理字符串
1610
+ if (!inComment && (char === "'" || char === '"') && (!inString || stringChar === char)) {
1611
+ // 检查是否是转义的引号
1612
+ let escaped = false;
1613
+ for (let j = i - 1; j >= 0; j--) {
1614
+ if (sqlContent[j] === '\\') {
1615
+ escaped = !escaped;
1616
+ } else {
1617
+ break;
1618
+ }
1619
+ }
1620
+
1621
+ if (!escaped) {
1622
+ if (inString && stringChar === char) {
1623
+ inString = false;
1624
+ stringChar = '';
1625
+ } else if (!inString) {
1626
+ inString = true;
1627
+ stringChar = char;
1628
+ }
1629
+ }
1630
+ }
1631
+
1632
+ // 分割语句
1633
+ if (!inString && !inComment && char === ';') {
1634
+ statements.push(currentStatement.trim());
1635
+ currentStatement = '';
1636
+ } else {
1637
+ currentStatement += char;
1638
+ }
1639
+ }
1640
+
1641
+ // 添加最后一个语句(如果有)
1642
+ if (currentStatement.trim()) {
1643
+ statements.push(currentStatement.trim());
1644
+ }
1645
+
1646
+ return statements;
1647
+ };
1648
+
920
1649
  module.exports = Sql;