Skip to content

Commit 658b8f9

Browse files
committed
DSN support, fixes #115
1 parent da32b13 commit 658b8f9

File tree

6 files changed

+366
-13
lines changed

6 files changed

+366
-13
lines changed

lib/mysql-libmysqlclient.js

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,26 +71,71 @@ for (var key in bindings) {
7171
* Asynchronous MySQL bindings for Node.js
7272
**/
7373

74+
/** internal
75+
* parseDSN(dsn) -> Array
76+
* -dsn(String): DSN
77+
*
78+
* Parses DSN to connect() arguments array
79+
*/
80+
function parseDSN(dsn) {
81+
var args;
82+
83+
var components = require('url').parse(dsn);
84+
85+
// DSN is not a plain hostname?
86+
if (typeof components.hostname !== 'undefined') {
87+
// Guard protocol
88+
if (components.protocol !== 'mysql:') {
89+
throw new Error("mysql-libmysqlclient supports only connections to MySQL server");
90+
}
91+
92+
var
93+
hostname = components.hostname,
94+
port = components.port,
95+
auth = components.auth.split(':'),
96+
user = auth.shift(),
97+
password = auth.shift(),
98+
database = (typeof components.pathname != 'undefined')
99+
? components.pathname.substr(1).replace(/\/.*$/, '').replace(/\?.*$/, '')
100+
: null,
101+
socket = null,
102+
flags = null;
103+
104+
args = [hostname, user, password, database, port, socket, flags];
105+
} else {
106+
args = [arguments[0]];
107+
}
108+
109+
return args;
110+
}
111+
74112
/** section: Exports
75-
* MysqlLibmysqlclient.createConnectionSync(hostname[, user[, password[, database[, port[, socket]]]]]) -> MysqlConnection
113+
* MysqlLibmysqlclient.createConnectionSync(hostname[, user[, password[, database[, port[, socket[, flags]]]]]]) -> MysqlConnection
76114
*
77115
* Creates connection to database
78116
*
79117
* Synchronous version
80118
**/
81119
exports.createConnectionSync = function createConnectionSync() {
82-
var connection = new bindings.MysqlConnection();
120+
var connection = new bindings.MysqlConnection(), args;
83121

84-
if (arguments.length > 0) {
122+
// DSN support
123+
if (arguments.length === 1) {
124+
args = parseDSN(arguments[0]);
125+
} else {
126+
args = Array.prototype.slice.call(arguments, 0, 7);
127+
}
128+
129+
if (args.length > 0) {
85130
// connection.constructor.prototype == bindings.MysqlConnection.prototype;
86-
bindings.MysqlConnection.prototype.connectSync.apply(connection, Array.prototype.slice.call(arguments, 0, 6));
131+
bindings.MysqlConnection.prototype.connectSync.apply(connection, args);
87132
}
88133

89134
return connection;
90135
};
91136

92137
/** section: Exports
93-
* MysqlLibmysqlclient.createConnection(hostname[, user[, password[, database[, port[, socket]]]]][, callback])
138+
* MysqlLibmysqlclient.createConnection(hostname[, user[, password[, database[, port[, socket[, flags]]]]][, callback])
94139
*
95140
* Creates connection to database
96141
*
@@ -115,6 +160,13 @@ exports.createConnection = function createConnection() {
115160
callback(null, connection);
116161
};
117162

163+
// DSN support
164+
if (args.length === 1) {
165+
args = parseDSN(args[0]);
166+
} else {
167+
args = Array.prototype.slice.call(args, 0, 7);
168+
}
169+
118170
// + callback
119171
args.push(actualCallback);
120172

@@ -266,11 +318,18 @@ exports.MysqlConnectionQueued = MysqlConnectionQueued;
266318
* Synchronous version
267319
**/
268320
exports.createConnectionQueuedSync = function createConnectionQueuedSync() {
269-
var connection = new MysqlConnectionQueued();
321+
var connection = new MysqlConnectionQueued(), args;
322+
323+
// DSN support
324+
if (arguments.length === 1) {
325+
args = parseDSN(arguments[0]);
326+
} else {
327+
args = Array.prototype.slice.call(arguments, 0, 7);
328+
}
270329

271-
if (arguments.length > 0) {
330+
if (args.length > 0) {
272331
// connection.constructor.prototype == bindings.MysqlConnection.prototype
273-
bindings.MysqlConnection.prototype.connectSync.apply(connection, Array.prototype.slice.call(arguments, 0, 6));
332+
bindings.MysqlConnection.prototype.connectSync.apply(connection, args);
274333
}
275334

276335
return connection;
@@ -302,6 +361,13 @@ exports.createConnectionQueued = function createConnectionQueued() {
302361
callback(null, connection);
303362
};
304363

364+
// DSN support
365+
if (args.length === 1) {
366+
args = parseDSN(args[0]);
367+
} else {
368+
args = Array.prototype.slice.call(arguments, 0, 7);
369+
}
370+
305371
// + callback
306372
args.push(actualCallback);
307373

@@ -379,11 +445,18 @@ MysqlConnectionHighlevel.prototype.query = function query(query, callback) {
379445
* Synchronous version
380446
**/
381447
exports.createConnectionHighlevelSync = function createConnectionHighlevelSync() {
382-
var connection = new MysqlConnectionHighlevel();
448+
var connection = new MysqlConnectionHighlevel(), args;
449+
450+
// DSN support
451+
if (arguments.length === 1) {
452+
args = parseDSN(arguments[0]);
453+
} else {
454+
args = Array.prototype.slice.call(arguments, 0, 7);
455+
}
383456

384-
if (arguments.length > 0) {
457+
if (args.length > 0) {
385458
// connection.constructor.prototype == bindings.MysqlConnection.prototype;
386-
MysqlConnectionHighlevel.prototype.connectSync.apply(connection, Array.prototype.slice.call(arguments, 0, 6));
459+
MysqlConnectionHighlevel.prototype.connectSync.apply(connection, args);
387460
}
388461

389462
return connection;
@@ -415,6 +488,13 @@ exports.createConnectionHighlevel = function createConnectionHighlevel() {
415488
callback(null, connection);
416489
};
417490

491+
// DSN support
492+
if (args.length === 1) {
493+
args = parseDSN(arguments[0]);
494+
} else {
495+
args = Array.prototype.slice.call(arguments, 0, 7);
496+
}
497+
418498
// + callback
419499
args.push(actualCallback);
420500

tests/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module.exports = {
2222

2323
// Database connection settings
2424
host: process.env["TRAVIS"] ? "localhost" : "localhost",
25+
port: process.env["TRAVIS"] ? 3306 : 3306,
2526
user: process.env["TRAVIS"] ? "test_user" : "test",
2627
password: process.env["TRAVIS"] ? "1234" : "",
2728
database: "test",

tests/high-level/test-createconnection-highlevel.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,30 @@ exports.mysql_libmysqlclient_createConnectionHighlevelSync_4 = function (test) {
4242
test.done();
4343
};
4444

45+
exports.mysql_libmysqlclient_createConnectionHighlevelSync_DSN = function (test) {
46+
test.expect(4);
47+
48+
var
49+
dsn = require('util').format("mysql://%s:%s@%s:%s/%s/zxcvbn?qwerty=1234", cfg.user, cfg.password, cfg.host, cfg.port, cfg.database),
50+
conn = cfg.mysql_libmysqlclient.createConnectionHighlevelSync(dsn),
51+
isConnected;
52+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
53+
test.ok(conn instanceof cfg.mysql_libmysqlclient.MysqlConnectionQueued);
54+
test.ok(conn instanceof cfg.mysql_libmysqlclient.MysqlConnectionHighlevel);
55+
56+
isConnected = conn.connectedSync();
57+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnectionHighlevelSync(dsn(user, password, host, port, database)) connects");
58+
59+
if (!isConnected) {
60+
// Extra debug output
61+
console.log("Error:" + conn.connectError);
62+
} else {
63+
conn.closeSync();
64+
}
65+
66+
test.done();
67+
};
68+
4569
exports.mysql_libmysqlclient_createConnectionHighlevel_0 = function (test) {
4670
test.expect(1);
4771

@@ -91,3 +115,28 @@ exports.mysql_libmysqlclient_createConnectionHighlevel_5 = function (test) {
91115
test.done();
92116
});
93117
};
118+
119+
exports.mysql_libmysqlclient_createConnectionHighlevel_DSN = function (test) {
120+
test.expect(5);
121+
122+
var dsn = require('util').format("mysql://%s:%s@%s:%s/%s/zxcvbn?qwerty=1234", cfg.user, cfg.password, cfg.host, cfg.port, cfg.database);
123+
124+
cfg.mysql_libmysqlclient.createConnectionHighlevel(dsn, function (err, conn) {
125+
test.ok(err === null, "Error object is not present");
126+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
127+
test.ok(conn instanceof cfg.mysql_libmysqlclient.MysqlConnectionQueued);
128+
test.ok(conn instanceof cfg.mysql_libmysqlclient.MysqlConnectionHighlevel);
129+
130+
isConnected = conn.connectedSync();
131+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnectionHighlevel(dsn(user, password, host, port, database), callback) connects");
132+
133+
if (!isConnected) {
134+
// Extra debug output
135+
console.log("Error:" + conn.connectError);
136+
} else {
137+
conn.closeSync();
138+
}
139+
140+
test.done();
141+
});
142+
};

tests/high-level/test-createconnection-queued.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,28 @@ exports.mysql_libmysqlclient_createConnectionQueuedSync_4 = function (test) {
4040
test.done();
4141
};
4242

43+
exports.mysql_libmysqlclient_createConnectionQueuedSync_DSN = function (test) {
44+
test.expect(2);
45+
46+
var
47+
dsn = require('util').format("mysql://%s:%s@%s:%s/%s/zxcvbn?qwerty=1234", cfg.user, cfg.password, cfg.host, cfg.port, cfg.database),
48+
conn = cfg.mysql_libmysqlclient.createConnectionQueuedSync(dsn),
49+
isConnected;
50+
test.ok(conn instanceof cfg.mysql_libmysqlclient.MysqlConnectionQueued, "cfg.mysql_libmysqlclient.createConnectionQueuedSync(dsn(user, password, host, port, database))");
51+
52+
isConnected = conn.connectedSync();
53+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnectionQueuedSync(dsn(user, password, host, port, database)) connects");
54+
55+
if (!isConnected) {
56+
// Extra debug output
57+
console.log("Error:" + conn.connectError);
58+
} else {
59+
conn.closeSync();
60+
}
61+
62+
test.done();
63+
};
64+
4365
exports.mysql_libmysqlclient_createConnectionQueued_0 = function (test) {
4466
test.expect(1);
4567

@@ -87,3 +109,27 @@ exports.mysql_libmysqlclient_createConnectionQueued_5 = function (test) {
87109
test.done();
88110
});
89111
};
112+
113+
exports.mysql_libmysqlclient_createConnectionQueued_DSN = function (test) {
114+
test.expect(4);
115+
116+
var dsn = require('util').format("mysql://%s:%s@%s:%s/%s/zxcvbn?qwerty=1234", cfg.user, cfg.password, cfg.host, cfg.port, cfg.database);
117+
118+
cfg.mysql_libmysqlclient.createConnectionQueued(dsn, function (err, conn) {
119+
test.ok(err === null, "Error object is not present");
120+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
121+
test.ok(conn instanceof cfg.mysql_libmysqlclient.MysqlConnectionQueued);
122+
123+
isConnected = conn.connectedSync();
124+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnectionQueued(dsn(user, password, host, port, database), callback) connects");
125+
126+
if (!isConnected) {
127+
// Extra debug output
128+
console.log("Error:" + conn.connectError);
129+
} else {
130+
conn.closeSync();
131+
}
132+
133+
test.done();
134+
});
135+
};

tests/low-level-async/test-createconnection-async.js

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,30 @@ exports.mysql_libmysqlclient_createConnection_5_AccessDenied = function (test) {
143143
exports.mysql_libmysqlclient_createConnection_6 = function (test) {
144144
test.expect(3);
145145

146+
cfg.mysql_libmysqlclient.createConnection(cfg.host, cfg.user, cfg.password, cfg.database, cfg.port, function (err, conn) {
147+
test.ok(err === null, "Error object is not present");
148+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
149+
150+
var isConnected = conn.connectedSync();
151+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnection(host, user, password, database, flags, callback)");
152+
153+
if (!isConnected) {
154+
// Extra debug output
155+
console.log("Error:" + conn.connectError);
156+
} else {
157+
conn.closeSync();
158+
}
159+
160+
test.done();
161+
});
162+
};
163+
164+
exports.mysql_libmysqlclient_createConnection_8 = function (test) {
165+
test.expect(3);
166+
146167
var compress_flag = cfg.mysql_bindings.CLIENT_COMPRESS;
147168

148-
cfg.mysql_libmysqlclient.createConnection(cfg.host, cfg.user, cfg.password, cfg.database, compress_flag, function (err, conn) {
169+
cfg.mysql_libmysqlclient.createConnection(cfg.host, cfg.user, cfg.password, cfg.database, null, null, compress_flag, function (err, conn) {
149170
test.ok(err === null, "Error object is not present");
150171
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
151172

@@ -162,3 +183,72 @@ exports.mysql_libmysqlclient_createConnection_6 = function (test) {
162183
test.done();
163184
});
164185
};
186+
187+
exports.mysql_libmysqlclient_createConnectionSync_DSN_1 = function (test) {
188+
test.expect(3);
189+
190+
var dsn = require('util').format("mysql://%s:%s@%s:%s", cfg.user, cfg.password, cfg.host, cfg.port);
191+
192+
cfg.mysql_libmysqlclient.createConnection(dsn, function (err, conn) {
193+
test.ok(err === null, "Error object is not present");
194+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
195+
196+
var isConnected = conn.connectedSync();
197+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnection(dsn(user, password, host, port), callback)");
198+
199+
if (!isConnected) {
200+
// Extra debug output
201+
console.log("Error:" + conn.connectError);
202+
} else {
203+
conn.closeSync();
204+
}
205+
206+
test.done();
207+
});
208+
};
209+
210+
exports.mysql_libmysqlclient_createConnectionSync_DSN_2 = function (test) {
211+
test.expect(3);
212+
213+
var dsn = require('util').format("mysql://%s:%s@%s:%s?qwerty=1234", cfg.user, cfg.password, cfg.host, cfg.port);
214+
215+
cfg.mysql_libmysqlclient.createConnection(dsn, function (err, conn) {
216+
test.ok(err === null, "Error object is not present");
217+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
218+
219+
var isConnected = conn.connectedSync();
220+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnection(dsn(user, password, host, port), callback)");
221+
222+
if (!isConnected) {
223+
// Extra debug output
224+
console.log("Error:" + conn.connectError);
225+
} else {
226+
conn.closeSync();
227+
}
228+
229+
test.done();
230+
});
231+
};
232+
233+
exports.mysql_libmysqlclient_createConnectionSync_DSN_3 = function (test) {
234+
test.expect(3);
235+
236+
var dsn = require('util').format("mysql://%s:%s@%s:%s/%s/zxcvbn?qwerty=1234", cfg.user, cfg.password, cfg.host, cfg.port, cfg.database);
237+
238+
cfg.mysql_libmysqlclient.createConnection(dsn, function (err, conn) {
239+
test.ok(err === null, "Error object is not present");
240+
test.ok(conn instanceof cfg.mysql_bindings.MysqlConnection);
241+
242+
var isConnected = conn.connectedSync();
243+
test.ok(isConnected, "cfg.mysql_libmysqlclient.createConnection(dsn(user, password, host, port, database), callback)");
244+
245+
if (!isConnected) {
246+
// Extra debug output
247+
console.log("Error:" + conn.connectError);
248+
} else {
249+
conn.closeSync();
250+
}
251+
252+
test.done();
253+
});
254+
};

0 commit comments

Comments
 (0)