mm_sqlite 1.1.3 → 1.1.4
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/LICENSE +21 -201
- package/README.md +52 -21
- package/db.js +37 -0
- package/index.js +28 -12
- package/package.json +2 -2
- package/config.json +0 -8
- package/db/db/test_db_methods.db.db +0 -0
- package/db/mm.db +0 -0
- package/test.js +0 -81
- package/test_all_methods.js +0 -115
- package/test_db_methods.js +0 -262
package/LICENSE
CHANGED
|
@@ -1,201 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
-
exercising permissions granted by this License.
|
|
25
|
-
|
|
26
|
-
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
-
including but not limited to software source code, documentation
|
|
28
|
-
source, and configuration files.
|
|
29
|
-
|
|
30
|
-
"Object" form shall mean any form resulting from mechanical
|
|
31
|
-
transformation or translation of a Source form, including but
|
|
32
|
-
not limited to compiled object code, generated documentation,
|
|
33
|
-
and conversions to other media types.
|
|
34
|
-
|
|
35
|
-
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
-
Object form, made available under the License, as indicated by a
|
|
37
|
-
copyright notice that is included in or attached to the work
|
|
38
|
-
(an example is provided in the Appendix below).
|
|
39
|
-
|
|
40
|
-
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
-
form, that is based on (or derived from) the Work and for which the
|
|
42
|
-
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
-
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
-
of this License, Derivative Works shall not include works that remain
|
|
45
|
-
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
-
the Work and Derivative Works thereof.
|
|
47
|
-
|
|
48
|
-
"Contribution" shall mean any work of authorship, including
|
|
49
|
-
the original version of the Work and any modifications or additions
|
|
50
|
-
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
-
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
-
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
-
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
-
means any form of electronic, verbal, or written communication sent
|
|
55
|
-
to the Licensor or its representatives, including but not limited to
|
|
56
|
-
communication on electronic mailing lists, source code control systems,
|
|
57
|
-
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
-
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
-
excluding communication that is conspicuously marked or otherwise
|
|
60
|
-
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
-
|
|
62
|
-
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
-
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
-
subsequently incorporated within the Work.
|
|
65
|
-
|
|
66
|
-
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
-
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
-
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
-
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
-
Work and such Derivative Works in Source or Object form.
|
|
72
|
-
|
|
73
|
-
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
-
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
-
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
-
(except as stated in this section) patent license to make, have made,
|
|
77
|
-
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
-
where such license applies only to those patent claims licensable
|
|
79
|
-
by such Contributor that are necessarily infringed by their
|
|
80
|
-
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
-
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
-
institute patent litigation against any entity (including a
|
|
83
|
-
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
-
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
-
or contributory patent infringement, then any patent licenses
|
|
86
|
-
granted to You under this License for that Work shall terminate
|
|
87
|
-
as of the date such litigation is filed.
|
|
88
|
-
|
|
89
|
-
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
-
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
-
modifications, and in Source or Object form, provided that You
|
|
92
|
-
meet the following conditions:
|
|
93
|
-
|
|
94
|
-
(a) You must give any other recipients of the Work or
|
|
95
|
-
Derivative Works a copy of this License; and
|
|
96
|
-
|
|
97
|
-
(b) You must cause any modified files to carry prominent notices
|
|
98
|
-
stating that You changed the files; and
|
|
99
|
-
|
|
100
|
-
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
-
that You distribute, all copyright, patent, trademark, and
|
|
102
|
-
attribution notices from the Source form of the Work,
|
|
103
|
-
excluding those notices that do not pertain to any part of
|
|
104
|
-
the Derivative Works; and
|
|
105
|
-
|
|
106
|
-
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
-
distribution, then any Derivative Works that You distribute must
|
|
108
|
-
include a readable copy of the attribution notices contained
|
|
109
|
-
within such NOTICE file, excluding those notices that do not
|
|
110
|
-
pertain to any part of the Derivative Works, in at least one
|
|
111
|
-
of the following places: within a NOTICE text file distributed
|
|
112
|
-
as part of the Derivative Works; within the Source form or
|
|
113
|
-
documentation, if provided along with the Derivative Works; or,
|
|
114
|
-
within a display generated by the Derivative Works, if and
|
|
115
|
-
wherever such third-party notices normally appear. The contents
|
|
116
|
-
of the NOTICE file are for informational purposes only and
|
|
117
|
-
do not modify the License. You may add Your own attribution
|
|
118
|
-
notices within Derivative Works that You distribute, alongside
|
|
119
|
-
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
-
that such additional attribution notices cannot be construed
|
|
121
|
-
as modifying the License.
|
|
122
|
-
|
|
123
|
-
You may add Your own copyright statement to Your modifications and
|
|
124
|
-
may provide additional or different license terms and conditions
|
|
125
|
-
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
-
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
-
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
-
the conditions stated in this License.
|
|
129
|
-
|
|
130
|
-
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
-
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
-
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
-
this License, without any additional terms or conditions.
|
|
134
|
-
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
-
the terms of any separate license agreement you may have executed
|
|
136
|
-
with Licensor regarding such Contributions.
|
|
137
|
-
|
|
138
|
-
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
-
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
-
except as required for reasonable and customary use in describing the
|
|
141
|
-
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
-
|
|
143
|
-
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
-
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
-
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
-
implied, including, without limitation, any warranties or conditions
|
|
148
|
-
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
-
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
-
appropriateness of using or redistributing the Work and assume any
|
|
151
|
-
risks associated with Your exercise of permissions under this License.
|
|
152
|
-
|
|
153
|
-
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
-
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
-
unless required by applicable law (such as deliberate and grossly
|
|
156
|
-
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
-
liable to You for damages, including any direct, indirect, special,
|
|
158
|
-
incidental, or consequential damages of any character arising as a
|
|
159
|
-
result of this License or out of the use or inability to use the
|
|
160
|
-
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
-
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
-
other commercial damages or losses), even if such Contributor
|
|
163
|
-
has been advised of the possibility of such damages.
|
|
164
|
-
|
|
165
|
-
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
-
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
-
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
-
or other liability obligations and/or rights consistent with this
|
|
169
|
-
License. However, in accepting such obligations, You may act only
|
|
170
|
-
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
-
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
-
defend, and hold each Contributor harmless for any liability
|
|
173
|
-
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
-
of your accepting any such warranty or additional liability.
|
|
175
|
-
|
|
176
|
-
END OF TERMS AND CONDITIONS
|
|
177
|
-
|
|
178
|
-
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
-
|
|
180
|
-
To apply the Apache License to your work, attach the following
|
|
181
|
-
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
-
replaced with your own identifying information. (Don't include
|
|
183
|
-
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
-
comment syntax for the file format. We also recommend that a
|
|
185
|
-
file or class name and description of purpose be included on the
|
|
186
|
-
same "printed page" as the copyright notice for easier
|
|
187
|
-
identification within third-party archives.
|
|
188
|
-
|
|
189
|
-
Copyright [yyyy] [name of copyright owner]
|
|
190
|
-
|
|
191
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
-
you may not use this file except in compliance with the License.
|
|
193
|
-
You may obtain a copy of the License at
|
|
194
|
-
|
|
195
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
-
|
|
197
|
-
Unless required by applicable law or agreed to in writing, software
|
|
198
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
-
See the License for the specific language governing permissions and
|
|
201
|
-
limitations under the License.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 邱文武
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
高性能SQLite数据库操作模块,提供与mm_mysql完全兼容的API接口。适用于Node.js应用的轻量级数据存储解决方案。
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/mm_sqlite)
|
|
6
|
+
[](https://www.npmjs.com/package/mm_sqlite)
|
|
7
|
+
[](https://nodejs.org/en/)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
5
10
|
## 特性
|
|
6
11
|
|
|
7
12
|
- 🚀 **高性能优化**:经过深度优化的SQL构建器和连接管理
|
|
@@ -13,18 +18,21 @@
|
|
|
13
18
|
|
|
14
19
|
## 安装
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
### 使用 npm
|
|
18
22
|
```bash
|
|
19
23
|
npm install mm_sqlite --save
|
|
20
24
|
```
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
### 使用 yarn
|
|
24
27
|
```bash
|
|
25
28
|
yarn add mm_sqlite
|
|
26
29
|
```
|
|
27
30
|
|
|
31
|
+
### 使用 pnpm
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add mm_sqlite
|
|
34
|
+
```
|
|
35
|
+
|
|
28
36
|
## 依赖要求
|
|
29
37
|
|
|
30
38
|
- Node.js 14.0+
|
|
@@ -41,11 +49,12 @@ const { Sqlite } = require('mm_sqlite');
|
|
|
41
49
|
|
|
42
50
|
// 创建数据库实例
|
|
43
51
|
const sqlite = new Sqlite({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
dir: './db/', // 数据库文件存储目录
|
|
53
|
+
database: 'test', // 数据库文件名(不包含扩展名)
|
|
54
|
+
timeout: 30000, // 查询超时时间(毫秒)
|
|
55
|
+
retry_count: 3, // 失败重试次数
|
|
56
|
+
conn_timeout: 30000, // 连接超时时间(毫秒)
|
|
57
|
+
enablePerformanceLog: false // 是否启用性能日志
|
|
49
58
|
});
|
|
50
59
|
|
|
51
60
|
// 打开数据库连接
|
|
@@ -165,14 +174,14 @@ await sqlite.beginTransaction();
|
|
|
165
174
|
|
|
166
175
|
try {
|
|
167
176
|
// 插入数据
|
|
168
|
-
await sqlite.table('users').
|
|
177
|
+
await sqlite.table('users').add({
|
|
169
178
|
name: '张三',
|
|
170
179
|
email: 'zhangsan@example.com',
|
|
171
180
|
status: 'active'
|
|
172
181
|
});
|
|
173
182
|
|
|
174
|
-
//
|
|
175
|
-
await sqlite.table('profiles').
|
|
183
|
+
// 插入关联数据
|
|
184
|
+
await sqlite.table('profiles').add({
|
|
176
185
|
user_id: 1,
|
|
177
186
|
bio: '这是一个测试用户'
|
|
178
187
|
});
|
|
@@ -242,21 +251,27 @@ const users = await sqlite
|
|
|
242
251
|
new Sqlite(config)
|
|
243
252
|
```
|
|
244
253
|
|
|
245
|
-
|
|
246
|
-
- `config.
|
|
254
|
+
**配置参数:**
|
|
255
|
+
- `config.dir` - 数据库文件存储目录,默认为`'./db/'`
|
|
256
|
+
- `config.database` - 数据库文件名,默认为`'mm'`
|
|
247
257
|
- `config.timeout` - 查询超时时间,默认`30000ms`
|
|
248
258
|
- `config.retry_count` - 失败重试次数,默认`3`
|
|
249
259
|
- `config.conn_timeout` - 连接超时时间,默认`30000ms`
|
|
250
|
-
- `config.enablePerformanceLog` -
|
|
260
|
+
- `config.enablePerformanceLog` - 是否启用性能日志,默认`false`
|
|
261
|
+
- `config.debug` - 是否启用调试模式,默认`false`
|
|
251
262
|
|
|
252
263
|
#### 主要方法
|
|
253
264
|
|
|
254
|
-
- `
|
|
255
|
-
- `
|
|
256
|
-
- `
|
|
257
|
-
- `
|
|
258
|
-
- `
|
|
259
|
-
- `
|
|
265
|
+
- `open(timeout)` - 打开数据库连接,返回`Promise<Boolean>`
|
|
266
|
+
- `close()` - 关闭数据库连接,返回`Promise<Boolean>`
|
|
267
|
+
- `getConn(timeout)` - 获取数据库连接,返回`Promise<Connection>`
|
|
268
|
+
- `run(sql, params, timeout)` - 执行SQL语句(非查询操作),返回`Promise<Object>`
|
|
269
|
+
- `exec(sql, params, timeout)` - 执行SQL查询,返回`Promise<Array>`
|
|
270
|
+
- `beginTransaction()` - 开始事务,返回`Promise<void>`
|
|
271
|
+
- `commit()` - 提交事务,返回`Promise<void>`
|
|
272
|
+
- `rollback()` - 回滚事务,返回`Promise<void>`
|
|
273
|
+
- `transaction(fn)` - 执行事务,返回`Promise<any>`
|
|
274
|
+
- `table(tableName)` - 设置表名,返回`Sql`实例
|
|
260
275
|
|
|
261
276
|
### Sql类
|
|
262
277
|
|
|
@@ -339,6 +354,12 @@ A: 可以使用相对路径或绝对路径。建议使用绝对路径以避免
|
|
|
339
354
|
**Q: 事务处理是否支持嵌套?**
|
|
340
355
|
A: 目前不支持嵌套事务,但可以在一个事务中执行多个操作。
|
|
341
356
|
|
|
357
|
+
**Q: 如何启用调试模式?**
|
|
358
|
+
A: 在创建Sqlite实例时,设置`debug: true`配置项即可启用调试模式。
|
|
359
|
+
|
|
360
|
+
**Q: 如何处理SQLite的锁问题?**
|
|
361
|
+
A: 避免长时间运行的事务,使用适当的事务隔离级别,并确保在操作完成后及时提交或回滚事务。
|
|
362
|
+
|
|
342
363
|
## 许可证
|
|
343
364
|
|
|
344
365
|
MIT License
|
|
@@ -350,3 +371,13 @@ MIT License
|
|
|
350
371
|
1. 运行测试确保功能正常
|
|
351
372
|
2. 添加适当的注释和文档
|
|
352
373
|
3. 遵循项目的代码风格
|
|
374
|
+
4. 确保代码符合ES6+标准
|
|
375
|
+
5. 提交前请先拉取最新代码,解决冲突
|
|
376
|
+
|
|
377
|
+
### 开发流程
|
|
378
|
+
|
|
379
|
+
1. Fork 仓库
|
|
380
|
+
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
|
|
381
|
+
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
|
382
|
+
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
383
|
+
5. 打开 Pull Request
|
package/db.js
CHANGED
|
@@ -896,4 +896,41 @@ DB.prototype.backup = function(table, backup, timeout = 60000) {
|
|
|
896
896
|
}
|
|
897
897
|
};
|
|
898
898
|
|
|
899
|
+
/**
|
|
900
|
+
* @description 创建表
|
|
901
|
+
* @param {String} table 表名
|
|
902
|
+
* @param {Object} model 表模型,键值对,根据值类型创建字段类型,根据键名创建字段名
|
|
903
|
+
* @param {String} key 主键
|
|
904
|
+
* @return {Promise|Number} 操作结果
|
|
905
|
+
*/
|
|
906
|
+
DB.prototype.createTable = function(table, model, key = 'id', timeout = 15000){
|
|
907
|
+
if (!table || !model || !model.fields) {
|
|
908
|
+
$.log.error("[DB] [createTable] 参数不完整");
|
|
909
|
+
return 0;
|
|
910
|
+
}
|
|
911
|
+
var fields = '';
|
|
912
|
+
for (const field in model.fields) {
|
|
913
|
+
const value = model.fields[field];
|
|
914
|
+
let type = '';
|
|
915
|
+
if (field === key) {
|
|
916
|
+
type = 'INTEGER PRIMARY KEY AUTOINCREMENT';
|
|
917
|
+
} else if (typeof value === 'number') {
|
|
918
|
+
if (value % 1 === 0) {
|
|
919
|
+
type = 'INTEGER';
|
|
920
|
+
} else {
|
|
921
|
+
type = 'REAL';
|
|
922
|
+
}
|
|
923
|
+
} else if (typeof value === 'string') {
|
|
924
|
+
type = 'TEXT';
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
type = 'BLOB';
|
|
928
|
+
}
|
|
929
|
+
fields += `\`${field}\` ${type}, `;
|
|
930
|
+
}
|
|
931
|
+
fields = fields.slice(0, -2);
|
|
932
|
+
var sql = `CREATE TABLE IF NOT EXISTS \`${table}\` (${fields});`;
|
|
933
|
+
return this.exec(sql, [], timeout);
|
|
934
|
+
}
|
|
935
|
+
|
|
899
936
|
module.exports = DB;
|
package/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const sqlite3 = require('sqlite3').verbose();
|
|
2
2
|
const DB = require('./db');
|
|
3
3
|
const { BaseService } = require('mm_base_service');
|
|
4
|
-
|
|
5
4
|
/**
|
|
6
5
|
* SQLite数据库操作类
|
|
7
6
|
* @class Sqlite
|
|
@@ -12,7 +11,7 @@ class Sqlite extends BaseService {
|
|
|
12
11
|
* 默认配置
|
|
13
12
|
*/
|
|
14
13
|
static default_config = {
|
|
15
|
-
dir: "
|
|
14
|
+
dir: "./db/".fullname(),
|
|
16
15
|
user: "root",
|
|
17
16
|
password: "",
|
|
18
17
|
database: "mm",
|
|
@@ -136,19 +135,16 @@ Sqlite.prototype.open = async function (timeout) {
|
|
|
136
135
|
Sqlite.prototype._openInternal = function () {
|
|
137
136
|
return new Promise((resolve, reject) => {
|
|
138
137
|
try {
|
|
139
|
-
const fs = require('fs');
|
|
140
|
-
const path = require('path');
|
|
141
138
|
|
|
142
139
|
// 确保数据库目录存在
|
|
143
|
-
const
|
|
144
|
-
const dir = path.dirname(db_path);
|
|
140
|
+
const file = this._getDatabasePath();
|
|
145
141
|
|
|
146
|
-
if (!
|
|
147
|
-
|
|
142
|
+
if (!file.hasDir()) {
|
|
143
|
+
file.addDir();
|
|
148
144
|
}
|
|
149
145
|
|
|
150
146
|
// 创建数据库连接
|
|
151
|
-
this._db = new sqlite3.Database(
|
|
147
|
+
this._db = new sqlite3.Database(file);
|
|
152
148
|
this._open = true;
|
|
153
149
|
this._conn_retry_count = 0;
|
|
154
150
|
|
|
@@ -158,7 +154,7 @@ Sqlite.prototype._openInternal = function () {
|
|
|
158
154
|
this._handleConnectionError(err);
|
|
159
155
|
});
|
|
160
156
|
|
|
161
|
-
$.log.debug(`SQLite数据库已打开: ${
|
|
157
|
+
$.log.debug(`SQLite数据库已打开: ${file}`);
|
|
162
158
|
resolve();
|
|
163
159
|
} catch (error) {
|
|
164
160
|
reject(error);
|
|
@@ -173,8 +169,11 @@ Sqlite.prototype._openInternal = function () {
|
|
|
173
169
|
*/
|
|
174
170
|
Sqlite.prototype._getDatabasePath = function () {
|
|
175
171
|
const db_name = this.config.database || 'mm';
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
if (db_name.endsWith('.db')) {
|
|
173
|
+
db_name = db_name.replace('.db', '');
|
|
174
|
+
}
|
|
175
|
+
const db_dir = this.config.dir || '/db/'.fullname();
|
|
176
|
+
return `./${db_name}.db`.fullname(db_dir);
|
|
178
177
|
};
|
|
179
178
|
|
|
180
179
|
/**
|
|
@@ -674,6 +673,23 @@ Sqlite.prototype.transaction = async function (callback) {
|
|
|
674
673
|
}
|
|
675
674
|
};
|
|
676
675
|
|
|
676
|
+
/**
|
|
677
|
+
* 设置当前操作的表名
|
|
678
|
+
* @param {String} name - 表名
|
|
679
|
+
* @param {String} key - 主键
|
|
680
|
+
* @returns {Object} 数据库操作实例
|
|
681
|
+
*/
|
|
682
|
+
Sqlite.prototype.table = function (name, key) {
|
|
683
|
+
var db = this.db();
|
|
684
|
+
db.table = name;
|
|
685
|
+
if (key) {
|
|
686
|
+
db.key = key;
|
|
687
|
+
}
|
|
688
|
+
return db;
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
// close 方法已在文件前面部分实现,这里不再重复
|
|
692
|
+
|
|
677
693
|
/**
|
|
678
694
|
* 确保连接池对象存在
|
|
679
695
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_sqlite",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "高性能SQLite数据库操作模块,提供与mm_mysql完全兼容的API接口,支持异步操作、事务处理和批量操作",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"node": ">=14.0.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"
|
|
39
|
+
"mm_base_service": "^1.0.2",
|
|
40
40
|
"sqlite3": "^5.1.7",
|
|
41
41
|
"sqlstring": "^2.3.3"
|
|
42
42
|
}
|
package/config.json
DELETED
|
Binary file
|
package/db/mm.db
DELETED
|
Binary file
|
package/test.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
const Sqlite = require('./index.js').Sqlite;
|
|
2
|
-
|
|
3
|
-
// 全面测试函数
|
|
4
|
-
async function runAllTests() {
|
|
5
|
-
$.log.info('开始全面测试mm_sqlite模块...');
|
|
6
|
-
var sql = new Sqlite();
|
|
7
|
-
await sql.open();
|
|
8
|
-
|
|
9
|
-
var test_table = 'test_mm_sqlite';
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
// 1. 测试表创建
|
|
13
|
-
$.log.info('1. 测试表创建...');
|
|
14
|
-
let create_sql = `CREATE TABLE IF NOT EXISTS ${test_table} (
|
|
15
|
-
uid INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
16
|
-
username VARCHAR(50) NOT NULL,
|
|
17
|
-
age INTEGER DEFAULT 0,
|
|
18
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
19
|
-
)`;
|
|
20
|
-
let create_result = await sql.run(create_sql);
|
|
21
|
-
$.log.info('表创建结果:', create_result);
|
|
22
|
-
|
|
23
|
-
// 2. 测试数据插入
|
|
24
|
-
$.log.info('2. 测试数据插入...');
|
|
25
|
-
let insert_sql = `INSERT INTO ${test_table} (username, age) VALUES (?, ?)`;
|
|
26
|
-
let insert_result = await sql.run(insert_sql, ['test_user_1', 25]);
|
|
27
|
-
$.log.info('插入结果:', insert_result);
|
|
28
|
-
|
|
29
|
-
// 3. 测试查询 - 使用exec方法并安全处理返回结果
|
|
30
|
-
$.log.info('3. 测试查询...');
|
|
31
|
-
let query_sql = `SELECT * FROM ${test_table}`;
|
|
32
|
-
let query_result = await sql.exec(query_sql);
|
|
33
|
-
$.log.info('查询结果类型:', typeof query_result);
|
|
34
|
-
$.log.info('查询结果:', query_result);
|
|
35
|
-
|
|
36
|
-
// 4. 测试更新
|
|
37
|
-
$.log.info('4. 测试更新...');
|
|
38
|
-
let update_sql = `UPDATE ${test_table} SET age = ? WHERE username = ?`;
|
|
39
|
-
let update_result = await sql.run(update_sql, [26, 'test_user_1']);
|
|
40
|
-
$.log.info('更新结果:', update_result);
|
|
41
|
-
|
|
42
|
-
// 5. 测试删除
|
|
43
|
-
$.log.info('5. 测试删除...');
|
|
44
|
-
let delete_sql = `DELETE FROM ${test_table} WHERE username = ?`;
|
|
45
|
-
let delete_result = await sql.run(delete_sql, ['test_user_1']);
|
|
46
|
-
$.log.info('删除结果:', delete_result);
|
|
47
|
-
|
|
48
|
-
// 6. 测试事务
|
|
49
|
-
$.log.info('6. 测试事务...');
|
|
50
|
-
let transaction_result = await sql.transaction(async () => {
|
|
51
|
-
await sql.run(`INSERT INTO ${test_table} (username, age) VALUES (?, ?)`, ['transaction_user', 40]);
|
|
52
|
-
return await sql.run(`DELETE FROM ${test_table} WHERE username = ?`, ['transaction_user']);
|
|
53
|
-
});
|
|
54
|
-
$.log.info('事务结果:', transaction_result);
|
|
55
|
-
|
|
56
|
-
// 7. 测试表列表 - 安全处理exec返回结果
|
|
57
|
-
$.log.info('7. 测试表列表...');
|
|
58
|
-
let tables_sql = `SELECT name FROM sqlite_master WHERE type='table'`;
|
|
59
|
-
let tables_result = await sql.exec(tables_sql);
|
|
60
|
-
$.log.info('表列表类型:', typeof tables_result);
|
|
61
|
-
$.log.info('表列表:', tables_result);
|
|
62
|
-
|
|
63
|
-
// 8. 清理测试表
|
|
64
|
-
$.log.info('8. 清理测试表...');
|
|
65
|
-
let drop_result = await sql.run(`DROP TABLE IF EXISTS ${test_table}`);
|
|
66
|
-
$.log.info('删除表结果:', drop_result);
|
|
67
|
-
|
|
68
|
-
$.log.info('所有测试完成!mm_sqlite模块功能正常。');
|
|
69
|
-
return true;
|
|
70
|
-
} catch (error) {
|
|
71
|
-
$.log.error('测试过程中发生错误:', error);
|
|
72
|
-
return false;
|
|
73
|
-
} finally {
|
|
74
|
-
await sql.close();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// 运行测试
|
|
79
|
-
(async function() {
|
|
80
|
-
await runAllTests();
|
|
81
|
-
})();
|
package/test_all_methods.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
// 核心方法测试脚本 - 专注测试del、delList等关键方法
|
|
2
|
-
const { Sqlite } = require('./index');
|
|
3
|
-
|
|
4
|
-
async function testAllMethods() {
|
|
5
|
-
try {
|
|
6
|
-
console.log('=== 开始测试 SQLite 模块核心方法 ===');
|
|
7
|
-
|
|
8
|
-
// 初始化SQLite实例
|
|
9
|
-
const sql = new Sqlite({
|
|
10
|
-
database: './db/test_core_methods.db'
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
await sql.open();
|
|
14
|
-
console.log('数据库连接成功');
|
|
15
|
-
|
|
16
|
-
// 获取数据库操作实例
|
|
17
|
-
const db = sql.db();
|
|
18
|
-
const test_table = 'test_core_methods';
|
|
19
|
-
|
|
20
|
-
// 准备测试表
|
|
21
|
-
console.log('\n=== 1. 准备测试环境 ===');
|
|
22
|
-
await db.exec(`DROP TABLE IF EXISTS ${test_table};`);
|
|
23
|
-
await db.exec(`CREATE TABLE IF NOT EXISTS ${test_table} (
|
|
24
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
25
|
-
username VARCHAR(50) NOT NULL,
|
|
26
|
-
email VARCHAR(100),
|
|
27
|
-
age INTEGER DEFAULT 0 NOT NULL
|
|
28
|
-
);`);
|
|
29
|
-
console.log('测试表创建完成');
|
|
30
|
-
|
|
31
|
-
db.table = test_table;
|
|
32
|
-
|
|
33
|
-
// 2. 单条数据操作测试
|
|
34
|
-
console.log('\n=== 2. 单条数据操作测试 ===');
|
|
35
|
-
// 添加单条数据
|
|
36
|
-
const addResult = await db.add({
|
|
37
|
-
username: 'test_user1',
|
|
38
|
-
email: 'test1@example.com',
|
|
39
|
-
age: 25
|
|
40
|
-
});
|
|
41
|
-
console.log('✓ add方法测试通过:', addResult);
|
|
42
|
-
|
|
43
|
-
// 查询单条数据
|
|
44
|
-
const getResult = await db.get({ username: 'test_user1' });
|
|
45
|
-
console.log('✓ get方法测试通过,数据:', getResult[0]?.username);
|
|
46
|
-
|
|
47
|
-
// 修改数据
|
|
48
|
-
const setResult = await db.set(
|
|
49
|
-
{ username: 'test_user1' },
|
|
50
|
-
{ age: 26 }
|
|
51
|
-
);
|
|
52
|
-
console.log('✓ set方法测试通过:', setResult);
|
|
53
|
-
|
|
54
|
-
// 3. 批量操作测试 - 重点测试addList
|
|
55
|
-
console.log('\n=== 3. 批量添加测试 ===');
|
|
56
|
-
const batchData = [
|
|
57
|
-
{ username: 'batch_user1', email: 'batch1@example.com', age: 30 },
|
|
58
|
-
{ username: 'batch_user2', email: 'batch2@example.com', age: 31 },
|
|
59
|
-
{ username: 'batch_user3', email: 'batch3@example.com', age: 32 }
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const addListResult = await db.addList(batchData);
|
|
63
|
-
console.log('✓ addList方法测试通过:', addListResult);
|
|
64
|
-
|
|
65
|
-
// 4. 单条删除测试 - 重点测试del
|
|
66
|
-
console.log('\n=== 4. 单条删除测试 ===');
|
|
67
|
-
const delResult = await db.del({ username: 'test_user1' });
|
|
68
|
-
console.log('✓ del方法测试通过:', delResult);
|
|
69
|
-
|
|
70
|
-
// 验证删除结果
|
|
71
|
-
const delCheck = await db.get({ username: 'test_user1' });
|
|
72
|
-
console.log(' del方法验证结果: 删除成功', delCheck.length === 0);
|
|
73
|
-
|
|
74
|
-
// 5. 批量删除测试 - 重点测试delList
|
|
75
|
-
console.log('\n=== 5. 批量删除测试 ===');
|
|
76
|
-
const deleteList = [
|
|
77
|
-
{ query: { username: 'batch_user1' } },
|
|
78
|
-
{ query: { username: 'batch_user2' } }
|
|
79
|
-
];
|
|
80
|
-
|
|
81
|
-
const delListResult = await db.delList(deleteList);
|
|
82
|
-
console.log('✓ delList方法测试通过:', delListResult);
|
|
83
|
-
|
|
84
|
-
// 验证批量删除结果
|
|
85
|
-
const batch1Check = await db.get({ username: 'batch_user1' });
|
|
86
|
-
const batch2Check = await db.get({ username: 'batch_user2' });
|
|
87
|
-
console.log(' delList方法验证结果: 批量删除成功',
|
|
88
|
-
batch1Check.length === 0 && batch2Check.length === 0);
|
|
89
|
-
|
|
90
|
-
// 验证剩余数据
|
|
91
|
-
const remainingData = await db.get({});
|
|
92
|
-
console.log(' 剩余数据数量:', remainingData.length);
|
|
93
|
-
|
|
94
|
-
// 6. 清理测试数据
|
|
95
|
-
console.log('\n=== 6. 清理测试环境 ===');
|
|
96
|
-
await db.exec(`DROP TABLE IF EXISTS ${test_table};`);
|
|
97
|
-
console.log('测试表清理完成');
|
|
98
|
-
|
|
99
|
-
// 关闭数据库连接
|
|
100
|
-
await sql.close();
|
|
101
|
-
console.log('\n=== 核心方法测试完成!===');
|
|
102
|
-
console.log('✓ del方法工作正常');
|
|
103
|
-
console.log('✓ delList方法工作正常');
|
|
104
|
-
console.log('✓ 其他核心方法(add, get, set, addList)工作正常');
|
|
105
|
-
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error('测试过程中出现错误:', error.message);
|
|
108
|
-
console.error('错误堆栈:', error.stack);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// 执行测试
|
|
113
|
-
(async () => {
|
|
114
|
-
await testAllMethods();
|
|
115
|
-
})();
|
package/test_db_methods.js
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
// 测试db.js中的所有方法
|
|
2
|
-
const { Sqlite } = require('./index');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
async function testDbMethods() {
|
|
6
|
-
let sql;
|
|
7
|
-
try {
|
|
8
|
-
console.log('=== 开始测试 mm_sqlite/db.js 中的方法 ===\n');
|
|
9
|
-
|
|
10
|
-
// 初始化SQLite实例
|
|
11
|
-
sql = new Sqlite({
|
|
12
|
-
database: './db/test_db_methods.db'
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
await sql.open();
|
|
16
|
-
console.log('✓ 数据库连接成功');
|
|
17
|
-
|
|
18
|
-
// 获取数据库操作实例
|
|
19
|
-
const db = sql.db();
|
|
20
|
-
const test_table = 'test_db_methods';
|
|
21
|
-
const backup_table = 'test_db_methods_backup';
|
|
22
|
-
|
|
23
|
-
// 清理测试环境
|
|
24
|
-
console.log('\n=== 1. 清理测试环境 ===');
|
|
25
|
-
await db.dropTable(test_table);
|
|
26
|
-
await db.dropTable(backup_table);
|
|
27
|
-
console.log('✓ 测试环境清理完成');
|
|
28
|
-
|
|
29
|
-
// 2. 测试表操作方法
|
|
30
|
-
console.log('\n=== 2. 测试表操作方法 ===');
|
|
31
|
-
|
|
32
|
-
// 测试addTable
|
|
33
|
-
console.log('测试addTable()方法...');
|
|
34
|
-
const createResult = await db.addTable(test_table, 'id', 'int', true, '测试表');
|
|
35
|
-
console.log('✓ 表创建结果:', createResult);
|
|
36
|
-
|
|
37
|
-
// 测试hasTable
|
|
38
|
-
console.log('测试hasTable()方法...');
|
|
39
|
-
const hasTableResult = await db.hasTable(test_table);
|
|
40
|
-
console.log('✓ 表是否存在:', hasTableResult);
|
|
41
|
-
|
|
42
|
-
// 测试tables
|
|
43
|
-
console.log('测试tables()方法...');
|
|
44
|
-
const tablesResult = await db.tables();
|
|
45
|
-
console.log('✓ 表列表:', tablesResult);
|
|
46
|
-
|
|
47
|
-
// 3. 测试字段操作方法
|
|
48
|
-
console.log('\n=== 3. 测试字段操作方法 ===');
|
|
49
|
-
|
|
50
|
-
// 设置表名
|
|
51
|
-
db.table = test_table;
|
|
52
|
-
|
|
53
|
-
// 测试addField
|
|
54
|
-
console.log('测试addField()方法...');
|
|
55
|
-
const addFieldResult1 = await db.addField('username', 'varchar', '', true, false, '用户名');
|
|
56
|
-
console.log('✓ 添加username字段结果:', addFieldResult1);
|
|
57
|
-
|
|
58
|
-
// 测试addField(添加email字段)
|
|
59
|
-
console.log('测试addField()方法(添加email字段)...');
|
|
60
|
-
const addFieldResult2 = await db.addField('email', 'varchar', '', true, false, '邮箱');
|
|
61
|
-
console.log('✓ 添加email字段结果:', addFieldResult2);
|
|
62
|
-
|
|
63
|
-
// 测试addField(添加age字段)
|
|
64
|
-
console.log('测试addField()方法(添加age字段)...');
|
|
65
|
-
const addFieldResult3 = await db.addField('age', 'int', 0, true, false, '年龄');
|
|
66
|
-
console.log('✓ 添加age字段结果:', addFieldResult3);
|
|
67
|
-
|
|
68
|
-
// 测试setField
|
|
69
|
-
console.log('测试setField()方法...');
|
|
70
|
-
const setFieldResult = await db.setField('email', 'varchar', '', true, false, '电子邮箱');
|
|
71
|
-
console.log('✓ 修改email字段结果:', setFieldResult);
|
|
72
|
-
|
|
73
|
-
// 测试addField(添加temp字段用于后续delField测试)
|
|
74
|
-
console.log('测试addField()方法(添加temp字段)...');
|
|
75
|
-
await db.addField('temp', 'int', 0, false, false, '临时字段');
|
|
76
|
-
console.log('✓ 添加temp字段结果: 成功');
|
|
77
|
-
|
|
78
|
-
// 测试fields
|
|
79
|
-
console.log('测试fields()方法...');
|
|
80
|
-
const fieldsResult = await db.fields();
|
|
81
|
-
console.log('✓ 字段信息:', fieldsResult.map(f => f.name));
|
|
82
|
-
|
|
83
|
-
// 测试hasField
|
|
84
|
-
console.log('测试hasField()方法...');
|
|
85
|
-
const hasFieldResult = await db.hasField(test_table, 'username');
|
|
86
|
-
console.log('✓ username字段是否存在:', hasFieldResult);
|
|
87
|
-
|
|
88
|
-
// 测试delField
|
|
89
|
-
console.log('测试delField()方法...');
|
|
90
|
-
const delFieldResult = await db.delField(test_table, 'temp');
|
|
91
|
-
console.log('✓ 删除temp字段结果:', delFieldResult);
|
|
92
|
-
|
|
93
|
-
// 测试renameField
|
|
94
|
-
console.log('测试renameField()方法...');
|
|
95
|
-
try {
|
|
96
|
-
// 先检查当前字段
|
|
97
|
-
const fieldsBefore = await db.fields();
|
|
98
|
-
console.log(' - 重命名前字段:', fieldsBefore.map(f => f.name));
|
|
99
|
-
|
|
100
|
-
const renameFieldResult = await db.renameField(test_table, 'age', 'user_age');
|
|
101
|
-
console.log(' - 重命名age字段结果:', renameFieldResult);
|
|
102
|
-
|
|
103
|
-
// 检查重命名后字段
|
|
104
|
-
const fieldsAfter = await db.fields();
|
|
105
|
-
console.log(' - 重命名后字段:', fieldsAfter.map(f => f.name));
|
|
106
|
-
|
|
107
|
-
// 只有当user_age字段存在时,才尝试重命名回age字段
|
|
108
|
-
const hasUserAgeField = fieldsAfter.some(f => f.name === 'user_age');
|
|
109
|
-
if (hasUserAgeField) {
|
|
110
|
-
// 重命名回age字段,保持后续测试一致
|
|
111
|
-
await db.renameField(test_table, 'user_age', 'age');
|
|
112
|
-
console.log(' - 重命名user_age字段回age结果: 成功');
|
|
113
|
-
|
|
114
|
-
// 再次检查字段
|
|
115
|
-
const fieldsFinal = await db.fields();
|
|
116
|
-
console.log(' - 最终字段:', fieldsFinal.map(f => f.name));
|
|
117
|
-
} else {
|
|
118
|
-
console.warn(' - user_age字段不存在,跳过重命名回age字段');
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
console.log('✓ renameField方法测试完成');
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.warn('⚠️ renameField()方法测试失败:', error.message);
|
|
124
|
-
console.log('⚠️ renameField()方法测试跳过');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// 4. 测试数据操作方法
|
|
128
|
-
console.log('\n=== 4. 测试数据操作方法 ===');
|
|
129
|
-
|
|
130
|
-
// 测试add(插入数据)
|
|
131
|
-
console.log('测试add()方法...');
|
|
132
|
-
const addResult = await db.add({
|
|
133
|
-
username: 'test_user',
|
|
134
|
-
email: 'test@example.com',
|
|
135
|
-
age: 25
|
|
136
|
-
});
|
|
137
|
-
console.log('✓ 插入数据结果:', addResult);
|
|
138
|
-
|
|
139
|
-
// 测试get(查询单条数据)
|
|
140
|
-
console.log('测试get()方法...');
|
|
141
|
-
const getResult = await db.get({ id: 1 });
|
|
142
|
-
console.log('✓ 查询单条数据结果:', getResult[0]);
|
|
143
|
-
|
|
144
|
-
// 测试get(查询多条数据)
|
|
145
|
-
console.log('测试get()方法(查询多条数据)...');
|
|
146
|
-
const listResult = await db.get();
|
|
147
|
-
console.log('✓ 查询多条数据结果:', listResult.length);
|
|
148
|
-
|
|
149
|
-
// 测试set(更新数据)
|
|
150
|
-
console.log('测试set()方法...');
|
|
151
|
-
const setResult = await db.set({ id: 1 }, { age: 26 });
|
|
152
|
-
console.log('✓ 更新数据结果:', setResult);
|
|
153
|
-
|
|
154
|
-
// 测试set(另一种查询条件更新方式)
|
|
155
|
-
console.log('测试set()方法(使用where属性)...');
|
|
156
|
-
db.where = { id: 1 };
|
|
157
|
-
const setResult2 = await db.set(db.where, { age: 27 });
|
|
158
|
-
console.log('✓ set方法(使用where属性)更新结果:', setResult2);
|
|
159
|
-
|
|
160
|
-
// 测试del(删除数据)
|
|
161
|
-
console.log('测试del()方法...');
|
|
162
|
-
const delResult = await db.del({ id: 1 });
|
|
163
|
-
console.log('✓ 删除数据结果:', delResult);
|
|
164
|
-
|
|
165
|
-
// 5. 测试事务操作方法
|
|
166
|
-
console.log('\n=== 5. 测试事务操作方法 ===');
|
|
167
|
-
|
|
168
|
-
// 重新插入一条数据用于事务测试
|
|
169
|
-
await db.add({
|
|
170
|
-
username: 'transaction_test',
|
|
171
|
-
email: 'transaction@example.com',
|
|
172
|
-
age: 30
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
// 测试start(开始事务)
|
|
177
|
-
console.log(' - 事务开始');
|
|
178
|
-
await db.start();
|
|
179
|
-
|
|
180
|
-
// 在事务中插入数据
|
|
181
|
-
await db.add({
|
|
182
|
-
username: 'transaction_user',
|
|
183
|
-
email: 'user@example.com',
|
|
184
|
-
age: 35
|
|
185
|
-
});
|
|
186
|
-
console.log(' - 事务中插入数据成功');
|
|
187
|
-
|
|
188
|
-
// 测试commit(提交事务)
|
|
189
|
-
await db.commit();
|
|
190
|
-
console.log(' - 事务提交成功');
|
|
191
|
-
|
|
192
|
-
// 验证事务提交结果
|
|
193
|
-
const transactionResult = await db.get();
|
|
194
|
-
console.log(' - 事务后数据总数:', transactionResult.length);
|
|
195
|
-
|
|
196
|
-
} catch (error) {
|
|
197
|
-
// 测试back(回滚事务)
|
|
198
|
-
await db.back();
|
|
199
|
-
console.log(' - 事务回滚');
|
|
200
|
-
throw error;
|
|
201
|
-
} finally {
|
|
202
|
-
// 测试end(结束事务)
|
|
203
|
-
db.end();
|
|
204
|
-
}
|
|
205
|
-
console.log('✓ 事务操作完成');
|
|
206
|
-
|
|
207
|
-
// 6. 测试其他方法
|
|
208
|
-
console.log('\n=== 6. 测试其他方法 ===');
|
|
209
|
-
|
|
210
|
-
// 测试getCreateTable
|
|
211
|
-
console.log('测试getCreateTable()方法...');
|
|
212
|
-
const createTableResult = await db.getCreateTable(test_table);
|
|
213
|
-
console.log('✓ 表创建语句:', createTableResult);
|
|
214
|
-
|
|
215
|
-
// 测试backupTable
|
|
216
|
-
console.log('测试backupTable()方法...');
|
|
217
|
-
const backupResult = await db.backupTable(test_table, backup_table);
|
|
218
|
-
console.log('✓ 表备份结果:', backupResult);
|
|
219
|
-
|
|
220
|
-
// 测试hasTable(备份表)
|
|
221
|
-
console.log('测试hasTable()方法(备份表)...');
|
|
222
|
-
const hasBackupTableResult = await db.hasTable(backup_table);
|
|
223
|
-
console.log('✓ 备份表是否存在:', hasBackupTableResult);
|
|
224
|
-
|
|
225
|
-
// 测试emptyTable
|
|
226
|
-
console.log('测试emptyTable()方法...');
|
|
227
|
-
const emptyResult = await db.emptyTable(test_table);
|
|
228
|
-
console.log('✓ 清空表结果:', emptyResult);
|
|
229
|
-
|
|
230
|
-
// 7. 清理测试环境
|
|
231
|
-
console.log('\n=== 7. 清理测试环境 ===');
|
|
232
|
-
await db.dropTable(test_table);
|
|
233
|
-
await db.dropTable(backup_table);
|
|
234
|
-
console.log('✓ 测试环境清理完成');
|
|
235
|
-
|
|
236
|
-
// 关闭数据库连接
|
|
237
|
-
console.log('\n=== 8. 关闭数据库连接 ===');
|
|
238
|
-
await sql.close();
|
|
239
|
-
console.log('✓ 数据库连接关闭成功');
|
|
240
|
-
|
|
241
|
-
console.log('\n' + '='.repeat(50));
|
|
242
|
-
console.log('所有测试完成!db.js方法测试通过');
|
|
243
|
-
console.log('='.repeat(50));
|
|
244
|
-
|
|
245
|
-
} catch (error) {
|
|
246
|
-
console.error('\n测试失败:', error.message);
|
|
247
|
-
// 关闭数据库连接
|
|
248
|
-
try {
|
|
249
|
-
if (sql) await sql.close();
|
|
250
|
-
} catch (closeError) {
|
|
251
|
-
console.error('关闭数据库连接失败:', closeError.message);
|
|
252
|
-
}
|
|
253
|
-
process.exit(1);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// 运行测试
|
|
258
|
-
testDbMethods();
|
|
259
|
-
|
|
260
|
-
setTimeout(() => {
|
|
261
|
-
process.exit(0);
|
|
262
|
-
}, 5000);
|