Skip to content

Commit a98337c

Browse files
authored
update MySQLImpl to support character_set_results (#77)
* update MySQLImpl to support character_set_results * remove WFComplexClientTask::is_user_request(). Co-authored-by: XieHan <XieHan@sogou-inc.com>
1 parent 8cd8960 commit a98337c

4 files changed

Lines changed: 57 additions & 40 deletions

File tree

src/factory/MySQLTaskImpl.cc

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
limitations under the License.
1515
1616
Authors: Wu Jiaxu (wujiaxu@sogou-inc.com)
17+
Xie Han (xiehan@sogou-inc.com)
1718
Li Yingxin (liyingxin@sogou-inc.com)
1819
*/
1920

@@ -54,14 +55,15 @@ class ComplexMySQLTask : public WFComplexClientTask<MySQLRequest, MySQLResponse>
5455
std::string username_;
5556
std::string password_;
5657
std::string db_;
58+
std::string res_charset_;
5759
int character_set_;
58-
bool succ_;
5960
#define NO_TRANSACTION -1
6061
#define TRANSACTION_OUT 0
6162
#define TRANSACTION_IN 1
6263
#define TRANSACTION_CONN_RESET -2
6364
int transaction_state_;
6465
#define PREPARE_IN 2
66+
bool succ_;
6567
bool is_user_request_;
6668

6769
public:
@@ -125,35 +127,44 @@ bool ComplexMySQLTask::check_request()
125127
CommMessageOut *ComplexMySQLTask::message_out()
126128
{
127129
long long seqid = this->get_seq();
130+
MySQLRequest *req;
128131

129132
if (seqid == 0)
130-
{
131-
succ_ = false;
132-
is_user_request_ = false;
133-
return new MySQLHandshakeRequest;
134-
}
133+
req = new MySQLHandshakeRequest;
135134
else if (seqid == 1)
136135
{
137-
succ_ = false;
138-
is_user_request_ = false;
139136
auto *auth_req = new MySQLAuthRequest;
140137
auto *conn = this->get_connection();
141138
auto *ctx = static_cast<handshake_ctx *>(conn->get_context());
142139

143140
auth_req->set_seqid(ctx->mysql_seqid);
144141
auth_req->set_challenge(ctx->challenge);
145142
delete ctx;
146-
conn->set_context(nullptr, nullptr);
143+
conn->set_context(NULL, nullptr);
147144
auth_req->set_auth(username_, password_, db_, character_set_);
148-
return auth_req;
145+
req = auth_req;
146+
}
147+
else if (seqid == 2 && res_charset_.size() != 0)
148+
{
149+
req = new MySQLRequest;
150+
req->set_query("SET NAMES " + res_charset_);
151+
}
152+
else
153+
req = NULL;
154+
155+
if (req)
156+
{
157+
succ_ = false;
158+
is_user_request_ = false;
159+
return req;
149160
}
150161

151162
if (is_transaction())
152163
{
153164
auto *target = static_cast<RouteManager::RouteTarget *>(this->get_target());
154165

155-
if (seqid == 2 && ((target->state & TRANSACTION_IN) ||
156-
(target->state & PREPARE_IN))) // CONN RESET
166+
if (seqid <= 3 && (seqid == 2 || res_charset_.size() != 0) &&
167+
(target->state & (TRANSACTION_IN | PREPARE_IN)))
157168
{
158169
target->state = TRANSACTION_OUT;
159170
transaction_state_ = TRANSACTION_CONN_RESET;
@@ -210,6 +221,8 @@ CommMessageIn *ComplexMySQLTask::message_in()
210221
return new MySQLHandshakeResponse;
211222
else if (seqid == 1)
212223
return new MySQLAuthResponse;
224+
else if (seqid == 2 && !is_user_request_)
225+
return new MySQLResponse;
213226

214227
return this->WFClientTask::message_in();
215228
}
@@ -242,24 +255,21 @@ int ComplexMySQLTask::keep_alive_timeout()
242255
succ_ = true;
243256
}
244257
}
245-
else if (seqid == 1)
258+
else if (!is_user_request_)
246259
{
247-
auto *resp = static_cast<MySQLAuthResponse *>(this->get_message_in());
260+
auto *resp = static_cast<MySQLResponse *>(this->get_message_in());
248261

249262
succ_ = resp->is_ok_packet();
250-
if (succ_)
251-
{
252-
return is_transaction() ? MYSQL_KEEPALIVE_TRANSACTION
253-
: MYSQL_KEEPALIVE_DEFAULT;
254-
}
255-
else
263+
if (!succ_)
256264
{
257-
this->resp = std::move(*static_cast<MySQLResponse *>(resp));
265+
this->resp = std::move(*resp);
258266
return 0;
259267
}
260268
}
269+
else
270+
return this->keep_alive_timeo;
261271

262-
return this->keep_alive_timeo;
272+
return MYSQL_KEEPALIVE_DEFAULT;
263273
}
264274

265275
/*
@@ -427,9 +437,11 @@ bool ComplexMySQLTask::init_success()
427437
{
428438
auto query_kv = URIParser::split_query(uri_.query);
429439

430-
for (const auto& kv : query_kv)
440+
for (auto& kv : query_kv)
431441
{
432-
if (strcasecmp(kv.first.c_str(), "character_set") == 0)
442+
if (strcasecmp(kv.first.c_str(), "transaction") == 0)
443+
transaction = std::move(kv.second);
444+
else if (strcasecmp(kv.first.c_str(), "character_set") == 0)
433445
{
434446
character_set_ = __mysql_get_character_set(kv.second);
435447
if (character_set_ < 0)
@@ -439,16 +451,19 @@ bool ComplexMySQLTask::init_success()
439451
return false;
440452
}
441453
}
442-
else if (strcasecmp(kv.first.c_str(), "transaction") == 0)
443-
transaction = kv.second;
454+
else if (strcasecmp(kv.first.c_str(), "character_set_results") == 0)
455+
res_charset_ = std::move(kv.second);
444456
}
445457
}
446458

447-
size_t info_len = username_.size() + password_.size() + db_.size() + 40;
459+
size_t info_len = username_.size() + password_.size() + db_.size() +
460+
res_charset_.size() + 50;
448461
char *info = new char[info_len];
449462

450-
snprintf(info, info_len, "mysql|user:%s|pass:%s|db:%s|charset:%d",
451-
username_.c_str(), password_.c_str(), db_.c_str(), character_set_);
463+
snprintf(info, info_len, "mysql|user:%s|pass:%s|db:%s|"
464+
"charset:%d|rcharset:%s",
465+
username_.c_str(), password_.c_str(), db_.c_str(),
466+
character_set_, res_charset_.c_str());
452467
this->WFComplexClientTask::set_type(type);
453468

454469
if (!transaction.empty())
@@ -478,10 +493,17 @@ bool ComplexMySQLTask::finish_once()
478493

479494
if (this->state == WFT_STATE_SUCCESS && !succ_)
480495
{
496+
long long seqid = this->get_seq();
497+
498+
if (seqid == 0)
499+
this->error = WFT_ERR_MYSQL_HOST_NOT_ALLOWED;
500+
else if (seqid == 1)
501+
this->error = WFT_ERR_MYSQL_ACCESS_DENIED;
502+
else
503+
this->error = WFT_ERR_MYSQL_INVALID_CHARACTER_SET;
504+
481505
this->disable_retry();
482506
this->state = WFT_STATE_TASK_ERROR;
483-
this->error = this->get_seq() == 0 ? WFT_ERR_MYSQL_HOST_NOT_ALLOWED
484-
: WFT_ERR_MYSQL_ACCESS_DENIED;
485507
}
486508

487509
return false;

src/factory/RedisTaskImpl.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ CommMessageOut *ComplexRedisTask::message_out()
118118

119119
int ComplexRedisTask::keep_alive_timeout()
120120
{
121-
if (this->is_user_request())
121+
if (this->is_user_request_)
122122
return this->keep_alive_timeo;
123123

124124
RedisResponse *resp = this->get_resp();

src/factory/WFTaskFactory.inl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,6 @@ protected:
317317
this->resp.set_size_limit(size);
318318
}
319319

320-
bool is_user_request() const
321-
{
322-
return this->get_message_out() == &this->req;
323-
}
324-
325320
void disable_retry()
326321
{
327322
retry_times_ = retry_max_;

src/protocol/MySQLMessage.inl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
namespace protocol
2525
{
2626

27-
using MySQLHandshakeRequest = MySQLMessage;
27+
using MySQLHandshakeRequest = MySQLRequest;
2828

2929
class MySQLHandshakeResponse : public MySQLResponse
3030
{
@@ -51,7 +51,7 @@ public:
5151
memcpy(auth_plugin_data_part_2_, auth2, 12);
5252
}
5353

54-
bool host_disallowed() { return this->disallowed_; }
54+
bool host_disallowed() const { return this->disallowed_; }
5555

5656
private:
5757
virtual int decode_packet(const char *buf, size_t buflen);
@@ -73,7 +73,7 @@ public:
7373
MySQLHandshakeResponse& operator= (MySQLHandshakeResponse&& move) = default;
7474
};
7575

76-
class MySQLAuthRequest : public MySQLMessage
76+
class MySQLAuthRequest : public MySQLRequest
7777
{
7878
public:
7979
void set_auth(const std::string& username,

0 commit comments

Comments
 (0)