mysql2 0.3.14 → 0.3.15

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.
@@ -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