ruby-mysql 2.9.4 → 2.9.5
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.
Potentially problematic release.
This version of ruby-mysql might be problematic. Click here for more details.
- data/lib/mysql.rb +24 -15
- data/lib/mysql/charset.rb +2 -0
- data/lib/mysql/error.rb +2 -2
- data/lib/mysql/protocol.rb +13 -4
- data/spec/mysql_spec.rb +1679 -0
- metadata +32 -61
- data/ChangeLog +0 -58
data/lib/mysql.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2008-
|
1
|
+
# Copyright (C) 2008-2012 TOMITA Masahiro
|
2
2
|
# mailto:tommy@tmtm.org
|
3
3
|
|
4
4
|
# MySQL connection class.
|
@@ -21,8 +21,6 @@ class Mysql
|
|
21
21
|
MYSQL_TCP_PORT = 3306 # TCP socket port number
|
22
22
|
|
23
23
|
attr_reader :charset # character set of MySQL connection
|
24
|
-
attr_reader :affected_rows # number of affected records by insert/update/delete.
|
25
|
-
attr_reader :warning_count # number of warnings for previous query
|
26
24
|
attr_reader :protocol # :nodoc:
|
27
25
|
|
28
26
|
attr_accessor :query_with_result
|
@@ -84,12 +82,9 @@ class Mysql
|
|
84
82
|
@read_timeout = nil
|
85
83
|
@write_timeout = nil
|
86
84
|
@init_command = nil
|
87
|
-
@affected_rows = nil
|
88
|
-
@warning_count = 0
|
89
85
|
@sqlstate = "00000"
|
90
86
|
@query_with_result = true
|
91
87
|
@host_info = nil
|
92
|
-
@info = nil
|
93
88
|
@last_error = nil
|
94
89
|
@result_exist = false
|
95
90
|
@local_infile = nil
|
@@ -106,9 +101,13 @@ class Mysql
|
|
106
101
|
# flag :: [Integer / nil] connection flag. Mysql::CLIENT_* ORed
|
107
102
|
# === Return
|
108
103
|
# self
|
109
|
-
def connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=
|
104
|
+
def connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=0)
|
105
|
+
if flag & CLIENT_COMPRESS != 0
|
106
|
+
warn 'unsupported flag: CLIENT_COMPRESS'
|
107
|
+
flag &= ~CLIENT_COMPRESS
|
108
|
+
end
|
110
109
|
@protocol = Protocol.new host, port, socket, @connect_timeout, @read_timeout, @write_timeout
|
111
|
-
@protocol.authenticate user, passwd, db, (@local_infile ? CLIENT_LOCAL_FILES : 0) |
|
110
|
+
@protocol.authenticate user, passwd, db, (@local_infile ? CLIENT_LOCAL_FILES : 0) | flag, @charset
|
112
111
|
@charset ||= @protocol.charset
|
113
112
|
@host_info = (host.nil? || host == "localhost") ? 'Localhost via UNIX socket' : "#{host} via TCP/IP"
|
114
113
|
query @init_command if @init_command
|
@@ -283,13 +282,25 @@ class Mysql
|
|
283
282
|
# === Return
|
284
283
|
# [String] information for last query
|
285
284
|
def info
|
286
|
-
@
|
285
|
+
@protocol && @protocol.message
|
286
|
+
end
|
287
|
+
|
288
|
+
# === Return
|
289
|
+
# [Integer] number of affected records by insert/update/delete.
|
290
|
+
def affected_rows
|
291
|
+
@protocol ? @protocol.affected_rows : 0
|
287
292
|
end
|
288
293
|
|
289
294
|
# === Return
|
290
295
|
# [Integer] latest auto_increment value
|
291
296
|
def insert_id
|
292
|
-
@insert_id
|
297
|
+
@protocol ? @protocol.insert_id : 0
|
298
|
+
end
|
299
|
+
|
300
|
+
# === Return
|
301
|
+
# [Integer] number of warnings for previous query
|
302
|
+
def warning_count
|
303
|
+
@protocol ? @protocol.warning_count : 0
|
293
304
|
end
|
294
305
|
|
295
306
|
# Kill query.
|
@@ -333,9 +344,6 @@ class Mysql
|
|
333
344
|
if nfields
|
334
345
|
@fields = @protocol.retr_fields nfields
|
335
346
|
@result_exist = true
|
336
|
-
else
|
337
|
-
@affected_rows, @insert_id, @server_status, @warning_count, @info =
|
338
|
-
@protocol.affected_rows, @protocol.insert_id, @protocol.server_status, @protocol.warning_count, @protocol.message
|
339
347
|
end
|
340
348
|
if block
|
341
349
|
while true
|
@@ -364,7 +372,6 @@ class Mysql
|
|
364
372
|
check_connection
|
365
373
|
raise ClientError, 'invalid usage' unless @result_exist
|
366
374
|
res = Result.new @fields, @protocol
|
367
|
-
@server_status = @protocol.server_status
|
368
375
|
@result_exist = false
|
369
376
|
res
|
370
377
|
end
|
@@ -395,7 +402,7 @@ class Mysql
|
|
395
402
|
|
396
403
|
# true if multiple queries are specified and unexecuted queries exists.
|
397
404
|
def more_results
|
398
|
-
@server_status & SERVER_MORE_RESULTS_EXISTS != 0
|
405
|
+
@protocol.server_status & SERVER_MORE_RESULTS_EXISTS != 0
|
399
406
|
end
|
400
407
|
alias more_results? more_results
|
401
408
|
|
@@ -634,6 +641,7 @@ class Mysql
|
|
634
641
|
@records = [] # all records
|
635
642
|
@index = 0 # index of record
|
636
643
|
@fieldname_with_table = nil
|
644
|
+
@fetched_record = nil
|
637
645
|
end
|
638
646
|
|
639
647
|
# ignore
|
@@ -839,6 +847,7 @@ class Mysql
|
|
839
847
|
@affected_rows = @insert_id = @server_status = @warning_count = 0
|
840
848
|
@sqlstate = "00000"
|
841
849
|
@param_count = nil
|
850
|
+
@bind_result = nil
|
842
851
|
end
|
843
852
|
|
844
853
|
# parse prepared-statement and return Mysql::Statement object
|
data/lib/mysql/charset.rb
CHANGED
@@ -181,6 +181,8 @@ class Mysql
|
|
181
181
|
CHARSET_DEFAULT[csname] = cs if default
|
182
182
|
end
|
183
183
|
|
184
|
+
BINARY_CHARSET_NUMBER = CHARSET_DEFAULT['binary'].number
|
185
|
+
|
184
186
|
def self.by_number(n)
|
185
187
|
raise ClientError, "unknown charset number: #{n}" unless NUMBER_TO_CHARSET.key? n
|
186
188
|
NUMBER_TO_CHARSET[n]
|
data/lib/mysql/error.rb
CHANGED
@@ -744,7 +744,7 @@ class Mysql
|
|
744
744
|
ER_ERROR_LAST = 1704
|
745
745
|
end
|
746
746
|
|
747
|
-
ServerError.define_error_class
|
747
|
+
ServerError.define_error_class(/\AER_/)
|
748
748
|
ServerError::ERROR_MAP.values.each{|v| Mysql.const_set v.name.split(/::/).last, v} # for compatibility
|
749
749
|
|
750
750
|
# client side error
|
@@ -813,7 +813,7 @@ class Mysql
|
|
813
813
|
CR_AUTH_PLUGIN_CANNOT_LOAD = 2059
|
814
814
|
end
|
815
815
|
|
816
|
-
ClientError.define_error_class
|
816
|
+
ClientError.define_error_class(/\ACR_/)
|
817
817
|
|
818
818
|
# protocol error
|
819
819
|
class ProtocolError < ClientError
|
data/lib/mysql/protocol.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2008-
|
1
|
+
# Copyright (C) 2008-2012 TOMITA Masahiro
|
2
2
|
# mailto:tommy@tmtm.org
|
3
3
|
|
4
4
|
require "socket"
|
@@ -201,6 +201,8 @@ class Mysql
|
|
201
201
|
# === Exception
|
202
202
|
# [ClientError] :: connection timeout
|
203
203
|
def initialize(host, port, socket, conn_timeout, read_timeout, write_timeout)
|
204
|
+
@insert_id = 0
|
205
|
+
@warning_count = 0
|
204
206
|
@gc_stmt_queue = [] # stmt id list which GC destroy.
|
205
207
|
set_state :INIT
|
206
208
|
@read_timeout = read_timeout
|
@@ -231,6 +233,8 @@ class Mysql
|
|
231
233
|
# db :: [String / nil] default database name. nil: no default.
|
232
234
|
# flag :: [Integer] client flag
|
233
235
|
# charset :: [Mysql::Charset / nil] charset for connection. nil: use server's charset
|
236
|
+
# === Exception
|
237
|
+
# ProtocolError :: The old style password is not supported
|
234
238
|
def authenticate(user, passwd, db, flag, charset)
|
235
239
|
check_state :INIT
|
236
240
|
@authinfo = [user, passwd, db, flag, charset]
|
@@ -249,7 +253,7 @@ class Mysql
|
|
249
253
|
end
|
250
254
|
netpw = encrypt_password passwd, init_packet.scramble_buff
|
251
255
|
write AuthenticationPacket.serialize(client_flags, 1024**3, @charset.number, user, netpw, db)
|
252
|
-
read
|
256
|
+
raise ProtocolError, 'The old style password is not supported' if read == "\xfe"
|
253
257
|
set_state :READY
|
254
258
|
end
|
255
259
|
|
@@ -510,7 +514,7 @@ class Mysql
|
|
510
514
|
v = self.class.net2value(data, f.type, unsigned)
|
511
515
|
if v.is_a? Numeric or v.is_a? Mysql::Time
|
512
516
|
v
|
513
|
-
elsif f.type == Field::TYPE_BIT or f.
|
517
|
+
elsif f.type == Field::TYPE_BIT or f.charsetnr == Charset::BINARY_CHARSET_NUMBER
|
514
518
|
Charset.to_binary(v)
|
515
519
|
else
|
516
520
|
Charset.convert_encoding(v, charset.encoding)
|
@@ -568,7 +572,12 @@ class Mysql
|
|
568
572
|
len = (len2 << 8) + len1
|
569
573
|
raise ProtocolError, "invalid packet: sequence number mismatch(#{seq} != #{@seq}(expected))" if @seq != seq
|
570
574
|
@seq = (@seq + 1) % 256
|
571
|
-
|
575
|
+
buf = ''.force_encoding('ASCII-8BIT')
|
576
|
+
l = len
|
577
|
+
while l > 0
|
578
|
+
ret.concat @sock.sysread(l, buf)
|
579
|
+
l -= buf.bytesize
|
580
|
+
end
|
572
581
|
end
|
573
582
|
rescue EOFError
|
574
583
|
raise ClientError::ServerGoneError, 'The MySQL server has gone away'
|
data/spec/mysql_spec.rb
ADDED
@@ -0,0 +1,1679 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift "#{File.dirname __FILE__}/../lib"
|
5
|
+
|
6
|
+
require "mysql"
|
7
|
+
|
8
|
+
# MYSQL_USER must have ALL privilege for MYSQL_DATABASE.* and RELOAD privilege for *.*
|
9
|
+
MYSQL_SERVER = ENV['MYSQL_SERVER']
|
10
|
+
MYSQL_USER = ENV['MYSQL_USER']
|
11
|
+
MYSQL_PASSWORD = ENV['MYSQL_PASSWORD']
|
12
|
+
MYSQL_DATABASE = ENV['MYSQL_DATABASE'] || "test_for_mysql_ruby"
|
13
|
+
MYSQL_PORT = ENV['MYSQL_PORT']
|
14
|
+
MYSQL_SOCKET = ENV['MYSQL_SOCKET']
|
15
|
+
|
16
|
+
describe 'Mysql::VERSION' do
|
17
|
+
it 'returns client version' do
|
18
|
+
Mysql::VERSION.should == 20904
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'Mysql.init' do
|
23
|
+
it 'returns Mysql object' do
|
24
|
+
Mysql.init.should be_kind_of Mysql
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'Mysql.real_connect' do
|
29
|
+
it 'connect to mysqld' do
|
30
|
+
@m = Mysql.real_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
31
|
+
@m.should be_kind_of Mysql
|
32
|
+
end
|
33
|
+
it 'flag argument affects' do
|
34
|
+
@m = Mysql.real_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET, Mysql::CLIENT_FOUND_ROWS)
|
35
|
+
@m.query 'create temporary table t (c int)'
|
36
|
+
@m.query 'insert into t values (123)'
|
37
|
+
@m.query 'update t set c=123'
|
38
|
+
@m.affected_rows.should == 1
|
39
|
+
end
|
40
|
+
after do
|
41
|
+
@m.close
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'Mysql.connect' do
|
46
|
+
it 'connect to mysqld' do
|
47
|
+
@m = Mysql.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
48
|
+
@m.should be_kind_of Mysql
|
49
|
+
end
|
50
|
+
after do
|
51
|
+
@m.close if @m
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'Mysql.new' do
|
56
|
+
it 'connect to mysqld' do
|
57
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
58
|
+
@m.should be_kind_of Mysql
|
59
|
+
end
|
60
|
+
after do
|
61
|
+
@m.close if @m
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'Mysql.escape_string' do
|
66
|
+
it 'escape special character' do
|
67
|
+
Mysql.escape_string("abc'def\"ghi\0jkl%mno").should == "abc\\'def\\\"ghi\\0jkl%mno"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'Mysql.quote' do
|
72
|
+
it 'escape special character' do
|
73
|
+
Mysql.quote("abc'def\"ghi\0jkl%mno").should == "abc\\'def\\\"ghi\\0jkl%mno"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'Mysql.client_info' do
|
78
|
+
it 'returns client version as string' do
|
79
|
+
Mysql.client_info.should == '5.0.0'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'Mysql.get_client_info' do
|
84
|
+
it 'returns client version as string' do
|
85
|
+
Mysql.get_client_info.should == '5.0.0'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'Mysql.client_version' do
|
90
|
+
it 'returns client version as Integer' do
|
91
|
+
Mysql.client_version.should == 50000
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'Mysql.get_client_version' do
|
96
|
+
it 'returns client version as Integer' do
|
97
|
+
Mysql.client_version.should == 50000
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'Mysql#real_connect' do
|
102
|
+
it 'connect to mysqld' do
|
103
|
+
@m = Mysql.init
|
104
|
+
@m.real_connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET).should == @m
|
105
|
+
end
|
106
|
+
after do
|
107
|
+
@m.close if @m
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'Mysql#connect' do
|
112
|
+
it 'connect to mysqld' do
|
113
|
+
@m = Mysql.init
|
114
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET).should == @m
|
115
|
+
end
|
116
|
+
after do
|
117
|
+
@m.close if @m
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'Mysql#options' do
|
122
|
+
before do
|
123
|
+
@m = Mysql.init
|
124
|
+
end
|
125
|
+
after do
|
126
|
+
@m.close
|
127
|
+
end
|
128
|
+
it 'INIT_COMMAND: execute query when connecting' do
|
129
|
+
@m.options(Mysql::INIT_COMMAND, "SET AUTOCOMMIT=0").should == @m
|
130
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET).should == @m
|
131
|
+
@m.query('select @@AUTOCOMMIT').fetch_row.should == ["0"]
|
132
|
+
end
|
133
|
+
it 'OPT_CONNECT_TIMEOUT: set timeout for connecting' do
|
134
|
+
@m.options(Mysql::OPT_CONNECT_TIMEOUT, 0.1).should == @m
|
135
|
+
UNIXSocket.stub!(:new).and_return{sleep 1}
|
136
|
+
TCPSocket.stub!(:new).and_return{sleep 1}
|
137
|
+
proc{@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)}.should raise_error Mysql::ClientError, 'connection timeout'
|
138
|
+
proc{@m.connect}.should raise_error Mysql::ClientError, 'connection timeout'
|
139
|
+
end
|
140
|
+
it 'OPT_LOCAL_INFILE: client can execute LOAD DATA LOCAL INFILE query' do
|
141
|
+
tmpf = Tempfile.new 'mysql_spec'
|
142
|
+
tmpf.puts "123\tabc\n"
|
143
|
+
tmpf.close
|
144
|
+
@m.options(Mysql::OPT_LOCAL_INFILE, true).should == @m
|
145
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
146
|
+
@m.query('create temporary table t (i int, c char(10))')
|
147
|
+
@m.query("load data local infile '#{tmpf.path}' into table t")
|
148
|
+
@m.query('select * from t').fetch_row.should == ['123','abc']
|
149
|
+
end
|
150
|
+
it 'OPT_READ_TIMEOUT: set timeout for reading packet' do
|
151
|
+
@m.options(Mysql::OPT_READ_TIMEOUT, 10).should == @m
|
152
|
+
end
|
153
|
+
it 'OPT_WRITE_TIMEOUT: set timeout for writing packet' do
|
154
|
+
@m.options(Mysql::OPT_WRITE_TIMEOUT, 10).should == @m
|
155
|
+
end
|
156
|
+
it 'SET_CHARSET_NAME: set charset for connection' do
|
157
|
+
@m.options(Mysql::SET_CHARSET_NAME, 'utf8').should == @m
|
158
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
159
|
+
@m.query('select @@character_set_connection').fetch_row.should == ['utf8']
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe 'Mysql' do
|
164
|
+
before do
|
165
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
166
|
+
end
|
167
|
+
|
168
|
+
after do
|
169
|
+
@m.close if @m rescue nil
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#escape_string' do
|
173
|
+
if defined? ::Encoding
|
174
|
+
it 'escape special character for charset' do
|
175
|
+
@m.charset = 'cp932'
|
176
|
+
@m.escape_string("abc'def\"ghi\0jkl%mno_表".encode('cp932')).should == "abc\\'def\\\"ghi\\0jkl%mno_表".encode('cp932')
|
177
|
+
end
|
178
|
+
else
|
179
|
+
it 'raise error if charset is multibyte' do
|
180
|
+
@m.charset = 'cp932'
|
181
|
+
proc{@m.escape_string("abc'def\"ghi\0jkl%mno_\x95\\")}.should raise_error(Mysql::ClientError, 'Mysql#escape_string is called for unsafe multibyte charset')
|
182
|
+
end
|
183
|
+
it 'not warn if charset is singlebyte' do
|
184
|
+
@m.charset = 'latin1'
|
185
|
+
@m.escape_string("abc'def\"ghi\0jkl%mno_\x95\\").should == "abc\\'def\\\"ghi\\0jkl%mno_\x95\\\\"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe '#quote' do
|
191
|
+
it 'is alias of #escape_string' do
|
192
|
+
@m.method(:quote).should == @m.method(:escape_string)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#client_info' do
|
197
|
+
it 'returns client version as string' do
|
198
|
+
@m.client_info.should == '5.0.0'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe '#get_client_info' do
|
203
|
+
it 'returns client version as string' do
|
204
|
+
@m.get_client_info.should == '5.0.0'
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe '#affected_rows' do
|
209
|
+
it 'returns number of affected rows' do
|
210
|
+
@m.query 'create temporary table t (id int)'
|
211
|
+
@m.query 'insert into t values (1),(2)'
|
212
|
+
@m.affected_rows.should == 2
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe '#character_set_name' do
|
217
|
+
it 'returns charset name' do
|
218
|
+
m = Mysql.init
|
219
|
+
m.options Mysql::SET_CHARSET_NAME, 'cp932'
|
220
|
+
m.connect MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET
|
221
|
+
m.character_set_name.should == 'cp932'
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe '#close' do
|
226
|
+
it 'returns self' do
|
227
|
+
@m.close.should == @m
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#close!' do
|
232
|
+
it 'returns self' do
|
233
|
+
@m.close!.should == @m
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# describe '#create_db' do
|
238
|
+
# end
|
239
|
+
|
240
|
+
# describe '#drop_db' do
|
241
|
+
# end
|
242
|
+
|
243
|
+
describe '#errno' do
|
244
|
+
it 'default value is 0' do
|
245
|
+
@m.errno.should == 0
|
246
|
+
end
|
247
|
+
it 'returns error number of latest error' do
|
248
|
+
@m.query('hogehoge') rescue nil
|
249
|
+
@m.errno.should == 1064
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#error' do
|
254
|
+
it 'returns error message of latest error' do
|
255
|
+
@m.query('hogehoge') rescue nil
|
256
|
+
@m.error.should == "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'hogehoge' at line 1"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe '#field_count' do
|
261
|
+
it 'returns number of fields for latest query' do
|
262
|
+
@m.query 'select 1,2,3'
|
263
|
+
@m.field_count.should == 3
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#client_version' do
|
268
|
+
it 'returns client version as Integer' do
|
269
|
+
@m.client_version.should be_kind_of Integer
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
describe '#get_client_version' do
|
274
|
+
it 'returns client version as Integer' do
|
275
|
+
@m.get_client_version.should be_kind_of Integer
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe '#get_host_info' do
|
280
|
+
it 'returns connection type as String' do
|
281
|
+
if MYSQL_SERVER == nil or MYSQL_SERVER == 'localhost'
|
282
|
+
@m.get_host_info.should == 'Localhost via UNIX socket'
|
283
|
+
else
|
284
|
+
@m.get_host_info.should == "#{MYSQL_SERVER} via TCP/IP"
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
describe '#host_info' do
|
290
|
+
it 'returns connection type as String' do
|
291
|
+
if MYSQL_SERVER == nil or MYSQL_SERVER == 'localhost'
|
292
|
+
@m.host_info.should == 'Localhost via UNIX socket'
|
293
|
+
else
|
294
|
+
@m.host_info.should == "#{MYSQL_SERVER} via TCP/IP"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
describe '#get_proto_info' do
|
300
|
+
it 'returns version of connection as Integer' do
|
301
|
+
@m.get_proto_info.should == 10
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
describe '#proto_info' do
|
306
|
+
it 'returns version of connection as Integer' do
|
307
|
+
@m.proto_info.should == 10
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
describe '#get_server_info' do
|
312
|
+
it 'returns server version as String' do
|
313
|
+
@m.get_server_info.should =~ /\A\d+\.\d+\.\d+/
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe '#server_info' do
|
318
|
+
it 'returns server version as String' do
|
319
|
+
@m.server_info.should =~ /\A\d+\.\d+\.\d+/
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe '#info' do
|
324
|
+
it 'returns information of latest query' do
|
325
|
+
@m.query 'create temporary table t (id int)'
|
326
|
+
@m.query 'insert into t values (1),(2),(3)'
|
327
|
+
@m.info.should == 'Records: 3 Duplicates: 0 Warnings: 0'
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
describe '#insert_id' do
|
332
|
+
it 'returns latest auto_increment value' do
|
333
|
+
@m.query 'create temporary table t (id int auto_increment, unique (id))'
|
334
|
+
@m.query 'insert into t values (0)'
|
335
|
+
@m.insert_id.should == 1
|
336
|
+
@m.query 'alter table t auto_increment=1234'
|
337
|
+
@m.query 'insert into t values (0)'
|
338
|
+
@m.insert_id.should == 1234
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe '#kill' do
|
343
|
+
it 'returns self' do
|
344
|
+
@m.kill(@m.thread_id).should == @m
|
345
|
+
end
|
346
|
+
it 'kill specified connection' do
|
347
|
+
m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
348
|
+
m.list_processes.map(&:first).should be_include @m.thread_id.to_s
|
349
|
+
m.close
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
describe '#list_dbs' do
|
354
|
+
it 'returns database list' do
|
355
|
+
ret = @m.list_dbs
|
356
|
+
ret.should be_kind_of Array
|
357
|
+
ret.should be_include MYSQL_DATABASE
|
358
|
+
end
|
359
|
+
it 'with pattern returns databases that matches pattern' do
|
360
|
+
@m.list_dbs('info%').should be_include 'information_schema'
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe '#list_fields' do
|
365
|
+
before do
|
366
|
+
@m.query 'create temporary table t (i int, c char(10), d date)'
|
367
|
+
end
|
368
|
+
it 'returns result set that contains information of fields' do
|
369
|
+
ret = @m.list_fields('t')
|
370
|
+
ret.should be_kind_of Mysql::Result
|
371
|
+
ret.num_rows.should == 0
|
372
|
+
ret.fetch_fields.map{|f|f.name}.should == ['i','c','d']
|
373
|
+
end
|
374
|
+
it 'with pattern returns result set that contains information of fields that matches pattern' do
|
375
|
+
ret = @m.list_fields('t', 'i')
|
376
|
+
ret.should be_kind_of Mysql::Result
|
377
|
+
ret.num_rows.should == 0
|
378
|
+
ret.fetch_fields.map{|f|f.name}.should == ['i']
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
describe '#list_processes' do
|
383
|
+
it 'returns result set that contains information of all connections' do
|
384
|
+
ret = @m.list_processes
|
385
|
+
ret.should be_kind_of Mysql::Result
|
386
|
+
ret.find{|r|r[0].to_i == @m.thread_id}[4].should == "Processlist"
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
describe '#list_tables' do
|
391
|
+
before do
|
392
|
+
@m.query 'create table test_mysql_list_tables (id int)'
|
393
|
+
end
|
394
|
+
after do
|
395
|
+
@m.query 'drop table test_mysql_list_tables'
|
396
|
+
end
|
397
|
+
it 'returns table list' do
|
398
|
+
ret = @m.list_tables
|
399
|
+
ret.should be_kind_of Array
|
400
|
+
ret.should be_include 'test_mysql_list_tables'
|
401
|
+
end
|
402
|
+
it 'with pattern returns lists that matches pattern' do
|
403
|
+
ret = @m.list_tables '%mysql\_list\_t%'
|
404
|
+
ret.should be_include 'test_mysql_list_tables'
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
describe '#ping' do
|
409
|
+
it 'returns self' do
|
410
|
+
@m.ping.should == @m
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
describe '#query' do
|
415
|
+
it 'returns Mysql::Result if query returns results' do
|
416
|
+
@m.query('select 123').should be_kind_of Mysql::Result
|
417
|
+
end
|
418
|
+
it 'returns nil if query returns no results' do
|
419
|
+
@m.query('set @hoge:=123').should == nil
|
420
|
+
end
|
421
|
+
it 'returns self if query_with_result is false' do
|
422
|
+
@m.query_with_result = false
|
423
|
+
@m.query('select 123').should == @m
|
424
|
+
@m.store_result
|
425
|
+
@m.query('set @hoge:=123').should == @m
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
describe '#real_query' do
|
430
|
+
it 'is same as #query' do
|
431
|
+
@m.real_query('select 123').should be_kind_of Mysql::Result
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
describe '#refresh' do
|
436
|
+
it 'returns self' do
|
437
|
+
@m.refresh(Mysql::REFRESH_HOSTS).should == @m
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
describe '#reload' do
|
442
|
+
it 'returns self' do
|
443
|
+
@m.reload.should == @m
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
describe '#select_db' do
|
448
|
+
it 'changes default database' do
|
449
|
+
@m.select_db 'information_schema'
|
450
|
+
@m.query('select database()').fetch_row.first.should == 'information_schema'
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
# describe '#shutdown' do
|
455
|
+
# end
|
456
|
+
|
457
|
+
describe '#stat' do
|
458
|
+
it 'returns server status' do
|
459
|
+
@m.stat.should =~ /\AUptime: \d+ Threads: \d+ Questions: \d+ Slow queries: \d+ Opens: \d+ Flush tables: \d+ Open tables: \d+ Queries per second avg: \d+\.\d+\z/
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
describe '#store_result' do
|
464
|
+
it 'returns Mysql::Result' do
|
465
|
+
@m.query_with_result = false
|
466
|
+
@m.query 'select 1,2,3'
|
467
|
+
ret = @m.store_result
|
468
|
+
ret.should be_kind_of Mysql::Result
|
469
|
+
ret.fetch_row.should == ['1','2','3']
|
470
|
+
end
|
471
|
+
it 'raises error when no query' do
|
472
|
+
proc{@m.store_result}.should raise_error Mysql::Error
|
473
|
+
end
|
474
|
+
it 'raises error when query does not return results' do
|
475
|
+
@m.query 'set @hoge:=123'
|
476
|
+
proc{@m.store_result}.should raise_error Mysql::Error
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
describe '#thread_id' do
|
481
|
+
it 'returns thread id as Integer' do
|
482
|
+
@m.thread_id.should be_kind_of Integer
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
describe '#use_result' do
|
487
|
+
it 'returns Mysql::Result' do
|
488
|
+
@m.query_with_result = false
|
489
|
+
@m.query 'select 1,2,3'
|
490
|
+
ret = @m.use_result
|
491
|
+
ret.should be_kind_of Mysql::Result
|
492
|
+
ret.fetch_row.should == ['1','2','3']
|
493
|
+
end
|
494
|
+
it 'raises error when no query' do
|
495
|
+
proc{@m.use_result}.should raise_error Mysql::Error
|
496
|
+
end
|
497
|
+
it 'raises error when query does not return results' do
|
498
|
+
@m.query 'set @hoge:=123'
|
499
|
+
proc{@m.use_result}.should raise_error Mysql::Error
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
describe '#get_server_version' do
|
504
|
+
it 'returns server version as Integer' do
|
505
|
+
@m.get_server_version.should be_kind_of Integer
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
describe '#server_version' do
|
510
|
+
it 'returns server version as Integer' do
|
511
|
+
@m.server_version.should be_kind_of Integer
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
describe '#warning_count' do
|
516
|
+
it 'default values is zero' do
|
517
|
+
@m.warning_count.should == 0
|
518
|
+
end
|
519
|
+
it 'returns number of warnings' do
|
520
|
+
@m.query 'create temporary table t (i tinyint)'
|
521
|
+
@m.query 'insert into t values (1234567)'
|
522
|
+
@m.warning_count.should == 1
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
describe '#commit' do
|
527
|
+
it 'returns self' do
|
528
|
+
@m.commit.should == @m
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
describe '#rollback' do
|
533
|
+
it 'returns self' do
|
534
|
+
@m.rollback.should == @m
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
describe '#autocommit' do
|
539
|
+
it 'returns self' do
|
540
|
+
@m.autocommit(true).should == @m
|
541
|
+
end
|
542
|
+
|
543
|
+
it 'change auto-commit mode' do
|
544
|
+
@m.autocommit(true)
|
545
|
+
@m.query('select @@autocommit').fetch_row.should == ['1']
|
546
|
+
@m.autocommit(false)
|
547
|
+
@m.query('select @@autocommit').fetch_row.should == ['0']
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
describe '#set_server_option' do
|
552
|
+
it 'returns self' do
|
553
|
+
@m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON).should == @m
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
describe '#sqlstate' do
|
558
|
+
it 'default values is "00000"' do
|
559
|
+
@m.sqlstate.should == "00000"
|
560
|
+
end
|
561
|
+
it 'returns sqlstate code' do
|
562
|
+
proc{@m.query("hoge")}.should raise_error
|
563
|
+
@m.sqlstate.should == "42000"
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
describe '#query_with_result' do
|
568
|
+
it 'default value is true' do
|
569
|
+
@m.query_with_result.should == true
|
570
|
+
end
|
571
|
+
it 'can set value' do
|
572
|
+
(@m.query_with_result=true).should == true
|
573
|
+
@m.query_with_result.should == true
|
574
|
+
(@m.query_with_result=false).should == false
|
575
|
+
@m.query_with_result.should == false
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
describe '#query_with_result is false' do
|
580
|
+
it 'Mysql#query returns self and Mysql#store_result returns result set' do
|
581
|
+
@m.query_with_result = false
|
582
|
+
@m.query('select 1,2,3').should == @m
|
583
|
+
res = @m.store_result
|
584
|
+
res.fetch_row.should == ['1','2','3']
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
describe '#query with block' do
|
589
|
+
it 'returns self' do
|
590
|
+
@m.query('select 1'){}.should == @m
|
591
|
+
end
|
592
|
+
it 'evaluate block with Mysql::Result' do
|
593
|
+
@m.query('select 1'){|res| res.should be_kind_of Mysql::Result}.should == @m
|
594
|
+
end
|
595
|
+
it 'evaluate block multiple times if multiple query is specified' do
|
596
|
+
@m.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
|
597
|
+
cnt = 0
|
598
|
+
expect = [["1"], ["2"]]
|
599
|
+
@m.query('select 1; select 2'){|res|
|
600
|
+
res.fetch_row.should == expect.shift
|
601
|
+
cnt += 1
|
602
|
+
}.should == @m
|
603
|
+
cnt.should == 2
|
604
|
+
end
|
605
|
+
it 'evaluate block only when query has result' do
|
606
|
+
@m.set_server_option Mysql::OPTION_MULTI_STATEMENTS_ON
|
607
|
+
cnt = 0
|
608
|
+
expect = [["1"], ["2"]]
|
609
|
+
@m.query('select 1; set @hoge:=1; select 2'){|res|
|
610
|
+
res.fetch_row.should == expect.shift
|
611
|
+
cnt += 1
|
612
|
+
}.should == @m
|
613
|
+
cnt.should == 2
|
614
|
+
end
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
describe 'multiple statement query:' do
|
619
|
+
before :all do
|
620
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
621
|
+
@m.set_server_option(Mysql::OPTION_MULTI_STATEMENTS_ON)
|
622
|
+
@res = @m.query 'select 1,2; select 3,4,5'
|
623
|
+
end
|
624
|
+
it 'Mysql#query returns results for first query' do
|
625
|
+
@res.entries.should == [['1','2']]
|
626
|
+
end
|
627
|
+
it 'Mysql#more_results is true' do
|
628
|
+
@m.more_results.should == true
|
629
|
+
end
|
630
|
+
it 'Mysql#more_results? is true' do
|
631
|
+
@m.more_results?.should == true
|
632
|
+
end
|
633
|
+
it 'Mysql#next_result is true' do
|
634
|
+
@m.next_result.should == true
|
635
|
+
end
|
636
|
+
it 'Mysql#store_result returns results for next query' do
|
637
|
+
res = @m.store_result
|
638
|
+
res.entries.should == [['3','4','5']]
|
639
|
+
end
|
640
|
+
it 'Mysql#more_results is false' do
|
641
|
+
@m.more_results.should == false
|
642
|
+
end
|
643
|
+
it 'Mysql#more_results? is false' do
|
644
|
+
@m.more_results?.should == false
|
645
|
+
end
|
646
|
+
it 'Mysql#next_result is false' do
|
647
|
+
@m.next_result.should == false
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
describe 'Mysql::Result' do
|
652
|
+
before do
|
653
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
654
|
+
@m.query 'create temporary table t (id int, str char(10), primary key (id))'
|
655
|
+
@m.query "insert into t values (1,'abc'),(2,'defg'),(3,'hi'),(4,null)"
|
656
|
+
@res = @m.query 'select * from t'
|
657
|
+
end
|
658
|
+
|
659
|
+
after do
|
660
|
+
@m.close if @m
|
661
|
+
end
|
662
|
+
|
663
|
+
it '#data_seek set position of current record' do
|
664
|
+
@res.fetch_row.should == ['1', 'abc']
|
665
|
+
@res.fetch_row.should == ['2', 'defg']
|
666
|
+
@res.fetch_row.should == ['3', 'hi']
|
667
|
+
@res.data_seek 1
|
668
|
+
@res.fetch_row.should == ['2', 'defg']
|
669
|
+
end
|
670
|
+
|
671
|
+
it '#fetch_field return current field' do
|
672
|
+
f = @res.fetch_field
|
673
|
+
f.name.should == 'id'
|
674
|
+
f.table.should == 't'
|
675
|
+
f.def.should == nil
|
676
|
+
f.type.should == Mysql::Field::TYPE_LONG
|
677
|
+
f.length.should == 11
|
678
|
+
f.max_length == 1
|
679
|
+
f.flags.should == Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG
|
680
|
+
f.decimals.should == 0
|
681
|
+
|
682
|
+
f = @res.fetch_field
|
683
|
+
f.name.should == 'str'
|
684
|
+
f.table.should == 't'
|
685
|
+
f.def.should == nil
|
686
|
+
f.type.should == Mysql::Field::TYPE_STRING
|
687
|
+
f.length.should == 10
|
688
|
+
f.max_length == 4
|
689
|
+
f.flags.should == 0
|
690
|
+
f.decimals.should == 0
|
691
|
+
|
692
|
+
@res.fetch_field.should == nil
|
693
|
+
end
|
694
|
+
|
695
|
+
it '#fetch_fields returns array of fields' do
|
696
|
+
ret = @res.fetch_fields
|
697
|
+
ret.size.should == 2
|
698
|
+
ret[0].name.should == 'id'
|
699
|
+
ret[1].name.should == 'str'
|
700
|
+
end
|
701
|
+
|
702
|
+
it '#fetch_field_direct returns field' do
|
703
|
+
f = @res.fetch_field_direct 0
|
704
|
+
f.name.should == 'id'
|
705
|
+
f = @res.fetch_field_direct 1
|
706
|
+
f.name.should == 'str'
|
707
|
+
proc{@res.fetch_field_direct(-1)}.should raise_error Mysql::ClientError, 'invalid argument: -1'
|
708
|
+
proc{@res.fetch_field_direct 2}.should raise_error Mysql::ClientError, 'invalid argument: 2'
|
709
|
+
end
|
710
|
+
|
711
|
+
it '#fetch_lengths returns array of length of field data' do
|
712
|
+
@res.fetch_lengths.should == nil
|
713
|
+
@res.fetch_row
|
714
|
+
@res.fetch_lengths.should == [1, 3]
|
715
|
+
@res.fetch_row
|
716
|
+
@res.fetch_lengths.should == [1, 4]
|
717
|
+
@res.fetch_row
|
718
|
+
@res.fetch_lengths.should == [1, 2]
|
719
|
+
@res.fetch_row
|
720
|
+
@res.fetch_lengths.should == [1, 0]
|
721
|
+
@res.fetch_row
|
722
|
+
@res.fetch_lengths.should == nil
|
723
|
+
end
|
724
|
+
|
725
|
+
it '#fetch_row returns one record as array for current record' do
|
726
|
+
@res.fetch_row.should == ['1', 'abc']
|
727
|
+
@res.fetch_row.should == ['2', 'defg']
|
728
|
+
@res.fetch_row.should == ['3', 'hi']
|
729
|
+
@res.fetch_row.should == ['4', nil]
|
730
|
+
@res.fetch_row.should == nil
|
731
|
+
end
|
732
|
+
|
733
|
+
it '#fetch_hash returns one record as hash for current record' do
|
734
|
+
@res.fetch_hash.should == {'id'=>'1', 'str'=>'abc'}
|
735
|
+
@res.fetch_hash.should == {'id'=>'2', 'str'=>'defg'}
|
736
|
+
@res.fetch_hash.should == {'id'=>'3', 'str'=>'hi'}
|
737
|
+
@res.fetch_hash.should == {'id'=>'4', 'str'=>nil}
|
738
|
+
@res.fetch_hash.should == nil
|
739
|
+
end
|
740
|
+
|
741
|
+
it '#fetch_hash(true) returns with table name' do
|
742
|
+
@res.fetch_hash(true).should == {'t.id'=>'1', 't.str'=>'abc'}
|
743
|
+
@res.fetch_hash(true).should == {'t.id'=>'2', 't.str'=>'defg'}
|
744
|
+
@res.fetch_hash(true).should == {'t.id'=>'3', 't.str'=>'hi'}
|
745
|
+
@res.fetch_hash(true).should == {'t.id'=>'4', 't.str'=>nil}
|
746
|
+
@res.fetch_hash(true).should == nil
|
747
|
+
end
|
748
|
+
|
749
|
+
it '#num_fields returns number of fields' do
|
750
|
+
@res.num_fields.should == 2
|
751
|
+
end
|
752
|
+
|
753
|
+
it '#num_rows returns number of records' do
|
754
|
+
@res.num_rows.should == 4
|
755
|
+
end
|
756
|
+
|
757
|
+
it '#each iterate block with a record' do
|
758
|
+
expect = [["1","abc"], ["2","defg"], ["3","hi"], ["4",nil]]
|
759
|
+
@res.each do |a|
|
760
|
+
a.should == expect.shift
|
761
|
+
end
|
762
|
+
end
|
763
|
+
|
764
|
+
it '#each_hash iterate block with a hash' do
|
765
|
+
expect = [{"id"=>"1","str"=>"abc"}, {"id"=>"2","str"=>"defg"}, {"id"=>"3","str"=>"hi"}, {"id"=>"4","str"=>nil}]
|
766
|
+
@res.each_hash do |a|
|
767
|
+
a.should == expect.shift
|
768
|
+
end
|
769
|
+
end
|
770
|
+
|
771
|
+
it '#each_hash(true): hash key has table name' do
|
772
|
+
expect = [{"t.id"=>"1","t.str"=>"abc"}, {"t.id"=>"2","t.str"=>"defg"}, {"t.id"=>"3","t.str"=>"hi"}, {"t.id"=>"4","t.str"=>nil}]
|
773
|
+
@res.each_hash(true) do |a|
|
774
|
+
a.should == expect.shift
|
775
|
+
end
|
776
|
+
end
|
777
|
+
|
778
|
+
it '#row_tell returns position of current record, #row_seek set position of current record' do
|
779
|
+
@res.fetch_row.should == ['1', 'abc']
|
780
|
+
pos = @res.row_tell
|
781
|
+
@res.fetch_row.should == ['2', 'defg']
|
782
|
+
@res.fetch_row.should == ['3', 'hi']
|
783
|
+
@res.row_seek pos
|
784
|
+
@res.fetch_row.should == ['2', 'defg']
|
785
|
+
end
|
786
|
+
|
787
|
+
it '#field_tell returns position of current field, #field_seek set position of current field' do
|
788
|
+
@res.field_tell.should == 0
|
789
|
+
@res.fetch_field
|
790
|
+
@res.field_tell.should == 1
|
791
|
+
@res.fetch_field
|
792
|
+
@res.field_tell.should == 2
|
793
|
+
@res.field_seek 1
|
794
|
+
@res.field_tell.should == 1
|
795
|
+
end
|
796
|
+
|
797
|
+
it '#free returns nil' do
|
798
|
+
@res.free.should == nil
|
799
|
+
end
|
800
|
+
|
801
|
+
it '#num_fields returns number of fields' do
|
802
|
+
@res.num_fields.should == 2
|
803
|
+
end
|
804
|
+
|
805
|
+
it '#num_rows returns number of records' do
|
806
|
+
@res.num_rows.should == 4
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
describe 'Mysql::Field' do
|
811
|
+
before do
|
812
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
813
|
+
@m.query 'create temporary table t (id int default 0, str char(10), primary key (id))'
|
814
|
+
@m.query "insert into t values (1,'abc'),(2,'defg'),(3,'hi'),(4,null)"
|
815
|
+
@res = @m.query 'select * from t'
|
816
|
+
end
|
817
|
+
|
818
|
+
after do
|
819
|
+
@m.close if @m
|
820
|
+
end
|
821
|
+
|
822
|
+
it '#name is name of field' do
|
823
|
+
@res.fetch_field.name.should == 'id'
|
824
|
+
end
|
825
|
+
|
826
|
+
it '#table is name of table for field' do
|
827
|
+
@res.fetch_field.table.should == 't'
|
828
|
+
end
|
829
|
+
|
830
|
+
it '#def for result set is null' do
|
831
|
+
@res.fetch_field.def.should == nil
|
832
|
+
end
|
833
|
+
|
834
|
+
it '#def for field information is default value' do
|
835
|
+
@m.list_fields('t').fetch_field.def.should == '0'
|
836
|
+
end
|
837
|
+
|
838
|
+
it '#type is type of field as Integer' do
|
839
|
+
@res.fetch_field.type.should == Mysql::Field::TYPE_LONG
|
840
|
+
@res.fetch_field.type.should == Mysql::Field::TYPE_STRING
|
841
|
+
end
|
842
|
+
|
843
|
+
it '#length is length of field' do
|
844
|
+
@res.fetch_field.length.should == 11
|
845
|
+
@res.fetch_field.length.should == 10
|
846
|
+
end
|
847
|
+
|
848
|
+
it '#max_length is maximum length of field value' do
|
849
|
+
@res.fetch_field.max_length.should == 1
|
850
|
+
@res.fetch_field.max_length.should == 4
|
851
|
+
end
|
852
|
+
|
853
|
+
it '#flags is flag of field as Integer' do
|
854
|
+
@res.fetch_field.flags.should == Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG
|
855
|
+
@res.fetch_field.flags.should == 0
|
856
|
+
end
|
857
|
+
|
858
|
+
it '#decimals is number of decimal digits' do
|
859
|
+
@m.query('select 1.23').fetch_field.decimals.should == 2
|
860
|
+
end
|
861
|
+
|
862
|
+
it '#hash return field as hash' do
|
863
|
+
@res.fetch_field.hash.should == {
|
864
|
+
'name' => 'id',
|
865
|
+
'table' => 't',
|
866
|
+
'def' => nil,
|
867
|
+
'type' => Mysql::Field::TYPE_LONG,
|
868
|
+
'length' => 11,
|
869
|
+
'max_length' => 1,
|
870
|
+
'flags' => Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG,
|
871
|
+
'decimals' => 0,
|
872
|
+
}
|
873
|
+
@res.fetch_field.hash.should == {
|
874
|
+
'name' => 'str',
|
875
|
+
'table' => 't',
|
876
|
+
'def' => nil,
|
877
|
+
'type' => Mysql::Field::TYPE_STRING,
|
878
|
+
'length' => 10,
|
879
|
+
'max_length' => 4,
|
880
|
+
'flags' => 0,
|
881
|
+
'decimals' => 0,
|
882
|
+
}
|
883
|
+
end
|
884
|
+
|
885
|
+
it '#inspect returns "#<Mysql::Field:name>"' do
|
886
|
+
@res.fetch_field.inspect.should == '#<Mysql::Field:id>'
|
887
|
+
@res.fetch_field.inspect.should == '#<Mysql::Field:str>'
|
888
|
+
end
|
889
|
+
|
890
|
+
it '#is_num? returns true if the field is numeric' do
|
891
|
+
@res.fetch_field.is_num?.should == true
|
892
|
+
@res.fetch_field.is_num?.should == false
|
893
|
+
end
|
894
|
+
|
895
|
+
it '#is_not_null? returns true if the field is not null' do
|
896
|
+
@res.fetch_field.is_not_null?.should == true
|
897
|
+
@res.fetch_field.is_not_null?.should == false
|
898
|
+
end
|
899
|
+
|
900
|
+
it '#is_pri_key? returns true if the field is primary key' do
|
901
|
+
@res.fetch_field.is_pri_key?.should == true
|
902
|
+
@res.fetch_field.is_pri_key?.should == false
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
describe 'create Mysql::Stmt object:' do
|
907
|
+
before do
|
908
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
909
|
+
end
|
910
|
+
|
911
|
+
after do
|
912
|
+
@m.close if @m
|
913
|
+
end
|
914
|
+
|
915
|
+
it 'Mysql#stmt_init returns Mysql::Stmt object' do
|
916
|
+
@m.stmt_init.should be_kind_of Mysql::Stmt
|
917
|
+
end
|
918
|
+
|
919
|
+
it 'Mysq;#prepare returns Mysql::Stmt object' do
|
920
|
+
@m.prepare("select 1").should be_kind_of Mysql::Stmt
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
describe 'Mysql::Stmt' do
|
925
|
+
before do
|
926
|
+
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
927
|
+
@s = @m.stmt_init
|
928
|
+
end
|
929
|
+
|
930
|
+
after do
|
931
|
+
@s.close if @s rescue nil
|
932
|
+
@m.close if @m
|
933
|
+
end
|
934
|
+
|
935
|
+
it '#affected_rows returns number of affected records' do
|
936
|
+
@m.query 'create temporary table t (i int, c char(10))'
|
937
|
+
@s.prepare 'insert into t values (?,?)'
|
938
|
+
@s.execute 1, 'hoge'
|
939
|
+
@s.affected_rows.should == 1
|
940
|
+
@s.execute 2, 'hoge'
|
941
|
+
@s.execute 3, 'hoge'
|
942
|
+
@s.prepare 'update t set c=?'
|
943
|
+
@s.execute 'fuga'
|
944
|
+
@s.affected_rows.should == 3
|
945
|
+
end
|
946
|
+
|
947
|
+
describe '#bind_result' do
|
948
|
+
before do
|
949
|
+
@m.query 'create temporary table t (i int, c char(10), d double, t datetime)'
|
950
|
+
@m.query 'insert into t values (123,"9abcdefg",1.2345,20091208100446)'
|
951
|
+
@s.prepare 'select * from t'
|
952
|
+
end
|
953
|
+
|
954
|
+
it '(nil) make result format to be standard value' do
|
955
|
+
@s.bind_result nil, nil, nil, nil
|
956
|
+
@s.execute
|
957
|
+
@s.fetch.should == [123, '9abcdefg', 1.2345, Mysql::Time.new(2009,12,8,10,4,46)]
|
958
|
+
end
|
959
|
+
|
960
|
+
it '(Numeric) make result format to be Integer value' do
|
961
|
+
@s.bind_result Numeric, Numeric, Numeric, Numeric
|
962
|
+
@s.execute
|
963
|
+
@s.fetch.should == [123, 9, 1, 20091208100446]
|
964
|
+
end
|
965
|
+
|
966
|
+
it '(Integer) make result format to be Integer value' do
|
967
|
+
@s.bind_result Integer, Integer, Integer, Integer
|
968
|
+
@s.execute
|
969
|
+
@s.fetch.should == [123, 9, 1, 20091208100446]
|
970
|
+
end
|
971
|
+
|
972
|
+
it '(Fixnum) make result format to be Integer value' do
|
973
|
+
@s.bind_result Fixnum, Fixnum, Fixnum, Fixnum
|
974
|
+
@s.execute
|
975
|
+
@s.fetch.should == [123, 9, 1, 20091208100446]
|
976
|
+
end
|
977
|
+
|
978
|
+
it '(String) make result format to be String value' do
|
979
|
+
@s.bind_result String, String, String, String
|
980
|
+
@s.execute
|
981
|
+
@s.fetch.should == ["123", "9abcdefg", "1.2345", "2009-12-08 10:04:46"]
|
982
|
+
end
|
983
|
+
|
984
|
+
it '(Float) make result format to be Float value' do
|
985
|
+
@s.bind_result Float, Float, Float, Float
|
986
|
+
@s.execute
|
987
|
+
@s.fetch.should == [123.0, 9.0, 1.2345 , 20091208100446.0]
|
988
|
+
end
|
989
|
+
|
990
|
+
it '(Mysql::Time) make result format to be Mysql::Time value' do
|
991
|
+
@s.bind_result Mysql::Time, Mysql::Time, Mysql::Time, Mysql::Time
|
992
|
+
@s.execute
|
993
|
+
@s.fetch.should == [Mysql::Time.new(2000,1,23), Mysql::Time.new, Mysql::Time.new, Mysql::Time.new(2009,12,8,10,4,46)]
|
994
|
+
end
|
995
|
+
|
996
|
+
it '(invalid) raises error' do
|
997
|
+
proc{@s.bind_result(Time, nil, nil, nil)}.should raise_error(TypeError)
|
998
|
+
end
|
999
|
+
|
1000
|
+
it 'with mismatch argument count raise error' do
|
1001
|
+
proc{@s.bind_result(nil)}.should raise_error(Mysql::ClientError, 'bind_result: result value count(4) != number of argument(1)')
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
it '#close returns nil' do
|
1006
|
+
@s.close.should == nil
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
it '#data_seek set position of current record' do
|
1010
|
+
@m.query 'create temporary table t (i int)'
|
1011
|
+
@m.query 'insert into t values (0),(1),(2),(3),(4),(5),(6)'
|
1012
|
+
@s.prepare 'select i from t'
|
1013
|
+
@s.execute
|
1014
|
+
@s.fetch.should == [0]
|
1015
|
+
@s.fetch.should == [1]
|
1016
|
+
@s.fetch.should == [2]
|
1017
|
+
@s.data_seek 5
|
1018
|
+
@s.fetch.should == [5]
|
1019
|
+
@s.data_seek 1
|
1020
|
+
@s.fetch.should == [1]
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
it '#each iterate block with a record' do
|
1024
|
+
@m.query 'create temporary table t (i int, c char(255), d datetime)'
|
1025
|
+
@m.query "insert into t values (1,'abc','19701224235905'),(2,'def','21120903123456'),(3,'123',null)"
|
1026
|
+
@s.prepare 'select * from t'
|
1027
|
+
@s.execute
|
1028
|
+
expect = [
|
1029
|
+
[1, 'abc', Mysql::Time.new(1970,12,24,23,59,05)],
|
1030
|
+
[2, 'def', Mysql::Time.new(2112,9,3,12,34,56)],
|
1031
|
+
[3, '123', nil],
|
1032
|
+
]
|
1033
|
+
@s.each do |a|
|
1034
|
+
a.should == expect.shift
|
1035
|
+
end
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
it '#execute returns self' do
|
1039
|
+
@s.prepare 'select 1'
|
1040
|
+
@s.execute.should == @s
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
it '#execute pass arguments to query' do
|
1044
|
+
@m.query 'create temporary table t (i int)'
|
1045
|
+
@s.prepare 'insert into t values (?)'
|
1046
|
+
@s.execute 123
|
1047
|
+
@s.execute '456'
|
1048
|
+
@m.query('select * from t').entries.should == [['123'], ['456']]
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
it '#execute with various arguments' do
|
1052
|
+
@m.query 'create temporary table t (i int, c char(255), t timestamp)'
|
1053
|
+
@s.prepare 'insert into t values (?,?,?)'
|
1054
|
+
@s.execute 123, 'hoge', Time.local(2009,12,8,19,56,21)
|
1055
|
+
@m.query('select * from t').fetch_row.should == ['123', 'hoge', '2009-12-08 19:56:21']
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
it '#execute with arguments that is invalid count raise error' do
|
1059
|
+
@s.prepare 'select ?'
|
1060
|
+
proc{@s.execute 123, 456}.should raise_error(Mysql::ClientError, 'parameter count mismatch')
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
it '#execute with huge value' do
|
1064
|
+
[30, 31, 32, 62, 63].each do |i|
|
1065
|
+
@m.prepare('select cast(? as signed)').execute(2**i-1).fetch.should == [2**i-1]
|
1066
|
+
@m.prepare('select cast(? as signed)').execute(-(2**i)).fetch.should == [-2**i]
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
it '#fetch returns result-record' do
|
1071
|
+
@s.prepare 'select 123, "abc", null'
|
1072
|
+
@s.execute
|
1073
|
+
@s.fetch.should == [123, 'abc', nil]
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
it '#fetch bit column (8bit)' do
|
1077
|
+
@m.query 'create temporary table t (i bit(8))'
|
1078
|
+
@m.query 'insert into t values (0),(-1),(127),(-128),(255),(-255),(256)'
|
1079
|
+
@s.prepare 'select i from t'
|
1080
|
+
@s.execute
|
1081
|
+
if defined? Encoding
|
1082
|
+
@s.entries.should == [
|
1083
|
+
["\x00".force_encoding('ASCII-8BIT')],
|
1084
|
+
["\xff".force_encoding('ASCII-8BIT')],
|
1085
|
+
["\x7f".force_encoding('ASCII-8BIT')],
|
1086
|
+
["\xff".force_encoding('ASCII-8BIT')],
|
1087
|
+
["\xff".force_encoding('ASCII-8BIT')],
|
1088
|
+
["\xff".force_encoding('ASCII-8BIT')],
|
1089
|
+
["\xff".force_encoding('ASCII-8BIT')],
|
1090
|
+
]
|
1091
|
+
else
|
1092
|
+
@s.entries.should == [["\x00"], ["\xff"], ["\x7f"], ["\xff"], ["\xff"], ["\xff"], ["\xff"]]
|
1093
|
+
end
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
it '#fetch bit column (64bit)' do
|
1097
|
+
@m.query 'create temporary table t (i bit(64))'
|
1098
|
+
@m.query 'insert into t values (0),(-1),(4294967296),(18446744073709551615),(18446744073709551616)'
|
1099
|
+
@s.prepare 'select i from t'
|
1100
|
+
@s.execute
|
1101
|
+
if defined? Encoding
|
1102
|
+
@s.entries.should == [
|
1103
|
+
["\x00\x00\x00\x00\x00\x00\x00\x00".force_encoding('ASCII-8BIT')],
|
1104
|
+
["\xff\xff\xff\xff\xff\xff\xff\xff".force_encoding('ASCII-8BIT')],
|
1105
|
+
["\x00\x00\x00\x01\x00\x00\x00\x00".force_encoding('ASCII-8BIT')],
|
1106
|
+
["\xff\xff\xff\xff\xff\xff\xff\xff".force_encoding('ASCII-8BIT')],
|
1107
|
+
["\xff\xff\xff\xff\xff\xff\xff\xff".force_encoding('ASCII-8BIT')],
|
1108
|
+
]
|
1109
|
+
else
|
1110
|
+
@s.entries.should == [
|
1111
|
+
["\x00\x00\x00\x00\x00\x00\x00\x00"],
|
1112
|
+
["\xff\xff\xff\xff\xff\xff\xff\xff"],
|
1113
|
+
["\x00\x00\x00\x01\x00\x00\x00\x00"],
|
1114
|
+
["\xff\xff\xff\xff\xff\xff\xff\xff"],
|
1115
|
+
["\xff\xff\xff\xff\xff\xff\xff\xff"],
|
1116
|
+
]
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
it '#fetch tinyint column' do
|
1121
|
+
@m.query 'create temporary table t (i tinyint)'
|
1122
|
+
@m.query 'insert into t values (0),(-1),(127),(-128),(255),(-255)'
|
1123
|
+
@s.prepare 'select i from t'
|
1124
|
+
@s.execute
|
1125
|
+
@s.entries.should == [[0], [-1], [127], [-128], [127], [-128]]
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
it '#fetch tinyint unsigned column' do
|
1129
|
+
@m.query 'create temporary table t (i tinyint unsigned)'
|
1130
|
+
@m.query 'insert into t values (0),(-1),(127),(-128),(255),(-255),(256)'
|
1131
|
+
@s.prepare 'select i from t'
|
1132
|
+
@s.execute
|
1133
|
+
@s.entries.should == [[0], [0], [127], [0], [255], [0], [255]]
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
it '#fetch smallint column' do
|
1137
|
+
@m.query 'create temporary table t (i smallint)'
|
1138
|
+
@m.query 'insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)'
|
1139
|
+
@s.prepare 'select i from t'
|
1140
|
+
@s.execute
|
1141
|
+
@s.entries.should == [[0], [-1], [32767], [-32768], [32767], [-32768], [32767]]
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
it '#fetch smallint unsigned column' do
|
1145
|
+
@m.query 'create temporary table t (i smallint unsigned)'
|
1146
|
+
@m.query 'insert into t values (0),(-1),(32767),(-32768),(65535),(-65535),(65536)'
|
1147
|
+
@s.prepare 'select i from t'
|
1148
|
+
@s.execute
|
1149
|
+
@s.entries.should == [[0], [0], [32767], [0], [65535], [0], [65535]]
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
it '#fetch mediumint column' do
|
1153
|
+
@m.query 'create temporary table t (i mediumint)'
|
1154
|
+
@m.query 'insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)'
|
1155
|
+
@s.prepare 'select i from t'
|
1156
|
+
@s.execute
|
1157
|
+
@s.entries.should == [[0], [-1], [8388607], [-8388608], [8388607], [-8388608], [8388607]]
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
it '#fetch mediumint unsigned column' do
|
1161
|
+
@m.query 'create temporary table t (i mediumint unsigned)'
|
1162
|
+
@m.query 'insert into t values (0),(-1),(8388607),(-8388608),(16777215),(-16777215),(16777216)'
|
1163
|
+
@s.prepare 'select i from t'
|
1164
|
+
@s.execute
|
1165
|
+
@s.entries.should == [[0], [0], [8388607], [0], [16777215], [0], [16777215]]
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
it '#fetch int column' do
|
1169
|
+
@m.query 'create temporary table t (i int)'
|
1170
|
+
@m.query 'insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)'
|
1171
|
+
@s.prepare 'select i from t'
|
1172
|
+
@s.execute
|
1173
|
+
@s.entries.should == [[0], [-1], [2147483647], [-2147483648], [2147483647], [-2147483648], [2147483647]]
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
it '#fetch int unsigned column' do
|
1177
|
+
@m.query 'create temporary table t (i int unsigned)'
|
1178
|
+
@m.query 'insert into t values (0),(-1),(2147483647),(-2147483648),(4294967295),(-4294967295),(4294967296)'
|
1179
|
+
@s.prepare 'select i from t'
|
1180
|
+
@s.execute
|
1181
|
+
@s.entries.should == [[0], [0], [2147483647], [0], [4294967295], [0], [4294967295]]
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
it '#fetch bigint column' do
|
1185
|
+
@m.query 'create temporary table t (i bigint)'
|
1186
|
+
@m.query 'insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)'
|
1187
|
+
@s.prepare 'select i from t'
|
1188
|
+
@s.execute
|
1189
|
+
@s.entries.should == [[0], [-1], [9223372036854775807], [-9223372036854775808], [9223372036854775807], [-9223372036854775808], [9223372036854775807]]
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
it '#fetch bigint unsigned column' do
|
1193
|
+
@m.query 'create temporary table t (i bigint unsigned)'
|
1194
|
+
@m.query 'insert into t values (0),(-1),(9223372036854775807),(-9223372036854775808),(18446744073709551615),(-18446744073709551615),(18446744073709551616)'
|
1195
|
+
@s.prepare 'select i from t'
|
1196
|
+
@s.execute
|
1197
|
+
@s.entries.should == [[0], [0], [9223372036854775807], [0], [18446744073709551615], [0], [18446744073709551615]]
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
it '#fetch float column' do
|
1201
|
+
@m.query 'create temporary table t (i float)'
|
1202
|
+
@m.query 'insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)'
|
1203
|
+
@s.prepare 'select i from t'
|
1204
|
+
@s.execute
|
1205
|
+
@s.fetch[0].should == 0.0
|
1206
|
+
(@s.fetch[0] - -3.402823466E+38).abs.should < 0.000000001E+38
|
1207
|
+
(@s.fetch[0] - -1.175494351E-38).abs.should < 0.000000001E-38
|
1208
|
+
(@s.fetch[0] - 1.175494351E-38).abs.should < 0.000000001E-38
|
1209
|
+
(@s.fetch[0] - 3.402823466E+38).abs.should < 0.000000001E+38
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
it '#fetch float unsigned column' do
|
1213
|
+
@m.query 'create temporary table t (i float unsigned)'
|
1214
|
+
@m.query 'insert into t values (0),(-3.402823466E+38),(-1.175494351E-38),(1.175494351E-38),(3.402823466E+38)'
|
1215
|
+
@s.prepare 'select i from t'
|
1216
|
+
@s.execute
|
1217
|
+
@s.fetch[0].should == 0.0
|
1218
|
+
@s.fetch[0].should == 0.0
|
1219
|
+
@s.fetch[0].should == 0.0
|
1220
|
+
(@s.fetch[0] - 1.175494351E-38).abs.should < 0.000000001E-38
|
1221
|
+
(@s.fetch[0] - 3.402823466E+38).abs.should < 0.000000001E+38
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
it '#fetch double column' do
|
1225
|
+
@m.query 'create temporary table t (i double)'
|
1226
|
+
@m.query 'insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)'
|
1227
|
+
@s.prepare 'select i from t'
|
1228
|
+
@s.execute
|
1229
|
+
@s.fetch[0].should == 0.0
|
1230
|
+
(@s.fetch[0] - -Float::MAX).abs.should < Float::EPSILON
|
1231
|
+
(@s.fetch[0] - -Float::MIN).abs.should < Float::EPSILON
|
1232
|
+
(@s.fetch[0] - Float::MIN).abs.should < Float::EPSILON
|
1233
|
+
(@s.fetch[0] - Float::MAX).abs.should < Float::EPSILON
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
it '#fetch double unsigned column' do
|
1237
|
+
@m.query 'create temporary table t (i double unsigned)'
|
1238
|
+
@m.query 'insert into t values (0),(-1.7976931348623157E+308),(-2.2250738585072014E-308),(2.2250738585072014E-308),(1.7976931348623157E+308)'
|
1239
|
+
@s.prepare 'select i from t'
|
1240
|
+
@s.execute
|
1241
|
+
@s.fetch[0].should == 0.0
|
1242
|
+
@s.fetch[0].should == 0.0
|
1243
|
+
@s.fetch[0].should == 0.0
|
1244
|
+
(@s.fetch[0] - Float::MIN).abs.should < Float::EPSILON
|
1245
|
+
(@s.fetch[0] - Float::MAX).abs.should < Float::EPSILON
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
it '#fetch decimal column' do
|
1249
|
+
@m.query 'create temporary table t (i decimal)'
|
1250
|
+
@m.query 'insert into t values (0),(9999999999),(-9999999999),(10000000000),(-10000000000)'
|
1251
|
+
@s.prepare 'select i from t'
|
1252
|
+
@s.execute
|
1253
|
+
@s.entries.should == [["0"], ["9999999999"], ["-9999999999"], ["9999999999"], ["-9999999999"]]
|
1254
|
+
end
|
1255
|
+
|
1256
|
+
it '#fetch decimal unsigned column' do
|
1257
|
+
@m.query 'create temporary table t (i decimal unsigned)'
|
1258
|
+
@m.query 'insert into t values (0),(9999999998),(9999999999),(-9999999998),(-9999999999),(10000000000),(-10000000000)'
|
1259
|
+
@s.prepare 'select i from t'
|
1260
|
+
@s.execute
|
1261
|
+
@s.entries.should == [["0"], ["9999999998"], ["9999999999"], ["0"], ["0"], ["9999999999"], ["0"]]
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
it '#fetch date column' do
|
1265
|
+
@m.query 'create temporary table t (i date)'
|
1266
|
+
@m.query "insert into t values ('0000-00-00'),('1000-01-01'),('9999-12-31')"
|
1267
|
+
@s.prepare 'select i from t'
|
1268
|
+
@s.execute
|
1269
|
+
@s.fetch.should == [Mysql::Time.new]
|
1270
|
+
@s.fetch.should == [Mysql::Time.new(1000,1,1)]
|
1271
|
+
@s.fetch.should == [Mysql::Time.new(9999,12,31)]
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
it '#fetch datetime column' do
|
1275
|
+
@m.query 'create temporary table t (i datetime)'
|
1276
|
+
@m.query "insert into t values ('0000-00-00 00:00:00'),('1000-01-01 00:00:00'),('9999-12-31 23:59:59')"
|
1277
|
+
@s.prepare 'select i from t'
|
1278
|
+
@s.execute
|
1279
|
+
@s.fetch.should == [Mysql::Time.new]
|
1280
|
+
@s.fetch.should == [Mysql::Time.new(1000,1,1)]
|
1281
|
+
@s.fetch.should == [Mysql::Time.new(9999,12,31,23,59,59)]
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
it '#fetch timestamp column' do
|
1285
|
+
@m.query 'create temporary table t (i timestamp)'
|
1286
|
+
@m.query("insert into t values ('1970-01-02 00:00:00'),('2037-12-30 23:59:59')")
|
1287
|
+
@s.prepare 'select i from t'
|
1288
|
+
@s.execute
|
1289
|
+
@s.fetch.should == [Mysql::Time.new(1970,1,2)]
|
1290
|
+
@s.fetch.should == [Mysql::Time.new(2037,12,30,23,59,59)]
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
it '#fetch time column' do
|
1294
|
+
@m.query 'create temporary table t (i time)'
|
1295
|
+
@m.query "insert into t values ('-838:59:59'),(0),('838:59:59')"
|
1296
|
+
@s.prepare 'select i from t'
|
1297
|
+
@s.execute
|
1298
|
+
@s.fetch.should == [Mysql::Time.new(0,0,0,838,59,59,true)]
|
1299
|
+
@s.fetch.should == [Mysql::Time.new(0,0,0,0,0,0,false)]
|
1300
|
+
@s.fetch.should == [Mysql::Time.new(0,0,0,838,59,59,false)]
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
it '#fetch year column' do
|
1304
|
+
@m.query 'create temporary table t (i year)'
|
1305
|
+
@m.query 'insert into t values (0),(70),(69),(1901),(2155)'
|
1306
|
+
@s.prepare 'select i from t'
|
1307
|
+
@s.execute
|
1308
|
+
@s.entries.should == [[0], [1970], [2069], [1901], [2155]]
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
it '#fetch char column' do
|
1312
|
+
@m.query 'create temporary table t (i char(10))'
|
1313
|
+
@m.query "insert into t values (null),('abc')"
|
1314
|
+
@s.prepare 'select i from t'
|
1315
|
+
@s.execute
|
1316
|
+
@s.entries.should == [[nil], ['abc']]
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
it '#fetch varchar column' do
|
1320
|
+
@m.query 'create temporary table t (i varchar(10))'
|
1321
|
+
@m.query "insert into t values (null),('abc')"
|
1322
|
+
@s.prepare 'select i from t'
|
1323
|
+
@s.execute
|
1324
|
+
@s.entries.should == [[nil], ['abc']]
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
it '#fetch binary column' do
|
1328
|
+
@m.query 'create temporary table t (i binary(10))'
|
1329
|
+
@m.query "insert into t values (null),('abc')"
|
1330
|
+
@s.prepare 'select i from t'
|
1331
|
+
@s.execute
|
1332
|
+
@s.entries.should == [[nil], ["abc\0\0\0\0\0\0\0"]]
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
it '#fetch varbinary column' do
|
1336
|
+
@m.query 'create temporary table t (i varbinary(10))'
|
1337
|
+
@m.query "insert into t values (null),('abc')"
|
1338
|
+
@s.prepare 'select i from t'
|
1339
|
+
@s.execute
|
1340
|
+
@s.entries.should == [[nil], ["abc"]]
|
1341
|
+
end
|
1342
|
+
|
1343
|
+
it '#fetch tinyblob column' do
|
1344
|
+
@m.query 'create temporary table t (i tinyblob)'
|
1345
|
+
@m.query "insert into t values (null),('abc')"
|
1346
|
+
@s.prepare 'select i from t'
|
1347
|
+
@s.execute
|
1348
|
+
@s.entries.should == [[nil], ["abc"]]
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
it '#fetch tinytext column' do
|
1352
|
+
@m.query 'create temporary table t (i tinytext)'
|
1353
|
+
@m.query "insert into t values (null),('abc')"
|
1354
|
+
@s.prepare 'select i from t'
|
1355
|
+
@s.execute
|
1356
|
+
@s.entries.should == [[nil], ["abc"]]
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
it '#fetch blob column' do
|
1360
|
+
@m.query 'create temporary table t (i blob)'
|
1361
|
+
@m.query "insert into t values (null),('abc')"
|
1362
|
+
@s.prepare 'select i from t'
|
1363
|
+
@s.execute
|
1364
|
+
@s.entries.should == [[nil], ["abc"]]
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
it '#fetch text column' do
|
1368
|
+
@m.query 'create temporary table t (i text)'
|
1369
|
+
@m.query "insert into t values (null),('abc')"
|
1370
|
+
@s.prepare 'select i from t'
|
1371
|
+
@s.execute
|
1372
|
+
@s.entries.should == [[nil], ["abc"]]
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
it '#fetch mediumblob column' do
|
1376
|
+
@m.query 'create temporary table t (i mediumblob)'
|
1377
|
+
@m.query "insert into t values (null),('abc')"
|
1378
|
+
@s.prepare 'select i from t'
|
1379
|
+
@s.execute
|
1380
|
+
@s.entries.should == [[nil], ["abc"]]
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
it '#fetch mediumtext column' do
|
1384
|
+
@m.query 'create temporary table t (i mediumtext)'
|
1385
|
+
@m.query "insert into t values (null),('abc')"
|
1386
|
+
@s.prepare 'select i from t'
|
1387
|
+
@s.execute
|
1388
|
+
@s.entries.should == [[nil], ["abc"]]
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
it '#fetch longblob column' do
|
1392
|
+
@m.query 'create temporary table t (i longblob)'
|
1393
|
+
@m.query "insert into t values (null),('abc')"
|
1394
|
+
@s.prepare 'select i from t'
|
1395
|
+
@s.execute
|
1396
|
+
@s.entries.should == [[nil], ["abc"]]
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
it '#fetch longtext column' do
|
1400
|
+
@m.query 'create temporary table t (i longtext)'
|
1401
|
+
@m.query "insert into t values (null),('abc')"
|
1402
|
+
@s.prepare 'select i from t'
|
1403
|
+
@s.execute
|
1404
|
+
@s.entries.should == [[nil], ["abc"]]
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
it '#fetch enum column' do
|
1408
|
+
@m.query "create temporary table t (i enum('abc','def'))"
|
1409
|
+
@m.query "insert into t values (null),(0),(1),(2),('abc'),('def'),('ghi')"
|
1410
|
+
@s.prepare 'select i from t'
|
1411
|
+
@s.execute
|
1412
|
+
@s.entries.should == [[nil], [''], ['abc'], ['def'], ['abc'], ['def'], ['']]
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
it '#fetch set column' do
|
1416
|
+
@m.query "create temporary table t (i set('abc','def'))"
|
1417
|
+
@m.query "insert into t values (null),(0),(1),(2),(3),('abc'),('def'),('abc,def'),('ghi')"
|
1418
|
+
@s.prepare 'select i from t'
|
1419
|
+
@s.execute
|
1420
|
+
@s.entries.should == [[nil], [''], ['abc'], ['def'], ['abc,def'], ['abc'], ['def'], ['abc,def'], ['']]
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
it '#field_count' do
|
1424
|
+
@s.prepare 'select 1,2,3'
|
1425
|
+
@s.field_count.should == 3
|
1426
|
+
@s.prepare 'set @a=1'
|
1427
|
+
@s.field_count.should == 0
|
1428
|
+
end
|
1429
|
+
|
1430
|
+
it '#free_result' do
|
1431
|
+
@s.free_result
|
1432
|
+
@s.prepare 'select 1,2,3'
|
1433
|
+
@s.execute
|
1434
|
+
@s.free_result
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
it '#insert_id' do
|
1438
|
+
@m.query 'create temporary table t (i int auto_increment, unique(i))'
|
1439
|
+
@s.prepare 'insert into t values (0)'
|
1440
|
+
@s.execute
|
1441
|
+
@s.insert_id.should == 1
|
1442
|
+
@s.execute
|
1443
|
+
@s.insert_id.should == 2
|
1444
|
+
end
|
1445
|
+
|
1446
|
+
it '#num_rows' do
|
1447
|
+
@m.query 'create temporary table t (i int)'
|
1448
|
+
@m.query 'insert into t values (1),(2),(3),(4)'
|
1449
|
+
@s.prepare 'select * from t'
|
1450
|
+
@s.execute
|
1451
|
+
@s.num_rows.should == 4
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
it '#param_count' do
|
1455
|
+
@m.query 'create temporary table t (a int, b int, c int)'
|
1456
|
+
@s.prepare 'select * from t'
|
1457
|
+
@s.param_count.should == 0
|
1458
|
+
@s.prepare 'insert into t values (?,?,?)'
|
1459
|
+
@s.param_count.should == 3
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
it '#prepare' do
|
1463
|
+
@s.prepare('select 1').should be_kind_of Mysql::Stmt
|
1464
|
+
proc{@s.prepare 'invalid syntax'}.should raise_error Mysql::ParseError
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
it '#prepare returns self' do
|
1468
|
+
@s.prepare('select 1').should == @s
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
it '#prepare with invalid query raises error' do
|
1472
|
+
proc{@s.prepare 'invalid query'}.should raise_error Mysql::ParseError
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
it '#result_metadata' do
|
1476
|
+
@s.prepare 'select 1 foo, 2 bar'
|
1477
|
+
f = @s.result_metadata.fetch_fields
|
1478
|
+
f[0].name.should == 'foo'
|
1479
|
+
f[1].name.should == 'bar'
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
it '#result_metadata forn no data' do
|
1483
|
+
@s.prepare 'set @a=1'
|
1484
|
+
@s.result_metadata.should == nil
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
it '#row_seek and #row_tell' do
|
1488
|
+
@m.query 'create temporary table t (i int)'
|
1489
|
+
@m.query 'insert into t values (0),(1),(2),(3),(4)'
|
1490
|
+
@s.prepare 'select * from t'
|
1491
|
+
@s.execute
|
1492
|
+
row0 = @s.row_tell
|
1493
|
+
@s.fetch.should == [0]
|
1494
|
+
@s.fetch.should == [1]
|
1495
|
+
row2 = @s.row_seek row0
|
1496
|
+
@s.fetch.should == [0]
|
1497
|
+
@s.row_seek row2
|
1498
|
+
@s.fetch.should == [2]
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
it '#sqlstate' do
|
1502
|
+
@s.prepare 'select 1'
|
1503
|
+
@s.sqlstate.should == '00000'
|
1504
|
+
proc{@s.prepare 'hogehoge'}.should raise_error Mysql::ParseError
|
1505
|
+
@s.sqlstate.should == '42000'
|
1506
|
+
end
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
describe 'Mysql::Time' do
|
1510
|
+
before do
|
1511
|
+
@t = Mysql::Time.new
|
1512
|
+
end
|
1513
|
+
|
1514
|
+
it '.new with no arguments returns 0' do
|
1515
|
+
@t.year.should == 0
|
1516
|
+
@t.month.should == 0
|
1517
|
+
@t.day.should == 0
|
1518
|
+
@t.hour.should == 0
|
1519
|
+
@t.minute.should == 0
|
1520
|
+
@t.second.should == 0
|
1521
|
+
@t.neg.should == false
|
1522
|
+
@t.second_part.should == 0
|
1523
|
+
end
|
1524
|
+
|
1525
|
+
it '#inspect' do
|
1526
|
+
Mysql::Time.new(2009,12,8,23,35,21).inspect.should == '#<Mysql::Time:2009-12-08 23:35:21>'
|
1527
|
+
end
|
1528
|
+
|
1529
|
+
it '#to_s' do
|
1530
|
+
Mysql::Time.new(2009,12,8,23,35,21).to_s.should == '2009-12-08 23:35:21'
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
it '#to_i' do
|
1534
|
+
Mysql::Time.new(2009,12,8,23,35,21).to_i.should == 20091208233521
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
it '#year' do
|
1538
|
+
(@t.year = 2009).should == 2009
|
1539
|
+
@t.year.should == 2009
|
1540
|
+
end
|
1541
|
+
|
1542
|
+
it '#month' do
|
1543
|
+
(@t.month = 12).should == 12
|
1544
|
+
@t.month.should == 12
|
1545
|
+
end
|
1546
|
+
|
1547
|
+
it '#day' do
|
1548
|
+
(@t.day = 8).should == 8
|
1549
|
+
@t.day.should == 8
|
1550
|
+
end
|
1551
|
+
|
1552
|
+
it '#hour' do
|
1553
|
+
(@t.hour = 23).should == 23
|
1554
|
+
@t.hour.should == 23
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
it '#minute' do
|
1558
|
+
(@t.minute = 35).should == 35
|
1559
|
+
@t.minute.should == 35
|
1560
|
+
end
|
1561
|
+
|
1562
|
+
it '#second' do
|
1563
|
+
(@t.second = 21).should == 21
|
1564
|
+
@t.second.should == 21
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
it '#neg' do
|
1568
|
+
@t.neg.should == false
|
1569
|
+
end
|
1570
|
+
|
1571
|
+
it '#second_part' do
|
1572
|
+
@t.second_part.should == 0
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
it '#==' do
|
1576
|
+
t1 = Mysql::Time.new 2009,12,8,23,35,21
|
1577
|
+
t2 = Mysql::Time.new 2009,12,8,23,35,21
|
1578
|
+
t1.should == t2
|
1579
|
+
end
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
describe 'Mysql::Error' do
|
1583
|
+
before do
|
1584
|
+
m = Mysql.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
1585
|
+
begin
|
1586
|
+
m.query('hogehoge')
|
1587
|
+
rescue => @e
|
1588
|
+
end
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
it '#error is error message' do
|
1592
|
+
@e.error.should == "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'hogehoge' at line 1"
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
it '#errno is error number' do
|
1596
|
+
@e.errno.should == 1064
|
1597
|
+
end
|
1598
|
+
|
1599
|
+
it '#sqlstate is sqlstate value as String' do
|
1600
|
+
@e.sqlstate.should == '42000'
|
1601
|
+
end
|
1602
|
+
end
|
1603
|
+
|
1604
|
+
if defined? Encoding
|
1605
|
+
describe 'Connection charset is UTF-8:' do
|
1606
|
+
before do
|
1607
|
+
@m = Mysql.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
1608
|
+
@m.charset = "utf8"
|
1609
|
+
@m.query "create temporary table t (utf8 char(10) charset utf8, cp932 char(10) charset cp932, eucjp char(10) charset eucjpms, bin varbinary(10))"
|
1610
|
+
@utf8 = "いろは"
|
1611
|
+
@cp932 = @utf8.encode "CP932"
|
1612
|
+
@eucjp = @utf8.encode "EUC-JP-MS"
|
1613
|
+
@bin = "\x00\x01\x7F\x80\xFE\xFF".force_encoding("ASCII-8BIT")
|
1614
|
+
@default_internal = Encoding.default_internal
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
after do
|
1618
|
+
Encoding.default_internal = @default_internal
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
describe 'default_internal is CP932' do
|
1622
|
+
before do
|
1623
|
+
Encoding.default_internal = 'CP932'
|
1624
|
+
end
|
1625
|
+
it 'is converted to CP932' do
|
1626
|
+
@m.query('select "あいう"').fetch.should == ["\x82\xA0\x82\xA2\x82\xA4".force_encoding("CP932")]
|
1627
|
+
end
|
1628
|
+
end
|
1629
|
+
|
1630
|
+
describe 'query with CP932 encoding' do
|
1631
|
+
it 'is converted to UTF-8' do
|
1632
|
+
@m.query('select HEX("あいう")'.encode("CP932")).fetch.should == ["E38182E38184E38186"]
|
1633
|
+
end
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
describe 'prepared statement with CP932 encoding' do
|
1637
|
+
it 'is converted to UTF-8' do
|
1638
|
+
@m.prepare('select HEX("あいう")'.encode("CP932")).execute.fetch.should == ["E38182E38184E38186"]
|
1639
|
+
end
|
1640
|
+
end
|
1641
|
+
|
1642
|
+
describe 'The encoding of data are correspond to charset of column:' do
|
1643
|
+
before do
|
1644
|
+
@m.prepare("insert into t (utf8,cp932,eucjp,bin) values (?,?,?,?)").execute @utf8, @cp932, @eucjp, @bin
|
1645
|
+
end
|
1646
|
+
it 'data is stored as is' do
|
1647
|
+
@m.query('select hex(utf8),hex(cp932),hex(eucjp),hex(bin) from t').fetch.should == ['E38184E3828DE381AF', '82A282EB82CD', 'A4A4A4EDA4CF', '00017F80FEFF']
|
1648
|
+
end
|
1649
|
+
it 'By simple query, charset of retrieved data is connection charset' do
|
1650
|
+
@m.query('select utf8,cp932,eucjp,bin from t').fetch.should == [@utf8, @utf8, @utf8, @bin.dup.force_encoding("UTF-8")]
|
1651
|
+
end
|
1652
|
+
it 'By prepared statement, charset of retrieved data is connection charset except for binary' do
|
1653
|
+
@m.prepare('select utf8,cp932,eucjp,bin from t').execute.fetch.should == [@utf8, @utf8, @utf8, @bin]
|
1654
|
+
end
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
describe 'The encoding of data are different from charset of column:' do
|
1658
|
+
before do
|
1659
|
+
@m.prepare("insert into t (utf8,cp932,eucjp,bin) values (?,?,?,?)").execute @utf8, @utf8, @utf8, @utf8
|
1660
|
+
end
|
1661
|
+
it 'stored data is converted' do
|
1662
|
+
@m.query("select hex(utf8),hex(cp932),hex(eucjp),hex(bin) from t").fetch.should == ["E38184E3828DE381AF", "82A282EB82CD", "A4A4A4EDA4CF", "E38184E3828DE381AF"]
|
1663
|
+
end
|
1664
|
+
it 'By simple query, charset of retrieved data is connection charset' do
|
1665
|
+
@m.query("select utf8,cp932,eucjp,bin from t").fetch.should == [@utf8, @utf8, @utf8, @utf8]
|
1666
|
+
end
|
1667
|
+
it 'By prepared statement, charset of retrieved data is connection charset except for binary' do
|
1668
|
+
@m.prepare("select utf8,cp932,eucjp,bin from t").execute.fetch.should == [@utf8, @utf8, @utf8, @utf8.dup.force_encoding("ASCII-8BIT")]
|
1669
|
+
end
|
1670
|
+
end
|
1671
|
+
|
1672
|
+
describe 'The data include invalid byte code:' do
|
1673
|
+
it 'raises Encoding::InvalidByteSequenceError' do
|
1674
|
+
cp932 = "\x01\xFF\x80".force_encoding("CP932")
|
1675
|
+
proc{@m.prepare("insert into t (cp932) values (?)").execute cp932}.should raise_error(Encoding::InvalidByteSequenceError)
|
1676
|
+
end
|
1677
|
+
end
|
1678
|
+
end
|
1679
|
+
end
|