ruby-mysql 2.9.13 → 2.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.rdoc +4 -3
- data/lib/mysql/authenticator/caching_sha2_password.rb +62 -0
- data/lib/mysql/authenticator/mysql_native_password.rb +37 -0
- data/lib/mysql/authenticator/sha256_password.rb +40 -0
- data/lib/mysql/authenticator.rb +84 -0
- data/lib/mysql/charset.rb +379 -256
- data/lib/mysql/constants.rb +154 -70
- data/lib/mysql/error.rb +13 -7
- data/lib/mysql/protocol.rb +191 -92
- data/lib/mysql.rb +55 -33
- data/test/test_mysql.rb +78 -16
- metadata +12 -9
data/test/test_mysql.rb
CHANGED
@@ -20,7 +20,7 @@ MYSQL_SOCKET = ENV['MYSQL_SOCKET']
|
|
20
20
|
class TestMysql < Test::Unit::TestCase
|
21
21
|
sub_test_case 'Mysql::VERSION' do
|
22
22
|
test 'returns client version' do
|
23
|
-
assert{ Mysql::VERSION ==
|
23
|
+
assert{ Mysql::VERSION == 21101 }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -140,8 +140,8 @@ class TestMysql < Test::Unit::TestCase
|
|
140
140
|
end
|
141
141
|
test 'OPT_CONNECT_TIMEOUT: set timeout for connecting' do
|
142
142
|
assert{ @m.options(Mysql::OPT_CONNECT_TIMEOUT, 0.1) == @m }
|
143
|
-
stub(
|
144
|
-
stub(
|
143
|
+
stub(Socket).tcp{ raise Errno::ETIMEDOUT }
|
144
|
+
stub(Socket).unix{ raise Errno::ETIMEDOUT }
|
145
145
|
assert_raise Mysql::ClientError, 'connection timeout' do
|
146
146
|
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
147
147
|
end
|
@@ -160,16 +160,63 @@ class TestMysql < Test::Unit::TestCase
|
|
160
160
|
@m.query("load data local infile '#{tmpf.path}' into table t")
|
161
161
|
assert{ @m.query('select * from t').fetch_row == ['123','abc'] }
|
162
162
|
end
|
163
|
+
test 'OPT_LOAD_DATA_LOCAL_DIR: client can execute LOAD DATA LOCAL INFILE query with specified directory' do
|
164
|
+
require 'tempfile'
|
165
|
+
tmpf = Tempfile.new 'mysql_spec'
|
166
|
+
tmpf.puts "123\tabc\n"
|
167
|
+
tmpf.close
|
168
|
+
assert{ @m.options(Mysql::OPT_LOAD_DATA_LOCAL_DIR, File.dirname(tmpf.path)) == @m }
|
169
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
170
|
+
@m.query('create temporary table t (i int, c char(10))')
|
171
|
+
@m.query("load data local infile '#{tmpf.path}' into table t")
|
172
|
+
assert{ @m.query('select * from t').fetch_row == ['123','abc'] }
|
173
|
+
end
|
174
|
+
test 'OPT_LOAD_DATA_LOCAL_DIR: client cannot execute LOAD DATA LOCAL INFILE query without specified directory' do
|
175
|
+
require 'tempfile'
|
176
|
+
tmpf = Tempfile.new 'mysql_spec'
|
177
|
+
tmpf.puts "123\tabc\n"
|
178
|
+
tmpf.close
|
179
|
+
assert{ @m.options(Mysql::OPT_LOAD_DATA_LOCAL_DIR, '/hoge') == @m }
|
180
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
181
|
+
@m.query('create temporary table t (i int, c char(10))')
|
182
|
+
assert_raise Mysql::ClientError::LoadDataLocalInfileRejected, 'LOAD DATA LOCAL INFILE file request rejected due to restrictions on access.' do
|
183
|
+
@m.query("load data local infile '#{tmpf.path}' into table t")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
test 'without OPT_LOCAL_INFILE and OPT_LOAD_DATA_LOCAL_DIR: client cannot execute LOAD DATA LOCAL INFILE query' do
|
187
|
+
require 'tempfile'
|
188
|
+
tmpf = Tempfile.new 'mysql_spec'
|
189
|
+
tmpf.puts "123\tabc\n"
|
190
|
+
tmpf.close
|
191
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
192
|
+
@m.query('create temporary table t (i int, c char(10))')
|
193
|
+
if @m.server_version >= 80000
|
194
|
+
assert_raise Mysql::ServerError, 'Loading local data is disabled; this must be enabled on both the client and server sides' do
|
195
|
+
@m.query("load data local infile '#{tmpf.path}' into table t")
|
196
|
+
end
|
197
|
+
else
|
198
|
+
assert_raise Mysql::ServerError::NotAllowedCommand, 'The used command is not allowed with this MySQL version' do
|
199
|
+
@m.query("load data local infile '#{tmpf.path}' into table t")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
163
203
|
test 'OPT_READ_TIMEOUT: set timeout for reading packet' do
|
164
|
-
assert{ @m.options(Mysql::OPT_READ_TIMEOUT,
|
204
|
+
assert{ @m.options(Mysql::OPT_READ_TIMEOUT, 1) == @m }
|
205
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
206
|
+
@m.query("select 123").entries
|
165
207
|
end
|
166
208
|
test 'OPT_WRITE_TIMEOUT: set timeout for writing packet' do
|
167
|
-
assert{ @m.options(Mysql::OPT_WRITE_TIMEOUT,
|
209
|
+
assert{ @m.options(Mysql::OPT_WRITE_TIMEOUT, 1) == @m }
|
210
|
+
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
211
|
+
@m.query("select 123").entries
|
168
212
|
end
|
169
213
|
test 'SET_CHARSET_NAME: set charset for connection' do
|
170
|
-
assert{ @m.options(Mysql::SET_CHARSET_NAME, '
|
214
|
+
assert{ @m.options(Mysql::SET_CHARSET_NAME, 'utf8mb3') == @m }
|
171
215
|
@m.connect(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
172
|
-
assert
|
216
|
+
assert do
|
217
|
+
@m.query('select @@character_set_connection').fetch_row == ['utf8mb3'] ||
|
218
|
+
@m.query('select @@character_set_connection').fetch_row == ['utf8']
|
219
|
+
end
|
173
220
|
end
|
174
221
|
end
|
175
222
|
|
@@ -537,6 +584,10 @@ class TestMysql < Test::Unit::TestCase
|
|
537
584
|
end
|
538
585
|
|
539
586
|
sub_test_case '#warning_count' do
|
587
|
+
setup do
|
588
|
+
@m.query("set sql_mode=''")
|
589
|
+
@m.query("set sql_mode=''") # clear warnings on previous `set' statement.
|
590
|
+
end
|
540
591
|
test 'default values is zero' do
|
541
592
|
assert{ @m.warning_count == 0 }
|
542
593
|
end
|
@@ -683,7 +734,7 @@ class TestMysql < Test::Unit::TestCase
|
|
683
734
|
setup do
|
684
735
|
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
685
736
|
@m.charset = 'latin1'
|
686
|
-
@m.query 'create temporary table t (id int, str char(10), primary key (id))'
|
737
|
+
@m.query 'create temporary table t (id int default 0, str char(10), primary key (id))'
|
687
738
|
@m.query "insert into t values (1,'abc'),(2,'defg'),(3,'hi'),(4,null)"
|
688
739
|
@res = @m.query 'select * from t'
|
689
740
|
end
|
@@ -707,7 +758,7 @@ class TestMysql < Test::Unit::TestCase
|
|
707
758
|
assert{ f.def == nil }
|
708
759
|
assert{ f.type == Mysql::Field::TYPE_LONG }
|
709
760
|
assert{ f.length == 11 }
|
710
|
-
f.max_length == 1
|
761
|
+
assert{ f.max_length == 1 }
|
711
762
|
assert{ f.flags == Mysql::Field::NUM_FLAG|Mysql::Field::PRI_KEY_FLAG|Mysql::Field::PART_KEY_FLAG|Mysql::Field::NOT_NULL_FLAG }
|
712
763
|
assert{ f.decimals == 0 }
|
713
764
|
|
@@ -717,7 +768,7 @@ class TestMysql < Test::Unit::TestCase
|
|
717
768
|
assert{ f.def == nil }
|
718
769
|
assert{ f.type == Mysql::Field::TYPE_STRING }
|
719
770
|
assert{ f.length == 10 }
|
720
|
-
f.max_length == 4
|
771
|
+
assert{ f.max_length == 4 }
|
721
772
|
assert{ f.flags == 0 }
|
722
773
|
assert{ f.decimals == 0 }
|
723
774
|
|
@@ -955,6 +1006,7 @@ class TestMysql < Test::Unit::TestCase
|
|
955
1006
|
sub_test_case 'Mysql::Stmt' do
|
956
1007
|
setup do
|
957
1008
|
@m = Mysql.new(MYSQL_SERVER, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_PORT, MYSQL_SOCKET)
|
1009
|
+
@m.query("set sql_mode=''")
|
958
1010
|
@s = @m.stmt_init
|
959
1011
|
end
|
960
1012
|
|
@@ -1000,12 +1052,6 @@ class TestMysql < Test::Unit::TestCase
|
|
1000
1052
|
assert{ @s.fetch == [123, 9, 1, 20091208100446] }
|
1001
1053
|
end
|
1002
1054
|
|
1003
|
-
test '(Fixnum) make result format to be Integer value' do
|
1004
|
-
@s.bind_result Fixnum, Fixnum, Fixnum, Fixnum
|
1005
|
-
@s.execute
|
1006
|
-
assert{ @s.fetch == [123, 9, 1, 20091208100446] }
|
1007
|
-
end
|
1008
|
-
|
1009
1055
|
test '(String) make result format to be String value' do
|
1010
1056
|
@s.bind_result String, String, String, String
|
1011
1057
|
@s.execute
|
@@ -1559,6 +1605,16 @@ class TestMysql < Test::Unit::TestCase
|
|
1559
1605
|
assert{ @s.entries == [[nil], [''], ['abc'], ['def'], ['abc,def'], ['abc'], ['def'], ['abc,def'], ['']] }
|
1560
1606
|
end
|
1561
1607
|
|
1608
|
+
test '#fetch json column' do
|
1609
|
+
if @m.server_version >= 50700
|
1610
|
+
@m.query "create temporary table t (i json)"
|
1611
|
+
@m.query "insert into t values ('123'),('{\"a\":1,\"b\":2,\"c\":3}'),('[1,2,3]')"
|
1612
|
+
@s.prepare 'select i from t'
|
1613
|
+
@s.execute
|
1614
|
+
assert{ @s.entries == [['123'], ['{"a": 1, "b": 2, "c": 3}'], ['[1, 2, 3]']] }
|
1615
|
+
end
|
1616
|
+
end
|
1617
|
+
|
1562
1618
|
test '#field_count' do
|
1563
1619
|
@s.prepare 'select 1,2,3'
|
1564
1620
|
assert{ @s.field_count == 3 }
|
@@ -1760,13 +1816,19 @@ class TestMysql < Test::Unit::TestCase
|
|
1760
1816
|
end
|
1761
1817
|
|
1762
1818
|
teardown do
|
1819
|
+
v = $VERBOSE
|
1820
|
+
$VERBOSE = false
|
1763
1821
|
Encoding.default_internal = @default_internal
|
1822
|
+
$VERBOSE = v
|
1764
1823
|
end
|
1765
1824
|
|
1766
1825
|
sub_test_case 'default_internal is CP932' do
|
1767
1826
|
setup do
|
1768
1827
|
@m.prepare("insert into t (utf8,cp932,eucjp,bin) values (?,?,?,?)").execute @utf8, @cp932, @eucjp, @bin
|
1828
|
+
v = $VERBOSE
|
1829
|
+
$VERBOSE = false
|
1769
1830
|
Encoding.default_internal = 'CP932'
|
1831
|
+
$VERBOSE = v
|
1770
1832
|
end
|
1771
1833
|
test 'is converted to CP932' do
|
1772
1834
|
assert @m.query('select "あいう"').fetch == ["\x82\xA0\x82\xA2\x82\xA4".force_encoding("CP932")]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-mysql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.11.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomita Masahiro
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This is MySQL connector. pure Ruby version
|
14
14
|
email: tommy@tmtm.org
|
@@ -19,6 +19,10 @@ extra_rdoc_files:
|
|
19
19
|
files:
|
20
20
|
- README.rdoc
|
21
21
|
- lib/mysql.rb
|
22
|
+
- lib/mysql/authenticator.rb
|
23
|
+
- lib/mysql/authenticator/caching_sha2_password.rb
|
24
|
+
- lib/mysql/authenticator/mysql_native_password.rb
|
25
|
+
- lib/mysql/authenticator/sha256_password.rb
|
22
26
|
- lib/mysql/charset.rb
|
23
27
|
- lib/mysql/constants.rb
|
24
28
|
- lib/mysql/error.rb
|
@@ -28,9 +32,9 @@ files:
|
|
28
32
|
- test/test_mysql_packet.rb
|
29
33
|
homepage: http://github.com/tmtm/ruby-mysql
|
30
34
|
licenses:
|
31
|
-
- Ruby
|
35
|
+
- Ruby
|
32
36
|
metadata: {}
|
33
|
-
post_install_message:
|
37
|
+
post_install_message:
|
34
38
|
rdoc_options: []
|
35
39
|
require_paths:
|
36
40
|
- lib
|
@@ -45,11 +49,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
49
|
- !ruby/object:Gem::Version
|
46
50
|
version: '0'
|
47
51
|
requirements: []
|
48
|
-
|
49
|
-
|
50
|
-
signing_key:
|
52
|
+
rubygems_version: 3.2.22
|
53
|
+
signing_key:
|
51
54
|
specification_version: 4
|
52
55
|
summary: MySQL connector
|
53
56
|
test_files:
|
54
|
-
- test/test_mysql_packet.rb
|
55
57
|
- test/test_mysql.rb
|
58
|
+
- test/test_mysql_packet.rb
|