ruby-oci8 2.2.0.2 → 2.2.12
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.
- 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
|