Skip to content

Commit f37c25e

Browse files
authored
Merge pull request #401 from sidorares/lru-cache
Lru cache
2 parents 7c06666 + 1f4e73b commit f37c25e

File tree

6 files changed

+19
-11
lines changed

6 files changed

+19
-11
lines changed

documentation/Prepared-Statements.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ connection.prepare('select ? + ? as tests', function(err, statement) {
3232
});
3333
```
3434
Note that you should not use statement after connection reset (`changeUser()` or disconnect). Statement scope is connection, you need to prepare statement for each new connection in order to use it.
35+
36+
# Configuration
37+
38+
`maxPreparedStatements` : We keep the cached statements in a [lru-cache](https://github.com/isaacs/node-lru-cache). Default size is `16000` but you can use this option to override it. Any statements that are dropped from cache will be `closed`.

lib/commands/change_user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ ChangeUser.prototype.start = function (packet, connection) {
3737
this.currentConfig.database = this.database;
3838
this.currentConfig.charsetNumber = this.charsetNumber;
3939
// reset prepared statements cache as all statements become invalid after changeUser
40-
connection._statements = {};
40+
connection._statements.reset();
4141
connection.writePacket(packet.toPacket());
4242
return ChangeUser.prototype.handshakeResult;
4343
};

lib/connection.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ var Tls = require('tls');
44
var Timers = require('timers');
55
var EventEmitter = require('events').EventEmitter;
66
var Queue = require('double-ended-queue');
7-
87
var SqlString = require('sqlstring');
8+
var LRU = require('lru-cache');
99

1010
var PacketParser = require('./packet_parser.js');
1111
var Packet = require('./packets/packet.js');
@@ -51,7 +51,10 @@ function Connection (opts)
5151
this._paused = false;
5252
this._paused_packets = new Queue();
5353

54-
this._statements = {};
54+
this._statements = LRU({
55+
max: this.config.maxPreparedStatements,
56+
dispose: function (key, statement) { statement.close(); }
57+
});
5558

5659
// TODO: make it lru cache
5760
// https://github.com/mercadolibre/node-simple-lru-cache
@@ -498,9 +501,9 @@ Connection.prototype.unprepare = function unprepare (sql) {
498501
options.sql = sql;
499502
}
500503
var key = statementKey(options);
501-
var stmt = this._statements[key];
504+
var stmt = this._statements.get(key);
502505
if (stmt) {
503-
this._statements[key] = null;
506+
this._statements.del(key);
504507
stmt.close();
505508
}
506509
return stmt;
@@ -531,7 +534,7 @@ Connection.prototype.execute = function execute (sql, values, cb) {
531534

532535
var connection = this;
533536
var key = statementKey(options);
534-
var statement = connection._statements[key];
537+
var statement = connection._statements.get(key);
535538

536539
options.statement = statement;
537540
var executeCommand = new Commands.Execute(options, cb);
@@ -547,7 +550,7 @@ Connection.prototype.execute = function execute (sql, values, cb) {
547550
return;
548551
}
549552
executeCommand.statement = stmt;
550-
connection._statements[key] = stmt;
553+
connection._statements.set(key, stmt);
551554
connection.addCommand(executeCommand);
552555
});
553556
} else {

lib/connection_config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ function ConnectionConfig (options) {
7070
options.flags || '');
7171

7272
this.connectAttributes = options.connectAttributes;
73+
this.maxPreparedStatements = options.maxPreparedStatements || 16000;
7374
}
7475

7576
ConnectionConfig.mergeFlags = function (default_flags, user_flags) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"double-ended-queue": "2.1.0-0",
3838
"iconv-lite": "^0.4.13",
3939
"long": "^3.2.0",
40+
"lru-cache": "^4.0.1",
4041
"named-placeholders": "1.1.1",
4142
"object-assign": "^4.1.0",
4243
"readable-stream": "2.1.5",

test/integration/connection/test-execute-cached.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ connection.execute(q, [123], function (err, _rows, _fields) {
2424
throw err;
2525
}
2626
rows2 = _rows;
27-
assert(Object.keys(connection._statements).length == 1);
28-
assert(connection._statements[key].query == q);
29-
assert(connection._statements[key].parameters.length == 1);
27+
assert(connection._statements.length == 1);
28+
assert(connection._statements.get(key).query == q);
29+
assert(connection._statements.get(key).parameters.length == 1);
3030
connection.end();
3131
});
3232
});
@@ -38,4 +38,3 @@ process.on('exit', function () {
3838
assert.deepEqual(rows1, [{'test': 125}]);
3939
assert.deepEqual(rows2, [{'test': 126}]);
4040
});
41-

0 commit comments

Comments
 (0)