mysql2 0.3.14 → 0.3.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +1,81 @@
1
+ # encoding: UTF-8
2
+
1
3
  module Mysql2
2
4
  class Error < StandardError
3
- attr_accessor :error_number, :sql_state
5
+ REPLACEMENT_CHAR = '?'
6
+ ENCODE_OPTS = {:undef => :replace, :invalid => :replace, :replace => REPLACEMENT_CHAR}
4
7
 
5
- def initialize msg
6
- super
7
- @error_number = nil
8
- @sql_state = nil
9
- end
8
+ attr_accessor :error_number, :sql_state
9
+ attr_writer :server_version
10
10
 
11
11
  # Mysql gem compatibility
12
12
  alias_method :errno, :error_number
13
13
  alias_method :error, :message
14
+
15
+ def initialize(msg, server_version=nil)
16
+ self.server_version = server_version
17
+
18
+ super(clean_message(msg))
19
+ end
20
+
21
+ if "".respond_to? :encode
22
+ def sql_state=(state)
23
+ @sql_state = state.encode(ENCODE_OPTS)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # In MySQL 5.5+ error messages are always constructed server-side as UTF-8
30
+ # then returned in the encoding set by the `character_set_results` system
31
+ # variable.
32
+ #
33
+ # See http://dev.mysql.com/doc/refman/5.5/en/charset-errors.html for
34
+ # more contetx.
35
+ #
36
+ # Before MySQL 5.5 error message template strings are in whatever encoding
37
+ # is associated with the error message language.
38
+ # See http://dev.mysql.com/doc/refman/5.1/en/error-message-language.html
39
+ # for more information.
40
+ #
41
+ # The issue is that the user-data inserted in the message could potentially
42
+ # be in any encoding MySQL supports and is insert into the latin1, euckr or
43
+ # koi8r string raw. Meaning there's a high probability the string will be
44
+ # corrupt encoding-wise.
45
+ #
46
+ # See http://dev.mysql.com/doc/refman/5.1/en/charset-errors.html for
47
+ # more information.
48
+ #
49
+ # So in an attempt to make sure the error message string is always in a valid
50
+ # encoding, we'll assume UTF-8 and clean the string of anything that's not a
51
+ # valid UTF-8 character.
52
+ #
53
+ # Except for if we're on 1.8, where we'll do nothing ;)
54
+ #
55
+ # Returns a valid UTF-8 string in Ruby 1.9+, the original string on Ruby 1.8
56
+ def clean_message(message)
57
+ return message if !message.respond_to?(:encoding)
58
+
59
+ if @server_version && @server_version > 50500
60
+ message.encode(ENCODE_OPTS)
61
+ else
62
+ if message.respond_to? :scrub
63
+ message.scrub(REPLACEMENT_CHAR).encode(ENCODE_OPTS)
64
+ else
65
+ # This is ugly as hell but Ruby 1.9 doesn't provide a way to clean a string
66
+ # and retain it's valid UTF-8 characters, that I know of.
67
+
68
+ new_message = "".force_encoding(Encoding::UTF_8)
69
+ message.chars.each do |char|
70
+ if char.valid_encoding?
71
+ new_message << char
72
+ else
73
+ new_message << REPLACEMENT_CHAR
74
+ end
75
+ end
76
+ new_message.encode(ENCODE_OPTS)
77
+ end
78
+ end
79
+ end
14
80
  end
15
81
  end
@@ -1,3 +1,3 @@
1
1
  module Mysql2
2
- VERSION = "0.3.14"
2
+ VERSION = "0.3.15"
3
3
  end
@@ -7,13 +7,14 @@ describe Mysql2::Client do
7
7
 
8
8
  it "should not raise an exception for valid defaults group" do
9
9
  lambda {
10
- @client = Mysql2::Client.new(:default_file => cnf_file, :default_group => "test")
10
+ opts = DatabaseCredentials['root'].merge(:default_file => cnf_file, :default_group => "test")
11
+ @client = Mysql2::Client.new(opts)
11
12
  }.should_not raise_error(Mysql2::Error)
12
13
  end
13
14
 
14
15
  it "should not raise an exception without default group" do
15
16
  lambda {
16
- @client = Mysql2::Client.new(:default_file => cnf_file)
17
+ @client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:default_file => cnf_file))
17
18
  }.should_not raise_error(Mysql2::Error)
18
19
  end
19
20
  end
@@ -78,7 +79,10 @@ describe Mysql2::Client do
78
79
  end
79
80
 
80
81
  it "should be able to connect via SSL options" do
81
- pending("DON'T WORRY, THIS TEST PASSES :) - but is machine-specific. You need to have MySQL running with SSL configured and enabled. Then update the paths in this test to your needs and remove the pending state.")
82
+ ssl = @client.query "SHOW VARIABLES LIKE 'have_%ssl'"
83
+ ssl_enabled = ssl.any? {|x| x['Value'] == 'ENABLED'}
84
+ pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") unless ssl_enabled
85
+ pending("DON'T WORRY, THIS TEST PASSES - but you must update the SSL cert paths in this test and remove this pending state.")
82
86
  ssl_client = nil
83
87
  lambda {
84
88
  ssl_client = Mysql2::Client.new(
@@ -104,6 +108,24 @@ describe Mysql2::Client do
104
108
  ssl_client.close
105
109
  end
106
110
 
111
+ it "should not leave dangling connections after garbage collection" do
112
+ GC.start
113
+ sleep 0.300 # Let GC do its work
114
+ client = Mysql2::Client.new(DatabaseCredentials['root'])
115
+ before_count = client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
116
+
117
+ 10.times do
118
+ Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1')
119
+ end
120
+ after_count = client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
121
+ after_count.should == before_count + 10
122
+
123
+ GC.start
124
+ sleep 0.300 # Let GC do its work
125
+ final_count = client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i
126
+ final_count.should == before_count
127
+ end
128
+
107
129
  it "should be able to connect to database with numeric-only name" do
108
130
  lambda {
109
131
  creds = DatabaseCredentials['numericuser']
@@ -179,6 +201,49 @@ describe Mysql2::Client do
179
201
  end
180
202
  end
181
203
 
204
+ context ":local_infile" do
205
+ before(:all) do
206
+ @client_i = Mysql2::Client.new DatabaseCredentials['root'].merge(:local_infile => true)
207
+ local = @client_i.query "SHOW VARIABLES LIKE 'local_infile'"
208
+ local_enabled = local.any? {|x| x['Value'] == 'ON'}
209
+ pending("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled
210
+
211
+ @client_i.query %[
212
+ CREATE TABLE IF NOT EXISTS infileTest (
213
+ id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
214
+ foo VARCHAR(10),
215
+ bar MEDIUMTEXT
216
+ )
217
+ ]
218
+ end
219
+
220
+ after(:all) do
221
+ @client_i.query "DROP TABLE infileTest"
222
+ end
223
+
224
+ it "should raise an error when local_infile is disabled" do
225
+ client = Mysql2::Client.new DatabaseCredentials['root'].merge(:local_infile => false)
226
+ lambda {
227
+ client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
228
+ }.should raise_error(Mysql2::Error, %r{command is not allowed})
229
+ end
230
+
231
+ it "should raise an error when a non-existent file is loaded" do
232
+ lambda {
233
+ @client_i.query "LOAD DATA LOCAL INFILE 'this/file/is/not/here' INTO TABLE infileTest"
234
+ }.should_not raise_error(Mysql2::Error, %r{file not found: this/file/is/not/here})
235
+ end
236
+
237
+ it "should LOAD DATA LOCAL INFILE" do
238
+ @client_i.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest"
239
+ info = @client_i.query_info
240
+ info.should eql({:records => 1, :deleted => 0, :skipped => 0, :warnings => 0})
241
+
242
+ result = @client_i.query "SELECT * FROM infileTest"
243
+ result.first.should eql({'id' => 1, 'foo' => 'Hello', 'bar' => 'World'})
244
+ end
245
+ end
246
+
182
247
  it "should expect connect_timeout to be a positive integer" do
183
248
  lambda {
184
249
  Mysql2::Client.new(:connect_timeout => -1)
@@ -332,6 +397,7 @@ describe Mysql2::Client do
332
397
  end
333
398
 
334
399
  it "should close the connection when an exception is raised" do
400
+ pending "Ruby 2.1 has changed Timeout behavior." if RUBY_VERSION =~ /2.1/
335
401
  begin
336
402
  Timeout.timeout(1) do
337
403
  @client.query("SELECT sleep(2)")
@@ -345,6 +411,7 @@ describe Mysql2::Client do
345
411
  end
346
412
 
347
413
  it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
414
+ pending "Ruby 2.1 has changed Timeout behavior." if RUBY_VERSION =~ /2.1/
348
415
  client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:reconnect => true))
349
416
  begin
350
417
  Timeout.timeout(1) do
@@ -359,6 +426,7 @@ describe Mysql2::Client do
359
426
  end
360
427
 
361
428
  it "should handle Timeouts without leaving the connection hanging if reconnect is set to true after construction true" do
429
+ pending "Ruby 2.1 has changed Timeout behavior." if RUBY_VERSION =~ /2.1/
362
430
  client = Mysql2::Client.new(DatabaseCredentials['root'])
363
431
  begin
364
432
  Timeout.timeout(1) do
@@ -433,6 +501,15 @@ describe Mysql2::Client do
433
501
  @multi_client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:flags => Mysql2::Client::MULTI_STATEMENTS))
434
502
  end
435
503
 
504
+ it "should raise an exception when one of multiple statements fails" do
505
+ result = @multi_client.query("SELECT 1 as 'set_1'; SELECT * FROM invalid_table_name;SELECT 2 as 'set_2';")
506
+ result.first['set_1'].should be(1)
507
+ lambda {
508
+ @multi_client.next_result
509
+ }.should raise_error(Mysql2::Error)
510
+ @multi_client.next_result.should be_false
511
+ end
512
+
436
513
  it "returns multiple result sets" do
437
514
  @multi_client.query( "select 1 as 'set_1'; select 2 as 'set_2'").first.should eql({ 'set_1' => 1 })
438
515
 
@@ -579,18 +656,22 @@ describe Mysql2::Client do
579
656
  if defined? Encoding
580
657
  context "strings returned by #info" do
581
658
  it "should default to the connection's encoding if Encoding.default_internal is nil" do
582
- Encoding.default_internal = nil
583
- @client.info[:version].encoding.should eql(Encoding.find('utf-8'))
659
+ with_internal_encoding nil do
660
+ @client.info[:version].encoding.should eql(Encoding.find('utf-8'))
584
661
 
585
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
586
- client2.info[:version].encoding.should eql(Encoding.find('us-ascii'))
662
+ client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
663
+ client2.info[:version].encoding.should eql(Encoding.find('us-ascii'))
664
+ end
587
665
  end
588
666
 
589
667
  it "should use Encoding.default_internal" do
590
- Encoding.default_internal = Encoding.find('utf-8')
591
- @client.info[:version].encoding.should eql(Encoding.default_internal)
592
- Encoding.default_internal = Encoding.find('us-ascii')
593
- @client.info[:version].encoding.should eql(Encoding.default_internal)
668
+ with_internal_encoding 'utf-8' do
669
+ @client.info[:version].encoding.should eql(Encoding.default_internal)
670
+ end
671
+
672
+ with_internal_encoding 'us-ascii' do
673
+ @client.info[:version].encoding.should eql(Encoding.default_internal)
674
+ end
594
675
  end
595
676
  end
596
677
  end
@@ -618,18 +699,22 @@ describe Mysql2::Client do
618
699
  if defined? Encoding
619
700
  context "strings returned by #server_info" do
620
701
  it "should default to the connection's encoding if Encoding.default_internal is nil" do
621
- Encoding.default_internal = nil
622
- @client.server_info[:version].encoding.should eql(Encoding.find('utf-8'))
702
+ with_internal_encoding nil do
703
+ @client.server_info[:version].encoding.should eql(Encoding.find('utf-8'))
623
704
 
624
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
625
- client2.server_info[:version].encoding.should eql(Encoding.find('us-ascii'))
705
+ client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
706
+ client2.server_info[:version].encoding.should eql(Encoding.find('us-ascii'))
707
+ end
626
708
  end
627
709
 
628
710
  it "should use Encoding.default_internal" do
629
- Encoding.default_internal = Encoding.find('utf-8')
630
- @client.server_info[:version].encoding.should eql(Encoding.default_internal)
631
- Encoding.default_internal = Encoding.find('us-ascii')
632
- @client.server_info[:version].encoding.should eql(Encoding.default_internal)
711
+ with_internal_encoding 'utf-8' do
712
+ @client.server_info[:version].encoding.should eql(Encoding.default_internal)
713
+ end
714
+
715
+ with_internal_encoding 'us-ascii' do
716
+ @client.server_info[:version].encoding.should eql(Encoding.default_internal)
717
+ end
633
718
  end
634
719
  end
635
720
  end
@@ -647,7 +732,7 @@ describe Mysql2::Client do
647
732
  context 'write operations api' do
648
733
  before(:each) do
649
734
  @client.query "USE test"
650
- @client.query "CREATE TABLE IF NOT EXISTS lastIdTest (`id` int(11) NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))"
735
+ @client.query "CREATE TABLE IF NOT EXISTS lastIdTest (`id` BIGINT NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))"
651
736
  end
652
737
 
653
738
  after(:each) do
@@ -674,6 +759,15 @@ describe Mysql2::Client do
674
759
  @client.query "UPDATE lastIdTest SET blah=4321 WHERE id=1"
675
760
  @client.affected_rows.should eql(1)
676
761
  end
762
+
763
+ it "#last_id should handle BIGINT auto-increment ids above 32 bits" do
764
+ # The id column type must be BIGINT. Surprise: INT(x) is limited to 32-bits for all values of x.
765
+ # Insert a row with a given ID, this should raise the auto-increment state
766
+ @client.query "INSERT INTO lastIdTest (id, blah) VALUES (5000000000, 5000)"
767
+ @client.last_id.should eql(5000000000)
768
+ @client.query "INSERT INTO lastIdTest (blah) VALUES (5001)"
769
+ @client.last_id.should eql(5000000001)
770
+ end
677
771
  end
678
772
 
679
773
  it "should respond to #thread_id" do
@@ -1,72 +1,82 @@
1
1
  # encoding: UTF-8
2
+
2
3
  require 'spec_helper'
3
4
 
4
5
  describe Mysql2::Error do
5
- before(:each) do
6
- begin
7
- @err_client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "utf8"))
8
- @err_client.query("HAHAHA")
9
- rescue Mysql2::Error => e
10
- @error = e
11
- ensure
12
- @err_client.close
13
- end
6
+ let(:client) { Mysql2::Client.new(DatabaseCredentials['root']) }
14
7
 
8
+ let :error do
15
9
  begin
16
- @err_client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => "big5"))
17
- @err_client2.query("HAHAHA")
10
+ client.query("HAHAHA")
18
11
  rescue Mysql2::Error => e
19
- @error2 = e
12
+ error = e
20
13
  ensure
21
- @err_client2.close
14
+ client.close
22
15
  end
23
- end
24
16
 
25
- it "should respond to #error_number" do
26
- @error.should respond_to(:error_number)
17
+ error
27
18
  end
28
19
 
29
- it "should respond to #sql_state" do
30
- @error.should respond_to(:sql_state)
31
- end
20
+ it "responds to error_number and sql_state, with aliases" do
21
+ error.should respond_to(:error_number)
22
+ error.should respond_to(:sql_state)
32
23
 
33
- # Mysql gem compatibility
34
- it "should alias #error_number to #errno" do
35
- @error.should respond_to(:errno)
24
+ # Mysql gem compatibility
25
+ error.should respond_to(:errno)
26
+ error.should respond_to(:error)
36
27
  end
37
28
 
38
- it "should alias #message to #error" do
39
- @error.should respond_to(:error)
40
- end
29
+ if "".respond_to? :encoding
30
+ let :error do
31
+ client = Mysql2::Client.new(DatabaseCredentials['root'])
32
+ begin
33
+ client.query("\xE9\x80\xA0\xE5\xAD\x97")
34
+ rescue Mysql2::Error => e
35
+ error = e
36
+ ensure
37
+ client.close
38
+ end
41
39
 
42
- unless RUBY_VERSION =~ /1.8/
43
- it "#message encoding should match the connection's encoding, or Encoding.default_internal if set" do
44
- if Encoding.default_internal.nil?
45
- @error.message.encoding.should eql(@err_client.encoding)
46
- @error2.message.encoding.should eql(@err_client2.encoding)
47
- else
48
- @error.message.encoding.should eql(Encoding.default_internal)
49
- @error2.message.encoding.should eql(Encoding.default_internal)
40
+ error
41
+ end
42
+
43
+ let :bad_err do
44
+ client = Mysql2::Client.new(DatabaseCredentials['root'])
45
+ begin
46
+ client.query("\xE5\xC6\x7D\x1F")
47
+ rescue Mysql2::Error => e
48
+ error = e
49
+ ensure
50
+ client.close
50
51
  end
52
+
53
+ error
51
54
  end
52
55
 
53
- it "#error encoding should match the connection's encoding, or Encoding.default_internal if set" do
54
- if Encoding.default_internal.nil?
55
- @error.error.encoding.should eql(@err_client.encoding)
56
- @error2.error.encoding.should eql(@err_client2.encoding)
57
- else
58
- @error.error.encoding.should eql(Encoding.default_internal)
59
- @error2.error.encoding.should eql(Encoding.default_internal)
56
+ it "returns error messages as UTF-8 by default" do
57
+ with_internal_encoding nil do
58
+ error.message.encoding.should eql(Encoding::UTF_8)
59
+ error.message.valid_encoding?
60
+
61
+ bad_err.message.encoding.should eql(Encoding::UTF_8)
62
+ bad_err.message.valid_encoding?
63
+
64
+ bad_err.message.should include("??}\u001F")
60
65
  end
61
66
  end
62
67
 
63
- it "#sql_state encoding should match the connection's encoding, or Encoding.default_internal if set" do
64
- if Encoding.default_internal.nil?
65
- @error.sql_state.encoding.should eql(@err_client.encoding)
66
- @error2.sql_state.encoding.should eql(@err_client2.encoding)
67
- else
68
- @error.sql_state.encoding.should eql(Encoding.default_internal)
69
- @error2.sql_state.encoding.should eql(Encoding.default_internal)
68
+ it "returns sql state as ASCII" do
69
+ error.sql_state.encoding.should eql(Encoding::US_ASCII)
70
+ error.sql_state.valid_encoding?
71
+ end
72
+
73
+ it "returns error messages and sql state in Encoding.default_internal if set" do
74
+ with_internal_encoding 'UTF-16LE' do
75
+ error.message.encoding.should eql(Encoding.default_internal)
76
+ error.message.valid_encoding?
77
+
78
+ bad_err.message.encoding.should eql(Encoding.default_internal)
79
+ bad_err.message.valid_encoding?
70
80
  end
71
81
  end
72
82
  end
@@ -6,35 +6,6 @@ describe Mysql2::Result do
6
6
  @result = @client.query "SELECT 1"
7
7
  end
8
8
 
9
- it "should maintain a count while streaming" do
10
- result = @client.query('SELECT 1')
11
-
12
- result.count.should eql(1)
13
- result.each.to_a
14
- result.count.should eql(1)
15
- end
16
-
17
- it "should set the actual count of rows after streaming" do
18
- @client.query "USE test"
19
- result = @client.query("SELECT * FROM mysql2_test", :stream => true, :cache_rows => false)
20
- result.count.should eql(0)
21
- result.each {|r| }
22
- result.count.should eql(1)
23
- end
24
-
25
- it "should not yield nil at the end of streaming" do
26
- result = @client.query('SELECT * FROM mysql2_test', :stream => true)
27
- result.each { |r| r.should_not be_nil}
28
- end
29
-
30
- it "#count should be zero for rows after streaming when there were no results " do
31
- @client.query "USE test"
32
- result = @client.query("SELECT * FROM mysql2_test WHERE null_test IS NOT NULL", :stream => true, :cache_rows => false)
33
- result.count.should eql(0)
34
- result.each.to_a
35
- result.count.should eql(0)
36
- end
37
-
38
9
  it "should have included Enumerable" do
39
10
  Mysql2::Result.ancestors.include?(Enumerable).should be_true
40
11
  end
@@ -121,7 +92,6 @@ describe Mysql2::Result do
121
92
 
122
93
  context "#fields" do
123
94
  before(:each) do
124
- @client.query "USE test"
125
95
  @test_result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1")
126
96
  end
127
97
 
@@ -135,9 +105,59 @@ describe Mysql2::Result do
135
105
  end
136
106
  end
137
107
 
108
+ context "streaming" do
109
+ it "should maintain a count while streaming" do
110
+ result = @client.query('SELECT 1')
111
+
112
+ result.count.should eql(1)
113
+ result.each.to_a
114
+ result.count.should eql(1)
115
+ end
116
+
117
+ it "should set the actual count of rows after streaming" do
118
+ result = @client.query("SELECT * FROM mysql2_test", :stream => true, :cache_rows => false)
119
+ result.count.should eql(0)
120
+ result.each {|r| }
121
+ result.count.should eql(1)
122
+ end
123
+
124
+ it "should not yield nil at the end of streaming" do
125
+ result = @client.query('SELECT * FROM mysql2_test', :stream => true, :cache_rows => false)
126
+ result.each { |r| r.should_not be_nil}
127
+ end
128
+
129
+ it "#count should be zero for rows after streaming when there were no results" do
130
+ result = @client.query("SELECT * FROM mysql2_test WHERE null_test IS NOT NULL", :stream => true, :cache_rows => false)
131
+ result.count.should eql(0)
132
+ result.each.to_a
133
+ result.count.should eql(0)
134
+ end
135
+
136
+ it "should raise an exception if streaming ended due to a timeout" do
137
+ # Create an extra client instance, since we're going to time it out
138
+ client = Mysql2::Client.new DatabaseCredentials['root']
139
+ client.query "CREATE TEMPORARY TABLE streamingTest (val BINARY(255))"
140
+
141
+ # Insert enough records to force the result set into multiple reads
142
+ # (the BINARY type is used simply because it forces full width results)
143
+ 10000.times do |i|
144
+ client.query "INSERT INTO streamingTest (val) VALUES ('Foo #{i}')"
145
+ end
146
+
147
+ client.query "SET net_write_timeout = 1"
148
+ res = client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false
149
+
150
+ lambda {
151
+ res.each_with_index do |row, i|
152
+ # Exhaust the first result packet then trigger a timeout
153
+ sleep 2 if i > 0 && i % 1000 == 0
154
+ end
155
+ }.should raise_error(Mysql2::Error, /Lost connection/)
156
+ end
157
+ end
158
+
138
159
  context "row data type mapping" do
139
160
  before(:each) do
140
- @client.query "USE test"
141
161
  @test_result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
142
162
  end
143
163
 
@@ -318,24 +338,27 @@ describe Mysql2::Result do
318
338
  if defined? Encoding
319
339
  context "string encoding for ENUM values" do
320
340
  it "should default to the connection's encoding if Encoding.default_internal is nil" do
321
- Encoding.default_internal = nil
322
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
323
- result['enum_test'].encoding.should eql(Encoding.find('utf-8'))
324
-
325
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
326
- client2.query "USE test"
327
- result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
328
- result['enum_test'].encoding.should eql(Encoding.find('us-ascii'))
329
- client2.close
341
+ with_internal_encoding nil do
342
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
343
+ result['enum_test'].encoding.should eql(Encoding.find('utf-8'))
344
+
345
+ client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
346
+ result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
347
+ result['enum_test'].encoding.should eql(Encoding.find('us-ascii'))
348
+ client2.close
349
+ end
330
350
  end
331
351
 
332
352
  it "should use Encoding.default_internal" do
333
- Encoding.default_internal = Encoding.find('utf-8')
334
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
335
- result['enum_test'].encoding.should eql(Encoding.default_internal)
336
- Encoding.default_internal = Encoding.find('us-ascii')
337
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
338
- result['enum_test'].encoding.should eql(Encoding.default_internal)
353
+ with_internal_encoding 'utf-8' do
354
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
355
+ result['enum_test'].encoding.should eql(Encoding.default_internal)
356
+ end
357
+
358
+ with_internal_encoding 'us-ascii' do
359
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
360
+ result['enum_test'].encoding.should eql(Encoding.default_internal)
361
+ end
339
362
  end
340
363
  end
341
364
  end
@@ -348,24 +371,27 @@ describe Mysql2::Result do
348
371
  if defined? Encoding
349
372
  context "string encoding for SET values" do
350
373
  it "should default to the connection's encoding if Encoding.default_internal is nil" do
351
- Encoding.default_internal = nil
352
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
353
- result['set_test'].encoding.should eql(Encoding.find('utf-8'))
354
-
355
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
356
- client2.query "USE test"
357
- result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
358
- result['set_test'].encoding.should eql(Encoding.find('us-ascii'))
359
- client2.close
374
+ with_internal_encoding nil do
375
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
376
+ result['set_test'].encoding.should eql(Encoding.find('utf-8'))
377
+
378
+ client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
379
+ result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
380
+ result['set_test'].encoding.should eql(Encoding.find('us-ascii'))
381
+ client2.close
382
+ end
360
383
  end
361
384
 
362
385
  it "should use Encoding.default_internal" do
363
- Encoding.default_internal = Encoding.find('utf-8')
364
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
365
- result['set_test'].encoding.should eql(Encoding.default_internal)
366
- Encoding.default_internal = Encoding.find('us-ascii')
367
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
368
- result['set_test'].encoding.should eql(Encoding.default_internal)
386
+ with_internal_encoding 'utf-8' do
387
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
388
+ result['set_test'].encoding.should eql(Encoding.default_internal)
389
+ end
390
+
391
+ with_internal_encoding 'us-ascii' do
392
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
393
+ result['set_test'].encoding.should eql(Encoding.default_internal)
394
+ end
369
395
  end
370
396
  end
371
397
  end
@@ -378,18 +404,22 @@ describe Mysql2::Result do
378
404
  if defined? Encoding
379
405
  context "string encoding for BINARY values" do
380
406
  it "should default to binary if Encoding.default_internal is nil" do
381
- Encoding.default_internal = nil
382
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
383
- result['binary_test'].encoding.should eql(Encoding.find('binary'))
407
+ with_internal_encoding nil do
408
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
409
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
410
+ end
384
411
  end
385
412
 
386
413
  it "should not use Encoding.default_internal" do
387
- Encoding.default_internal = Encoding.find('utf-8')
388
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
389
- result['binary_test'].encoding.should eql(Encoding.find('binary'))
390
- Encoding.default_internal = Encoding.find('us-ascii')
391
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
392
- result['binary_test'].encoding.should eql(Encoding.find('binary'))
414
+ with_internal_encoding 'utf-8' do
415
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
416
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
417
+ end
418
+
419
+ with_internal_encoding 'us-ascii' do
420
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
421
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
422
+ end
393
423
  end
394
424
  end
395
425
  end
@@ -416,39 +446,46 @@ describe Mysql2::Result do
416
446
  context "string encoding for #{type} values" do
417
447
  if ['VARBINARY', 'TINYBLOB', 'BLOB', 'MEDIUMBLOB', 'LONGBLOB'].include?(type)
418
448
  it "should default to binary if Encoding.default_internal is nil" do
419
- Encoding.default_internal = nil
420
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
421
- result['binary_test'].encoding.should eql(Encoding.find('binary'))
449
+ with_internal_encoding nil do
450
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
451
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
452
+ end
422
453
  end
423
454
 
424
455
  it "should not use Encoding.default_internal" do
425
- Encoding.default_internal = Encoding.find('utf-8')
426
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
427
- result['binary_test'].encoding.should eql(Encoding.find('binary'))
428
- Encoding.default_internal = Encoding.find('us-ascii')
429
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
430
- result['binary_test'].encoding.should eql(Encoding.find('binary'))
456
+ with_internal_encoding 'utf-8' do
457
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
458
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
459
+ end
460
+
461
+ with_internal_encoding 'us-ascii' do
462
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
463
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
464
+ end
431
465
  end
432
466
  else
433
467
  it "should default to utf-8 if Encoding.default_internal is nil" do
434
- Encoding.default_internal = nil
435
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
436
- result[field].encoding.should eql(Encoding.find('utf-8'))
437
-
438
- client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
439
- client2.query "USE test"
440
- result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
441
- result[field].encoding.should eql(Encoding.find('us-ascii'))
442
- client2.close
468
+ with_internal_encoding nil do
469
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
470
+ result[field].encoding.should eql(Encoding.find('utf-8'))
471
+
472
+ client2 = Mysql2::Client.new(DatabaseCredentials['root'].merge(:encoding => 'ascii'))
473
+ result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
474
+ result[field].encoding.should eql(Encoding.find('us-ascii'))
475
+ client2.close
476
+ end
443
477
  end
444
478
 
445
479
  it "should use Encoding.default_internal" do
446
- Encoding.default_internal = Encoding.find('utf-8')
447
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
448
- result[field].encoding.should eql(Encoding.default_internal)
449
- Encoding.default_internal = Encoding.find('us-ascii')
450
- result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
451
- result[field].encoding.should eql(Encoding.default_internal)
480
+ with_internal_encoding 'utf-8' do
481
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
482
+ result[field].encoding.should eql(Encoding.default_internal)
483
+ end
484
+
485
+ with_internal_encoding 'us-ascii' do
486
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
487
+ result[field].encoding.should eql(Encoding.default_internal)
488
+ end
452
489
  end
453
490
  end
454
491
  end