UNPKG

mysql2

Version:

fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS

128 lines (107 loc) 4.36 kB
var Buffer = require('safe-buffer').Buffer; var Packet = require('../packets/packet'); var StringParser = require('../parsers/string'); var CharsetToEncoding = require('../constants/charset_encodings.js'); // creating JS string is relatively expensive (compared to // reading few bytes from buffer) because all string properties // except for name are unlikely to be used we postpone // string conversion until property access // // TODO: watch for integration benchmarks (one with real network buffer) // there could be bad side effect as keeping reference to a buffer makes it // sit in the memory longer (usually until final .query() callback) // Latest v8 perform much better in regard to bufferer -> string conversion, // at some point of time this optimisation might become unnecessary // see https://github.com/sidorares/node-mysql2/pull/137 // function ColumnDefinition (packet) { this._buf = packet.buffer; this._catalogLength = packet.readLengthCodedNumber(); this._catalogStart = packet.offset; packet.offset += this._catalogLength; this._schemaLength = packet.readLengthCodedNumber(); this._schemaStart = packet.offset; packet.offset += this._schemaLength; this._tableLength = packet.readLengthCodedNumber(); this._tableStart = packet.offset; packet.offset += this._tableLength; this._orgTableLength = packet.readLengthCodedNumber(); this._orgTableStart = packet.offset; packet.offset += this._orgTableLength; // name is always used, don't make it lazy var _nameLength = packet.readLengthCodedNumber(); var _nameStart = packet.offset; packet.offset += _nameLength; this._orgNameLength = packet.readLengthCodedNumber(); this._orgNameStart = packet.offset; packet.offset += this._orgNameLength; packet.skip(1); // length of the following fields (always 0x0c) this.characterSet = packet.readInt16(); this.encoding = CharsetToEncoding[this.characterSet]; // TODO: use this.characterSet to get proper encoding // May be keep it cesu8 since MySQL meta data is actually cesu8 // https://github.com/sidorares/node-mysql2/pull/374 this.name = StringParser.decode(this._buf.slice(_nameStart, _nameStart + _nameLength), this.encoding); this.columnLength = packet.readInt32(); this.columnType = packet.readInt8(); this.flags = packet.readInt16(); this.decimals = packet.readInt8(); } var addString = function (name) { Object.defineProperty(ColumnDefinition.prototype, name, {get: function () { var start = this['_' + name + 'Start']; var end = start + this['_' + name + 'Length']; return StringParser.decode(this._buf.slice(start, end), this.encoding); }}); }; addString('catalog'); addString('schema'); addString('table'); addString('orgTable'); addString('orgName'); // node-mysql compatibility: alias "db" to "schema" Object.defineProperty(ColumnDefinition.prototype, 'db', {get: function () { var start = this._schemaStart; var end = start._shemaLength; return this._buf.utf8Slice(start, end); }}); ColumnDefinition.prototype.inspect = function () { return { catalog : this.catalog, schema : this.schema, name : this.name, orgName : this.orgName, table : this.table, orgTable : this.orgTable, characterSet: this.characterSet, columnLength: this.columnLength, columnType : this.columnType, flags : this.flags, decimals : this.decimals }; }; var fields = ['catalog', 'schema', 'table', 'orgTable', 'name', 'orgName']; ColumnDefinition.toPacket = function (column, sequenceId) { var length = 17; // = 4 padding + 1 + 12 for the rest fields.forEach(function (field) { length += Packet.lengthCodedStringLength(column[field], CharsetToEncoding[column.characterSet]); }); var buffer = Buffer.allocUnsafe(length); function writeField (name) { packet.writeLengthCodedString(column[name], CharsetToEncoding[column.characterSet]); } var packet = new Packet(sequenceId, buffer, 0, length); packet.offset = 4; fields.forEach(writeField); packet.writeInt8(0x0c); packet.writeInt16(column.characterSet); packet.writeInt32(column.columnLength); packet.writeInt8(column.columnType); packet.writeInt16(column.flags); packet.writeInt8(column.decimals); packet.writeInt16(0); // filler return packet; }; module.exports = ColumnDefinition;