dborm-mysql 2.2.3 → 2.2.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/.history/base/db_20240619174313.js +215 -0
- package/.history/base/db_20250620173735.js +215 -0
- package/.history/base/db_20250620173736.js +215 -0
- package/.history/base/db_20250620173746.js +215 -0
- package/.history/{package_20230807152934.json → package_20250620173753.json} +1 -1
- package/.history/{package_20230807152935.json → package_20250620173754.json} +1 -1
- package/.history/package_20250620173755.json +36 -0
- package/base/db.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Created by hzzhangdianpeng on 2016/12/2.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let mysql = require('mysql');
|
|
6
|
+
const co = require('co');
|
|
7
|
+
let shortUuid = require('short-uuid');
|
|
8
|
+
let moment = require('moment');
|
|
9
|
+
|
|
10
|
+
function initMysqlPool(db, dbConfig) {
|
|
11
|
+
db.pool = mysql.createPool(dbConfig);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let logSql = (connection, rows, sql, startTime, logExecuteTime, logger) => {
|
|
15
|
+
let insertIdLog = (rows && rows.insertId) ? `[insertId = ${rows.insertId}] ` : '';
|
|
16
|
+
|
|
17
|
+
let info = `[${connection.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}]`;
|
|
18
|
+
if(logExecuteTime){
|
|
19
|
+
const executeTime = (new Date()).getTime() - startTime.getTime();
|
|
20
|
+
info += `[execute time: ${executeTime}ms]`;
|
|
21
|
+
}
|
|
22
|
+
info += `${insertIdLog} ${sql}`;
|
|
23
|
+
logger(info);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// 去掉报错信息行,只保留当前函数调用栈
|
|
27
|
+
let getCurrentStack = (currentStack) => {
|
|
28
|
+
// new Error().stack的格式是:Error: 错误信息\n at 函数名 (文件路径:行号:列号)... 去掉第一行即可获取当前函数的调用栈
|
|
29
|
+
return currentStack.split('\n').slice(1).join('\n');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = (dbConfig, {log, noConvertDbCodes, dbCode, logExecuteTime, logger}) => {
|
|
33
|
+
let db = {
|
|
34
|
+
pool: null
|
|
35
|
+
};
|
|
36
|
+
initMysqlPool(db, dbConfig);
|
|
37
|
+
let reconnectionTime = 0;
|
|
38
|
+
//获取数据连接,将回调转换为promise
|
|
39
|
+
db.getConnection = function (options = {}) {
|
|
40
|
+
return new Promise(function (resolve, reject) {
|
|
41
|
+
db.pool.getConnection(function (err, connection) {
|
|
42
|
+
if (err) {
|
|
43
|
+
if(err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT' || err.code === 'PROTOCOL_SEQUENCE_TIMEOUT'){
|
|
44
|
+
logger('mysql reconnect, reconnect time:', reconnectionTime++);
|
|
45
|
+
db.getConnection().then(resolve, reject);
|
|
46
|
+
}
|
|
47
|
+
reject(err);
|
|
48
|
+
} else {
|
|
49
|
+
connection.connectionLogId = options.transId || shortUuid().new().slice(0, 6);
|
|
50
|
+
reconnectionTime = 0;
|
|
51
|
+
connection.logSql = options.transId || options.logSql || log || process.SQL_LOG;
|
|
52
|
+
resolve(connection);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
db.wrapTransaction = function (fn, nth, timeout, options = {}) {
|
|
59
|
+
const Message = '等待事务超时';
|
|
60
|
+
return function () {
|
|
61
|
+
let ctx = this;
|
|
62
|
+
let params = Array.from(arguments);
|
|
63
|
+
if (params[nth]) {
|
|
64
|
+
return fn.apply(ctx, params);
|
|
65
|
+
} else {
|
|
66
|
+
return (co.wrap(function* (params) {
|
|
67
|
+
let newOptions = Object.assign({}, options);
|
|
68
|
+
if (options.transId && typeof options.transId === 'function'){
|
|
69
|
+
newOptions.transId = options.transId(params);
|
|
70
|
+
}
|
|
71
|
+
if (options.logSql && typeof options.logSql === 'function'){
|
|
72
|
+
newOptions.logSql = options.logSql(params);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let conn = yield db.beginTransaction(newOptions);
|
|
76
|
+
let result;
|
|
77
|
+
let timer;
|
|
78
|
+
try {
|
|
79
|
+
params[nth] = conn;
|
|
80
|
+
result = yield Promise.race([
|
|
81
|
+
fn.apply(ctx, params),
|
|
82
|
+
new Promise((res) => {
|
|
83
|
+
timer = setTimeout(() => {
|
|
84
|
+
res(Message);
|
|
85
|
+
}, timeout || 50000);
|
|
86
|
+
})
|
|
87
|
+
]);
|
|
88
|
+
if(timer) clearTimeout(timer);
|
|
89
|
+
if(result === Message){
|
|
90
|
+
throw new Error(result);
|
|
91
|
+
}
|
|
92
|
+
yield db.commitTransaction(conn);
|
|
93
|
+
conn.release();
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if(timer) clearTimeout(timer);
|
|
96
|
+
yield db.rollbackTransaction(conn);
|
|
97
|
+
conn.release();
|
|
98
|
+
conn.destroy();
|
|
99
|
+
if(!noConvertDbCodes.includes(err.code)){
|
|
100
|
+
err.code = dbCode;
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}))(params);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
db.query = function (sql, sqlParam, connection) {
|
|
111
|
+
let currentStack = new Error().stack;
|
|
112
|
+
let query;
|
|
113
|
+
return new Promise(function (resolve, reject) {
|
|
114
|
+
if(process.MYSQL_READ_ONLY && !sql.toLowerCase().trimLeft().startsWith('select')){
|
|
115
|
+
reject({
|
|
116
|
+
code: 739,
|
|
117
|
+
message: '当前系统正在维护中,不能使用编辑功能'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const startTime = new Date();
|
|
122
|
+
|
|
123
|
+
if (connection) {
|
|
124
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
125
|
+
if(connection.logSql){
|
|
126
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
127
|
+
}
|
|
128
|
+
if (err) {
|
|
129
|
+
if (!connection.logSql){
|
|
130
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
131
|
+
}
|
|
132
|
+
err.code = dbCode;
|
|
133
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
134
|
+
reject(err);
|
|
135
|
+
} else {
|
|
136
|
+
resolve(rows);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
db.getConnection().then(function (connection) {
|
|
141
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
142
|
+
if(connection.logSql){
|
|
143
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
144
|
+
}
|
|
145
|
+
connection.release();
|
|
146
|
+
if (err) {
|
|
147
|
+
if (!connection.logSql){
|
|
148
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
149
|
+
}
|
|
150
|
+
connection.destroy();
|
|
151
|
+
err.code = dbCode;
|
|
152
|
+
reject(err);
|
|
153
|
+
} else {
|
|
154
|
+
resolve(rows);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}).catch(function (err) {
|
|
158
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
159
|
+
reject(err);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
db.beginTransaction = function (options) {
|
|
166
|
+
let p = new Promise(function (resolve, reject) {
|
|
167
|
+
db.getConnection(options).then(function (conn) {
|
|
168
|
+
if(conn.logSql){
|
|
169
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] beginTransaction`);
|
|
170
|
+
}
|
|
171
|
+
conn.beginTransaction(function (err) {
|
|
172
|
+
if (err) {
|
|
173
|
+
conn.rollback(function () {
|
|
174
|
+
conn.release();
|
|
175
|
+
reject(err);
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
resolve(conn);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}).catch(function (err) {
|
|
182
|
+
reject(err);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
return p;
|
|
186
|
+
};
|
|
187
|
+
db.commitTransaction = function (conn) {
|
|
188
|
+
return new Promise(function (resolve, reject) {
|
|
189
|
+
conn.commit(function (err) {
|
|
190
|
+
if (err) {
|
|
191
|
+
reject(err);
|
|
192
|
+
} else {
|
|
193
|
+
if(conn.logSql){
|
|
194
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] commitTransaction`);
|
|
195
|
+
}
|
|
196
|
+
// conn.release();
|
|
197
|
+
resolve('success');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
db.rollbackTransaction = function (conn) {
|
|
204
|
+
return new Promise(function (resolve, reject) {
|
|
205
|
+
conn.rollback(function (err, suc) {
|
|
206
|
+
if(conn.logSql){
|
|
207
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] rollbackTransaction`);
|
|
208
|
+
}
|
|
209
|
+
resolve();
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return db;
|
|
215
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Created by hzzhangdianpeng on 2016/12/2.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let mysql = require('mysql');
|
|
6
|
+
const co = require('co');
|
|
7
|
+
let shortUuid = require('short-uuid');
|
|
8
|
+
let moment = require('moment');
|
|
9
|
+
|
|
10
|
+
function initMysqlPool(db, dbConfig) {
|
|
11
|
+
db.pool = mysql.createPool(dbConfig);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let logSql = (connection, rows, sql, startTime, logExecuteTime, logger) => {
|
|
15
|
+
let insertIdLog = (rows && rows.insertId) ? `[insertId = ${rows.insertId}] ` : '';
|
|
16
|
+
|
|
17
|
+
let info = `[${connection.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}]`;
|
|
18
|
+
if(logExecuteTime){
|
|
19
|
+
const executeTime = (new Date()).getTime() - startTime.getTime();
|
|
20
|
+
info += `[execute time: ${executeTime}ms]`;
|
|
21
|
+
}
|
|
22
|
+
info += `${insertIdLog} ${sql}`;
|
|
23
|
+
logger(info);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// 去掉报错信息行,只保留当前函数调用栈
|
|
27
|
+
let getCurrentStack = (currentStack) => {
|
|
28
|
+
// new Error().stack的格式是:Error: 错误信息\n at 函数名 (文件路径:行号:列号)... 去掉第一行即可获取当前函数的调用栈
|
|
29
|
+
return currentStack.split('\n').slice(1).join('\n');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = (dbConfig, {log, noConvertDbCodes, dbCode, logExecuteTime, logger}) => {
|
|
33
|
+
let db = {
|
|
34
|
+
pool: null
|
|
35
|
+
};
|
|
36
|
+
initMysqlPool(db, dbConfig);
|
|
37
|
+
let reconnectionTime = 0;
|
|
38
|
+
//获取数据连接,将回调转换为promise
|
|
39
|
+
db.getConnection = function (options = {}) {
|
|
40
|
+
return new Promise(function (resolve, reject) {
|
|
41
|
+
db.pool.getConnection(function (err, connection) {
|
|
42
|
+
if (err) {
|
|
43
|
+
if(err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT' || err.code === 'PROTOCOL_SEQUENCE_TIMEOUT'){
|
|
44
|
+
logger('mysql reconnect, reconnect time:', reconnectionTime++);
|
|
45
|
+
db.getConnection().then(resolve, reject);
|
|
46
|
+
}
|
|
47
|
+
reject(err);
|
|
48
|
+
} else {
|
|
49
|
+
connection.connectionLogId = options.transId || shortUuid().new().slice(0, 6);
|
|
50
|
+
reconnectionTime = 0;
|
|
51
|
+
connection.logSql = options.transId || options.logSql || log || process.SQL_LOG;
|
|
52
|
+
resolve(connection);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
db.wrapTransaction = function (fn, nth, timeout, options = {}) {
|
|
59
|
+
const Message = options.errorMessage || '等待事务超时';
|
|
60
|
+
return function () {
|
|
61
|
+
let ctx = this;
|
|
62
|
+
let params = Array.from(arguments);
|
|
63
|
+
if (params[nth]) {
|
|
64
|
+
return fn.apply(ctx, params);
|
|
65
|
+
} else {
|
|
66
|
+
return (co.wrap(function* (params) {
|
|
67
|
+
let newOptions = Object.assign({}, options);
|
|
68
|
+
if (options.transId && typeof options.transId === 'function'){
|
|
69
|
+
newOptions.transId = options.transId(params);
|
|
70
|
+
}
|
|
71
|
+
if (options.logSql && typeof options.logSql === 'function'){
|
|
72
|
+
newOptions.logSql = options.logSql(params);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let conn = yield db.beginTransaction(newOptions);
|
|
76
|
+
let result;
|
|
77
|
+
let timer;
|
|
78
|
+
try {
|
|
79
|
+
params[nth] = conn;
|
|
80
|
+
result = yield Promise.race([
|
|
81
|
+
fn.apply(ctx, params),
|
|
82
|
+
new Promise((res) => {
|
|
83
|
+
timer = setTimeout(() => {
|
|
84
|
+
res(Message);
|
|
85
|
+
}, timeout || 50000);
|
|
86
|
+
})
|
|
87
|
+
]);
|
|
88
|
+
if(timer) clearTimeout(timer);
|
|
89
|
+
if(result === Message){
|
|
90
|
+
throw new Error(result);
|
|
91
|
+
}
|
|
92
|
+
yield db.commitTransaction(conn);
|
|
93
|
+
conn.release();
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if(timer) clearTimeout(timer);
|
|
96
|
+
yield db.rollbackTransaction(conn);
|
|
97
|
+
conn.release();
|
|
98
|
+
conn.destroy();
|
|
99
|
+
if(!noConvertDbCodes.includes(err.code)){
|
|
100
|
+
err.code = dbCode;
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}))(params);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
db.query = function (sql, sqlParam, connection) {
|
|
111
|
+
let currentStack = new Error().stack;
|
|
112
|
+
let query;
|
|
113
|
+
return new Promise(function (resolve, reject) {
|
|
114
|
+
if(process.MYSQL_READ_ONLY && !sql.toLowerCase().trimLeft().startsWith('select')){
|
|
115
|
+
reject({
|
|
116
|
+
code: 739,
|
|
117
|
+
message: '当前系统正在维护中,不能使用编辑功能'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const startTime = new Date();
|
|
122
|
+
|
|
123
|
+
if (connection) {
|
|
124
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
125
|
+
if(connection.logSql){
|
|
126
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
127
|
+
}
|
|
128
|
+
if (err) {
|
|
129
|
+
if (!connection.logSql){
|
|
130
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
131
|
+
}
|
|
132
|
+
err.code = dbCode;
|
|
133
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
134
|
+
reject(err);
|
|
135
|
+
} else {
|
|
136
|
+
resolve(rows);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
db.getConnection().then(function (connection) {
|
|
141
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
142
|
+
if(connection.logSql){
|
|
143
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
144
|
+
}
|
|
145
|
+
connection.release();
|
|
146
|
+
if (err) {
|
|
147
|
+
if (!connection.logSql){
|
|
148
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
149
|
+
}
|
|
150
|
+
connection.destroy();
|
|
151
|
+
err.code = dbCode;
|
|
152
|
+
reject(err);
|
|
153
|
+
} else {
|
|
154
|
+
resolve(rows);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}).catch(function (err) {
|
|
158
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
159
|
+
reject(err);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
db.beginTransaction = function (options) {
|
|
166
|
+
let p = new Promise(function (resolve, reject) {
|
|
167
|
+
db.getConnection(options).then(function (conn) {
|
|
168
|
+
if(conn.logSql){
|
|
169
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] beginTransaction`);
|
|
170
|
+
}
|
|
171
|
+
conn.beginTransaction(function (err) {
|
|
172
|
+
if (err) {
|
|
173
|
+
conn.rollback(function () {
|
|
174
|
+
conn.release();
|
|
175
|
+
reject(err);
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
resolve(conn);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}).catch(function (err) {
|
|
182
|
+
reject(err);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
return p;
|
|
186
|
+
};
|
|
187
|
+
db.commitTransaction = function (conn) {
|
|
188
|
+
return new Promise(function (resolve, reject) {
|
|
189
|
+
conn.commit(function (err) {
|
|
190
|
+
if (err) {
|
|
191
|
+
reject(err);
|
|
192
|
+
} else {
|
|
193
|
+
if(conn.logSql){
|
|
194
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] commitTransaction`);
|
|
195
|
+
}
|
|
196
|
+
// conn.release();
|
|
197
|
+
resolve('success');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
db.rollbackTransaction = function (conn) {
|
|
204
|
+
return new Promise(function (resolve, reject) {
|
|
205
|
+
conn.rollback(function (err, suc) {
|
|
206
|
+
if(conn.logSql){
|
|
207
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] rollbackTransaction`);
|
|
208
|
+
}
|
|
209
|
+
resolve();
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return db;
|
|
215
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Created by hzzhangdianpeng on 2016/12/2.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let mysql = require('mysql');
|
|
6
|
+
const co = require('co');
|
|
7
|
+
let shortUuid = require('short-uuid');
|
|
8
|
+
let moment = require('moment');
|
|
9
|
+
|
|
10
|
+
function initMysqlPool(db, dbConfig) {
|
|
11
|
+
db.pool = mysql.createPool(dbConfig);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let logSql = (connection, rows, sql, startTime, logExecuteTime, logger) => {
|
|
15
|
+
let insertIdLog = (rows && rows.insertId) ? `[insertId = ${rows.insertId}] ` : '';
|
|
16
|
+
|
|
17
|
+
let info = `[${connection.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}]`;
|
|
18
|
+
if(logExecuteTime){
|
|
19
|
+
const executeTime = (new Date()).getTime() - startTime.getTime();
|
|
20
|
+
info += `[execute time: ${executeTime}ms]`;
|
|
21
|
+
}
|
|
22
|
+
info += `${insertIdLog} ${sql}`;
|
|
23
|
+
logger(info);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// 去掉报错信息行,只保留当前函数调用栈
|
|
27
|
+
let getCurrentStack = (currentStack) => {
|
|
28
|
+
// new Error().stack的格式是:Error: 错误信息\n at 函数名 (文件路径:行号:列号)... 去掉第一行即可获取当前函数的调用栈
|
|
29
|
+
return currentStack.split('\n').slice(1).join('\n');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = (dbConfig, {log, noConvertDbCodes, dbCode, logExecuteTime, logger}) => {
|
|
33
|
+
let db = {
|
|
34
|
+
pool: null
|
|
35
|
+
};
|
|
36
|
+
initMysqlPool(db, dbConfig);
|
|
37
|
+
let reconnectionTime = 0;
|
|
38
|
+
//获取数据连接,将回调转换为promise
|
|
39
|
+
db.getConnection = function (options = {}) {
|
|
40
|
+
return new Promise(function (resolve, reject) {
|
|
41
|
+
db.pool.getConnection(function (err, connection) {
|
|
42
|
+
if (err) {
|
|
43
|
+
if(err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT' || err.code === 'PROTOCOL_SEQUENCE_TIMEOUT'){
|
|
44
|
+
logger('mysql reconnect, reconnect time:', reconnectionTime++);
|
|
45
|
+
db.getConnection().then(resolve, reject);
|
|
46
|
+
}
|
|
47
|
+
reject(err);
|
|
48
|
+
} else {
|
|
49
|
+
connection.connectionLogId = options.transId || shortUuid().new().slice(0, 6);
|
|
50
|
+
reconnectionTime = 0;
|
|
51
|
+
connection.logSql = options.transId || options.logSql || log || process.SQL_LOG;
|
|
52
|
+
resolve(connection);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
db.wrapTransaction = function (fn, nth, timeout, options = {}) {
|
|
59
|
+
const Message = options.errorMessage || '等待事务超时';
|
|
60
|
+
return function () {
|
|
61
|
+
let ctx = this;
|
|
62
|
+
let params = Array.from(arguments);
|
|
63
|
+
if (params[nth]) {
|
|
64
|
+
return fn.apply(ctx, params);
|
|
65
|
+
} else {
|
|
66
|
+
return (co.wrap(function* (params) {
|
|
67
|
+
let newOptions = Object.assign({}, options);
|
|
68
|
+
if (options.transId && typeof options.transId === 'function'){
|
|
69
|
+
newOptions.transId = options.transId(params);
|
|
70
|
+
}
|
|
71
|
+
if (options.logSql && typeof options.logSql === 'function'){
|
|
72
|
+
newOptions.logSql = options.logSql(params);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let conn = yield db.beginTransaction(newOptions);
|
|
76
|
+
let result;
|
|
77
|
+
let timer;
|
|
78
|
+
try {
|
|
79
|
+
params[nth] = conn;
|
|
80
|
+
result = yield Promise.race([
|
|
81
|
+
fn.apply(ctx, params),
|
|
82
|
+
new Promise((res) => {
|
|
83
|
+
timer = setTimeout(() => {
|
|
84
|
+
res(Message);
|
|
85
|
+
}, timeout || 50000);
|
|
86
|
+
})
|
|
87
|
+
]);
|
|
88
|
+
if(timer) clearTimeout(timer);
|
|
89
|
+
if(result === Message){
|
|
90
|
+
throw new Error(result);
|
|
91
|
+
}
|
|
92
|
+
yield db.commitTransaction(conn);
|
|
93
|
+
conn.release();
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if(timer) clearTimeout(timer);
|
|
96
|
+
yield db.rollbackTransaction(conn);
|
|
97
|
+
conn.release();
|
|
98
|
+
conn.destroy();
|
|
99
|
+
if(!noConvertDbCodes.includes(err.code)){
|
|
100
|
+
err.code = dbCode;
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}))(params);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
db.query = function (sql, sqlParam, connection) {
|
|
111
|
+
let currentStack = new Error().stack;
|
|
112
|
+
let query;
|
|
113
|
+
return new Promise(function (resolve, reject) {
|
|
114
|
+
if(process.MYSQL_READ_ONLY && !sql.toLowerCase().trimLeft().startsWith('select')){
|
|
115
|
+
reject({
|
|
116
|
+
code: 739,
|
|
117
|
+
message: '当前系统正在维护中,不能使用编辑功能'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const startTime = new Date();
|
|
122
|
+
|
|
123
|
+
if (connection) {
|
|
124
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
125
|
+
if(connection.logSql){
|
|
126
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
127
|
+
}
|
|
128
|
+
if (err) {
|
|
129
|
+
if (!connection.logSql){
|
|
130
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
131
|
+
}
|
|
132
|
+
err.code = dbCode;
|
|
133
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
134
|
+
reject(err);
|
|
135
|
+
} else {
|
|
136
|
+
resolve(rows);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
db.getConnection().then(function (connection) {
|
|
141
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
142
|
+
if(connection.logSql){
|
|
143
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
144
|
+
}
|
|
145
|
+
connection.release();
|
|
146
|
+
if (err) {
|
|
147
|
+
if (!connection.logSql){
|
|
148
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
149
|
+
}
|
|
150
|
+
connection.destroy();
|
|
151
|
+
err.code = dbCode;
|
|
152
|
+
reject(err);
|
|
153
|
+
} else {
|
|
154
|
+
resolve(rows);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}).catch(function (err) {
|
|
158
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
159
|
+
reject(err);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
db.beginTransaction = function (options) {
|
|
166
|
+
let p = new Promise(function (resolve, reject) {
|
|
167
|
+
db.getConnection(options).then(function (conn) {
|
|
168
|
+
if(conn.logSql){
|
|
169
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] beginTransaction`);
|
|
170
|
+
}
|
|
171
|
+
conn.beginTransaction(function (err) {
|
|
172
|
+
if (err) {
|
|
173
|
+
conn.rollback(function () {
|
|
174
|
+
conn.release();
|
|
175
|
+
reject(err);
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
resolve(conn);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}).catch(function (err) {
|
|
182
|
+
reject(err);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
return p;
|
|
186
|
+
};
|
|
187
|
+
db.commitTransaction = function (conn) {
|
|
188
|
+
return new Promise(function (resolve, reject) {
|
|
189
|
+
conn.commit(function (err) {
|
|
190
|
+
if (err) {
|
|
191
|
+
reject(err);
|
|
192
|
+
} else {
|
|
193
|
+
if(conn.logSql){
|
|
194
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] commitTransaction`);
|
|
195
|
+
}
|
|
196
|
+
// conn.release();
|
|
197
|
+
resolve('success');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
db.rollbackTransaction = function (conn) {
|
|
204
|
+
return new Promise(function (resolve, reject) {
|
|
205
|
+
conn.rollback(function (err, suc) {
|
|
206
|
+
if(conn.logSql){
|
|
207
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] rollbackTransaction`);
|
|
208
|
+
}
|
|
209
|
+
resolve();
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return db;
|
|
215
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Created by hzzhangdianpeng on 2016/12/2.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let mysql = require('mysql');
|
|
6
|
+
const co = require('co');
|
|
7
|
+
let shortUuid = require('short-uuid');
|
|
8
|
+
let moment = require('moment');
|
|
9
|
+
|
|
10
|
+
function initMysqlPool(db, dbConfig) {
|
|
11
|
+
db.pool = mysql.createPool(dbConfig);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let logSql = (connection, rows, sql, startTime, logExecuteTime, logger) => {
|
|
15
|
+
let insertIdLog = (rows && rows.insertId) ? `[insertId = ${rows.insertId}] ` : '';
|
|
16
|
+
|
|
17
|
+
let info = `[${connection.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}]`;
|
|
18
|
+
if(logExecuteTime){
|
|
19
|
+
const executeTime = (new Date()).getTime() - startTime.getTime();
|
|
20
|
+
info += `[execute time: ${executeTime}ms]`;
|
|
21
|
+
}
|
|
22
|
+
info += `${insertIdLog} ${sql}`;
|
|
23
|
+
logger(info);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// 去掉报错信息行,只保留当前函数调用栈
|
|
27
|
+
let getCurrentStack = (currentStack) => {
|
|
28
|
+
// new Error().stack的格式是:Error: 错误信息\n at 函数名 (文件路径:行号:列号)... 去掉第一行即可获取当前函数的调用栈
|
|
29
|
+
return currentStack.split('\n').slice(1).join('\n');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
module.exports = (dbConfig, {log, noConvertDbCodes, dbCode, logExecuteTime, logger}) => {
|
|
33
|
+
let db = {
|
|
34
|
+
pool: null
|
|
35
|
+
};
|
|
36
|
+
initMysqlPool(db, dbConfig);
|
|
37
|
+
let reconnectionTime = 0;
|
|
38
|
+
//获取数据连接,将回调转换为promise
|
|
39
|
+
db.getConnection = function (options = {}) {
|
|
40
|
+
return new Promise(function (resolve, reject) {
|
|
41
|
+
db.pool.getConnection(function (err, connection) {
|
|
42
|
+
if (err) {
|
|
43
|
+
if(err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT' || err.code === 'PROTOCOL_SEQUENCE_TIMEOUT'){
|
|
44
|
+
logger('mysql reconnect, reconnect time:', reconnectionTime++);
|
|
45
|
+
db.getConnection().then(resolve, reject);
|
|
46
|
+
}
|
|
47
|
+
reject(err);
|
|
48
|
+
} else {
|
|
49
|
+
connection.connectionLogId = options.transId || shortUuid().new().slice(0, 6);
|
|
50
|
+
reconnectionTime = 0;
|
|
51
|
+
connection.logSql = options.transId || options.logSql || log || process.SQL_LOG;
|
|
52
|
+
resolve(connection);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
db.wrapTransaction = function (fn, nth, timeout, options = {}) {
|
|
59
|
+
const Message = options && options.errorMessage || '等待事务超时';
|
|
60
|
+
return function () {
|
|
61
|
+
let ctx = this;
|
|
62
|
+
let params = Array.from(arguments);
|
|
63
|
+
if (params[nth]) {
|
|
64
|
+
return fn.apply(ctx, params);
|
|
65
|
+
} else {
|
|
66
|
+
return (co.wrap(function* (params) {
|
|
67
|
+
let newOptions = Object.assign({}, options);
|
|
68
|
+
if (options.transId && typeof options.transId === 'function'){
|
|
69
|
+
newOptions.transId = options.transId(params);
|
|
70
|
+
}
|
|
71
|
+
if (options.logSql && typeof options.logSql === 'function'){
|
|
72
|
+
newOptions.logSql = options.logSql(params);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let conn = yield db.beginTransaction(newOptions);
|
|
76
|
+
let result;
|
|
77
|
+
let timer;
|
|
78
|
+
try {
|
|
79
|
+
params[nth] = conn;
|
|
80
|
+
result = yield Promise.race([
|
|
81
|
+
fn.apply(ctx, params),
|
|
82
|
+
new Promise((res) => {
|
|
83
|
+
timer = setTimeout(() => {
|
|
84
|
+
res(Message);
|
|
85
|
+
}, timeout || 50000);
|
|
86
|
+
})
|
|
87
|
+
]);
|
|
88
|
+
if(timer) clearTimeout(timer);
|
|
89
|
+
if(result === Message){
|
|
90
|
+
throw new Error(result);
|
|
91
|
+
}
|
|
92
|
+
yield db.commitTransaction(conn);
|
|
93
|
+
conn.release();
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if(timer) clearTimeout(timer);
|
|
96
|
+
yield db.rollbackTransaction(conn);
|
|
97
|
+
conn.release();
|
|
98
|
+
conn.destroy();
|
|
99
|
+
if(!noConvertDbCodes.includes(err.code)){
|
|
100
|
+
err.code = dbCode;
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}))(params);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
db.query = function (sql, sqlParam, connection) {
|
|
111
|
+
let currentStack = new Error().stack;
|
|
112
|
+
let query;
|
|
113
|
+
return new Promise(function (resolve, reject) {
|
|
114
|
+
if(process.MYSQL_READ_ONLY && !sql.toLowerCase().trimLeft().startsWith('select')){
|
|
115
|
+
reject({
|
|
116
|
+
code: 739,
|
|
117
|
+
message: '当前系统正在维护中,不能使用编辑功能'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const startTime = new Date();
|
|
122
|
+
|
|
123
|
+
if (connection) {
|
|
124
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
125
|
+
if(connection.logSql){
|
|
126
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
127
|
+
}
|
|
128
|
+
if (err) {
|
|
129
|
+
if (!connection.logSql){
|
|
130
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
131
|
+
}
|
|
132
|
+
err.code = dbCode;
|
|
133
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
134
|
+
reject(err);
|
|
135
|
+
} else {
|
|
136
|
+
resolve(rows);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
db.getConnection().then(function (connection) {
|
|
141
|
+
query = connection.query(sql, sqlParam, function (err, rows) {
|
|
142
|
+
if(connection.logSql){
|
|
143
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
144
|
+
}
|
|
145
|
+
connection.release();
|
|
146
|
+
if (err) {
|
|
147
|
+
if (!connection.logSql){
|
|
148
|
+
logSql(connection, rows, query.sql, startTime, logExecuteTime, logger);
|
|
149
|
+
}
|
|
150
|
+
connection.destroy();
|
|
151
|
+
err.code = dbCode;
|
|
152
|
+
reject(err);
|
|
153
|
+
} else {
|
|
154
|
+
resolve(rows);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}).catch(function (err) {
|
|
158
|
+
err.stack = err.stack + getCurrentStack(currentStack);
|
|
159
|
+
reject(err);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
db.beginTransaction = function (options) {
|
|
166
|
+
let p = new Promise(function (resolve, reject) {
|
|
167
|
+
db.getConnection(options).then(function (conn) {
|
|
168
|
+
if(conn.logSql){
|
|
169
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] beginTransaction`);
|
|
170
|
+
}
|
|
171
|
+
conn.beginTransaction(function (err) {
|
|
172
|
+
if (err) {
|
|
173
|
+
conn.rollback(function () {
|
|
174
|
+
conn.release();
|
|
175
|
+
reject(err);
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
resolve(conn);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}).catch(function (err) {
|
|
182
|
+
reject(err);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
return p;
|
|
186
|
+
};
|
|
187
|
+
db.commitTransaction = function (conn) {
|
|
188
|
+
return new Promise(function (resolve, reject) {
|
|
189
|
+
conn.commit(function (err) {
|
|
190
|
+
if (err) {
|
|
191
|
+
reject(err);
|
|
192
|
+
} else {
|
|
193
|
+
if(conn.logSql){
|
|
194
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] commitTransaction`);
|
|
195
|
+
}
|
|
196
|
+
// conn.release();
|
|
197
|
+
resolve('success');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
db.rollbackTransaction = function (conn) {
|
|
204
|
+
return new Promise(function (resolve, reject) {
|
|
205
|
+
conn.rollback(function (err, suc) {
|
|
206
|
+
if(conn.logSql){
|
|
207
|
+
logger(`[${conn.connectionLogId}] [${moment().format('YYYY-MM-DD HH:mm:ss.mm.SSS')}] rollbackTransaction`);
|
|
208
|
+
}
|
|
209
|
+
resolve();
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
return db;
|
|
215
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dborm-mysql",
|
|
3
|
+
"version": "2.2.4",
|
|
4
|
+
"description": "a NodeJs ORM for mysql",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@types/node": "^14.14.13",
|
|
9
|
+
"co": "^4.6.0",
|
|
10
|
+
"lodash": "^4.17.4",
|
|
11
|
+
"moment": "^2.24.0",
|
|
12
|
+
"mysql": "^2.14.1",
|
|
13
|
+
"short-uuid": "^2.2.0",
|
|
14
|
+
"util": "^0.10.3"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"chai": "^3.5.0",
|
|
18
|
+
"istanbul": "^1.1.0-alpha.1",
|
|
19
|
+
"mocha": "^3.3.0",
|
|
20
|
+
"should": "~3.3.1"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "istanbul cover node_modules/mocha/bin/_mocha test.js"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/ZhangDianPeng/dborm"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"nodejs",
|
|
31
|
+
"orm",
|
|
32
|
+
"mysql"
|
|
33
|
+
],
|
|
34
|
+
"author": "zhangdianp@163.com",
|
|
35
|
+
"license": "ISC"
|
|
36
|
+
}
|
package/base/db.js
CHANGED
|
@@ -56,7 +56,7 @@ module.exports = (dbConfig, {log, noConvertDbCodes, dbCode, logExecuteTime, logg
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
db.wrapTransaction = function (fn, nth, timeout, options = {}) {
|
|
59
|
-
const Message = '等待事务超时';
|
|
59
|
+
const Message = options && options.errorMessage || '等待事务超时';
|
|
60
60
|
return function () {
|
|
61
61
|
let ctx = this;
|
|
62
62
|
let params = Array.from(arguments);
|