mm_mysql 1.9.1 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/index.js +154 -58
  2. package/package.json +33 -37
  3. package/test.js +25 -5
  4. package/data.sql +0 -4963
package/index.js CHANGED
@@ -11,6 +11,7 @@ const {
11
11
  } = require('./db');
12
12
 
13
13
  const Link_model = require('./link_model');
14
+ const { table } = require('console');
14
15
 
15
16
  var pool = {};
16
17
 
@@ -80,7 +81,7 @@ class Mysql {
80
81
  * @param {Array} val 替换值
81
82
  * @return {Promise|Array} 异步构造器, 当await时返回执行结果
82
83
  */
83
- this.run = function(sql, val) {
84
+ this.run = function (sql, val) {
84
85
  var _this = this;
85
86
  this.sql = sql;
86
87
  if ($this.config.log) {
@@ -89,7 +90,7 @@ class Mysql {
89
90
 
90
91
  // 返回一个 Promise
91
92
  return new Promise((resolve, reject) => {
92
- $this.conn.getConnection(function(err, db) {
93
+ $this.conn.getConnection(function (err, db) {
93
94
  if (err) {
94
95
  _this.error = {
95
96
  code: 2003,
@@ -131,7 +132,7 @@ class Mysql {
131
132
  * @param {Array} val 替换值
132
133
  * @return {Promise|Array} 异步构造器, 当await时返回执行结果
133
134
  */
134
- this.exec = function(sql, val) {
135
+ this.exec = function (sql, val) {
135
136
  var _this = this;
136
137
  if (this.task) {
137
138
  this.task_sql += sql + "\r\n";
@@ -153,7 +154,7 @@ class Mysql {
153
154
  }
154
155
  // 返回一个 Promise
155
156
  return new Promise((resolve, reject) => {
156
- $this.conn.getConnection(function(err, db) {
157
+ $this.conn.getConnection(function (err, db) {
157
158
  if (err) {
158
159
  _this.error = {
159
160
  code: 41000,
@@ -182,7 +183,7 @@ class Mysql {
182
183
  if (o.constructor == Array) {
183
184
  if (o.length > 0) {
184
185
  var num = 0;
185
- o.map(function(item) {
186
+ o.map(function (item) {
186
187
  num += item['affectedRows'];
187
188
  });
188
189
  if (num === 0) {
@@ -213,74 +214,169 @@ class Mysql {
213
214
  /**
214
215
  * @description 获取数据库管理器
215
216
  */
216
- this.db = function() {
217
+ this.db = function () {
217
218
  return new DB($this);
218
219
  };
220
+ }
221
+ }
219
222
 
220
- /**
221
- *
222
- * @param {Object} file sql文件
223
- * @param {Function} func 回调函数
224
- * @return {Promise} 异步构造器, 当await时返回执行结果
225
- */
226
- this.load = async function(file, func) {
227
- var count = 0;
228
- var progress = 0;
229
- var errors = [];
230
- var index = 0;
231
- try {
232
- var data = file.loadText();
233
- // 将SQL文件内容分割成单独的语句
234
- const arr = data.split(';\r\n');
235
- count = arr.length;
236
- for (var i = 0; i < arr.length; i++) {
237
- var sql_str = arr[i].trim();
238
- var bl;
239
- if (sql_str !== '') {
240
- await this.run(sql_str + ";");
241
- if (this.error) {
242
- errors.push({
243
- sql_str: sql_str.slice(0, 512),
244
- error: this.error
245
- });
246
- bl = false;
247
- // 如果数据库链接失败(密码错误或无法连接),则退出循环
248
- if (this.error.code == 1045 || this.error.code == 2003) {
249
- break;
250
- }
251
- } else {
252
- bl = true;
253
- }
223
+ /**
224
+ * 导入数据库
225
+ * @param {Object} file sql文件
226
+ * @param {Function} func 回调函数
227
+ * @return {Promise} 异步构造器, 当await时返回执行结果
228
+ */
229
+ Mysql.prototype.load = async function (file, func) {
230
+ var count = 0;
231
+ var progress = 0;
232
+ var errors = [];
233
+ var index = 0;
234
+ try {
235
+ var data = file.loadText();
236
+ // 将SQL文件内容分割成单独的语句
237
+ const arr = data.split(';\r\n');
238
+ count = arr.length;
239
+ for (var i = 0; i < arr.length; i++) {
240
+ var sql_str = arr[i].trim();
241
+ if (sql_str !== '') {
242
+ await this.run(sql_str + ";");
243
+ if (this.error) {
244
+ errors.push({
245
+ sql_str: sql_str.slice(0, 512),
246
+ error: this.error
247
+ });
248
+ // 如果数据库链接失败(密码错误或无法连接),则退出循环
249
+ if (this.error.code == 1045 || this.error.code == 2003) {
250
+ break;
254
251
  }
255
- var p = i / arr.length;
256
- progress = Math.ceil(p * 100);
257
- index = i;
258
- if (func) {
259
- func(progress, index, bl, this.error, sql_str);
252
+ }
253
+ }
254
+ var p = i / arr.length;
255
+ progress = Math.ceil(p * 100);
256
+ index = i;
257
+ if (func) {
258
+ func(progress, index, this.error, sql_str);
259
+ }
260
+ }
261
+ } catch (err) {
262
+ $.log.error("导入SQL文件失败!", err);
263
+ }
264
+ return {
265
+ index,
266
+ count,
267
+ progress,
268
+ errors
269
+ }
270
+ };
271
+
272
+ /**
273
+ * 保存数据库为文件
274
+ * @param {String} file 文件对象
275
+ * @param {Function} func 回调函数
276
+ * @return {Promise} 异步构造器, 当await时返回执行结果
277
+ */
278
+ Mysql.prototype.save = async function (file, func, tables = []) {
279
+ const fs = require('fs');
280
+ const stream = fs.createWriteStream(file);
281
+ let count = 0;
282
+ let progress = 0;
283
+ let errors = [];
284
+ let index = 0;
285
+ let tableCount = 0;
286
+
287
+ try {
288
+ // 开始导出数据库
289
+ stream.write('SET FOREIGN_KEY_CHECKS = 0;\r\n\r\n');
290
+ count++;
291
+
292
+ if(!tables.length) {
293
+ // 获取所有表
294
+ var tbs = await this.run('SHOW TABLES');
295
+ tables = tbs.map((item) => {
296
+ return item[Object.keys(item)[0]];
297
+ });
298
+ }
299
+
300
+ tableCount = tables.length;
301
+ console.log("tables", tables);
302
+ for (var i = 0; i < tables.length; i++) {
303
+ var tableName = tables[i];
304
+ try {
305
+ // 导出表结构
306
+ const createTable = await this.run(`SHOW CREATE TABLE ${tableName}`);
307
+ stream.write(`-- 表结构: ${tableName}\r\n`);
308
+ stream.write(`DROP TABLE IF EXISTS \`${tableName}\`;\r\n`);
309
+ count++;
310
+ stream.write(`${createTable[0]['Create Table']};\r\n\r\n`);
311
+ count++;
312
+ // 导出表数据
313
+ const rows = await this.run(`SELECT * FROM ${tableName}`);
314
+ if (rows.length > 0) {
315
+ stream.write(`-- 表数据: ${tableName}\r\n`);
316
+ for (const row of rows) {
317
+ const rowValues = Object.values(row)
318
+ .map(value => {
319
+ if (value === null) return 'NULL';
320
+ if (typeof value === 'boolean') return value ? 1 : 0;
321
+ if (typeof value === 'number') return value;
322
+ if (value instanceof Date) {
323
+ return "'" + value.toStr('yyyy-MM-dd hh:mm:ss') + "'";
324
+ }
325
+ // 处理字符串,转义特殊字符
326
+ return "'" + value.toString()
327
+ .replace(/[\\']/g, '\\$&')
328
+ .replace(/\n/g, '\\n')
329
+ .replace(/\r/g, '\\r')
330
+ .replace(/\t/g, '\\t')
331
+ .replace(/\u0000/g, '\\0') + "'";
332
+ })
333
+ .join(',');
334
+ stream.write(`INSERT INTO ${tableName} VALUES (${rowValues});\r\n`);
335
+ count++;
260
336
  }
337
+ stream.write('\r\n');
261
338
  }
262
339
  } catch (err) {
263
- $.log.error("导入SQL文件失败!", err);
340
+ errors.push({
341
+ table: tableName,
342
+ error: err.message
343
+ });
264
344
  }
265
- return {
266
- index,
267
- count,
268
- progress,
269
- errors
345
+
346
+ index++;
347
+ progress = Math.ceil((index / tableCount) * 100);
348
+ if (func) {
349
+ func(progress, index, this.error, tableName);
270
350
  }
271
351
  }
352
+
353
+ // 完成导出
354
+ stream.write('SET FOREIGN_KEY_CHECKS = 1;\r\n');
355
+ count++;
356
+ stream.end();
357
+ } catch (err) {
358
+ $.log.error("导出SQL文件失败!", err);
359
+ stream.end();
272
360
  }
273
- }
361
+
362
+ return {
363
+ tableCount,
364
+ index,
365
+ count,
366
+ progress,
367
+ errors
368
+ }
369
+ };
274
370
 
275
371
  /**
276
372
  * 获取数据库管理器
277
373
  * @param {String} key 主键
278
- * @param {String|Number} value 对象值
374
+ * @param {String|Number} value 对象值
279
375
  * @param {Boolean} clear_prefix 清除前缀
280
376
  * @param {Array} arr_table 关联的数据表
281
377
  * @return {Object} 管理模型
282
378
  */
283
- Mysql.prototype.dbs = async function(key, value, clear_prefix, ...arr_table) {
379
+ Mysql.prototype.dbs = async function (key, value, clear_prefix, ...arr_table) {
284
380
  var lm = new Link_model({
285
381
  key,
286
382
  value,
@@ -297,9 +393,9 @@ Mysql.prototype.dbs = async function(key, value, clear_prefix, ...arr_table) {
297
393
  * 设置配置参数
298
394
  * @param {Object} cg 配置对象或配置路径
299
395
  */
300
- Mysql.prototype.setConfig = function(cg) {
396
+ Mysql.prototype.setConfig = function (cg) {
301
397
  var obj;
302
- if (typeof(cg) === "string") {
398
+ if (typeof (cg) === "string") {
303
399
  obj = cg.loadJson(this.dir);
304
400
  } else {
305
401
  obj = cg;
@@ -312,7 +408,7 @@ Mysql.prototype.setConfig = function(cg) {
312
408
  * @description 打开数据库, 如果没有则建立数据库连接再打开
313
409
  * @param {boolean} 是否重置
314
410
  */
315
- Mysql.prototype.open = function(reset) {
411
+ Mysql.prototype.open = function (reset) {
316
412
  if (reset || !this.state || !pool[this.identifier]) {
317
413
  this.state = 1;
318
414
  pool[this.identifier] = createPool(this.config);
@@ -323,7 +419,7 @@ Mysql.prototype.open = function(reset) {
323
419
  /**
324
420
  * @description 关闭连接
325
421
  */
326
- Mysql.prototype.close = function() {
422
+ Mysql.prototype.close = function () {
327
423
  if (pool[this.identifier]) {
328
424
  pool[this.identifier].end();
329
425
  pool[this.identifier] = null;
package/package.json CHANGED
@@ -1,37 +1,33 @@
1
- {
2
- "name": "mm_mysql",
3
- "version": "1.9.1",
4
- "description": "这是超级美眉mysql帮助函数模块,用于便捷操作mysql,使用await方式,可以避免嵌套函数",
5
- "main": "index.js",
6
- "dependencies": {
7
- "mm_logs": "^1.1.6",
8
- "mysql": "^2.18.1"
9
- },
10
- "scripts": {
11
- "test": "node test.js",
12
- "dev": "nodemon test.js"
13
- },
14
- "author": "邱文武",
15
- "license": "ISC",
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/qiuwenwu/mm_mysql.git"
19
- },
20
- "keywords": [
21
- "mysql",
22
- "async",
23
- "await",
24
- "promise",
25
- "add",
26
- "del",
27
- "set",
28
- "get",
29
- "query",
30
- "run",
31
- "exec"
32
- ],
33
- "bugs": {
34
- "url": "https://github.com/qiuwenwu/mm_mysql/issues"
35
- },
36
- "homepage": "https://github.com/qiuwenwu/mm_mysql#readme"
37
- }
1
+ {
2
+ "name": "mm_mysql",
3
+ "version": "1.9.2",
4
+ "description": "这是超级美眉mysql帮助函数模块,用于便捷操作mysql,使用await方式,可以避免嵌套函数",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "node test.js",
8
+ "dev": "nodemon test.js"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://gitee.com/qiuwenwu91/mm_mysql.git"
13
+ },
14
+ "keywords": [
15
+ "mysql",
16
+ "async",
17
+ "await",
18
+ "promise",
19
+ "add",
20
+ "del",
21
+ "set",
22
+ "get",
23
+ "query",
24
+ "run",
25
+ "exec"
26
+ ],
27
+ "author": "qww",
28
+ "license": "ISC",
29
+ "dependencies": {
30
+ "mm_logs": "^1.1.7",
31
+ "mysql": "^2.18.1"
32
+ }
33
+ }
package/test.js CHANGED
@@ -14,12 +14,32 @@ async function test() {
14
14
  multipleStatements: true
15
15
  });
16
16
  await sql.open();
17
- var file = "./data.sql".fullname(__dirname);
18
- var ret = await sql.load(file, function(progress, index, bl, error, sql_str) {
19
- console.log(progress, index, bl, error, sql_str);
20
- });
17
+ // // 导入
18
+ // var ret = await sql.load("./data.sql".fullname(__dirname), function(progress, index, error, sql_str) {
19
+ // console.log("导入", progress, index, error, sql_str);
20
+ // });
21
+ // console.log("导入结果", ret);
22
+
23
+ // 导出指定表'user_account', 'user_info'
24
+ // var ret2 = await sql.save("./bat.sql".fullname(__dirname), function(progress, index, error, sql_str) {
25
+ // console.log("导出", progress, index, error, sql_str);
26
+ // }, ['user_account', 'user_info']);
27
+ // console.log("导出结果", ret2);
28
+
29
+ // // 导出
30
+ // var ret2 = await sql.save("./bat.sql".fullname(__dirname), function(progress, index, error, sql_str) {
31
+ // // console.log("导出", progress, index, error, sql_str);
32
+ // });
33
+ // console.log("导出结果", ret2);
34
+
35
+ // // 导入
36
+ // var ret = await sql.load("./bat.sql".fullname(__dirname), function(progress, index, error, sql_str) {
37
+ // // console.log("导入", progress, index, error, sql_str);
38
+ // });
39
+ // console.log("导入结果", ret);
40
+
21
41
  sql.close();
22
- console.log("执行结果", ret);
42
+
23
43
  }
24
44
  test();
25
45