96 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			96 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | const Types = require('../constants/types'); | ||
|  | const Packet = require('../packets/packet'); | ||
|  | 
 | ||
|  | const binaryReader = new Array(256); | ||
|  | 
 | ||
|  | class BinaryRow { | ||
|  |   constructor(columns) { | ||
|  |     this.columns = columns || []; | ||
|  |   } | ||
|  | 
 | ||
|  |   static toPacket(columns, encoding) { | ||
|  |     // throw new Error('Not implemented');
 | ||
|  |     const sequenceId = 0; // TODO remove, this is calculated now in connecton
 | ||
|  |     let length = 0; | ||
|  |     columns.forEach((val) => { | ||
|  |       if (val === null || typeof val === 'undefined') { | ||
|  |         ++length; | ||
|  |         return; | ||
|  |       } | ||
|  |       length += Packet.lengthCodedStringLength(val.toString(10), encoding); | ||
|  |     }); | ||
|  | 
 | ||
|  |     length = length + 2; | ||
|  | 
 | ||
|  |     const buffer = Buffer.allocUnsafe(length + 4); | ||
|  |     const packet = new Packet(sequenceId, buffer, 0, length + 4); | ||
|  |     packet.offset = 4; | ||
|  | 
 | ||
|  |     packet.writeInt8(0); | ||
|  | 
 | ||
|  |     let bitmap = 0; | ||
|  |     let bitValue = 1; | ||
|  |     columns.forEach((parameter) => { | ||
|  |       if (parameter.type === Types.NULL) { | ||
|  |         bitmap += bitValue; | ||
|  |       } | ||
|  |       bitValue *= 2; | ||
|  |       if (bitValue === 256) { | ||
|  |         packet.writeInt8(bitmap); | ||
|  |         bitmap = 0; | ||
|  |         bitValue = 1; | ||
|  |       } | ||
|  |     }); | ||
|  |     if (bitValue !== 1) { | ||
|  |       packet.writeInt8(bitmap); | ||
|  |     } | ||
|  | 
 | ||
|  |     columns.forEach((val) => { | ||
|  |       if (val === null) { | ||
|  |         packet.writeNull(); | ||
|  |         return; | ||
|  |       } | ||
|  |       if (typeof val === 'undefined') { | ||
|  |         packet.writeInt8(0); | ||
|  |         return; | ||
|  |       } | ||
|  |       packet.writeLengthCodedString(val.toString(10), encoding); | ||
|  |     }); | ||
|  |     return packet; | ||
|  |   } | ||
|  | 
 | ||
|  |   // TODO: complete list of types...
 | ||
|  |   static fromPacket(fields, packet) { | ||
|  |     const columns = new Array(fields.length); | ||
|  |     packet.readInt8(); // TODO check it's 0
 | ||
|  |     const nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8); | ||
|  |     // TODO: read and interpret null bitmap
 | ||
|  |     packet.skip(nullBitmapLength); | ||
|  |     for (let i = 0; i < columns.length; ++i) { | ||
|  |       columns[i] = binaryReader[fields[i].columnType].apply(packet); | ||
|  |     } | ||
|  |     return new BinaryRow(columns); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | // TODO: replace with constants.MYSQL_TYPE_*
 | ||
|  | binaryReader[Types.DECIMAL] = Packet.prototype.readLengthCodedString; | ||
|  | binaryReader[1] = Packet.prototype.readInt8; // tiny
 | ||
|  | binaryReader[2] = Packet.prototype.readInt16; // short
 | ||
|  | binaryReader[3] = Packet.prototype.readInt32; // long
 | ||
|  | binaryReader[4] = Packet.prototype.readFloat; // float
 | ||
|  | binaryReader[5] = Packet.prototype.readDouble; // double
 | ||
|  | binaryReader[6] = Packet.prototype.assertInvalid; // null, should be skipped vie null bitmap
 | ||
|  | binaryReader[7] = Packet.prototype.readTimestamp; // timestamp, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIMESTAMP
 | ||
|  | binaryReader[8] = Packet.prototype.readInt64; // long long
 | ||
|  | binaryReader[9] = Packet.prototype.readInt32; // int24
 | ||
|  | binaryReader[10] = Packet.prototype.readTimestamp; // date
 | ||
|  | binaryReader[11] = Packet.prototype.readTime; // time, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIME
 | ||
|  | binaryReader[12] = Packet.prototype.readDateTime; // datetime, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_DATETIME
 | ||
|  | binaryReader[13] = Packet.prototype.readInt16; // year
 | ||
|  | binaryReader[Types.VAR_STRING] = Packet.prototype.readLengthCodedString; // var string
 | ||
|  | 
 | ||
|  | module.exports = BinaryRow; |