-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.cpp
More file actions
124 lines (103 loc) · 3.17 KB
/
Copy pathparser.cpp
File metadata and controls
124 lines (103 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <iomanip>
#include "parser.hpp"
#include "debug.hpp"
#include "logger.hpp"
namespace db_proxy {
namespace My {
Parser::~Parser(){
prepared_stmts.clear();
}
bool Parser::parse(const uint8_t *data, size_t size) {
auto logger = LoggerRegistry::instance().get("logger");
// some magick to skip auth phase
if(packets_ < 3)
{
packets_++;
return true;
}
// command phase
size_t offset = 0;
PacketHeader header = read_header(data, size);
offset += 4;
if(header.sequence_id == 0) {
current_state_ = State::PARSE_QUERY;
}
switch(current_state_) {
case State::PARSE_QUERY:
{
auto type = data[offset++];
std::string s;
switch(type) {
case COM_QUERY:
{
s.assign(reinterpret_cast<char*>(const_cast<uint8_t*>(&data[offset])), header.payload_length - 1);
logger->log() << "Execute query: " << s << '\n';
current_state_ = State::PARSE_QUERY_RESPONSE;
}
break;
case COM_STMT_PREPARE:
last_stmt_.assign(reinterpret_cast<char*>(const_cast<uint8_t*>(&data[offset])), header.payload_length - 1);
logger->log() << "Prepare statement: " << last_stmt_ << '\n';
current_state_ = State::PARSE_STMT_RESPONSE;
break;
case COM_STMT_SEND_LONG_DATA:
logger->log() << "COM_STMT_SEND_LONG_DATA\n";
current_state_ = State::PARSE_QUERY_RESPONSE;
break;
case COM_STMT_EXECUTE:
{
uint32_t stmt_id = read_u4(data+offset);
auto stmt = prepared_stmts[stmt_id];
offset += 5;
logger->log() << "Execute prepared statement: " << stmt.first;
if(stmt.second > 0) {
uint32_t bitmap = (stmt.second + 7) / 8;
offset += bitmap;
uint32_t bound_flag = data[offset];
if (bound_flag == 1) {
}
}
current_state_ = State::PARSE_STMT_EXECUTE_RESPONSE;
logger->log() << '\n';
}
break;
case COM_STMT_CLOSE:
{
uint32_t stmt_id = read_u4(data+offset);
auto stmt = prepared_stmts[stmt_id];
logger->log() << "Deallocate prepared statement: " << stmt.first << '\n';
prepared_stmts.erase(stmt_id);
}
break;
}
}
break;
case State::PARSE_QUERY_RESPONSE:
break;
case State::PARSE_STMT_RESPONSE:
{
int status = data[offset++];
if (status == 0) // OK
{
uint32_t stmt_id = read_u4(data+offset);
offset += 4;
uint32_t num_params = read_u2(data+offset+2);
prepared_stmts.emplace(stmt_id, std::make_pair(last_stmt_, num_params));
}
}
break;
case State::PARSE_STMT_EXECUTE_RESPONSE:
break;
}
return true;
}
PacketHeader Parser::read_header(const uint8_t *data, size_t size)
{
PacketHeader header;
header.payload_length = read_u3(data);
header.sequence_id = data[3];
return header;
}
} // namespace My
} // namespace db_proxy