mysql2 0.4.0-x86-mingw32 → 0.4.1-x86-mingw32
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/1.8/mysql2.so +0 -0
 - data/lib/mysql2/1.9/mysql2.so +0 -0
 - data/lib/mysql2/2.0/mysql2.so +0 -0
 - data/lib/mysql2/2.1/mysql2.so +0 -0
 - data/lib/mysql2/2.2/mysql2.so +0 -0
 - 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
 
    
        data/lib/mysql2.rb
    CHANGED
    
    | 
         @@ -8,16 +8,16 @@ require 'rational' unless RUBY_VERSION >= '1.9.2' 
     | 
|
| 
       8 
8 
     | 
    
         
             
            # Or to bomb out with a clear error message instead of a linker crash
         
     | 
| 
       9 
9 
     | 
    
         
             
            if RUBY_PLATFORM =~ /mswin|mingw/
         
     | 
| 
       10 
10 
     | 
    
         
             
              dll_path = if ENV['RUBY_MYSQL2_LIBMYSQL_DLL']
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
                # If this environment variable is set, it overrides any other paths
         
     | 
| 
      
 12 
     | 
    
         
            +
                # The user is advised to use backslashes not forward slashes
         
     | 
| 
      
 13 
     | 
    
         
            +
                ENV['RUBY_MYSQL2_LIBMYSQL_DLL']
         
     | 
| 
      
 14 
     | 
    
         
            +
              elsif File.exist?(File.expand_path('../vendor/libmysql.dll', File.dirname(__FILE__)))
         
     | 
| 
      
 15 
     | 
    
         
            +
                # Use vendor/libmysql.dll if it exists, convert slashes for Win32 LoadLibrary
         
     | 
| 
      
 16 
     | 
    
         
            +
                File.expand_path('../vendor/libmysql.dll', File.dirname(__FILE__)).tr('/', '\\')
         
     | 
| 
      
 17 
     | 
    
         
            +
              else
         
     | 
| 
      
 18 
     | 
    
         
            +
                # This will use default / system library paths
         
     | 
| 
      
 19 
     | 
    
         
            +
                'libmysql.dll'
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
              require 'Win32API'
         
     | 
| 
       23 
23 
     | 
    
         
             
              LoadLibrary = Win32API.new('Kernel32', 'LoadLibrary', ['P'], 'I')
         
     | 
| 
         @@ -53,14 +53,32 @@ if defined?(ActiveRecord::VERSION::STRING) && ActiveRecord::VERSION::STRING < "3 
     | 
|
| 
       53 
53 
     | 
    
         
             
            end
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
            # For holding utility methods
         
     | 
| 
       56 
     | 
    
         
            -
            module Mysql2 
     | 
| 
      
 56 
     | 
    
         
            +
            module Mysql2
         
     | 
| 
      
 57 
     | 
    
         
            +
              module Util
         
     | 
| 
      
 58 
     | 
    
         
            +
                #
         
     | 
| 
      
 59 
     | 
    
         
            +
                # Rekey a string-keyed hash with equivalent symbols.
         
     | 
| 
      
 60 
     | 
    
         
            +
                #
         
     | 
| 
      
 61 
     | 
    
         
            +
                def self.key_hash_as_symbols(hash)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  return nil unless hash
         
     | 
| 
      
 63 
     | 
    
         
            +
                  Hash[hash.map { |k, v| [k.to_sym, v] }]
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
       57 
65 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
                 
     | 
| 
       63 
     | 
    
         
            -
                 
     | 
| 
      
 66 
     | 
    
         
            +
                #
         
     | 
| 
      
 67 
     | 
    
         
            +
                # In Mysql2::Client#query and Mysql2::Statement#execute,
         
     | 
| 
      
 68 
     | 
    
         
            +
                # Thread#handle_interrupt is used to prevent Timeout#timeout
         
     | 
| 
      
 69 
     | 
    
         
            +
                # from interrupting query execution.
         
     | 
| 
      
 70 
     | 
    
         
            +
                #
         
     | 
| 
      
 71 
     | 
    
         
            +
                # Timeout::ExitException was removed in Ruby 2.3.0, 2.2.3, and 2.1.8,
         
     | 
| 
      
 72 
     | 
    
         
            +
                # but is present in earlier 2.1.x and 2.2.x, so we provide a shim.
         
     | 
| 
      
 73 
     | 
    
         
            +
                #
         
     | 
| 
      
 74 
     | 
    
         
            +
                if Thread.respond_to?(:handle_interrupt)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  require 'timeout'
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # rubocop:disable Style/ConstantName
         
     | 
| 
      
 77 
     | 
    
         
            +
                  TimeoutError = if defined?(::Timeout::ExitException)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    ::Timeout::ExitException
         
     | 
| 
      
 79 
     | 
    
         
            +
                  else
         
     | 
| 
      
 80 
     | 
    
         
            +
                    ::Timeout::Error
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
       64 
83 
     | 
    
         
             
              end
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
84 
     | 
    
         
             
            end
         
     | 
    
        data/lib/mysql2/1.8/mysql2.so
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/lib/mysql2/1.9/mysql2.so
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/lib/mysql2/2.0/mysql2.so
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/lib/mysql2/2.1/mysql2.so
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/lib/mysql2/2.2/mysql2.so
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/lib/mysql2/client.rb
    CHANGED
    
    | 
         @@ -1,24 +1,27 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Mysql2
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Client
         
     | 
| 
       3 
3 
     | 
    
         
             
                attr_reader :query_options, :read_timeout
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def self.default_query_options
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @default_query_options ||= {
         
     | 
| 
      
 7 
     | 
    
         
            +
                    :as => :hash,                   # the type of object you want each row back as; also supports :array (an array of values)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    :async => false,                # don't wait for a result after sending the query, you'll have to monitor the socket yourself then eventually call Mysql2::Client#async_result
         
     | 
| 
      
 9 
     | 
    
         
            +
                    :cast_booleans => false,        # cast tinyint(1) fields as true/false in ruby
         
     | 
| 
      
 10 
     | 
    
         
            +
                    :symbolize_keys => false,       # return field names as symbols instead of strings
         
     | 
| 
      
 11 
     | 
    
         
            +
                    :database_timezone => :local,   # timezone Mysql2 will assume datetime objects are stored in
         
     | 
| 
      
 12 
     | 
    
         
            +
                    :application_timezone => nil,   # timezone Mysql2 will convert to before handing the object back to the caller
         
     | 
| 
      
 13 
     | 
    
         
            +
                    :cache_rows => true,            # tells Mysql2 to use it's internal row cache for results
         
     | 
| 
      
 14 
     | 
    
         
            +
                    :connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION,
         
     | 
| 
      
 15 
     | 
    
         
            +
                    :cast => true,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    :default_file => nil,
         
     | 
| 
      
 17 
     | 
    
         
            +
                    :default_group => nil,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  }
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
       17 
20 
     | 
    
         | 
| 
       18 
21 
     | 
    
         
             
                def initialize(opts = {})
         
     | 
| 
       19 
     | 
    
         
            -
                  opts = Mysql2::Util.key_hash_as_symbols( 
     | 
| 
      
 22 
     | 
    
         
            +
                  opts = Mysql2::Util.key_hash_as_symbols(opts)
         
     | 
| 
       20 
23 
     | 
    
         
             
                  @read_timeout = nil
         
     | 
| 
       21 
     | 
    
         
            -
                  @query_options =  
     | 
| 
      
 24 
     | 
    
         
            +
                  @query_options = self.class.default_query_options.dup
         
     | 
| 
       22 
25 
     | 
    
         
             
                  @query_options.merge! opts
         
     | 
| 
       23 
26 
     | 
    
         | 
| 
       24 
27 
     | 
    
         
             
                  initialize_ext
         
     | 
| 
         @@ -26,11 +29,12 @@ module Mysql2 
     | 
|
| 
       26 
29 
     | 
    
         
             
                  # Set default connect_timeout to avoid unlimited retries from signal interruption
         
     | 
| 
       27 
30 
     | 
    
         
             
                  opts[:connect_timeout] = 120 unless opts.key?(:connect_timeout)
         
     | 
| 
       28 
31 
     | 
    
         | 
| 
      
 32 
     | 
    
         
            +
                  # TODO: stricter validation rather than silent massaging
         
     | 
| 
       29 
33 
     | 
    
         
             
                  [:reconnect, :connect_timeout, :local_infile, :read_timeout, :write_timeout, :default_file, :default_group, :secure_auth, :init_command].each do |key|
         
     | 
| 
       30 
34 
     | 
    
         
             
                    next unless opts.key?(key)
         
     | 
| 
       31 
35 
     | 
    
         
             
                    case key
         
     | 
| 
       32 
36 
     | 
    
         
             
                    when :reconnect, :local_infile, :secure_auth
         
     | 
| 
       33 
     | 
    
         
            -
                      send(:"#{key}=", !!opts[key])
         
     | 
| 
      
 37 
     | 
    
         
            +
                      send(:"#{key}=", !!opts[key]) # rubocop:disable Style/DoubleNegation
         
     | 
| 
       34 
38 
     | 
    
         
             
                    when :connect_timeout, :read_timeout, :write_timeout
         
     | 
| 
       35 
39 
     | 
    
         
             
                      send(:"#{key}=", opts[key].to_i)
         
     | 
| 
       36 
40 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -48,9 +52,9 @@ module Mysql2 
     | 
|
| 
       48 
52 
     | 
    
         
             
                  flags = 0
         
     | 
| 
       49 
53 
     | 
    
         
             
                  flags |= @query_options[:connect_flags]
         
     | 
| 
       50 
54 
     | 
    
         
             
                  flags |= opts[:flags] if opts[:flags]
         
     | 
| 
       51 
     | 
    
         
            -
                  flags |= SSL_VERIFY_SERVER_CERT if opts[:sslverify]  
     | 
| 
      
 55 
     | 
    
         
            +
                  flags |= SSL_VERIFY_SERVER_CERT if opts[:sslverify] && ssl_options.any?
         
     | 
| 
       52 
56 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                  if [:user 
     | 
| 
      
 57 
     | 
    
         
            +
                  if [:user, :pass, :hostname, :dbname, :db, :sock].any? { |k| @query_options.key?(k) }
         
     | 
| 
       54 
58 
     | 
    
         
             
                    warn "============= WARNING FROM mysql2 ============="
         
     | 
| 
       55 
59 
     | 
    
         
             
                    warn "The options :user, :pass, :hostname, :dbname, :db, and :sock will be deprecated at some point in the future."
         
     | 
| 
       56 
60 
     | 
    
         
             
                    warn "Instead, please use :username, :password, :host, :port, :database, :socket, :flags for the options."
         
     | 
| 
         @@ -75,15 +79,9 @@ module Mysql2 
     | 
|
| 
       75 
79 
     | 
    
         
             
                  connect user, pass, host, port, database, socket, flags
         
     | 
| 
       76 
80 
     | 
    
         
             
                end
         
     | 
| 
       77 
81 
     | 
    
         | 
| 
       78 
     | 
    
         
            -
                def self.default_query_options
         
     | 
| 
       79 
     | 
    
         
            -
                  @@default_query_options
         
     | 
| 
       80 
     | 
    
         
            -
                end
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
82 
     | 
    
         
             
                if Thread.respond_to?(:handle_interrupt)
         
     | 
| 
       83 
     | 
    
         
            -
                  require 'timeout'
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
83 
     | 
    
         
             
                  def query(sql, options = {})
         
     | 
| 
       86 
     | 
    
         
            -
                    Thread.handle_interrupt(:: 
     | 
| 
      
 84 
     | 
    
         
            +
                    Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
         
     | 
| 
       87 
85 
     | 
    
         
             
                      _query(sql, @query_options.merge(options))
         
     | 
| 
       88 
86 
     | 
    
         
             
                    end
         
     | 
| 
       89 
87 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -105,9 +103,12 @@ module Mysql2 
     | 
|
| 
       105 
103 
     | 
    
         
             
                  self.class.info
         
     | 
| 
       106 
104 
     | 
    
         
             
                end
         
     | 
| 
       107 
105 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
                 
     | 
| 
       109 
     | 
    
         
            -
                   
     | 
| 
      
 106 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 107 
     | 
    
         
            +
                  private
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  def local_offset
         
     | 
| 
       110 
110 
     | 
    
         
             
                    ::Time.local(2010).utc_offset.to_r / 86400
         
     | 
| 
       111 
111 
     | 
    
         
             
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
       112 
113 
     | 
    
         
             
              end
         
     | 
| 
       113 
114 
     | 
    
         
             
            end
         
     | 
    
        data/lib/mysql2/console.rb
    CHANGED
    
    
    
        data/lib/mysql2/em.rb
    CHANGED
    
    | 
         @@ -17,7 +17,7 @@ module Mysql2 
     | 
|
| 
       17 
17 
     | 
    
         
             
                      detach
         
     | 
| 
       18 
18 
     | 
    
         
             
                      begin
         
     | 
| 
       19 
19 
     | 
    
         
             
                        result = @client.async_result
         
     | 
| 
       20 
     | 
    
         
            -
                      rescue  
     | 
| 
      
 20 
     | 
    
         
            +
                      rescue => e
         
     | 
| 
       21 
21 
     | 
    
         
             
                        @deferable.fail(e)
         
     | 
| 
       22 
22 
     | 
    
         
             
                      else
         
     | 
| 
       23 
23 
     | 
    
         
             
                        @deferable.succeed(result)
         
     | 
| 
         @@ -34,17 +34,16 @@ module Mysql2 
     | 
|
| 
       34 
34 
     | 
    
         
             
                  end
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                  def close(*args)
         
     | 
| 
       37 
     | 
    
         
            -
                    if @watch
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @watch.detach if @watch && @watch.watching?
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
       40 
39 
     | 
    
         
             
                    super(*args)
         
     | 
| 
       41 
40 
     | 
    
         
             
                  end
         
     | 
| 
       42 
41 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                  def query(sql, opts={})
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def query(sql, opts = {})
         
     | 
| 
       44 
43 
     | 
    
         
             
                    if ::EM.reactor_running?
         
     | 
| 
       45 
44 
     | 
    
         
             
                      super(sql, opts.merge(:async => true))
         
     | 
| 
       46 
45 
     | 
    
         
             
                      deferable = ::EM::DefaultDeferrable.new
         
     | 
| 
       47 
     | 
    
         
            -
                      @watch = ::EM.watch( 
     | 
| 
      
 46 
     | 
    
         
            +
                      @watch = ::EM.watch(socket, Watcher, self, deferable)
         
     | 
| 
       48 
47 
     | 
    
         
             
                      @watch.notify_readable = true
         
     | 
| 
       49 
48 
     | 
    
         
             
                      deferable
         
     | 
| 
       50 
49 
     | 
    
         
             
                    else
         
     | 
    
        data/lib/mysql2/error.rb
    CHANGED
    
    | 
         @@ -8,22 +8,25 @@ module Mysql2 
     | 
|
| 
       8 
8 
     | 
    
         
             
                  :replace => '?'.freeze,
         
     | 
| 
       9 
9 
     | 
    
         
             
                }.freeze
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
       12 
     | 
    
         
            -
                attr_reader   :sql_state
         
     | 
| 
       13 
     | 
    
         
            -
                attr_writer   :server_version
         
     | 
| 
      
 11 
     | 
    
         
            +
                attr_reader :error_number, :sql_state
         
     | 
| 
       14 
12 
     | 
    
         | 
| 
       15 
13 
     | 
    
         
             
                # Mysql gem compatibility
         
     | 
| 
       16 
14 
     | 
    
         
             
                alias_method :errno, :error_number
         
     | 
| 
       17 
15 
     | 
    
         
             
                alias_method :error, :message
         
     | 
| 
       18 
16 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                def initialize(msg 
     | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
      
 17 
     | 
    
         
            +
                def initialize(msg)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @server_version ||= nil
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
                  super(clean_message(msg))
         
     | 
| 
       23 
21 
     | 
    
         
             
                end
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
                def sql_state 
     | 
| 
       26 
     | 
    
         
            -
                   
     | 
| 
      
 23 
     | 
    
         
            +
                def self.new_with_args(msg, server_version, error_number, sql_state)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  err = allocate
         
     | 
| 
      
 25 
     | 
    
         
            +
                  err.instance_variable_set('@server_version', server_version)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  err.instance_variable_set('@error_number', error_number)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  err.instance_variable_set('@sql_state', sql_state.respond_to?(:encode) ? sql_state.encode(ENCODE_OPTS) : sql_state)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  err.send(:initialize, msg)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  err
         
     | 
| 
       27 
30 
     | 
    
         
             
                end
         
     | 
| 
       28 
31 
     | 
    
         | 
| 
       29 
32 
     | 
    
         
             
                private
         
     | 
    
        data/lib/mysql2/field.rb
    CHANGED
    
    
    
        data/lib/mysql2/statement.rb
    CHANGED
    
    | 
         @@ -1,5 +1,17 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Mysql2
         
     | 
| 
       2 
2 
     | 
    
         
             
              class Statement
         
     | 
| 
       3 
3 
     | 
    
         
             
                include Enumerable
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                if Thread.respond_to?(:handle_interrupt)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def execute(*args)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      _execute(*args)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                else
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def execute(*args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    _execute(*args)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
       4 
16 
     | 
    
         
             
              end
         
     | 
| 
       5 
17 
     | 
    
         
             
            end
         
     | 
    
        data/lib/mysql2/version.rb
    CHANGED
    
    
    
        data/spec/em/em_spec.rb
    CHANGED
    
    | 
         @@ -53,11 +53,11 @@ begin 
     | 
|
| 
       53 
53 
     | 
    
         
             
                    EM.run do
         
     | 
| 
       54 
54 
     | 
    
         
             
                      client = Mysql2::EM::Client.new DatabaseCredentials['root']
         
     | 
| 
       55 
55 
     | 
    
         
             
                      defer = client.query "SELECT sleep(0.1) as first_query"
         
     | 
| 
       56 
     | 
    
         
            -
                      defer.callback do 
     | 
| 
      
 56 
     | 
    
         
            +
                      defer.callback do
         
     | 
| 
       57 
57 
     | 
    
         
             
                        client.close
         
     | 
| 
       58 
     | 
    
         
            -
                         
     | 
| 
      
 58 
     | 
    
         
            +
                        fail 'some error'
         
     | 
| 
       59 
59 
     | 
    
         
             
                      end
         
     | 
| 
       60 
     | 
    
         
            -
                      defer.errback do 
     | 
| 
      
 60 
     | 
    
         
            +
                      defer.errback do
         
     | 
| 
       61 
61 
     | 
    
         
             
                        # This _shouldn't_ be run, but it needed to prevent the specs from
         
     | 
| 
       62 
62 
     | 
    
         
             
                        # freezing if this test fails.
         
     | 
| 
       63 
63 
     | 
    
         
             
                        EM.stop_event_loop
         
     | 
| 
         @@ -75,7 +75,7 @@ begin 
     | 
|
| 
       75 
75 
     | 
    
         
             
                    errors = []
         
     | 
| 
       76 
76 
     | 
    
         
             
                    EM.run do
         
     | 
| 
       77 
77 
     | 
    
         
             
                      defer = client.query "SELECT sleep(0.1) as first_query"
         
     | 
| 
       78 
     | 
    
         
            -
                      defer.callback do 
     | 
| 
      
 78 
     | 
    
         
            +
                      defer.callback do
         
     | 
| 
       79 
79 
     | 
    
         
             
                        # This _shouldn't_ be run, but it is needed to prevent the specs from
         
     | 
| 
       80 
80 
     | 
    
         
             
                        # freezing if this test fails.
         
     | 
| 
       81 
81 
     | 
    
         
             
                        EM.stop_event_loop
         
     | 
| 
         @@ -93,13 +93,13 @@ begin 
     | 
|
| 
       93 
93 
     | 
    
         
             
                    EM.run do
         
     | 
| 
       94 
94 
     | 
    
         
             
                      defer = client.query "SELECT sleep(0.025) as first_query"
         
     | 
| 
       95 
95 
     | 
    
         
             
                      EM.add_timer(0.1) do
         
     | 
| 
       96 
     | 
    
         
            -
                        defer.callback do 
     | 
| 
      
 96 
     | 
    
         
            +
                        defer.callback do
         
     | 
| 
       97 
97 
     | 
    
         
             
                          callbacks_run << :callback
         
     | 
| 
       98 
98 
     | 
    
         
             
                          # This _shouldn't_ be run, but it is needed to prevent the specs from
         
     | 
| 
       99 
99 
     | 
    
         
             
                          # freezing if this test fails.
         
     | 
| 
       100 
100 
     | 
    
         
             
                          EM.stop_event_loop
         
     | 
| 
       101 
101 
     | 
    
         
             
                        end
         
     | 
| 
       102 
     | 
    
         
            -
                        defer.errback do 
     | 
| 
      
 102 
     | 
    
         
            +
                        defer.errback do
         
     | 
| 
       103 
103 
     | 
    
         
             
                          callbacks_run << :errback
         
     | 
| 
       104 
104 
     | 
    
         
             
                          EM.stop_event_loop
         
     | 
| 
       105 
105 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -114,10 +114,10 @@ begin 
     | 
|
| 
       114 
114 
     | 
    
         
             
                  EM.run do
         
     | 
| 
       115 
115 
     | 
    
         
             
                    client = Mysql2::EM::Client.new DatabaseCredentials['root']
         
     | 
| 
       116 
116 
     | 
    
         
             
                    defer = client.query("select sleep(0.025)")
         
     | 
| 
       117 
     | 
    
         
            -
                    defer.callback do 
     | 
| 
      
 117 
     | 
    
         
            +
                    defer.callback do
         
     | 
| 
       118 
118 
     | 
    
         
             
                      callbacks_run << :callback
         
     | 
| 
       119 
119 
     | 
    
         
             
                    end
         
     | 
| 
       120 
     | 
    
         
            -
                    defer.errback do 
     | 
| 
      
 120 
     | 
    
         
            +
                    defer.errback do
         
     | 
| 
       121 
121 
     | 
    
         
             
                      callbacks_run << :errback
         
     | 
| 
       122 
122 
     | 
    
         
             
                    end
         
     | 
| 
       123 
123 
     | 
    
         
             
                    EM.add_timer(0.1) do
         
     | 
    
        data/spec/mysql2/client_spec.rb
    CHANGED
    
    | 
         @@ -46,7 +46,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       46 
46 
     | 
    
         
             
              it "should accept connect flags and pass them to #connect" do
         
     | 
| 
       47 
47 
     | 
    
         
             
                klient = Class.new(Mysql2::Client) do
         
     | 
| 
       48 
48 
     | 
    
         
             
                  attr_reader :connect_args
         
     | 
| 
       49 
     | 
    
         
            -
                  def connect 
     | 
| 
      
 49 
     | 
    
         
            +
                  def connect(*args)
         
     | 
| 
       50 
50 
     | 
    
         
             
                    @connect_args ||= []
         
     | 
| 
       51 
51 
     | 
    
         
             
                    @connect_args << args
         
     | 
| 
       52 
52 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -58,7 +58,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       58 
58 
     | 
    
         
             
              it "should default flags to (REMEMBER_OPTIONS, LONG_PASSWORD, LONG_FLAG, TRANSACTIONS, PROTOCOL_41, SECURE_CONNECTION)" do
         
     | 
| 
       59 
59 
     | 
    
         
             
                klient = Class.new(Mysql2::Client) do
         
     | 
| 
       60 
60 
     | 
    
         
             
                  attr_reader :connect_args
         
     | 
| 
       61 
     | 
    
         
            -
                  def connect 
     | 
| 
      
 61 
     | 
    
         
            +
                  def connect(*args)
         
     | 
| 
       62 
62 
     | 
    
         
             
                    @connect_args ||= []
         
     | 
| 
       63 
63 
     | 
    
         
             
                    @connect_args << args
         
     | 
| 
       64 
64 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -117,32 +117,37 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       117 
117 
     | 
    
         | 
| 
       118 
118 
     | 
    
         
             
              it "should be able to connect via SSL options" do
         
     | 
| 
       119 
119 
     | 
    
         
             
                ssl = @client.query "SHOW VARIABLES LIKE 'have_ssl'"
         
     | 
| 
       120 
     | 
    
         
            -
                ssl_uncompiled = ssl.any? {|x| x['Value'] == 'OFF'}
         
     | 
| 
      
 120 
     | 
    
         
            +
                ssl_uncompiled = ssl.any? { |x| x['Value'] == 'OFF' }
         
     | 
| 
       121 
121 
     | 
    
         
             
                pending("DON'T WORRY, THIS TEST PASSES - but SSL is not compiled into your MySQL daemon.") if ssl_uncompiled
         
     | 
| 
       122 
     | 
    
         
            -
                ssl_disabled = ssl.any? {|x| x['Value'] == 'DISABLED'}
         
     | 
| 
      
 122 
     | 
    
         
            +
                ssl_disabled = ssl.any? { |x| x['Value'] == 'DISABLED' }
         
     | 
| 
       123 
123 
     | 
    
         
             
                pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") if ssl_disabled
         
     | 
| 
       124 
124 
     | 
    
         | 
| 
       125 
125 
     | 
    
         
             
                # You may need to adjust the lines below to match your SSL certificate paths
         
     | 
| 
       126 
126 
     | 
    
         
             
                ssl_client = nil
         
     | 
| 
       127 
127 
     | 
    
         
             
                expect {
         
     | 
| 
      
 128 
     | 
    
         
            +
                  # rubocop:disable Style/TrailingComma
         
     | 
| 
       128 
129 
     | 
    
         
             
                  ssl_client = Mysql2::Client.new(
         
     | 
| 
       129 
     | 
    
         
            -
                     
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
      
 130 
     | 
    
         
            +
                    DatabaseCredentials['root'].merge(
         
     | 
| 
      
 131 
     | 
    
         
            +
                      'host'     => 'mysql2gem.example.com', # must match the certificates
         
     | 
| 
      
 132 
     | 
    
         
            +
                      :sslkey    => '/etc/mysql/client-key.pem',
         
     | 
| 
      
 133 
     | 
    
         
            +
                      :sslcert   => '/etc/mysql/client-cert.pem',
         
     | 
| 
      
 134 
     | 
    
         
            +
                      :sslca     => '/etc/mysql/ca-cert.pem',
         
     | 
| 
      
 135 
     | 
    
         
            +
                      :sslcipher => 'DHE-RSA-AES256-SHA',
         
     | 
| 
      
 136 
     | 
    
         
            +
                      :sslverify => true
         
     | 
| 
      
 137 
     | 
    
         
            +
                    )
         
     | 
| 
       134 
138 
     | 
    
         
             
                  )
         
     | 
| 
      
 139 
     | 
    
         
            +
                  # rubocop:enable Style/TrailingComma
         
     | 
| 
       135 
140 
     | 
    
         
             
                }.not_to raise_error
         
     | 
| 
       136 
141 
     | 
    
         | 
| 
       137 
142 
     | 
    
         
             
                results = ssl_client.query("SHOW STATUS WHERE Variable_name = \"Ssl_version\" OR Variable_name = \"Ssl_cipher\"").to_a
         
     | 
| 
       138 
143 
     | 
    
         
             
                expect(results[0]['Variable_name']).to eql('Ssl_cipher')
         
     | 
| 
       139 
144 
     | 
    
         
             
                expect(results[0]['Value']).not_to be_nil
         
     | 
| 
       140 
     | 
    
         
            -
                expect(results[0]['Value']).to  
     | 
| 
      
 145 
     | 
    
         
            +
                expect(results[0]['Value']).to be_an_instance_of(String)
         
     | 
| 
       141 
146 
     | 
    
         
             
                expect(results[0]['Value']).not_to be_empty
         
     | 
| 
       142 
147 
     | 
    
         | 
| 
       143 
148 
     | 
    
         
             
                expect(results[1]['Variable_name']).to eql('Ssl_version')
         
     | 
| 
       144 
149 
     | 
    
         
             
                expect(results[1]['Value']).not_to be_nil
         
     | 
| 
       145 
     | 
    
         
            -
                expect(results[1]['Value']).to  
     | 
| 
      
 150 
     | 
    
         
            +
                expect(results[1]['Value']).to be_an_instance_of(String)
         
     | 
| 
       146 
151 
     | 
    
         
             
                expect(results[1]['Value']).not_to be_empty
         
     | 
| 
       147 
152 
     | 
    
         | 
| 
       148 
153 
     | 
    
         
             
                ssl_client.close
         
     | 
| 
         @@ -157,6 +162,14 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       157 
162 
     | 
    
         
             
                sleep(0.5)
         
     | 
| 
       158 
163 
     | 
    
         
             
              end
         
     | 
| 
       159 
164 
     | 
    
         | 
| 
      
 165 
     | 
    
         
            +
              it "should terminate connections when calling close" do
         
     | 
| 
      
 166 
     | 
    
         
            +
                expect {
         
     | 
| 
      
 167 
     | 
    
         
            +
                  Mysql2::Client.new(DatabaseCredentials['root']).close
         
     | 
| 
      
 168 
     | 
    
         
            +
                }.to_not change {
         
     | 
| 
      
 169 
     | 
    
         
            +
                  @client.query("SHOW STATUS LIKE 'Aborted_clients'").first['Value'].to_i
         
     | 
| 
      
 170 
     | 
    
         
            +
                }
         
     | 
| 
      
 171 
     | 
    
         
            +
              end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
       160 
173 
     | 
    
         
             
              it "should not leave dangling connections after garbage collection" do
         
     | 
| 
       161 
174 
     | 
    
         
             
                run_gc
         
     | 
| 
       162 
175 
     | 
    
         | 
| 
         @@ -182,7 +195,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       182 
195 
     | 
    
         | 
| 
       183 
196 
     | 
    
         
             
                # this empty `fork` call fixes this tests on RBX; without it, the next
         
     | 
| 
       184 
197 
     | 
    
         
             
                # `fork` call hangs forever. WTF?
         
     | 
| 
       185 
     | 
    
         
            -
                fork { 
     | 
| 
      
 198 
     | 
    
         
            +
                fork {}
         
     | 
| 
       186 
199 
     | 
    
         | 
| 
       187 
200 
     | 
    
         
             
                fork do
         
     | 
| 
       188 
201 
     | 
    
         
             
                  client.query('SELECT 1')
         
     | 
| 
         @@ -264,7 +277,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       264 
277 
     | 
    
         
             
                    # # Note that mysql_info() returns a non-NULL value for INSERT ... VALUES only for the multiple-row form of the statement (that is, only if multiple value lists are specified).
         
     | 
| 
       265 
278 
     | 
    
         
             
                    @client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
         
     | 
| 
       266 
279 
     | 
    
         | 
| 
       267 
     | 
    
         
            -
                    expect(@client.query_info).to 
     | 
| 
      
 280 
     | 
    
         
            +
                    expect(@client.query_info).to eql(:records => 2, :duplicates => 0, :warnings => 0)
         
     | 
| 
       268 
281 
     | 
    
         
             
                    expect(@client.query_info_string).to eq('Records: 2  Duplicates: 0  Warnings: 0')
         
     | 
| 
       269 
282 
     | 
    
         | 
| 
       270 
283 
     | 
    
         
             
                    @client.query "DROP TABLE infoTest"
         
     | 
| 
         @@ -276,7 +289,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       276 
289 
     | 
    
         
             
                before(:all) do
         
     | 
| 
       277 
290 
     | 
    
         
             
                  @client_i = Mysql2::Client.new DatabaseCredentials['root'].merge(:local_infile => true)
         
     | 
| 
       278 
291 
     | 
    
         
             
                  local = @client_i.query "SHOW VARIABLES LIKE 'local_infile'"
         
     | 
| 
       279 
     | 
    
         
            -
                  local_enabled = local.any? {|x| x['Value'] == 'ON'}
         
     | 
| 
      
 292 
     | 
    
         
            +
                  local_enabled = local.any? { |x| x['Value'] == 'ON' }
         
     | 
| 
       280 
293 
     | 
    
         
             
                  pending("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled
         
     | 
| 
       281 
294 
     | 
    
         | 
| 
       282 
295 
     | 
    
         
             
                  @client_i.query %[
         
     | 
| 
         @@ -308,10 +321,10 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       308 
321 
     | 
    
         
             
                it "should LOAD DATA LOCAL INFILE" do
         
     | 
| 
       309 
322 
     | 
    
         
             
                  @client_i.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
         
     | 
| 
       310 
323 
     | 
    
         
             
                  info = @client_i.query_info
         
     | 
| 
       311 
     | 
    
         
            -
                  expect(info).to eql( 
     | 
| 
      
 324 
     | 
    
         
            +
                  expect(info).to eql(:records => 1, :deleted => 0, :skipped => 0, :warnings => 0)
         
     | 
| 
       312 
325 
     | 
    
         | 
| 
       313 
326 
     | 
    
         
             
                  result = @client_i.query "SELECT * FROM infileTest"
         
     | 
| 
       314 
     | 
    
         
            -
                  expect(result.first).to eql( 
     | 
| 
      
 327 
     | 
    
         
            +
                  expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
         
     | 
| 
       315 
328 
     | 
    
         
             
                end
         
     | 
| 
       316 
329 
     | 
    
         
             
              end
         
     | 
| 
       317 
330 
     | 
    
         | 
| 
         @@ -379,16 +392,16 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       379 
392 
     | 
    
         
             
                end
         
     | 
| 
       380 
393 
     | 
    
         | 
| 
       381 
394 
     | 
    
         
             
                it "should return results as a hash by default" do
         
     | 
| 
       382 
     | 
    
         
            -
                  expect(@client.query("SELECT 1").first 
     | 
| 
      
 395 
     | 
    
         
            +
                  expect(@client.query("SELECT 1").first).to be_an_instance_of(Hash)
         
     | 
| 
       383 
396 
     | 
    
         
             
                end
         
     | 
| 
       384 
397 
     | 
    
         | 
| 
       385 
398 
     | 
    
         
             
                it "should be able to return results as an array" do
         
     | 
| 
       386 
     | 
    
         
            -
                  expect(@client.query("SELECT 1", :as => :array).first 
     | 
| 
      
 399 
     | 
    
         
            +
                  expect(@client.query("SELECT 1", :as => :array).first).to be_an_instance_of(Array)
         
     | 
| 
       387 
400 
     | 
    
         
             
                  @client.query("SELECT 1").each(:as => :array)
         
     | 
| 
       388 
401 
     | 
    
         
             
                end
         
     | 
| 
       389 
402 
     | 
    
         | 
| 
       390 
403 
     | 
    
         
             
                it "should be able to return results with symbolized keys" do
         
     | 
| 
       391 
     | 
    
         
            -
                  expect(@client.query("SELECT 1", :symbolize_keys => true).first.keys[0] 
     | 
| 
      
 404 
     | 
    
         
            +
                  expect(@client.query("SELECT 1", :symbolize_keys => true).first.keys[0]).to be_an_instance_of(Symbol)
         
     | 
| 
       392 
405 
     | 
    
         
             
                end
         
     | 
| 
       393 
406 
     | 
    
         | 
| 
       394 
407 
     | 
    
         
             
                it "should require an open connection" do
         
     | 
| 
         @@ -451,7 +464,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       451 
464 
     | 
    
         
             
                  end
         
     | 
| 
       452 
465 
     | 
    
         | 
| 
       453 
466 
     | 
    
         
             
                  it "#socket should return a Fixnum (file descriptor from C)" do
         
     | 
| 
       454 
     | 
    
         
            -
                    expect(@client.socket 
     | 
| 
      
 467 
     | 
    
         
            +
                    expect(@client.socket).to be_an_instance_of(Fixnum)
         
     | 
| 
       455 
468 
     | 
    
         
             
                    expect(@client.socket).not_to eql(0)
         
     | 
| 
       456 
469 
     | 
    
         
             
                  end
         
     | 
| 
       457 
470 
     | 
    
         | 
| 
         @@ -462,7 +475,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       462 
475 
     | 
    
         
             
                    }.to raise_error(Mysql2::Error)
         
     | 
| 
       463 
476 
     | 
    
         
             
                  end
         
     | 
| 
       464 
477 
     | 
    
         | 
| 
       465 
     | 
    
         
            -
                  it 'should be impervious to connection-corrupting timeouts ' do
         
     | 
| 
      
 478 
     | 
    
         
            +
                  it 'should be impervious to connection-corrupting timeouts in #query' do
         
     | 
| 
       466 
479 
     | 
    
         
             
                    pending('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
         
     | 
| 
       467 
480 
     | 
    
         
             
                    # attempt to break the connection
         
     | 
| 
       468 
481 
     | 
    
         
             
                    expect { Timeout.timeout(0.1) { @client.query('SELECT SLEEP(0.2)') } }.to raise_error(Timeout::Error)
         
     | 
| 
         @@ -471,6 +484,20 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       471 
484 
     | 
    
         
             
                    expect { @client.query('SELECT 1') }.to_not raise_error
         
     | 
| 
       472 
485 
     | 
    
         
             
                  end
         
     | 
| 
       473 
486 
     | 
    
         | 
| 
      
 487 
     | 
    
         
            +
                  it 'should be impervious to connection-corrupting timeouts in #execute' do
         
     | 
| 
      
 488 
     | 
    
         
            +
                    # the statement handle gets corrupted and will segfault the tests if interrupted,
         
     | 
| 
      
 489 
     | 
    
         
            +
                    # so we can't even use pending on this test, really have to skip it on older Rubies.
         
     | 
| 
      
 490 
     | 
    
         
            +
                    skip('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
         
     | 
| 
      
 491 
     | 
    
         
            +
             
     | 
| 
      
 492 
     | 
    
         
            +
                    # attempt to break the connection
         
     | 
| 
      
 493 
     | 
    
         
            +
                    stmt = @client.prepare('SELECT SLEEP(?)')
         
     | 
| 
      
 494 
     | 
    
         
            +
                    expect { Timeout.timeout(0.1) { stmt.execute(0.2) } }.to raise_error(Timeout::Error)
         
     | 
| 
      
 495 
     | 
    
         
            +
                    stmt.close
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
      
 497 
     | 
    
         
            +
                    # expect the connection to not be broken
         
     | 
| 
      
 498 
     | 
    
         
            +
                    expect { @client.query('SELECT 1') }.to_not raise_error
         
     | 
| 
      
 499 
     | 
    
         
            +
                  end
         
     | 
| 
      
 500 
     | 
    
         
            +
             
     | 
| 
       474 
501 
     | 
    
         
             
                  context 'when a non-standard exception class is raised' do
         
     | 
| 
       475 
502 
     | 
    
         
             
                    it "should close the connection when an exception is raised" do
         
     | 
| 
       476 
503 
     | 
    
         
             
                      expect { Timeout.timeout(0.1, ArgumentError) { @client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
         
     | 
| 
         @@ -542,7 +569,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       542 
569 
     | 
    
         
             
                    expect(loops >= 1).to be true
         
     | 
| 
       543 
570 
     | 
    
         | 
| 
       544 
571 
     | 
    
         
             
                    result = @client.async_result
         
     | 
| 
       545 
     | 
    
         
            -
                    expect(result 
     | 
| 
      
 572 
     | 
    
         
            +
                    expect(result).to be_an_instance_of(Mysql2::Result)
         
     | 
| 
       546 
573 
     | 
    
         
             
                  end
         
     | 
| 
       547 
574 
     | 
    
         
             
                end
         
     | 
| 
       548 
575 
     | 
    
         | 
| 
         @@ -561,21 +588,19 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       561 
588 
     | 
    
         
             
                  end
         
     | 
| 
       562 
589 
     | 
    
         | 
| 
       563 
590 
     | 
    
         
             
                  it "returns multiple result sets" do
         
     | 
| 
       564 
     | 
    
         
            -
                    expect(@multi_client.query("SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'").first).to eql( 
     | 
| 
      
 591 
     | 
    
         
            +
                    expect(@multi_client.query("SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'").first).to eql('set_1' => 1)
         
     | 
| 
       565 
592 
     | 
    
         | 
| 
       566 
593 
     | 
    
         
             
                    expect(@multi_client.next_result).to be true
         
     | 
| 
       567 
     | 
    
         
            -
                    expect(@multi_client.store_result.first).to eql( 
     | 
| 
      
 594 
     | 
    
         
            +
                    expect(@multi_client.store_result.first).to eql('set_2' => 2)
         
     | 
| 
       568 
595 
     | 
    
         | 
| 
       569 
596 
     | 
    
         
             
                    expect(@multi_client.next_result).to be false
         
     | 
| 
       570 
597 
     | 
    
         
             
                  end
         
     | 
| 
       571 
598 
     | 
    
         | 
| 
       572 
599 
     | 
    
         
             
                  it "does not interfere with other statements" do
         
     | 
| 
       573 
600 
     | 
    
         
             
                    @multi_client.query("SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'")
         
     | 
| 
       574 
     | 
    
         
            -
                    while 
     | 
| 
       575 
     | 
    
         
            -
                      @multi_client.store_result
         
     | 
| 
       576 
     | 
    
         
            -
                    end
         
     | 
| 
      
 601 
     | 
    
         
            +
                    @multi_client.store_result while @multi_client.next_result
         
     | 
| 
       577 
602 
     | 
    
         | 
| 
       578 
     | 
    
         
            -
                    expect(@multi_client.query("SELECT 3 AS 'next'").first).to eq( 
     | 
| 
      
 603 
     | 
    
         
            +
                    expect(@multi_client.query("SELECT 3 AS 'next'").first).to eq('next' => 3)
         
     | 
| 
       579 
604 
     | 
    
         
             
                  end
         
     | 
| 
       580 
605 
     | 
    
         | 
| 
       581 
606 
     | 
    
         
             
                  it "will raise on query if there are outstanding results to read" do
         
     | 
| 
         @@ -606,11 +631,11 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       606 
631 
     | 
    
         
             
                  it "#more_results? should work with stored procedures" do
         
     | 
| 
       607 
632 
     | 
    
         
             
                    @multi_client.query("DROP PROCEDURE IF EXISTS test_proc")
         
     | 
| 
       608 
633 
     | 
    
         
             
                    @multi_client.query("CREATE PROCEDURE test_proc() BEGIN SELECT 1 AS 'set_1'; SELECT 2 AS 'set_2'; END")
         
     | 
| 
       609 
     | 
    
         
            -
                    expect(@multi_client.query("CALL test_proc()").first).to eql( 
     | 
| 
      
 634 
     | 
    
         
            +
                    expect(@multi_client.query("CALL test_proc()").first).to eql('set_1' => 1)
         
     | 
| 
       610 
635 
     | 
    
         
             
                    expect(@multi_client.more_results?).to be true
         
     | 
| 
       611 
636 
     | 
    
         | 
| 
       612 
637 
     | 
    
         
             
                    @multi_client.next_result
         
     | 
| 
       613 
     | 
    
         
            -
                    expect(@multi_client.store_result.first).to eql( 
     | 
| 
      
 638 
     | 
    
         
            +
                    expect(@multi_client.store_result.first).to eql('set_2' => 2)
         
     | 
| 
       614 
639 
     | 
    
         | 
| 
       615 
640 
     | 
    
         
             
                    @multi_client.next_result
         
     | 
| 
       616 
641 
     | 
    
         
             
                    expect(@multi_client.store_result).to be_nil # this is the result from CALL itself
         
     | 
| 
         @@ -724,11 +749,11 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       724 
749 
     | 
    
         | 
| 
       725 
750 
     | 
    
         
             
              it "#info should return a hash containing the client version ID and String" do
         
     | 
| 
       726 
751 
     | 
    
         
             
                info = @client.info
         
     | 
| 
       727 
     | 
    
         
            -
                expect(info 
     | 
| 
      
 752 
     | 
    
         
            +
                expect(info).to be_an_instance_of(Hash)
         
     | 
| 
       728 
753 
     | 
    
         
             
                expect(info).to have_key(:id)
         
     | 
| 
       729 
     | 
    
         
            -
                expect(info[:id] 
     | 
| 
      
 754 
     | 
    
         
            +
                expect(info[:id]).to be_an_instance_of(Fixnum)
         
     | 
| 
       730 
755 
     | 
    
         
             
                expect(info).to have_key(:version)
         
     | 
| 
       731 
     | 
    
         
            -
                expect(info[:version] 
     | 
| 
      
 756 
     | 
    
         
            +
                expect(info[:version]).to be_an_instance_of(String)
         
     | 
| 
       732 
757 
     | 
    
         
             
              end
         
     | 
| 
       733 
758 
     | 
    
         | 
| 
       734 
759 
     | 
    
         
             
              context "strings returned by #info" do
         
     | 
| 
         @@ -755,11 +780,11 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       755 
780 
     | 
    
         | 
| 
       756 
781 
     | 
    
         
             
              it "#server_info should return a hash containing the client version ID and String" do
         
     | 
| 
       757 
782 
     | 
    
         
             
                server_info = @client.server_info
         
     | 
| 
       758 
     | 
    
         
            -
                expect(server_info 
     | 
| 
      
 783 
     | 
    
         
            +
                expect(server_info).to be_an_instance_of(Hash)
         
     | 
| 
       759 
784 
     | 
    
         
             
                expect(server_info).to have_key(:id)
         
     | 
| 
       760 
     | 
    
         
            -
                expect(server_info[:id] 
     | 
| 
      
 785 
     | 
    
         
            +
                expect(server_info[:id]).to be_an_instance_of(Fixnum)
         
     | 
| 
       761 
786 
     | 
    
         
             
                expect(server_info).to have_key(:version)
         
     | 
| 
       762 
     | 
    
         
            -
                expect(server_info[:version] 
     | 
| 
      
 787 
     | 
    
         
            +
                expect(server_info[:version]).to be_an_instance_of(String)
         
     | 
| 
       763 
788 
     | 
    
         
             
              end
         
     | 
| 
       764 
789 
     | 
    
         | 
| 
       765 
790 
     | 
    
         
             
              it "#server_info should require an open connection" do
         
     | 
| 
         @@ -848,7 +873,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       848 
873 
     | 
    
         
             
              end
         
     | 
| 
       849 
874 
     | 
    
         | 
| 
       850 
875 
     | 
    
         
             
              it "#thread_id should be a Fixnum" do
         
     | 
| 
       851 
     | 
    
         
            -
                expect(@client.thread_id 
     | 
| 
      
 876 
     | 
    
         
            +
                expect(@client.thread_id).to be_an_instance_of(Fixnum)
         
     | 
| 
       852 
877 
     | 
    
         
             
              end
         
     | 
| 
       853 
878 
     | 
    
         | 
| 
       854 
879 
     | 
    
         
             
              it "should respond to #ping" do
         
     |