| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- 'use strict';
- const Packet = require('../packets/packet.js');
- const CommandCode = require('../constants/commands.js');
- const StringParser = require('../parsers/string.js');
- const CharsetToEncoding = require('../constants/charset_encodings.js');
- const ClientConstants = require('../constants/client.js');
- const Types = require('../constants/types.js');
- const { toParameter } = require('./encode_parameter.js');
- class Query {
- constructor(sql, charsetNumber, attributes, clientFlags) {
- this.query = sql;
- this.charsetNumber = charsetNumber;
- this.encoding = CharsetToEncoding[charsetNumber];
- this.attributes = attributes;
- this.clientFlags = clientFlags || 0;
- }
- serializeToBuffer(buffer) {
- const useQueryAttributes =
- this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
- const sqlBuf = StringParser.encode(this.query, this.encoding);
- const packet = new Packet(0, buffer, 0, buffer.length);
- packet.offset = 4;
- packet.writeInt8(CommandCode.QUERY);
- if (useQueryAttributes) {
- const attrs = this.attributes;
- const names = attrs ? Object.keys(attrs) : [];
- const paramCount = names.length;
- packet.writeLengthCodedNumber(paramCount);
- packet.writeLengthCodedNumber(1); // parameter_set_count, always 1
- if (paramCount > 0) {
- const parameters = names.map((name) =>
- toParameter(attrs[name], this.encoding, 'local')
- );
- // null bitmap
- let bitmap = 0;
- let bitValue = 1;
- parameters.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);
- }
- packet.writeInt8(1); // new_params_bind_flag
- // types and names
- for (let i = 0; i < paramCount; i++) {
- packet.writeInt8(parameters[i].type);
- packet.writeInt8(0); // unsigned flag
- packet.writeLengthCodedString(names[i], this.encoding);
- }
- // values
- parameters.forEach((parameter) => {
- if (parameter.type !== Types.NULL) {
- parameter.writer.call(packet, parameter.value);
- }
- });
- }
- }
- packet.writeBuffer(sqlBuf);
- return packet;
- }
- toPacket() {
- const useQueryAttributes =
- this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
- if (!useQueryAttributes) {
- const buf = StringParser.encode(this.query, this.encoding);
- const length = 5 + buf.length;
- const buffer = Buffer.allocUnsafe(length);
- const packet = new Packet(0, buffer, 0, length);
- packet.offset = 4;
- packet.writeInt8(CommandCode.QUERY);
- packet.writeBuffer(buf);
- return packet;
- }
- // dry run to calculate required buffer length
- const p = this.serializeToBuffer(Packet.MockBuffer());
- return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
- }
- }
- module.exports = Query;
|