1 /*
2  * Copyright (C) 2019, HuntLabs
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 module hunt.database.driver.mysql.impl.codec.SimpleQueryCommandCodec;
18 
19 import hunt.database.driver.mysql.impl.codec.CommandType;
20 import hunt.database.driver.mysql.impl.codec.DataFormat;
21 import hunt.database.driver.mysql.impl.codec.MySQLEncoder;
22 import hunt.database.driver.mysql.impl.codec.Packets;
23 import hunt.database.driver.mysql.impl.codec.QueryCommandBaseCodec;
24 
25 import hunt.database.base.impl.command.CommandResponse;
26 import hunt.database.base.impl.command.SimpleQueryCommand;
27 
28 import hunt.Exceptions;
29 import hunt.logging;
30 import hunt.net.buffer.ByteBuf;
31 import hunt.text.Charset;
32 
33 /**
34  * 
35  */
36 class SimpleQueryCommandCodec(T) : QueryCommandBaseCodec!(T, SimpleQueryCommand!(T)) {
37 
38     this(SimpleQueryCommand!(T) cmd) {
39         super(cmd, DataFormat.TEXT);
40     }
41 
42     override
43     void encode(MySQLEncoder encoder) {
44         super.encode(encoder);
45         sendQueryCommand();
46     }
47 
48     override
49     protected void handleInitPacket(ByteBuf payload) {
50         // may receive ERR_Packet, OK_Packet, LOCAL INFILE Request, Text Resultset
51         int firstByte = payload.getUnsignedByte(payload.readerIndex());
52         // version(HUNT_DB_DEBUG_MORE) tracef("firstByte: %d", firstByte);
53         if (firstByte == Packets.OK_PACKET_HEADER) {
54             OkPacket okPacket = decodeOkPacketPayload(payload, StandardCharsets.UTF_8);
55             handleSingleResultsetDecodingCompleted(okPacket.serverStatusFlags(),
56                 cast(int) okPacket.affectedRows(), cast(int) okPacket.lastInsertId());
57         } else if (firstByte == Packets.ERROR_PACKET_HEADER) {
58             handleErrorPacketPayload(payload);
59         } else if (firstByte == 0xFB) {
60             //TODO LOCAL INFILE Request support
61             if(completionHandler !is null) {
62                 completionHandler(failedResponse!(ICommandResponse)(
63                         new UnsupportedOperationException("LOCAL INFILE is not supported for now")));
64             }
65         } else {
66             handleResultsetColumnCountPacketBody(payload);
67         }
68     }
69 
70     private void sendQueryCommand() {
71         ByteBuf packet = allocateBuffer();
72         // encode packet header
73         int packetStartIdx = packet.writerIndex();
74         packet.writeMediumLE(0); // will set payload length later by calculation
75         packet.writeByte(sequenceId);
76 
77         // encode packet payload
78         packet.writeByte(CommandType.COM_QUERY);
79         // version(HUNT_DB_DEBUG) {
80         //     infof("%s", cmd.sql());
81         // }
82         packet.writeCharSequence(cmd.sql(), StandardCharsets.UTF_8);
83 
84         // set payload length
85         int payloadLength = packet.writerIndex() - packetStartIdx - 4;
86         packet.setMediumLE(packetStartIdx, payloadLength);
87 
88         sendPacket(packet, payloadLength);
89     }
90 }