From e7ea748165a9c8ecb2d1d3173a0f571b99c6fbe6 Mon Sep 17 00:00:00 2001 From: Cees de Groot Date: Fri, 20 May 2016 14:09:42 -0400 Subject: [PATCH 1/3] Make server_status available --- ext/mysql2/client.c | 17 +++++++++++++++++ ext/mysql2/statement.c | 2 ++ lib/mysql2/client.rb | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index 54a7d6278..28fb7fe60 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -525,6 +525,8 @@ static VALUE rb_mysql_client_async_result(VALUE self) { Check_Type(current, T_HASH); resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil); + rb_iv_set(self, "@server_status", INT2NUM(wrapper->client->server_status)); + return resultObj; } @@ -1464,4 +1466,19 @@ void init_mysql2_client() { rb_const_set(cMysql2Client, rb_intern("BASIC_FLAGS"), LONG2NUM(CLIENT_BASIC_FLAGS)); #endif + +#ifdef SERVER_QUERY_NO_GOOD_INDEX_USED + rb_const_set(cMysql2Client, rb_intern("NO_GOOD_INDEX_USED"), + LONG2NUM(SERVER_QUERY_NO_GOOD_INDEX_USED)); +#endif + +#ifdef SERVER_QUERY_NO_INDEX_USED + rb_const_set(cMysql2Client, rb_intern("NO_INDEX_USED"), + LONG2NUM(SERVER_QUERY_NO_INDEX_USED)); +#endif + +#ifdef SERVER_QUERY_WAS_SLOW + rb_const_set(cMysql2Client, rb_intern("QUERY_WAS_SLOW"), + LONG2NUM(SERVER_QUERY_WAS_SLOW)); +#endif } diff --git a/ext/mysql2/statement.c b/ext/mysql2/statement.c index 1461e0b76..1cce3b4ef 100644 --- a/ext/mysql2/statement.c +++ b/ext/mysql2/statement.c @@ -352,6 +352,8 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { FREE_BINDS; + rb_iv_set(self, "@server_status", INT2NUM(wrapper->client->server_status)); + metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { if (mysql_stmt_errno(stmt) != 0) { diff --git a/lib/mysql2/client.rb b/lib/mysql2/client.rb index 81a2c77ad..87bf29b32 100644 --- a/lib/mysql2/client.rb +++ b/lib/mysql2/client.rb @@ -1,6 +1,6 @@ module Mysql2 class Client - attr_reader :query_options, :read_timeout + attr_reader :query_options, :read_timeout, :server_status def self.default_query_options @default_query_options ||= { From 57baabb1efeb050e1995efb92f1ef2103ba00cd6 Mon Sep 17 00:00:00 2001 From: Cees de Groot Date: Tue, 24 May 2016 11:56:36 -0400 Subject: [PATCH 2/3] Move server flags to result object --- ext/mysql2/client.c | 26 +++++++++++++++++++------- ext/mysql2/client.h | 2 ++ ext/mysql2/statement.c | 4 ++-- lib/mysql2/client.rb | 2 +- lib/mysql2/result.rb | 2 ++ spec/mysql2/result_spec.rb | 16 ++++++++++++++++ 6 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index 28fb7fe60..72d197d94 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -525,7 +525,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) { Check_Type(current, T_HASH); resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil); - rb_iv_set(self, "@server_status", INT2NUM(wrapper->client->server_status)); + rb_mysql_set_server_query_flags(wrapper->client, resultObj); return resultObj; } @@ -1466,19 +1466,31 @@ void init_mysql2_client() { rb_const_set(cMysql2Client, rb_intern("BASIC_FLAGS"), LONG2NUM(CLIENT_BASIC_FLAGS)); #endif +} + +#define flag_to_bool(f) ((client->server_status & f) ? Qtrue : Qfalse) + +void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result) { + VALUE server_flags = rb_hash_new(); #ifdef SERVER_QUERY_NO_GOOD_INDEX_USED - rb_const_set(cMysql2Client, rb_intern("NO_GOOD_INDEX_USED"), - LONG2NUM(SERVER_QUERY_NO_GOOD_INDEX_USED)); + rb_hash_aset(server_flags, ID2SYM(rb_intern("no_good_index_used")), flag_to_bool(SERVER_QUERY_NO_GOOD_INDEX_USED)); +#else + rb_hash_aset(server_flags, ID2SYM(rb_intern("no_good_index_used")), Qnil); #endif #ifdef SERVER_QUERY_NO_INDEX_USED - rb_const_set(cMysql2Client, rb_intern("NO_INDEX_USED"), - LONG2NUM(SERVER_QUERY_NO_INDEX_USED)); + rb_hash_aset(server_flags, ID2SYM(rb_intern("no_index_used")), flag_to_bool(SERVER_QUERY_NO_INDEX_USED)); +#else + rb_hash_aset(server_flags, ID2SYM(rb_intern("no_index_used")), Qnil); #endif #ifdef SERVER_QUERY_WAS_SLOW - rb_const_set(cMysql2Client, rb_intern("QUERY_WAS_SLOW"), - LONG2NUM(SERVER_QUERY_WAS_SLOW)); + rb_hash_aset(server_flags, ID2SYM(rb_intern("query_was_slow")), flag_to_bool(SERVER_QUERY_WAS_SLOW)); +#else + rb_hash_aset(server_flags, ID2SYM(rb_intern("query_was_slow")), Qnil;) #endif + + rb_iv_set(result, "@server_flags", server_flags); } + diff --git a/ext/mysql2/client.h b/ext/mysql2/client.h index d10274f84..47b383ec8 100644 --- a/ext/mysql2/client.h +++ b/ext/mysql2/client.h @@ -58,6 +58,7 @@ typedef struct { } void rb_mysql_client_set_active_thread(VALUE self); +void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result); #define GET_CLIENT(self) \ mysql_client_wrapper *wrapper; \ @@ -71,3 +72,4 @@ void decr_mysql2_client(mysql_client_wrapper *wrapper); #ifndef HAVE_RB_HASH_DUP VALUE rb_hash_dup(VALUE other); #endif + diff --git a/ext/mysql2/statement.c b/ext/mysql2/statement.c index 1cce3b4ef..116b5de4c 100644 --- a/ext/mysql2/statement.c +++ b/ext/mysql2/statement.c @@ -352,8 +352,6 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { FREE_BINDS; - rb_iv_set(self, "@server_status", INT2NUM(wrapper->client->server_status)); - metadata = mysql_stmt_result_metadata(stmt); if (metadata == NULL) { if (mysql_stmt_errno(stmt) != 0) { @@ -381,6 +379,8 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { resultObj = rb_mysql_result_to_obj(stmt_wrapper->client, wrapper->encoding, current, metadata, self); + rb_mysql_set_server_query_flags(wrapper->client, resultObj); + if (!is_streaming) { // cache all result rb_funcall(resultObj, intern_each, 0); diff --git a/lib/mysql2/client.rb b/lib/mysql2/client.rb index 87bf29b32..81a2c77ad 100644 --- a/lib/mysql2/client.rb +++ b/lib/mysql2/client.rb @@ -1,6 +1,6 @@ module Mysql2 class Client - attr_reader :query_options, :read_timeout, :server_status + attr_reader :query_options, :read_timeout def self.default_query_options @default_query_options ||= { diff --git a/lib/mysql2/result.rb b/lib/mysql2/result.rb index e005e817c..585104e0b 100644 --- a/lib/mysql2/result.rb +++ b/lib/mysql2/result.rb @@ -1,5 +1,7 @@ module Mysql2 class Result + attr_reader :server_flags + include Enumerable end end diff --git a/spec/mysql2/result_spec.rb b/spec/mysql2/result_spec.rb index ce797baa2..196f86f6f 100644 --- a/spec/mysql2/result_spec.rb +++ b/spec/mysql2/result_spec.rb @@ -516,4 +516,20 @@ end end end + + context "server flags" do + before(:each) do + @test_result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1") + end + + it "should set a definitive value for query_was_slow" do + expect(@test_result.server_flags[:query_was_slow]).to eql(false) + end + it "should set a definitive value for no_index_used" do + expect(@test_result.server_flags[:no_index_used]).to eql(true) + end + it "should set a definitive value for no_good_index_used" do + expect(@test_result.server_flags[:no_good_index_used]).to eql(false) + end + end end From cc572139b3cc4247ff4adbc5c1b5feee45d7d196 Mon Sep 17 00:00:00 2001 From: Cees de Groot Date: Tue, 24 May 2016 16:41:33 -0400 Subject: [PATCH 3/3] Move symbols for server flags to static variables --- ext/mysql2/client.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c index 72d197d94..28ecd3fb5 100644 --- a/ext/mysql2/client.c +++ b/ext/mysql2/client.c @@ -17,6 +17,7 @@ VALUE cMysql2Client; extern VALUE mMysql2, cMysql2Error; static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream; +static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow; static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args; #ifndef HAVE_RB_HASH_DUP @@ -1352,6 +1353,10 @@ void init_mysql2_client() { sym_array = ID2SYM(rb_intern("array")); sym_stream = ID2SYM(rb_intern("stream")); + sym_no_good_index_used = ID2SYM(rb_intern("no_good_index_used")); + sym_no_index_used = ID2SYM(rb_intern("no_index_used")); + sym_query_was_slow = ID2SYM(rb_intern("query_was_slow")); + intern_brackets = rb_intern("[]"); intern_merge = rb_intern("merge"); intern_merge_bang = rb_intern("merge!"); @@ -1474,21 +1479,21 @@ void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result) { VALUE server_flags = rb_hash_new(); #ifdef SERVER_QUERY_NO_GOOD_INDEX_USED - rb_hash_aset(server_flags, ID2SYM(rb_intern("no_good_index_used")), flag_to_bool(SERVER_QUERY_NO_GOOD_INDEX_USED)); + rb_hash_aset(server_flags, sym_no_good_index_used, flag_to_bool(SERVER_QUERY_NO_GOOD_INDEX_USED)); #else - rb_hash_aset(server_flags, ID2SYM(rb_intern("no_good_index_used")), Qnil); + rb_hash_aset(server_flags, sym_no_good_index_used, Qnil); #endif #ifdef SERVER_QUERY_NO_INDEX_USED - rb_hash_aset(server_flags, ID2SYM(rb_intern("no_index_used")), flag_to_bool(SERVER_QUERY_NO_INDEX_USED)); + rb_hash_aset(server_flags, sym_no_index_used, flag_to_bool(SERVER_QUERY_NO_INDEX_USED)); #else - rb_hash_aset(server_flags, ID2SYM(rb_intern("no_index_used")), Qnil); + rb_hash_aset(server_flags, sym_no_index_used, Qnil); #endif #ifdef SERVER_QUERY_WAS_SLOW - rb_hash_aset(server_flags, ID2SYM(rb_intern("query_was_slow")), flag_to_bool(SERVER_QUERY_WAS_SLOW)); + rb_hash_aset(server_flags, sym_query_was_slow, flag_to_bool(SERVER_QUERY_WAS_SLOW)); #else - rb_hash_aset(server_flags, ID2SYM(rb_intern("query_was_slow")), Qnil;) + rb_hash_aset(server_flags, sym_query_was_slow, Qnil); #endif rb_iv_set(result, "@server_flags", server_flags);