mysql2 0.4.4 → 0.4.5
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 +15 -5
 - data/ext/mysql2/client.c +82 -0
 - data/ext/mysql2/client.h +0 -6
 - data/ext/mysql2/extconf.rb +20 -0
 - data/ext/mysql2/result.c +3 -0
 - data/ext/mysql2/statement.c +82 -12
 - data/lib/mysql2/client.rb +14 -1
 - data/lib/mysql2/version.rb +1 -1
 - data/spec/configuration.yml.example +0 -6
 - data/spec/mysql2/client_spec.rb +27 -22
 - data/spec/mysql2/error_spec.rb +1 -1
 - data/spec/mysql2/statement_spec.rb +62 -6
 - data/spec/ssl/gen_certs.sh +1 -1
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: d82596af22ef47aa19d633dabb82afc9928c3f3f
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 09b024bdf203f596f35b4df22ed3149b19af6feb
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 23f6e023618c65e82d5f4289242257449da6138e731f27cc45553aac2ffd5b712350d59e5b5e90c0e8961795394fc437007ba8651e1a2b6863a3d6951b0a6c16
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 03bede95a81a4dc20b1dfc288a5f5807eb8d7c243b091e03f6809623d2e30726c5b69dedd9de7b94ca6a56ce13c854927c2241e528c7bb8aa42cc39dc235eba7
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -164,8 +164,8 @@ by the query like this: 
     | 
|
| 
       164 
164 
     | 
    
         
             
            ``` ruby
         
     | 
| 
       165 
165 
     | 
    
         
             
            headers = results.fields # <= that's an array of field names, in order
         
     | 
| 
       166 
166 
     | 
    
         
             
            results.each(:as => :array) do |row|
         
     | 
| 
       167 
     | 
    
         
            -
            # Each row is an array, ordered the same as the query results
         
     | 
| 
       168 
     | 
    
         
            -
            # An otter's den is called a "holt" or "couch"
         
     | 
| 
      
 167 
     | 
    
         
            +
              # Each row is an array, ordered the same as the query results
         
     | 
| 
      
 168 
     | 
    
         
            +
              # An otter's den is called a "holt" or "couch"
         
     | 
| 
       169 
169 
     | 
    
         
             
            end
         
     | 
| 
       170 
170 
     | 
    
         
             
            ```
         
     | 
| 
       171 
171 
     | 
    
         | 
| 
         @@ -203,6 +203,7 @@ Mysql2::Client.new( 
     | 
|
| 
       203 
203 
     | 
    
         
             
              :reconnect = true/false,
         
     | 
| 
       204 
204 
     | 
    
         
             
              :local_infile = true/false,
         
     | 
| 
       205 
205 
     | 
    
         
             
              :secure_auth = true/false,
         
     | 
| 
      
 206 
     | 
    
         
            +
              :ssl_mode = :disabled / :preferred / :required / :verify_ca / :verify_identity,
         
     | 
| 
       206 
207 
     | 
    
         
             
              :default_file = '/path/to/my.cfg',
         
     | 
| 
       207 
208 
     | 
    
         
             
              :default_group = 'my.cfg section',
         
     | 
| 
       208 
209 
     | 
    
         
             
              :init_command => sql
         
     | 
| 
         @@ -398,6 +399,15 @@ client = Mysql2::Client.new 
     | 
|
| 
       398 
399 
     | 
    
         
             
            result = client.query("SELECT * FROM table_with_boolean_field", :cast_booleans => true)
         
     | 
| 
       399 
400 
     | 
    
         
             
            ```
         
     | 
| 
       400 
401 
     | 
    
         | 
| 
      
 402 
     | 
    
         
            +
            Keep in mind that this works only with fields and not with computed values, e.g. this result will contain `1`, not `true`:
         
     | 
| 
      
 403 
     | 
    
         
            +
             
     | 
| 
      
 404 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 405 
     | 
    
         
            +
            client = Mysql2::Client.new
         
     | 
| 
      
 406 
     | 
    
         
            +
            result = client.query("SELECT true", :cast_booleans => true)
         
     | 
| 
      
 407 
     | 
    
         
            +
            ```
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
      
 409 
     | 
    
         
            +
            CAST function wouldn't help here as there's no way to cast to TINYINT(1). Apparently the only way to solve this is to use a stored procedure with return type set to TINYINT(1).
         
     | 
| 
      
 410 
     | 
    
         
            +
             
     | 
| 
       401 
411 
     | 
    
         
             
            ### Skipping casting
         
     | 
| 
       402 
412 
     | 
    
         | 
| 
       403 
413 
     | 
    
         
             
            Mysql2 casting is fast, but not as fast as not casting data.  In rare cases where typecasting is not needed, it will be faster to disable it by providing :cast => false. (Note that :cast => false overrides :cast_booleans => true.)
         
     | 
| 
         @@ -484,13 +494,13 @@ As for field values themselves, I'm workin on it - but expect that soon. 
     | 
|
| 
       484 
494 
     | 
    
         | 
| 
       485 
495 
     | 
    
         
             
            This gem is tested with the following Ruby versions on Linux and Mac OS X:
         
     | 
| 
       486 
496 
     | 
    
         | 
| 
       487 
     | 
    
         
            -
             * Ruby MRI 1.8.7, 1.9.3, 2.0.0, 2.1.x, 2.2.x, 2.3.x
         
     | 
| 
      
 497 
     | 
    
         
            +
             * Ruby MRI 1.8.7, 1.9.3, 2.0.0, 2.1.x, 2.2.x, 2.3.x, 2.4.x
         
     | 
| 
       488 
498 
     | 
    
         
             
             * Ruby Enterprise Edition (based on MRI 1.8.7)
         
     | 
| 
       489 
     | 
    
         
            -
             * Rubinius 2.x 
     | 
| 
      
 499 
     | 
    
         
            +
             * Rubinius 2.x and 3.x do work but may fail under some workloads
         
     | 
| 
       490 
500 
     | 
    
         | 
| 
       491 
501 
     | 
    
         
             
            This gem is tested with the following MySQL and MariaDB versions:
         
     | 
| 
       492 
502 
     | 
    
         | 
| 
       493 
     | 
    
         
            -
             * MySQL 5.5, 5.6, 5.7
         
     | 
| 
      
 503 
     | 
    
         
            +
             * MySQL 5.5, 5.6, 5.7, 8.0
         
     | 
| 
       494 
504 
     | 
    
         
             
             * MySQL Connector/C 6.0 and 6.1 (primarily on Windows)
         
     | 
| 
       495 
505 
     | 
    
         
             
             * MariaDB 5.5, 10.0, 10.1
         
     | 
| 
       496 
506 
     | 
    
         | 
    
        data/ext/mysql2/client.c
    CHANGED
    
    | 
         @@ -30,6 +30,12 @@ VALUE rb_hash_dup(VALUE other) { 
     | 
|
| 
       30 
30 
     | 
    
         
             
                rb_raise(cMysql2Error, "MySQL client is not initialized"); \
         
     | 
| 
       31 
31 
     | 
    
         
             
              }
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
      
 33 
     | 
    
         
            +
            #define REQUIRE_CONNECTED(wrapper) \
         
     | 
| 
      
 34 
     | 
    
         
            +
              REQUIRE_INITIALIZED(wrapper) \
         
     | 
| 
      
 35 
     | 
    
         
            +
              if (!wrapper->connected && !wrapper->reconnect_enabled) { \
         
     | 
| 
      
 36 
     | 
    
         
            +
                rb_raise(cMysql2Error, "MySQL client is not connected"); \
         
     | 
| 
      
 37 
     | 
    
         
            +
              }
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
       33 
39 
     | 
    
         
             
            #define REQUIRE_NOT_CONNECTED(wrapper) \
         
     | 
| 
       34 
40 
     | 
    
         
             
              REQUIRE_INITIALIZED(wrapper) \
         
     | 
| 
       35 
41 
     | 
    
         
             
              if (wrapper->connected) { \
         
     | 
| 
         @@ -47,6 +53,16 @@ VALUE rb_hash_dup(VALUE other) { 
     | 
|
| 
       47 
53 
     | 
    
         
             
              #define MYSQL_LINK_VERSION MYSQL_SERVER_VERSION
         
     | 
| 
       48 
54 
     | 
    
         
             
            #endif
         
     | 
| 
       49 
55 
     | 
    
         | 
| 
      
 56 
     | 
    
         
            +
            /*
         
     | 
| 
      
 57 
     | 
    
         
            +
             * compatibility with mysql-connector-c 6.1.x, and with MySQL 5.7.3 - 5.7.10.
         
     | 
| 
      
 58 
     | 
    
         
            +
             */
         
     | 
| 
      
 59 
     | 
    
         
            +
            #ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
         
     | 
| 
      
 60 
     | 
    
         
            +
              #define SSL_MODE_DISABLED 1
         
     | 
| 
      
 61 
     | 
    
         
            +
              #define SSL_MODE_REQUIRED 3
         
     | 
| 
      
 62 
     | 
    
         
            +
              #define HAVE_CONST_SSL_MODE_DISABLED
         
     | 
| 
      
 63 
     | 
    
         
            +
              #define HAVE_CONST_SSL_MODE_REQUIRED
         
     | 
| 
      
 64 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       50 
66 
     | 
    
         
             
            /*
         
     | 
| 
       51 
67 
     | 
    
         
             
             * used to pass all arguments to mysql_real_connect while inside
         
     | 
| 
       52 
68 
     | 
    
         
             
             * rb_thread_call_without_gvl
         
     | 
| 
         @@ -83,6 +99,43 @@ struct nogvl_select_db_args { 
     | 
|
| 
       83 
99 
     | 
    
         
             
              char *db;
         
     | 
| 
       84 
100 
     | 
    
         
             
            };
         
     | 
| 
       85 
101 
     | 
    
         | 
| 
      
 102 
     | 
    
         
            +
            static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
         
     | 
| 
      
 103 
     | 
    
         
            +
              unsigned long version = mysql_get_client_version();
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              if (version < 50703) {
         
     | 
| 
      
 106 
     | 
    
         
            +
                rb_warn( "Your mysql client library does not support setting ssl_mode; full support comes with 5.7.11." );
         
     | 
| 
      
 107 
     | 
    
         
            +
                return Qnil;
         
     | 
| 
      
 108 
     | 
    
         
            +
              }
         
     | 
| 
      
 109 
     | 
    
         
            +
            #ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
         
     | 
| 
      
 110 
     | 
    
         
            +
              GET_CLIENT(self); 
         
     | 
| 
      
 111 
     | 
    
         
            +
              int val = NUM2INT( setting );
         
     | 
| 
      
 112 
     | 
    
         
            +
              if (version >= 50703 && version < 50711) {
         
     | 
| 
      
 113 
     | 
    
         
            +
                if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
         
     | 
| 
      
 114 
     | 
    
         
            +
                  my_bool b = ( val == SSL_MODE_REQUIRED );
         
     | 
| 
      
 115 
     | 
    
         
            +
                  int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
         
     | 
| 
      
 116 
     | 
    
         
            +
                  return INT2NUM(result);
         
     | 
| 
      
 117 
     | 
    
         
            +
                  
         
     | 
| 
      
 118 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 119 
     | 
    
         
            +
                  rb_warn( "MySQL client libraries between 5.7.3 and 5.7.10 only support SSL_MODE_DISABLED and SSL_MODE_REQUIRED" );
         
     | 
| 
      
 120 
     | 
    
         
            +
                  return Qnil;
         
     | 
| 
      
 121 
     | 
    
         
            +
                }
         
     | 
| 
      
 122 
     | 
    
         
            +
              }
         
     | 
| 
      
 123 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 124 
     | 
    
         
            +
            #ifdef FULL_SSL_MODE_SUPPORT
         
     | 
| 
      
 125 
     | 
    
         
            +
              GET_CLIENT(self); 
         
     | 
| 
      
 126 
     | 
    
         
            +
              int val = NUM2INT( setting );
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              if (val != SSL_MODE_DISABLED && val != SSL_MODE_PREFERRED && val != SSL_MODE_REQUIRED && val != SSL_MODE_VERIFY_CA && val != SSL_MODE_VERIFY_IDENTITY) {
         
     | 
| 
      
 129 
     | 
    
         
            +
                rb_raise(cMysql2Error, "ssl_mode= takes DISABLED, PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY, you passed: %d", val );
         
     | 
| 
      
 130 
     | 
    
         
            +
              }
         
     | 
| 
      
 131 
     | 
    
         
            +
              int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_MODE, &val );
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              return INT2NUM(result);
         
     | 
| 
      
 134 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 135 
     | 
    
         
            +
            #ifdef NO_SSL_MODE_SUPPORT
         
     | 
| 
      
 136 
     | 
    
         
            +
              return Qnil;
         
     | 
| 
      
 137 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 138 
     | 
    
         
            +
            }
         
     | 
| 
       86 
139 
     | 
    
         
             
            /*
         
     | 
| 
       87 
140 
     | 
    
         
             
             * non-blocking mysql_*() functions that we won't be wrapping since
         
     | 
| 
       88 
141 
     | 
    
         
             
             * they do not appear to hit the network nor issue any interruptible
         
     | 
| 
         @@ -1192,6 +1245,7 @@ static VALUE set_charset_name(VALUE self, VALUE value) { 
     | 
|
| 
       1192 
1245 
     | 
    
         
             
            #endif
         
     | 
| 
       1193 
1246 
     | 
    
         
             
              GET_CLIENT(self);
         
     | 
| 
       1194 
1247 
     | 
    
         | 
| 
      
 1248 
     | 
    
         
            +
              Check_Type(value, T_STRING);
         
     | 
| 
       1195 
1249 
     | 
    
         
             
              charset_name = RSTRING_PTR(value);
         
     | 
| 
       1196 
1250 
     | 
    
         | 
| 
       1197 
1251 
     | 
    
         
             
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
         @@ -1337,6 +1391,7 @@ void init_mysql2_client() { 
     | 
|
| 
       1337 
1391 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "default_group=", set_read_default_group, 1);
         
     | 
| 
       1338 
1392 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "init_command=", set_init_command, 1);
         
     | 
| 
       1339 
1393 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5);
         
     | 
| 
      
 1394 
     | 
    
         
            +
              rb_define_private_method(cMysql2Client, "ssl_mode=", rb_set_ssl_mode_option, 1);
         
     | 
| 
       1340 
1395 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0);
         
     | 
| 
       1341 
1396 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "connect", rb_connect, 7);
         
     | 
| 
       1342 
1397 
     | 
    
         
             
              rb_define_private_method(cMysql2Client, "_query", rb_query, 2);
         
     | 
| 
         @@ -1464,4 +1519,31 @@ void init_mysql2_client() { 
     | 
|
| 
       1464 
1519 
     | 
    
         
             
              rb_const_set(cMysql2Client, rb_intern("BASIC_FLAGS"),
         
     | 
| 
       1465 
1520 
     | 
    
         
             
                  LONG2NUM(CLIENT_BASIC_FLAGS));
         
     | 
| 
       1466 
1521 
     | 
    
         
             
            #endif
         
     | 
| 
      
 1522 
     | 
    
         
            +
             
     | 
| 
      
 1523 
     | 
    
         
            +
            #if defined(FULL_SSL_MODE_SUPPORT) // MySQL 5.7.11 and above
         
     | 
| 
      
 1524 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(SSL_MODE_DISABLED));
         
     | 
| 
      
 1525 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_PREFERRED"), INT2NUM(SSL_MODE_PREFERRED));
         
     | 
| 
      
 1526 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_REQUIRED"), INT2NUM(SSL_MODE_REQUIRED));
         
     | 
| 
      
 1527 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_CA"), INT2NUM(SSL_MODE_VERIFY_CA));
         
     | 
| 
      
 1528 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_IDENTITY"), INT2NUM(SSL_MODE_VERIFY_IDENTITY));
         
     | 
| 
      
 1529 
     | 
    
         
            +
            #elif defined(HAVE_CONST_MYSQL_OPT_SSL_ENFORCE) // MySQL 5.7.3 - 5.7.10
         
     | 
| 
      
 1530 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(SSL_MODE_DISABLED));
         
     | 
| 
      
 1531 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_REQUIRED"), INT2NUM(SSL_MODE_REQUIRED));
         
     | 
| 
      
 1532 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1533 
     | 
    
         
            +
             
     | 
| 
      
 1534 
     | 
    
         
            +
            #ifndef HAVE_CONST_SSL_MODE_DISABLED
         
     | 
| 
      
 1535 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_DISABLED"), INT2NUM(0));
         
     | 
| 
      
 1536 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1537 
     | 
    
         
            +
            #ifndef HAVE_CONST_SSL_MODE_PREFERRED
         
     | 
| 
      
 1538 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_PREFERRED"), INT2NUM(0));
         
     | 
| 
      
 1539 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1540 
     | 
    
         
            +
            #ifndef HAVE_CONST_SSL_MODE_REQUIRED
         
     | 
| 
      
 1541 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_REQUIRED"), INT2NUM(0));
         
     | 
| 
      
 1542 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1543 
     | 
    
         
            +
            #ifndef HAVE_CONST_SSL_MODE_VERIFY_CA
         
     | 
| 
      
 1544 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_CA"), INT2NUM(0));
         
     | 
| 
      
 1545 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 1546 
     | 
    
         
            +
            #ifndef HAVE_CONST_SSL_MODE_VERIFY_IDENTITY
         
     | 
| 
      
 1547 
     | 
    
         
            +
              rb_const_set(cMysql2Client, rb_intern("SSL_MODE_VERIFY_IDENTITY"), INT2NUM(0));
         
     | 
| 
      
 1548 
     | 
    
         
            +
            #endif
         
     | 
| 
       1467 
1549 
     | 
    
         
             
            }
         
     | 
    
        data/ext/mysql2/client.h
    CHANGED
    
    | 
         @@ -51,12 +51,6 @@ typedef struct { 
     | 
|
| 
       51 
51 
     | 
    
         
             
              MYSQL *client;
         
     | 
| 
       52 
52 
     | 
    
         
             
            } mysql_client_wrapper;
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
            #define REQUIRE_CONNECTED(wrapper) \
         
     | 
| 
       55 
     | 
    
         
            -
              REQUIRE_INITIALIZED(wrapper) \
         
     | 
| 
       56 
     | 
    
         
            -
              if (!wrapper->connected && !wrapper->reconnect_enabled) { \
         
     | 
| 
       57 
     | 
    
         
            -
                rb_raise(cMysql2Error, "closed MySQL connection"); \
         
     | 
| 
       58 
     | 
    
         
            -
              }
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
54 
     | 
    
         
             
            void rb_mysql_client_set_active_thread(VALUE self);
         
     | 
| 
       61 
55 
     | 
    
         | 
| 
       62 
56 
     | 
    
         
             
            #define GET_CLIENT(self) \
         
     | 
    
        data/ext/mysql2/extconf.rb
    CHANGED
    
    | 
         @@ -12,6 +12,20 @@ def asplode(lib) 
     | 
|
| 
       12 
12 
     | 
    
         
             
              end
         
     | 
| 
       13 
13 
     | 
    
         
             
            end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
      
 15 
     | 
    
         
            +
            def add_ssl_defines(header)
         
     | 
| 
      
 16 
     | 
    
         
            +
              all_modes_found = %w(SSL_MODE_DISABLED SSL_MODE_PREFERRED SSL_MODE_REQUIRED SSL_MODE_VERIFY_CA SSL_MODE_VERIFY_IDENTITY).inject(true) do |m, ssl_mode|
         
     | 
| 
      
 17 
     | 
    
         
            +
                m && have_const(ssl_mode, header)
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
              $CFLAGS << ' -DFULL_SSL_MODE_SUPPORT' if all_modes_found
         
     | 
| 
      
 20 
     | 
    
         
            +
              # if we only have ssl toggle (--ssl,--disable-ssl) from 5.7.3 to 5.7.10
         
     | 
| 
      
 21 
     | 
    
         
            +
              has_no_support = all_modes_found ? false : !have_const('MYSQL_OPT_SSL_ENFORCE', header)
         
     | 
| 
      
 22 
     | 
    
         
            +
              $CFLAGS << ' -DNO_SSL_MODE_SUPPORT' if has_no_support
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            # 2.1+
         
     | 
| 
      
 26 
     | 
    
         
            +
            have_func('rb_absint_size')
         
     | 
| 
      
 27 
     | 
    
         
            +
            have_func('rb_absint_singlebit_p')
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       15 
29 
     | 
    
         
             
            # 2.0-only
         
     | 
| 
       16 
30 
     | 
    
         
             
            have_header('ruby/thread.h') && have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
         
     | 
| 
       17 
31 
     | 
    
         | 
| 
         @@ -20,6 +34,7 @@ have_func('rb_thread_blocking_region') 
     | 
|
| 
       20 
34 
     | 
    
         
             
            have_func('rb_wait_for_single_fd')
         
     | 
| 
       21 
35 
     | 
    
         
             
            have_func('rb_hash_dup')
         
     | 
| 
       22 
36 
     | 
    
         
             
            have_func('rb_intern3')
         
     | 
| 
      
 37 
     | 
    
         
            +
            have_func('rb_big_cmp')
         
     | 
| 
       23 
38 
     | 
    
         | 
| 
       24 
39 
     | 
    
         
             
            # borrowed from mysqlplus
         
     | 
| 
       25 
40 
     | 
    
         
             
            # http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
         
     | 
| 
         @@ -37,6 +52,9 @@ dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w( 
     | 
|
| 
       37 
52 
     | 
    
         
             
              /usr/local/opt/mysql5*
         
     | 
| 
       38 
53 
     | 
    
         
             
            ).map { |dir| dir << '/bin' }
         
     | 
| 
       39 
54 
     | 
    
         | 
| 
      
 55 
     | 
    
         
            +
            # For those without HOMEBREW_ROOT in PATH
         
     | 
| 
      
 56 
     | 
    
         
            +
            dirs << "#{ENV['HOMEBREW_ROOT']}/bin" if ENV['HOMEBREW_ROOT']
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
       40 
58 
     | 
    
         
             
            GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}"
         
     | 
| 
       41 
59 
     | 
    
         | 
| 
       42 
60 
     | 
    
         
             
            # If the user has provided a --with-mysql-dir argument, we must respect it or fail.
         
     | 
| 
         @@ -87,6 +105,8 @@ else 
     | 
|
| 
       87 
105 
     | 
    
         
             
              asplode 'mysql.h'
         
     | 
| 
       88 
106 
     | 
    
         
             
            end
         
     | 
| 
       89 
107 
     | 
    
         | 
| 
      
 108 
     | 
    
         
            +
            add_ssl_defines([prefix, 'mysql.h'].compact.join('/'))
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
       90 
110 
     | 
    
         
             
            %w(errmsg.h mysqld_error.h).each do |h|
         
     | 
| 
       91 
111 
     | 
    
         
             
              header = [prefix, h].compact.join '/'
         
     | 
| 
       92 
112 
     | 
    
         
             
              asplode h unless have_header header
         
     | 
    
        data/ext/mysql2/result.c
    CHANGED
    
    | 
         @@ -920,6 +920,9 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) { 
     | 
|
| 
       920 
920 
     | 
    
         
             
                wrapper->numberOfRows = wrapper->stmt_wrapper ? mysql_stmt_num_rows(wrapper->stmt_wrapper->stmt) : mysql_num_rows(wrapper->result);
         
     | 
| 
       921 
921 
     | 
    
         
             
                wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
         
     | 
| 
       922 
922 
     | 
    
         
             
              } else if (wrapper->rows && !cacheRows) {
         
     | 
| 
      
 923 
     | 
    
         
            +
                if (wrapper->resultFreed) {
         
     | 
| 
      
 924 
     | 
    
         
            +
                  rb_raise(cMysql2Error, "Result set has already been freed");
         
     | 
| 
      
 925 
     | 
    
         
            +
                }
         
     | 
| 
       923 
926 
     | 
    
         
             
                mysql_data_seek(wrapper->result, 0);
         
     | 
| 
       924 
927 
     | 
    
         
             
                wrapper->lastRowProcessed = 0;
         
     | 
| 
       925 
928 
     | 
    
         
             
                wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
         
     | 
    
        data/ext/mysql2/statement.c
    CHANGED
    
    | 
         @@ -2,8 +2,11 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            VALUE cMysql2Statement;
         
     | 
| 
       4 
4 
     | 
    
         
             
            extern VALUE mMysql2, cMysql2Error, cBigDecimal, cDateTime, cDate;
         
     | 
| 
       5 
     | 
    
         
            -
            static VALUE sym_stream, intern_new_with_args, intern_each;
         
     | 
| 
       6 
     | 
    
         
            -
            static VALUE intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year 
     | 
| 
      
 5 
     | 
    
         
            +
            static VALUE sym_stream, intern_new_with_args, intern_each, intern_to_s;
         
     | 
| 
      
 6 
     | 
    
         
            +
            static VALUE intern_sec_fraction, intern_usec, intern_sec, intern_min, intern_hour, intern_day, intern_month, intern_year;
         
     | 
| 
      
 7 
     | 
    
         
            +
            #ifndef HAVE_RB_BIG_CMP
         
     | 
| 
      
 8 
     | 
    
         
            +
            static ID id_cmp;
         
     | 
| 
      
 9 
     | 
    
         
            +
            #endif
         
     | 
| 
       7 
10 
     | 
    
         | 
| 
       8 
11 
     | 
    
         
             
            #define GET_STATEMENT(self) \
         
     | 
| 
       9 
12 
     | 
    
         
             
              mysql_stmt_wrapper *stmt_wrapper; \
         
     | 
| 
         @@ -180,7 +183,6 @@ static void *nogvl_execute(void *ptr) { 
     | 
|
| 
       180 
183 
     | 
    
         
             
            static void set_buffer_for_string(MYSQL_BIND* bind_buffer, unsigned long *length_buffer, VALUE string) {
         
     | 
| 
       181 
184 
     | 
    
         
             
              unsigned long length;
         
     | 
| 
       182 
185 
     | 
    
         | 
| 
       183 
     | 
    
         
            -
              bind_buffer->buffer_type = MYSQL_TYPE_STRING;
         
     | 
| 
       184 
186 
     | 
    
         
             
              bind_buffer->buffer = RSTRING_PTR(string);
         
     | 
| 
       185 
187 
     | 
    
         | 
| 
       186 
188 
     | 
    
         
             
              length = RSTRING_LEN(string);
         
     | 
| 
         @@ -204,6 +206,50 @@ static void set_buffer_for_string(MYSQL_BIND* bind_buffer, unsigned long *length 
     | 
|
| 
       204 
206 
     | 
    
         
             
                xfree(length_buffers);                                  \
         
     | 
| 
       205 
207 
     | 
    
         
             
              }
         
     | 
| 
       206 
208 
     | 
    
         | 
| 
      
 209 
     | 
    
         
            +
            /* return 0 if the given bignum can cast as LONG_LONG, otherwise 1 */
         
     | 
| 
      
 210 
     | 
    
         
            +
            static int my_big2ll(VALUE bignum, LONG_LONG *ptr)
         
     | 
| 
      
 211 
     | 
    
         
            +
            {
         
     | 
| 
      
 212 
     | 
    
         
            +
              unsigned LONG_LONG num;
         
     | 
| 
      
 213 
     | 
    
         
            +
              size_t len;
         
     | 
| 
      
 214 
     | 
    
         
            +
            #ifdef HAVE_RB_ABSINT_SIZE
         
     | 
| 
      
 215 
     | 
    
         
            +
              int nlz_bits = 0;
         
     | 
| 
      
 216 
     | 
    
         
            +
              len = rb_absint_size(bignum, &nlz_bits);
         
     | 
| 
      
 217 
     | 
    
         
            +
            #else
         
     | 
| 
      
 218 
     | 
    
         
            +
              len = RBIGNUM_LEN(bignum) * SIZEOF_BDIGITS;
         
     | 
| 
      
 219 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 220 
     | 
    
         
            +
              if (len > sizeof(LONG_LONG)) goto overflow;
         
     | 
| 
      
 221 
     | 
    
         
            +
              if (RBIGNUM_POSITIVE_P(bignum)) {
         
     | 
| 
      
 222 
     | 
    
         
            +
                num = rb_big2ull(bignum);
         
     | 
| 
      
 223 
     | 
    
         
            +
                if (num > LLONG_MAX)
         
     | 
| 
      
 224 
     | 
    
         
            +
                  goto overflow;
         
     | 
| 
      
 225 
     | 
    
         
            +
                *ptr = num;
         
     | 
| 
      
 226 
     | 
    
         
            +
              }
         
     | 
| 
      
 227 
     | 
    
         
            +
              else {
         
     | 
| 
      
 228 
     | 
    
         
            +
                if (len == 8 &&
         
     | 
| 
      
 229 
     | 
    
         
            +
            #ifdef HAVE_RB_ABSINT_SIZE
         
     | 
| 
      
 230 
     | 
    
         
            +
                    nlz_bits == 0 &&
         
     | 
| 
      
 231 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 232 
     | 
    
         
            +
            #if defined(HAVE_RB_ABSINT_SIZE) && defined(HAVE_RB_ABSINT_SINGLEBIT_P)
         
     | 
| 
      
 233 
     | 
    
         
            +
                    /* Optimized to avoid object allocation for Ruby 2.1+
         
     | 
| 
      
 234 
     | 
    
         
            +
                     * only -0x8000000000000000 is safe if `len == 8 && nlz_bits == 0`
         
     | 
| 
      
 235 
     | 
    
         
            +
                     */
         
     | 
| 
      
 236 
     | 
    
         
            +
                    !rb_absint_singlebit_p(bignum)
         
     | 
| 
      
 237 
     | 
    
         
            +
            #elif defined(HAVE_RB_BIG_CMP)
         
     | 
| 
      
 238 
     | 
    
         
            +
                    rb_big_cmp(bignum, LL2NUM(LLONG_MIN)) == INT2FIX(-1)
         
     | 
| 
      
 239 
     | 
    
         
            +
            #else
         
     | 
| 
      
 240 
     | 
    
         
            +
                    /* Ruby 1.8.7 and REE doesn't have rb_big_cmp */
         
     | 
| 
      
 241 
     | 
    
         
            +
                    rb_funcall(bignum, id_cmp, 1, LL2NUM(LLONG_MIN)) == INT2FIX(-1)
         
     | 
| 
      
 242 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 243 
     | 
    
         
            +
                   ) {
         
     | 
| 
      
 244 
     | 
    
         
            +
                  goto overflow;
         
     | 
| 
      
 245 
     | 
    
         
            +
                }
         
     | 
| 
      
 246 
     | 
    
         
            +
                *ptr = rb_big2ll(bignum);
         
     | 
| 
      
 247 
     | 
    
         
            +
              }
         
     | 
| 
      
 248 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 249 
     | 
    
         
            +
            overflow:
         
     | 
| 
      
 250 
     | 
    
         
            +
              return 1;
         
     | 
| 
      
 251 
     | 
    
         
            +
            }
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
       207 
253 
     | 
    
         
             
            /* call-seq: stmt.execute
         
     | 
| 
       208 
254 
     | 
    
         
             
             *
         
     | 
| 
       209 
255 
     | 
    
         
             
             * Executes the current prepared statement, returns +result+.
         
     | 
| 
         @@ -265,9 +311,23 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       265 
311 
     | 
    
         
             
            #endif
         
     | 
| 
       266 
312 
     | 
    
         
             
                      break;
         
     | 
| 
       267 
313 
     | 
    
         
             
                    case T_BIGNUM:
         
     | 
| 
       268 
     | 
    
         
            -
                       
     | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
      
 314 
     | 
    
         
            +
                      {
         
     | 
| 
      
 315 
     | 
    
         
            +
                        LONG_LONG num;
         
     | 
| 
      
 316 
     | 
    
         
            +
                        if (my_big2ll(argv[i], &num) == 0) {
         
     | 
| 
      
 317 
     | 
    
         
            +
                          bind_buffers[i].buffer_type = MYSQL_TYPE_LONGLONG;
         
     | 
| 
      
 318 
     | 
    
         
            +
                          bind_buffers[i].buffer = xmalloc(sizeof(long long int));
         
     | 
| 
      
 319 
     | 
    
         
            +
                          *(LONG_LONG*)(bind_buffers[i].buffer) = num;
         
     | 
| 
      
 320 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 321 
     | 
    
         
            +
                          /* The bignum was larger than we can fit in LONG_LONG, send it as a string */
         
     | 
| 
      
 322 
     | 
    
         
            +
                          VALUE rb_val_as_string = rb_big2str(argv[i], 10);
         
     | 
| 
      
 323 
     | 
    
         
            +
                          bind_buffers[i].buffer_type = MYSQL_TYPE_NEWDECIMAL;
         
     | 
| 
      
 324 
     | 
    
         
            +
                          params_enc[i] = rb_val_as_string;
         
     | 
| 
      
 325 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 326 
     | 
    
         
            +
                          params_enc[i] = rb_str_export_to_enc(params_enc[i], conn_enc);
         
     | 
| 
      
 327 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 328 
     | 
    
         
            +
                          set_buffer_for_string(&bind_buffers[i], &length_buffers[i], params_enc[i]);
         
     | 
| 
      
 329 
     | 
    
         
            +
                        }
         
     | 
| 
      
 330 
     | 
    
         
            +
                      }
         
     | 
| 
       271 
331 
     | 
    
         
             
                      break;
         
     | 
| 
       272 
332 
     | 
    
         
             
                    case T_FLOAT:
         
     | 
| 
       273 
333 
     | 
    
         
             
                      bind_buffers[i].buffer_type = MYSQL_TYPE_DOUBLE;
         
     | 
| 
         @@ -275,13 +335,13 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       275 
335 
     | 
    
         
             
                      *(double*)(bind_buffers[i].buffer) = NUM2DBL(argv[i]);
         
     | 
| 
       276 
336 
     | 
    
         
             
                      break;
         
     | 
| 
       277 
337 
     | 
    
         
             
                    case T_STRING:
         
     | 
| 
       278 
     | 
    
         
            -
                       
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
      
 338 
     | 
    
         
            +
                      bind_buffers[i].buffer_type = MYSQL_TYPE_STRING;
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
                      params_enc[i] = argv[i];
         
     | 
| 
       280 
341 
     | 
    
         
             
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
      
 342 
     | 
    
         
            +
                      params_enc[i] = rb_str_export_to_enc(params_enc[i], conn_enc);
         
     | 
| 
       282 
343 
     | 
    
         
             
            #endif
         
     | 
| 
       283 
     | 
    
         
            -
             
     | 
| 
       284 
     | 
    
         
            -
                      }
         
     | 
| 
      
 344 
     | 
    
         
            +
                      set_buffer_for_string(&bind_buffers[i], &length_buffers[i], params_enc[i]);
         
     | 
| 
       285 
345 
     | 
    
         
             
                      break;
         
     | 
| 
       286 
346 
     | 
    
         
             
                    default:
         
     | 
| 
       287 
347 
     | 
    
         
             
                      // TODO: what Ruby type should support MYSQL_TYPE_TIME
         
     | 
| 
         @@ -294,7 +354,13 @@ static VALUE execute(int argc, VALUE *argv, VALUE self) { 
     | 
|
| 
       294 
354 
     | 
    
         | 
| 
       295 
355 
     | 
    
         
             
                        memset(&t, 0, sizeof(MYSQL_TIME));
         
     | 
| 
       296 
356 
     | 
    
         
             
                        t.neg = 0;
         
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
      
 358 
     | 
    
         
            +
                        if (CLASS_OF(argv[i]) == rb_cTime) {
         
     | 
| 
      
 359 
     | 
    
         
            +
                          t.second_part = FIX2INT(rb_funcall(rb_time, intern_usec, 0));
         
     | 
| 
      
 360 
     | 
    
         
            +
                        } else if (CLASS_OF(argv[i]) == cDateTime) {
         
     | 
| 
      
 361 
     | 
    
         
            +
                          t.second_part = NUM2DBL(rb_funcall(rb_time, intern_sec_fraction, 0)) * 1000000;
         
     | 
| 
      
 362 
     | 
    
         
            +
                        }
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
       298 
364 
     | 
    
         
             
                        t.second = FIX2INT(rb_funcall(rb_time, intern_sec, 0));
         
     | 
| 
       299 
365 
     | 
    
         
             
                        t.minute = FIX2INT(rb_funcall(rb_time, intern_min, 0));
         
     | 
| 
       300 
366 
     | 
    
         
             
                        t.hour = FIX2INT(rb_funcall(rb_time, intern_hour, 0));
         
     | 
| 
         @@ -492,6 +558,7 @@ void init_mysql2_statement() { 
     | 
|
| 
       492 
558 
     | 
    
         
             
              intern_new_with_args = rb_intern("new_with_args");
         
     | 
| 
       493 
559 
     | 
    
         
             
              intern_each = rb_intern("each");
         
     | 
| 
       494 
560 
     | 
    
         | 
| 
      
 561 
     | 
    
         
            +
              intern_sec_fraction = rb_intern("sec_fraction");
         
     | 
| 
       495 
562 
     | 
    
         
             
              intern_usec = rb_intern("usec");
         
     | 
| 
       496 
563 
     | 
    
         
             
              intern_sec = rb_intern("sec");
         
     | 
| 
       497 
564 
     | 
    
         
             
              intern_min = rb_intern("min");
         
     | 
| 
         @@ -501,4 +568,7 @@ void init_mysql2_statement() { 
     | 
|
| 
       501 
568 
     | 
    
         
             
              intern_year = rb_intern("year");
         
     | 
| 
       502 
569 
     | 
    
         | 
| 
       503 
570 
     | 
    
         
             
              intern_to_s = rb_intern("to_s");
         
     | 
| 
      
 571 
     | 
    
         
            +
            #ifndef HAVE_RB_BIG_CMP
         
     | 
| 
      
 572 
     | 
    
         
            +
              id_cmp = rb_intern("<=>");
         
     | 
| 
      
 573 
     | 
    
         
            +
            #endif
         
     | 
| 
       504 
574 
     | 
    
         
             
            }
         
     | 
    
        data/lib/mysql2/client.rb
    CHANGED
    
    | 
         @@ -19,6 +19,7 @@ module Mysql2 
     | 
|
| 
       19 
19 
     | 
    
         
             
                end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                def initialize(opts = {})
         
     | 
| 
      
 22 
     | 
    
         
            +
                  fail Mysql2::Error, "Options parameter must be a Hash" unless opts.is_a? Hash
         
     | 
| 
       22 
23 
     | 
    
         
             
                  opts = Mysql2::Util.key_hash_as_symbols(opts)
         
     | 
| 
       23 
24 
     | 
    
         
             
                  @read_timeout = nil
         
     | 
| 
       24 
25 
     | 
    
         
             
                  @query_options = self.class.default_query_options.dup
         
     | 
| 
         @@ -36,7 +37,7 @@ module Mysql2 
     | 
|
| 
       36 
37 
     | 
    
         
             
                    when :reconnect, :local_infile, :secure_auth, :automatic_close
         
     | 
| 
       37 
38 
     | 
    
         
             
                      send(:"#{key}=", !!opts[key]) # rubocop:disable Style/DoubleNegation
         
     | 
| 
       38 
39 
     | 
    
         
             
                    when :connect_timeout, :read_timeout, :write_timeout
         
     | 
| 
       39 
     | 
    
         
            -
                      send(:"#{key}=", opts[key]) unless opts[key].nil?
         
     | 
| 
      
 40 
     | 
    
         
            +
                      send(:"#{key}=", opts[key].to_i) unless opts[key].nil?
         
     | 
| 
       40 
41 
     | 
    
         
             
                    else
         
     | 
| 
       41 
42 
     | 
    
         
             
                      send(:"#{key}=", opts[key])
         
     | 
| 
       42 
43 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -47,6 +48,7 @@ module Mysql2 
     | 
|
| 
       47 
48 
     | 
    
         | 
| 
       48 
49 
     | 
    
         
             
                  ssl_options = opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslcipher)
         
     | 
| 
       49 
50 
     | 
    
         
             
                  ssl_set(*ssl_options) if ssl_options.any?
         
     | 
| 
      
 51 
     | 
    
         
            +
                  self.ssl_mode = parse_ssl_mode(opts[:ssl_mode]) if opts[:ssl_mode]
         
     | 
| 
       50 
52 
     | 
    
         | 
| 
       51 
53 
     | 
    
         
             
                  case opts[:flags]
         
     | 
| 
       52 
54 
     | 
    
         
             
                  when Array
         
     | 
| 
         @@ -87,6 +89,17 @@ module Mysql2 
     | 
|
| 
       87 
89 
     | 
    
         
             
                  connect user, pass, host, port, database, socket, flags
         
     | 
| 
       88 
90 
     | 
    
         
             
                end
         
     | 
| 
       89 
91 
     | 
    
         | 
| 
      
 92 
     | 
    
         
            +
                def parse_ssl_mode(mode)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  m = mode.to_s.upcase
         
     | 
| 
      
 94 
     | 
    
         
            +
                  if m.start_with?('SSL_MODE_')
         
     | 
| 
      
 95 
     | 
    
         
            +
                    return Mysql2::Client.const_get(m) if Mysql2::Client.const_defined?(m)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  else
         
     | 
| 
      
 97 
     | 
    
         
            +
                    x = 'SSL_MODE_' + m
         
     | 
| 
      
 98 
     | 
    
         
            +
                    return Mysql2::Client.const_get(x) if Mysql2::Client.const_defined?(x)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                  warn "Unknown MySQL ssl_mode flag: #{mode}"
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       90 
103 
     | 
    
         
             
                def parse_flags_array(flags, initial = 0)
         
     | 
| 
       91 
104 
     | 
    
         
             
                  flags.reduce(initial) do |memo, f|
         
     | 
| 
       92 
105 
     | 
    
         
             
                    fneg = f.start_with?('-') ? f[1..-1] : nil
         
     | 
    
        data/lib/mysql2/version.rb
    CHANGED
    
    
    
        data/spec/mysql2/client_spec.rb
    CHANGED
    
    | 
         @@ -1,6 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # encoding: UTF-8
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'spec_helper'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'stringio'
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
4 
     | 
    
         
             
            RSpec.describe Mysql2::Client do
         
     | 
| 
       6 
5 
     | 
    
         
             
              context "using defaults file" do
         
     | 
| 
         @@ -34,6 +33,12 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       34 
33 
     | 
    
         
             
                }.to raise_error(Mysql2::Error)
         
     | 
| 
       35 
34 
     | 
    
         
             
              end
         
     | 
| 
       36 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
              it "should raise an exception on non-string encodings" do
         
     | 
| 
      
 37 
     | 
    
         
            +
                expect {
         
     | 
| 
      
 38 
     | 
    
         
            +
                  Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => :fake))
         
     | 
| 
      
 39 
     | 
    
         
            +
                }.to raise_error(TypeError)
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
       37 
42 
     | 
    
         
             
              it "should not raise an exception on create for a valid encoding" do
         
     | 
| 
       38 
43 
     | 
    
         
             
                expect {
         
     | 
| 
       39 
44 
     | 
    
         
             
                  Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "utf8"))
         
     | 
| 
         @@ -200,22 +205,21 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       200 
205 
     | 
    
         | 
| 
       201 
206 
     | 
    
         
             
                if RUBY_PLATFORM =~ /mingw|mswin/
         
     | 
| 
       202 
207 
     | 
    
         
             
                  it "cannot be disabled" do
         
     | 
| 
       203 
     | 
    
         
            -
                     
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
                      client  
     | 
| 
      
 208 
     | 
    
         
            +
                    expect do
         
     | 
| 
      
 209 
     | 
    
         
            +
                      client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:automatic_close => false))
         
     | 
| 
      
 210 
     | 
    
         
            +
                      expect(client.automatic_close?).to be(true)
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end.to output(/always closed by garbage collector/).to_stderr
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                    expect do
         
     | 
| 
      
 214 
     | 
    
         
            +
                      client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:automatic_close => true))
         
     | 
| 
      
 215 
     | 
    
         
            +
                      expect(client.automatic_close?).to be(true)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    end.to_not output(/always closed by garbage collector/).to_stderr
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                    expect do
         
     | 
| 
      
 219 
     | 
    
         
            +
                      client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:automatic_close => true))
         
     | 
| 
       211 
220 
     | 
    
         
             
                      client.automatic_close = false
         
     | 
| 
       212 
     | 
    
         
            -
                      expect( 
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
                      expect { client.automatic_close = true }.to_not change { $stderr.string }
         
     | 
| 
       216 
     | 
    
         
            -
                    ensure
         
     | 
| 
       217 
     | 
    
         
            -
                      $stderr = stderr
         
     | 
| 
       218 
     | 
    
         
            -
                    end
         
     | 
| 
      
 221 
     | 
    
         
            +
                      expect(client.automatic_close?).to be(true)
         
     | 
| 
      
 222 
     | 
    
         
            +
                    end.to output(/always closed by garbage collector/).to_stderr
         
     | 
| 
       219 
223 
     | 
    
         
             
                  end
         
     | 
| 
       220 
224 
     | 
    
         
             
                else
         
     | 
| 
       221 
225 
     | 
    
         
             
                  it "can be configured" do
         
     | 
| 
         @@ -263,13 +267,14 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       263 
267 
     | 
    
         
             
              end
         
     | 
| 
       264 
268 
     | 
    
         | 
| 
       265 
269 
     | 
    
         
             
              it "should be able to connect to database with numeric-only name" do
         
     | 
| 
       266 
     | 
    
         
            -
                 
     | 
| 
       267 
     | 
    
         
            -
                @client.query "CREATE DATABASE IF NOT EXISTS `#{ 
     | 
| 
       268 
     | 
    
         
            -
                @client.query "GRANT ALL ON `#{creds['database']}`.* TO #{creds['username']}@`#{creds['host']}`"
         
     | 
| 
      
 270 
     | 
    
         
            +
                database = 1235
         
     | 
| 
      
 271 
     | 
    
         
            +
                @client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
         
     | 
| 
       269 
272 
     | 
    
         | 
| 
       270 
     | 
    
         
            -
                expect { 
     | 
| 
      
 273 
     | 
    
         
            +
                expect {
         
     | 
| 
      
 274 
     | 
    
         
            +
                  Mysql2::Client.new(DatabaseCredentials['root'].merge('database' => database))
         
     | 
| 
      
 275 
     | 
    
         
            +
                }.not_to raise_error
         
     | 
| 
       271 
276 
     | 
    
         | 
| 
       272 
     | 
    
         
            -
                @client.query "DROP DATABASE IF EXISTS `#{ 
     | 
| 
      
 277 
     | 
    
         
            +
                @client.query "DROP DATABASE IF EXISTS `#{database}`"
         
     | 
| 
       273 
278 
     | 
    
         
             
              end
         
     | 
| 
       274 
279 
     | 
    
         | 
| 
       275 
280 
     | 
    
         
             
              it "should respond to #close" do
         
     | 
| 
         @@ -559,7 +564,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       559 
564 
     | 
    
         
             
                  context 'when a non-standard exception class is raised' do
         
     | 
| 
       560 
565 
     | 
    
         
             
                    it "should close the connection when an exception is raised" do
         
     | 
| 
       561 
566 
     | 
    
         
             
                      expect { Timeout.timeout(0.1, ArgumentError) { @client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
         
     | 
| 
       562 
     | 
    
         
            -
                      expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, ' 
     | 
| 
      
 567 
     | 
    
         
            +
                      expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, 'MySQL client is not connected')
         
     | 
| 
       563 
568 
     | 
    
         
             
                    end
         
     | 
| 
       564 
569 
     | 
    
         | 
| 
       565 
570 
     | 
    
         
             
                    it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
         
     | 
    
        data/spec/mysql2/error_spec.rb
    CHANGED
    
    
| 
         @@ -6,11 +6,13 @@ RSpec.describe Mysql2::Statement do 
     | 
|
| 
       6 
6 
     | 
    
         
             
                @client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "utf8"))
         
     | 
| 
       7 
7 
     | 
    
         
             
              end
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
              def stmt_count
         
     | 
| 
      
 10 
     | 
    
         
            +
                @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       9 
13 
     | 
    
         
             
              it "should create a statement" do
         
     | 
| 
       10 
14 
     | 
    
         
             
                statement = nil
         
     | 
| 
       11 
     | 
    
         
            -
                expect { statement = @client.prepare 'SELECT 1' }.to change 
     | 
| 
       12 
     | 
    
         
            -
                  @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
         
     | 
| 
       13 
     | 
    
         
            -
                }.by(1)
         
     | 
| 
      
 15 
     | 
    
         
            +
                expect { statement = @client.prepare 'SELECT 1' }.to change(&method(:stmt_count)).by(1)
         
     | 
| 
       14 
16 
     | 
    
         
             
                expect(statement).to be_an_instance_of(Mysql2::Statement)
         
     | 
| 
       15 
17 
     | 
    
         
             
              end
         
     | 
| 
       16 
18 
     | 
    
         | 
| 
         @@ -59,6 +61,26 @@ RSpec.describe Mysql2::Statement do 
     | 
|
| 
       59 
61 
     | 
    
         
             
                expect(rows).to eq([{ "1" => 1 }])
         
     | 
| 
       60 
62 
     | 
    
         
             
              end
         
     | 
| 
       61 
63 
     | 
    
         | 
| 
      
 64 
     | 
    
         
            +
              it "should handle bignum but in int64_t" do
         
     | 
| 
      
 65 
     | 
    
         
            +
                stmt = @client.prepare('SELECT ? AS max, ? AS min')
         
     | 
| 
      
 66 
     | 
    
         
            +
                int64_max = (1 << 63) - 1
         
     | 
| 
      
 67 
     | 
    
         
            +
                int64_min = -(1 << 63)
         
     | 
| 
      
 68 
     | 
    
         
            +
                result = stmt.execute(int64_max, int64_min)
         
     | 
| 
      
 69 
     | 
    
         
            +
                expect(result.to_a).to eq(['max' => int64_max, 'min' => int64_min])
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              it "should handle bignum but beyond int64_t" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                stmt = @client.prepare('SELECT ? AS max1, ? AS max2, ? AS max3, ? AS min1, ? AS min2, ? AS min3')
         
     | 
| 
      
 74 
     | 
    
         
            +
                int64_max1 = (1 << 63)
         
     | 
| 
      
 75 
     | 
    
         
            +
                int64_max2 = (1 << 64) - 1
         
     | 
| 
      
 76 
     | 
    
         
            +
                int64_max3 = 1 << 64
         
     | 
| 
      
 77 
     | 
    
         
            +
                int64_min1 = -(1 << 63) - 1
         
     | 
| 
      
 78 
     | 
    
         
            +
                int64_min2 = -(1 << 64) + 1
         
     | 
| 
      
 79 
     | 
    
         
            +
                int64_min3 = -0xC000000000000000
         
     | 
| 
      
 80 
     | 
    
         
            +
                result = stmt.execute(int64_max1, int64_max2, int64_max3, int64_min1, int64_min2, int64_min3)
         
     | 
| 
      
 81 
     | 
    
         
            +
                expect(result.to_a).to eq(['max1' => int64_max1, 'max2' => int64_max2, 'max3' => int64_max3, 'min1' => int64_min1, 'min2' => int64_min2, 'min3' => int64_min3])
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       62 
84 
     | 
    
         
             
              it "should keep its result after other query" do
         
     | 
| 
       63 
85 
     | 
    
         
             
                @client.query 'USE test'
         
     | 
| 
       64 
86 
     | 
    
         
             
                @client.query 'CREATE TABLE IF NOT EXISTS mysql2_stmt_q(a int)'
         
     | 
| 
         @@ -108,6 +130,35 @@ RSpec.describe Mysql2::Statement do 
     | 
|
| 
       108 
130 
     | 
    
         
             
                expect(result.first.first[1]).to be_an_instance_of(Time)
         
     | 
| 
       109 
131 
     | 
    
         
             
              end
         
     | 
| 
       110 
132 
     | 
    
         | 
| 
      
 133 
     | 
    
         
            +
              it "should prepare Date values" do
         
     | 
| 
      
 134 
     | 
    
         
            +
                now = Date.today
         
     | 
| 
      
 135 
     | 
    
         
            +
                statement = @client.prepare('SELECT ? AS a')
         
     | 
| 
      
 136 
     | 
    
         
            +
                result = statement.execute(now)
         
     | 
| 
      
 137 
     | 
    
         
            +
                expect(result.first['a'].to_s).to eql(now.strftime('%F'))
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
              it "should prepare Time values with microseconds" do
         
     | 
| 
      
 141 
     | 
    
         
            +
                now = Time.now
         
     | 
| 
      
 142 
     | 
    
         
            +
                statement = @client.prepare('SELECT ? AS a')
         
     | 
| 
      
 143 
     | 
    
         
            +
                result = statement.execute(now)
         
     | 
| 
      
 144 
     | 
    
         
            +
                if RUBY_VERSION =~ /1.8/
         
     | 
| 
      
 145 
     | 
    
         
            +
                  expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
         
     | 
| 
      
 146 
     | 
    
         
            +
                else
         
     | 
| 
      
 147 
     | 
    
         
            +
                  expect(result.first['a'].strftime('%F %T.%6N %z')).to eql(now.strftime('%F %T.%6N %z'))
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              it "should prepare DateTime values with microseconds" do
         
     | 
| 
      
 152 
     | 
    
         
            +
                now = DateTime.now
         
     | 
| 
      
 153 
     | 
    
         
            +
                statement = @client.prepare('SELECT ? AS a')
         
     | 
| 
      
 154 
     | 
    
         
            +
                result = statement.execute(now)
         
     | 
| 
      
 155 
     | 
    
         
            +
                if RUBY_VERSION =~ /1.8/
         
     | 
| 
      
 156 
     | 
    
         
            +
                  expect(result.first['a'].strftime('%F %T %z')).to eql(now.strftime('%F %T %z'))
         
     | 
| 
      
 157 
     | 
    
         
            +
                else
         
     | 
| 
      
 158 
     | 
    
         
            +
                  expect(result.first['a'].strftime('%F %T.%6N %z')).to eql(now.strftime('%F %T.%6N %z'))
         
     | 
| 
      
 159 
     | 
    
         
            +
                end
         
     | 
| 
      
 160 
     | 
    
         
            +
              end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
       111 
162 
     | 
    
         
             
              it "should tell us about the fields" do
         
     | 
| 
       112 
163 
     | 
    
         
             
                statement = @client.prepare 'SELECT 1 as foo, 2'
         
     | 
| 
       113 
164 
     | 
    
         
             
                statement.execute
         
     | 
| 
         @@ -117,6 +168,13 @@ RSpec.describe Mysql2::Statement do 
     | 
|
| 
       117 
168 
     | 
    
         
             
                expect(list[1]).to eq('2')
         
     | 
| 
       118 
169 
     | 
    
         
             
              end
         
     | 
| 
       119 
170 
     | 
    
         | 
| 
      
 171 
     | 
    
         
            +
              it "should handle as a decimal binding a BigDecimal" do
         
     | 
| 
      
 172 
     | 
    
         
            +
                stmt = @client.prepare('SELECT ? AS decimal_test')
         
     | 
| 
      
 173 
     | 
    
         
            +
                test_result = stmt.execute(BigDecimal.new("123.45")).first
         
     | 
| 
      
 174 
     | 
    
         
            +
                expect(test_result['decimal_test']).to be_an_instance_of(BigDecimal)
         
     | 
| 
      
 175 
     | 
    
         
            +
                expect(test_result['decimal_test']).to eql(123.45)
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
       120 
178 
     | 
    
         
             
              it "should update a DECIMAL value passing a BigDecimal" do
         
     | 
| 
       121 
179 
     | 
    
         
             
                @client.query 'USE test'
         
     | 
| 
       122 
180 
     | 
    
         
             
                @client.query 'DROP TABLE IF EXISTS mysql2_stmt_decimal_test'
         
     | 
| 
         @@ -689,9 +747,7 @@ RSpec.describe Mysql2::Statement do 
     | 
|
| 
       689 
747 
     | 
    
         
             
              context 'close' do
         
     | 
| 
       690 
748 
     | 
    
         
             
                it 'should free server resources' do
         
     | 
| 
       691 
749 
     | 
    
         
             
                  stmt = @client.prepare 'SELECT 1'
         
     | 
| 
       692 
     | 
    
         
            -
                  expect { stmt.close }.to change 
     | 
| 
       693 
     | 
    
         
            -
                    @client.query("SHOW STATUS LIKE 'Prepared_stmt_count'").first['Value'].to_i
         
     | 
| 
       694 
     | 
    
         
            -
                  }.by(-1)
         
     | 
| 
      
 750 
     | 
    
         
            +
                  expect { stmt.close }.to change(&method(:stmt_count)).by(-1)
         
     | 
| 
       695 
751 
     | 
    
         
             
                end
         
     | 
| 
       696 
752 
     | 
    
         | 
| 
       697 
753 
     | 
    
         
             
                it 'should raise an error on subsequent execution' do
         
     | 
    
        data/spec/ssl/gen_certs.sh
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: mysql2
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.4. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.4.5
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Brian Lopez
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2016- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2016-10-22 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       14 
14 
     | 
    
         
             
            description: 
         
     | 
| 
       15 
15 
     | 
    
         
             
            email:
         
     |