mysql2 0.4.6 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +82 -52
 - data/examples/eventmachine.rb +0 -2
 - data/examples/threaded.rb +2 -4
 - data/ext/mysql2/client.c +171 -75
 - data/ext/mysql2/client.h +2 -41
 - data/ext/mysql2/extconf.rb +30 -23
 - data/ext/mysql2/mysql2_ext.c +2 -1
 - data/ext/mysql2/mysql2_ext.h +8 -8
 - data/ext/mysql2/mysql_enc_to_ruby.h +10 -0
 - data/ext/mysql2/result.c +24 -77
 - data/ext/mysql2/result.h +2 -3
 - data/ext/mysql2/statement.c +101 -73
 - data/ext/mysql2/statement.h +0 -2
 - data/ext/mysql2/wait_for_single_fd.h +2 -1
 - data/lib/mysql2/client.rb +37 -31
 - data/lib/mysql2/em.rb +2 -4
 - data/lib/mysql2/error.rb +49 -20
 - data/lib/mysql2/result.rb +2 -0
 - data/lib/mysql2/statement.rb +3 -9
 - data/lib/mysql2/version.rb +1 -1
 - data/lib/mysql2.rb +14 -15
 - data/spec/em/em_spec.rb +6 -6
 - data/spec/mysql2/client_spec.rb +300 -215
 - data/spec/mysql2/error_spec.rb +3 -9
 - data/spec/mysql2/result_spec.rb +124 -158
 - data/spec/mysql2/statement_spec.rb +138 -185
 - data/spec/spec_helper.rb +79 -61
 - data/support/5072E1F5.asc +432 -0
 - data/support/mysql_enc_to_ruby.rb +2 -2
 - data/support/ruby_enc_to_mysql.rb +5 -5
 - metadata +16 -14
 
    
        data/ext/mysql2/client.c
    CHANGED
    
    | 
         @@ -15,30 +15,31 @@ 
     | 
|
| 
       15 
15 
     | 
    
         
             
            #include "mysql_enc_name_to_ruby.h"
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
            VALUE cMysql2Client;
         
     | 
| 
       18 
     | 
    
         
            -
            extern VALUE mMysql2, cMysql2Error;
         
     | 
| 
      
 18 
     | 
    
         
            +
            extern VALUE mMysql2, cMysql2Error, cMysql2TimeoutError;
         
     | 
| 
       19 
19 
     | 
    
         
             
            static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
         
     | 
| 
      
 20 
     | 
    
         
            +
            static VALUE sym_no_good_index_used, sym_no_index_used, sym_query_was_slow;
         
     | 
| 
       20 
21 
     | 
    
         
             
            static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args;
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            #ifndef HAVE_RB_HASH_DUP
         
     | 
| 
       23 
     | 
    
         
            -
            VALUE rb_hash_dup(VALUE other) {
         
     | 
| 
       24 
     | 
    
         
            -
              return rb_funcall(rb_cHash, intern_brackets, 1, other);
         
     | 
| 
       25 
     | 
    
         
            -
            }
         
     | 
| 
       26 
     | 
    
         
            -
            #endif
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
23 
     | 
    
         
             
            #define REQUIRE_INITIALIZED(wrapper) \
         
     | 
| 
       29 
24 
     | 
    
         
             
              if (!wrapper->initialized) { \
         
     | 
| 
       30 
25 
     | 
    
         
             
                rb_raise(cMysql2Error, "MySQL client is not initialized"); \
         
     | 
| 
       31 
26 
     | 
    
         
             
              }
         
     | 
| 
       32 
27 
     | 
    
         | 
| 
      
 28 
     | 
    
         
            +
            #if defined(HAVE_MYSQL_NET_VIO) || defined(HAVE_ST_NET_VIO)
         
     | 
| 
      
 29 
     | 
    
         
            +
              #define CONNECTED(wrapper) (wrapper->client->net.vio != NULL && wrapper->client->net.fd != -1)
         
     | 
| 
      
 30 
     | 
    
         
            +
            #elif defined(HAVE_MYSQL_NET_PVIO) || defined(HAVE_ST_NET_PVIO)
         
     | 
| 
      
 31 
     | 
    
         
            +
              #define CONNECTED(wrapper) (wrapper->client->net.pvio != NULL && wrapper->client->net.fd != -1)
         
     | 
| 
      
 32 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       33 
34 
     | 
    
         
             
            #define REQUIRE_CONNECTED(wrapper) \
         
     | 
| 
       34 
35 
     | 
    
         
             
              REQUIRE_INITIALIZED(wrapper) \
         
     | 
| 
       35 
     | 
    
         
            -
              if (!wrapper 
     | 
| 
      
 36 
     | 
    
         
            +
              if (!CONNECTED(wrapper) && !wrapper->reconnect_enabled) { \
         
     | 
| 
       36 
37 
     | 
    
         
             
                rb_raise(cMysql2Error, "MySQL client is not connected"); \
         
     | 
| 
       37 
38 
     | 
    
         
             
              }
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
       39 
40 
     | 
    
         
             
            #define REQUIRE_NOT_CONNECTED(wrapper) \
         
     | 
| 
       40 
41 
     | 
    
         
             
              REQUIRE_INITIALIZED(wrapper) \
         
     | 
| 
       41 
     | 
    
         
            -
              if (wrapper 
     | 
| 
      
 42 
     | 
    
         
            +
              if (CONNECTED(wrapper)) { \
         
     | 
| 
       42 
43 
     | 
    
         
             
                rb_raise(cMysql2Error, "MySQL connection is already open"); \
         
     | 
| 
       43 
44 
     | 
    
         
             
              }
         
     | 
| 
       44 
45 
     | 
    
         | 
| 
         @@ -47,7 +48,9 @@ VALUE rb_hash_dup(VALUE other) { 
     | 
|
| 
       47 
48 
     | 
    
         
             
             * variable to use, but MYSQL_SERVER_VERSION gives the correct numbers when
         
     | 
| 
       48 
49 
     | 
    
         
             
             * linking against the server itself
         
     | 
| 
       49 
50 
     | 
    
         
             
             */
         
     | 
| 
       50 
     | 
    
         
            -
            # 
     | 
| 
      
 51 
     | 
    
         
            +
            #if defined(MARIADB_CLIENT_VERSION_STR)
         
     | 
| 
      
 52 
     | 
    
         
            +
              #define MYSQL_LINK_VERSION MARIADB_CLIENT_VERSION_STR
         
     | 
| 
      
 53 
     | 
    
         
            +
            #elif defined(LIBMYSQL_VERSION)
         
     | 
| 
       51 
54 
     | 
    
         
             
              #define MYSQL_LINK_VERSION LIBMYSQL_VERSION
         
     | 
| 
       52 
55 
     | 
    
         
             
            #else
         
     | 
| 
       53 
56 
     | 
    
         
             
              #define MYSQL_LINK_VERSION MYSQL_SERVER_VERSION
         
     | 
| 
         @@ -107,14 +110,13 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) { 
     | 
|
| 
       107 
110 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       108 
111 
     | 
    
         
             
              }
         
     | 
| 
       109 
112 
     | 
    
         
             
            #ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
         
     | 
| 
       110 
     | 
    
         
            -
              GET_CLIENT(self); 
     | 
| 
      
 113 
     | 
    
         
            +
              GET_CLIENT(self);
         
     | 
| 
       111 
114 
     | 
    
         
             
              int val = NUM2INT( setting );
         
     | 
| 
       112 
115 
     | 
    
         
             
              if (version >= 50703 && version < 50711) {
         
     | 
| 
       113 
116 
     | 
    
         
             
                if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
         
     | 
| 
       114 
     | 
    
         
            -
                   
     | 
| 
      
 117 
     | 
    
         
            +
                  my_bool b = ( val == SSL_MODE_REQUIRED );
         
     | 
| 
       115 
118 
     | 
    
         
             
                  int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
         
     | 
| 
       116 
119 
     | 
    
         
             
                  return INT2NUM(result);
         
     | 
| 
       117 
     | 
    
         
            -
                  
         
     | 
| 
       118 
120 
     | 
    
         
             
                } else {
         
     | 
| 
       119 
121 
     | 
    
         
             
                  rb_warn( "MySQL client libraries between 5.7.3 and 5.7.10 only support SSL_MODE_DISABLED and SSL_MODE_REQUIRED" );
         
     | 
| 
       120 
122 
     | 
    
         
             
                  return Qnil;
         
     | 
| 
         @@ -122,7 +124,7 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) { 
     | 
|
| 
       122 
124 
     | 
    
         
             
              }
         
     | 
| 
       123 
125 
     | 
    
         
             
            #endif
         
     | 
| 
       124 
126 
     | 
    
         
             
            #ifdef FULL_SSL_MODE_SUPPORT
         
     | 
| 
       125 
     | 
    
         
            -
              GET_CLIENT(self); 
     | 
| 
      
 127 
     | 
    
         
            +
              GET_CLIENT(self);
         
     | 
| 
       126 
128 
     | 
    
         
             
              int val = NUM2INT( setting );
         
     | 
| 
       127 
129 
     | 
    
         | 
| 
       128 
130 
     | 
    
         
             
              if (val != SSL_MODE_DISABLED && val != SSL_MODE_PREFERRED && val != SSL_MODE_REQUIRED && val != SSL_MODE_VERIFY_CA && val != SSL_MODE_VERIFY_IDENTITY) {
         
     | 
| 
         @@ -171,10 +173,8 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) { 
     | 
|
| 
       171 
173 
     | 
    
         
             
              VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client));
         
     | 
| 
       172 
174 
     | 
    
         
             
              VALUE e;
         
     | 
| 
       173 
175 
     | 
    
         | 
| 
       174 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       175 
176 
     | 
    
         
             
              rb_enc_associate(rb_error_msg, rb_utf8_encoding());
         
     | 
| 
       176 
177 
     | 
    
         
             
              rb_enc_associate(rb_sql_state, rb_usascii_encoding());
         
     | 
| 
       177 
     | 
    
         
            -
            #endif
         
     | 
| 
       178 
178 
     | 
    
         | 
| 
       179 
179 
     | 
    
         
             
              e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
         
     | 
| 
       180 
180 
     | 
    
         
             
                             rb_error_msg,
         
     | 
| 
         @@ -264,11 +264,10 @@ static VALUE invalidate_fd(int clientfd) 
     | 
|
| 
       264 
264 
     | 
    
         
             
            static void *nogvl_close(void *ptr) {
         
     | 
| 
       265 
265 
     | 
    
         
             
              mysql_client_wrapper *wrapper = ptr;
         
     | 
| 
       266 
266 
     | 
    
         | 
| 
       267 
     | 
    
         
            -
              if (wrapper-> 
     | 
| 
      
 267 
     | 
    
         
            +
              if (!wrapper->closed) {
         
     | 
| 
       268 
268 
     | 
    
         
             
                mysql_close(wrapper->client);
         
     | 
| 
       269 
     | 
    
         
            -
                 
     | 
| 
       270 
     | 
    
         
            -
                wrapper-> 
     | 
| 
       271 
     | 
    
         
            -
                wrapper->connected = 0;
         
     | 
| 
      
 269 
     | 
    
         
            +
                wrapper->closed = 1;
         
     | 
| 
      
 270 
     | 
    
         
            +
                wrapper->reconnect_enabled = 0;
         
     | 
| 
       272 
271 
     | 
    
         
             
                wrapper->active_thread = Qnil;
         
     | 
| 
       273 
272 
     | 
    
         
             
              }
         
     | 
| 
       274 
273 
     | 
    
         | 
| 
         @@ -287,7 +286,7 @@ void decr_mysql2_client(mysql_client_wrapper *wrapper) 
     | 
|
| 
       287 
286 
     | 
    
         | 
| 
       288 
287 
     | 
    
         
             
              if (wrapper->refcount == 0) {
         
     | 
| 
       289 
288 
     | 
    
         
             
            #ifndef _WIN32
         
     | 
| 
       290 
     | 
    
         
            -
                if (wrapper 
     | 
| 
      
 289 
     | 
    
         
            +
                if (CONNECTED(wrapper) && !wrapper->automatic_close) {
         
     | 
| 
       291 
290 
     | 
    
         
             
                  /* The client is being garbage collected while connected. Prevent
         
     | 
| 
       292 
291 
     | 
    
         
             
                   * mysql_close() from sending a mysql-QUIT or from calling shutdown() on
         
     | 
| 
       293 
292 
     | 
    
         
             
                   * the socket by invalidating it. invalidate_fd() will drop this
         
     | 
| 
         @@ -299,10 +298,12 @@ void decr_mysql2_client(mysql_client_wrapper *wrapper) 
     | 
|
| 
       299 
298 
     | 
    
         
             
                    fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely\n");
         
     | 
| 
       300 
299 
     | 
    
         
             
                    close(wrapper->client->net.fd);
         
     | 
| 
       301 
300 
     | 
    
         
             
                  }
         
     | 
| 
      
 301 
     | 
    
         
            +
                  wrapper->client->net.fd = -1;
         
     | 
| 
       302 
302 
     | 
    
         
             
                }
         
     | 
| 
       303 
303 
     | 
    
         
             
            #endif
         
     | 
| 
       304 
304 
     | 
    
         | 
| 
       305 
305 
     | 
    
         
             
                nogvl_close(wrapper);
         
     | 
| 
      
 306 
     | 
    
         
            +
                xfree(wrapper->client);
         
     | 
| 
       306 
307 
     | 
    
         
             
                xfree(wrapper);
         
     | 
| 
       307 
308 
     | 
    
         
             
              }
         
     | 
| 
       308 
309 
     | 
    
         
             
            }
         
     | 
| 
         @@ -317,9 +318,9 @@ static VALUE allocate(VALUE klass) { 
     | 
|
| 
       317 
318 
     | 
    
         
             
              wrapper->server_version = 0;
         
     | 
| 
       318 
319 
     | 
    
         
             
              wrapper->reconnect_enabled = 0;
         
     | 
| 
       319 
320 
     | 
    
         
             
              wrapper->connect_timeout = 0;
         
     | 
| 
       320 
     | 
    
         
            -
              wrapper->connected = 0; /* means that a database connection is open */
         
     | 
| 
       321 
321 
     | 
    
         
             
              wrapper->initialized = 0; /* means that that the wrapper is initialized */
         
     | 
| 
       322 
322 
     | 
    
         
             
              wrapper->refcount = 1;
         
     | 
| 
      
 323 
     | 
    
         
            +
              wrapper->closed = 0;
         
     | 
| 
       323 
324 
     | 
    
         
             
              wrapper->client = (MYSQL*)xmalloc(sizeof(MYSQL));
         
     | 
| 
       324 
325 
     | 
    
         | 
| 
       325 
326 
     | 
    
         
             
              return obj;
         
     | 
| 
         @@ -349,9 +350,7 @@ static VALUE rb_mysql_client_escape(RB_MYSQL_UNUSED VALUE klass, VALUE str) { 
     | 
|
| 
       349 
350 
     | 
    
         
             
                return str;
         
     | 
| 
       350 
351 
     | 
    
         
             
              } else {
         
     | 
| 
       351 
352 
     | 
    
         
             
                rb_str = rb_str_new((const char*)newStr, newLen);
         
     | 
| 
       352 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       353 
353 
     | 
    
         
             
                rb_enc_copy(rb_str, str);
         
     | 
| 
       354 
     | 
    
         
            -
            #endif
         
     | 
| 
       355 
354 
     | 
    
         
             
                xfree(newStr);
         
     | 
| 
       356 
355 
     | 
    
         
             
                return rb_str;
         
     | 
| 
       357 
356 
     | 
    
         
             
              }
         
     | 
| 
         @@ -378,9 +377,7 @@ static VALUE rb_mysql_info(VALUE self) { 
     | 
|
| 
       378 
377 
     | 
    
         
             
              }
         
     | 
| 
       379 
378 
     | 
    
         | 
| 
       380 
379 
     | 
    
         
             
              rb_str = rb_str_new2(info);
         
     | 
| 
       381 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       382 
380 
     | 
    
         
             
              rb_enc_associate(rb_str, rb_utf8_encoding());
         
     | 
| 
       383 
     | 
    
         
            -
            #endif
         
     | 
| 
       384 
381 
     | 
    
         | 
| 
       385 
382 
     | 
    
         
             
              return rb_str;
         
     | 
| 
       386 
383 
     | 
    
         
             
            }
         
     | 
| 
         @@ -398,14 +395,25 @@ static VALUE rb_mysql_get_ssl_cipher(VALUE self) 
     | 
|
| 
       398 
395 
     | 
    
         
             
              }
         
     | 
| 
       399 
396 
     | 
    
         | 
| 
       400 
397 
     | 
    
         
             
              rb_str = rb_str_new2(cipher);
         
     | 
| 
       401 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       402 
398 
     | 
    
         
             
              rb_enc_associate(rb_str, rb_utf8_encoding());
         
     | 
| 
       403 
     | 
    
         
            -
            #endif
         
     | 
| 
       404 
399 
     | 
    
         | 
| 
       405 
400 
     | 
    
         
             
              return rb_str;
         
     | 
| 
       406 
401 
     | 
    
         
             
            }
         
     | 
| 
       407 
402 
     | 
    
         | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
      
 403 
     | 
    
         
            +
            #ifdef CLIENT_CONNECT_ATTRS
         
     | 
| 
      
 404 
     | 
    
         
            +
            static int opt_connect_attr_add_i(VALUE key, VALUE value, VALUE arg)
         
     | 
| 
      
 405 
     | 
    
         
            +
            {
         
     | 
| 
      
 406 
     | 
    
         
            +
              mysql_client_wrapper *wrapper = (mysql_client_wrapper *)arg;
         
     | 
| 
      
 407 
     | 
    
         
            +
              rb_encoding *enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
      
 408 
     | 
    
         
            +
              key = rb_str_export_to_enc(key, enc);
         
     | 
| 
      
 409 
     | 
    
         
            +
              value = rb_str_export_to_enc(value, enc);
         
     | 
| 
      
 410 
     | 
    
         
            +
             
     | 
| 
      
 411 
     | 
    
         
            +
              mysql_options4(wrapper->client, MYSQL_OPT_CONNECT_ATTR_ADD, StringValueCStr(key), StringValueCStr(value));
         
     | 
| 
      
 412 
     | 
    
         
            +
              return ST_CONTINUE;
         
     | 
| 
      
 413 
     | 
    
         
            +
            }
         
     | 
| 
      
 414 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 415 
     | 
    
         
            +
             
     | 
| 
      
 416 
     | 
    
         
            +
            static VALUE rb_mysql_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags, VALUE conn_attrs) {
         
     | 
| 
       409 
417 
     | 
    
         
             
              struct nogvl_connect_args args;
         
     | 
| 
       410 
418 
     | 
    
         
             
              time_t start_time, end_time, elapsed_time, connect_timeout;
         
     | 
| 
       411 
419 
     | 
    
         
             
              VALUE rv;
         
     | 
| 
         @@ -420,6 +428,11 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po 
     | 
|
| 
       420 
428 
     | 
    
         
             
              args.mysql       = wrapper->client;
         
     | 
| 
       421 
429 
     | 
    
         
             
              args.client_flag = NUM2ULONG(flags);
         
     | 
| 
       422 
430 
     | 
    
         | 
| 
      
 431 
     | 
    
         
            +
            #ifdef CLIENT_CONNECT_ATTRS
         
     | 
| 
      
 432 
     | 
    
         
            +
              mysql_options(wrapper->client, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
         
     | 
| 
      
 433 
     | 
    
         
            +
              rb_hash_foreach(conn_attrs, opt_connect_attr_add_i, (VALUE)wrapper);
         
     | 
| 
      
 434 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 435 
     | 
    
         
            +
             
     | 
| 
       423 
436 
     | 
    
         
             
              if (wrapper->connect_timeout)
         
     | 
| 
       424 
437 
     | 
    
         
             
                time(&start_time);
         
     | 
| 
       425 
438 
     | 
    
         
             
              rv = (VALUE) rb_thread_call_without_gvl(nogvl_connect, &args, RUBY_UBF_IO, 0);
         
     | 
| 
         @@ -450,7 +463,6 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po 
     | 
|
| 
       450 
463 
     | 
    
         
             
              }
         
     | 
| 
       451 
464 
     | 
    
         | 
| 
       452 
465 
     | 
    
         
             
              wrapper->server_version = mysql_get_server_version(wrapper->client);
         
     | 
| 
       453 
     | 
    
         
            -
              wrapper->connected = 1;
         
     | 
| 
       454 
466 
     | 
    
         
             
              return self;
         
     | 
| 
       455 
467 
     | 
    
         
             
            }
         
     | 
| 
       456 
468 
     | 
    
         | 
| 
         @@ -465,13 +477,23 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po 
     | 
|
| 
       465 
477 
     | 
    
         
             
            static VALUE rb_mysql_client_close(VALUE self) {
         
     | 
| 
       466 
478 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       467 
479 
     | 
    
         | 
| 
       468 
     | 
    
         
            -
              if (wrapper-> 
     | 
| 
      
 480 
     | 
    
         
            +
              if (wrapper->client) {
         
     | 
| 
       469 
481 
     | 
    
         
             
                rb_thread_call_without_gvl(nogvl_close, wrapper, RUBY_UBF_IO, 0);
         
     | 
| 
       470 
482 
     | 
    
         
             
              }
         
     | 
| 
       471 
483 
     | 
    
         | 
| 
       472 
484 
     | 
    
         
             
              return Qnil;
         
     | 
| 
       473 
485 
     | 
    
         
             
            }
         
     | 
| 
       474 
486 
     | 
    
         | 
| 
      
 487 
     | 
    
         
            +
            /* call-seq:
         
     | 
| 
      
 488 
     | 
    
         
            +
             *    client.closed?
         
     | 
| 
      
 489 
     | 
    
         
            +
             *
         
     | 
| 
      
 490 
     | 
    
         
            +
             * @return [Boolean]
         
     | 
| 
      
 491 
     | 
    
         
            +
             */
         
     | 
| 
      
 492 
     | 
    
         
            +
            static VALUE rb_mysql_client_closed(VALUE self) {
         
     | 
| 
      
 493 
     | 
    
         
            +
              GET_CLIENT(self);
         
     | 
| 
      
 494 
     | 
    
         
            +
              return CONNECTED(wrapper) ? Qfalse : Qtrue;
         
     | 
| 
      
 495 
     | 
    
         
            +
            }
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
       475 
497 
     | 
    
         
             
            /*
         
     | 
| 
       476 
498 
     | 
    
         
             
             * mysql_send_query is unlikely to block since most queries are small
         
     | 
| 
       477 
499 
     | 
    
         
             
             * enough to fit in a socket buffer, but sometimes large UPDATE and
         
     | 
| 
         @@ -504,7 +526,7 @@ static VALUE do_send_query(void *args) { 
     | 
|
| 
       504 
526 
     | 
    
         
             
             */
         
     | 
| 
       505 
527 
     | 
    
         
             
            static void *nogvl_read_query_result(void *ptr) {
         
     | 
| 
       506 
528 
     | 
    
         
             
              MYSQL * client = ptr;
         
     | 
| 
       507 
     | 
    
         
            -
               
     | 
| 
      
 529 
     | 
    
         
            +
              my_bool res = mysql_read_query_result(client);
         
     | 
| 
       508 
530 
     | 
    
         | 
| 
       509 
531 
     | 
    
         
             
              return (void *)(res == 0 ? Qtrue : Qfalse);
         
     | 
| 
       510 
532 
     | 
    
         
             
            }
         
     | 
| 
         @@ -573,11 +595,14 @@ static VALUE rb_mysql_client_async_result(VALUE self) { 
     | 
|
| 
       573 
595 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       574 
596 
     | 
    
         
             
              }
         
     | 
| 
       575 
597 
     | 
    
         | 
| 
      
 598 
     | 
    
         
            +
              // Duplicate the options hash and put the copy in the Result object
         
     | 
| 
       576 
599 
     | 
    
         
             
              current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
         
     | 
| 
       577 
600 
     | 
    
         
             
              (void)RB_GC_GUARD(current);
         
     | 
| 
       578 
601 
     | 
    
         
             
              Check_Type(current, T_HASH);
         
     | 
| 
       579 
602 
     | 
    
         
             
              resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result, Qnil);
         
     | 
| 
       580 
603 
     | 
    
         | 
| 
      
 604 
     | 
    
         
            +
              rb_mysql_set_server_query_flags(wrapper->client, resultObj);
         
     | 
| 
      
 605 
     | 
    
         
            +
             
     | 
| 
       581 
606 
     | 
    
         
             
              return resultObj;
         
     | 
| 
       582 
607 
     | 
    
         
             
            }
         
     | 
| 
       583 
608 
     | 
    
         | 
| 
         @@ -591,16 +616,16 @@ static VALUE disconnect_and_raise(VALUE self, VALUE error) { 
     | 
|
| 
       591 
616 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       592 
617 
     | 
    
         | 
| 
       593 
618 
     | 
    
         
             
              wrapper->active_thread = Qnil;
         
     | 
| 
       594 
     | 
    
         
            -
              wrapper->connected = 0;
         
     | 
| 
       595 
619 
     | 
    
         | 
| 
       596 
620 
     | 
    
         
             
              /* Invalidate the MySQL socket to prevent further communication.
         
     | 
| 
       597 
621 
     | 
    
         
             
               * The GC will come along later and call mysql_close to free it.
         
     | 
| 
       598 
622 
     | 
    
         
             
               */
         
     | 
| 
       599 
     | 
    
         
            -
              if (wrapper 
     | 
| 
      
 623 
     | 
    
         
            +
              if (CONNECTED(wrapper)) {
         
     | 
| 
       600 
624 
     | 
    
         
             
                if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
         
     | 
| 
       601 
625 
     | 
    
         
             
                  fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely, closing unsafely\n");
         
     | 
| 
       602 
626 
     | 
    
         
             
                  close(wrapper->client->net.fd);
         
     | 
| 
       603 
627 
     | 
    
         
             
                }
         
     | 
| 
      
 628 
     | 
    
         
            +
                wrapper->client->net.fd = -1;
         
     | 
| 
       604 
629 
     | 
    
         
             
              }
         
     | 
| 
       605 
630 
     | 
    
         | 
| 
       606 
631 
     | 
    
         
             
              rb_exc_raise(error);
         
     | 
| 
         @@ -635,7 +660,7 @@ static VALUE do_query(void *args) { 
     | 
|
| 
       635 
660 
     | 
    
         
             
                retval = rb_wait_for_single_fd(async_args->fd, RB_WAITFD_IN, tvp);
         
     | 
| 
       636 
661 
     | 
    
         | 
| 
       637 
662 
     | 
    
         
             
                if (retval == 0) {
         
     | 
| 
       638 
     | 
    
         
            -
                  rb_raise( 
     | 
| 
      
 663 
     | 
    
         
            +
                  rb_raise(cMysql2TimeoutError, "Timeout waiting for a response from the last query. (waited %d seconds)", FIX2INT(read_timeout));
         
     | 
| 
       639 
664 
     | 
    
         
             
                }
         
     | 
| 
       640 
665 
     | 
    
         | 
| 
       641 
666 
     | 
    
         
             
                if (retval < 0) {
         
     | 
| 
         @@ -656,19 +681,21 @@ static VALUE disconnect_and_mark_inactive(VALUE self) { 
     | 
|
| 
       656 
681 
     | 
    
         | 
| 
       657 
682 
     | 
    
         
             
              /* Check if execution terminated while result was still being read. */
         
     | 
| 
       658 
683 
     | 
    
         
             
              if (!NIL_P(wrapper->active_thread)) {
         
     | 
| 
       659 
     | 
    
         
            -
                 
     | 
| 
      
 684 
     | 
    
         
            +
                if (CONNECTED(wrapper)) {
         
     | 
| 
      
 685 
     | 
    
         
            +
                  /* Invalidate the MySQL socket to prevent further communication. */
         
     | 
| 
       660 
686 
     | 
    
         
             
            #ifndef _WIN32
         
     | 
| 
       661 
     | 
    
         
            -
             
     | 
| 
       662 
     | 
    
         
            -
             
     | 
| 
       663 
     | 
    
         
            -
             
     | 
| 
       664 
     | 
    
         
            -
             
     | 
| 
      
 687 
     | 
    
         
            +
                  if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
         
     | 
| 
      
 688 
     | 
    
         
            +
                    rb_warn("mysql2 failed to invalidate FD safely, closing unsafely\n");
         
     | 
| 
      
 689 
     | 
    
         
            +
                    close(wrapper->client->net.fd);
         
     | 
| 
      
 690 
     | 
    
         
            +
                  }
         
     | 
| 
       665 
691 
     | 
    
         
             
            #else
         
     | 
| 
       666 
     | 
    
         
            -
             
     | 
| 
      
 692 
     | 
    
         
            +
                  close(wrapper->client->net.fd);
         
     | 
| 
       667 
693 
     | 
    
         
             
            #endif
         
     | 
| 
      
 694 
     | 
    
         
            +
                  wrapper->client->net.fd = -1;
         
     | 
| 
      
 695 
     | 
    
         
            +
                }
         
     | 
| 
       668 
696 
     | 
    
         
             
                /* Skip mysql client check performed before command execution. */
         
     | 
| 
       669 
697 
     | 
    
         
             
                wrapper->client->status = MYSQL_STATUS_READY;
         
     | 
| 
       670 
698 
     | 
    
         
             
                wrapper->active_thread = Qnil;
         
     | 
| 
       671 
     | 
    
         
            -
                wrapper->connected = 0;
         
     | 
| 
       672 
699 
     | 
    
         
             
              }
         
     | 
| 
       673 
700 
     | 
    
         | 
| 
       674 
701 
     | 
    
         
             
              return Qnil;
         
     | 
| 
         @@ -728,7 +755,7 @@ static VALUE rb_mysql_client_abandon_results(VALUE self) { 
     | 
|
| 
       728 
755 
     | 
    
         
             
             * Query the database with +sql+, with optional +options+.  For the possible
         
     | 
| 
       729 
756 
     | 
    
         
             
             * options, see default_query_options on the Mysql2::Client class.
         
     | 
| 
       730 
757 
     | 
    
         
             
             */
         
     | 
| 
       731 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 758 
     | 
    
         
            +
            static VALUE rb_mysql_query(VALUE self, VALUE sql, VALUE current) {
         
     | 
| 
       732 
759 
     | 
    
         
             
            #ifndef _WIN32
         
     | 
| 
       733 
760 
     | 
    
         
             
              struct async_query_args async_args;
         
     | 
| 
       734 
761 
     | 
    
         
             
            #endif
         
     | 
| 
         @@ -743,12 +770,8 @@ static VALUE rb_query(VALUE self, VALUE sql, VALUE current) { 
     | 
|
| 
       743 
770 
     | 
    
         
             
              rb_iv_set(self, "@current_query_options", current);
         
     | 
| 
       744 
771 
     | 
    
         | 
| 
       745 
772 
     | 
    
         
             
              Check_Type(sql, T_STRING);
         
     | 
| 
       746 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       747 
773 
     | 
    
         
             
              /* ensure the string is in the encoding the connection is expecting */
         
     | 
| 
       748 
774 
     | 
    
         
             
              args.sql = rb_str_export_to_enc(sql, rb_to_encoding(wrapper->encoding));
         
     | 
| 
       749 
     | 
    
         
            -
            #else
         
     | 
| 
       750 
     | 
    
         
            -
              args.sql = sql;
         
     | 
| 
       751 
     | 
    
         
            -
            #endif
         
     | 
| 
       752 
775 
     | 
    
         
             
              args.sql_ptr = RSTRING_PTR(args.sql);
         
     | 
| 
       753 
776 
     | 
    
         
             
              args.sql_len = RSTRING_LEN(args.sql);
         
     | 
| 
       754 
777 
     | 
    
         
             
              args.wrapper = wrapper;
         
     | 
| 
         @@ -785,20 +808,16 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) { 
     | 
|
| 
       785 
808 
     | 
    
         
             
              unsigned char *newStr;
         
     | 
| 
       786 
809 
     | 
    
         
             
              VALUE rb_str;
         
     | 
| 
       787 
810 
     | 
    
         
             
              unsigned long newLen, oldLen;
         
     | 
| 
       788 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       789 
811 
     | 
    
         
             
              rb_encoding *default_internal_enc;
         
     | 
| 
       790 
812 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       791 
     | 
    
         
            -
            #endif
         
     | 
| 
       792 
813 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       793 
814 
     | 
    
         | 
| 
       794 
815 
     | 
    
         
             
              REQUIRE_CONNECTED(wrapper);
         
     | 
| 
       795 
816 
     | 
    
         
             
              Check_Type(str, T_STRING);
         
     | 
| 
       796 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       797 
817 
     | 
    
         
             
              default_internal_enc = rb_default_internal_encoding();
         
     | 
| 
       798 
818 
     | 
    
         
             
              conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       799 
819 
     | 
    
         
             
              /* ensure the string is in the encoding the connection is expecting */
         
     | 
| 
       800 
820 
     | 
    
         
             
              str = rb_str_export_to_enc(str, conn_enc);
         
     | 
| 
       801 
     | 
    
         
            -
            #endif
         
     | 
| 
       802 
821 
     | 
    
         | 
| 
       803 
822 
     | 
    
         
             
              oldLen = RSTRING_LEN(str);
         
     | 
| 
       804 
823 
     | 
    
         
             
              newStr = xmalloc(oldLen*2+1);
         
     | 
| 
         @@ -806,21 +825,17 @@ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) { 
     | 
|
| 
       806 
825 
     | 
    
         
             
              newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, RSTRING_PTR(str), oldLen);
         
     | 
| 
       807 
826 
     | 
    
         
             
              if (newLen == oldLen) {
         
     | 
| 
       808 
827 
     | 
    
         
             
                /* no need to return a new ruby string if nothing changed */
         
     | 
| 
       809 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       810 
828 
     | 
    
         
             
                if (default_internal_enc) {
         
     | 
| 
       811 
829 
     | 
    
         
             
                  str = rb_str_export_to_enc(str, default_internal_enc);
         
     | 
| 
       812 
830 
     | 
    
         
             
                }
         
     | 
| 
       813 
     | 
    
         
            -
            #endif
         
     | 
| 
       814 
831 
     | 
    
         
             
                xfree(newStr);
         
     | 
| 
       815 
832 
     | 
    
         
             
                return str;
         
     | 
| 
       816 
833 
     | 
    
         
             
              } else {
         
     | 
| 
       817 
834 
     | 
    
         
             
                rb_str = rb_str_new((const char*)newStr, newLen);
         
     | 
| 
       818 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       819 
835 
     | 
    
         
             
                rb_enc_associate(rb_str, conn_enc);
         
     | 
| 
       820 
836 
     | 
    
         
             
                if (default_internal_enc) {
         
     | 
| 
       821 
837 
     | 
    
         
             
                  rb_str = rb_str_export_to_enc(rb_str, default_internal_enc);
         
     | 
| 
       822 
838 
     | 
    
         
             
                }
         
     | 
| 
       823 
     | 
    
         
            -
            #endif
         
     | 
| 
       824 
839 
     | 
    
         
             
                xfree(newStr);
         
     | 
| 
       825 
840 
     | 
    
         
             
                return rb_str;
         
     | 
| 
       826 
841 
     | 
    
         
             
              }
         
     | 
| 
         @@ -831,7 +846,7 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) { 
     | 
|
| 
       831 
846 
     | 
    
         
             
              const void *retval = NULL;
         
     | 
| 
       832 
847 
     | 
    
         
             
              unsigned int intval = 0;
         
     | 
| 
       833 
848 
     | 
    
         
             
              const char * charval = NULL;
         
     | 
| 
       834 
     | 
    
         
            -
               
     | 
| 
      
 849 
     | 
    
         
            +
              my_bool boolval;
         
     | 
| 
       835 
850 
     | 
    
         | 
| 
       836 
851 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       837 
852 
     | 
    
         | 
| 
         @@ -866,10 +881,12 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) { 
     | 
|
| 
       866 
881 
     | 
    
         
             
                  retval = &boolval;
         
     | 
| 
       867 
882 
     | 
    
         
             
                  break;
         
     | 
| 
       868 
883 
     | 
    
         | 
| 
      
 884 
     | 
    
         
            +
            #ifdef MYSQL_SECURE_AUTH
         
     | 
| 
       869 
885 
     | 
    
         
             
                case MYSQL_SECURE_AUTH:
         
     | 
| 
       870 
886 
     | 
    
         
             
                  boolval = (value == Qfalse ? 0 : 1);
         
     | 
| 
       871 
887 
     | 
    
         
             
                  retval = &boolval;
         
     | 
| 
       872 
888 
     | 
    
         
             
                  break;
         
     | 
| 
      
 889 
     | 
    
         
            +
            #endif
         
     | 
| 
       873 
890 
     | 
    
         | 
| 
       874 
891 
     | 
    
         
             
                case MYSQL_READ_DEFAULT_FILE:
         
     | 
| 
       875 
892 
     | 
    
         
             
                  charval = (const char *)StringValueCStr(value);
         
     | 
| 
         @@ -886,6 +903,13 @@ static VALUE _mysql_client_options(VALUE self, int opt, VALUE value) { 
     | 
|
| 
       886 
903 
     | 
    
         
             
                  retval  = charval;
         
     | 
| 
       887 
904 
     | 
    
         
             
                  break;
         
     | 
| 
       888 
905 
     | 
    
         | 
| 
      
 906 
     | 
    
         
            +
            #ifdef HAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN
         
     | 
| 
      
 907 
     | 
    
         
            +
                case MYSQL_ENABLE_CLEARTEXT_PLUGIN:
         
     | 
| 
      
 908 
     | 
    
         
            +
                  boolval = (value == Qfalse ? 0 : 1);
         
     | 
| 
      
 909 
     | 
    
         
            +
                  retval = &boolval;
         
     | 
| 
      
 910 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 911 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 912 
     | 
    
         
            +
             
     | 
| 
       889 
913 
     | 
    
         
             
                default:
         
     | 
| 
       890 
914 
     | 
    
         
             
                  return Qfalse;
         
     | 
| 
       891 
915 
     | 
    
         
             
              }
         
     | 
| 
         @@ -922,10 +946,8 @@ static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) { 
     | 
|
| 
       922 
946 
     | 
    
         
             
              version = rb_str_new2(mysql_get_client_info());
         
     | 
| 
       923 
947 
     | 
    
         
             
              header_version = rb_str_new2(MYSQL_LINK_VERSION);
         
     | 
| 
       924 
948 
     | 
    
         | 
| 
       925 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       926 
949 
     | 
    
         
             
              rb_enc_associate(version, rb_usascii_encoding());
         
     | 
| 
       927 
950 
     | 
    
         
             
              rb_enc_associate(header_version, rb_usascii_encoding());
         
     | 
| 
       928 
     | 
    
         
            -
            #endif
         
     | 
| 
       929 
951 
     | 
    
         | 
| 
       930 
952 
     | 
    
         
             
              rb_hash_aset(version_info, sym_id, LONG2NUM(mysql_get_client_version()));
         
     | 
| 
       931 
953 
     | 
    
         
             
              rb_hash_aset(version_info, sym_version, version);
         
     | 
| 
         @@ -941,27 +963,21 @@ static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE klass) { 
     | 
|
| 
       941 
963 
     | 
    
         
             
             */
         
     | 
| 
       942 
964 
     | 
    
         
             
            static VALUE rb_mysql_client_server_info(VALUE self) {
         
     | 
| 
       943 
965 
     | 
    
         
             
              VALUE version, server_info;
         
     | 
| 
       944 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       945 
966 
     | 
    
         
             
              rb_encoding *default_internal_enc;
         
     | 
| 
       946 
967 
     | 
    
         
             
              rb_encoding *conn_enc;
         
     | 
| 
       947 
     | 
    
         
            -
            #endif
         
     | 
| 
       948 
968 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       949 
969 
     | 
    
         | 
| 
       950 
970 
     | 
    
         
             
              REQUIRE_CONNECTED(wrapper);
         
     | 
| 
       951 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       952 
971 
     | 
    
         
             
              default_internal_enc = rb_default_internal_encoding();
         
     | 
| 
       953 
972 
     | 
    
         
             
              conn_enc = rb_to_encoding(wrapper->encoding);
         
     | 
| 
       954 
     | 
    
         
            -
            #endif
         
     | 
| 
       955 
973 
     | 
    
         | 
| 
       956 
974 
     | 
    
         
             
              version = rb_hash_new();
         
     | 
| 
       957 
975 
     | 
    
         
             
              rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(wrapper->client)));
         
     | 
| 
       958 
976 
     | 
    
         
             
              server_info = rb_str_new2(mysql_get_server_info(wrapper->client));
         
     | 
| 
       959 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       960 
977 
     | 
    
         
             
              rb_enc_associate(server_info, conn_enc);
         
     | 
| 
       961 
978 
     | 
    
         
             
              if (default_internal_enc) {
         
     | 
| 
       962 
979 
     | 
    
         
             
                server_info = rb_str_export_to_enc(server_info, default_internal_enc);
         
     | 
| 
       963 
980 
     | 
    
         
             
              }
         
     | 
| 
       964 
     | 
    
         
            -
            #endif
         
     | 
| 
       965 
981 
     | 
    
         
             
              rb_hash_aset(version, sym_version, server_info);
         
     | 
| 
       966 
982 
     | 
    
         
             
              return version;
         
     | 
| 
       967 
983 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1075,13 +1091,30 @@ static void *nogvl_ping(void *ptr) { 
     | 
|
| 
       1075 
1091 
     | 
    
         
             
            static VALUE rb_mysql_client_ping(VALUE self) {
         
     | 
| 
       1076 
1092 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       1077 
1093 
     | 
    
         | 
| 
       1078 
     | 
    
         
            -
              if (!wrapper 
     | 
| 
      
 1094 
     | 
    
         
            +
              if (!CONNECTED(wrapper)) {
         
     | 
| 
       1079 
1095 
     | 
    
         
             
                return Qfalse;
         
     | 
| 
       1080 
1096 
     | 
    
         
             
              } else {
         
     | 
| 
       1081 
1097 
     | 
    
         
             
                return (VALUE)rb_thread_call_without_gvl(nogvl_ping, wrapper->client, RUBY_UBF_IO, 0);
         
     | 
| 
       1082 
1098 
     | 
    
         
             
              }
         
     | 
| 
       1083 
1099 
     | 
    
         
             
            }
         
     | 
| 
       1084 
1100 
     | 
    
         | 
| 
      
 1101 
     | 
    
         
            +
            /* call-seq:
         
     | 
| 
      
 1102 
     | 
    
         
            +
             *    client.set_server_option(value)
         
     | 
| 
      
 1103 
     | 
    
         
            +
             *
         
     | 
| 
      
 1104 
     | 
    
         
            +
             * Enables or disables an option for the connection.
         
     | 
| 
      
 1105 
     | 
    
         
            +
             * Read https://dev.mysql.com/doc/refman/5.7/en/mysql-set-server-option.html
         
     | 
| 
      
 1106 
     | 
    
         
            +
             * for more information.
         
     | 
| 
      
 1107 
     | 
    
         
            +
             */
         
     | 
| 
      
 1108 
     | 
    
         
            +
            static VALUE rb_mysql_client_set_server_option(VALUE self, VALUE value) {
         
     | 
| 
      
 1109 
     | 
    
         
            +
              GET_CLIENT(self);
         
     | 
| 
      
 1110 
     | 
    
         
            +
             
     | 
| 
      
 1111 
     | 
    
         
            +
              if (mysql_set_server_option(wrapper->client, NUM2INT(value)) == 0) {
         
     | 
| 
      
 1112 
     | 
    
         
            +
                return Qtrue;
         
     | 
| 
      
 1113 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 1114 
     | 
    
         
            +
                return Qfalse;
         
     | 
| 
      
 1115 
     | 
    
         
            +
              }
         
     | 
| 
      
 1116 
     | 
    
         
            +
            }
         
     | 
| 
      
 1117 
     | 
    
         
            +
             
     | 
| 
       1085 
1118 
     | 
    
         
             
            /* call-seq:
         
     | 
| 
       1086 
1119 
     | 
    
         
             
             *    client.more_results?
         
     | 
| 
       1087 
1120 
     | 
    
         
             
             *
         
     | 
| 
         @@ -1140,6 +1173,7 @@ static VALUE rb_mysql_client_store_result(VALUE self) 
     | 
|
| 
       1140 
1173 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       1141 
1174 
     | 
    
         
             
              }
         
     | 
| 
       1142 
1175 
     | 
    
         | 
| 
      
 1176 
     | 
    
         
            +
              // Duplicate the options hash and put the copy in the Result object
         
     | 
| 
       1143 
1177 
     | 
    
         
             
              current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
         
     | 
| 
       1144 
1178 
     | 
    
         
             
              (void)RB_GC_GUARD(current);
         
     | 
| 
       1145 
1179 
     | 
    
         
             
              Check_Type(current, T_HASH);
         
     | 
| 
         @@ -1148,7 +1182,6 @@ static VALUE rb_mysql_client_store_result(VALUE self) 
     | 
|
| 
       1148 
1182 
     | 
    
         
             
              return resultObj;
         
     | 
| 
       1149 
1183 
     | 
    
         
             
            }
         
     | 
| 
       1150 
1184 
     | 
    
         | 
| 
       1151 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       1152 
1185 
     | 
    
         
             
            /* call-seq:
         
     | 
| 
       1153 
1186 
     | 
    
         
             
             *    client.encoding
         
     | 
| 
       1154 
1187 
     | 
    
         
             
             *
         
     | 
| 
         @@ -1158,7 +1191,6 @@ static VALUE rb_mysql_client_encoding(VALUE self) { 
     | 
|
| 
       1158 
1191 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       1159 
1192 
     | 
    
         
             
              return wrapper->encoding;
         
     | 
| 
       1160 
1193 
     | 
    
         
             
            }
         
     | 
| 
       1161 
     | 
    
         
            -
            #endif
         
     | 
| 
       1162 
1194 
     | 
    
         | 
| 
       1163 
1195 
     | 
    
         
             
            /* call-seq:
         
     | 
| 
       1164 
1196 
     | 
    
         
             
             *    client.automatic_close?
         
     | 
| 
         @@ -1244,17 +1276,14 @@ static VALUE set_write_timeout(VALUE self, VALUE value) { 
     | 
|
| 
       1244 
1276 
     | 
    
         | 
| 
       1245 
1277 
     | 
    
         
             
            static VALUE set_charset_name(VALUE self, VALUE value) {
         
     | 
| 
       1246 
1278 
     | 
    
         
             
              char *charset_name;
         
     | 
| 
       1247 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       1248 
1279 
     | 
    
         
             
              const struct mysql2_mysql_enc_name_to_rb_map *mysql2rb;
         
     | 
| 
       1249 
1280 
     | 
    
         
             
              rb_encoding *enc;
         
     | 
| 
       1250 
1281 
     | 
    
         
             
              VALUE rb_enc;
         
     | 
| 
       1251 
     | 
    
         
            -
            #endif
         
     | 
| 
       1252 
1282 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       1253 
1283 
     | 
    
         | 
| 
       1254 
1284 
     | 
    
         
             
              Check_Type(value, T_STRING);
         
     | 
| 
       1255 
1285 
     | 
    
         
             
              charset_name = RSTRING_PTR(value);
         
     | 
| 
       1256 
1286 
     | 
    
         | 
| 
       1257 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       1258 
1287 
     | 
    
         
             
              mysql2rb = mysql2_mysql_enc_name_to_rb(charset_name, (unsigned int)RSTRING_LEN(value));
         
     | 
| 
       1259 
1288 
     | 
    
         
             
              if (mysql2rb == NULL || mysql2rb->rb_name == NULL) {
         
     | 
| 
       1260 
1289 
     | 
    
         
             
                VALUE inspect = rb_inspect(value);
         
     | 
| 
         @@ -1264,7 +1293,6 @@ static VALUE set_charset_name(VALUE self, VALUE value) { 
     | 
|
| 
       1264 
1293 
     | 
    
         
             
                rb_enc = rb_enc_from_encoding(enc);
         
     | 
| 
       1265 
1294 
     | 
    
         
             
                wrapper->encoding = rb_enc;
         
     | 
| 
       1266 
1295 
     | 
    
         
             
              }
         
     | 
| 
       1267 
     | 
    
         
            -
            #endif
         
     | 
| 
       1268 
1296 
     | 
    
         | 
| 
       1269 
1297 
     | 
    
         
             
              if (mysql_options(wrapper->client, MYSQL_SET_CHARSET_NAME, charset_name)) {
         
     | 
| 
       1270 
1298 
     | 
    
         
             
                /* TODO: warning - unable to set charset */
         
     | 
| 
         @@ -1288,7 +1316,12 @@ static VALUE set_ssl_options(VALUE self, VALUE key, VALUE cert, VALUE ca, VALUE 
     | 
|
| 
       1288 
1316 
     | 
    
         
             
            }
         
     | 
| 
       1289 
1317 
     | 
    
         | 
| 
       1290 
1318 
     | 
    
         
             
            static VALUE set_secure_auth(VALUE self, VALUE value) {
         
     | 
| 
      
 1319 
     | 
    
         
            +
            /* This option was deprecated in MySQL 5.x and removed in MySQL 8.0 */
         
     | 
| 
      
 1320 
     | 
    
         
            +
            #ifdef MYSQL_SECURE_AUTH
         
     | 
| 
       1291 
1321 
     | 
    
         
             
              return _mysql_client_options(self, MYSQL_SECURE_AUTH, value);
         
     | 
| 
      
 1322 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1323 
     | 
    
         
            +
              return Qfalse;
         
     | 
| 
      
 1324 
     | 
    
         
            +
            #endif
         
     | 
| 
       1292 
1325 
     | 
    
         
             
            }
         
     | 
| 
       1293 
1326 
     | 
    
         | 
| 
       1294 
1327 
     | 
    
         
             
            static VALUE set_read_default_file(VALUE self, VALUE value) {
         
     | 
| 
         @@ -1303,6 +1336,14 @@ static VALUE set_init_command(VALUE self, VALUE value) { 
     | 
|
| 
       1303 
1336 
     | 
    
         
             
              return _mysql_client_options(self, MYSQL_INIT_COMMAND, value);
         
     | 
| 
       1304 
1337 
     | 
    
         
             
            }
         
     | 
| 
       1305 
1338 
     | 
    
         | 
| 
      
 1339 
     | 
    
         
            +
            static VALUE set_enable_cleartext_plugin(VALUE self, VALUE value) {
         
     | 
| 
      
 1340 
     | 
    
         
            +
            #ifdef HAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN
         
     | 
| 
      
 1341 
     | 
    
         
            +
              return _mysql_client_options(self, MYSQL_ENABLE_CLEARTEXT_PLUGIN, value);
         
     | 
| 
      
 1342 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1343 
     | 
    
         
            +
              rb_raise(cMysql2Error, "enable-cleartext-plugin is not available, you may need a newer MySQL client library");
         
     | 
| 
      
 1344 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1345 
     | 
    
         
            +
            }
         
     | 
| 
      
 1346 
     | 
    
         
            +
             
     | 
| 
       1306 
1347 
     | 
    
         
             
            static VALUE initialize_ext(VALUE self) {
         
     | 
| 
       1307 
1348 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       1308 
1349 
     | 
    
         | 
| 
         @@ -1363,6 +1404,7 @@ void init_mysql2_client() { 
     | 
|
| 
       1363 
1404 
     | 
    
         
             
              rb_define_singleton_method(cMysql2Client, "info", rb_mysql_client_info, 0);
         
     | 
| 
       1364 
1405 
     | 
    
         | 
| 
       1365 
1406 
     | 
    
         
             
              rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0);
         
     | 
| 
      
 1407 
     | 
    
         
            +
              rb_define_method(cMysql2Client, "closed?", rb_mysql_client_closed, 0);
         
     | 
| 
       1366 
1408 
     | 
    
         
             
              rb_define_method(cMysql2Client, "abandon_results!", rb_mysql_client_abandon_results, 0);
         
     | 
| 
       1367 
1409 
     | 
    
         
             
              rb_define_method(cMysql2Client, "escape", rb_mysql_client_real_escape, 1);
         
     | 
| 
       1368 
1410 
     | 
    
         
             
              rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0);
         
     | 
| 
         @@ -1374,6 +1416,7 @@ void init_mysql2_client() { 
     | 
|
| 
       1374 
1416 
     | 
    
         
             
              rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0);
         
     | 
| 
       1375 
1417 
     | 
    
         
             
              rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0);
         
     | 
| 
       1376 
1418 
     | 
    
         
             
              rb_define_method(cMysql2Client, "select_db", rb_mysql_client_select_db, 1);
         
     | 
| 
      
 1419 
     | 
    
         
            +
              rb_define_method(cMysql2Client, "set_server_option", rb_mysql_client_set_server_option, 1);
         
     | 
| 
       1377 
1420 
     | 
    
         
             
              rb_define_method(cMysql2Client, "more_results?", rb_mysql_client_more_results, 0);
         
     | 
| 
       1378 
1421 
     | 
    
         
             
              rb_define_method(cMysql2Client, "next_result", rb_mysql_client_next_result, 0);
         
     | 
| 
       1379 
1422 
     | 
    
         
             
              rb_define_method(cMysql2Client, "store_result", rb_mysql_client_store_result, 0);
         
     | 
| 
         @@ -1383,9 +1426,7 @@ void init_mysql2_client() { 
     | 
|
| 
       1383 
1426 
     | 
    
         
             
              rb_define_method(cMysql2Client, "warning_count", rb_mysql_client_warning_count, 0);
         
     | 
| 
       1384 
1427 
     | 
    
         
             
              rb_define_method(cMysql2Client, "query_info_string", rb_mysql_info, 0);
         
     | 
| 
       1385 
1428 
     | 
    
         
             
              rb_define_method(cMysql2Client, "ssl_cipher", rb_mysql_get_ssl_cipher, 0);
         
     | 
| 
       1386 
     | 
    
         
            -
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       1387 
1429 
     | 
    
         
             
              rb_define_method(cMysql2Client, "encoding", rb_mysql_client_encoding, 0);
         
     | 
| 
       1388 
     | 
    
         
            -
            #endif
         
     | 
| 
       1389 
1430 
     | 
    
         | 
| 
       1390 
1431 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "connect_timeout=", set_connect_timeout, 1);
         
     | 
| 
       1391 
1432 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "read_timeout=", set_read_timeout, 1);
         
     | 
| 
         @@ -1398,9 +1439,10 @@ void init_mysql2_client() { 
     | 
|
| 
       1398 
1439 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "init_command=", set_init_command, 1);
         
     | 
| 
       1399 
1440 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5);
         
     | 
| 
       1400 
1441 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "ssl_mode=", rb_set_ssl_mode_option, 1);
         
     | 
| 
      
 1442 
     | 
    
         
            +
              rb_define_private_method(cMysql2Client, "enable_cleartext_plugin=", set_enable_cleartext_plugin, 1);
         
     | 
| 
       1401 
1443 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0);
         
     | 
| 
       1402 
     | 
    
         
            -
              rb_define_private_method(cMysql2Client, "connect",  
     | 
| 
       1403 
     | 
    
         
            -
              rb_define_private_method(cMysql2Client, "_query",  
     | 
| 
      
 1444 
     | 
    
         
            +
              rb_define_private_method(cMysql2Client, "connect", rb_mysql_connect, 8);
         
     | 
| 
      
 1445 
     | 
    
         
            +
              rb_define_private_method(cMysql2Client, "_query", rb_mysql_query, 2);
         
     | 
| 
       1404 
1446 
     | 
    
         | 
| 
       1405 
1447 
     | 
    
         
             
              sym_id              = ID2SYM(rb_intern("id"));
         
     | 
| 
       1406 
1448 
     | 
    
         
             
              sym_version         = ID2SYM(rb_intern("version"));
         
     | 
| 
         @@ -1411,6 +1453,10 @@ void init_mysql2_client() { 
     | 
|
| 
       1411 
1453 
     | 
    
         
             
              sym_array           = ID2SYM(rb_intern("array"));
         
     | 
| 
       1412 
1454 
     | 
    
         
             
              sym_stream          = ID2SYM(rb_intern("stream"));
         
     | 
| 
       1413 
1455 
     | 
    
         | 
| 
      
 1456 
     | 
    
         
            +
              sym_no_good_index_used = ID2SYM(rb_intern("no_good_index_used"));
         
     | 
| 
      
 1457 
     | 
    
         
            +
              sym_no_index_used      = ID2SYM(rb_intern("no_index_used"));
         
     | 
| 
      
 1458 
     | 
    
         
            +
              sym_query_was_slow     = ID2SYM(rb_intern("query_was_slow"));
         
     | 
| 
      
 1459 
     | 
    
         
            +
             
     | 
| 
       1414 
1460 
     | 
    
         
             
              intern_brackets = rb_intern("[]");
         
     | 
| 
       1415 
1461 
     | 
    
         
             
              intern_merge = rb_intern("merge");
         
     | 
| 
       1416 
1462 
     | 
    
         
             
              intern_merge_bang = rb_intern("merge!");
         
     | 
| 
         @@ -1419,6 +1465,10 @@ void init_mysql2_client() { 
     | 
|
| 
       1419 
1465 
     | 
    
         
             
            #ifdef CLIENT_LONG_PASSWORD
         
     | 
| 
       1420 
1466 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"),
         
     | 
| 
       1421 
1467 
     | 
    
         
             
                  LONG2NUM(CLIENT_LONG_PASSWORD));
         
     | 
| 
      
 1468 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1469 
     | 
    
         
            +
              /* HACK because MariaDB 10.2 no longer defines this constant,
         
     | 
| 
      
 1470 
     | 
    
         
            +
               * but we're using it in our default connection flags. */
         
     | 
| 
      
 1471 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"), INT2NUM(0));
         
     | 
| 
       1422 
1472 
     | 
    
         
             
            #endif
         
     | 
| 
       1423 
1473 
     | 
    
         | 
| 
       1424 
1474 
     | 
    
         
             
            #ifdef CLIENT_FOUND_ROWS
         
     | 
| 
         @@ -1496,6 +1546,16 @@ void init_mysql2_client() { 
     | 
|
| 
       1496 
1546 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(0));
         
     | 
| 
       1497 
1547 
     | 
    
         
             
            #endif
         
     | 
| 
       1498 
1548 
     | 
    
         | 
| 
      
 1549 
     | 
    
         
            +
            #ifdef HAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON
         
     | 
| 
      
 1550 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_ON"),
         
     | 
| 
      
 1551 
     | 
    
         
            +
                  LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_ON));
         
     | 
| 
      
 1552 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1553 
     | 
    
         
            +
             
     | 
| 
      
 1554 
     | 
    
         
            +
            #ifdef HAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF
         
     | 
| 
      
 1555 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("OPTION_MULTI_STATEMENTS_OFF"),
         
     | 
| 
      
 1556 
     | 
    
         
            +
                  LONG2NUM(MYSQL_OPTION_MULTI_STATEMENTS_OFF));
         
     | 
| 
      
 1557 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1558 
     | 
    
         
            +
             
     | 
| 
       1499 
1559 
     | 
    
         
             
            #ifdef CLIENT_MULTI_STATEMENTS
         
     | 
| 
       1500 
1560 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("MULTI_STATEMENTS"),
         
     | 
| 
       1501 
1561 
     | 
    
         
             
                  LONG2NUM(CLIENT_MULTI_STATEMENTS));
         
     | 
| 
         @@ -1526,6 +1586,16 @@ void init_mysql2_client() { 
     | 
|
| 
       1526 
1586 
     | 
    
         
             
                  LONG2NUM(CLIENT_BASIC_FLAGS));
         
     | 
| 
       1527 
1587 
     | 
    
         
             
            #endif
         
     | 
| 
       1528 
1588 
     | 
    
         | 
| 
      
 1589 
     | 
    
         
            +
            #ifdef CLIENT_CONNECT_ATTRS
         
     | 
| 
      
 1590 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("CONNECT_ATTRS"),
         
     | 
| 
      
 1591 
     | 
    
         
            +
                  LONG2NUM(CLIENT_CONNECT_ATTRS));
         
     | 
| 
      
 1592 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1593 
     | 
    
         
            +
              /* HACK because MySQL 5.5 and earlier don't define this constant,
         
     | 
| 
      
 1594 
     | 
    
         
            +
               * but we're using it in our default connection flags. */
         
     | 
| 
      
 1595 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("CONNECT_ATTRS"),
         
     | 
| 
      
 1596 
     | 
    
         
            +
                  INT2NUM(0));
         
     | 
| 
      
 1597 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1598 
     | 
    
         
            +
             
     | 
| 
       1529 
1599 
     | 
    
         
             
            #if defined(FULL_SSL_MODE_SUPPORT) // MySQL 5.7.11 and above
         
     | 
| 
       1530 
1600 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(SSL_MODE_DISABLED));
         
     | 
| 
       1531 
1601 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_PREFERRED"), INT2NUM(SSL_MODE_PREFERRED));
         
     | 
| 
         @@ -1553,3 +1623,29 @@ void init_mysql2_client() { 
     | 
|
| 
       1553 
1623 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_IDENTITY"), INT2NUM(0));
         
     | 
| 
       1554 
1624 
     | 
    
         
             
            #endif
         
     | 
| 
       1555 
1625 
     | 
    
         
             
            }
         
     | 
| 
      
 1626 
     | 
    
         
            +
             
     | 
| 
      
 1627 
     | 
    
         
            +
            #define flag_to_bool(f) ((client->server_status & f) ? Qtrue : Qfalse)
         
     | 
| 
      
 1628 
     | 
    
         
            +
             
     | 
| 
      
 1629 
     | 
    
         
            +
            void rb_mysql_set_server_query_flags(MYSQL *client, VALUE result) {
         
     | 
| 
      
 1630 
     | 
    
         
            +
              VALUE server_flags = rb_hash_new();
         
     | 
| 
      
 1631 
     | 
    
         
            +
             
     | 
| 
      
 1632 
     | 
    
         
            +
            #ifdef HAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED
         
     | 
| 
      
 1633 
     | 
    
         
            +
              rb_hash_aset(server_flags, sym_no_good_index_used, flag_to_bool(SERVER_QUERY_NO_GOOD_INDEX_USED));
         
     | 
| 
      
 1634 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1635 
     | 
    
         
            +
              rb_hash_aset(server_flags, sym_no_good_index_used, Qnil);
         
     | 
| 
      
 1636 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1637 
     | 
    
         
            +
             
     | 
| 
      
 1638 
     | 
    
         
            +
            #ifdef HAVE_CONST_SERVER_QUERY_NO_INDEX_USED
         
     | 
| 
      
 1639 
     | 
    
         
            +
              rb_hash_aset(server_flags, sym_no_index_used, flag_to_bool(SERVER_QUERY_NO_INDEX_USED));
         
     | 
| 
      
 1640 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1641 
     | 
    
         
            +
              rb_hash_aset(server_flags, sym_no_index_used, Qnil);
         
     | 
| 
      
 1642 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1643 
     | 
    
         
            +
             
     | 
| 
      
 1644 
     | 
    
         
            +
            #ifdef HAVE_CONST_SERVER_QUERY_WAS_SLOW
         
     | 
| 
      
 1645 
     | 
    
         
            +
              rb_hash_aset(server_flags, sym_query_was_slow, flag_to_bool(SERVER_QUERY_WAS_SLOW));
         
     | 
| 
      
 1646 
     | 
    
         
            +
            #else
         
     | 
| 
      
 1647 
     | 
    
         
            +
              rb_hash_aset(server_flags, sym_query_was_slow, Qnil);
         
     | 
| 
      
 1648 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1649 
     | 
    
         
            +
             
     | 
| 
      
 1650 
     | 
    
         
            +
              rb_iv_set(result, "@server_flags", server_flags);
         
     | 
| 
      
 1651 
     | 
    
         
            +
            }
         
     |