mm_sqlite 1.4.0 → 1.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.
package/sql.js CHANGED
@@ -564,46 +564,40 @@ Sql.prototype.backup = async function (file) {
564
564
  throw new TypeError('表名未设置');
565
565
  }
566
566
 
567
- try {
568
- // 获取所有数据
569
- const data = await this.getSql('', '', '*');
567
+ // 获取所有数据
568
+ const data = await this.getSql('', '', '*');
570
569
 
571
- if (!data || !Array.isArray(data)) {
572
- throw new Error('获取数据失败');
573
- }
570
+ if (!data || !Array.isArray(data)) {
571
+ throw new Error('获取数据失败');
572
+ }
574
573
 
575
- // 构建 SQL 语句
576
- let sqlContent = '';
574
+ // 构建 SQL 语句
575
+ let sqlContent = '';
577
576
 
578
- // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
579
- sqlContent += `-- 备份表: ${this.table}\n`;
580
- sqlContent += `-- 备份时间: ${new Date().toISOString()}\n\n`;
577
+ // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
578
+ sqlContent += `-- 备份表: ${this.table}\n`;
579
+ sqlContent += `-- 备份时间: ${new Date().toISOString()}\n\n`;
581
580
 
582
- // 添加数据插入语句
583
- for (const row of data) {
584
- const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
585
- const values = Object.values(row).map(value => this.escape(value)).join(', ');
586
- sqlContent += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
587
- }
581
+ // 添加数据插入语句
582
+ for (const row of data) {
583
+ const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
584
+ const values = Object.values(row).map(value => this.escape(value)).join(', ');
585
+ sqlContent += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
586
+ }
588
587
 
589
- // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
590
- const fs = require('fs');
591
- const path = require('path');
588
+ // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
589
+ const fs = require('fs');
590
+ const path = require('path');
592
591
 
593
- // 确保目录存在
594
- const dir = path.dirname(file);
595
- if (!fs.existsSync(dir)) {
596
- fs.mkdirSync(dir, { recursive: true });
597
- }
592
+ // 确保目录存在
593
+ const dir = path.dirname(file);
594
+ if (!fs.existsSync(dir)) {
595
+ fs.mkdirSync(dir, { recursive: true });
596
+ }
598
597
 
599
- fs.writeFileSync(file, sqlContent, 'utf8');
598
+ fs.writeFileSync(file, sqlContent, 'utf8');
600
599
 
601
- return true;
602
- } catch (err) {
603
- this.error = err.message;
604
- this.log('error', '备份数据库失败', err);
605
- return false;
606
- }
600
+ return true;
607
601
  };
608
602
 
609
603
  /**
@@ -620,40 +614,34 @@ Sql.prototype.restore = async function (file) {
620
614
  throw new TypeError('表名未设置');
621
615
  }
622
616
 
623
- try {
624
- const fs = require('fs');
617
+ const fs = require('fs');
625
618
 
626
- // 检查文件是否存在
627
- if (!fs.existsSync(file)) {
628
- throw new Error('备份文件不存在');
629
- }
619
+ // 检查文件是否存在
620
+ if (!fs.existsSync(file)) {
621
+ throw new Error('备份文件不存在');
622
+ }
630
623
 
631
- // 读取文件内容
632
- const sqlContent = fs.readFileSync(file, 'utf8');
624
+ // 读取文件内容
625
+ const sqlContent = fs.readFileSync(file, 'utf8');
633
626
 
634
- if (!sqlContent) {
635
- throw new Error('备份文件为空');
636
- }
627
+ if (!sqlContent) {
628
+ throw new Error('备份文件为空');
629
+ }
637
630
 
638
- // 解析 SQL 语句(按分号分割,但需要处理字符串中的分号)
639
- const statements = this._parseSqlStatements(sqlContent);
631
+ // 解析 SQL 语句(按分号分割,但需要处理字符串中的分号)
632
+ const statements = this._parseSqlStatements(sqlContent);
640
633
 
641
- // 执行所有 SQL 语句
642
- for (const statement of statements) {
643
- if (statement.trim()) {
644
- // 跳过注释行
645
- if (!statement.trim().startsWith('--')) {
646
- await this.exec(statement);
647
- }
634
+ // 执行所有 SQL 语句
635
+ for (const statement of statements) {
636
+ if (statement.trim()) {
637
+ // 跳过注释行
638
+ if (!statement.trim().startsWith('--')) {
639
+ await this.exec(statement);
648
640
  }
649
641
  }
650
-
651
- return true;
652
- } catch (err) {
653
- this.error = err.message;
654
- this.log('error', '恢复数据库失败', err);
655
- return false;
656
642
  }
643
+
644
+ return true;
657
645
  };
658
646
 
659
647
  /**
@@ -870,18 +858,11 @@ Sql.prototype.add = async function (body) {
870
858
  if (!this.table || !body || typeof body !== 'object') {
871
859
  throw new Error('表名或数据未设置');
872
860
  }
873
- try {
874
- var sql = this.toAddSql(body);
875
- this.sql = sql;
876
- var bl = await this.exec(sql);
861
+ var sql = this.toAddSql(body);
862
+ this.sql = sql;
863
+ var bl = await this.exec(sql);
877
864
 
878
- return bl;
879
- } catch (err) {
880
- this.error = err.message;
881
- this.log('error', '添加数据失败', err);
882
- // 返回默认操作结果对象,保持返回值类型一致
883
- return 0;
884
- }
865
+ return bl;
885
866
  };
886
867
  /**
887
868
  * @description 删除数据
@@ -893,17 +874,10 @@ Sql.prototype.del = async function (query, like) {
893
874
  if (!this.table) {
894
875
  throw new Error('表名未设置');
895
876
  }
896
- try {
897
- var sql = this.toDelSql(query, like);
898
- this.sql = sql;
899
- var bl = await this.exec(sql);
900
- return bl;
901
- } catch (err) {
902
- this.error = err.message;
903
- this.log('error', '删除数据失败', err);
904
- // 返回默认操作结果对象,保持返回值类型一致
905
- return 0;
906
- }
877
+ var sql = this.toDelSql(query, like);
878
+ this.sql = sql;
879
+ var bl = await this.exec(sql);
880
+ return bl;
907
881
  };
908
882
 
909
883
  /**
@@ -917,17 +891,10 @@ Sql.prototype.set = async function (query, body, like) {
917
891
  if (!this.table || !body || typeof body !== 'object') {
918
892
  throw new Error('表名或数据未设置');
919
893
  }
920
- try {
921
- var sql = this.toSetSql(query, body, like);
922
- this.sql = sql;
923
- var bl = await this.exec(sql);
924
- return bl;
925
- } catch (err) {
926
- this.error = err.message;
927
- this.log('error', '修改数据失败', err);
928
- // 返回默认操作结果对象,保持返回值类型一致
929
- return 0;
930
- }
894
+ var sql = this.toSetSql(query, body, like);
895
+ this.sql = sql;
896
+ var bl = await this.exec(sql);
897
+ return bl;
931
898
  };
932
899
 
933
900
  /**
@@ -944,16 +911,9 @@ Sql.prototype.get = async function (query, sort, view, like, timeout = 5000) {
944
911
  throw new Error('表名未设置');
945
912
  }
946
913
 
947
- try {
948
- var sql = this.toGetSql(query, sort, view, like);
949
- var list = await this.run(sql, [], timeout);
950
- return list;
951
- } catch (err) {
952
- this.error = err.message;
953
- this.log('error', '查询数据失败', err);
954
- // 返回空数组作为默认值,保持返回值类型一致
955
- return [];
956
- }
914
+ var sql = this.toGetSql(query, sort, view, like);
915
+ var list = await this.run(sql, [], timeout);
916
+ return list;
957
917
  };
958
918
 
959
919
  /**
@@ -967,55 +927,48 @@ Sql.prototype.addOrSet = async function (where, set, like) {
967
927
  if (!this.table || !where || !set) {
968
928
  throw new Error('表名、条件或数据未设置');
969
929
  }
970
- try {
971
- let where_str;
930
+ let where_str;
972
931
 
973
- if (typeof where === 'object') {
974
- where_str = await this.toWhere(where, like);
975
- } else {
976
- where_str = where;
977
- }
978
-
979
- const count = await this.countSql(whereStr);
932
+ if (typeof where === 'object') {
933
+ where_str = this.toWhere(where, like);
934
+ } else {
935
+ where_str = where;
936
+ }
980
937
 
981
- if (count === 0) {
982
- let key = '';
983
- let value = '';
938
+ const count = await this.countSql(where_str);
984
939
 
985
- if (typeof set === 'string') {
986
- const arr = set.split(',');
987
- for (const o of arr) {
988
- const ar = o.split('=');
989
- if (ar.length === 2) {
990
- key += ',' + ar[0];
991
- value += ',' + ar[1];
992
- }
993
- }
994
- } else {
995
- for (const k in set) {
996
- key += ',' + this.escapeId(k);
997
- value += ',' + this.escape(set[k]);
940
+ if (count === 0) {
941
+ let key = '';
942
+ let value = '';
943
+
944
+ if (typeof set === 'string') {
945
+ const arr = set.split(',');
946
+ for (const o of arr) {
947
+ const ar = o.split('=');
948
+ if (ar.length === 2) {
949
+ key += ',' + ar[0];
950
+ value += ',' + ar[1];
998
951
  }
999
952
  }
1000
-
1001
- const bl = await this.addSql(key.replace(',', ''), value.replace(',', ''));
1002
-
1003
- return bl;
1004
953
  } else {
1005
- let set_vals = set;
1006
- if (typeof set === 'object') {
1007
- set_vals = await this.toSet(set);
954
+ for (const k in set) {
955
+ key += ',' + this.escapeId(k);
956
+ value += ',' + this.escape(set[k]);
1008
957
  }
958
+ }
1009
959
 
1010
- const bl1 = await this.setSql(where_str, set_vals);
960
+ const bl = await this.addSql(key.replace(',', ''), value.replace(',', ''));
1011
961
 
1012
- return bl1;
962
+ return bl;
963
+ } else {
964
+ let set_vals = set;
965
+ if (typeof set === 'object') {
966
+ set_vals = await this.toSet(set);
1013
967
  }
1014
- } catch (err) {
1015
- this.error = err.message;
1016
- this.log('error', '添加或修改数据失败', err);
1017
- // 返回默认操作结果对象,保持返回值类型一致
1018
- return 0;
968
+
969
+ const bl1 = await this.setSql(where_str, set_vals);
970
+
971
+ return bl1;
1019
972
  }
1020
973
  };
1021
974
 
@@ -1031,20 +984,13 @@ Sql.prototype.count = async function (query, like, timeout = 30000) {
1031
984
  throw new Error('表名未设置');
1032
985
  }
1033
986
 
1034
- try {
1035
- const where = typeof query === 'string' ? query : await this.toWhere(query, like);
1036
- const sql = 'SELECT COUNT(*) as num FROM `' + this.table + '`' + (where ? ' WHERE ' + where : '');
1037
- this.sql = sql;
1038
- const list = await this.run(sql);
1039
- const total = list && list[0] && list[0].num ? parseInt(list[0].num) : 0;
987
+ const where = typeof query === 'string' ? query : await this.toWhere(query, like);
988
+ const sql = 'SELECT COUNT(*) as num FROM `' + this.table + '`' + (where ? ' WHERE ' + where : '');
989
+ this.sql = sql;
990
+ const list = await this.run(sql);
991
+ const total = list && list[0] && list[0].num ? parseInt(list[0].num) : 0;
1040
992
 
1041
- return total;
1042
- } catch (err) {
1043
- this.error = err.message;
1044
- this.log('error', '统计记录数失败', err);
1045
- // 返回0作为默认统计值,保持返回值类型一致
1046
- return 0;
1047
- }
993
+ return total;
1048
994
  };
1049
995
 
1050
996
  /**
@@ -1070,37 +1016,31 @@ Sql.prototype.addList = async function (list, batch_size = 100, timeout = 60000)
1070
1016
  if (!this.table || !Array.isArray(list) || list.length === 0) {
1071
1017
  throw new Error('表名或数据列表未设置');
1072
1018
  }
1073
- try {
1074
- if (list.length <= batch_size) {
1075
- // 使用批量插入语法,不使用事务包装
1076
- this.sql = this.toBatchAddSql(list);
1077
- return await this.exec(this.sql);
1078
- }
1079
-
1080
- // 分批处理大数据量
1081
- const total = Math.ceil(list.length / batch_size);
1082
- this.log('info', `开始分批添加数据,共${total}批,每批${batch_size}条`);
1019
+ if (list.length <= batch_size) {
1020
+ // 使用批量插入语法,不使用事务包装
1021
+ this.sql = this.toBatchAddSql(list);
1022
+ return await this.exec(this.sql);
1023
+ }
1083
1024
 
1084
- // 分批执行,每批一个单独的批量插入语句
1085
- let final_res = null;
1086
- for (let i = 0; i < total; i++) {
1087
- const batch = list.slice(i * batch_size, (i + 1) * batch_size);
1088
- this.log('debug', `处理第${i + 1}/${total}批数据,${batch.length}条`);
1025
+ // 分批处理大数据量
1026
+ const total = Math.ceil(list.length / batch_size);
1027
+ this.log('info', `开始分批添加数据,共${total}批,每批${batch_size}条`);
1089
1028
 
1090
- // 生成批量插入SQL
1091
- const batch_sql = this.toBatchAddSql(batch);
1092
- this.sql = batch_sql;
1029
+ // 分批执行,每批一个单独的批量插入语句
1030
+ let final_res = null;
1031
+ for (let i = 0; i < total; i++) {
1032
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
1033
+ this.log('debug', `处理第${i + 1}/${total}批数据,${batch.length}条`);
1093
1034
 
1094
- final_res = await this.exec(batch_sql);
1095
- }
1035
+ // 生成批量插入SQL
1036
+ const batch_sql = this.toBatchAddSql(batch);
1037
+ this.sql = batch_sql;
1096
1038
 
1097
- this.log('success', `批量添加数据完成,共${list.length}条`);
1098
- return final_res;
1099
- } catch (error) {
1100
- this.log('error', '批量添加数据失败', error);
1101
- // 返回默认操作结果对象,保持返回值类型一致
1102
- return 0;
1039
+ final_res = await this.exec(batch_sql);
1103
1040
  }
1041
+
1042
+ this.log('success', `批量添加数据完成,共${list.length}条`);
1043
+ return final_res;
1104
1044
  };
1105
1045
 
1106
1046
  /**
@@ -1156,59 +1096,53 @@ Sql.prototype.delList = async function (list, like, batch_size = 100, timeout =
1156
1096
  if (!this.table || !Array.isArray(list) || list.length === 0) {
1157
1097
  throw new Error('表名或数据列表未设置');
1158
1098
  }
1159
- try {
1160
- if (list.length <= batch_size) {
1161
- let sql = '';
1162
- for (const item of list) {
1163
- sql += this.toDelSql(item.query, like);
1164
- }
1165
- this.sql = sql;
1166
- return await this.exec(sql, [], timeout);
1099
+ if (list.length <= batch_size) {
1100
+ let sql = '';
1101
+ for (const item of list) {
1102
+ sql += this.toDelSql(item.query, like);
1167
1103
  }
1104
+ this.sql = sql;
1105
+ return await this.exec(sql, [], timeout);
1106
+ }
1168
1107
 
1169
- // 分批处理大数据量
1170
- const total = Math.ceil(list.length / batch_size);
1171
- this.log('info', `开始分批删除数据,共${total}批,每批${batch_size}条`);
1172
-
1173
- // 使用事务包装整个操作以保证原子性
1174
- let final_res = null;
1175
- try {
1176
- // 开始事务
1177
- await this.exec('BEGIN;');
1108
+ // 分批处理大数据量
1109
+ const total = Math.ceil(list.length / batch_size);
1110
+ this.log('info', `开始分批删除数据,共${total}批,每批${batch_size}条`);
1178
1111
 
1179
- // 分批处理
1180
- for (let i = 0; i < total; i++) {
1181
- const batch = list.slice(i * batch_size, (i + 1) * batch_size);
1182
- this.log('debug', `处理第${i + 1}/${total}批数据,${batch.length}条`);
1112
+ // 使用事务包装整个操作以保证原子性
1113
+ let final_res = null;
1114
+ try {
1115
+ // 开始事务
1116
+ await this.exec('BEGIN;');
1183
1117
 
1184
- let batch_sql = '';
1185
- for (const item of batch) {
1186
- batch_sql += this.toDelSql(item.query, like);
1187
- }
1188
- final_res = await this.exec(batch_sql, [], timeout);
1189
- }
1118
+ // 分批处理
1119
+ for (let i = 0; i < total; i++) {
1120
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
1121
+ this.log('debug', `处理第${i + 1}/${total}批数据,${batch.length}条`);
1190
1122
 
1191
- // 提交事务
1192
- await this.exec('COMMIT;', [], timeout);
1193
- } catch (error) {
1194
- // 发生错误时回滚事务
1195
- try {
1196
- await this.exec('ROLLBACK;', [], timeout);
1197
- this.log('error', '批量删除数据失败,事务已回滚', error);
1198
- } catch (rollback_err) {
1199
- this.log('error', '批量删除数据失败,事务回滚也失败', rollback_err);
1123
+ let batch_sql = '';
1124
+ for (const item of batch) {
1125
+ batch_sql += this.toDelSql(item.query, like);
1200
1126
  }
1201
- // 记录错误日志
1202
- this.log('error', 'SQL语句执行失败', error);
1127
+ final_res = await this.exec(batch_sql, [], timeout);
1203
1128
  }
1204
1129
 
1205
- this.log('success', `批量删除数据完成,共${list.length}条`);
1206
- return final_res;
1207
- } catch (err) {
1208
- this.log('error', '批量删除数据失败', err);
1209
- // 返回默认操作结果对象,保持返回值类型一致
1210
- return 0;
1130
+ // 提交事务
1131
+ await this.exec('COMMIT;', [], timeout);
1132
+ } catch (error) {
1133
+ // 发生错误时回滚事务
1134
+ try {
1135
+ await this.exec('ROLLBACK;', [], timeout);
1136
+ this.log('error', '批量删除数据失败,事务已回滚', error);
1137
+ } catch (rollback_err) {
1138
+ this.log('error', '批量删除数据失败,事务回滚也失败', rollback_err);
1139
+ }
1140
+ // 记录错误日志
1141
+ this.log('error', 'SQL语句执行失败', error);
1211
1142
  }
1143
+
1144
+ this.log('success', `批量删除数据完成,共${list.length}条`);
1145
+ return final_res;
1212
1146
  };
1213
1147
  /**
1214
1148
  * 更新多条数据
@@ -1222,58 +1156,48 @@ Sql.prototype.setList = async function (list, like = false, batch_size = 100, ti
1222
1156
  if (!this.table || !Array.isArray(list) || list.length === 0) {
1223
1157
  throw new Error('表名或数据列表未设置');
1224
1158
  }
1225
- try {
1226
- if (list.length <= batch_size) {
1227
- let sql = '';
1228
- for (const item of list) {
1229
- sql += this.toSetSql(item.query, item.obj, like);
1230
- }
1231
- this.sql = sql;
1232
- return await this.exec(sql, [], timeout);
1159
+ if (list.length <= batch_size) {
1160
+ let sql = '';
1161
+ for (const item of list) {
1162
+ sql += this.toSetSql(item.query, item.obj, like);
1233
1163
  }
1164
+ this.sql = sql;
1165
+ return await this.exec(sql, [], timeout);
1166
+ }
1234
1167
 
1235
- // 分批处理大数据量
1236
- const total = Math.ceil(list.length / batch_size);
1237
- this.log('info', `开始分批更新数据,共${total}批,每批${batch_size}条`);
1238
-
1239
- // 使用事务包装整个操作以保证原子性
1240
- let final_res = null;
1241
- try {
1242
- // 开始事务
1243
- await this.exec('BEGIN;');
1168
+ // 分批处理大数据量
1169
+ const total = Math.ceil(list.length / batch_size);
1170
+ this.log('info', `开始分批更新数据,共${total}批,每批${batch_size}条`);
1244
1171
 
1245
- // 分批处理
1246
- for (let i = 0; i < total; i++) {
1247
- const batch = list.slice(i * batch_size, (i + 1) * batch_size);
1248
- this.log('debug', `处理第${i + 1}/${total}批数据,${batch.length}条`);
1172
+ // 使用事务包装整个操作以保证原子性
1173
+ let final_res = null;
1174
+ try {
1175
+ // 开始事务
1176
+ await this.exec('BEGIN;');
1249
1177
 
1250
- let batch_sql = '';
1251
- for (const item of batch) {
1252
- batch_sql += this.toSetSql(item.query, item.obj, like);
1253
- }
1178
+ // 分批处理
1179
+ for (let i = 0; i < total; i++) {
1180
+ const batch = list.slice(i * batch_size, (i + 1) * batch_size);
1181
+ this.log('debug', `处理第${i + 1}/${total}批数据,${batch.length}条`);
1254
1182
 
1255
- final_res = await this.exec(batch_sql, [], timeout);
1183
+ let batch_sql = '';
1184
+ for (const item of batch) {
1185
+ batch_sql += this.toSetSql(item.query, item.obj, like);
1256
1186
  }
1257
1187
 
1258
- // 提交事务
1259
- await this.exec('COMMIT;', [], timeout);
1260
- } catch (error) {
1261
- // 发生错误时回滚事务
1262
- try {
1263
- await this.exec('ROLLBACK;', [], timeout);
1264
- this.log('error', '批量更新数据失败,事务已回滚', error);
1265
- } catch (rollback_err) {
1266
- this.log('error', '批量更新数据失败,事务回滚也失败', rollback_err);
1267
- }
1188
+ final_res = await this.exec(batch_sql, [], timeout);
1268
1189
  }
1269
1190
 
1270
- this.log('success', `批量更新数据完成,共${list.length}条`);
1271
- return final_res;
1272
- } catch (err) {
1273
- this.log('error', '批量更新数据失败', err);
1274
- // 返回默认操作结果对象,保持返回值类型一致
1275
- return 0;
1191
+ // 提交事务
1192
+ await this.exec('COMMIT;', [], timeout);
1193
+ } catch (error) {
1194
+ // 发生错误时回滚事务
1195
+ await this.exec('ROLLBACK;', [], timeout);
1196
+ this.log('error', '批量更新数据失败,事务已回滚', error);
1276
1197
  }
1198
+
1199
+ this.log('success', `批量更新数据完成,共${list.length}条`);
1200
+ return final_res;
1277
1201
  };
1278
1202
 
1279
1203
  /* 辅助类 */
@@ -1490,36 +1414,30 @@ Sql.prototype.model = function (model) {
1490
1414
  * @returns {Promise | object | null} 查询结果
1491
1415
  */
1492
1416
  Sql.prototype.getObj = async function (query, sort, view, like, timeout = 30000) {
1493
- try {
1494
- // 保存当前分页设置
1495
- const old_page = this.page;
1496
- const size = this.size;
1497
-
1498
- // 设置为只查询一条
1499
- this.page = 1;
1500
- this.size = 1;
1501
-
1502
- // 使用优化后的get方法
1503
- const list = await this.get(query, sort, view, like, timeout);
1504
-
1505
- // 恢复分页设置
1506
- this.page = old_page;
1507
- this.size = size;
1508
-
1509
- var obj = null;
1510
- if (list.length > 0) {
1511
- obj = list[0];
1512
- if (this.key) {
1513
- obj = this.model(obj);
1514
- }
1417
+ // 保存当前分页设置
1418
+ const old_page = this.page;
1419
+ const size = this.size;
1420
+
1421
+ // 设置为只查询一条
1422
+ this.page = 1;
1423
+ this.size = 1;
1424
+
1425
+ // 使用优化后的get方法
1426
+ const list = await this.get(query, sort, view, like, timeout);
1427
+
1428
+ // 恢复分页设置
1429
+ this.page = old_page;
1430
+ this.size = size;
1431
+
1432
+ var obj = null;
1433
+ if (list.length > 0) {
1434
+ obj = list[0];
1435
+ if (this.key) {
1436
+ obj = this.model(obj);
1515
1437
  }
1516
-
1517
- return obj;
1518
- } catch (err) {
1519
- this.error = err.message;
1520
- this.log('error', '查询单条数据失败', err);
1521
1438
  }
1522
- return null;
1439
+
1440
+ return obj;
1523
1441
  };
1524
1442
 
1525
1443
  /**
@@ -1528,65 +1446,61 @@ Sql.prototype.getObj = async function (query, sort, view, like, timeout = 30000)
1528
1446
  * @returns {Promise<boolean>} 是否加载成功
1529
1447
  */
1530
1448
  Sql.prototype.load = async function (file) {
1531
- try {
1532
- // 记录操作日志
1533
- if (this.config && this.config.debug) {
1534
- this.log('debug', `开始从文件加载数据库`, {
1535
- file: file
1536
- });
1537
- }
1449
+ // 记录操作日志
1450
+ if (this.config && this.config.debug) {
1451
+ this.log('debug', `开始从文件加载数据库`, {
1452
+ file: file
1453
+ });
1454
+ }
1538
1455
 
1539
- // 检查文件是否存在
1540
- if (!file.hasFile()) {
1541
- throw new Error(`SQL文件不存在: ${file}`);
1542
- }
1456
+ // 检查文件是否存在
1457
+ if (!file.hasFile()) {
1458
+ throw new Error(`SQL文件不存在: ${file}`);
1459
+ }
1543
1460
 
1544
- // 读取SQL文件内容
1545
- const sql_content = await $.file.readText(file);
1461
+ // 读取SQL文件内容
1462
+ const sql_content = await $.file.readText(file);
1546
1463
 
1547
- if (!sql_content || sql_content.trim() === '') {
1548
- throw new Error(`SQL文件内容为空: ${file}`);
1549
- }
1464
+ if (!sql_content || sql_content.trim() === '') {
1465
+ throw new Error(`SQL文件内容为空: ${file}`);
1466
+ }
1550
1467
 
1551
- // 分割SQL语句(按分号分割,但需要注意处理字符串中的分号)
1552
- const sql_stmts = this._splitSqlStatements(sql_content);
1468
+ // 分割SQL语句(按分号分割,但需要注意处理字符串中的分号)
1469
+ const sql_stmts = this._splitSqlStatements(sql_content);
1553
1470
 
1554
- // 开始事务执行SQL语句
1555
- await this.exec('BEGIN TRANSACTION');
1471
+ // 开始事务执行SQL语句
1472
+ await this.exec('BEGIN TRANSACTION');
1556
1473
 
1557
- try {
1558
- // 逐个执行SQL语句
1559
- for (const sql of sql_stmts) {
1560
- const trim_sql = sql.trim();
1561
- if (trim_sql) {
1562
- await this.exec(trim_sql);
1563
- }
1474
+ try {
1475
+ // 逐个执行SQL语句
1476
+ for (const sql of sql_stmts) {
1477
+ const trim_sql = sql.trim();
1478
+ if (trim_sql) {
1479
+ await this.exec(trim_sql);
1564
1480
  }
1481
+ }
1565
1482
 
1566
- // 提交事务
1567
- await this.exec('COMMIT');
1568
-
1569
- if (this.config && this.config.debug) {
1570
- this.log('info', `数据库加载成功`, {
1571
- file: file,
1572
- stmt_num: sql_stmts.length
1573
- });
1574
- }
1483
+ // 提交事务
1484
+ await this.exec('COMMIT');
1575
1485
 
1576
- return true;
1577
- } catch (err) {
1578
- // 回滚事务
1579
- await this.exec('ROLLBACK').catch(rollback_err => {
1580
- this.log('error', '事务回滚失败', rollback_err);
1486
+ if (this.config && this.config.debug) {
1487
+ this.log('info', `数据库加载成功`, {
1488
+ file: file,
1489
+ stmt_num: sql_stmts.length
1581
1490
  });
1582
-
1583
- // 记录错误日志
1584
- this.log('error', 'SQL语句执行失败', err);
1585
1491
  }
1586
- } catch (error) {
1492
+
1493
+ return true;
1494
+ } catch (err) {
1495
+ // 回滚事务
1496
+ await this.exec('ROLLBACK').catch(rollback_err => {
1497
+ this.log('error', '事务回滚失败', rollback_err);
1498
+ });
1499
+
1587
1500
  // 记录错误日志
1588
- this.log('error', '数据库加载失败', error);
1501
+ this.log('error', 'SQL语句执行失败', err);
1589
1502
  }
1503
+ return false;
1590
1504
  };
1591
1505
 
1592
1506
  /**
@@ -1681,25 +1595,20 @@ Sql.prototype._splitSqlStatements = function (sql_content) {
1681
1595
  * @private
1682
1596
  */
1683
1597
  Sql.prototype._getCreateTableSql = async function () {
1684
- try {
1685
- // 查询表结构信息(SQLite 使用 sqlite_master 表)
1686
- const sql = `SELECT sql FROM sqlite_master WHERE type='table' AND name='${this.table}'`;
1687
- const result = await this.run(sql);
1688
-
1689
- if (result && result.length > 0 && result[0].sql) {
1690
- // 在创建表语句中添加 IF NOT EXISTS 条件
1691
- let create_sql = result[0].sql;
1692
- if (create_sql.toUpperCase().startsWith('CREATE TABLE')) {
1693
- create_sql = create_sql.replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS');
1694
- }
1695
- return create_sql + ';';
1598
+ // 查询表结构信息(SQLite 使用 sqlite_master 表)
1599
+ const sql = `SELECT sql FROM sqlite_master WHERE type='table' AND name='${this.table}'`;
1600
+ const result = await this.run(sql);
1601
+
1602
+ if (result && result.length > 0 && result[0].sql) {
1603
+ // 在创建表语句中添加 IF NOT EXISTS 条件
1604
+ let create_sql = result[0].sql;
1605
+ if (create_sql.toUpperCase().startsWith('CREATE TABLE')) {
1606
+ create_sql = create_sql.replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS');
1696
1607
  }
1697
-
1698
- return '';
1699
- } catch (err) {
1700
- this.log('warn', '获取表结构失败,将仅备份数据', err);
1701
- return '';
1608
+ return create_sql + ';';
1702
1609
  }
1610
+
1611
+ return '';
1703
1612
  };
1704
1613
 
1705
1614
  /**
@@ -1717,54 +1626,48 @@ Sql.prototype.backup = async function (file, create = false) {
1717
1626
  throw new TypeError('表名未设置');
1718
1627
  }
1719
1628
 
1720
- try {
1721
- // 获取所有数据
1722
- const data = await this.getSql('', '', '*');
1629
+ // 获取所有数据
1630
+ const data = await this.getSql('', '', '*');
1723
1631
 
1724
- if (!data || !Array.isArray(data)) {
1725
- throw new Error('获取数据失败');
1726
- }
1632
+ if (!data || !Array.isArray(data)) {
1633
+ throw new Error('获取数据失败');
1634
+ }
1727
1635
 
1728
- // 构建 SQL 语句
1729
- let sql_content = '';
1636
+ // 构建 SQL 语句
1637
+ let sql_content = '';
1730
1638
 
1731
- // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
1732
- sql_content += `-- 备份表: ${this.table}\n`;
1733
- sql_content += `-- 备份时间: ${new Date().toISOString()}\n\n`;
1639
+ // 添加表结构(简化版,实际应用中可能需要更复杂的表结构导出)
1640
+ sql_content += `-- 备份表: ${this.table}\n`;
1641
+ sql_content += `-- 备份时间: ${new Date().toISOString()}\n\n`;
1734
1642
 
1735
- // 如果create为true,添加创建表语句
1736
- if (create) {
1737
- const create_table_sql = await this._getCreateTableSql();
1738
- if (create_table_sql) {
1739
- sql_content += create_table_sql + '\n\n';
1740
- }
1643
+ // 如果create为true,添加创建表语句
1644
+ if (create) {
1645
+ const create_table_sql = await this._getCreateTableSql();
1646
+ if (create_table_sql) {
1647
+ sql_content += create_table_sql + '\n\n';
1741
1648
  }
1649
+ }
1742
1650
 
1743
- // 添加数据插入语句
1744
- for (const row of data) {
1745
- const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
1746
- const values = Object.values(row).map(value => this.escape(value)).join(', ');
1747
- sql_content += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
1748
- }
1651
+ // 添加数据插入语句
1652
+ for (const row of data) {
1653
+ const keys = Object.keys(row).map(key => this.escapeId(key)).join(', ');
1654
+ const values = Object.values(row).map(value => this.escape(value)).join(', ');
1655
+ sql_content += `INSERT INTO \`${this.table}\` (${keys}) VALUES (${values});\n`;
1656
+ }
1749
1657
 
1750
- // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
1751
- const fs = require('fs');
1752
- const path = require('path');
1658
+ // 写入文件(这里需要文件系统模块,实际使用时需要引入 fs)
1659
+ const fs = require('fs');
1660
+ const path = require('path');
1753
1661
 
1754
- // 确保目录存在
1755
- const dir = path.dirname(file);
1756
- if (!fs.existsSync(dir)) {
1757
- fs.mkdirSync(dir, { recursive: true });
1758
- }
1662
+ // 确保目录存在
1663
+ const dir = path.dirname(file);
1664
+ if (!fs.existsSync(dir)) {
1665
+ fs.mkdirSync(dir, { recursive: true });
1666
+ }
1759
1667
 
1760
- fs.writeFileSync(file, sql_content, 'utf8');
1668
+ fs.writeFileSync(file, sql_content, 'utf8');
1761
1669
 
1762
- return true;
1763
- } catch (err) {
1764
- this.error = err.message;
1765
- this.log('error', '备份数据库失败', err);
1766
- return false;
1767
- }
1670
+ return true;
1768
1671
  };
1769
1672
 
1770
1673
  /**
@@ -1781,32 +1684,26 @@ Sql.prototype.restore = async function (file) {
1781
1684
  throw new TypeError('表名未设置');
1782
1685
  }
1783
1686
 
1784
- try {
1785
- const fs = require('fs');
1687
+ const fs = require('fs');
1786
1688
 
1787
- if (!fs.existsSync(file)) {
1788
- throw new Error('备份文件不存在');
1789
- }
1689
+ if (!fs.existsSync(file)) {
1690
+ throw new Error('备份文件不存在');
1691
+ }
1790
1692
 
1791
- // 读取 SQL 文件
1792
- const sql_content = fs.readFileSync(file, 'utf8');
1693
+ // 读取 SQL 文件
1694
+ const sql_content = fs.readFileSync(file, 'utf8');
1793
1695
 
1794
- // 解析 SQL 语句
1795
- const stmts = this._parseSqlStatements(sql_content);
1696
+ // 解析 SQL 语句
1697
+ const stmts = this._parseSqlStatements(sql_content);
1796
1698
 
1797
- // 执行每个 SQL 语句
1798
- for (const stmt of stmts) {
1799
- if (stmt.trim() && !stmt.startsWith('--')) {
1800
- await this.exec(stmt);
1801
- }
1699
+ // 执行每个 SQL 语句
1700
+ for (const stmt of stmts) {
1701
+ if (stmt.trim() && !stmt.startsWith('--')) {
1702
+ await this.exec(stmt);
1802
1703
  }
1803
-
1804
- return true;
1805
- } catch (err) {
1806
- this.error = err.message;
1807
- this.log('error', '恢复数据库失败', err);
1808
- return false;
1809
1704
  }
1705
+
1706
+ return true;
1810
1707
  };
1811
1708
 
1812
1709
  /**