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
6769public:
@@ -125,35 +127,44 @@ bool ComplexMySQLTask::check_request()
125127CommMessageOut *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 ;
0 commit comments