ruby-oci8 2.2.0.2 → 2.2.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +1 -6
- data/ChangeLog +600 -0
- data/NEWS +426 -35
- data/README.md +27 -9
- data/dist-files +13 -2
- data/docs/bind-array-to-in_cond.md +38 -0
- data/docs/conflicts-local-connections-and-processes.md +98 -0
- data/docs/hanging-after-inactivity.md +63 -0
- data/docs/install-binary-package.md +15 -11
- data/docs/install-full-client.md +18 -21
- data/docs/install-instant-client.md +45 -27
- data/docs/install-on-osx.md +31 -117
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/platform-specific-issues.md +17 -50
- data/docs/report-installation-issue.md +11 -8
- data/docs/timeout-parameters.md +94 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +39 -143
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +421 -9
- data/ext/oci8/connection_pool.c +3 -3
- data/ext/oci8/encoding.c +5 -5
- data/ext/oci8/env.c +8 -2
- data/ext/oci8/error.c +24 -16
- data/ext/oci8/extconf.rb +35 -63
- data/ext/oci8/hook_funcs.c +274 -61
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +8 -6
- data/ext/oci8/object.c +119 -29
- data/ext/oci8/oci8.c +46 -133
- data/ext/oci8/oci8.h +40 -123
- data/ext/oci8/oci8lib.c +178 -46
- data/ext/oci8/ocihandle.c +37 -37
- data/ext/oci8/ocinumber.c +24 -35
- data/ext/oci8/oraconf.rb +168 -337
- data/ext/oci8/oradate.c +19 -19
- data/ext/oci8/plthook.h +10 -0
- data/ext/oci8/plthook_elf.c +433 -268
- data/ext/oci8/plthook_osx.c +40 -9
- data/ext/oci8/plthook_win32.c +16 -1
- data/ext/oci8/stmt.c +52 -17
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +10 -17
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/compat.rb +5 -1
- data/lib/oci8/connection_pool.rb +74 -3
- data/lib/oci8/cursor.rb +70 -31
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +14 -1
- data/lib/oci8/oci8.rb +184 -58
- data/lib/oci8/ocihandle.rb +0 -16
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/properties.rb +55 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +48 -4
- data/lib/ruby-oci8.rb +1 -0
- data/pre-distclean.rb +1 -3
- data/ruby-oci8.gemspec +4 -9
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +8 -1
- data/test/setup_test_object.sql +42 -14
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +4 -0
- data/test/test_bind_array.rb +70 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_bind_integer.rb +47 -0
- data/test/test_break.rb +11 -9
- data/test/test_clob.rb +5 -17
- data/test/test_connstr.rb +142 -0
- data/test/test_datetime.rb +8 -3
- data/test/test_metadata.rb +2 -1
- data/test/test_object.rb +99 -18
- data/test/test_oci8.rb +170 -46
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +17 -3
- data/test/test_properties.rb +17 -0
- metadata +45 -55
- data/docs/osx-install-dev-tools.png +0 -0
- data/test/README +0 -42
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'oci8'
|
2
|
+
require File.dirname(__FILE__) + '/config'
|
3
|
+
|
4
|
+
class TestBindInteger < Minitest::Test
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@conn = get_oci8_connection
|
8
|
+
end
|
9
|
+
|
10
|
+
POSITIVE_INTS = [
|
11
|
+
100,
|
12
|
+
2**30,
|
13
|
+
2**31,
|
14
|
+
2**32,
|
15
|
+
2**33,
|
16
|
+
2**62,
|
17
|
+
2**63,
|
18
|
+
2**64,
|
19
|
+
('9' * 38).to_i
|
20
|
+
]
|
21
|
+
|
22
|
+
def bind_and_get(input_value, output_type)
|
23
|
+
cursor = @conn.parse("BEGIN :out := :in; END;")
|
24
|
+
cursor.bind_param(:out, output_type)
|
25
|
+
cursor.bind_param(:in, input_value)
|
26
|
+
cursor.exec
|
27
|
+
result = cursor[:out]
|
28
|
+
cursor.close
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
32
|
+
(POSITIVE_INTS + [0] + POSITIVE_INTS.map(&:-@)).each do |num|
|
33
|
+
define_method("test_bind_param_with_input_of '#{num}'") do
|
34
|
+
assert_equal(OraNumber.new(num.to_s), bind_and_get(num, OraNumber))
|
35
|
+
end
|
36
|
+
|
37
|
+
define_method("test_bind_param_with_output_of '#{num}'") do
|
38
|
+
result = bind_and_get(OraNumber.new(num.to_s), Integer)
|
39
|
+
assert_equal(num, result)
|
40
|
+
assert_kind_of(Integer, result)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def teardown
|
45
|
+
@conn.logoff
|
46
|
+
end
|
47
|
+
end
|
data/test/test_break.rb
CHANGED
@@ -7,10 +7,12 @@ class TestBreak < Minitest::Test
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
@conn = get_oci8_connection
|
10
|
+
Thread.report_on_exception, @original_report_on_exception = false, Thread.report_on_exception if Thread.respond_to?(:report_on_exception)
|
10
11
|
end
|
11
12
|
|
12
13
|
def teardown
|
13
14
|
@conn.logoff
|
15
|
+
Thread.report_on_exception = @original_report_on_exception if Thread.respond_to?(:report_on_exception)
|
14
16
|
end
|
15
17
|
|
16
18
|
def report(str)
|
@@ -20,9 +22,8 @@ class TestBreak < Minitest::Test
|
|
20
22
|
@@server_is_runing_on_windows = nil
|
21
23
|
def server_is_runing_on_windows?
|
22
24
|
if @@server_is_runing_on_windows.nil?
|
23
|
-
|
24
|
-
|
25
|
-
@@server_is_runing_on_windows = true if row[0].include? 'Windows'
|
25
|
+
@conn.exec('select dbms_utility.port_string from dual') do |row|
|
26
|
+
@@server_is_runing_on_windows = row[0].include? '/WIN'
|
26
27
|
end
|
27
28
|
end
|
28
29
|
@@server_is_runing_on_windows
|
@@ -61,7 +62,7 @@ class TestBreak < Minitest::Test
|
|
61
62
|
expect = []
|
62
63
|
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
63
64
|
expect[OCIBREAK] = "Invalid status"
|
64
|
-
if defined? Rubinius and Rubinius::VERSION >= "2.0"
|
65
|
+
if (defined? Rubinius and Rubinius::VERSION >= "2.0") || (defined? RUBY_ENGINE and RUBY_ENGINE == "truffleruby")
|
65
66
|
# Rubinius 2.0.0.
|
66
67
|
# DBMS_LOCK.SLEEP blocks ruby threads which try to call C-API.
|
67
68
|
expect[SEND_BREAK] = TIME_TO_BREAK
|
@@ -98,6 +99,11 @@ class TestBreak < Minitest::Test
|
|
98
99
|
def test_timeout
|
99
100
|
@conn.non_blocking = true
|
100
101
|
start_time = Time.now
|
102
|
+
if server_is_runing_on_windows?
|
103
|
+
end_time = start_time + 5
|
104
|
+
else
|
105
|
+
end_time = start_time + 1
|
106
|
+
end
|
101
107
|
|
102
108
|
if defined? Rubinius and Rubinius::VERSION < "2.0"
|
103
109
|
# Rubinius 1.2.4
|
@@ -111,12 +117,8 @@ class TestBreak < Minitest::Test
|
|
111
117
|
@conn.exec("BEGIN DBMS_LOCK.SLEEP(5); END;")
|
112
118
|
end
|
113
119
|
end
|
114
|
-
if server_is_runing_on_windows?
|
115
|
-
end_time = start_time + 5
|
116
|
-
else
|
117
|
-
end_time = start_time + 1
|
118
|
-
end
|
119
120
|
assert_in_delta(Time.now, end_time, 1)
|
121
|
+
sleep(0.01) # for truffleruby. Is truffleruby too fast?
|
120
122
|
@conn.exec("BEGIN NULL; END;")
|
121
123
|
assert_in_delta(Time.now, end_time, 1)
|
122
124
|
end
|
data/test/test_clob.rb
CHANGED
@@ -24,22 +24,6 @@ class TestCLob < Minitest::Test
|
|
24
24
|
lob.close
|
25
25
|
end
|
26
26
|
|
27
|
-
def test_insert_with_flush
|
28
|
-
filename = File.basename($lobfile)
|
29
|
-
@conn.exec("DELETE FROM test_table WHERE filename = :1", filename)
|
30
|
-
@conn.exec("INSERT INTO test_table(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
31
|
-
cursor = @conn.exec("SELECT content FROM test_table WHERE filename = :1 FOR UPDATE", filename)
|
32
|
-
lob = cursor.fetch[0]
|
33
|
-
lob.sync = false
|
34
|
-
open($lobfile) do |f|
|
35
|
-
while s = f.read(1000)
|
36
|
-
lob.write(s)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
lob.flush
|
40
|
-
lob.close
|
41
|
-
end
|
42
|
-
|
43
27
|
def test_insert_symbol
|
44
28
|
filename = 'test_symbol'
|
45
29
|
value = :foo_bar
|
@@ -67,7 +51,7 @@ class TestCLob < Minitest::Test
|
|
67
51
|
# Though buf.size counts in byte,
|
68
52
|
# offset and $lobreadnum count in character.
|
69
53
|
end
|
70
|
-
|
54
|
+
assert_nil(buf)
|
71
55
|
assert(f.eof?)
|
72
56
|
assert(lob.eof?)
|
73
57
|
end
|
@@ -76,7 +60,11 @@ class TestCLob < Minitest::Test
|
|
76
60
|
|
77
61
|
# https://github.com/kubo/ruby-oci8/issues/20
|
78
62
|
def test_github_issue_20
|
63
|
+
# Skip this test if FULLTEST isn't set because it takes 4 minutes in my Linux box.
|
64
|
+
return if ENV['FULLTEST']
|
65
|
+
|
79
66
|
lob1 = OCI8::CLOB.new(@conn, ' ' * (1024 * 1024))
|
67
|
+
lob1.read(1) # to suppress `warning: assigned but unused variable - lob1`
|
80
68
|
begin
|
81
69
|
lob2 = OCI8::CLOB.new(@conn, ' ' * (128 * 1024 * 1024))
|
82
70
|
rescue OCIError
|
data/test/test_connstr.rb
CHANGED
@@ -75,4 +75,146 @@ class TestConnStr < Minitest::Test
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
# https://docs.oracle.com/database/121/NETAG/naming.htm#BABJBFHJ
|
80
|
+
DESC_TEST_CASE =
|
81
|
+
[
|
82
|
+
# Cannot distinguish net service names from easy connect strings in this case.
|
83
|
+
["sales-server", nil, nil, false, "sales-server"],
|
84
|
+
# Easy Connect string with host.
|
85
|
+
["//sales-server", nil, nil, false, <<EOS],
|
86
|
+
(DESCRIPTION=
|
87
|
+
(CONNECT_DATA=
|
88
|
+
(SERVICE_NAME=))
|
89
|
+
(ADDRESS=
|
90
|
+
(PROTOCOL=TCP)
|
91
|
+
(HOST=sales-server)
|
92
|
+
(PORT=1521)))
|
93
|
+
EOS
|
94
|
+
# Easy Connect string with host and port.
|
95
|
+
["sales-server:3456", nil, nil, false, <<EOS],
|
96
|
+
(DESCRIPTION=
|
97
|
+
(CONNECT_DATA=
|
98
|
+
(SERVICE_NAME=))
|
99
|
+
(ADDRESS=
|
100
|
+
(PROTOCOL=TCP)
|
101
|
+
(HOST=sales-server)
|
102
|
+
(PORT=3456)))
|
103
|
+
EOS
|
104
|
+
# The host name is sales-server and the service name is sales.
|
105
|
+
["sales-server/sales", nil, nil, false, <<EOS],
|
106
|
+
(DESCRIPTION=
|
107
|
+
(CONNECT_DATA=
|
108
|
+
(SERVICE_NAME=sales))
|
109
|
+
(ADDRESS=
|
110
|
+
(PROTOCOL=TCP)
|
111
|
+
(HOST=sales-server)
|
112
|
+
(PORT=1521)))
|
113
|
+
EOS
|
114
|
+
# Easy Connect string with IPv6 address.
|
115
|
+
["[2001:0db8:0:0::200C:417A]:80/sales", nil, nil, false, <<EOS],
|
116
|
+
(DESCRIPTION=
|
117
|
+
(CONNECT_DATA=
|
118
|
+
(SERVICE_NAME=sales))
|
119
|
+
(ADDRESS=
|
120
|
+
(PROTOCOL=TCP)
|
121
|
+
(HOST=2001:0db8:0:0::200C:417A)
|
122
|
+
(PORT=80)))
|
123
|
+
EOS
|
124
|
+
# Easy Connect string with IPv6 host address.
|
125
|
+
["sales-server:80/sales", nil, nil, false, <<EOS],
|
126
|
+
(DESCRIPTION=
|
127
|
+
(CONNECT_DATA=
|
128
|
+
(SERVICE_NAME=sales))
|
129
|
+
(ADDRESS=
|
130
|
+
(PROTOCOL=TCP)
|
131
|
+
(HOST=sales-server)
|
132
|
+
(PORT=80)))
|
133
|
+
EOS
|
134
|
+
# Easy Connect string with host, service name, and server.
|
135
|
+
["sales-server/sales:dedicated/inst1", nil, nil, false, <<EOS],
|
136
|
+
(DESCRIPTION=
|
137
|
+
(CONNECT_DATA=
|
138
|
+
(SERVICE_NAME=sales)
|
139
|
+
(SERVER=dedicated)
|
140
|
+
(INSTANCE_NAME=inst1))
|
141
|
+
(ADDRESS=
|
142
|
+
(PROTOCOL=TCP)
|
143
|
+
(HOST=sales-server)
|
144
|
+
(PORT=1521)))
|
145
|
+
EOS
|
146
|
+
["sales-server//inst1", nil, nil, false, <<EOS],
|
147
|
+
(DESCRIPTION=
|
148
|
+
(CONNECT_DATA=
|
149
|
+
(SERVICE_NAME=)
|
150
|
+
(INSTANCE_NAME=inst1))
|
151
|
+
(ADDRESS=
|
152
|
+
(PROTOCOL=TCP)
|
153
|
+
(HOST=sales-server)
|
154
|
+
(PORT=1521)))
|
155
|
+
EOS
|
156
|
+
#
|
157
|
+
["sales-server/sales", 20, nil, false, <<EOS],
|
158
|
+
(DESCRIPTION=
|
159
|
+
(CONNECT_DATA=
|
160
|
+
(SERVICE_NAME=sales))
|
161
|
+
(ADDRESS=
|
162
|
+
(PROTOCOL=TCP)
|
163
|
+
(HOST=sales-server)
|
164
|
+
(PORT=1521))
|
165
|
+
(TRANSPORT_CONNECT_TIMEOUT=20))
|
166
|
+
EOS
|
167
|
+
#
|
168
|
+
["sales-server/sales", nil, 30, false, <<EOS],
|
169
|
+
(DESCRIPTION=
|
170
|
+
(CONNECT_DATA=
|
171
|
+
(SERVICE_NAME=sales))
|
172
|
+
(ADDRESS=
|
173
|
+
(PROTOCOL=TCP)
|
174
|
+
(HOST=sales-server)
|
175
|
+
(PORT=1521))
|
176
|
+
(CONNECT_TIMEOUT=30))
|
177
|
+
EOS
|
178
|
+
#
|
179
|
+
["sales-server/sales", 20, 30, false, <<EOS],
|
180
|
+
(DESCRIPTION=
|
181
|
+
(CONNECT_DATA=
|
182
|
+
(SERVICE_NAME=sales))
|
183
|
+
(ADDRESS=
|
184
|
+
(PROTOCOL=TCP)
|
185
|
+
(HOST=sales-server)
|
186
|
+
(PORT=1521))
|
187
|
+
(TRANSPORT_CONNECT_TIMEOUT=20)
|
188
|
+
(CONNECT_TIMEOUT=30))
|
189
|
+
EOS
|
190
|
+
["sales-server/sales", 20, 30, true, <<EOS],
|
191
|
+
(DESCRIPTION=
|
192
|
+
(CONNECT_DATA=
|
193
|
+
(SERVICE_NAME=sales)
|
194
|
+
)
|
195
|
+
(ADDRESS=
|
196
|
+
(PROTOCOL=TCP)
|
197
|
+
(HOST=sales-server)
|
198
|
+
(PORT=1521)
|
199
|
+
)
|
200
|
+
(TRANSPORT_CONNECT_TIMEOUT=20)
|
201
|
+
(CONNECT_TIMEOUT=30)
|
202
|
+
(ENABLE=BROKEN)
|
203
|
+
)
|
204
|
+
EOS
|
205
|
+
]
|
206
|
+
|
207
|
+
def test_connect_descriptor
|
208
|
+
obj = OCI8.allocate # create an uninitialized object.
|
209
|
+
DESC_TEST_CASE.each do |test_case|
|
210
|
+
easy_connect_string = test_case[0]
|
211
|
+
tcp_connnect_timeout= test_case[1]
|
212
|
+
outbound_connnect_timeout = test_case[2]
|
213
|
+
tcp_keepalive = test_case[3]
|
214
|
+
expected_result = test_case[4].gsub(/\s/, '')
|
215
|
+
# use instance_eval to call a private method to_connect_descriptor
|
216
|
+
result = obj.instance_eval { to_connect_descriptor(easy_connect_string, tcp_connnect_timeout, outbound_connnect_timeout, tcp_keepalive) }
|
217
|
+
assert_equal(expected_result, result, easy_connect_string)
|
218
|
+
end
|
219
|
+
end
|
78
220
|
end
|
data/test/test_datetime.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'oci8'
|
2
2
|
require File.dirname(__FILE__) + '/config'
|
3
|
-
require 'scanf'
|
4
3
|
|
5
4
|
class TestDateTime < Minitest::Test
|
6
5
|
|
@@ -28,6 +27,12 @@ class TestDateTime < Minitest::Test
|
|
28
27
|
convert_to_datetime($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, subsec, $8)
|
29
28
|
end
|
30
29
|
|
30
|
+
# 'YYYY-MM-DD HH24:MI:SS' or 'YYYY-MM-DD HH24:MI:SS.FF6' to array
|
31
|
+
def string_to_array(str)
|
32
|
+
/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(?:\.(\d+))?/ =~ str
|
33
|
+
[$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, $7 ? $7.to_i / 1000 : 0]
|
34
|
+
end
|
35
|
+
|
31
36
|
def setup
|
32
37
|
@conn = get_oci8_connection
|
33
38
|
end
|
@@ -43,7 +48,7 @@ class TestDateTime < Minitest::Test
|
|
43
48
|
@conn.exec(<<-EOS) do |row|
|
44
49
|
SELECT TO_DATE('#{date}', 'YYYY-MM-DD HH24:MI:SS') FROM dual
|
45
50
|
EOS
|
46
|
-
assert_equal(Time.local(*date
|
51
|
+
assert_equal(Time.local(*string_to_array(date)), row[0])
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
@@ -94,7 +99,7 @@ EOS
|
|
94
99
|
@conn.exec(<<-EOS) do |row|
|
95
100
|
SELECT TO_TIMESTAMP('#{date}', 'YYYY-MM-DD HH24:MI:SS.FF') FROM dual
|
96
101
|
EOS
|
97
|
-
assert_equal(Time.local(*date
|
102
|
+
assert_equal(Time.local(*string_to_array(date)), row[0])
|
98
103
|
end
|
99
104
|
end
|
100
105
|
end
|
data/test/test_metadata.rb
CHANGED
@@ -42,6 +42,8 @@ class TestMetadata < Minitest::Test
|
|
42
42
|
assert(expected_value.call(val), "#{msg} > #{method}")
|
43
43
|
when Regexp
|
44
44
|
assert_match(expected_value, val, "#{msg} > #{method}")
|
45
|
+
when nil
|
46
|
+
assert_nil(val, "#{msg} > #{method}")
|
45
47
|
else
|
46
48
|
assert_equal(expected_value, val, "#{msg} > #{method}")
|
47
49
|
end
|
@@ -1335,7 +1337,6 @@ EOS
|
|
1335
1337
|
drop_type('TEST_TYPE_NESTEAD_TABLE')
|
1336
1338
|
drop_type('TEST_TYPE_CHILD')
|
1337
1339
|
drop_type('TEST_TYPE_PARENT')
|
1338
|
-
expected_values = []
|
1339
1340
|
attrs_map = {}
|
1340
1341
|
|
1341
1342
|
@conn.exec(<<-EOS)
|
data/test/test_object.rb
CHANGED
@@ -22,7 +22,7 @@ begin
|
|
22
22
|
|
23
23
|
begin
|
24
24
|
version = RbTestObj.test_object_version(conn)
|
25
|
-
error_message = "Invalid test object version" if version !=
|
25
|
+
error_message = "Invalid test object version" if version != 4
|
26
26
|
rescue NoMethodError
|
27
27
|
raise unless $!.to_s.include?('test_object_version')
|
28
28
|
error_message = "rb_test_obj.test_object_version is not declared."
|
@@ -48,6 +48,12 @@ EOS
|
|
48
48
|
class RbTestIntArray < OCI8::Object::Base
|
49
49
|
end
|
50
50
|
|
51
|
+
class RbTestObjBase < OCI8::Object::Base
|
52
|
+
end
|
53
|
+
|
54
|
+
class RbTestObjSub < RbTestObjBase
|
55
|
+
end
|
56
|
+
|
51
57
|
class TestObj1 < Minitest::Test
|
52
58
|
Delta = 0.00001
|
53
59
|
|
@@ -94,7 +100,8 @@ class TestObj1 < Minitest::Test
|
|
94
100
|
attr_reader :obj_array_val
|
95
101
|
attr_reader :obj_ary_of_ary_val
|
96
102
|
attr_reader :date_val
|
97
|
-
|
103
|
+
attr_reader :timestamp_val
|
104
|
+
attr_reader :timestamp_tz_val
|
98
105
|
|
99
106
|
attr_accessor :assertions
|
100
107
|
|
@@ -103,16 +110,28 @@ class TestObj1 < Minitest::Test
|
|
103
110
|
@assertions = 0
|
104
111
|
end
|
105
112
|
|
106
|
-
def
|
113
|
+
def to_test_datetime(n, type)
|
107
114
|
year = (1990 + n).round
|
108
115
|
month = (n.round * 5) % 12 + 1
|
109
116
|
mday = (n.round * 7) % 27 + 1
|
110
117
|
hour = (n.round * 9) % 24
|
111
118
|
minute = (n.round * 11) % 60
|
112
119
|
sec = (n.round * 13) % 60
|
113
|
-
|
120
|
+
nsec = if type == :date
|
121
|
+
0
|
122
|
+
else
|
123
|
+
((n.round * 333_333_333) % 1_000_000_000).to_r / 1_000_000_000
|
124
|
+
end
|
125
|
+
tz = if type == :timestamp_tz
|
126
|
+
tzh = (n.round * 15) % 24 - 11
|
127
|
+
tzm = (n.round * 17) % 60
|
128
|
+
format('%+03d:%02d', tzh, tzm)
|
129
|
+
else
|
130
|
+
nil
|
131
|
+
end
|
132
|
+
convert_to_time(year, month, mday, hour, minute, sec, nsec, tz)
|
114
133
|
end
|
115
|
-
private :
|
134
|
+
private :to_test_datetime
|
116
135
|
|
117
136
|
def next
|
118
137
|
@n += 1.2
|
@@ -129,7 +148,9 @@ class TestObj1 < Minitest::Test
|
|
129
148
|
@nclob_val = @str_val
|
130
149
|
@blob_val = @str_val
|
131
150
|
@obj_val = ExpectedValObjElem.new(@int_val, @int_val + 1)
|
132
|
-
@date_val =
|
151
|
+
@date_val = to_test_datetime(@n, :date)
|
152
|
+
@timestamp_val = to_test_datetime(@n, :timestamp)
|
153
|
+
@timestamp_tz_val = to_test_datetime(@n, :timestamp_tz)
|
133
154
|
if @int_val == 1
|
134
155
|
@int_array_val = nil
|
135
156
|
@flt_array_val = nil
|
@@ -193,7 +214,8 @@ class TestObj1 < Minitest::Test
|
|
193
214
|
obj_array_val = val[18]
|
194
215
|
obj_ary_of_ary_val = val[19]
|
195
216
|
date_val = val[20]
|
196
|
-
|
217
|
+
timestamp_val = val[21]
|
218
|
+
timestamp_tz_val = val[22]
|
197
219
|
else
|
198
220
|
assert_instance_of(RbTestObj, val)
|
199
221
|
int_val = val.int_val
|
@@ -217,7 +239,8 @@ class TestObj1 < Minitest::Test
|
|
217
239
|
obj_array_val = val.obj_array_val
|
218
240
|
obj_ary_of_ary_val = val.obj_ary_of_ary_val
|
219
241
|
date_val = val.date_val
|
220
|
-
|
242
|
+
timestamp_val = val.timestamp_val
|
243
|
+
timestamp_tz_val = val.timestamp_tz_val
|
221
244
|
end
|
222
245
|
|
223
246
|
assert_equal(@int_val, int_val)
|
@@ -231,17 +254,38 @@ class TestObj1 < Minitest::Test
|
|
231
254
|
assert_equal(@nclob_val, nclob_val)
|
232
255
|
assert_equal(@blob_val, blob_val)
|
233
256
|
assert_equal(@obj_val, obj_val)
|
234
|
-
|
257
|
+
if @int_array_val
|
258
|
+
assert_equal(@int_array_val, int_array_val.to_ary)
|
259
|
+
else
|
260
|
+
assert_nil(@int_array_val, int_array_val)
|
261
|
+
end
|
235
262
|
assert_array_in_delta(@flt_array_val, flt_array_val && flt_array_val.to_ary)
|
236
263
|
assert_array_in_delta(@num_array_val, num_array_val && num_array_val.to_ary)
|
237
264
|
assert_array_in_delta(@bdbl_array_val, bdbl_array_val && bdbl_array_val.to_ary)
|
238
265
|
assert_array_in_delta(@bflt_array_val, bflt_array_val && bflt_array_val.to_ary)
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
266
|
+
if @str_array_val
|
267
|
+
assert_equal(@str_array_val, str_array_val.to_ary)
|
268
|
+
else
|
269
|
+
assert_nil(str_array_val)
|
270
|
+
end
|
271
|
+
if @raw_array_val
|
272
|
+
assert_equal(@raw_array_val, raw_array_val.to_ary)
|
273
|
+
else
|
274
|
+
assert_nil(raw_array_val)
|
275
|
+
end
|
276
|
+
if @obj_array_val
|
277
|
+
assert_equal(@obj_array_val, obj_array_val.to_ary)
|
278
|
+
else
|
279
|
+
assert_nil(obj_array_val)
|
280
|
+
end
|
281
|
+
if @obj_ary_of_ary_val
|
282
|
+
assert_equal(@obj_ary_of_ary_val, obj_ary_of_ary_val.to_ary.collect { |elem| elem.to_ary })
|
283
|
+
else
|
284
|
+
assert_nil(obj_ary_of_ary_val)
|
285
|
+
end
|
243
286
|
assert_equal(@date_val, date_val)
|
244
|
-
|
287
|
+
assert_equal(@timestamp_val, timestamp_val)
|
288
|
+
assert_equal(@timestamp_tz_val, timestamp_tz_val)
|
245
289
|
end
|
246
290
|
|
247
291
|
def assert_array_in_delta(exp, val)
|
@@ -250,6 +294,8 @@ class TestObj1 < Minitest::Test
|
|
250
294
|
exp.each_with_index do |elem, idx|
|
251
295
|
assert_in_delta(elem, val[idx], Delta)
|
252
296
|
end
|
297
|
+
elsif exp.nil?
|
298
|
+
assert_nil(val)
|
253
299
|
else
|
254
300
|
assert_equal(exp, val)
|
255
301
|
end
|
@@ -450,10 +496,45 @@ EOS
|
|
450
496
|
csr.bind_param(:out2, nil, Integer)
|
451
497
|
csr.bind_param(:out3, nil, Integer)
|
452
498
|
csr.exec
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
499
|
+
if ary
|
500
|
+
assert_equal(ary.length, csr[:cnt])
|
501
|
+
else
|
502
|
+
assert_equal(-1, csr[:cnt])
|
503
|
+
end
|
504
|
+
if ary && ary[0]
|
505
|
+
assert_equal(ary[0], csr[:out1])
|
506
|
+
else
|
507
|
+
assert_nil(csr[:out1])
|
508
|
+
end
|
509
|
+
if ary && ary[1]
|
510
|
+
assert_equal(ary[1], csr[:out2])
|
511
|
+
else
|
512
|
+
assert_nil(csr[:out2])
|
513
|
+
end
|
514
|
+
if ary && ary[2]
|
515
|
+
assert_equal(ary[2], csr[:out3])
|
516
|
+
else
|
517
|
+
assert_nil(csr[:out3])
|
518
|
+
end
|
457
519
|
end
|
458
520
|
end
|
521
|
+
|
522
|
+
def test_get_subtype
|
523
|
+
csr = @conn.parse("BEGIN :result := rb_test_obj_get_object(:1); END;")
|
524
|
+
csr.bind_param(1, nil, RbTestObjBase)
|
525
|
+
csr.bind_param(2, nil, Integer)
|
526
|
+
|
527
|
+
csr[2] = 0
|
528
|
+
csr.exec
|
529
|
+
val = csr[1]
|
530
|
+
assert_instance_of(RbTestObjBase, val)
|
531
|
+
assert_equal(val.id, 'base')
|
532
|
+
|
533
|
+
csr[2] = 1
|
534
|
+
csr.exec
|
535
|
+
val = csr[1]
|
536
|
+
assert_instance_of(RbTestObjSub, val)
|
537
|
+
assert_equal(val.id, 'sub')
|
538
|
+
assert_equal(val.subid, 'subid')
|
539
|
+
end
|
459
540
|
end
|