-
Notifications
You must be signed in to change notification settings - Fork 0
/
mysql.js
112 lines (101 loc) · 3.28 KB
/
mysql.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* This is an SQL database engine for Node
* based on http://www.w3.org/TR/webdatabase/
* Currently only supports MySQL.
*/
var DatabaseError = require('perstore/errors').DatabaseError,
DuplicateEntryError = require('perstore/errors').DuplicateEntryError;
// set the SQL database
var sqlStore = require('perstore/store/sql');
sqlStore.SQLDatabase = MysqlWrapper;
exports.SQLStore = sqlStore.SQLStore;
var engines = {
mysql: MysqlWrapper
};
exports.SQLDatabase = function(params) {
if (params.type in engines)
return engines[params.type](params);
throw new DatabaseError("Unsupported database engine");
};
function MysqlWrapper(params) {
var currentConnection;
var x=0;
// adapted from http://github.com/sidorares/nodejs-mysql-native/lib/mysql-native/websql.js
return {
executeSql: function(query, args, callback, errback) {
var conn = currentConnection;
if(!conn) {
errback(new DatabaseError("No transactional context has been created"));
return;
}
if (!conn.clean) {
errback(new DatabaseError("Cannot commit a transaction with an error"));
return;
}
var charset = require("mysql-native/lib/mysql-native/charset").Charset.by_name(conn.get("charset"));
if(charset && charset.name=="utf8") conn.execute("SET NAMES utf8");
var cmd = conn.execute(query,args);
cmd.on('result', function(result) {
if (conn.clean && callback) {
callback({
insertId: result.insert_id,
rowsAffected: result.affected_rows,
rows: result.rows
});
}
});
cmd.on('error', function(err) {
conn.clean = false;
if(errback) {
var patt=/^duplicate entry/ig;
if(err && patt.test(err.message)) {
errback(new DuplicateEntryError(err.message));
} else {
errback(err);
}
}
});
},
transaction: function() {
var conn = connectMysql(params);
currentConnection = conn;
throwOnError(conn.query('SET autocommit=0;'), 'disable autocommit');
throwOnError(conn.query('BEGIN'), 'initialize transaction');
return {
commit: function() {
throwOnError(conn.query("COMMIT"), 'commit SQL transaction');
throwOnError(conn.close(), 'close connection');
},
abort: function() {
throwOnError(conn.query("ROLLBACK"), 'rollback SQL transaction');
throwOnError(conn.close(), 'close connection');
},
suspend: function(){
currentConnection = null;
},
resume: function(){
currentConnection = conn;
}
};
}
};
function throwOnError(cmd, action) {
cmd.on('error', function(err) {
console.log('Failed to ' + action +
(err && err.message ? ': ' + err.message : ''));
throw new DatabaseError('Failed to ' + action +
(err && err.message ? ': ' + err.message : ''));
});
}
function connectMysql(params) {
var ret = require("mysql-native/lib/mysql-native/client").createTCPClient(params.host, params.port);
ret.auto_prepare = true;
ret.row_as_hash = true;
ret.clean = true;
// use charset if available
if(params.charset) ret.set("charset",params.charset);
throwOnError(ret.connection, 'connect to DB');
throwOnError(ret.auth(params.name, params.username, params.password), 'authenticate');
return ret;
}
}