Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add reverse type lookup for small performance gain
closes #2170
- Loading branch information
1 parent
d916479
commit 5569e02
Showing
6 changed files
with
181 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,72 @@ | ||
// Manually extracted from mysql-5.7.9/include/mysql.h.pp | ||
// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html | ||
exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html) | ||
exports.TINY = 0x01; // aka TINYINT, 1 byte | ||
exports.SHORT = 0x02; // aka SMALLINT, 2 bytes | ||
exports.LONG = 0x03; // aka INT, 4 bytes | ||
exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes | ||
exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes | ||
exports.NULL = 0x06; // NULL (used for prepared statements, I think) | ||
exports.TIMESTAMP = 0x07; // aka TIMESTAMP | ||
exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes | ||
exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes | ||
exports.DATE = 0x0a; // aka DATE | ||
exports.TIME = 0x0b; // aka TIME | ||
exports.DATETIME = 0x0c; // aka DATETIME | ||
exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask) | ||
exports.NEWDATE = 0x0e; // aka ? | ||
exports.VARCHAR = 0x0f; // aka VARCHAR (?) | ||
exports.BIT = 0x10; // aka BIT, 1-8 byte | ||
exports.TIMESTAMP2 = 0x11; // aka TIMESTAMP with fractional seconds | ||
exports.DATETIME2 = 0x12; // aka DATETIME with fractional seconds | ||
exports.TIME2 = 0x13; // aka TIME with fractional seconds | ||
exports.JSON = 0xf5; // aka JSON | ||
exports.NEWDECIMAL = 0xf6; // aka DECIMAL | ||
exports.ENUM = 0xf7; // aka ENUM | ||
exports.SET = 0xf8; // aka SET | ||
exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT | ||
exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT | ||
exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT | ||
exports.BLOB = 0xfc; // aka BLOB, TEXT | ||
exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY | ||
exports.STRING = 0xfe; // aka CHAR, BINARY | ||
exports.GEOMETRY = 0xff; // aka GEOMETRY | ||
/** | ||
* MySQL type constants | ||
* | ||
* Extracted from version 5.7.19 | ||
* | ||
* !! Generated by generate-type-constants.js, do not modify by hand !! | ||
*/ | ||
|
||
exports.DECIMAL = 0; | ||
exports.TINY = 1; | ||
exports.SHORT = 2; | ||
exports.LONG = 3; | ||
exports.FLOAT = 4; | ||
exports.DOUBLE = 5; | ||
exports.NULL = 6; | ||
exports.TIMESTAMP = 7; | ||
exports.LONGLONG = 8; | ||
exports.INT24 = 9; | ||
exports.DATE = 10; | ||
exports.TIME = 11; | ||
exports.DATETIME = 12; | ||
exports.YEAR = 13; | ||
exports.NEWDATE = 14; | ||
exports.VARCHAR = 15; | ||
exports.BIT = 16; | ||
exports.TIMESTAMP2 = 17; | ||
exports.DATETIME2 = 18; | ||
exports.TIME2 = 19; | ||
exports.JSON = 245; | ||
exports.NEWDECIMAL = 246; | ||
exports.ENUM = 247; | ||
exports.SET = 248; | ||
exports.TINY_BLOB = 249; | ||
exports.MEDIUM_BLOB = 250; | ||
exports.LONG_BLOB = 251; | ||
exports.BLOB = 252; | ||
exports.VAR_STRING = 253; | ||
exports.STRING = 254; | ||
exports.GEOMETRY = 255; | ||
|
||
// Lookup-by-number table | ||
exports[0] = 'DECIMAL'; | ||
exports[1] = 'TINY'; | ||
exports[2] = 'SHORT'; | ||
exports[3] = 'LONG'; | ||
exports[4] = 'FLOAT'; | ||
exports[5] = 'DOUBLE'; | ||
exports[6] = 'NULL'; | ||
exports[7] = 'TIMESTAMP'; | ||
exports[8] = 'LONGLONG'; | ||
exports[9] = 'INT24'; | ||
exports[10] = 'DATE'; | ||
exports[11] = 'TIME'; | ||
exports[12] = 'DATETIME'; | ||
exports[13] = 'YEAR'; | ||
exports[14] = 'NEWDATE'; | ||
exports[15] = 'VARCHAR'; | ||
exports[16] = 'BIT'; | ||
exports[17] = 'TIMESTAMP2'; | ||
exports[18] = 'DATETIME2'; | ||
exports[19] = 'TIME2'; | ||
exports[245] = 'JSON'; | ||
exports[246] = 'NEWDECIMAL'; | ||
exports[247] = 'ENUM'; | ||
exports[248] = 'SET'; | ||
exports[249] = 'TINY_BLOB'; | ||
exports[250] = 'MEDIUM_BLOB'; | ||
exports[251] = 'LONG_BLOB'; | ||
exports[252] = 'BLOB'; | ||
exports[253] = 'VAR_STRING'; | ||
exports[254] = 'STRING'; | ||
exports[255] = 'GEOMETRY'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#!/usr/bin/env node | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var script = path.basename(__filename); | ||
|
||
var srcDir = process.argv[2]; | ||
if (!srcDir) { | ||
var args = []; | ||
args[0] = process.argv[0].indexOf(' ') !== -1 | ||
? '"' + process.argv[0] + '"' | ||
: process.argv[0]; | ||
args[1] = process.argv[1].indexOf(' ') !== -1 | ||
? '"' + process.argv[1] + '"' | ||
: process.argv[1]; | ||
args[2] = path.join('path', 'to', 'mysql', 'src'); | ||
console.error('Usage: ' + args.join(' ')); | ||
process.exit(1); | ||
} | ||
|
||
var types = extractTypes(srcDir); | ||
var targetFile = path.join(__dirname, '..', 'lib', 'protocol', 'constants', 'types.js'); | ||
var stream = fs.createWriteStream(targetFile); | ||
var version = extractMySqlVersion(srcDir); | ||
|
||
stream.write('/**\n * MySQL type constants\n *\n * Extracted from version ' + version + '\n *\n * !! Generated by ' + script + ', do not modify by hand !!\n */\n\n'); | ||
|
||
var alignment = types.reduce(maxLength, 0); | ||
for (var i = 0; i < types.length; i++) { | ||
if (i in types) { | ||
stream.write('exports.' + types[i] + (new Array(alignment - types[i].length + 1)).join(' ') + ' = ' + i + ';\n'); | ||
} | ||
} | ||
|
||
stream.write('\n// Lookup-by-number table\n'); | ||
|
||
var alignment = String(types.length).length; | ||
for (var i = 0; i < types.length; i++) { | ||
if (i in types) { | ||
stream.write('exports[' + i + ']' + (new Array(alignment - String(i).length + 1)).join(' ') + ' = \'' + types[i] + '\';\n'); | ||
} | ||
} | ||
|
||
console.log('Wrote constants to ' + targetFile); | ||
|
||
function extractMySqlVersion(srcDir) { | ||
var versionFile = path.join(srcDir, 'VERSION'); | ||
var contents = fs.readFileSync(versionFile, 'utf-8'); | ||
var dictionary = Object.create(null); | ||
|
||
contents.split('\n').forEach(function (line) { | ||
var pair = line.split('='); | ||
var key = pair[0]; | ||
var val = pair.slice(1).join('=').trimRight(); | ||
dictionary[key] = val; | ||
}); | ||
|
||
return dictionary.MYSQL_VERSION_MAJOR + '.' + | ||
dictionary.MYSQL_VERSION_MINOR + '.' + | ||
dictionary.MYSQL_VERSION_PATCH; | ||
} | ||
|
||
function extractTypes(srcDir) { | ||
var headerFile = path.join(srcDir, 'include', 'mysql.h.pp'); | ||
var contents = fs.readFileSync(headerFile, 'utf-8'); | ||
var enumRegexp = /typedef enum enum_field_types {([^}]*)}/m; | ||
var match = enumRegexp.exec(contents); | ||
var regexp = /([A-Z0-9_]+)(?: *= *([0-9]+))?/g; | ||
|
||
if (!match) { | ||
throw new Error('Cannot locate enum enum_field_types in "' + headerFile + '"'); | ||
} | ||
|
||
var enumContents = match[1]; | ||
var index = 0; | ||
var types = []; | ||
|
||
while ((match = regexp.exec(enumContents))) { | ||
var name = match[1]; | ||
var num = Number(match[2]) || index++; | ||
|
||
if (name.indexOf('MYSQL_TYPE_') === 0) { | ||
types[num] = name.substring(11); | ||
} | ||
} | ||
|
||
return types; | ||
} | ||
|
||
function maxLength(max, value) { | ||
return Math.max(max, value.length); | ||
} |