Skip to content

added support for the reset connection packet #1469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .travis.install-mysql-5.7.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q remove --purge "^mysql.*"
sudo rm -rf /var/lib/mysql /var/log/mysql /etc/mysql
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q autoremove
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q autoclean
sudo deluser mysql
sudo service apparmor restart
wget https://dev.mysql.com/get/mysql-apt-config_0.7.3-1_all.deb
sudo DEBIAN_FRONTEND=noninteractive dpkg --force-confold --install mysql-apt-config_0.7.3-1_all.deb
echo mysql-apt-config mysql-apt-config/preview-component string | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/repo-url string http://repo.mysql.com/apt | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/select-product select Ok | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/select-tools select Disabled | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/select-server select mysql-5.7 | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/select-preview select Disabled | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/unsupported-platform select abort | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/repo-distro select ubuntu | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/tools-component string | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/repo-codename select precise | sudo debconf-set-selections
echo mysql-apt-config mysql-apt-config/tools-component string | sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure mysql-apt-config
sudo DEBIAN_FRONTEND=noninteractive apt-get -y -q update
echo mysql-community-server mysql-community-server/root-pass password pass | sudo debconf-set-selections
echo mysql-community-server mysql-community-server/re-root-pass password pass | sudo debconf-set-selections
echo mysql-community-server mysql-community-server/root-pass-mismatch error | sudo debconf-set-selections
echo mysql-community-server mysql-community-server/data-dir note | sudo debconf-set-selections
echo mysql-community-server mysql-community-server/remove-data-dir boolean false | sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt-get -q -y -f install mysql-server
20 changes: 6 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,16 @@ node_js:
- '5.11'
- '6.2'

matrix:
include:
- node_js: '4.4'
env: MYSQL_TYPE=mariadb MYSQL_HOST=localhost MYSQL_DATABASE=node_mysql MYSQL_USER=root MYSQL_PASSWORD=
addons: {mariadb: '10.1'}
allow_failures:
# Allow MariaDB to fail while https://github.com/travis-ci/travis-ci/issues/5837 is being resolved
- node_js: '4.4'
env: MYSQL_TYPE=mariadb MYSQL_HOST=localhost MYSQL_DATABASE=node_mysql MYSQL_USER=root MYSQL_PASSWORD=
addons: {mariadb: '10.1'}

sudo: false
sudo: required

cache:
directories:
- node_modules

before_install:
# install MySQL 5.7
- bash .travis.install-mysql-5.7.sh

# Setup Node.js version-specific dependencies
- "test $TRAVIS_NODE_VERSION != '0.6' || npm rm --save-dev istanbul"
- "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul"
Expand All @@ -40,7 +32,7 @@ before_install:
- "test ! -d node_modules || npm rebuild"

before_script:
- "mysql -e 'create database node_mysql; select version();'"
- "mysql -u root -ppass -e 'create database node_mysql; select version();'"

script:
# Run test script, depending on istanbul install
Expand All @@ -52,7 +44,7 @@ after_script:
- "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"

env:
- MYSQL_TYPE=mysql MYSQL_HOST=localhost MYSQL_DATABASE=node_mysql MYSQL_USER=root MYSQL_PASSWORD=
- MYSQL_TYPE=mysql MYSQL_HOST=localhost MYSQL_DATABASE=node_mysql MYSQL_USER=root MYSQL_PASSWORD=pass

mysql:
adapter: mysql2
Expand Down
18 changes: 18 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
- [Stored procedures](#stored-procedures)
- [Joins with overlapping column names](#joins-with-overlapping-column-names)
- [Transactions](#transactions)
- [Ping](#ping)
- [Reset connection](#reset-connection)
- [Timeouts](#timeouts)
- [Error handling](#error-handling)
- [Exception Safety](#exception-safety)
Expand Down Expand Up @@ -1033,6 +1035,22 @@ connection.ping(function (err) {
})
```

## Reset Connection

The `connection.reset` method causes the server to clear the session state (such as
user variables and temporary tables). This is similar to but more light-weight than
`connection.changeUser`, because reset does not close the connection and reauthenticate.

Documentation defining what is cleared.
[mysql-reset-connection]: https://dev.mysql.com/doc/refman/5.7/en/mysql-reset-connection.html

```js
connection.ping(function (err) {
if (err) throw err;
console.log('Server responded to ping');
})
```

## Timeouts

Every operation takes an optional inactivity timeout option. This allows you to
Expand Down
5 changes: 5 additions & 0 deletions lib/Connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ Connection.prototype.statistics = function statistics(options, callback) {
this._protocol.stats(options, bindToCurrentDomain(callback));
};

Connection.prototype.reset = function reset(callback) {
this._implyConnect();
this._protocol.resetConnection(bindToCurrentDomain(callback));
};

Connection.prototype.end = function end(options, callback) {
var cb = callback;
var opts = options;
Expand Down
4 changes: 4 additions & 0 deletions lib/protocol/Protocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ Protocol.prototype.stats = function stats(options, callback) {
return this._enqueue(new Sequences.Statistics(options, callback));
};

Protocol.prototype.resetConnection = function resetConnection(callback) {
return this._enqueue(new Sequences.ResetConnection(callback));
};

Protocol.prototype.quit = function quit(options, callback) {
if (typeof options === 'function') {
callback = options;
Expand Down
12 changes: 12 additions & 0 deletions lib/protocol/packets/ComResetConnectionPacket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = ComResetConnectionPacket;
function ComResetConnectionPacket(sql) {
this.command = 0x1f;
}

ComResetConnectionPacket.prototype.write = function(writer) {
writer.writeUnsignedNumber(1, this.command);
};

ComResetConnectionPacket.prototype.parse = function(parser) {
this.command = parser.parseUnsignedNumber(1);
};
1 change: 1 addition & 0 deletions lib/protocol/packets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ exports.ComChangeUserPacket = require('./ComChangeUserPacket');
exports.ComPingPacket = require('./ComPingPacket');
exports.ComQueryPacket = require('./ComQueryPacket');
exports.ComQuitPacket = require('./ComQuitPacket');
exports.ComResetConnectionPacket = require('./ComResetConnectionPacket');
exports.ComStatisticsPacket = require('./ComStatisticsPacket');
exports.EmptyPacket = require('./EmptyPacket');
exports.EofPacket = require('./EofPacket');
Expand Down
14 changes: 14 additions & 0 deletions lib/protocol/sequences/ResetConnection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var Sequence = require('./Sequence');
var Util = require('util');
var Packets = require('../packets');

module.exports = ResetConnection;
Util.inherits(ResetConnection, Sequence);

function ResetConnection(callback) {
Sequence.call(this, callback);
}

ResetConnection.prototype.start = function() {
this.emit('packet', new Packets.ComResetConnectionPacket);
};
1 change: 1 addition & 0 deletions lib/protocol/sequences/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ exports.Handshake = require('./Handshake');
exports.Ping = require('./Ping');
exports.Query = require('./Query');
exports.Quit = require('./Quit');
exports.ResetConnection = require('./ResetConnection');
exports.Sequence = require('./Sequence');
exports.Statistics = require('./Statistics');
59 changes: 49 additions & 10 deletions test/integration/connection/test-query-dates-as-strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var util = require('util');

var table = 'dates_as_strings';

common.getTestConnection(function (err, connection) {
common.getTestConnection({dateStrings: true}, function (err, connection) {
assert.ifError(err);

common.useTestDb(connection);
Expand All @@ -17,23 +17,62 @@ common.getTestConnection(function (err, connection) {
') ENGINE=InnoDB DEFAULT CHARSET=utf8'
].join('\n'), [table], assert.ifError);

connection.query('INSERT INTO ?? SET ?', [table, {dt: '0000-00-00'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '2013-00-00'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '2013-03-00'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '1000-01-01'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '2013-01-01'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '2013-03-01'}]);

connection.query('SELECT * FROM ??', [table], function (err, rows) {
assert.ifError(err);
assert.equal(rows.length, 4);
assert.equal(rows.length, 3);
assert.equal(rows[0].id, 1);
assert.equal(rows[0].dt, '0000-00-00');
assert.equal(rows[0].dt, '1000-01-01');
assert.equal(rows[1].id, 2);
assert.equal(rows[1].dt, '2013-00-00');
assert.equal(rows[1].dt, '2013-01-01');
assert.equal(rows[2].id, 3);
assert.equal(rows[2].dt, '2013-03-00');
assert.equal(rows[3].id, 4);
assert(util.isDate(rows[3].dt));
assert.equal(rows[2].dt, '2013-03-01');
connection.end(assert.ifError);
});
});

common.getTestConnection({dateStrings: false}, function (err, connection) {
assert.ifError(err);

common.useTestDb(connection);

connection.query([
'CREATE TEMPORARY TABLE ?? (',
'`id` int(11) unsigned NOT NULL AUTO_INCREMENT,',
'`dt` DATE,',
'PRIMARY KEY (`id`)',
') ENGINE=InnoDB DEFAULT CHARSET=utf8'
].join('\n'), [table], assert.ifError);

connection.query('INSERT INTO ?? SET ?', [table, {dt: '1000-01-01'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '2013-01-01'}]);
connection.query('INSERT INTO ?? SET ?', [table, {dt: '2013-03-01'}]);

connection.query('SELECT * FROM ??', [table], function (err, rows) {
assert.ifError(err);
assert.equal(rows.length, 3);

assert.equal(rows[0].id, 1);
assert.equal(rows[0].dt.getFullYear(), 1000);
assert.equal(rows[0].dt.getMonth()+1, 1);
assert.equal(rows[0].dt.getDate(), 1);
assert(util.isDate(rows[0].dt));

assert.equal(rows[1].id, 2);
assert.equal(rows[1].dt.getFullYear(), 2013);
assert.equal(rows[1].dt.getMonth()+1, 1);
assert.equal(rows[1].dt.getDate(), 1);
assert(util.isDate(rows[1].dt));

assert.equal(rows[2].id, 3);
assert.equal(rows[2].dt.getFullYear(), 2013);
assert.equal(rows[2].dt.getMonth()+1, 3);
assert.equal(rows[2].dt.getDate(), 1);
assert(util.isDate(rows[2].dt));

connection.end(assert.ifError);
});
});
26 changes: 26 additions & 0 deletions test/integration/connection/test-reset-connection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var assert = require('assert');
var common = require('../../common');

common.getTestConnection(function (err, connection) {
assert.ifError(err);

connection.query('SET @var1 = ?', [1234], assert.ifError);

connection.query('SELECT @var1 AS var1', function(err, rows) {
assert.ifError(err);
assert.equal(rows.length, 1);
assert.equal(rows[0].var1, 1234);

connection.reset(function(err) {
assert.ifError(err);

connection.query('SELECT @var1 AS var1', function(err, rows2) {
assert.ifError(err);
assert.equal(rows2.length, 1);
assert.equal(rows2[0].var1, null);
});

connection.end(assert.ifError);
});
});
});