Skip to content
Merged
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
9 changes: 9 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var SqlString = require('sqlstring');

var Connection = require('./lib/connection.js');
var ConnectionConfig = require('./lib/connection_config.js');
var parserCache = require("./lib/parsers/parser_cache");

module.exports.createConnection = function(opts) {
return new Connection({ config: new ConnectionConfig(opts) });
Expand Down Expand Up @@ -61,3 +62,11 @@ exports.__defineGetter__('Charsets', function() {
exports.__defineGetter__('CharsetToEncoding', function() {
return require('./lib/constants/charset_encodings.js');
});

exports.setMaxParserCache = function (max) {
parserCache.setMaxCache(max);
};

exports.clearParserCache = function () {
parserCache.clearCache();
};
10 changes: 2 additions & 8 deletions lib/commands/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var Packets = require('../packets/index.js');

var objectAssign = require('object-assign');

var compileParser = require('../compile_binary_parser.js');
var getBinaryParser = require('../parsers/binary_parser.js');

function Execute(options, callback) {
Command.call(this);
Expand All @@ -33,13 +33,7 @@ function Execute(options, callback) {
util.inherits(Execute, Command);

Execute.prototype.buildParserFromFields = function(fields, connection) {
var parserKey = connection.keyFromFields(fields, this.options);
var parser = connection.binaryProtocolParsers[parserKey];
if (!parser) {
parser = compileParser(fields, this.options, connection.config);
connection.binaryProtocolParsers[parserKey] = parser;
}
return parser;
return getBinaryParser(fields, this.options, connection.config);
};

Execute.prototype.start = function(packet, connection) {
Expand Down
11 changes: 3 additions & 8 deletions lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var objectAssign = require('object-assign');

var Command = require('./command.js');
var Packets = require('../packets/index.js');
var compileParser = require('../compile_text_parser.js');
var getTextParser = require('../parsers/text_parser.js');
var ServerStatus = require('../constants/server_status.js');
var CharsetToEncoding = require('../constants/charset_encodings.js');

Expand Down Expand Up @@ -195,15 +195,10 @@ Query.prototype.readField = function(packet, connection) {
}

// last field received
if (this._receivedFieldsCount == this._fieldCount) {
if (this._receivedFieldsCount === this._fieldCount) {
var fields = this._fields[this._resultIndex];
this.emit('fields', fields);
var parserKey = connection.keyFromFields(fields, this.options);
this._rowParser = connection.textProtocolParsers[parserKey];
if (!this._rowParser) {
this._rowParser = compileParser(fields, this.options, connection.config);
connection.textProtocolParsers[parserKey] = this._rowParser;
}
this._rowParser = getTextParser(fields, this.options, connection.config);
return Query.prototype.fieldsEOF;
}
return Query.prototype.readField;
Expand Down
32 changes: 0 additions & 32 deletions lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,6 @@ function Connection(opts) {
}
});

// TODO: make it lru cache
// https://github.com/mercadolibre/node-simple-lru-cache
// or https://github.com/rsms/js-lru
// or https://github.com/monsur/jscache
// or https://github.com/isaacs/node-lru-cache
//
// key is field.name + ':' + field.columnType + ':' field.flags + '/'
this.textProtocolParsers = {};

// TODO: not sure if cache should be separate (same key as with textProtocolParsers)
// or part of prepared statements cache (key is sql query)
this.binaryProtocolParsers = {};

this.serverCapabilityFlags = 0;
this.authorized = false;

Expand Down Expand Up @@ -639,25 +626,6 @@ Connection.prototype.resume = function resume() {
this.stream.resume();
};

Connection.prototype.keyFromFields = function keyFromFields(fields, options) {
var res =
typeof options.nestTables +
'/' +
options.nestTables +
'/' +
options.rowsAsArray +
options.supportBigNumbers +
'/' +
options.bigNumberStrings +
'/' +
typeof options.typeCast;
for (var i = 0; i < fields.length; ++i) {
res +=
'/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags;
}
return res;
};

Connection.statementKey = function(options) {
return (
typeof options.nestTables +
Expand Down
18 changes: 11 additions & 7 deletions lib/compile_binary_parser.js → lib/parsers/binary_parser.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var FieldFlags = require('./constants/field_flags.js');
var Charsets = require('./constants/charsets.js');
var CharsetToEncoding = require('./constants/charset_encodings.js');
var Types = require('./constants/types.js');
var srcEscape = require('./helpers').srcEscape;
var FieldFlags = require('../constants/field_flags.js');
var Charsets = require('../constants/charsets.js');
var CharsetToEncoding = require('../constants/charset_encodings.js');
var Types = require('../constants/types.js');
var srcEscape = require('../helpers').srcEscape;
var genFunc = require('generate-function');

var parserCache = require('./parser_cache.js');
var typeNames = [];
for (var t in Types) {
typeNames[Types[t]] = t;
Expand Down Expand Up @@ -181,4 +181,8 @@ function readCodeFor(field, config, options, fieldNum) {
}
}

module.exports = compile;
function getBinaryParser(fields, options, config) {
return parserCache.getParser('binary', fields, options, config, compile);
}

module.exports = getBinaryParser;
53 changes: 53 additions & 0 deletions lib/parsers/parser_cache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var LRU = require('lru-cache');

var parserCache = new LRU({
max: 15000
});

function keyFromFields(type, fields, options) {
var res =
type +
'/' +
typeof options.nestTables +
'/' +
options.nestTables +
'/' +
options.rowsAsArray +
options.supportBigNumbers +
'/' +
options.bigNumberStrings +
'/' +
typeof options.typeCast;
for (var i = 0; i < fields.length; ++i) {
res +=
'/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags;
}
return res;
}

function getParser(type, fields, options, config, compiler) {
var key = keyFromFields(type, fields, options);
var parser = parserCache.get(key);

if (parser) {
return parser;
}

parser = compiler(fields, options, config);
parserCache.set(key, parser);
return parser;
}

function setMaxCache(max) {
parserCache.max = max;
}

function clearCache() {
parserCache.reset();
}

module.exports = {
getParser: getParser,
setMaxCache: setMaxCache,
clearCache: clearCache
};
14 changes: 9 additions & 5 deletions lib/compile_text_parser.js → lib/parsers/text_parser.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
var Types = require('./constants/types.js');
var Charsets = require('./constants/charsets.js');
var CharsetToEncoding = require('./constants/charset_encodings.js');
var srcEscape = require('./helpers').srcEscape;
var Types = require('../constants/types.js');
var Charsets = require('../constants/charsets.js');
var CharsetToEncoding = require('../constants/charset_encodings.js');
var srcEscape = require('../helpers').srcEscape;
var genFunc = require('generate-function');
var parserCache = require('./parser_cache.js');

var typeNames = [];
for (var t in Types) {
Expand Down Expand Up @@ -189,4 +190,7 @@ function readCodeFor(type, charset, encodingExpr, config, options) {
}
}

module.exports = compile;
function getTextParser(fields, options, config) {
return parserCache.getParser('text', fields, options, config, compile);
}
module.exports = getTextParser;