mm_sql 1.3.8 → 1.4.0

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @fileOverview SQL通用类
3
- * @author <a href="http://qww.elins.cn">邱文武</a>
3
+ * @author <a href="http://qww.elins.cn">qww</a>
4
4
  * @version 1.0
5
5
  */
6
6
 
@@ -17,7 +17,12 @@ class Sql {
17
17
  * 配置信息
18
18
  */
19
19
  this.config = Object.assign({
20
- db_type: 'mysql'
20
+ scope: 'sys',
21
+ db_type: 'mysql',
22
+ dir: '/db/',
23
+ host: 'localhost',
24
+ port: 3306,
25
+ database: ''
21
26
  }, config || {});
22
27
 
23
28
  /**
@@ -49,12 +54,12 @@ Sql.prototype._createSqlAdapter = function () {
49
54
  // 根据数据库类型选择不同的初始化方式
50
55
  if (this.config.db_type === 'mysql') {
51
56
  // 创建MySQL实例
52
- const Mysql = adapter.Mysql;
53
- this._adapter = new Mysql(this.config);
57
+ const admin = adapter.mysqlAdmin;
58
+ this._adapter = admin(this.config.scope, this.config);
54
59
  } else if (this.config.db_type === 'sqlite') {
55
60
  // SQLite应该有类似的结构
56
- const Sqlite = adapter.Sqlite;
57
- this._adapter = new Sqlite(this.config);
61
+ const admin = adapter.sqliteAdmin;
62
+ this._adapter = admin(this.config.scope, this.config);
58
63
  } else {
59
64
  // 其他数据库类型直接使用Sql类(如果存在)
60
65
  const AdapterClass = adapter.Sql;
@@ -72,15 +77,32 @@ Sql.prototype._createSqlAdapter = function () {
72
77
  * @param {Array} params - 参数数组
73
78
  * @param {Number} timeout - 超时时间(毫秒)
74
79
  * @returns {Promise} 查询结果
80
+ * @throws {TypeError} 当sql参数无效时
75
81
  */
76
82
  Sql.prototype.run = function (sql, params = [], timeout = null) {
77
- // 支持两种调用方式:run(sql, params, timeout) 或 run({sql: '', params: []})
78
- if (typeof sql === 'object') {
79
- params = sql.params || [];
80
- timeout = sql.timeout || null;
81
- sql = sql.sql || '';
82
- }
83
- return this._adapter.run(sql, params, timeout);
83
+ // 参数校验
84
+ if (typeof sql !== 'string' && typeof sql !== 'object') {
85
+ throw new TypeError('sql must be string or object');
86
+ }
87
+ if (!Array.isArray(params)) {
88
+ throw new TypeError('params must be array');
89
+ }
90
+ if (timeout !== null && typeof timeout !== 'number') {
91
+ throw new TypeError('timeout must be number or null');
92
+ }
93
+
94
+ try {
95
+ // 支持两种调用方式:run(sql, params, timeout) 或 run({sql: '', params: []})
96
+ if (typeof sql === 'object') {
97
+ params = sql.params || [];
98
+ timeout = sql.timeout || null;
99
+ sql = sql.sql || '';
100
+ }
101
+ return this._adapter.run(sql, params, timeout);
102
+ } catch (error) {
103
+ this.logger('error', 'SQL查询执行失败', error);
104
+ throw error;
105
+ }
84
106
  };
85
107
 
86
108
  /**
@@ -89,15 +111,32 @@ Sql.prototype.run = function (sql, params = [], timeout = null) {
89
111
  * @param {Array} params - 参数数组
90
112
  * @param {Number} timeout - 超时时间(毫秒)
91
113
  * @returns {Promise} 修改结果
114
+ * @throws {TypeError} 当sql参数无效时
92
115
  */
93
116
  Sql.prototype.exec = function (sql, params = [], timeout = null) {
94
- // 支持两种调用方式:exec(sql, params, timeout) 或 exec({sql: '', params: []})
95
- if (typeof sql === 'object') {
96
- params = sql.params || [];
97
- timeout = sql.timeout || null;
98
- sql = sql.sql || '';
99
- }
100
- return this._adapter.exec(sql, params, timeout);
117
+ // 参数校验
118
+ if (typeof sql !== 'string' && typeof sql !== 'object') {
119
+ throw new TypeError('sql must be string or object');
120
+ }
121
+ if (!Array.isArray(params)) {
122
+ throw new TypeError('params must be array');
123
+ }
124
+ if (timeout !== null && typeof timeout !== 'number') {
125
+ throw new TypeError('timeout must be number or null');
126
+ }
127
+
128
+ try {
129
+ // 支持两种调用方式:exec(sql, params, timeout) 或 exec({sql: '', params: []})
130
+ if (typeof sql === 'object') {
131
+ params = sql.params || [];
132
+ timeout = sql.timeout || null;
133
+ sql = sql.sql || '';
134
+ }
135
+ return this._adapter.exec(sql, params, timeout);
136
+ } catch (error) {
137
+ this.logger('error', 'SQL修改执行失败', error);
138
+ return 0;
139
+ }
101
140
  };
102
141
 
103
142
  /**
@@ -105,7 +144,12 @@ Sql.prototype.exec = function (sql, params = [], timeout = null) {
105
144
  * @returns {Promise} 连接结果
106
145
  */
107
146
  Sql.prototype.open = function () {
108
- return this._adapter.open();
147
+ try {
148
+ return this._adapter.open();
149
+ } catch (error) {
150
+ this.logger('error', '数据库连接打开失败', error);
151
+ return null;
152
+ }
109
153
  };
110
154
 
111
155
  /**
@@ -113,57 +157,30 @@ Sql.prototype.open = function () {
113
157
  * @returns {Promise} 关闭结果
114
158
  */
115
159
  Sql.prototype.close = function () {
116
- return this._adapter.close();
160
+ try {
161
+ return this._adapter.close();
162
+ } catch (error) {
163
+ this.logger('error', '数据库连接关闭失败', error);
164
+ }
117
165
  };
118
166
 
119
167
  /**
120
168
  * 设置配置
121
169
  * @param {Object} config - 配置对象
170
+ * @throws {TypeError} 当config参数无效时
122
171
  */
123
172
  Sql.prototype.setConfig = function (config) {
124
- this.config = Object.assign(this.config, config);
125
- this._init();
126
- };
127
-
128
- /**
129
- * 获取连接信息
130
- * @returns {Object} 连接信息
131
- */
132
- Sql.prototype.getConnectionInfo = function () {
133
- // 确保返回包含必要字段的连接信息
134
- return {
135
- db_type: this.config.db_type,
136
- host: this.config.host || 'localhost',
137
- port: this.config.port || 3306,
138
- database: this.config.database || ''
139
- };
140
- };
141
-
142
- /**
143
- * 检查数据库连接状态
144
- * @returns {Boolean} 连接状态
145
- */
146
- Sql.prototype.isConnected = function () {
147
- // 简单实现,返回true表示连接正常
148
- return true;
149
- };
150
-
151
- /**
152
- * 获取标识符
153
- * @private
154
- * @param {String} name - 名称
155
- * @returns {String} 标识符
156
- */
157
- Sql.prototype._getIdentifier = function (name) {
158
- const dbType = this.config.db_type;
159
- switch (dbType) {
160
- case 'mysql':
161
- return `\`${name}\``;
162
- case 'sqlite':
163
- return `"${name}"`;
164
- default:
165
- return name;
166
- }
173
+ // 参数校验
174
+ if (!config || typeof config !== 'object') {
175
+ throw new TypeError('config must be object');
176
+ }
177
+
178
+ try {
179
+ this.config = Object.assign(this.config, config);
180
+ this._init();
181
+ } catch (error) {
182
+ this.logger('error', '配置设置失败', error);
183
+ }
167
184
  };
168
185
 
169
186
  /**
@@ -171,22 +188,36 @@ Sql.prototype._getIdentifier = function (name) {
171
188
  * @param {Object} paramDt - 参数对象
172
189
  * @param {Object} sqlDt - SQL模板对象
173
190
  * @returns {Object} 查询结果对象
191
+ * @throws {TypeError} 当参数对象无效时
174
192
  */
175
193
  Sql.prototype.tplQuery = function (paramDt, sqlDt) {
176
- let sql = '';
177
-
178
- for (const key in paramDt) {
179
- if (sqlDt[key]) {
180
- // 替换占位符{0}为参数值
181
- const sqlSegment = sqlDt[key].replace(/\{0\}/g, paramDt[key]);
182
- sql += 'AND ' + sqlSegment + ' ';
183
- }
184
- else {
185
- sql += 'AND `' + key + "` = '" + paramDt[key] + "'";
194
+ // 参数校验
195
+ if (!paramDt || typeof paramDt !== 'object') {
196
+ throw new TypeError('paramDt must be object');
197
+ }
198
+ if (!sqlDt || typeof sqlDt !== 'object') {
199
+ throw new TypeError('sqlDt must be object');
200
+ }
201
+
202
+ try {
203
+ let sql = '';
204
+
205
+ for (const key in paramDt) {
206
+ if (sqlDt[key]) {
207
+ // 替换占位符{0}为参数值
208
+ const sqlSegment = sqlDt[key].replace(/\{0\}/g, paramDt[key]);
209
+ sql += 'AND ' + sqlSegment + ' ';
210
+ }
211
+ else {
212
+ sql += 'AND `' + key + "` = '" + paramDt[key] + "'";
213
+ }
186
214
  }
187
- }
188
-
189
- return sql.replace('AND ', '');
215
+
216
+ return sql.replace('AND ', '');
217
+ } catch (error) {
218
+ this.logger('error', '模板查询生成失败', error);
219
+ return '';
220
+ }
190
221
  };
191
222
 
192
223
  /**
@@ -194,22 +225,36 @@ Sql.prototype.tplQuery = function (paramDt, sqlDt) {
194
225
  * @param {Object} paramDt - 参数对象
195
226
  * @param {Object} sqlDt - SQL模板对象
196
227
  * @returns {Object} 查询结果对象
228
+ * @throws {TypeError} 当参数对象无效时
197
229
  */
198
230
  Sql.prototype.tplBody = function (paramDt, sqlDt) {
199
- let sql = '';
200
-
201
- for (const key in paramDt) {
202
- if (sqlDt[key]) {
203
- // 替换占位符{0}为参数值
204
- const sqlSegment = sqlDt[key].replace(/\{0\}/g, paramDt[key]);
205
- sql += ', ' + sqlSegment + ' ';
206
- }
207
- else {
208
- sql += ', `' + key + "` = '" + paramDt[key] + "'";
231
+ // 参数校验
232
+ if (!paramDt || typeof paramDt !== 'object') {
233
+ throw new TypeError('paramDt must be object');
234
+ }
235
+ if (!sqlDt || typeof sqlDt !== 'object') {
236
+ throw new TypeError('sqlDt must be object');
237
+ }
238
+
239
+ try {
240
+ let sql = '';
241
+
242
+ for (const key in paramDt) {
243
+ if (sqlDt[key]) {
244
+ // 替换占位符{0}为参数值
245
+ const sqlSegment = sqlDt[key].replace(/\{0\}/g, paramDt[key]);
246
+ sql += ', ' + sqlSegment + ' ';
247
+ }
248
+ else {
249
+ sql += ', `' + key + "` = '" + paramDt[key] + "'";
250
+ }
209
251
  }
210
- }
211
-
212
- return sql.replace(', ', '');
252
+
253
+ return sql.replace(', ', '');
254
+ } catch (error) {
255
+ this.logger('error', '模板数据生成失败', error);
256
+ return '';
257
+ }
213
258
  };
214
259
 
215
260
  /**
@@ -217,14 +262,28 @@ Sql.prototype.tplBody = function (paramDt, sqlDt) {
217
262
  * @param {Object} paramDt - 参数对象
218
263
  * @param {Array} arr - 过滤数组
219
264
  * @returns {Object} 过滤后的参数对象
265
+ * @throws {TypeError} 当参数对象无效时
220
266
  */
221
267
  Sql.prototype.filter = function (paramDt, arr) {
222
- for (const key in paramDt) {
223
- if (arr.includes(key)) {
224
- delete paramDt[key];
225
- }
226
- }
227
- return paramDt;
268
+ // 参数校验
269
+ if (!paramDt || typeof paramDt !== 'object') {
270
+ throw new TypeError('paramDt must be object');
271
+ }
272
+ if (!Array.isArray(arr)) {
273
+ throw new TypeError('arr must be array');
274
+ }
275
+
276
+ try {
277
+ for (const key in paramDt) {
278
+ if (arr.includes(key)) {
279
+ delete paramDt[key];
280
+ }
281
+ }
282
+ return paramDt;
283
+ } catch (error) {
284
+ this.logger('error', '参数过滤失败', error);
285
+ return {};
286
+ }
228
287
  };
229
288
 
230
289
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_sql",
3
- "version": "1.3.8",
3
+ "version": "1.4.0",
4
4
  "description": "一个通用的SQL帮助类,支持通过切换db_type实现对不同数据库的操作,包括MySQL和SQLite等",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -41,7 +41,7 @@
41
41
  "node": ">=12.0.0"
42
42
  },
43
43
  "dependencies": {
44
- "mm_mysql": "^2.1.1",
45
- "mm_sqlite": "^1.1.2"
44
+ "mm_mysql": "^2.2.5",
45
+ "mm_sqlite": "^1.2.2"
46
46
  }
47
47
  }
package/test.js CHANGED
@@ -1,4 +1,4 @@
1
- const {Sql} = require('./index.js');
1
+ const { Sql } = require('./index.js');
2
2
 
3
3
  /**
4
4
  * @description Sql类测试
@@ -18,7 +18,9 @@ class SqlTest {
18
18
  async init() {
19
19
  try {
20
20
  this.sql = new Sql({
21
- db_type: 'mysql',
21
+ // db_type: 'mysql',
22
+ db_type: 'sqlite',
23
+ dir: './db',
22
24
  host: 'localhost',
23
25
  user: 'root',
24
26
  password: 'Asd159357',
@@ -39,7 +41,7 @@ class SqlTest {
39
41
  this.testCount++;
40
42
  try {
41
43
  // 测试setConfig方法
42
- this.sql.setConfig({size: 50});
44
+ this.sql.setConfig({ size: 50 });
43
45
  if (this.sql.config.size !== 50) {
44
46
  throw new Error('setConfig方法测试失败');
45
47
  }
@@ -68,67 +70,6 @@ class SqlTest {
68
70
  }
69
71
  }
70
72
 
71
-
72
-
73
- /**
74
- * @description 测试标识符处理方法
75
- */
76
- testIdentifierMethod() {
77
- this.testCount++;
78
- try {
79
- // 测试MySQL标识符
80
- this.sql.config.db_type = 'mysql';
81
- const mysqlId = this.sql._getIdentifier('test_table');
82
- if (mysqlId !== '`test_table`') {
83
- throw new Error('MySQL标识符处理失败');
84
- }
85
-
86
- // 测试SQLite标识符
87
- this.sql.config.db_type = 'sqlite';
88
- const sqliteId = this.sql._getIdentifier('test_table');
89
- if (sqliteId !== '"test_table"') {
90
- throw new Error('SQLite标识符处理失败');
91
- }
92
-
93
- // 恢复默认数据库类型
94
- this.sql.config.db_type = 'mysql';
95
-
96
- console.log('标识符处理方法测试成功');
97
- this.successCount++;
98
- return true;
99
- } catch (error) {
100
- console.error('标识符处理方法测试失败:', error.message);
101
- return false;
102
- }
103
- }
104
-
105
- /**
106
- * @description 测试连接状态方法
107
- */
108
- testConnectionMethods() {
109
- this.testCount++;
110
- try {
111
- // 测试isConnected方法
112
- const connected = this.sql.isConnected();
113
- if (typeof connected !== 'boolean') {
114
- throw new Error('isConnected方法返回值类型错误');
115
- }
116
-
117
- // 测试getConnectionInfo方法
118
- const connInfo = this.sql.getConnectionInfo();
119
- if (!connInfo.db_type || !connInfo.host) {
120
- throw new Error('getConnectionInfo方法返回值不完整');
121
- }
122
-
123
- console.log('连接状态方法测试成功');
124
- this.successCount++;
125
- return true;
126
- } catch (error) {
127
- console.error('连接状态方法测试失败:', error.message);
128
- return false;
129
- }
130
- }
131
-
132
73
  /**
133
74
  * @description 测试模板查询方法
134
75
  */
@@ -243,7 +184,27 @@ class SqlTest {
243
184
  if (!dbInstance) {
244
185
  throw new Error('db方法返回值无效');
245
186
  }
246
-
187
+ dbInstance.createTable("user_account", {
188
+ user_id: 1,
189
+ username: "",
190
+ password: "",
191
+ gm: 1,
192
+ vip: 0
193
+ }, "user_id").then(() => {
194
+ console.log('创建表成功');
195
+ }).catch((error) => {
196
+ console.error('创建表失败:', error);
197
+ });
198
+ dbInstance.fields("user_account").then((result) => {
199
+ console.log('查询字段:', result);
200
+ });
201
+ dbInstance.table = "user_account";
202
+ dbInstance.get({
203
+ user_id: "1"
204
+ }).then((result) => {
205
+ console.log('查询结果:', result);
206
+ });
207
+ console.log('调试DB:查询方法测试完成后', dbInstance.sql, dbInstance.error);
247
208
  console.log('核心方法测试成功');
248
209
  this.successCount++;
249
210
  return true;
@@ -273,10 +234,6 @@ class SqlTest {
273
234
  console.log('调试:配置方法测试完成后');
274
235
  this.testSqlBuilderMethods();
275
236
  console.log('调试:SQL构建方法测试完成后');
276
- this.testIdentifierMethod();
277
- console.log('调试:标识符处理方法测试完成后');
278
- this.testConnectionMethods();
279
- console.log('调试:连接状态方法测试完成后');
280
237
  this.testTemplateMethods();
281
238
  console.log('调试:模板查询方法测试完成后');
282
239
  this.testCoreMethods();
@@ -284,7 +241,7 @@ class SqlTest {
284
241
 
285
242
  console.log('='.repeat(50));
286
243
  console.log(`测试完成: ${this.successCount}/${this.testCount} 个测试通过`);
287
-
244
+
288
245
  if (this.successCount === this.testCount) {
289
246
  console.log('所有测试通过!');
290
247
  return true;
package/test2.js CHANGED
@@ -1,10 +1,9 @@
1
1
  const { Sql } = require('./index.js');
2
-
3
2
  async function test() {
4
3
  var sql = new Sql({
5
4
  // 数据库类型 mysql, sqlite, postgres
6
5
  db_type: 'sqlite',
7
- host: '/db/',
6
+ dir: "/db/",
8
7
  user: 'root',
9
8
  password: 'Asd159357',
10
9
  database: 'mm'
@@ -15,17 +14,35 @@ async function test() {
15
14
 
16
15
  var db = sql.db();
17
16
  db.table = "user_account";
17
+ // 添加表
18
18
  var res = await db.addTable('user_account', 'user_id');
19
- await db.addField('user_account', 'vip', 'INT', '0');
20
- await db.addField('user_account', 'gm', 'INT', '0');
21
19
  console.log("添加表结果:", res);
20
+
21
+ // 添加字段(不需要指定表名,因为已通过db.table设置)
22
+ var res2 = await db.addField('age', 'INT', '0');
23
+ var res3 = await db.addField('sex', 'INT', '0');
24
+ console.log("添加字段结果:", res2, res3);
22
25
  db.key = "user_id";
23
26
  var user = await db.getObj({
24
27
  user_id: 1
25
28
  });
26
- user.vip = 5;
27
- user.gm = 5;
28
- await $.sleep(3000);
29
+
30
+ if (!user) {
31
+ // 如果用户不存在,创建一个新用户
32
+ user = {
33
+ user_id: 1,
34
+ vip: 5,
35
+ gm: 5
36
+ };
37
+ await db.add(user);
38
+ } else {
39
+ // 如果用户存在,更新其属性
40
+ user.vip = 5;
41
+ user.gm = 5;
42
+ await db.set({ user_id: 1 }, user);
43
+ }
44
+ // 使用原生的setTimeout实现延迟
45
+ await new Promise(resolve => setTimeout(resolve, 3000));
29
46
  db.size = 1;
30
47
  var list = await db.get({
31
48
  user_id: 1
@@ -33,4 +50,11 @@ async function test() {
33
50
  console.log("查询结果:", list);
34
51
  }
35
52
 
36
- test();
53
+ // 调用test函数并处理异常
54
+ test().catch(err => {
55
+ console.error('测试过程中发生错误:', err);
56
+ process.exit(1);
57
+ }).finally(() => {
58
+ // 确保程序以零退出码结束
59
+ process.exit(0);
60
+ });
package/localhostmm.db DELETED
File without changes