mysql2 0.4.10 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,22 +4,22 @@ module Mysql2
4
4
 
5
5
  def self.default_query_options
6
6
  @default_query_options ||= {
7
- :as => :hash, # the type of object you want each row back as; also supports :array (an array of values)
8
- :async => false, # don't wait for a result after sending the query, you'll have to monitor the socket yourself then eventually call Mysql2::Client#async_result
9
- :cast_booleans => false, # cast tinyint(1) fields as true/false in ruby
10
- :symbolize_keys => false, # return field names as symbols instead of strings
11
- :database_timezone => :local, # timezone Mysql2 will assume datetime objects are stored in
12
- :application_timezone => nil, # timezone Mysql2 will convert to before handing the object back to the caller
13
- :cache_rows => true, # tells Mysql2 to use its internal row cache for results
14
- :connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION,
15
- :cast => true,
16
- :default_file => nil,
17
- :default_group => nil,
7
+ as: :hash, # the type of object you want each row back as; also supports :array (an array of values)
8
+ async: false, # don't wait for a result after sending the query, you'll have to monitor the socket yourself then eventually call Mysql2::Client#async_result
9
+ cast_booleans: false, # cast tinyint(1) fields as true/false in ruby
10
+ symbolize_keys: false, # return field names as symbols instead of strings
11
+ database_timezone: :local, # timezone Mysql2 will assume datetime objects are stored in
12
+ application_timezone: nil, # timezone Mysql2 will convert to before handing the object back to the caller
13
+ cache_rows: true, # tells Mysql2 to use its internal row cache for results
14
+ connect_flags: REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION | CONNECT_ATTRS,
15
+ cast: true,
16
+ default_file: nil,
17
+ default_group: nil,
18
18
  }
19
19
  end
20
20
 
21
21
  def initialize(opts = {})
22
- fail Mysql2::Error, "Options parameter must be a Hash" unless opts.is_a? Hash
22
+ raise Mysql2::Error, "Options parameter must be a Hash" unless opts.is_a? Hash
23
23
  opts = Mysql2::Util.key_hash_as_symbols(opts)
24
24
  @read_timeout = nil
25
25
  @query_options = self.class.default_query_options.dup
@@ -31,7 +31,7 @@ module Mysql2
31
31
  opts[:connect_timeout] = 120 unless opts.key?(:connect_timeout)
32
32
 
33
33
  # TODO: stricter validation rather than silent massaging
34
- [:reconnect, :connect_timeout, :local_infile, :read_timeout, :write_timeout, :default_file, :default_group, :secure_auth, :init_command, :automatic_close, :enable_cleartext_plugin].each do |key|
34
+ %i[reconnect connect_timeout local_infile read_timeout write_timeout default_file default_group secure_auth init_command automatic_close enable_cleartext_plugin].each do |key|
35
35
  next unless opts.key?(key)
36
36
  case key
37
37
  when :reconnect, :local_infile, :secure_auth, :automatic_close, :enable_cleartext_plugin
@@ -50,21 +50,21 @@ module Mysql2
50
50
  ssl_set(*ssl_options) if ssl_options.any? || opts.key?(:sslverify)
51
51
  self.ssl_mode = parse_ssl_mode(opts[:ssl_mode]) if opts[:ssl_mode]
52
52
 
53
- case opts[:flags]
53
+ flags = case opts[:flags]
54
54
  when Array
55
- flags = parse_flags_array(opts[:flags], @query_options[:connect_flags])
55
+ parse_flags_array(opts[:flags], @query_options[:connect_flags])
56
56
  when String
57
- flags = parse_flags_array(opts[:flags].split(' '), @query_options[:connect_flags])
57
+ parse_flags_array(opts[:flags].split(' '), @query_options[:connect_flags])
58
58
  when Integer
59
- flags = @query_options[:connect_flags] | opts[:flags]
59
+ @query_options[:connect_flags] | opts[:flags]
60
60
  else
61
- flags = @query_options[:connect_flags]
61
+ @query_options[:connect_flags]
62
62
  end
63
63
 
64
64
  # SSL verify is a connection flag rather than a mysql_ssl_set option
65
65
  flags |= SSL_VERIFY_SERVER_CERT if opts[:sslverify]
66
66
 
67
- if [:user, :pass, :hostname, :dbname, :db, :sock].any? { |k| @query_options.key?(k) }
67
+ if %i[user pass hostname dbname db sock].any? { |k| @query_options.key?(k) }
68
68
  warn "============= WARNING FROM mysql2 ============="
69
69
  warn "The options :user, :pass, :hostname, :dbname, :db, and :sock are deprecated and will be removed at some point in the future."
70
70
  warn "Instead, please use :username, :password, :host, :port, :database, :socket, :flags for the options."
@@ -85,8 +85,9 @@ module Mysql2
85
85
  port = port.to_i unless port.nil?
86
86
  database = database.to_s unless database.nil?
87
87
  socket = socket.to_s unless socket.nil?
88
+ conn_attrs = parse_connect_attrs(opts[:connect_attrs])
88
89
 
89
- connect user, pass, host, port, database, socket, flags
90
+ connect user, pass, host, port, database, socket, flags, conn_attrs
90
91
  end
91
92
 
92
93
  def parse_ssl_mode(mode)
@@ -114,14 +115,19 @@ module Mysql2
114
115
  end
115
116
  end
116
117
 
117
- if Thread.respond_to?(:handle_interrupt)
118
- def query(sql, options = {})
119
- Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
120
- _query(sql, @query_options.merge(options))
121
- end
118
+ # Set default program_name in performance_schema.session_connect_attrs
119
+ # and performance_schema.session_account_connect_attrs
120
+ def parse_connect_attrs(conn_attrs)
121
+ return {} if Mysql2::Client::CONNECT_ATTRS.zero?
122
+ conn_attrs ||= {}
123
+ conn_attrs[:program_name] ||= $PROGRAM_NAME
124
+ conn_attrs.each_with_object({}) do |(key, value), hash|
125
+ hash[key.to_s] = value.to_s
122
126
  end
123
- else
124
- def query(sql, options = {})
127
+ end
128
+
129
+ def query(sql, options = {})
130
+ Thread.handle_interrupt(::Mysql2::Util::TIMEOUT_ERROR_CLASS => :never) do
125
131
  _query(sql, @query_options.merge(options))
126
132
  end
127
133
  end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'eventmachine'
4
2
  require 'mysql2'
5
3
 
@@ -17,7 +15,7 @@ module Mysql2
17
15
  detach
18
16
  begin
19
17
  result = @client.async_result
20
- rescue => e
18
+ rescue StandardError => e
21
19
  @deferable.fail(e)
22
20
  else
23
21
  @deferable.succeed(result)
@@ -41,7 +39,7 @@ module Mysql2
41
39
 
42
40
  def query(sql, opts = {})
43
41
  if ::EM.reactor_running?
44
- super(sql, opts.merge(:async => true))
42
+ super(sql, opts.merge(async: true))
45
43
  deferable = ::EM::DefaultDeferrable.new
46
44
  @watch = ::EM.watch(socket, Watcher, self, deferable)
47
45
  @watch.notify_readable = true
@@ -1,32 +1,65 @@
1
- # encoding: UTF-8
2
-
3
1
  module Mysql2
4
2
  class Error < StandardError
5
3
  ENCODE_OPTS = {
6
- :undef => :replace,
7
- :invalid => :replace,
8
- :replace => '?'.freeze,
4
+ undef: :replace,
5
+ invalid: :replace,
6
+ replace: '?'.freeze,
7
+ }.freeze
8
+
9
+ ConnectionError = Class.new(Error)
10
+ TimeoutError = Class.new(Error)
11
+
12
+ CODES = {
13
+ 1205 => TimeoutError, # ER_LOCK_WAIT_TIMEOUT
14
+
15
+ 1044 => ConnectionError, # ER_DBACCESS_DENIED_ERROR
16
+ 1045 => ConnectionError, # ER_ACCESS_DENIED_ERROR
17
+ 1152 => ConnectionError, # ER_ABORTING_CONNECTION
18
+ 1153 => ConnectionError, # ER_NET_PACKET_TOO_LARGE
19
+ 1154 => ConnectionError, # ER_NET_READ_ERROR_FROM_PIPE
20
+ 1155 => ConnectionError, # ER_NET_FCNTL_ERROR
21
+ 1156 => ConnectionError, # ER_NET_PACKETS_OUT_OF_ORDER
22
+ 1157 => ConnectionError, # ER_NET_UNCOMPRESS_ERROR
23
+ 1158 => ConnectionError, # ER_NET_READ_ERROR
24
+ 1159 => ConnectionError, # ER_NET_READ_INTERRUPTED
25
+ 1160 => ConnectionError, # ER_NET_ERROR_ON_WRITE
26
+ 1161 => ConnectionError, # ER_NET_WRITE_INTERRUPTED
27
+
28
+ 2001 => ConnectionError, # CR_SOCKET_CREATE_ERROR
29
+ 2002 => ConnectionError, # CR_CONNECTION_ERROR
30
+ 2003 => ConnectionError, # CR_CONN_HOST_ERROR
31
+ 2004 => ConnectionError, # CR_IPSOCK_ERROR
32
+ 2005 => ConnectionError, # CR_UNKNOWN_HOST
33
+ 2006 => ConnectionError, # CR_SERVER_GONE_ERROR
34
+ 2007 => ConnectionError, # CR_VERSION_ERROR
35
+ 2009 => ConnectionError, # CR_WRONG_HOST_INFO
36
+ 2012 => ConnectionError, # CR_SERVER_HANDSHAKE_ERR
37
+ 2013 => ConnectionError, # CR_SERVER_LOST
38
+ 2020 => ConnectionError, # CR_NET_PACKET_TOO_LARGE
39
+ 2026 => ConnectionError, # CR_SSL_CONNECTION_ERROR
40
+ 2027 => ConnectionError, # CR_MALFORMED_PACKET
41
+ 2047 => ConnectionError, # CR_CONN_UNKNOW_PROTOCOL
42
+ 2048 => ConnectionError, # CR_INVALID_CONN_HANDLE
43
+ 2049 => ConnectionError, # CR_UNUSED_1
9
44
  }.freeze
10
45
 
11
46
  attr_reader :error_number, :sql_state
12
47
 
13
48
  # Mysql gem compatibility
14
- alias_method :errno, :error_number
15
- alias_method :error, :message
49
+ alias errno error_number
50
+ alias error message
16
51
 
17
- def initialize(msg)
18
- @server_version ||= nil
52
+ def initialize(msg, server_version = nil, error_number = nil, sql_state = nil)
53
+ @server_version = server_version
54
+ @error_number = error_number
55
+ @sql_state = sql_state ? sql_state.encode(ENCODE_OPTS) : nil
19
56
 
20
57
  super(clean_message(msg))
21
58
  end
22
59
 
23
60
  def self.new_with_args(msg, server_version, error_number, sql_state)
24
- err = allocate
25
- err.instance_variable_set('@server_version', server_version)
26
- err.instance_variable_set('@error_number', error_number)
27
- err.instance_variable_set('@sql_state', sql_state.respond_to?(:encode) ? sql_state.encode(ENCODE_OPTS) : sql_state)
28
- err.send(:initialize, msg)
29
- err
61
+ error_class = CODES.fetch(error_number, self)
62
+ error_class.new(msg, server_version, error_number, sql_state)
30
63
  end
31
64
 
32
65
  private
@@ -55,12 +88,8 @@ module Mysql2
55
88
  # encoding, we'll assume UTF-8 and clean the string of anything that's not a
56
89
  # valid UTF-8 character.
57
90
  #
58
- # Except for if we're on 1.8, where we'll do nothing ;)
59
- #
60
- # Returns a valid UTF-8 string in Ruby 1.9+, the original string on Ruby 1.8
91
+ # Returns a valid UTF-8 string.
61
92
  def clean_message(message)
62
- return message unless message.respond_to?(:encode)
63
-
64
93
  if @server_version && @server_version > 50500
65
94
  message.encode(ENCODE_OPTS)
66
95
  else
@@ -1,5 +1,7 @@
1
1
  module Mysql2
2
2
  class Result
3
+ attr_reader :server_flags
4
+
3
5
  include Enumerable
4
6
  end
5
7
  end
@@ -2,15 +2,9 @@ module Mysql2
2
2
  class Statement
3
3
  include Enumerable
4
4
 
5
- if Thread.respond_to?(:handle_interrupt)
6
- def execute(*args)
7
- Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
8
- _execute(*args)
9
- end
10
- end
11
- else
12
- def execute(*args)
13
- _execute(*args)
5
+ def execute(*args, **kwargs)
6
+ Thread.handle_interrupt(::Mysql2::Util::TIMEOUT_ERROR_CLASS => :never) do
7
+ _execute(*args, **kwargs)
14
8
  end
15
9
  end
16
10
  end
@@ -1,3 +1,3 @@
1
1
  module Mysql2
2
- VERSION = "0.4.10"
2
+ VERSION = "0.5.1".freeze
3
3
  end
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  require 'spec_helper'
3
2
  begin
4
3
  require 'eventmachine'
@@ -49,13 +48,13 @@ begin
49
48
  end
50
49
 
51
50
  it "should not swallow exceptions raised in callbacks" do
52
- expect {
51
+ expect do
53
52
  EM.run do
54
53
  client = Mysql2::EM::Client.new DatabaseCredentials['root']
55
54
  defer = client.query "SELECT sleep(0.1) as first_query"
56
55
  defer.callback do
57
56
  client.close
58
- fail 'some error'
57
+ raise 'some error'
59
58
  end
60
59
  defer.errback do
61
60
  # This _shouldn't_ be run, but it needed to prevent the specs from
@@ -63,7 +62,7 @@ begin
63
62
  EM.stop_event_loop
64
63
  end
65
64
  end
66
- }.to raise_error('some error')
65
+ end.to raise_error('some error')
67
66
  end
68
67
 
69
68
  context 'when an exception is raised by the client' do
@@ -123,9 +122,9 @@ begin
123
122
  end
124
123
  EM.add_timer(0.1) do
125
124
  expect(callbacks_run).to eq([:callback])
126
- expect {
125
+ expect do
127
126
  client.close
128
- }.not_to raise_error
127
+ end.not_to raise_error
129
128
  EM.stop_event_loop
130
129
  end
131
130
  end
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  require 'spec_helper'
3
2
 
4
3
  RSpec.describe Mysql2::Client do
@@ -6,46 +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
- new_client(:default_file => cnf_file, :default_group => "test")
11
- }.not_to raise_error
8
+ expect do
9
+ new_client(default_file: cnf_file, default_group: "test")
10
+ end.not_to raise_error
12
11
  end
13
12
 
14
13
  it "should not raise an exception without default group" do
15
- expect {
16
- new_client(:default_file => cnf_file)
17
- }.not_to raise_error
14
+ expect do
15
+ new_client(default_file: cnf_file)
16
+ end.not_to raise_error
18
17
  end
19
18
  end
20
19
 
21
- it "should raise an exception upon connection failure" do
22
- expect {
20
+ it "should raise a Mysql::Error::ConnectionError upon connection failure" do
21
+ expect do
23
22
  # The odd local host IP address forces the mysql client library to
24
23
  # use a TCP socket rather than a domain socket.
25
24
  new_client('host' => '127.0.0.2', 'port' => 999999)
26
- }.to raise_error(Mysql2::Error)
25
+ end.to raise_error(Mysql2::Error::ConnectionError)
27
26
  end
28
27
 
29
28
  it "should raise an exception on create for invalid encodings" do
30
- expect {
31
- new_client(:encoding => "fake")
32
- }.to raise_error(Mysql2::Error)
29
+ expect do
30
+ new_client(encoding: "fake")
31
+ end.to raise_error(Mysql2::Error)
33
32
  end
34
33
 
35
34
  it "should raise an exception on non-string encodings" do
36
- expect {
37
- new_client(:encoding => :fake)
38
- }.to raise_error(TypeError)
35
+ expect do
36
+ new_client(encoding: :fake)
37
+ end.to raise_error(TypeError)
39
38
  end
40
39
 
41
40
  it "should not raise an exception on create for a valid encoding" do
42
- expect {
43
- new_client(:encoding => "utf8")
44
- }.not_to raise_error
41
+ expect do
42
+ new_client(encoding: "utf8")
43
+ end.not_to raise_error
45
44
 
46
- expect {
47
- new_client(DatabaseCredentials['root'].merge(:encoding => "big5"))
48
- }.not_to raise_error
45
+ expect do
46
+ new_client(DatabaseCredentials['root'].merge(encoding: "big5"))
47
+ end.not_to raise_error
49
48
  end
50
49
 
51
50
  Klient = Class.new(Mysql2::Client) do
@@ -57,18 +56,18 @@ RSpec.describe Mysql2::Client do
57
56
  end
58
57
 
59
58
  it "should accept connect flags and pass them to #connect" do
60
- client = Klient.new :flags => Mysql2::Client::FOUND_ROWS
59
+ client = Klient.new flags: Mysql2::Client::FOUND_ROWS
61
60
  expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0
62
61
  end
63
62
 
64
63
  it "should parse flags array" do
65
- client = Klient.new :flags => %w( FOUND_ROWS -PROTOCOL_41 )
64
+ client = Klient.new flags: %w[FOUND_ROWS -PROTOCOL_41]
66
65
  expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
67
66
  expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
68
67
  end
69
68
 
70
69
  it "should parse flags string" do
71
- client = Klient.new :flags => "FOUND_ROWS -PROTOCOL_41"
70
+ client = Klient.new flags: "FOUND_ROWS -PROTOCOL_41"
72
71
  expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS)
73
72
  expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0)
74
73
  end
@@ -80,7 +79,8 @@ RSpec.describe Mysql2::Client do
80
79
  Mysql2::Client::LONG_FLAG |
81
80
  Mysql2::Client::TRANSACTIONS |
82
81
  Mysql2::Client::PROTOCOL_41 |
83
- Mysql2::Client::SECURE_CONNECTION
82
+ Mysql2::Client::SECURE_CONNECTION |
83
+ Mysql2::Client::CONNECT_ATTRS
84
84
  expect(client.connect_args.last[6]).to eql(client_flags)
85
85
  end
86
86
 
@@ -135,18 +135,16 @@ RSpec.describe Mysql2::Client do
135
135
 
136
136
  # You may need to adjust the lines below to match your SSL certificate paths
137
137
  ssl_client = nil
138
- expect {
139
- # rubocop:disable Style/TrailingComma
138
+ expect do
140
139
  ssl_client = new_client(
141
140
  'host' => 'mysql2gem.example.com', # must match the certificates
142
141
  :sslkey => '/etc/mysql/client-key.pem',
143
142
  :sslcert => '/etc/mysql/client-cert.pem',
144
143
  :sslca => '/etc/mysql/ca-cert.pem',
145
144
  :sslcipher => 'DHE-RSA-AES256-SHA',
146
- :sslverify => true
145
+ :sslverify => true,
147
146
  )
148
- # rubocop:enable Style/TrailingComma
149
- }.not_to raise_error
147
+ end.not_to raise_error
150
148
 
151
149
  results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
152
150
  expect(results['Ssl_cipher']).not_to be_empty
@@ -166,7 +164,8 @@ RSpec.describe Mysql2::Client do
166
164
  end
167
165
 
168
166
  it "should terminate connections when calling close" do
169
- expect {
167
+ # rubocop:disable Lint/AmbiguousBlockAssociation
168
+ expect do
170
169
  client = Mysql2::Client.new(DatabaseCredentials['root'])
171
170
  connection_id = client.thread_id
172
171
  client.close
@@ -180,27 +179,64 @@ RSpec.describe Mysql2::Client do
180
179
  sleep(0.1)
181
180
  end
182
181
  expect(closed).to eq(true)
183
- }.to_not change {
182
+ end.to_not change {
184
183
  @client.query("SHOW STATUS LIKE 'Aborted_%'").to_a
185
184
  }
185
+ # rubocop:enable Lint/AmbiguousBlockAssociation
186
186
  end
187
187
 
188
188
  it "should not leave dangling connections after garbage collection" do
189
189
  run_gc
190
- expect {
191
- expect {
190
+ # rubocop:disable Lint/AmbiguousBlockAssociation
191
+ expect do
192
+ expect do
192
193
  10.times do
193
194
  Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1')
194
195
  end
195
- }.to change {
196
+ end.to change {
196
197
  @client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
197
198
  }.by(10)
198
199
 
199
200
  run_gc
200
- }.to_not change {
201
+ end.to_not change {
201
202
  @client.query("SHOW STATUS LIKE 'Aborted_%'").to_a +
202
203
  @client.query("SHOW STATUS LIKE 'Threads_connected'").to_a
203
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
204
240
  end
205
241
 
206
242
  context "#automatic_close" do
@@ -211,24 +247,24 @@ RSpec.describe Mysql2::Client do
211
247
  if RUBY_PLATFORM =~ /mingw|mswin/
212
248
  it "cannot be disabled" do
213
249
  expect do
214
- client = new_client(:automatic_close => false)
250
+ client = new_client(automatic_close: false)
215
251
  expect(client.automatic_close?).to be(true)
216
252
  end.to output(/always closed by garbage collector/).to_stderr
217
253
 
218
254
  expect do
219
- client = new_client(:automatic_close => true)
255
+ client = new_client(automatic_close: true)
220
256
  expect(client.automatic_close?).to be(true)
221
257
  end.to_not output(/always closed by garbage collector/).to_stderr
222
258
 
223
259
  expect do
224
- client = new_client(:automatic_close => true)
260
+ client = new_client(automatic_close: true)
225
261
  client.automatic_close = false
226
262
  expect(client.automatic_close?).to be(true)
227
263
  end.to output(/always closed by garbage collector/).to_stderr
228
264
  end
229
265
  else
230
266
  it "can be configured" do
231
- client = new_client(:automatic_close => false)
267
+ client = new_client(automatic_close: false)
232
268
  expect(client.automatic_close?).to be(false)
233
269
  end
234
270
 
@@ -272,9 +308,9 @@ RSpec.describe Mysql2::Client do
272
308
  database = 1235
273
309
  @client.query "CREATE DATABASE IF NOT EXISTS `#{database}`"
274
310
 
275
- expect {
311
+ expect do
276
312
  new_client('database' => database)
277
- }.not_to raise_error
313
+ end.not_to raise_error
278
314
 
279
315
  @client.query "DROP DATABASE IF EXISTS `#{database}`"
280
316
  end
@@ -285,9 +321,9 @@ RSpec.describe Mysql2::Client do
285
321
 
286
322
  it "should be able to close properly" do
287
323
  expect(@client.close).to be_nil
288
- expect {
324
+ expect do
289
325
  @client.query "SELECT 1"
290
- }.to raise_error(Mysql2::Error)
326
+ end.to raise_error(Mysql2::Error)
291
327
  end
292
328
 
293
329
  context "#closed?" do
@@ -302,11 +338,11 @@ RSpec.describe Mysql2::Client do
302
338
  end
303
339
 
304
340
  it "should not try to query closed mysql connection" do
305
- client = new_client(:reconnect => true)
341
+ client = new_client(reconnect: true)
306
342
  expect(client.close).to be_nil
307
- expect {
343
+ expect do
308
344
  client.query "SELECT 1"
309
- }.to raise_error(Mysql2::Error)
345
+ end.to raise_error(Mysql2::Error)
310
346
  end
311
347
 
312
348
  it "should respond to #query" do
@@ -355,7 +391,7 @@ RSpec.describe Mysql2::Client do
355
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).
356
392
  @client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
357
393
 
358
- expect(@client.query_info).to eql(:records => 2, :duplicates => 0, :warnings => 0)
394
+ expect(@client.query_info).to eql(records: 2, duplicates: 0, warnings: 0)
359
395
  expect(@client.query_info_string).to eq('Records: 2 Duplicates: 0 Warnings: 0')
360
396
 
361
397
  @client.query "DROP TABLE infoTest"
@@ -365,7 +401,7 @@ RSpec.describe Mysql2::Client do
365
401
 
366
402
  context ":local_infile" do
367
403
  before(:all) do
368
- new_client(:local_infile => true) do |client|
404
+ new_client(local_infile: true) do |client|
369
405
  local = client.query "SHOW VARIABLES LIKE 'local_infile'"
370
406
  local_enabled = local.any? { |x| x['Value'] == 'ON' }
371
407
  skip("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled
@@ -387,24 +423,24 @@ RSpec.describe Mysql2::Client do
387
423
  end
388
424
 
389
425
  it "should raise an error when local_infile is disabled" do
390
- client = new_client(:local_infile => false)
391
- expect {
426
+ client = new_client(local_infile: false)
427
+ expect do
392
428
  client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
393
- }.to raise_error(Mysql2::Error, /command is not allowed/)
429
+ end.to raise_error(Mysql2::Error, /command is not allowed/)
394
430
  end
395
431
 
396
432
  it "should raise an error when a non-existent file is loaded" do
397
- client = new_client(:local_infile => true)
398
- expect {
433
+ client = new_client(local_infile: true)
434
+ expect do
399
435
  client.query "LOAD DATA LOCAL INFILE 'this/file/is/not/here' INTO TABLE infileTest"
400
- }.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here')
436
+ end.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here')
401
437
  end
402
438
 
403
439
  it "should LOAD DATA LOCAL INFILE" do
404
- client = new_client(:local_infile => true)
440
+ client = new_client(local_infile: true)
405
441
  client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
406
442
  info = client.query_info
407
- expect(info).to eql(:records => 1, :deleted => 0, :skipped => 0, :warnings => 0)
443
+ expect(info).to eql(records: 1, deleted: 0, skipped: 0, warnings: 0)
408
444
 
409
445
  result = client.query "SELECT * FROM infileTest"
410
446
  expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World')
@@ -412,57 +448,77 @@ RSpec.describe Mysql2::Client do
412
448
  end
413
449
 
414
450
  it "should expect connect_timeout to be a positive integer" do
415
- expect {
416
- new_client(:connect_timeout => -1)
417
- }.to raise_error(Mysql2::Error)
451
+ expect do
452
+ new_client(connect_timeout: -1)
453
+ end.to raise_error(Mysql2::Error)
418
454
  end
419
455
 
420
456
  it "should expect read_timeout to be a positive integer" do
421
- expect {
422
- new_client(:read_timeout => -1)
423
- }.to raise_error(Mysql2::Error)
457
+ expect do
458
+ new_client(read_timeout: -1)
459
+ end.to raise_error(Mysql2::Error)
424
460
  end
425
461
 
426
462
  it "should expect write_timeout to be a positive integer" do
427
- expect {
428
- new_client(:write_timeout => -1)
429
- }.to raise_error(Mysql2::Error)
463
+ expect do
464
+ new_client(write_timeout: -1)
465
+ end.to raise_error(Mysql2::Error)
430
466
  end
431
467
 
432
468
  it "should allow nil read_timeout" do
433
- client = new_client(:read_timeout => nil)
469
+ client = new_client(read_timeout: nil)
434
470
 
435
471
  expect(client.read_timeout).to be_nil
436
472
  end
437
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
+
438
494
  context "#query" do
439
495
  it "should let you query again if iterating is finished when streaming" do
440
- @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false).each.to_a
496
+ @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).each.to_a
441
497
 
442
- expect {
443
- @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false)
444
- }.to_not raise_error
498
+ expect do
499
+ @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
500
+ end.to_not raise_error
445
501
  end
446
502
 
447
503
  it "should not let you query again if iterating is not finished when streaming" do
448
- @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false).first
504
+ @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).first
449
505
 
450
- expect {
451
- @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false)
452
- }.to raise_exception(Mysql2::Error)
506
+ expect do
507
+ @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false)
508
+ end.to raise_exception(Mysql2::Error)
453
509
  end
454
510
 
455
511
  it "should only accept strings as the query parameter" do
456
- expect {
512
+ expect do
457
513
  @client.query ["SELECT 'not right'"]
458
- }.to raise_error(TypeError)
514
+ end.to raise_error(TypeError)
459
515
  end
460
516
 
461
517
  it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do
462
- result = @client.query "SELECT 1", :something => :else
518
+ result = @client.query "SELECT 1", something: :else
463
519
  expect(@client.query_options[:something]).to be_nil
464
- expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(:something => :else))
465
- expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(:something => :else))
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))
466
522
 
467
523
  result = @client.query "SELECT 1"
468
524
  expect(result.instance_variable_get('@query_options')).to eql(@client.query_options)
@@ -470,7 +526,7 @@ RSpec.describe Mysql2::Client do
470
526
  end
471
527
 
472
528
  it "should allow changing query options for subsequent queries" do
473
- @client.query_options.merge!(:something => :else)
529
+ @client.query_options[:something] = :else
474
530
  result = @client.query "SELECT 1"
475
531
  expect(@client.query_options[:something]).to eql(:else)
476
532
  expect(result.instance_variable_get('@query_options')[:something]).to eql(:else)
@@ -485,19 +541,19 @@ RSpec.describe Mysql2::Client do
485
541
  end
486
542
 
487
543
  it "should be able to return results as an array" do
488
- expect(@client.query("SELECT 1", :as => :array).first).to be_an_instance_of(Array)
489
- @client.query("SELECT 1").each(:as => :array)
544
+ expect(@client.query("SELECT 1", as: :array).first).to be_an_instance_of(Array)
545
+ @client.query("SELECT 1").each(as: :array)
490
546
  end
491
547
 
492
548
  it "should be able to return results with symbolized keys" do
493
- expect(@client.query("SELECT 1", :symbolize_keys => true).first.keys[0]).to be_an_instance_of(Symbol)
549
+ expect(@client.query("SELECT 1", symbolize_keys: true).first.keys[0]).to be_an_instance_of(Symbol)
494
550
  end
495
551
 
496
552
  it "should require an open connection" do
497
553
  @client.close
498
- expect {
554
+ expect do
499
555
  @client.query "SELECT 1"
500
- }.to raise_error(Mysql2::Error)
556
+ end.to raise_error(Mysql2::Error)
501
557
  end
502
558
 
503
559
  it "should detect closed connection on query read error" do
@@ -508,37 +564,37 @@ RSpec.describe Mysql2::Client do
508
564
  supervisor.query("KILL #{connection_id}")
509
565
  end.close
510
566
  end
511
- expect {
567
+ expect do
512
568
  @client.query("SELECT SLEEP(1)")
513
- }.to raise_error(Mysql2::Error, /Lost connection to MySQL server/)
569
+ end.to raise_error(Mysql2::Error, /Lost connection to MySQL server/)
514
570
 
515
571
  if RUBY_PLATFORM !~ /mingw|mswin/
516
- expect {
572
+ expect do
517
573
  @client.socket
518
- }.to raise_error(Mysql2::Error, 'MySQL client is not connected')
574
+ end.to raise_error(Mysql2::Error, 'MySQL client is not connected')
519
575
  end
520
576
  end
521
577
 
522
578
  if RUBY_PLATFORM !~ /mingw|mswin/
523
579
  it "should not allow another query to be sent without fetching a result first" do
524
- @client.query("SELECT 1", :async => true)
525
- expect {
580
+ @client.query("SELECT 1", async: true)
581
+ expect do
526
582
  @client.query("SELECT 1")
527
- }.to raise_error(Mysql2::Error)
583
+ end.to raise_error(Mysql2::Error)
528
584
  end
529
585
 
530
586
  it "should describe the thread holding the active query" do
531
- thr = Thread.new { @client.query("SELECT 1", :async => true) }
587
+ thr = Thread.new { @client.query("SELECT 1", async: true) }
532
588
 
533
589
  thr.join
534
590
  expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, Regexp.new(Regexp.escape(thr.inspect)))
535
591
  end
536
592
 
537
593
  it "should timeout if we wait longer than :read_timeout" do
538
- client = new_client(:read_timeout => 0)
539
- expect {
594
+ client = new_client(read_timeout: 0)
595
+ expect do
540
596
  client.query('SELECT SLEEP(0.1)')
541
- }.to raise_error(Mysql2::Error)
597
+ end.to raise_error(Mysql2::Error::TimeoutError)
542
598
  end
543
599
 
544
600
  # XXX this test is not deterministic (because Unix signal handling is not)
@@ -572,22 +628,18 @@ RSpec.describe Mysql2::Client do
572
628
  end
573
629
 
574
630
  it "#socket should return a Fixnum (file descriptor from C)" do
575
- expect(@client.socket).to be_an_instance_of(Fixnum)
631
+ expect(@client.socket).to be_an_instance_of(0.class)
576
632
  expect(@client.socket).not_to eql(0)
577
633
  end
578
634
 
579
635
  it "#socket should require an open connection" do
580
636
  @client.close
581
- expect {
637
+ expect do
582
638
  @client.socket
583
- }.to raise_error(Mysql2::Error)
639
+ end.to raise_error(Mysql2::Error)
584
640
  end
585
641
 
586
642
  it 'should be impervious to connection-corrupting timeouts in #execute' do
587
- # the statement handle gets corrupted and will segfault the tests if interrupted,
588
- # so we can't even use pending on this test, really have to skip it on older Rubies.
589
- skip('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
590
-
591
643
  # attempt to break the connection
592
644
  stmt = @client.prepare('SELECT SLEEP(?)')
593
645
  expect { Timeout.timeout(0.1) { stmt.execute(0.2) } }.to raise_error(Timeout::Error)
@@ -608,7 +660,7 @@ RSpec.describe Mysql2::Client do
608
660
  pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.')
609
661
  end
610
662
 
611
- client = new_client(:reconnect => true)
663
+ client = new_client(reconnect: true)
612
664
 
613
665
  expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
614
666
  expect { client.query('SELECT 1') }.to_not raise_error
@@ -635,7 +687,7 @@ RSpec.describe Mysql2::Client do
635
687
  sleep_time = 0.5
636
688
 
637
689
  # Note that each thread opens its own database connection
638
- threads = 5.times.map do
690
+ threads = Array.new(5) do
639
691
  Thread.new do
640
692
  new_client do |client|
641
693
  client.query("SELECT SLEEP(#{sleep_time})")
@@ -652,19 +704,12 @@ RSpec.describe Mysql2::Client do
652
704
  end
653
705
 
654
706
  it "evented async queries should be supported" do
655
- skip("ruby 1.8 doesn't support IO.for_fd options") if RUBY_VERSION.start_with?("1.8.")
656
707
  # should immediately return nil
657
- expect(@client.query("SELECT sleep(0.1)", :async => true)).to eql(nil)
708
+ expect(@client.query("SELECT sleep(0.1)", async: true)).to eql(nil)
658
709
 
659
- io_wrapper = IO.for_fd(@client.socket, :autoclose => false)
710
+ io_wrapper = IO.for_fd(@client.socket, autoclose: false)
660
711
  loops = 0
661
- loop do
662
- if IO.select([io_wrapper], nil, nil, 0.05)
663
- break
664
- else
665
- loops += 1
666
- end
667
- end
712
+ loops += 1 until IO.select([io_wrapper], nil, nil, 0.05)
668
713
 
669
714
  # make sure we waited some period of time
670
715
  expect(loops >= 1).to be true
@@ -676,15 +721,15 @@ RSpec.describe Mysql2::Client do
676
721
 
677
722
  context "Multiple results sets" do
678
723
  before(:each) do
679
- @multi_client = new_client(:flags => Mysql2::Client::MULTI_STATEMENTS)
724
+ @multi_client = new_client(flags: Mysql2::Client::MULTI_STATEMENTS)
680
725
  end
681
726
 
682
727
  it "should raise an exception when one of multiple statements fails" do
683
728
  result = @multi_client.query("SELECT 1 AS 'set_1'; SELECT * FROM invalid_table_name; SELECT 2 AS 'set_2';")
684
729
  expect(result.first['set_1']).to be(1)
685
- expect {
730
+ expect do
686
731
  @multi_client.next_result
687
- }.to raise_error(Mysql2::Error)
732
+ end.to raise_error(Mysql2::Error)
688
733
  expect(@multi_client.next_result).to be false
689
734
  end
690
735
 
@@ -706,17 +751,17 @@ RSpec.describe Mysql2::Client do
706
751
 
707
752
  it "will raise on query if there are outstanding results to read" do
708
753
  @multi_client.query("SELECT 1; SELECT 2; SELECT 3")
709
- expect {
754
+ expect do
710
755
  @multi_client.query("SELECT 4")
711
- }.to raise_error(Mysql2::Error)
756
+ end.to raise_error(Mysql2::Error)
712
757
  end
713
758
 
714
759
  it "#abandon_results! should work" do
715
760
  @multi_client.query("SELECT 1; SELECT 2; SELECT 3")
716
761
  @multi_client.abandon_results!
717
- expect {
762
+ expect do
718
763
  @multi_client.query("SELECT 4")
719
- }.not_to raise_error
764
+ end.not_to raise_error
720
765
  end
721
766
 
722
767
  it "#more_results? should work" do
@@ -752,9 +797,9 @@ RSpec.describe Mysql2::Client do
752
797
 
753
798
  if RUBY_PLATFORM =~ /mingw|mswin/
754
799
  it "#socket should raise as it's not supported" do
755
- expect {
800
+ expect do
756
801
  @client.socket
757
- }.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
802
+ end.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/)
758
803
  end
759
804
  end
760
805
 
@@ -773,27 +818,25 @@ RSpec.describe Mysql2::Client do
773
818
  end
774
819
 
775
820
  it "should not overflow the thread stack" do
776
- expect {
821
+ expect do
777
822
  Thread.new { Mysql2::Client.escape("'" * 256 * 1024) }.join
778
- }.not_to raise_error
823
+ end.not_to raise_error
779
824
  end
780
825
 
781
826
  it "should not overflow the process stack" do
782
- expect {
827
+ expect do
783
828
  Thread.new { Mysql2::Client.escape("'" * 1024 * 1024 * 4) }.join
784
- }.not_to raise_error
829
+ end.not_to raise_error
785
830
  end
786
831
 
787
- unless RUBY_VERSION =~ /1.8/
788
- it "should carry over the original string's encoding" do
789
- str = "abc'def\"ghi\0jkl%mno"
790
- escaped = Mysql2::Client.escape(str)
791
- 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)
792
836
 
793
- str.encode!('us-ascii')
794
- escaped = Mysql2::Client.escape(str)
795
- expect(escaped.encoding).to eql(str.encoding)
796
- end
837
+ str.encode!('us-ascii')
838
+ escaped = Mysql2::Client.escape(str)
839
+ expect(escaped.encoding).to eql(str.encoding)
797
840
  end
798
841
  end
799
842
 
@@ -812,28 +855,26 @@ RSpec.describe Mysql2::Client do
812
855
  end
813
856
 
814
857
  it "should not overflow the thread stack" do
815
- expect {
858
+ expect do
816
859
  Thread.new { @client.escape("'" * 256 * 1024) }.join
817
- }.not_to raise_error
860
+ end.not_to raise_error
818
861
  end
819
862
 
820
863
  it "should not overflow the process stack" do
821
- expect {
864
+ expect do
822
865
  Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join
823
- }.not_to raise_error
866
+ end.not_to raise_error
824
867
  end
825
868
 
826
869
  it "should require an open connection" do
827
870
  @client.close
828
- expect {
871
+ expect do
829
872
  @client.escape ""
830
- }.to raise_error(Mysql2::Error)
873
+ end.to raise_error(Mysql2::Error)
831
874
  end
832
875
 
833
876
  context 'when mysql encoding is not utf8' do
834
- before { pending('Encoding is undefined') unless defined?(Encoding) }
835
-
836
- let(:client) { new_client(:encoding => "ujis") }
877
+ let(:client) { new_client(encoding: "ujis") }
837
878
 
838
879
  it 'should return a internal encoding string if Encoding.default_internal is set' do
839
880
  with_internal_encoding Encoding::UTF_8 do
@@ -852,14 +893,12 @@ RSpec.describe Mysql2::Client do
852
893
  info = @client.info
853
894
  expect(info).to be_an_instance_of(Hash)
854
895
  expect(info).to have_key(:id)
855
- expect(info[:id]).to be_an_instance_of(Fixnum)
896
+ expect(info[:id]).to be_an_instance_of(0.class)
856
897
  expect(info).to have_key(:version)
857
898
  expect(info[:version]).to be_an_instance_of(String)
858
899
  end
859
900
 
860
901
  context "strings returned by #info" do
861
- before { pending('Encoding is undefined') unless defined?(Encoding) }
862
-
863
902
  it "should be tagged as ascii" do
864
903
  expect(@client.info[:version].encoding).to eql(Encoding::US_ASCII)
865
904
  expect(@client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
@@ -867,8 +906,6 @@ RSpec.describe Mysql2::Client do
867
906
  end
868
907
 
869
908
  context "strings returned by .info" do
870
- before { pending('Encoding is undefined') unless defined?(Encoding) }
871
-
872
909
  it "should be tagged as ascii" do
873
910
  expect(Mysql2::Client.info[:version].encoding).to eql(Encoding::US_ASCII)
874
911
  expect(Mysql2::Client.info[:header_version].encoding).to eql(Encoding::US_ASCII)
@@ -883,26 +920,24 @@ RSpec.describe Mysql2::Client do
883
920
  server_info = @client.server_info
884
921
  expect(server_info).to be_an_instance_of(Hash)
885
922
  expect(server_info).to have_key(:id)
886
- expect(server_info[:id]).to be_an_instance_of(Fixnum)
923
+ expect(server_info[:id]).to be_an_instance_of(0.class)
887
924
  expect(server_info).to have_key(:version)
888
925
  expect(server_info[:version]).to be_an_instance_of(String)
889
926
  end
890
927
 
891
928
  it "#server_info should require an open connection" do
892
929
  @client.close
893
- expect {
930
+ expect do
894
931
  @client.server_info
895
- }.to raise_error(Mysql2::Error)
932
+ end.to raise_error(Mysql2::Error)
896
933
  end
897
934
 
898
935
  context "strings returned by #server_info" do
899
- before { pending('Encoding is undefined') unless defined?(Encoding) }
900
-
901
936
  it "should default to the connection's encoding if Encoding.default_internal is nil" do
902
937
  with_internal_encoding nil do
903
938
  expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8)
904
939
 
905
- client2 = new_client(:encoding => 'ascii')
940
+ client2 = new_client(encoding: 'ascii')
906
941
  expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII)
907
942
  end
908
943
  end
@@ -918,14 +953,14 @@ RSpec.describe Mysql2::Client do
918
953
  end
919
954
  end
920
955
 
921
- it "should raise a Mysql2::Error exception upon connection failure" do
922
- expect {
923
- new_client(:host => "localhost", :username => 'asdfasdf8d2h', :password => 'asdfasdfw42')
924
- }.to raise_error(Mysql2::Error)
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)
925
960
 
926
- expect {
961
+ expect do
927
962
  new_client(DatabaseCredentials['root'])
928
- }.not_to raise_error
963
+ end.not_to raise_error
929
964
  end
930
965
 
931
966
  context 'write operations api' do
@@ -974,7 +1009,7 @@ RSpec.describe Mysql2::Client do
974
1009
  end
975
1010
 
976
1011
  it "#thread_id should be a Fixnum" do
977
- expect(@client.thread_id).to be_an_instance_of(Fixnum)
1012
+ expect(@client.thread_id).to be_an_instance_of(0.class)
978
1013
  end
979
1014
 
980
1015
  it "should respond to #ping" do
@@ -1010,9 +1045,9 @@ RSpec.describe Mysql2::Client do
1010
1045
  end
1011
1046
 
1012
1047
  it "should raise a Mysql2::Error when the database doesn't exist" do
1013
- expect {
1048
+ expect do
1014
1049
  @client.select_db("nopenothere")
1015
- }.to raise_error(Mysql2::Error)
1050
+ end.to raise_error(Mysql2::Error)
1016
1051
  end
1017
1052
 
1018
1053
  it "should return the database switched to" do
@@ -1027,13 +1062,11 @@ RSpec.describe Mysql2::Client do
1027
1062
  end
1028
1063
 
1029
1064
  it "should be able to connect using plaintext password" do
1030
- client = new_client(:enable_cleartext_plugin => true)
1065
+ client = new_client(enable_cleartext_plugin: true)
1031
1066
  client.query('SELECT 1')
1032
1067
  end
1033
1068
 
1034
- unless RUBY_VERSION =~ /1.8/
1035
- it "should respond to #encoding" do
1036
- expect(@client).to respond_to(:encoding)
1037
- end
1069
+ it "should respond to #encoding" do
1070
+ expect(@client).to respond_to(:encoding)
1038
1071
  end
1039
1072
  end