mysql2 0.4.0 → 0.4.1
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/examples/eventmachine.rb +1 -1
- data/ext/mysql2/client.c +45 -44
- data/ext/mysql2/client.h +1 -2
- data/ext/mysql2/extconf.rb +59 -37
- data/ext/mysql2/infile.c +2 -2
- data/ext/mysql2/mysql2_ext.h +4 -6
- data/ext/mysql2/mysql_enc_name_to_ruby.h +8 -8
- data/ext/mysql2/mysql_enc_to_ruby.h +25 -22
- data/ext/mysql2/result.c +4 -16
- data/ext/mysql2/result.h +3 -3
- data/ext/mysql2/statement.c +79 -42
- data/ext/mysql2/statement.h +2 -6
- data/lib/mysql2.rb +36 -18
- data/lib/mysql2/client.rb +28 -27
- data/lib/mysql2/console.rb +1 -1
- data/lib/mysql2/em.rb +5 -6
- data/lib/mysql2/error.rb +10 -7
- data/lib/mysql2/field.rb +1 -2
- data/lib/mysql2/statement.rb +12 -0
- data/lib/mysql2/version.rb +1 -1
- data/spec/em/em_spec.rb +8 -8
- data/spec/mysql2/client_spec.rb +62 -37
- data/spec/mysql2/result_spec.rb +48 -48
- data/spec/mysql2/statement_spec.rb +143 -57
- data/spec/ssl/ca-cert.pem +17 -0
- data/spec/ssl/ca-key.pem +27 -0
- data/spec/ssl/ca.cnf +22 -0
- data/spec/ssl/cert.cnf +22 -0
- data/spec/ssl/client-cert.pem +17 -0
- data/spec/ssl/client-key.pem +27 -0
- data/spec/ssl/client-req.pem +15 -0
- data/spec/ssl/gen_certs.sh +48 -0
- data/spec/ssl/pkcs8-client-key.pem +28 -0
- data/spec/ssl/pkcs8-server-key.pem +28 -0
- data/spec/ssl/server-cert.pem +17 -0
- data/spec/ssl/server-key.pem +27 -0
- data/spec/ssl/server-req.pem +15 -0
- data/support/mysql_enc_to_ruby.rb +7 -8
- data/support/ruby_enc_to_mysql.rb +1 -1
- metadata +28 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ea76ea0b1ef19163cecb0a38f0a4bcf44b0b32c5
         | 
| 4 | 
            +
              data.tar.gz: 472478d5dd515629891b26aca5169d038df0df0e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: de4abae3ac4f88dcedf81ab2b4d24b38b22e2006b38476b986a4fe072512d7eb7a7c1c68f569f0ee30b45ffa0e3a727ea626b392e837fcde2444a099a1cb00c5
         | 
| 7 | 
            +
              data.tar.gz: 15b876980c214865b1098d4f821647f0c1fd93ab397b020214325984d1e10e36d69297739958773ae158af9ecf2aa932c408b926b18e31a1446a3d8bdfed4de1
         | 
    
        data/examples/eventmachine.rb
    CHANGED
    
    
    
        data/ext/mysql2/client.c
    CHANGED
    
    | @@ -17,8 +17,7 @@ | |
| 17 17 | 
             
            VALUE cMysql2Client;
         | 
| 18 18 | 
             
            extern VALUE mMysql2, cMysql2Error;
         | 
| 19 19 | 
             
            static VALUE sym_id, sym_version, sym_header_version, sym_async, sym_symbolize_keys, sym_as, sym_array, sym_stream;
         | 
| 20 | 
            -
            static ID intern_merge, intern_merge_bang,  | 
| 21 | 
            -
            static ID intern_brackets, intern_new;
         | 
| 20 | 
            +
            static ID intern_brackets, intern_merge, intern_merge_bang, intern_new_with_args;
         | 
| 22 21 |  | 
| 23 22 | 
             
            #ifndef HAVE_RB_HASH_DUP
         | 
| 24 23 | 
             
            VALUE rb_hash_dup(VALUE other) {
         | 
| @@ -124,11 +123,12 @@ static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) { | |
| 124 123 | 
             
              rb_enc_associate(rb_sql_state, rb_usascii_encoding());
         | 
| 125 124 | 
             
            #endif
         | 
| 126 125 |  | 
| 127 | 
            -
              e = rb_funcall(cMysql2Error,  | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 126 | 
            +
              e = rb_funcall(cMysql2Error, intern_new_with_args, 4,
         | 
| 127 | 
            +
                             rb_error_msg,
         | 
| 128 | 
            +
                             LONG2FIX(wrapper->server_version),
         | 
| 129 | 
            +
                             UINT2NUM(mysql_errno(wrapper->client)),
         | 
| 130 | 
            +
                             rb_sql_state);
         | 
| 130 131 | 
             
              rb_exc_raise(e);
         | 
| 131 | 
            -
              return Qnil;
         | 
| 132 132 | 
             
            }
         | 
| 133 133 |  | 
| 134 134 | 
             
            static void *nogvl_init(void *ptr) {
         | 
| @@ -209,32 +209,19 @@ static VALUE invalidate_fd(int clientfd) | |
| 209 209 | 
             
            #endif /* _WIN32 */
         | 
| 210 210 |  | 
| 211 211 | 
             
            static void *nogvl_close(void *ptr) {
         | 
| 212 | 
            -
              mysql_client_wrapper *wrapper;
         | 
| 213 | 
            -
              wrapper = ptr;
         | 
| 214 | 
            -
              if (wrapper->connected) {
         | 
| 215 | 
            -
                wrapper->active_thread = Qnil;
         | 
| 216 | 
            -
                wrapper->connected = 0;
         | 
| 217 | 
            -
            #ifndef _WIN32
         | 
| 218 | 
            -
                /* Invalidate the socket before calling mysql_close(). This prevents
         | 
| 219 | 
            -
                 * mysql_close() from sending a mysql-QUIT or from calling shutdown() on
         | 
| 220 | 
            -
                 * the socket. The difference is that invalidate_fd will drop this
         | 
| 221 | 
            -
                 * process's reference to the socket only, while a QUIT or shutdown()
         | 
| 222 | 
            -
                 * would render the underlying connection unusable, interrupting other
         | 
| 223 | 
            -
                 * processes which share this object across a fork().
         | 
| 224 | 
            -
                 */
         | 
| 225 | 
            -
                if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
         | 
| 226 | 
            -
                  fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely, leaking some memory\n");
         | 
| 227 | 
            -
                  close(wrapper->client->net.fd);
         | 
| 228 | 
            -
                  return NULL;
         | 
| 229 | 
            -
                }
         | 
| 230 | 
            -
            #endif
         | 
| 212 | 
            +
              mysql_client_wrapper *wrapper = ptr;
         | 
| 231 213 |  | 
| 232 | 
            -
             | 
| 214 | 
            +
              if (wrapper->client) {
         | 
| 215 | 
            +
                mysql_close(wrapper->client);
         | 
| 216 | 
            +
                wrapper->client = NULL;
         | 
| 217 | 
            +
                wrapper->connected = 0;
         | 
| 218 | 
            +
                wrapper->active_thread = Qnil;
         | 
| 233 219 | 
             
              }
         | 
| 234 220 |  | 
| 235 221 | 
             
              return NULL;
         | 
| 236 222 | 
             
            }
         | 
| 237 223 |  | 
| 224 | 
            +
            /* this is called during GC */
         | 
| 238 225 | 
             
            static void rb_mysql_client_free(void *ptr) {
         | 
| 239 226 | 
             
              mysql_client_wrapper *wrapper = (mysql_client_wrapper *)ptr;
         | 
| 240 227 | 
             
              decr_mysql2_client(wrapper);
         | 
| @@ -245,6 +232,22 @@ void decr_mysql2_client(mysql_client_wrapper *wrapper) | |
| 245 232 | 
             
              wrapper->refcount--;
         | 
| 246 233 |  | 
| 247 234 | 
             
              if (wrapper->refcount == 0) {
         | 
| 235 | 
            +
            #ifndef _WIN32
         | 
| 236 | 
            +
                if (wrapper->connected) {
         | 
| 237 | 
            +
                  /* The client is being garbage collected while connected. Prevent
         | 
| 238 | 
            +
                   * mysql_close() from sending a mysql-QUIT or from calling shutdown() on
         | 
| 239 | 
            +
                   * the socket by invalidating it. invalidate_fd() will drop this
         | 
| 240 | 
            +
                   * process's reference to the socket only, while a QUIT or shutdown()
         | 
| 241 | 
            +
                   * would render the underlying connection unusable, interrupting other
         | 
| 242 | 
            +
                   * processes which share this object across a fork().
         | 
| 243 | 
            +
                   */
         | 
| 244 | 
            +
                  if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
         | 
| 245 | 
            +
                    fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely\n");
         | 
| 246 | 
            +
                    close(wrapper->client->net.fd);
         | 
| 247 | 
            +
                  }
         | 
| 248 | 
            +
                }
         | 
| 249 | 
            +
            #endif
         | 
| 250 | 
            +
             | 
| 248 251 | 
             
                nogvl_close(wrapper);
         | 
| 249 252 | 
             
                xfree(wrapper->client);
         | 
| 250 253 | 
             
                xfree(wrapper);
         | 
| @@ -256,7 +259,7 @@ static VALUE allocate(VALUE klass) { | |
| 256 259 | 
             
              mysql_client_wrapper * wrapper;
         | 
| 257 260 | 
             
              obj = Data_Make_Struct(klass, mysql_client_wrapper, rb_mysql_client_mark, rb_mysql_client_free, wrapper);
         | 
| 258 261 | 
             
              wrapper->encoding = Qnil;
         | 
| 259 | 
            -
               | 
| 262 | 
            +
              MARK_CONN_INACTIVE(self);
         | 
| 260 263 | 
             
              wrapper->server_version = 0;
         | 
| 261 264 | 
             
              wrapper->reconnect_enabled = 0;
         | 
| 262 265 | 
             
              wrapper->connect_timeout = 0;
         | 
| @@ -378,10 +381,13 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po | |
| 378 381 | 
             
            }
         | 
| 379 382 |  | 
| 380 383 | 
             
            /*
         | 
| 381 | 
            -
             *  | 
| 382 | 
            -
             *  | 
| 383 | 
            -
             *  | 
| 384 | 
            -
             *  | 
| 384 | 
            +
             * Terminate the connection; call this when the connection is no longer needed.
         | 
| 385 | 
            +
             * The garbage collector can close the connection, but doing so emits an
         | 
| 386 | 
            +
             * "Aborted connection" error on the server and increments the Aborted_clients
         | 
| 387 | 
            +
             * status variable.
         | 
| 388 | 
            +
             *
         | 
| 389 | 
            +
             * @see http://dev.mysql.com/doc/en/communication-errors.html
         | 
| 390 | 
            +
             * @return [void]
         | 
| 385 391 | 
             
             */
         | 
| 386 392 | 
             
            static VALUE rb_mysql_client_close(VALUE self) {
         | 
| 387 393 | 
             
              GET_CLIENT(self);
         | 
| @@ -412,7 +418,7 @@ static VALUE do_send_query(void *args) { | |
| 412 418 | 
             
              mysql_client_wrapper *wrapper = query_args->wrapper;
         | 
| 413 419 | 
             
              if ((VALUE)rb_thread_call_without_gvl(nogvl_send_query, args, RUBY_UBF_IO, 0) == Qfalse) {
         | 
| 414 420 | 
             
                /* an error occurred, we're not active anymore */
         | 
| 415 | 
            -
                 | 
| 421 | 
            +
                MARK_CONN_INACTIVE(self);
         | 
| 416 422 | 
             
                return rb_raise_mysql2_error(wrapper);
         | 
| 417 423 | 
             
              }
         | 
| 418 424 | 
             
              return Qnil;
         | 
| @@ -443,7 +449,7 @@ static void *nogvl_do_result(void *ptr, char use_result) { | |
| 443 449 |  | 
| 444 450 | 
             
              /* once our result is stored off, this connection is
         | 
| 445 451 | 
             
                 ready for another command to be issued */
         | 
| 446 | 
            -
               | 
| 452 | 
            +
              MARK_CONN_INACTIVE(self);
         | 
| 447 453 |  | 
| 448 454 | 
             
              return result;
         | 
| 449 455 | 
             
            }
         | 
| @@ -512,7 +518,7 @@ struct async_query_args { | |
| 512 518 | 
             
            static VALUE disconnect_and_raise(VALUE self, VALUE error) {
         | 
| 513 519 | 
             
              GET_CLIENT(self);
         | 
| 514 520 |  | 
| 515 | 
            -
               | 
| 521 | 
            +
              MARK_CONN_INACTIVE(self);
         | 
| 516 522 | 
             
              wrapper->connected = 0;
         | 
| 517 523 |  | 
| 518 524 | 
             
              /* Invalidate the MySQL socket to prevent further communication.
         | 
| @@ -524,8 +530,6 @@ static VALUE disconnect_and_raise(VALUE self, VALUE error) { | |
| 524 530 | 
             
              }
         | 
| 525 531 |  | 
| 526 532 | 
             
              rb_exc_raise(error);
         | 
| 527 | 
            -
             | 
| 528 | 
            -
              return Qnil;
         | 
| 529 533 | 
             
            }
         | 
| 530 534 |  | 
| 531 535 | 
             
            static VALUE do_query(void *args) {
         | 
| @@ -588,7 +592,7 @@ static VALUE finish_and_mark_inactive(void *args) { | |
| 588 592 | 
             
                result = (MYSQL_RES *)rb_thread_call_without_gvl(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
         | 
| 589 593 | 
             
                mysql_free_result(result);
         | 
| 590 594 |  | 
| 591 | 
            -
                 | 
| 595 | 
            +
                MARK_CONN_INACTIVE(self);
         | 
| 592 596 | 
             
              }
         | 
| 593 597 |  | 
| 594 598 | 
             
              return Qnil;
         | 
| @@ -610,7 +614,6 @@ void rb_mysql_client_set_active_thread(VALUE self) { | |
| 610 614 | 
             
                const char *thr = StringValueCStr(inspect);
         | 
| 611 615 |  | 
| 612 616 | 
             
                rb_raise(cMysql2Error, "This connection is in use by: %s", thr);
         | 
| 613 | 
            -
                (void)RB_GC_GUARD(inspect);
         | 
| 614 617 | 
             
              }
         | 
| 615 618 | 
             
            }
         | 
| 616 619 |  | 
| @@ -648,7 +651,7 @@ static VALUE rb_mysql_client_abandon_results(VALUE self) { | |
| 648 651 | 
             
             *    client.query(sql, options = {})
         | 
| 649 652 | 
             
             *
         | 
| 650 653 | 
             
             * Query the database with +sql+, with optional +options+.  For the possible
         | 
| 651 | 
            -
             * options, see  | 
| 654 | 
            +
             * options, see default_query_options on the Mysql2::Client class.
         | 
| 652 655 | 
             
             */
         | 
| 653 656 | 
             
            static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
         | 
| 654 657 | 
             
            #ifndef _WIN32
         | 
| @@ -1215,6 +1218,7 @@ static VALUE rb_mysql_client_prepare_statement(VALUE self, VALUE sql) { | |
| 1215 1218 | 
             
            }
         | 
| 1216 1219 |  | 
| 1217 1220 | 
             
            void init_mysql2_client() {
         | 
| 1221 | 
            +
            #ifdef _WIN32
         | 
| 1218 1222 | 
             
              /* verify the libmysql we're about to use was the version we were built against
         | 
| 1219 1223 | 
             
                 https://github.com/luislavena/mysql-gem/commit/a600a9c459597da0712f70f43736e24b484f8a99 */
         | 
| 1220 1224 | 
             
              int i;
         | 
| @@ -1229,15 +1233,14 @@ void init_mysql2_client() { | |
| 1229 1233 | 
             
                }
         | 
| 1230 1234 | 
             
                if (lib[i] != MYSQL_LINK_VERSION[i]) {
         | 
| 1231 1235 | 
             
                  rb_raise(rb_eRuntimeError, "Incorrect MySQL client library version! This gem was compiled for %s but the client library is %s.", MYSQL_LINK_VERSION, lib);
         | 
| 1232 | 
            -
                  return;
         | 
| 1233 1236 | 
             
                }
         | 
| 1234 1237 | 
             
              }
         | 
| 1238 | 
            +
            #endif
         | 
| 1235 1239 |  | 
| 1236 1240 | 
             
              /* Initializing mysql library, so different threads could call Client.new */
         | 
| 1237 1241 | 
             
              /* without race condition in the library */
         | 
| 1238 1242 | 
             
              if (mysql_library_init(0, NULL, NULL) != 0) {
         | 
| 1239 1243 | 
             
                rb_raise(rb_eRuntimeError, "Could not initialize MySQL client library");
         | 
| 1240 | 
            -
                return;
         | 
| 1241 1244 | 
             
              }
         | 
| 1242 1245 |  | 
| 1243 1246 | 
             
            #if 0
         | 
| @@ -1296,11 +1299,9 @@ void init_mysql2_client() { | |
| 1296 1299 | 
             
              sym_stream          = ID2SYM(rb_intern("stream"));
         | 
| 1297 1300 |  | 
| 1298 1301 | 
             
              intern_brackets = rb_intern("[]");
         | 
| 1299 | 
            -
              intern_new = rb_intern("new");
         | 
| 1300 1302 | 
             
              intern_merge = rb_intern("merge");
         | 
| 1301 1303 | 
             
              intern_merge_bang = rb_intern("merge!");
         | 
| 1302 | 
            -
               | 
| 1303 | 
            -
              intern_sql_state_eql = rb_intern("sql_state=");
         | 
| 1304 | 
            +
              intern_new_with_args = rb_intern("new_with_args");
         | 
| 1304 1305 |  | 
| 1305 1306 | 
             
            #ifdef CLIENT_LONG_PASSWORD
         | 
| 1306 1307 | 
             
              rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"),
         | 
    
        data/ext/mysql2/client.h
    CHANGED
    
    | @@ -59,7 +59,6 @@ typedef struct { | |
| 59 59 | 
             
            void rb_mysql_client_set_active_thread(VALUE self);
         | 
| 60 60 |  | 
| 61 61 | 
             
            #define MARK_CONN_INACTIVE(conn) do {\
         | 
| 62 | 
            -
                GET_CLIENT(conn); \
         | 
| 63 62 | 
             
                wrapper->active_thread = Qnil; \
         | 
| 64 63 | 
             
              } while(0)
         | 
| 65 64 |  | 
| @@ -67,7 +66,7 @@ void rb_mysql_client_set_active_thread(VALUE self); | |
| 67 66 | 
             
              mysql_client_wrapper *wrapper; \
         | 
| 68 67 | 
             
              Data_Get_Struct(self, mysql_client_wrapper, wrapper);
         | 
| 69 68 |  | 
| 70 | 
            -
            void init_mysql2_client();
         | 
| 69 | 
            +
            void init_mysql2_client(void);
         | 
| 71 70 | 
             
            void decr_mysql2_client(mysql_client_wrapper *wrapper);
         | 
| 72 71 |  | 
| 73 72 | 
             
            #endif
         | 
    
        data/ext/mysql2/extconf.rb
    CHANGED
    
    | @@ -1,7 +1,8 @@ | |
| 1 1 | 
             
            # encoding: UTF-8
         | 
| 2 2 | 
             
            require 'mkmf'
         | 
| 3 | 
            +
            require 'English'
         | 
| 3 4 |  | 
| 4 | 
            -
            def asplode | 
| 5 | 
            +
            def asplode(lib)
         | 
| 5 6 | 
             
              if RUBY_PLATFORM =~ /mingw|mswin/
         | 
| 6 7 | 
             
                abort "-----\n#{lib} is missing. Check your installation of MySQL or Connector/C, and try again.\n-----"
         | 
| 7 8 | 
             
              elsif RUBY_PLATFORM =~ /darwin/
         | 
| @@ -22,7 +23,7 @@ have_func('rb_intern3') | |
| 22 23 |  | 
| 23 24 | 
             
            # borrowed from mysqlplus
         | 
| 24 25 | 
             
            # http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
         | 
| 25 | 
            -
            dirs = ENV | 
| 26 | 
            +
            dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w(
         | 
| 26 27 | 
             
              /opt
         | 
| 27 28 | 
             
              /opt/local
         | 
| 28 29 | 
             
              /opt/local/mysql
         | 
| @@ -34,13 +35,14 @@ dirs = ENV['PATH'].split(File::PATH_SEPARATOR) + %w[ | |
| 34 35 | 
             
              /usr/local/mysql-*
         | 
| 35 36 | 
             
              /usr/local/lib/mysql5*
         | 
| 36 37 | 
             
              /usr/local/opt/mysql5*
         | 
| 37 | 
            -
             | 
| 38 | 
            +
            ).map { |dir| dir << '/bin' }
         | 
| 38 39 |  | 
| 39 40 | 
             
            GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}"
         | 
| 40 41 |  | 
| 41 42 | 
             
            # If the user has provided a --with-mysql-dir argument, we must respect it or fail.
         | 
| 42 43 | 
             
            inc, lib = dir_config('mysql')
         | 
| 43 44 | 
             
            if inc && lib
         | 
| 45 | 
            +
              # TODO: Remove when 2.0.0 is the minimum supported version
         | 
| 44 46 | 
             
              # Ruby versions not incorporating the mkmf fix at
         | 
| 45 47 | 
             
              # https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717
         | 
| 46 48 | 
             
              # do not properly search for lib directories, and must be corrected
         | 
| @@ -48,35 +50,33 @@ if inc && lib | |
| 48 50 | 
             
                @libdir_basename = 'lib'
         | 
| 49 51 | 
             
                inc, lib = dir_config('mysql')
         | 
| 50 52 | 
             
              end
         | 
| 51 | 
            -
              abort "-----\nCannot find include dir(s) #{inc}\n-----" unless inc && inc.split(File::PATH_SEPARATOR).any?{|dir| File.directory?(dir)}
         | 
| 52 | 
            -
              abort "-----\nCannot find library dir(s) #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any?{|dir| File.directory?(dir)}
         | 
| 53 | 
            -
              warn | 
| 53 | 
            +
              abort "-----\nCannot find include dir(s) #{inc}\n-----" unless inc && inc.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) }
         | 
| 54 | 
            +
              abort "-----\nCannot find library dir(s) #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) }
         | 
| 55 | 
            +
              warn "-----\nUsing --with-mysql-dir=#{File.dirname inc}\n-----"
         | 
| 54 56 | 
             
              rpath_dir = lib
         | 
| 55 | 
            -
            elsif mc = (with_config('mysql-config') || Dir[GLOB].first)
         | 
| 57 | 
            +
            elsif (mc = (with_config('mysql-config') || Dir[GLOB].first))
         | 
| 56 58 | 
             
              # If the user has provided a --with-mysql-config argument, we must respect it or fail.
         | 
| 57 59 | 
             
              # If the user gave --with-mysql-config with no argument means we should try to find it.
         | 
| 58 60 | 
             
              mc = Dir[GLOB].first if mc == true
         | 
| 59 | 
            -
              abort "-----\nCannot find mysql_config at #{mc}\n-----" unless mc && File. | 
| 61 | 
            +
              abort "-----\nCannot find mysql_config at #{mc}\n-----" unless mc && File.exist?(mc)
         | 
| 60 62 | 
             
              abort "-----\nCannot execute mysql_config at #{mc}\n-----" unless File.executable?(mc)
         | 
| 61 | 
            -
              warn | 
| 63 | 
            +
              warn "-----\nUsing mysql_config at #{mc}\n-----"
         | 
| 62 64 | 
             
              ver = `#{mc} --version`.chomp.to_f
         | 
| 63 65 | 
             
              includes = `#{mc} --include`.chomp
         | 
| 64 | 
            -
               | 
| 66 | 
            +
              abort unless $CHILD_STATUS.success?
         | 
| 65 67 | 
             
              libs = `#{mc} --libs_r`.chomp
         | 
| 66 68 | 
             
              # MySQL 5.5 and above already have re-entrant code in libmysqlclient (no _r).
         | 
| 67 | 
            -
              if ver >= 5.5 || libs.empty?
         | 
| 68 | 
            -
             | 
| 69 | 
            -
              end
         | 
| 70 | 
            -
              exit 1 if $? != 0
         | 
| 69 | 
            +
              libs = `#{mc} --libs`.chomp if ver >= 5.5 || libs.empty?
         | 
| 70 | 
            +
              abort unless $CHILD_STATUS.success?
         | 
| 71 71 | 
             
              $INCFLAGS += ' ' + includes
         | 
| 72 72 | 
             
              $libs = libs + " " + $libs
         | 
| 73 73 | 
             
              rpath_dir = libs
         | 
| 74 74 | 
             
            else
         | 
| 75 | 
            -
               | 
| 75 | 
            +
              _, usr_local_lib = dir_config('mysql', '/usr/local')
         | 
| 76 76 |  | 
| 77 | 
            -
              asplode("mysql client") unless find_library('mysqlclient', 'mysql_query',  | 
| 77 | 
            +
              asplode("mysql client") unless find_library('mysqlclient', 'mysql_query', usr_local_lib, "#{usr_local_lib}/mysql")
         | 
| 78 78 |  | 
| 79 | 
            -
              rpath_dir =  | 
| 79 | 
            +
              rpath_dir = usr_local_lib
         | 
| 80 80 | 
             
            end
         | 
| 81 81 |  | 
| 82 82 | 
             
            if have_header('mysql.h')
         | 
| @@ -87,27 +87,49 @@ else | |
| 87 87 | 
             
              asplode 'mysql.h'
         | 
| 88 88 | 
             
            end
         | 
| 89 89 |  | 
| 90 | 
            -
            %w | 
| 90 | 
            +
            %w(errmsg.h mysqld_error.h).each do |h|
         | 
| 91 91 | 
             
              header = [prefix, h].compact.join '/'
         | 
| 92 | 
            -
              asplode h unless have_header  | 
| 92 | 
            +
              asplode h unless have_header header
         | 
| 93 93 | 
             
            end
         | 
| 94 94 |  | 
| 95 95 | 
             
            # This is our wishlist. We use whichever flags work on the host.
         | 
| 96 | 
            -
            #  | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
              - | 
| 100 | 
            -
              - | 
| 101 | 
            -
              - | 
| 102 | 
            -
              -Wno- | 
| 103 | 
            -
              -Wno- | 
| 104 | 
            -
              -Wno- | 
| 105 | 
            -
             | 
| 96 | 
            +
            # -Wall and -Wextra are included by default.
         | 
| 97 | 
            +
            wishlist = [
         | 
| 98 | 
            +
              '-Weverything',
         | 
| 99 | 
            +
              '-Wno-bad-function-cast', # rb_thread_call_without_gvl returns void * that we cast to VALUE
         | 
| 100 | 
            +
              '-Wno-conditional-uninitialized', # false positive in client.c
         | 
| 101 | 
            +
              '-Wno-covered-switch-default', # result.c -- enum_field_types (when fully covered, e.g. mysql 5.5)
         | 
| 102 | 
            +
              '-Wno-declaration-after-statement', # GET_CLIENT followed by GET_STATEMENT in statement.c
         | 
| 103 | 
            +
              '-Wno-disabled-macro-expansion', # rubby :(
         | 
| 104 | 
            +
              '-Wno-documentation-unknown-command', # rubby :(
         | 
| 105 | 
            +
              '-Wno-missing-field-initializers', # gperf generates bad code
         | 
| 106 | 
            +
              '-Wno-missing-variable-declarations', # missing symbols due to ruby native ext initialization
         | 
| 107 | 
            +
              '-Wno-padded', # mysql :(
         | 
| 108 | 
            +
              '-Wno-sign-conversion', # gperf generates bad code
         | 
| 109 | 
            +
              '-Wno-static-in-inline', # gperf generates bad code
         | 
| 110 | 
            +
              '-Wno-switch-enum', # result.c -- enum_field_types (when not fully covered, e.g. mysql 5.6+)
         | 
| 111 | 
            +
              '-Wno-undef', # rubinius :(
         | 
| 112 | 
            +
              '-Wno-used-but-marked-unused', # rubby :(
         | 
| 113 | 
            +
            ]
         | 
| 114 | 
            +
             | 
| 115 | 
            +
            if ENV['CI']
         | 
| 116 | 
            +
              wishlist += [
         | 
| 117 | 
            +
                '-Werror',
         | 
| 118 | 
            +
                '-fsanitize=address',
         | 
| 119 | 
            +
                '-fsanitize=cfi',
         | 
| 120 | 
            +
                '-fsanitize=integer',
         | 
| 121 | 
            +
                '-fsanitize=memory',
         | 
| 122 | 
            +
                '-fsanitize=thread',
         | 
| 123 | 
            +
                '-fsanitize=undefined',
         | 
| 124 | 
            +
              ]
         | 
| 125 | 
            +
            end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
            usable_flags = wishlist.select do |flag|
         | 
| 106 128 | 
             
              try_link('int main() {return 0;}', flag)
         | 
| 107 | 
            -
            end.each do |flag|
         | 
| 108 | 
            -
              $CFLAGS << ' ' << flag
         | 
| 109 129 | 
             
            end
         | 
| 110 130 |  | 
| 131 | 
            +
            $CFLAGS << ' ' << usable_flags.join(' ')
         | 
| 132 | 
            +
             | 
| 111 133 | 
             
            if RUBY_PLATFORM =~ /mswin|mingw/
         | 
| 112 134 | 
             
              # Build libmysql.a interface link library
         | 
| 113 135 | 
             
              require 'rake'
         | 
| @@ -116,15 +138,15 @@ if RUBY_PLATFORM =~ /mswin|mingw/ | |
| 116 138 | 
             
              # Use rake to rebuild only if these files change
         | 
| 117 139 | 
             
              deffile = File.expand_path('../../../support/libmysql.def', __FILE__)
         | 
| 118 140 | 
             
              libfile = File.expand_path(File.join(rpath_dir, 'libmysql.lib'))
         | 
| 119 | 
            -
              file 'libmysql.a' => [deffile, libfile] do | 
| 141 | 
            +
              file 'libmysql.a' => [deffile, libfile] do
         | 
| 120 142 | 
             
                when_writing 'building libmysql.a' do
         | 
| 121 143 | 
             
                  # Ruby kindly shows us where dllwrap is, but that tool does more than we want.
         | 
| 122 144 | 
             
                  # Maybe in the future Ruby could provide RbConfig::CONFIG['DLLTOOL'] directly.
         | 
| 123 145 | 
             
                  dlltool = RbConfig::CONFIG['DLLWRAP'].gsub('dllwrap', 'dlltool')
         | 
| 124 146 | 
             
                  sh dlltool, '--kill-at',
         | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 147 | 
            +
                     '--dllname', 'libmysql.dll',
         | 
| 148 | 
            +
                     '--output-lib', 'libmysql.a',
         | 
| 149 | 
            +
                     '--input-def', deffile, libfile
         | 
| 128 150 | 
             
                end
         | 
| 129 151 | 
             
              end
         | 
| 130 152 |  | 
| @@ -143,7 +165,7 @@ if RUBY_PLATFORM =~ /mswin|mingw/ | |
| 143 165 |  | 
| 144 166 | 
             
              vendordll = File.join(vendordir, 'libmysql.dll')
         | 
| 145 167 | 
             
              dllfile = File.expand_path(File.join(rpath_dir, 'libmysql.dll'))
         | 
| 146 | 
            -
              file vendordll => [dllfile, vendordir] do | 
| 168 | 
            +
              file vendordll => [dllfile, vendordir] do
         | 
| 147 169 | 
             
                when_writing 'copying libmysql.dll' do
         | 
| 148 170 | 
             
                  cp dllfile, vendordll
         | 
| 149 171 | 
             
                end
         | 
| @@ -169,7 +191,7 @@ else | |
| 169 191 | 
             
                warn "-----\nSetting mysql rpath to #{explicit_rpath}\n-----"
         | 
| 170 192 | 
             
                $LDFLAGS << rpath_flags
         | 
| 171 193 | 
             
              else
         | 
| 172 | 
            -
                if libdir = rpath_dir[%r{(-L)?(/[^ ]+)}, 2]
         | 
| 194 | 
            +
                if (libdir = rpath_dir[%r{(-L)?(/[^ ]+)}, 2])
         | 
| 173 195 | 
             
                  rpath_flags = " -Wl,-rpath,#{libdir}"
         | 
| 174 196 | 
             
                  if RbConfig::CONFIG["RPATHFLAG"].to_s.empty? && try_link('int main() {return 0;}', rpath_flags)
         | 
| 175 197 | 
             
                    # Usually Ruby sets RPATHFLAG the right way for each system, but not on OS X.
         | 
    
        data/ext/mysql2/infile.c
    CHANGED
    
    | @@ -56,7 +56,7 @@ mysql2_local_infile_init(void **ptr, const char *filename, void *userdata) | |
| 56 56 | 
             
             * < 0   error
         | 
| 57 57 | 
             
             */
         | 
| 58 58 | 
             
            static int
         | 
| 59 | 
            -
            mysql2_local_infile_read(void *ptr, char *buf,  | 
| 59 | 
            +
            mysql2_local_infile_read(void *ptr, char *buf, unsigned int buf_len)
         | 
| 60 60 | 
             
            {
         | 
| 61 61 | 
             
              int count;
         | 
| 62 62 | 
             
              mysql2_local_infile_data *data = (mysql2_local_infile_data *)ptr;
         | 
| @@ -95,7 +95,7 @@ mysql2_local_infile_end(void *ptr) | |
| 95 95 | 
             
             * Error message number (see http://dev.mysql.com/doc/refman/5.0/en/error-messages-client.html)
         | 
| 96 96 | 
             
             */
         | 
| 97 97 | 
             
            static int
         | 
| 98 | 
            -
            mysql2_local_infile_error(void *ptr, char *error_msg,  | 
| 98 | 
            +
            mysql2_local_infile_error(void *ptr, char *error_msg, unsigned int error_msg_len)
         | 
| 99 99 | 
             
            {
         | 
| 100 100 | 
             
              mysql2_local_infile_data *data = (mysql2_local_infile_data *) ptr;
         | 
| 101 101 |  | 
    
        data/ext/mysql2/mysql2_ext.h
    CHANGED
    
    | @@ -1,18 +1,14 @@ | |
| 1 1 | 
             
            #ifndef MYSQL2_EXT
         | 
| 2 2 | 
             
            #define MYSQL2_EXT
         | 
| 3 3 |  | 
| 4 | 
            +
            void Init_mysql2(void);
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
            /* tell rbx not to use it's caching compat layer
         | 
| 5 7 | 
             
               by doing this we're making a promise to RBX that
         | 
| 6 8 | 
             
               we'll never modify the pointers we get back from RSTRING_PTR */
         | 
| 7 9 | 
             
            #define RSTRING_NOT_MODIFIED
         | 
| 8 10 | 
             
            #include <ruby.h>
         | 
| 9 11 |  | 
| 10 | 
            -
            #ifndef HAVE_UINT
         | 
| 11 | 
            -
            #define HAVE_UINT
         | 
| 12 | 
            -
            typedef unsigned short    ushort;
         | 
| 13 | 
            -
            typedef unsigned int    uint;
         | 
| 14 | 
            -
            #endif
         | 
| 15 | 
            -
             | 
| 16 12 | 
             
            #ifdef HAVE_MYSQL_H
         | 
| 17 13 | 
             
            #include <mysql.h>
         | 
| 18 14 | 
             
            #include <mysql_com.h>
         | 
| @@ -33,8 +29,10 @@ typedef unsigned int    uint; | |
| 33 29 | 
             
            #endif
         | 
| 34 30 |  | 
| 35 31 | 
             
            #if defined(__GNUC__) && (__GNUC__ >= 3)
         | 
| 32 | 
            +
            #define RB_MYSQL_NORETURN __attribute__ ((noreturn))
         | 
| 36 33 | 
             
            #define RB_MYSQL_UNUSED __attribute__ ((unused))
         | 
| 37 34 | 
             
            #else
         | 
| 35 | 
            +
            #define RB_MYSQL_NORETURN
         | 
| 38 36 | 
             
            #define RB_MYSQL_UNUSED
         | 
| 39 37 | 
             
            #endif
         | 
| 40 38 |  |