mysql2 0.4.6 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +82 -52
 - data/examples/eventmachine.rb +0 -2
 - data/examples/threaded.rb +2 -4
 - data/ext/mysql2/client.c +171 -75
 - data/ext/mysql2/client.h +2 -41
 - data/ext/mysql2/extconf.rb +30 -23
 - data/ext/mysql2/mysql2_ext.c +2 -1
 - data/ext/mysql2/mysql2_ext.h +8 -8
 - data/ext/mysql2/mysql_enc_to_ruby.h +10 -0
 - data/ext/mysql2/result.c +24 -77
 - data/ext/mysql2/result.h +2 -3
 - data/ext/mysql2/statement.c +101 -73
 - data/ext/mysql2/statement.h +0 -2
 - data/ext/mysql2/wait_for_single_fd.h +2 -1
 - data/lib/mysql2/client.rb +37 -31
 - data/lib/mysql2/em.rb +2 -4
 - data/lib/mysql2/error.rb +49 -20
 - data/lib/mysql2/result.rb +2 -0
 - data/lib/mysql2/statement.rb +3 -9
 - data/lib/mysql2/version.rb +1 -1
 - data/lib/mysql2.rb +14 -15
 - data/spec/em/em_spec.rb +6 -6
 - data/spec/mysql2/client_spec.rb +300 -215
 - data/spec/mysql2/error_spec.rb +3 -9
 - data/spec/mysql2/result_spec.rb +124 -158
 - data/spec/mysql2/statement_spec.rb +138 -185
 - data/spec/spec_helper.rb +79 -61
 - data/support/5072E1F5.asc +432 -0
 - data/support/mysql_enc_to_ruby.rb +2 -2
 - data/support/ruby_enc_to_mysql.rb +5 -5
 - metadata +16 -14
 
    
        data/spec/mysql2/client_spec.rb
    CHANGED
    
    | 
         @@ -1,4 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # encoding: UTF-8
         
     | 
| 
       2 
1 
     | 
    
         
             
            require 'spec_helper'
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
3 
     | 
    
         
             
            RSpec.describe Mysql2::Client do
         
     | 
| 
         @@ -6,47 +5,46 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       6 
5 
     | 
    
         
             
                let(:cnf_file) { File.expand_path('../../my.cnf', __FILE__) }
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
7 
     | 
    
         
             
                it "should not raise an exception for valid defaults group" do
         
     | 
| 
       9 
     | 
    
         
            -
                  expect  
     | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  }.not_to raise_error
         
     | 
| 
      
 8 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 9 
     | 
    
         
            +
                    new_client(default_file: cnf_file, default_group: "test")
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end.not_to raise_error
         
     | 
| 
       13 
11 
     | 
    
         
             
                end
         
     | 
| 
       14 
12 
     | 
    
         | 
| 
       15 
13 
     | 
    
         
             
                it "should not raise an exception without default group" do
         
     | 
| 
       16 
     | 
    
         
            -
                  expect  
     | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
       18 
     | 
    
         
            -
                   
     | 
| 
      
 14 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 15 
     | 
    
         
            +
                    new_client(default_file: cnf_file)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end.not_to raise_error
         
     | 
| 
       19 
17 
     | 
    
         
             
                end
         
     | 
| 
       20 
18 
     | 
    
         
             
              end
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
              it "should raise  
     | 
| 
       23 
     | 
    
         
            -
                expect  
     | 
| 
      
 20 
     | 
    
         
            +
              it "should raise a Mysql::Error::ConnectionError upon connection failure" do
         
     | 
| 
      
 21 
     | 
    
         
            +
                expect do
         
     | 
| 
       24 
22 
     | 
    
         
             
                  # The odd local host IP address forces the mysql client library to
         
     | 
| 
       25 
23 
     | 
    
         
             
                  # use a TCP socket rather than a domain socket.
         
     | 
| 
       26 
     | 
    
         
            -
                   
     | 
| 
       27 
     | 
    
         
            -
                 
     | 
| 
      
 24 
     | 
    
         
            +
                  new_client('host' => '127.0.0.2', 'port' => 999999)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error::ConnectionError)
         
     | 
| 
       28 
26 
     | 
    
         
             
              end
         
     | 
| 
       29 
27 
     | 
    
         | 
| 
       30 
28 
     | 
    
         
             
              it "should raise an exception on create for invalid encodings" do
         
     | 
| 
       31 
     | 
    
         
            -
                expect  
     | 
| 
       32 
     | 
    
         
            -
                   
     | 
| 
       33 
     | 
    
         
            -
                 
     | 
| 
      
 29 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  new_client(encoding: "fake")
         
     | 
| 
      
 31 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
       34 
32 
     | 
    
         
             
              end
         
     | 
| 
       35 
33 
     | 
    
         | 
| 
       36 
34 
     | 
    
         
             
              it "should raise an exception on non-string encodings" do
         
     | 
| 
       37 
     | 
    
         
            -
                expect  
     | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
       39 
     | 
    
         
            -
                 
     | 
| 
      
 35 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  new_client(encoding: :fake)
         
     | 
| 
      
 37 
     | 
    
         
            +
                end.to raise_error(TypeError)
         
     | 
| 
       40 
38 
     | 
    
         
             
              end
         
     | 
| 
       41 
39 
     | 
    
         | 
| 
       42 
40 
     | 
    
         
             
              it "should not raise an exception on create for a valid encoding" do
         
     | 
| 
       43 
     | 
    
         
            -
                expect  
     | 
| 
       44 
     | 
    
         
            -
                   
     | 
| 
       45 
     | 
    
         
            -
                 
     | 
| 
      
 41 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  new_client(encoding: "utf8")
         
     | 
| 
      
 43 
     | 
    
         
            +
                end.not_to raise_error
         
     | 
| 
       46 
44 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
                expect  
     | 
| 
       48 
     | 
    
         
            -
                   
     | 
| 
       49 
     | 
    
         
            -
                 
     | 
| 
      
 45 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 46 
     | 
    
         
            +
                  new_client(DatabaseCredentials['root'].merge(encoding: "big5"))
         
     | 
| 
      
 47 
     | 
    
         
            +
                end.not_to raise_error
         
     | 
| 
       50 
48 
     | 
    
         
             
              end
         
     | 
| 
       51 
49 
     | 
    
         | 
| 
       52 
50 
     | 
    
         
             
              Klient = Class.new(Mysql2::Client) do
         
     | 
| 
         @@ -58,18 +56,18 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       58 
56 
     | 
    
         
             
              end
         
     | 
| 
       59 
57 
     | 
    
         | 
| 
       60 
58 
     | 
    
         
             
              it "should accept connect flags and pass them to #connect" do
         
     | 
| 
       61 
     | 
    
         
            -
                client = Klient.new : 
     | 
| 
      
 59 
     | 
    
         
            +
                client = Klient.new flags: Mysql2::Client::FOUND_ROWS
         
     | 
| 
       62 
60 
     | 
    
         
             
                expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0
         
     | 
| 
       63 
61 
     | 
    
         
             
              end
         
     | 
| 
       64 
62 
     | 
    
         | 
| 
       65 
63 
     | 
    
         
             
              it "should parse flags array" do
         
     | 
| 
       66 
     | 
    
         
            -
                client = Klient.new : 
     | 
| 
      
 64 
     | 
    
         
            +
                client = Klient.new flags: %w[FOUND_ROWS -PROTOCOL_41]
         
     | 
| 
       67 
65 
     | 
    
         
             
                expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
         
     | 
| 
       68 
66 
     | 
    
         
             
                expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
         
     | 
| 
       69 
67 
     | 
    
         
             
              end
         
     | 
| 
       70 
68 
     | 
    
         | 
| 
       71 
69 
     | 
    
         
             
              it "should parse flags string" do
         
     | 
| 
       72 
     | 
    
         
            -
                client = Klient.new : 
     | 
| 
      
 70 
     | 
    
         
            +
                client = Klient.new flags: "FOUND_ROWS -PROTOCOL_41"
         
     | 
| 
       73 
71 
     | 
    
         
             
                expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
         
     | 
| 
       74 
72 
     | 
    
         
             
                expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
         
     | 
| 
       75 
73 
     | 
    
         
             
              end
         
     | 
| 
         @@ -81,14 +79,15 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       81 
79 
     | 
    
         
             
                               Mysql2::Client::LONG_FLAG |
         
     | 
| 
       82 
80 
     | 
    
         
             
                               Mysql2::Client::TRANSACTIONS |
         
     | 
| 
       83 
81 
     | 
    
         
             
                               Mysql2::Client::PROTOCOL_41 |
         
     | 
| 
       84 
     | 
    
         
            -
                               Mysql2::Client::SECURE_CONNECTION
         
     | 
| 
      
 82 
     | 
    
         
            +
                               Mysql2::Client::SECURE_CONNECTION |
         
     | 
| 
      
 83 
     | 
    
         
            +
                               Mysql2::Client::CONNECT_ATTRS
         
     | 
| 
       85 
84 
     | 
    
         
             
                expect(client.connect_args.last[6]).to eql(client_flags)
         
     | 
| 
       86 
85 
     | 
    
         
             
              end
         
     | 
| 
       87 
86 
     | 
    
         | 
| 
       88 
87 
     | 
    
         
             
              it "should execute init command" do
         
     | 
| 
       89 
88 
     | 
    
         
             
                options = DatabaseCredentials['root'].dup
         
     | 
| 
       90 
89 
     | 
    
         
             
                options[:init_command] = "SET @something = 'setting_value';"
         
     | 
| 
       91 
     | 
    
         
            -
                client =  
     | 
| 
      
 90 
     | 
    
         
            +
                client = new_client(options)
         
     | 
| 
       92 
91 
     | 
    
         
             
                result = client.query("SELECT @something;")
         
     | 
| 
       93 
92 
     | 
    
         
             
                expect(result.first['@something']).to eq('setting_value')
         
     | 
| 
       94 
93 
     | 
    
         
             
              end
         
     | 
| 
         @@ -97,7 +96,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       97 
96 
     | 
    
         
             
                options = DatabaseCredentials['root'].dup
         
     | 
| 
       98 
97 
     | 
    
         
             
                options[:init_command] = "SET @something = 'setting_value';"
         
     | 
| 
       99 
98 
     | 
    
         
             
                options[:reconnect] = true
         
     | 
| 
       100 
     | 
    
         
            -
                client =  
     | 
| 
      
 99 
     | 
    
         
            +
                client = new_client(options)
         
     | 
| 
       101 
100 
     | 
    
         | 
| 
       102 
101 
     | 
    
         
             
                result = client.query("SELECT @something;")
         
     | 
| 
       103 
102 
     | 
    
         
             
                expect(result.first['@something']).to eq('setting_value')
         
     | 
| 
         @@ -136,20 +135,16 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       136 
135 
     | 
    
         | 
| 
       137 
136 
     | 
    
         
             
                # You may need to adjust the lines below to match your SSL certificate paths
         
     | 
| 
       138 
137 
     | 
    
         
             
                ssl_client = nil
         
     | 
| 
       139 
     | 
    
         
            -
                expect  
     | 
| 
       140 
     | 
    
         
            -
                   
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                     
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                      :sslcipher => 'DHE-RSA-AES256-SHA',
         
     | 
| 
       148 
     | 
    
         
            -
                      :sslverify => true
         
     | 
| 
       149 
     | 
    
         
            -
                    )
         
     | 
| 
      
 138 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 139 
     | 
    
         
            +
                  ssl_client = new_client(
         
     | 
| 
      
 140 
     | 
    
         
            +
                    'host'     => 'mysql2gem.example.com', # must match the certificates
         
     | 
| 
      
 141 
     | 
    
         
            +
                    :sslkey    => '/etc/mysql/client-key.pem',
         
     | 
| 
      
 142 
     | 
    
         
            +
                    :sslcert   => '/etc/mysql/client-cert.pem',
         
     | 
| 
      
 143 
     | 
    
         
            +
                    :sslca     => '/etc/mysql/ca-cert.pem',
         
     | 
| 
      
 144 
     | 
    
         
            +
                    :sslcipher => 'DHE-RSA-AES256-SHA',
         
     | 
| 
      
 145 
     | 
    
         
            +
                    :sslverify => true,
         
     | 
| 
       150 
146 
     | 
    
         
             
                  )
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
                }.not_to raise_error
         
     | 
| 
      
 147 
     | 
    
         
            +
                end.not_to raise_error
         
     | 
| 
       153 
148 
     | 
    
         | 
| 
       154 
149 
     | 
    
         
             
                results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
         
     | 
| 
       155 
150 
     | 
    
         
             
                expect(results['Ssl_cipher']).not_to be_empty
         
     | 
| 
         @@ -157,8 +152,6 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       157 
152 
     | 
    
         | 
| 
       158 
153 
     | 
    
         
             
                expect(ssl_client.ssl_cipher).not_to be_empty
         
     | 
| 
       159 
154 
     | 
    
         
             
                expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
         
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
                ssl_client.close
         
     | 
| 
       162 
155 
     | 
    
         
             
              end
         
     | 
| 
       163 
156 
     | 
    
         | 
| 
       164 
157 
     | 
    
         
             
              def run_gc
         
     | 
| 
         @@ -171,64 +164,112 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       171 
164 
     | 
    
         
             
              end
         
     | 
| 
       172 
165 
     | 
    
         | 
| 
       173 
166 
     | 
    
         
             
              it "should terminate connections when calling close" do
         
     | 
| 
       174 
     | 
    
         
            -
                 
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
                   
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
      
 167 
     | 
    
         
            +
                # rubocop:disable Lint/AmbiguousBlockAssociation
         
     | 
| 
      
 168 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 169 
     | 
    
         
            +
                  client = Mysql2::Client.new(DatabaseCredentials['root'])
         
     | 
| 
      
 170 
     | 
    
         
            +
                  connection_id = client.thread_id
         
     | 
| 
      
 171 
     | 
    
         
            +
                  client.close
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                  # mysql_close sends a quit command without waiting for a response
         
     | 
| 
      
 174 
     | 
    
         
            +
                  # so give the server some time to handle the detect the closed connection
         
     | 
| 
      
 175 
     | 
    
         
            +
                  closed = false
         
     | 
| 
      
 176 
     | 
    
         
            +
                  10.times do
         
     | 
| 
      
 177 
     | 
    
         
            +
                    closed = @client.query("SHOW PROCESSLIST").none? { |row| row['Id'] == connection_id }
         
     | 
| 
      
 178 
     | 
    
         
            +
                    break if closed
         
     | 
| 
      
 179 
     | 
    
         
            +
                    sleep(0.1)
         
     | 
| 
      
 180 
     | 
    
         
            +
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
                  expect(closed).to eq(true)
         
     | 
| 
      
 182 
     | 
    
         
            +
                end.to_not change {
         
     | 
| 
      
 183 
     | 
    
         
            +
                  @client.query("SHOW STATUS LIKE 'Aborted_%'").to_a
         
     | 
| 
       179 
184 
     | 
    
         
             
                }
         
     | 
| 
      
 185 
     | 
    
         
            +
                # rubocop:enable Lint/AmbiguousBlockAssociation
         
     | 
| 
       180 
186 
     | 
    
         
             
              end
         
     | 
| 
       181 
187 
     | 
    
         | 
| 
       182 
188 
     | 
    
         
             
              it "should not leave dangling connections after garbage collection" do
         
     | 
| 
       183 
189 
     | 
    
         
             
                run_gc
         
     | 
| 
       184 
     | 
    
         
            -
                 
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
      
 190 
     | 
    
         
            +
                # rubocop:disable Lint/AmbiguousBlockAssociation
         
     | 
| 
      
 191 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 192 
     | 
    
         
            +
                  expect do
         
     | 
| 
       186 
193 
     | 
    
         
             
                    10.times do
         
     | 
| 
       187 
194 
     | 
    
         
             
                      Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1')
         
     | 
| 
       188 
195 
     | 
    
         
             
                    end
         
     | 
| 
       189 
     | 
    
         
            -
                   
     | 
| 
      
 196 
     | 
    
         
            +
                  end.to change {
         
     | 
| 
       190 
197 
     | 
    
         
             
                    @client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
         
     | 
| 
       191 
198 
     | 
    
         
             
                  }.by(10)
         
     | 
| 
       192 
199 
     | 
    
         | 
| 
       193 
200 
     | 
    
         
             
                  run_gc
         
     | 
| 
       194 
     | 
    
         
            -
                 
     | 
| 
      
 201 
     | 
    
         
            +
                end.to_not change {
         
     | 
| 
       195 
202 
     | 
    
         
             
                  @client.query("SHOW STATUS LIKE 'Aborted_%'").to_a +
         
     | 
| 
       196 
203 
     | 
    
         
             
                    @client.query("SHOW STATUS LIKE 'Threads_connected'").to_a
         
     | 
| 
       197 
204 
     | 
    
         
             
                }
         
     | 
| 
      
 205 
     | 
    
         
            +
                # rubocop:enable Lint/AmbiguousBlockAssociation
         
     | 
| 
      
 206 
     | 
    
         
            +
              end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
              context "#set_server_option" do
         
     | 
| 
      
 209 
     | 
    
         
            +
                let(:client) do
         
     | 
| 
      
 210 
     | 
    
         
            +
                  new_client.tap do |client|
         
     | 
| 
      
 211 
     | 
    
         
            +
                    client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)
         
     | 
| 
      
 212 
     | 
    
         
            +
                  end
         
     | 
| 
      
 213 
     | 
    
         
            +
                end
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                it 'returns true when multi_statements is enable' do
         
     | 
| 
      
 216 
     | 
    
         
            +
                  expect(client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)).to be true
         
     | 
| 
      
 217 
     | 
    
         
            +
                end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
                it 'returns true when multi_statements is disable' do
         
     | 
| 
      
 220 
     | 
    
         
            +
                  expect(client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)).to be true
         
     | 
| 
      
 221 
     | 
    
         
            +
                end
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                it 'returns false when multi_statements is neither OPTION_MULTI_STATEMENTS_OFF or OPTION_MULTI_STATEMENTS_ON' do
         
     | 
| 
      
 224 
     | 
    
         
            +
                  expect(client.set_server_option(344)).to be false
         
     | 
| 
      
 225 
     | 
    
         
            +
                end
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                it 'enables multiple-statement' do
         
     | 
| 
      
 228 
     | 
    
         
            +
                  client.query("SELECT 1;SELECT 2;")
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                  expect(client.next_result).to be true
         
     | 
| 
      
 231 
     | 
    
         
            +
                  expect(client.store_result.first).to eql('2' => 2)
         
     | 
| 
      
 232 
     | 
    
         
            +
                  expect(client.next_result).to be false
         
     | 
| 
      
 233 
     | 
    
         
            +
                end
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                it 'disables multiple-statement' do
         
     | 
| 
      
 236 
     | 
    
         
            +
                  client.set_server_option(Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
                  expect { client.query("SELECT 1;SELECT 2;") }.to raise_error(Mysql2::Error)
         
     | 
| 
      
 239 
     | 
    
         
            +
                end
         
     | 
| 
       198 
240 
     | 
    
         
             
              end
         
     | 
| 
       199 
241 
     | 
    
         | 
| 
       200 
242 
     | 
    
         
             
              context "#automatic_close" do
         
     | 
| 
       201 
243 
     | 
    
         
             
                it "is enabled by default" do
         
     | 
| 
       202 
     | 
    
         
            -
                   
     | 
| 
       203 
     | 
    
         
            -
                  expect(client.automatic_close?).to be(true)
         
     | 
| 
      
 244 
     | 
    
         
            +
                  expect(new_client.automatic_close?).to be(true)
         
     | 
| 
       204 
245 
     | 
    
         
             
                end
         
     | 
| 
       205 
246 
     | 
    
         | 
| 
       206 
247 
     | 
    
         
             
                if RUBY_PLATFORM =~ /mingw|mswin/
         
     | 
| 
       207 
248 
     | 
    
         
             
                  it "cannot be disabled" do
         
     | 
| 
       208 
249 
     | 
    
         
             
                    expect do
         
     | 
| 
       209 
     | 
    
         
            -
                      client =  
     | 
| 
      
 250 
     | 
    
         
            +
                      client = new_client(automatic_close: false)
         
     | 
| 
       210 
251 
     | 
    
         
             
                      expect(client.automatic_close?).to be(true)
         
     | 
| 
       211 
252 
     | 
    
         
             
                    end.to output(/always closed by garbage collector/).to_stderr
         
     | 
| 
       212 
253 
     | 
    
         | 
| 
       213 
254 
     | 
    
         
             
                    expect do
         
     | 
| 
       214 
     | 
    
         
            -
                      client =  
     | 
| 
      
 255 
     | 
    
         
            +
                      client = new_client(automatic_close: true)
         
     | 
| 
       215 
256 
     | 
    
         
             
                      expect(client.automatic_close?).to be(true)
         
     | 
| 
       216 
257 
     | 
    
         
             
                    end.to_not output(/always closed by garbage collector/).to_stderr
         
     | 
| 
       217 
258 
     | 
    
         | 
| 
       218 
259 
     | 
    
         
             
                    expect do
         
     | 
| 
       219 
     | 
    
         
            -
                      client =  
     | 
| 
      
 260 
     | 
    
         
            +
                      client = new_client(automatic_close: true)
         
     | 
| 
       220 
261 
     | 
    
         
             
                      client.automatic_close = false
         
     | 
| 
       221 
262 
     | 
    
         
             
                      expect(client.automatic_close?).to be(true)
         
     | 
| 
       222 
263 
     | 
    
         
             
                    end.to output(/always closed by garbage collector/).to_stderr
         
     | 
| 
       223 
264 
     | 
    
         
             
                  end
         
     | 
| 
       224 
265 
     | 
    
         
             
                else
         
     | 
| 
       225 
266 
     | 
    
         
             
                  it "can be configured" do
         
     | 
| 
       226 
     | 
    
         
            -
                    client =  
     | 
| 
      
 267 
     | 
    
         
            +
                    client = new_client(automatic_close: false)
         
     | 
| 
       227 
268 
     | 
    
         
             
                    expect(client.automatic_close?).to be(false)
         
     | 
| 
       228 
269 
     | 
    
         
             
                  end
         
     | 
| 
       229 
270 
     | 
    
         | 
| 
       230 
271 
     | 
    
         
             
                  it "can be assigned" do
         
     | 
| 
       231 
     | 
    
         
            -
                    client =  
     | 
| 
      
 272 
     | 
    
         
            +
                    client = new_client
         
     | 
| 
       232 
273 
     | 
    
         
             
                    client.automatic_close = false
         
     | 
| 
       233 
274 
     | 
    
         
             
                    expect(client.automatic_close?).to be(false)
         
     | 
| 
       234 
275 
     | 
    
         | 
| 
         @@ -247,21 +288,18 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       247 
288 
     | 
    
         
             
                    client = Mysql2::Client.new(DatabaseCredentials['root'])
         
     | 
| 
       248 
289 
     | 
    
         
             
                    client.automatic_close = false
         
     | 
| 
       249 
290 
     | 
    
         | 
| 
       250 
     | 
    
         
            -
                     
     | 
| 
       251 
     | 
    
         
            -
                    # `fork` call hangs forever. WTF?
         
     | 
| 
       252 
     | 
    
         
            -
                    fork {}
         
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
                    fork do
         
     | 
| 
      
 291 
     | 
    
         
            +
                    child = fork do
         
     | 
| 
       255 
292 
     | 
    
         
             
                      client.query('SELECT 1')
         
     | 
| 
       256 
293 
     | 
    
         
             
                      client = nil
         
     | 
| 
       257 
294 
     | 
    
         
             
                      run_gc
         
     | 
| 
       258 
295 
     | 
    
         
             
                    end
         
     | 
| 
       259 
296 
     | 
    
         | 
| 
       260 
     | 
    
         
            -
                    Process.wait
         
     | 
| 
      
 297 
     | 
    
         
            +
                    Process.wait(child)
         
     | 
| 
       261 
298 
     | 
    
         | 
| 
       262 
299 
     | 
    
         
             
                    # this will throw an error if the underlying socket was shutdown by the
         
     | 
| 
       263 
300 
     | 
    
         
             
                    # child's GC
         
     | 
| 
       264 
301 
     | 
    
         
             
                    expect { client.query('SELECT 1') }.to_not raise_exception
         
     | 
| 
      
 302 
     | 
    
         
            +
                    client.close
         
     | 
| 
       265 
303 
     | 
    
         
             
                  end
         
     | 
| 
       266 
304 
     | 
    
         
             
                end
         
     | 
| 
       267 
305 
     | 
    
         
             
              end
         
     | 
| 
         @@ -270,9 +308,9 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       270 
308 
     | 
    
         
             
                database = 1235
         
     | 
| 
       271 
309 
     | 
    
         
             
                @client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
         
     | 
| 
       272 
310 
     | 
    
         | 
| 
       273 
     | 
    
         
            -
                expect  
     | 
| 
       274 
     | 
    
         
            -
                   
     | 
| 
       275 
     | 
    
         
            -
                 
     | 
| 
      
 311 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 312 
     | 
    
         
            +
                  new_client('database' => database)
         
     | 
| 
      
 313 
     | 
    
         
            +
                end.not_to raise_error
         
     | 
| 
       276 
314 
     | 
    
         | 
| 
       277 
315 
     | 
    
         
             
                @client.query "DROP DATABASE IF EXISTS `#{database}`"
         
     | 
| 
       278 
316 
     | 
    
         
             
              end
         
     | 
| 
         @@ -283,9 +321,28 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       283 
321 
     | 
    
         | 
| 
       284 
322 
     | 
    
         
             
              it "should be able to close properly" do
         
     | 
| 
       285 
323 
     | 
    
         
             
                expect(@client.close).to be_nil
         
     | 
| 
       286 
     | 
    
         
            -
                expect  
     | 
| 
      
 324 
     | 
    
         
            +
                expect do
         
     | 
| 
       287 
325 
     | 
    
         
             
                  @client.query "SELECT 1"
         
     | 
| 
       288 
     | 
    
         
            -
                 
     | 
| 
      
 326 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
      
 327 
     | 
    
         
            +
              end
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
              context "#closed?" do
         
     | 
| 
      
 330 
     | 
    
         
            +
                it "should return false when connected" do
         
     | 
| 
      
 331 
     | 
    
         
            +
                  expect(@client.closed?).to eql(false)
         
     | 
| 
      
 332 
     | 
    
         
            +
                end
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                it "should return true after close" do
         
     | 
| 
      
 335 
     | 
    
         
            +
                  @client.close
         
     | 
| 
      
 336 
     | 
    
         
            +
                  expect(@client.closed?).to eql(true)
         
     | 
| 
      
 337 
     | 
    
         
            +
                end
         
     | 
| 
      
 338 
     | 
    
         
            +
              end
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
              it "should not try to query closed mysql connection" do
         
     | 
| 
      
 341 
     | 
    
         
            +
                client = new_client(reconnect: true)
         
     | 
| 
      
 342 
     | 
    
         
            +
                expect(client.close).to be_nil
         
     | 
| 
      
 343 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 344 
     | 
    
         
            +
                  client.query "SELECT 1"
         
     | 
| 
      
 345 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
       289 
346 
     | 
    
         
             
              end
         
     | 
| 
       290 
347 
     | 
    
         | 
| 
       291 
348 
     | 
    
         
             
              it "should respond to #query" do
         
     | 
| 
         @@ -306,8 +363,8 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       306 
363 
     | 
    
         
             
                context "when has a warnings" do
         
     | 
| 
       307 
364 
     | 
    
         
             
                  it "should > 0" do
         
     | 
| 
       308 
365 
     | 
    
         
             
                    # "the statement produces extra information that can be viewed by issuing a SHOW WARNINGS"
         
     | 
| 
       309 
     | 
    
         
            -
                    #  
     | 
| 
       310 
     | 
    
         
            -
                    @client.query( 
     | 
| 
      
 366 
     | 
    
         
            +
                    # https://dev.mysql.com/doc/refman/5.7/en/show-warnings.html
         
     | 
| 
      
 367 
     | 
    
         
            +
                    @client.query('DROP TABLE IF EXISTS test.no_such_table')
         
     | 
| 
       311 
368 
     | 
    
         
             
                    expect(@client.warning_count).to be > 0
         
     | 
| 
       312 
369 
     | 
    
         
             
                  end
         
     | 
| 
       313 
370 
     | 
    
         
             
                end
         
     | 
| 
         @@ -334,7 +391,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       334 
391 
     | 
    
         
             
                    # # 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).
         
     | 
| 
       335 
392 
     | 
    
         
             
                    @client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
         
     | 
| 
       336 
393 
     | 
    
         | 
| 
       337 
     | 
    
         
            -
                    expect(@client.query_info).to eql(: 
     | 
| 
      
 394 
     | 
    
         
            +
                    expect(@client.query_info).to eql(records: 2, duplicates: 0, warnings: 0)
         
     | 
| 
       338 
395 
     | 
    
         
             
                    expect(@client.query_info_string).to eq('Records: 2  Duplicates: 0  Warnings: 0')
         
     | 
| 
       339 
396 
     | 
    
         | 
| 
       340 
397 
     | 
    
         
             
                    @client.query "DROP TABLE infoTest"
         
     | 
| 
         @@ -344,99 +401,124 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       344 
401 
     | 
    
         | 
| 
       345 
402 
     | 
    
         
             
              context ":local_infile" do
         
     | 
| 
       346 
403 
     | 
    
         
             
                before(:all) do
         
     | 
| 
       347 
     | 
    
         
            -
                   
     | 
| 
       348 
     | 
    
         
            -
             
     | 
| 
       349 
     | 
    
         
            -
             
     | 
| 
       350 
     | 
    
         
            -
             
     | 
| 
       351 
     | 
    
         
            -
             
     | 
| 
       352 
     | 
    
         
            -
             
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
     | 
    
         
            -
             
     | 
| 
       355 
     | 
    
         
            -
             
     | 
| 
       356 
     | 
    
         
            -
             
     | 
| 
       357 
     | 
    
         
            -
             
     | 
| 
       358 
     | 
    
         
            -
             
     | 
| 
      
 404 
     | 
    
         
            +
                  new_client(local_infile: true) do |client|
         
     | 
| 
      
 405 
     | 
    
         
            +
                    local = client.query "SHOW VARIABLES LIKE 'local_infile'"
         
     | 
| 
      
 406 
     | 
    
         
            +
                    local_enabled = local.any? { |x| x['Value'] == 'ON' }
         
     | 
| 
      
 407 
     | 
    
         
            +
                    skip("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
      
 409 
     | 
    
         
            +
                    client.query %[
         
     | 
| 
      
 410 
     | 
    
         
            +
                      CREATE TABLE IF NOT EXISTS infileTest (
         
     | 
| 
      
 411 
     | 
    
         
            +
                        id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
         
     | 
| 
      
 412 
     | 
    
         
            +
                        foo VARCHAR(10),
         
     | 
| 
      
 413 
     | 
    
         
            +
                        bar MEDIUMTEXT
         
     | 
| 
      
 414 
     | 
    
         
            +
                      )
         
     | 
| 
      
 415 
     | 
    
         
            +
                    ]
         
     | 
| 
      
 416 
     | 
    
         
            +
                  end
         
     | 
| 
       359 
417 
     | 
    
         
             
                end
         
     | 
| 
       360 
418 
     | 
    
         | 
| 
       361 
419 
     | 
    
         
             
                after(:all) do
         
     | 
| 
       362 
     | 
    
         
            -
                   
     | 
| 
      
 420 
     | 
    
         
            +
                  new_client do |client|
         
     | 
| 
      
 421 
     | 
    
         
            +
                    client.query "DROP TABLE IF EXISTS infileTest"
         
     | 
| 
      
 422 
     | 
    
         
            +
                  end
         
     | 
| 
       363 
423 
     | 
    
         
             
                end
         
     | 
| 
       364 
424 
     | 
    
         | 
| 
       365 
425 
     | 
    
         
             
                it "should raise an error when local_infile is disabled" do
         
     | 
| 
       366 
     | 
    
         
            -
                  client =  
     | 
| 
       367 
     | 
    
         
            -
                  expect  
     | 
| 
      
 426 
     | 
    
         
            +
                  client = new_client(local_infile: false)
         
     | 
| 
      
 427 
     | 
    
         
            +
                  expect do
         
     | 
| 
       368 
428 
     | 
    
         
             
                    client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
         
     | 
| 
       369 
     | 
    
         
            -
                   
     | 
| 
      
 429 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error, /command is not allowed/)
         
     | 
| 
       370 
430 
     | 
    
         
             
                end
         
     | 
| 
       371 
431 
     | 
    
         | 
| 
       372 
432 
     | 
    
         
             
                it "should raise an error when a non-existent file is loaded" do
         
     | 
| 
       373 
     | 
    
         
            -
                   
     | 
| 
       374 
     | 
    
         
            -
             
     | 
| 
       375 
     | 
    
         
            -
             
     | 
| 
      
 433 
     | 
    
         
            +
                  client = new_client(local_infile: true)
         
     | 
| 
      
 434 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 435 
     | 
    
         
            +
                    client.query "LOAD DATA LOCAL INFILE 'this/file/is/not/here' INTO TABLE infileTest"
         
     | 
| 
      
 436 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here')
         
     | 
| 
       376 
437 
     | 
    
         
             
                end
         
     | 
| 
       377 
438 
     | 
    
         | 
| 
       378 
439 
     | 
    
         
             
                it "should LOAD DATA LOCAL INFILE" do
         
     | 
| 
       379 
     | 
    
         
            -
                   
     | 
| 
       380 
     | 
    
         
            -
                   
     | 
| 
       381 
     | 
    
         
            -
                   
     | 
| 
      
 440 
     | 
    
         
            +
                  client = new_client(local_infile: true)
         
     | 
| 
      
 441 
     | 
    
         
            +
                  client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
         
     | 
| 
      
 442 
     | 
    
         
            +
                  info = client.query_info
         
     | 
| 
      
 443 
     | 
    
         
            +
                  expect(info).to eql(records: 1, deleted: 0, skipped: 0, warnings: 0)
         
     | 
| 
       382 
444 
     | 
    
         | 
| 
       383 
     | 
    
         
            -
                  result =  
     | 
| 
      
 445 
     | 
    
         
            +
                  result = client.query "SELECT * FROM infileTest"
         
     | 
| 
       384 
446 
     | 
    
         
             
                  expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
         
     | 
| 
       385 
447 
     | 
    
         
             
                end
         
     | 
| 
       386 
448 
     | 
    
         
             
              end
         
     | 
| 
       387 
449 
     | 
    
         | 
| 
       388 
450 
     | 
    
         
             
              it "should expect connect_timeout to be a positive integer" do
         
     | 
| 
       389 
     | 
    
         
            -
                expect  
     | 
| 
       390 
     | 
    
         
            -
                   
     | 
| 
       391 
     | 
    
         
            -
                 
     | 
| 
      
 451 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 452 
     | 
    
         
            +
                  new_client(connect_timeout: -1)
         
     | 
| 
      
 453 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
       392 
454 
     | 
    
         
             
              end
         
     | 
| 
       393 
455 
     | 
    
         | 
| 
       394 
456 
     | 
    
         
             
              it "should expect read_timeout to be a positive integer" do
         
     | 
| 
       395 
     | 
    
         
            -
                expect  
     | 
| 
       396 
     | 
    
         
            -
                   
     | 
| 
       397 
     | 
    
         
            -
                 
     | 
| 
      
 457 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 458 
     | 
    
         
            +
                  new_client(read_timeout: -1)
         
     | 
| 
      
 459 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
       398 
460 
     | 
    
         
             
              end
         
     | 
| 
       399 
461 
     | 
    
         | 
| 
       400 
462 
     | 
    
         
             
              it "should expect write_timeout to be a positive integer" do
         
     | 
| 
       401 
     | 
    
         
            -
                expect  
     | 
| 
       402 
     | 
    
         
            -
                   
     | 
| 
       403 
     | 
    
         
            -
                 
     | 
| 
      
 463 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 464 
     | 
    
         
            +
                  new_client(write_timeout: -1)
         
     | 
| 
      
 465 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
       404 
466 
     | 
    
         
             
              end
         
     | 
| 
       405 
467 
     | 
    
         | 
| 
       406 
468 
     | 
    
         
             
              it "should allow nil read_timeout" do
         
     | 
| 
       407 
     | 
    
         
            -
                client =  
     | 
| 
      
 469 
     | 
    
         
            +
                client = new_client(read_timeout: nil)
         
     | 
| 
       408 
470 
     | 
    
         | 
| 
       409 
471 
     | 
    
         
             
                expect(client.read_timeout).to be_nil
         
     | 
| 
       410 
472 
     | 
    
         
             
              end
         
     | 
| 
       411 
473 
     | 
    
         | 
| 
      
 474 
     | 
    
         
            +
              it "should set default program_name in connect_attrs" do
         
     | 
| 
      
 475 
     | 
    
         
            +
                client = new_client
         
     | 
| 
      
 476 
     | 
    
         
            +
                if Mysql2::Client::CONNECT_ATTRS.zero? || client.server_info[:version].match(/10.[01].\d+-MariaDB/)
         
     | 
| 
      
 477 
     | 
    
         
            +
                  pending('Both client and server versions must be MySQL 5.6 or MariaDB 10.2 or later.')
         
     | 
| 
      
 478 
     | 
    
         
            +
                end
         
     | 
| 
      
 479 
     | 
    
         
            +
                result = client.query("SELECT attr_value FROM performance_schema.session_account_connect_attrs WHERE processlist_id = connection_id() AND attr_name = 'program_name'")
         
     | 
| 
      
 480 
     | 
    
         
            +
                expect(result.first['attr_value']).to eq($PROGRAM_NAME)
         
     | 
| 
      
 481 
     | 
    
         
            +
              end
         
     | 
| 
      
 482 
     | 
    
         
            +
             
     | 
| 
      
 483 
     | 
    
         
            +
              it "should set custom connect_attrs" do
         
     | 
| 
      
 484 
     | 
    
         
            +
                client = new_client(connect_attrs: { program_name: 'my_program_name', foo: 'fooval', bar: 'barval' })
         
     | 
| 
      
 485 
     | 
    
         
            +
                if Mysql2::Client::CONNECT_ATTRS.zero? || client.server_info[:version].match(/10.[01].\d+-MariaDB/)
         
     | 
| 
      
 486 
     | 
    
         
            +
                  pending('Both client and server versions must be MySQL 5.6 or MariaDB 10.2 or later.')
         
     | 
| 
      
 487 
     | 
    
         
            +
                end
         
     | 
| 
      
 488 
     | 
    
         
            +
                results = Hash[client.query("SELECT * FROM performance_schema.session_account_connect_attrs WHERE processlist_id = connection_id()").map { |x| x.values_at('ATTR_NAME', 'ATTR_VALUE') }]
         
     | 
| 
      
 489 
     | 
    
         
            +
                expect(results['program_name']).to eq('my_program_name')
         
     | 
| 
      
 490 
     | 
    
         
            +
                expect(results['foo']).to eq('fooval')
         
     | 
| 
      
 491 
     | 
    
         
            +
                expect(results['bar']).to eq('barval')
         
     | 
| 
      
 492 
     | 
    
         
            +
              end
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
       412 
494 
     | 
    
         
             
              context "#query" do
         
     | 
| 
       413 
495 
     | 
    
         
             
                it "should let you query again if iterating is finished when streaming" do
         
     | 
| 
       414 
     | 
    
         
            -
                  @client.query("SELECT 1 UNION SELECT 2", : 
     | 
| 
      
 496 
     | 
    
         
            +
                  @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).each.to_a
         
     | 
| 
       415 
497 
     | 
    
         | 
| 
       416 
     | 
    
         
            -
                  expect  
     | 
| 
       417 
     | 
    
         
            -
                    @client.query("SELECT 1 UNION SELECT 2", : 
     | 
| 
       418 
     | 
    
         
            -
                   
     | 
| 
      
 498 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 499 
     | 
    
         
            +
                    @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
         
     | 
| 
      
 500 
     | 
    
         
            +
                  end.to_not raise_error
         
     | 
| 
       419 
501 
     | 
    
         
             
                end
         
     | 
| 
       420 
502 
     | 
    
         | 
| 
       421 
503 
     | 
    
         
             
                it "should not let you query again if iterating is not finished when streaming" do
         
     | 
| 
       422 
     | 
    
         
            -
                  @client.query("SELECT 1 UNION SELECT 2", : 
     | 
| 
      
 504 
     | 
    
         
            +
                  @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).first
         
     | 
| 
       423 
505 
     | 
    
         | 
| 
       424 
     | 
    
         
            -
                  expect  
     | 
| 
       425 
     | 
    
         
            -
                    @client.query("SELECT 1 UNION SELECT 2", : 
     | 
| 
       426 
     | 
    
         
            -
                   
     | 
| 
      
 506 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 507 
     | 
    
         
            +
                    @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
         
     | 
| 
      
 508 
     | 
    
         
            +
                  end.to raise_exception(Mysql2::Error)
         
     | 
| 
       427 
509 
     | 
    
         
             
                end
         
     | 
| 
       428 
510 
     | 
    
         | 
| 
       429 
511 
     | 
    
         
             
                it "should only accept strings as the query parameter" do
         
     | 
| 
       430 
     | 
    
         
            -
                  expect  
     | 
| 
      
 512 
     | 
    
         
            +
                  expect do
         
     | 
| 
       431 
513 
     | 
    
         
             
                    @client.query ["SELECT 'not right'"]
         
     | 
| 
       432 
     | 
    
         
            -
                   
     | 
| 
      
 514 
     | 
    
         
            +
                  end.to raise_error(TypeError)
         
     | 
| 
       433 
515 
     | 
    
         
             
                end
         
     | 
| 
       434 
516 
     | 
    
         | 
| 
       435 
517 
     | 
    
         
             
                it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do
         
     | 
| 
       436 
     | 
    
         
            -
                  result = @client.query "SELECT 1", : 
     | 
| 
      
 518 
     | 
    
         
            +
                  result = @client.query "SELECT 1", something: :else
         
     | 
| 
       437 
519 
     | 
    
         
             
                  expect(@client.query_options[:something]).to be_nil
         
     | 
| 
       438 
     | 
    
         
            -
                  expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(: 
     | 
| 
       439 
     | 
    
         
            -
                  expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(: 
     | 
| 
      
 520 
     | 
    
         
            +
                  expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(something: :else))
         
     | 
| 
      
 521 
     | 
    
         
            +
                  expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(something: :else))
         
     | 
| 
       440 
522 
     | 
    
         | 
| 
       441 
523 
     | 
    
         
             
                  result = @client.query "SELECT 1"
         
     | 
| 
       442 
524 
     | 
    
         
             
                  expect(result.instance_variable_get('@query_options')).to eql(@client.query_options)
         
     | 
| 
         @@ -444,7 +526,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       444 
526 
     | 
    
         
             
                end
         
     | 
| 
       445 
527 
     | 
    
         | 
| 
       446 
528 
     | 
    
         
             
                it "should allow changing query options for subsequent queries" do
         
     | 
| 
       447 
     | 
    
         
            -
                  @client.query_options 
     | 
| 
      
 529 
     | 
    
         
            +
                  @client.query_options[:something] = :else
         
     | 
| 
       448 
530 
     | 
    
         
             
                  result = @client.query "SELECT 1"
         
     | 
| 
       449 
531 
     | 
    
         
             
                  expect(@client.query_options[:something]).to eql(:else)
         
     | 
| 
       450 
532 
     | 
    
         
             
                  expect(result.instance_variable_get('@query_options')[:something]).to eql(:else)
         
     | 
| 
         @@ -459,41 +541,60 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       459 
541 
     | 
    
         
             
                end
         
     | 
| 
       460 
542 
     | 
    
         | 
| 
       461 
543 
     | 
    
         
             
                it "should be able to return results as an array" do
         
     | 
| 
       462 
     | 
    
         
            -
                  expect(@client.query("SELECT 1", : 
     | 
| 
       463 
     | 
    
         
            -
                  @client.query("SELECT 1").each(: 
     | 
| 
      
 544 
     | 
    
         
            +
                  expect(@client.query("SELECT 1", as: :array).first).to be_an_instance_of(Array)
         
     | 
| 
      
 545 
     | 
    
         
            +
                  @client.query("SELECT 1").each(as: :array)
         
     | 
| 
       464 
546 
     | 
    
         
             
                end
         
     | 
| 
       465 
547 
     | 
    
         | 
| 
       466 
548 
     | 
    
         
             
                it "should be able to return results with symbolized keys" do
         
     | 
| 
       467 
     | 
    
         
            -
                  expect(@client.query("SELECT 1", : 
     | 
| 
      
 549 
     | 
    
         
            +
                  expect(@client.query("SELECT 1", symbolize_keys: true).first.keys[0]).to be_an_instance_of(Symbol)
         
     | 
| 
       468 
550 
     | 
    
         
             
                end
         
     | 
| 
       469 
551 
     | 
    
         | 
| 
       470 
552 
     | 
    
         
             
                it "should require an open connection" do
         
     | 
| 
       471 
553 
     | 
    
         
             
                  @client.close
         
     | 
| 
       472 
     | 
    
         
            -
                  expect  
     | 
| 
      
 554 
     | 
    
         
            +
                  expect do
         
     | 
| 
       473 
555 
     | 
    
         
             
                    @client.query "SELECT 1"
         
     | 
| 
       474 
     | 
    
         
            -
                   
     | 
| 
      
 556 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error)
         
     | 
| 
      
 557 
     | 
    
         
            +
                end
         
     | 
| 
      
 558 
     | 
    
         
            +
             
     | 
| 
      
 559 
     | 
    
         
            +
                it "should detect closed connection on query read error" do
         
     | 
| 
      
 560 
     | 
    
         
            +
                  connection_id = @client.thread_id
         
     | 
| 
      
 561 
     | 
    
         
            +
                  Thread.new do
         
     | 
| 
      
 562 
     | 
    
         
            +
                    sleep(0.1)
         
     | 
| 
      
 563 
     | 
    
         
            +
                    Mysql2::Client.new(DatabaseCredentials['root']).tap do |supervisor|
         
     | 
| 
      
 564 
     | 
    
         
            +
                      supervisor.query("KILL #{connection_id}")
         
     | 
| 
      
 565 
     | 
    
         
            +
                    end.close
         
     | 
| 
      
 566 
     | 
    
         
            +
                  end
         
     | 
| 
      
 567 
     | 
    
         
            +
                  expect do
         
     | 
| 
      
 568 
     | 
    
         
            +
                    @client.query("SELECT SLEEP(1)")
         
     | 
| 
      
 569 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error, /Lost connection to MySQL server/)
         
     | 
| 
      
 570 
     | 
    
         
            +
             
     | 
| 
      
 571 
     | 
    
         
            +
                  if RUBY_PLATFORM !~ /mingw|mswin/
         
     | 
| 
      
 572 
     | 
    
         
            +
                    expect do
         
     | 
| 
      
 573 
     | 
    
         
            +
                      @client.socket
         
     | 
| 
      
 574 
     | 
    
         
            +
                    end.to raise_error(Mysql2::Error, 'MySQL client is not connected')
         
     | 
| 
      
 575 
     | 
    
         
            +
                  end
         
     | 
| 
       475 
576 
     | 
    
         
             
                end
         
     | 
| 
       476 
577 
     | 
    
         | 
| 
       477 
578 
     | 
    
         
             
                if RUBY_PLATFORM !~ /mingw|mswin/
         
     | 
| 
       478 
579 
     | 
    
         
             
                  it "should not allow another query to be sent without fetching a result first" do
         
     | 
| 
       479 
     | 
    
         
            -
                    @client.query("SELECT 1", : 
     | 
| 
       480 
     | 
    
         
            -
                    expect  
     | 
| 
      
 580 
     | 
    
         
            +
                    @client.query("SELECT 1", async: true)
         
     | 
| 
      
 581 
     | 
    
         
            +
                    expect do
         
     | 
| 
       481 
582 
     | 
    
         
             
                      @client.query("SELECT 1")
         
     | 
| 
       482 
     | 
    
         
            -
                     
     | 
| 
      
 583 
     | 
    
         
            +
                    end.to raise_error(Mysql2::Error)
         
     | 
| 
       483 
584 
     | 
    
         
             
                  end
         
     | 
| 
       484 
585 
     | 
    
         | 
| 
       485 
586 
     | 
    
         
             
                  it "should describe the thread holding the active query" do
         
     | 
| 
       486 
     | 
    
         
            -
                    thr = Thread.new { @client.query("SELECT 1", : 
     | 
| 
      
 587 
     | 
    
         
            +
                    thr = Thread.new { @client.query("SELECT 1", async: true) }
         
     | 
| 
       487 
588 
     | 
    
         | 
| 
       488 
589 
     | 
    
         
             
                    thr.join
         
     | 
| 
       489 
590 
     | 
    
         
             
                    expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, Regexp.new(Regexp.escape(thr.inspect)))
         
     | 
| 
       490 
591 
     | 
    
         
             
                  end
         
     | 
| 
       491 
592 
     | 
    
         | 
| 
       492 
593 
     | 
    
         
             
                  it "should timeout if we wait longer than :read_timeout" do
         
     | 
| 
       493 
     | 
    
         
            -
                    client =  
     | 
| 
       494 
     | 
    
         
            -
                    expect  
     | 
| 
      
 594 
     | 
    
         
            +
                    client = new_client(read_timeout: 0)
         
     | 
| 
      
 595 
     | 
    
         
            +
                    expect do
         
     | 
| 
       495 
596 
     | 
    
         
             
                      client.query('SELECT SLEEP(0.1)')
         
     | 
| 
       496 
     | 
    
         
            -
                     
     | 
| 
      
 597 
     | 
    
         
            +
                    end.to raise_error(Mysql2::Error::TimeoutError)
         
     | 
| 
       497 
598 
     | 
    
         
             
                  end
         
     | 
| 
       498 
599 
     | 
    
         | 
| 
       499 
600 
     | 
    
         
             
                  # XXX this test is not deterministic (because Unix signal handling is not)
         
     | 
| 
         @@ -527,22 +628,18 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       527 
628 
     | 
    
         
             
                  end
         
     | 
| 
       528 
629 
     | 
    
         | 
| 
       529 
630 
     | 
    
         
             
                  it "#socket should return a Fixnum (file descriptor from C)" do
         
     | 
| 
       530 
     | 
    
         
            -
                    expect(@client.socket).to be_an_instance_of( 
     | 
| 
      
 631 
     | 
    
         
            +
                    expect(@client.socket).to be_an_instance_of(0.class)
         
     | 
| 
       531 
632 
     | 
    
         
             
                    expect(@client.socket).not_to eql(0)
         
     | 
| 
       532 
633 
     | 
    
         
             
                  end
         
     | 
| 
       533 
634 
     | 
    
         | 
| 
       534 
635 
     | 
    
         
             
                  it "#socket should require an open connection" do
         
     | 
| 
       535 
636 
     | 
    
         
             
                    @client.close
         
     | 
| 
       536 
     | 
    
         
            -
                    expect  
     | 
| 
      
 637 
     | 
    
         
            +
                    expect do
         
     | 
| 
       537 
638 
     | 
    
         
             
                      @client.socket
         
     | 
| 
       538 
     | 
    
         
            -
                     
     | 
| 
      
 639 
     | 
    
         
            +
                    end.to raise_error(Mysql2::Error)
         
     | 
| 
       539 
640 
     | 
    
         
             
                  end
         
     | 
| 
       540 
641 
     | 
    
         | 
| 
       541 
642 
     | 
    
         
             
                  it 'should be impervious to connection-corrupting timeouts in #execute' do
         
     | 
| 
       542 
     | 
    
         
            -
                    # the statement handle gets corrupted and will segfault the tests if interrupted,
         
     | 
| 
       543 
     | 
    
         
            -
                    # so we can't even use pending on this test, really have to skip it on older Rubies.
         
     | 
| 
       544 
     | 
    
         
            -
                    skip('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
         
     | 
| 
       545 
     | 
    
         
            -
             
     | 
| 
       546 
643 
     | 
    
         
             
                    # attempt to break the connection
         
     | 
| 
       547 
644 
     | 
    
         
             
                    stmt = @client.prepare('SELECT SLEEP(?)')
         
     | 
| 
       548 
645 
     | 
    
         
             
                    expect { Timeout.timeout(0.1) { stmt.execute(0.2) } }.to raise_error(Timeout::Error)
         
     | 
| 
         @@ -559,22 +656,22 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       559 
656 
     | 
    
         
             
                    end
         
     | 
| 
       560 
657 
     | 
    
         | 
| 
       561 
658 
     | 
    
         
             
                    it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
         
     | 
| 
       562 
     | 
    
         
            -
                      if RUBY_PLATFORM.include?('darwin') &&  
     | 
| 
       563 
     | 
    
         
            -
                        pending(' 
     | 
| 
      
 659 
     | 
    
         
            +
                      if RUBY_PLATFORM.include?('darwin') && @client.server_info.fetch(:version).start_with?('5.5')
         
     | 
| 
      
 660 
     | 
    
         
            +
                        pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
         
     | 
| 
       564 
661 
     | 
    
         
             
                      end
         
     | 
| 
       565 
662 
     | 
    
         | 
| 
       566 
     | 
    
         
            -
                      client =  
     | 
| 
      
 663 
     | 
    
         
            +
                      client = new_client(reconnect: true)
         
     | 
| 
       567 
664 
     | 
    
         | 
| 
       568 
665 
     | 
    
         
             
                      expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
         
     | 
| 
       569 
666 
     | 
    
         
             
                      expect { client.query('SELECT 1') }.to_not raise_error
         
     | 
| 
       570 
667 
     | 
    
         
             
                    end
         
     | 
| 
       571 
668 
     | 
    
         | 
| 
       572 
669 
     | 
    
         
             
                    it "should handle Timeouts without leaving the connection hanging if reconnect is set to true after construction" do
         
     | 
| 
       573 
     | 
    
         
            -
                      if RUBY_PLATFORM.include?('darwin') &&  
     | 
| 
       574 
     | 
    
         
            -
                        pending(' 
     | 
| 
      
 670 
     | 
    
         
            +
                      if RUBY_PLATFORM.include?('darwin') && @client.server_info.fetch(:version).start_with?('5.5')
         
     | 
| 
      
 671 
     | 
    
         
            +
                        pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
         
     | 
| 
       575 
672 
     | 
    
         
             
                      end
         
     | 
| 
       576 
673 
     | 
    
         | 
| 
       577 
     | 
    
         
            -
                      client =  
     | 
| 
      
 674 
     | 
    
         
            +
                      client = new_client
         
     | 
| 
       578 
675 
     | 
    
         | 
| 
       579 
676 
     | 
    
         
             
                      expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
         
     | 
| 
       580 
677 
     | 
    
         
             
                      expect { client.query('SELECT 1') }.to raise_error(Mysql2::Error)
         
     | 
| 
         @@ -590,10 +687,11 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       590 
687 
     | 
    
         
             
                    sleep_time = 0.5
         
     | 
| 
       591 
688 
     | 
    
         | 
| 
       592 
689 
     | 
    
         
             
                    # Note that each thread opens its own database connection
         
     | 
| 
       593 
     | 
    
         
            -
                    threads = 5 
     | 
| 
      
 690 
     | 
    
         
            +
                    threads = Array.new(5) do
         
     | 
| 
       594 
691 
     | 
    
         
             
                      Thread.new do
         
     | 
| 
       595 
     | 
    
         
            -
                         
     | 
| 
       596 
     | 
    
         
            -
             
     | 
| 
      
 692 
     | 
    
         
            +
                        new_client do |client|
         
     | 
| 
      
 693 
     | 
    
         
            +
                          client.query("SELECT SLEEP(#{sleep_time})")
         
     | 
| 
      
 694 
     | 
    
         
            +
                        end
         
     | 
| 
       597 
695 
     | 
    
         
             
                        Thread.current.object_id
         
     | 
| 
       598 
696 
     | 
    
         
             
                      end
         
     | 
| 
       599 
697 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -607,17 +705,11 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       607 
705 
     | 
    
         | 
| 
       608 
706 
     | 
    
         
             
                  it "evented async queries should be supported" do
         
     | 
| 
       609 
707 
     | 
    
         
             
                    # should immediately return nil
         
     | 
| 
       610 
     | 
    
         
            -
                    expect(@client.query("SELECT sleep(0.1)", : 
     | 
| 
      
 708 
     | 
    
         
            +
                    expect(@client.query("SELECT sleep(0.1)", async: true)).to eql(nil)
         
     | 
| 
       611 
709 
     | 
    
         | 
| 
       612 
     | 
    
         
            -
                    io_wrapper = IO.for_fd(@client.socket)
         
     | 
| 
      
 710 
     | 
    
         
            +
                    io_wrapper = IO.for_fd(@client.socket, autoclose: false)
         
     | 
| 
       613 
711 
     | 
    
         
             
                    loops = 0
         
     | 
| 
       614 
     | 
    
         
            -
                     
     | 
| 
       615 
     | 
    
         
            -
                      if IO.select([io_wrapper], nil, nil, 0.05)
         
     | 
| 
       616 
     | 
    
         
            -
                        break
         
     | 
| 
       617 
     | 
    
         
            -
                      else
         
     | 
| 
       618 
     | 
    
         
            -
                        loops += 1
         
     | 
| 
       619 
     | 
    
         
            -
                      end
         
     | 
| 
       620 
     | 
    
         
            -
                    end
         
     | 
| 
      
 712 
     | 
    
         
            +
                    loops += 1 until IO.select([io_wrapper], nil, nil, 0.05)
         
     | 
| 
       621 
713 
     | 
    
         | 
| 
       622 
714 
     | 
    
         
             
                    # make sure we waited some period of time
         
     | 
| 
       623 
715 
     | 
    
         
             
                    expect(loops >= 1).to be true
         
     | 
| 
         @@ -629,15 +721,15 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       629 
721 
     | 
    
         | 
| 
       630 
722 
     | 
    
         
             
                context "Multiple results sets" do
         
     | 
| 
       631 
723 
     | 
    
         
             
                  before(:each) do
         
     | 
| 
       632 
     | 
    
         
            -
                    @multi_client =  
     | 
| 
      
 724 
     | 
    
         
            +
                    @multi_client = new_client(flags: Mysql2::Client::MULTI_STATEMENTS)
         
     | 
| 
       633 
725 
     | 
    
         
             
                  end
         
     | 
| 
       634 
726 
     | 
    
         | 
| 
       635 
727 
     | 
    
         
             
                  it "should raise an exception when one of multiple statements fails" do
         
     | 
| 
       636 
728 
     | 
    
         
             
                    result = @multi_client.query("SELECT 1 AS 'set_1'; SELECT * FROM invalid_table_name; SELECT 2 AS 'set_2';")
         
     | 
| 
       637 
729 
     | 
    
         
             
                    expect(result.first['set_1']).to be(1)
         
     | 
| 
       638 
     | 
    
         
            -
                    expect  
     | 
| 
      
 730 
     | 
    
         
            +
                    expect do
         
     | 
| 
       639 
731 
     | 
    
         
             
                      @multi_client.next_result
         
     | 
| 
       640 
     | 
    
         
            -
                     
     | 
| 
      
 732 
     | 
    
         
            +
                    end.to raise_error(Mysql2::Error)
         
     | 
| 
       641 
733 
     | 
    
         
             
                    expect(@multi_client.next_result).to be false
         
     | 
| 
       642 
734 
     | 
    
         
             
                  end
         
     | 
| 
       643 
735 
     | 
    
         | 
| 
         @@ -659,17 +751,17 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       659 
751 
     | 
    
         | 
| 
       660 
752 
     | 
    
         
             
                  it "will raise on query if there are outstanding results to read" do
         
     | 
| 
       661 
753 
     | 
    
         
             
                    @multi_client.query("SELECT 1; SELECT 2; SELECT 3")
         
     | 
| 
       662 
     | 
    
         
            -
                    expect  
     | 
| 
      
 754 
     | 
    
         
            +
                    expect do
         
     | 
| 
       663 
755 
     | 
    
         
             
                      @multi_client.query("SELECT 4")
         
     | 
| 
       664 
     | 
    
         
            -
                     
     | 
| 
      
 756 
     | 
    
         
            +
                    end.to raise_error(Mysql2::Error)
         
     | 
| 
       665 
757 
     | 
    
         
             
                  end
         
     | 
| 
       666 
758 
     | 
    
         | 
| 
       667 
759 
     | 
    
         
             
                  it "#abandon_results! should work" do
         
     | 
| 
       668 
760 
     | 
    
         
             
                    @multi_client.query("SELECT 1; SELECT 2; SELECT 3")
         
     | 
| 
       669 
761 
     | 
    
         
             
                    @multi_client.abandon_results!
         
     | 
| 
       670 
     | 
    
         
            -
                    expect  
     | 
| 
      
 762 
     | 
    
         
            +
                    expect do
         
     | 
| 
       671 
763 
     | 
    
         
             
                      @multi_client.query("SELECT 4")
         
     | 
| 
       672 
     | 
    
         
            -
                     
     | 
| 
      
 764 
     | 
    
         
            +
                    end.not_to raise_error
         
     | 
| 
       673 
765 
     | 
    
         
             
                  end
         
     | 
| 
       674 
766 
     | 
    
         | 
| 
       675 
767 
     | 
    
         
             
                  it "#more_results? should work" do
         
     | 
| 
         @@ -705,9 +797,9 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       705 
797 
     | 
    
         | 
| 
       706 
798 
     | 
    
         
             
              if RUBY_PLATFORM =~ /mingw|mswin/
         
     | 
| 
       707 
799 
     | 
    
         
             
                it "#socket should raise as it's not supported" do
         
     | 
| 
       708 
     | 
    
         
            -
                  expect  
     | 
| 
      
 800 
     | 
    
         
            +
                  expect do
         
     | 
| 
       709 
801 
     | 
    
         
             
                    @client.socket
         
     | 
| 
       710 
     | 
    
         
            -
                   
     | 
| 
      
 802 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
         
     | 
| 
       711 
803 
     | 
    
         
             
                end
         
     | 
| 
       712 
804 
     | 
    
         
             
              end
         
     | 
| 
       713 
805 
     | 
    
         | 
| 
         @@ -726,27 +818,25 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       726 
818 
     | 
    
         
             
                end
         
     | 
| 
       727 
819 
     | 
    
         | 
| 
       728 
820 
     | 
    
         
             
                it "should not overflow the thread stack" do
         
     | 
| 
       729 
     | 
    
         
            -
                  expect  
     | 
| 
      
 821 
     | 
    
         
            +
                  expect do
         
     | 
| 
       730 
822 
     | 
    
         
             
                    Thread.new { Mysql2::Client.escape("'" * 256 * 1024) }.join
         
     | 
| 
       731 
     | 
    
         
            -
                   
     | 
| 
      
 823 
     | 
    
         
            +
                  end.not_to raise_error
         
     | 
| 
       732 
824 
     | 
    
         
             
                end
         
     | 
| 
       733 
825 
     | 
    
         | 
| 
       734 
826 
     | 
    
         
             
                it "should not overflow the process stack" do
         
     | 
| 
       735 
     | 
    
         
            -
                  expect  
     | 
| 
      
 827 
     | 
    
         
            +
                  expect do
         
     | 
| 
       736 
828 
     | 
    
         
             
                    Thread.new { Mysql2::Client.escape("'" * 1024 * 1024 * 4) }.join
         
     | 
| 
       737 
     | 
    
         
            -
                   
     | 
| 
      
 829 
     | 
    
         
            +
                  end.not_to raise_error
         
     | 
| 
       738 
830 
     | 
    
         
             
                end
         
     | 
| 
       739 
831 
     | 
    
         | 
| 
       740 
     | 
    
         
            -
                 
     | 
| 
       741 
     | 
    
         
            -
                   
     | 
| 
       742 
     | 
    
         
            -
             
     | 
| 
       743 
     | 
    
         
            -
             
     | 
| 
       744 
     | 
    
         
            -
                    expect(escaped.encoding).to eql(str.encoding)
         
     | 
| 
      
 832 
     | 
    
         
            +
                it "should carry over the original string's encoding" do
         
     | 
| 
      
 833 
     | 
    
         
            +
                  str = "abc'def\"ghi\0jkl%mno"
         
     | 
| 
      
 834 
     | 
    
         
            +
                  escaped = Mysql2::Client.escape(str)
         
     | 
| 
      
 835 
     | 
    
         
            +
                  expect(escaped.encoding).to eql(str.encoding)
         
     | 
| 
       745 
836 
     | 
    
         | 
| 
       746 
     | 
    
         
            -
             
     | 
| 
       747 
     | 
    
         
            -
             
     | 
| 
       748 
     | 
    
         
            -
             
     | 
| 
       749 
     | 
    
         
            -
                  end
         
     | 
| 
      
 837 
     | 
    
         
            +
                  str.encode!('us-ascii')
         
     | 
| 
      
 838 
     | 
    
         
            +
                  escaped = Mysql2::Client.escape(str)
         
     | 
| 
      
 839 
     | 
    
         
            +
                  expect(escaped.encoding).to eql(str.encoding)
         
     | 
| 
       750 
840 
     | 
    
         
             
                end
         
     | 
| 
       751 
841 
     | 
    
         
             
              end
         
     | 
| 
       752 
842 
     | 
    
         | 
| 
         @@ -765,28 +855,26 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       765 
855 
     | 
    
         
             
                end
         
     | 
| 
       766 
856 
     | 
    
         | 
| 
       767 
857 
     | 
    
         
             
                it "should not overflow the thread stack" do
         
     | 
| 
       768 
     | 
    
         
            -
                  expect  
     | 
| 
      
 858 
     | 
    
         
            +
                  expect do
         
     | 
| 
       769 
859 
     | 
    
         
             
                    Thread.new { @client.escape("'" * 256 * 1024) }.join
         
     | 
| 
       770 
     | 
    
         
            -
                   
     | 
| 
      
 860 
     | 
    
         
            +
                  end.not_to raise_error
         
     | 
| 
       771 
861 
     | 
    
         
             
                end
         
     | 
| 
       772 
862 
     | 
    
         | 
| 
       773 
863 
     | 
    
         
             
                it "should not overflow the process stack" do
         
     | 
| 
       774 
     | 
    
         
            -
                  expect  
     | 
| 
      
 864 
     | 
    
         
            +
                  expect do
         
     | 
| 
       775 
865 
     | 
    
         
             
                    Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join
         
     | 
| 
       776 
     | 
    
         
            -
                   
     | 
| 
      
 866 
     | 
    
         
            +
                  end.not_to raise_error
         
     | 
| 
       777 
867 
     | 
    
         
             
                end
         
     | 
| 
       778 
868 
     | 
    
         | 
| 
       779 
869 
     | 
    
         
             
                it "should require an open connection" do
         
     | 
| 
       780 
870 
     | 
    
         
             
                  @client.close
         
     | 
| 
       781 
     | 
    
         
            -
                  expect  
     | 
| 
      
 871 
     | 
    
         
            +
                  expect do
         
     | 
| 
       782 
872 
     | 
    
         
             
                    @client.escape ""
         
     | 
| 
       783 
     | 
    
         
            -
                   
     | 
| 
      
 873 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error)
         
     | 
| 
       784 
874 
     | 
    
         
             
                end
         
     | 
| 
       785 
875 
     | 
    
         | 
| 
       786 
876 
     | 
    
         
             
                context 'when mysql encoding is not utf8' do
         
     | 
| 
       787 
     | 
    
         
            -
                   
     | 
| 
       788 
     | 
    
         
            -
             
     | 
| 
       789 
     | 
    
         
            -
                  let(:client) { Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "ujis")) }
         
     | 
| 
      
 877 
     | 
    
         
            +
                  let(:client) { new_client(encoding: "ujis") }
         
     | 
| 
       790 
878 
     | 
    
         | 
| 
       791 
879 
     | 
    
         
             
                  it 'should return a internal encoding string if Encoding.default_internal is set' do
         
     | 
| 
       792 
880 
     | 
    
         
             
                    with_internal_encoding Encoding::UTF_8 do
         
     | 
| 
         @@ -805,14 +893,12 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       805 
893 
     | 
    
         
             
                info = @client.info
         
     | 
| 
       806 
894 
     | 
    
         
             
                expect(info).to be_an_instance_of(Hash)
         
     | 
| 
       807 
895 
     | 
    
         
             
                expect(info).to have_key(:id)
         
     | 
| 
       808 
     | 
    
         
            -
                expect(info[:id]).to be_an_instance_of( 
     | 
| 
      
 896 
     | 
    
         
            +
                expect(info[:id]).to be_an_instance_of(0.class)
         
     | 
| 
       809 
897 
     | 
    
         
             
                expect(info).to have_key(:version)
         
     | 
| 
       810 
898 
     | 
    
         
             
                expect(info[:version]).to be_an_instance_of(String)
         
     | 
| 
       811 
899 
     | 
    
         
             
              end
         
     | 
| 
       812 
900 
     | 
    
         | 
| 
       813 
901 
     | 
    
         
             
              context "strings returned by #info" do
         
     | 
| 
       814 
     | 
    
         
            -
                before { pending('Encoding is undefined') unless defined?(Encoding) }
         
     | 
| 
       815 
     | 
    
         
            -
             
     | 
| 
       816 
902 
     | 
    
         
             
                it "should be tagged as ascii" do
         
     | 
| 
       817 
903 
     | 
    
         
             
                  expect(@client.info[:version].encoding).to eql(Encoding::US_ASCII)
         
     | 
| 
       818 
904 
     | 
    
         
             
                  expect(@client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
         
     | 
| 
         @@ -820,8 +906,6 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       820 
906 
     | 
    
         
             
              end
         
     | 
| 
       821 
907 
     | 
    
         | 
| 
       822 
908 
     | 
    
         
             
              context "strings returned by .info" do
         
     | 
| 
       823 
     | 
    
         
            -
                before { pending('Encoding is undefined') unless defined?(Encoding) }
         
     | 
| 
       824 
     | 
    
         
            -
             
     | 
| 
       825 
909 
     | 
    
         
             
                it "should be tagged as ascii" do
         
     | 
| 
       826 
910 
     | 
    
         
             
                  expect(Mysql2::Client.info[:version].encoding).to eql(Encoding::US_ASCII)
         
     | 
| 
       827 
911 
     | 
    
         
             
                  expect(Mysql2::Client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
         
     | 
| 
         @@ -836,26 +920,24 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       836 
920 
     | 
    
         
             
                server_info = @client.server_info
         
     | 
| 
       837 
921 
     | 
    
         
             
                expect(server_info).to be_an_instance_of(Hash)
         
     | 
| 
       838 
922 
     | 
    
         
             
                expect(server_info).to have_key(:id)
         
     | 
| 
       839 
     | 
    
         
            -
                expect(server_info[:id]).to be_an_instance_of( 
     | 
| 
      
 923 
     | 
    
         
            +
                expect(server_info[:id]).to be_an_instance_of(0.class)
         
     | 
| 
       840 
924 
     | 
    
         
             
                expect(server_info).to have_key(:version)
         
     | 
| 
       841 
925 
     | 
    
         
             
                expect(server_info[:version]).to be_an_instance_of(String)
         
     | 
| 
       842 
926 
     | 
    
         
             
              end
         
     | 
| 
       843 
927 
     | 
    
         | 
| 
       844 
928 
     | 
    
         
             
              it "#server_info should require an open connection" do
         
     | 
| 
       845 
929 
     | 
    
         
             
                @client.close
         
     | 
| 
       846 
     | 
    
         
            -
                expect  
     | 
| 
      
 930 
     | 
    
         
            +
                expect do
         
     | 
| 
       847 
931 
     | 
    
         
             
                  @client.server_info
         
     | 
| 
       848 
     | 
    
         
            -
                 
     | 
| 
      
 932 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error)
         
     | 
| 
       849 
933 
     | 
    
         
             
              end
         
     | 
| 
       850 
934 
     | 
    
         | 
| 
       851 
935 
     | 
    
         
             
              context "strings returned by #server_info" do
         
     | 
| 
       852 
     | 
    
         
            -
                before { pending('Encoding is undefined') unless defined?(Encoding) }
         
     | 
| 
       853 
     | 
    
         
            -
             
     | 
| 
       854 
936 
     | 
    
         
             
                it "should default to the connection's encoding if Encoding.default_internal is nil" do
         
     | 
| 
       855 
937 
     | 
    
         
             
                  with_internal_encoding nil do
         
     | 
| 
       856 
938 
     | 
    
         
             
                    expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8)
         
     | 
| 
       857 
939 
     | 
    
         | 
| 
       858 
     | 
    
         
            -
                    client2 =  
     | 
| 
      
 940 
     | 
    
         
            +
                    client2 = new_client(encoding: 'ascii')
         
     | 
| 
       859 
941 
     | 
    
         
             
                    expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII)
         
     | 
| 
       860 
942 
     | 
    
         
             
                  end
         
     | 
| 
       861 
943 
     | 
    
         
             
                end
         
     | 
| 
         @@ -871,14 +953,14 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       871 
953 
     | 
    
         
             
                end
         
     | 
| 
       872 
954 
     | 
    
         
             
              end
         
     | 
| 
       873 
955 
     | 
    
         | 
| 
       874 
     | 
    
         
            -
              it "should raise a Mysql2::Error exception upon connection failure" do
         
     | 
| 
       875 
     | 
    
         
            -
                expect  
     | 
| 
       876 
     | 
    
         
            -
                   
     | 
| 
       877 
     | 
    
         
            -
                 
     | 
| 
      
 956 
     | 
    
         
            +
              it "should raise a Mysql2::Error::ConnectionError exception upon connection failure due to invalid credentials" do
         
     | 
| 
      
 957 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 958 
     | 
    
         
            +
                  new_client(host: 'localhost', username: 'asdfasdf8d2h', password: 'asdfasdfw42')
         
     | 
| 
      
 959 
     | 
    
         
            +
                end.to raise_error(Mysql2::Error::ConnectionError)
         
     | 
| 
       878 
960 
     | 
    
         | 
| 
       879 
     | 
    
         
            -
                expect  
     | 
| 
       880 
     | 
    
         
            -
                   
     | 
| 
       881 
     | 
    
         
            -
                 
     | 
| 
      
 961 
     | 
    
         
            +
                expect do
         
     | 
| 
      
 962 
     | 
    
         
            +
                  new_client(DatabaseCredentials['root'])
         
     | 
| 
      
 963 
     | 
    
         
            +
                end.not_to raise_error
         
     | 
| 
       882 
964 
     | 
    
         
             
              end
         
     | 
| 
       883 
965 
     | 
    
         | 
| 
       884 
966 
     | 
    
         
             
              context 'write operations api' do
         
     | 
| 
         @@ -927,7 +1009,7 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       927 
1009 
     | 
    
         
             
              end
         
     | 
| 
       928 
1010 
     | 
    
         | 
| 
       929 
1011 
     | 
    
         
             
              it "#thread_id should be a Fixnum" do
         
     | 
| 
       930 
     | 
    
         
            -
                expect(@client.thread_id).to be_an_instance_of( 
     | 
| 
      
 1012 
     | 
    
         
            +
                expect(@client.thread_id).to be_an_instance_of(0.class)
         
     | 
| 
       931 
1013 
     | 
    
         
             
              end
         
     | 
| 
       932 
1014 
     | 
    
         | 
| 
       933 
1015 
     | 
    
         
             
              it "should respond to #ping" do
         
     | 
| 
         @@ -963,9 +1045,9 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       963 
1045 
     | 
    
         
             
                end
         
     | 
| 
       964 
1046 
     | 
    
         | 
| 
       965 
1047 
     | 
    
         
             
                it "should raise a Mysql2::Error when the database doesn't exist" do
         
     | 
| 
       966 
     | 
    
         
            -
                  expect  
     | 
| 
      
 1048 
     | 
    
         
            +
                  expect do
         
     | 
| 
       967 
1049 
     | 
    
         
             
                    @client.select_db("nopenothere")
         
     | 
| 
       968 
     | 
    
         
            -
                   
     | 
| 
      
 1050 
     | 
    
         
            +
                  end.to raise_error(Mysql2::Error)
         
     | 
| 
       969 
1051 
     | 
    
         
             
                end
         
     | 
| 
       970 
1052 
     | 
    
         | 
| 
       971 
1053 
     | 
    
         
             
                it "should return the database switched to" do
         
     | 
| 
         @@ -979,9 +1061,12 @@ RSpec.describe Mysql2::Client do 
     | 
|
| 
       979 
1061 
     | 
    
         
             
                expect(@client.ping).to eql(false)
         
     | 
| 
       980 
1062 
     | 
    
         
             
              end
         
     | 
| 
       981 
1063 
     | 
    
         | 
| 
       982 
     | 
    
         
            -
               
     | 
| 
       983 
     | 
    
         
            -
                 
     | 
| 
       984 
     | 
    
         
            -
             
     | 
| 
       985 
     | 
    
         
            -
             
     | 
| 
      
 1064 
     | 
    
         
            +
              it "should be able to connect using plaintext password" do
         
     | 
| 
      
 1065 
     | 
    
         
            +
                client = new_client(enable_cleartext_plugin: true)
         
     | 
| 
      
 1066 
     | 
    
         
            +
                client.query('SELECT 1')
         
     | 
| 
      
 1067 
     | 
    
         
            +
              end
         
     | 
| 
      
 1068 
     | 
    
         
            +
             
     | 
| 
      
 1069 
     | 
    
         
            +
              it "should respond to #encoding" do
         
     | 
| 
      
 1070 
     | 
    
         
            +
                expect(@client).to respond_to(:encoding)
         
     | 
| 
       986 
1071 
     | 
    
         
             
              end
         
     | 
| 
       987 
1072 
     | 
    
         
             
            end
         
     |