ruby-oci8 2.1.5.1-x64-mingw32
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 +17 -0
- data/COPYING +30 -0
- data/COPYING_old +64 -0
- data/ChangeLog +2779 -0
- data/Makefile +92 -0
- data/NEWS +660 -0
- data/README.md +43 -0
- data/VERSION +1 -0
- data/dist-files +91 -0
- data/docs/install-binary-package.md +40 -0
- data/docs/install-full-client.md +116 -0
- data/docs/install-instant-client.md +167 -0
- data/docs/platform-specific-issues.md +197 -0
- data/docs/report-installation-issue.md +50 -0
- data/lib/.document +1 -0
- data/lib/dbd/OCI8.rb +591 -0
- data/lib/oci8.rb +147 -0
- data/lib/oci8.rb.in +147 -0
- data/lib/oci8/.document +8 -0
- data/lib/oci8/bindtype.rb +350 -0
- data/lib/oci8/compat.rb +113 -0
- data/lib/oci8/connection_pool.rb +108 -0
- data/lib/oci8/cursor.rb +564 -0
- data/lib/oci8/datetime.rb +605 -0
- data/lib/oci8/encoding-init.rb +79 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2092 -0
- data/lib/oci8/object.rb +605 -0
- data/lib/oci8/oci8.rb +560 -0
- data/lib/oci8/ocihandle.rb +607 -0
- data/lib/oci8/oracle_version.rb +143 -0
- data/lib/oci8/properties.rb +134 -0
- data/lib/oci8lib_200.so +0 -0
- data/metaconfig +142 -0
- data/pre-distclean.rb +7 -0
- data/ruby-oci8.gemspec +80 -0
- data/setup.rb +1333 -0
- data/test/README +42 -0
- data/test/config.rb +184 -0
- data/test/setup_test_object.sql +171 -0
- data/test/test_all.rb +54 -0
- data/test/test_appinfo.rb +63 -0
- data/test/test_array_dml.rb +333 -0
- data/test/test_bind_raw.rb +46 -0
- data/test/test_bind_string.rb +106 -0
- data/test/test_bind_time.rb +178 -0
- data/test/test_break.rb +124 -0
- data/test/test_clob.rb +98 -0
- data/test/test_connection_pool.rb +125 -0
- data/test/test_connstr.rb +81 -0
- data/test/test_datetime.rb +581 -0
- data/test/test_dbi.rb +366 -0
- data/test/test_dbi_clob.rb +53 -0
- data/test/test_encoding.rb +104 -0
- data/test/test_error.rb +88 -0
- data/test/test_metadata.rb +1485 -0
- data/test/test_object.rb +462 -0
- data/test/test_oci8.rb +489 -0
- data/test/test_oracle_version.rb +70 -0
- data/test/test_oradate.rb +256 -0
- data/test/test_oranumber.rb +787 -0
- data/test/test_rowid.rb +33 -0
- metadata +109 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'oci8'
|
2
|
+
require 'test/unit'
|
3
|
+
require File.dirname(__FILE__) + '/config'
|
4
|
+
|
5
|
+
class TestBindTime < Test::Unit::TestCase
|
6
|
+
|
7
|
+
YEAR_CHECK_TARGET = [1971, 1989, 2002, 2037]
|
8
|
+
MON_CHECK_TARGET = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
9
|
+
DAY_CHECK_TARGET = [1, 10, 20, 31] # days of January.
|
10
|
+
HOUR_CHECK_TARGET = [0, 6, 12, 18, 23]
|
11
|
+
MIN_CHECK_TARGET = [0, 15, 30, 45, 59]
|
12
|
+
SEC_CHECK_TARGET = [0, 15, 30, 45, 59]
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@conn = get_oci8_connection
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_set_year
|
19
|
+
cursor = @conn.parse("BEGIN :year := TO_NUMBER(TO_CHAR(:time, 'SYYYY'), '9999'); END;")
|
20
|
+
cursor.bind_param(:time, Time)
|
21
|
+
cursor.bind_param(:year, Fixnum)
|
22
|
+
|
23
|
+
YEAR_CHECK_TARGET.each do |i|
|
24
|
+
# set year
|
25
|
+
cursor[:time] = Time.local(i, 1)
|
26
|
+
# check result
|
27
|
+
cursor.exec
|
28
|
+
assert_equal(i, cursor[:year])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_get_year
|
33
|
+
cursor = @conn.parse("BEGIN :time := TO_DATE(TO_CHAR(:year, '0999'), 'SYYYY'); END;")
|
34
|
+
cursor.bind_param(:year, Fixnum)
|
35
|
+
cursor.bind_param(:time, Time)
|
36
|
+
YEAR_CHECK_TARGET.each do |i|
|
37
|
+
# set time via oracle.
|
38
|
+
cursor[:year] = i
|
39
|
+
cursor.exec
|
40
|
+
# check Time#year
|
41
|
+
assert_equal(i, cursor[:time].year)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_set_mon
|
46
|
+
cursor = @conn.parse("BEGIN :mon := TO_NUMBER(TO_CHAR(:time, 'MM'), '99'); END;")
|
47
|
+
cursor.bind_param(:time, Time)
|
48
|
+
cursor.bind_param(:mon, Fixnum)
|
49
|
+
MON_CHECK_TARGET.each do |i|
|
50
|
+
# set mon
|
51
|
+
cursor[:time] = Time.local(2001, i)
|
52
|
+
# check result via oracle.
|
53
|
+
cursor.exec
|
54
|
+
assert_equal(i, cursor[:mon])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_get_mon
|
59
|
+
cursor = @conn.parse("BEGIN :time := TO_DATE(TO_CHAR(:mon, '99'), 'MM'); END;")
|
60
|
+
cursor.bind_param(:mon, Fixnum)
|
61
|
+
cursor.bind_param(:time, Time)
|
62
|
+
MON_CHECK_TARGET.each do |i|
|
63
|
+
# set time via oracle.
|
64
|
+
cursor[:mon] = i;
|
65
|
+
cursor.exec
|
66
|
+
# check Time#mon
|
67
|
+
assert_equal(i, cursor[:time].mon)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_set_day
|
72
|
+
cursor = @conn.parse("BEGIN :day := TO_NUMBER(TO_CHAR(:time, 'DD'), '99'); END;")
|
73
|
+
cursor.bind_param(:time, Time)
|
74
|
+
cursor.bind_param(:day, Fixnum)
|
75
|
+
DAY_CHECK_TARGET.each do |i|
|
76
|
+
# set day
|
77
|
+
cursor[:time] = Time.local(2001, 1, i)
|
78
|
+
# check result via oracle.
|
79
|
+
cursor.exec
|
80
|
+
assert_equal(i, cursor[:day])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_get_day
|
85
|
+
cursor = @conn.parse("BEGIN :time := TO_DATE('200101' || TO_CHAR(:day, 'FM00'), 'YYYYMMDD'); END;")
|
86
|
+
cursor.bind_param(:day, Fixnum)
|
87
|
+
cursor.bind_param(:time, Time)
|
88
|
+
DAY_CHECK_TARGET.each do |i|
|
89
|
+
# set time via oracle.
|
90
|
+
cursor[:day] = i;
|
91
|
+
cursor.exec
|
92
|
+
# check Time#day
|
93
|
+
assert_equal(i, cursor[:time].day)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_set_hour
|
98
|
+
cursor = @conn.parse("BEGIN :hour := TO_NUMBER(TO_CHAR(:time, 'HH24'), '99'); END;")
|
99
|
+
cursor.bind_param(:time, Time)
|
100
|
+
cursor.bind_param(:hour, Fixnum)
|
101
|
+
HOUR_CHECK_TARGET.each do |i|
|
102
|
+
# set hour
|
103
|
+
cursor[:time] = Time.local(2001, 1, 1, i)
|
104
|
+
# check result via oracle.
|
105
|
+
cursor.exec
|
106
|
+
assert_equal(i, cursor[:hour])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_get_hour
|
111
|
+
cursor = @conn.parse("BEGIN :time := TO_DATE(TO_CHAR(:hour, '99'), 'HH24'); END;")
|
112
|
+
cursor.bind_param(:hour, Fixnum)
|
113
|
+
cursor.bind_param(:time, Time)
|
114
|
+
HOUR_CHECK_TARGET.each do |i|
|
115
|
+
# set time via oracle.
|
116
|
+
cursor[:hour] = i
|
117
|
+
cursor.exec
|
118
|
+
# check Time#hour
|
119
|
+
assert_equal(i, cursor[:time].hour)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_set_min
|
124
|
+
cursor = @conn.parse("BEGIN :min := TO_NUMBER(TO_CHAR(:time, 'MI'), '99'); END;")
|
125
|
+
cursor.bind_param(:time, Time)
|
126
|
+
cursor.bind_param(:min, Fixnum)
|
127
|
+
MIN_CHECK_TARGET.each do |i|
|
128
|
+
# set min
|
129
|
+
cursor[:time] = Time.local(2001, 1, 1, 0, i)
|
130
|
+
# check result via oracle.
|
131
|
+
cursor.exec
|
132
|
+
assert_equal(i, cursor[:min])
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_get_min
|
137
|
+
cursor = @conn.parse("BEGIN :time := TO_DATE(TO_CHAR(:min, '99'), 'MI'); END;")
|
138
|
+
cursor.bind_param(:min, Fixnum)
|
139
|
+
cursor.bind_param(:time, Time)
|
140
|
+
MIN_CHECK_TARGET.each do |i|
|
141
|
+
# set time via oracle.
|
142
|
+
cursor[:min] = i;
|
143
|
+
cursor.exec
|
144
|
+
# check Time#min
|
145
|
+
assert_equal(i, cursor[:time].min)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_set_sec
|
150
|
+
cursor = @conn.parse("BEGIN :sec := TO_NUMBER(TO_CHAR(:time, 'SS'), '99'); END;")
|
151
|
+
cursor.bind_param(:time, Time)
|
152
|
+
cursor.bind_param(:sec, Fixnum)
|
153
|
+
SEC_CHECK_TARGET.each do |i|
|
154
|
+
# set sec
|
155
|
+
cursor[:time] = Time.local(2001, 1, 1, 0, 0, i)
|
156
|
+
# check result via oracle.
|
157
|
+
cursor.exec
|
158
|
+
assert_equal(i, cursor[:sec])
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_get_sec
|
163
|
+
cursor = @conn.parse("BEGIN :time := TO_DATE(TO_CHAR(:sec, '99'), 'SS'); END;")
|
164
|
+
cursor.bind_param(:sec, Fixnum)
|
165
|
+
cursor.bind_param(:time, Time)
|
166
|
+
SEC_CHECK_TARGET.each do |i|
|
167
|
+
# set time via oracle.
|
168
|
+
cursor[:sec] = i
|
169
|
+
cursor.exec
|
170
|
+
# check Time#sec
|
171
|
+
assert_equal(i, cursor[:time].sec)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def teardown
|
176
|
+
@conn.logoff
|
177
|
+
end
|
178
|
+
end
|
data/test/test_break.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# High-level API
|
2
|
+
require 'oci8'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'timeout'
|
5
|
+
require File.dirname(__FILE__) + '/config'
|
6
|
+
|
7
|
+
class TestBreak < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@conn = get_oci8_connection
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@conn.logoff
|
15
|
+
end
|
16
|
+
|
17
|
+
def report(str)
|
18
|
+
printf "%d: %s\n", (Time.now - $start_time), str
|
19
|
+
end
|
20
|
+
|
21
|
+
@@server_is_runing_on_windows = nil
|
22
|
+
def server_is_runing_on_windows?
|
23
|
+
if @@server_is_runing_on_windows.nil?
|
24
|
+
@@server_is_runing_on_windows = false
|
25
|
+
@conn.exec('select banner from v$version') do |row|
|
26
|
+
@@server_is_runing_on_windows = true if row[0].include? 'Windows'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@@server_is_runing_on_windows
|
30
|
+
end
|
31
|
+
|
32
|
+
PLSQL_DONE = 1
|
33
|
+
OCIBREAK = 2
|
34
|
+
SEND_BREAK = 3
|
35
|
+
|
36
|
+
TIME_IN_PLSQL = 5
|
37
|
+
TIME_TO_BREAK = 2
|
38
|
+
|
39
|
+
def do_test_ocibreak(conn, expect)
|
40
|
+
$start_time = Time.now
|
41
|
+
|
42
|
+
th = Thread.start do
|
43
|
+
begin
|
44
|
+
conn.exec("BEGIN DBMS_LOCK.SLEEP(#{TIME_IN_PLSQL}); END;")
|
45
|
+
assert_equal(expect[PLSQL_DONE], (Time.now - $start_time).round, 'PLSQL_DONE')
|
46
|
+
rescue OCIBreak
|
47
|
+
assert_equal(expect[OCIBREAK], (Time.now - $start_time).round, 'OCIBREAK')
|
48
|
+
assert_equal('Canceled by user request.', $!.to_s)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
sleep(0.3) # Wait until DBMS_LOCK.SLEEP is running.
|
53
|
+
sleep(TIME_TO_BREAK - 0.3)
|
54
|
+
assert_equal(expect[SEND_BREAK], (Time.now - $start_time).round, 'SEND_BREAK')
|
55
|
+
conn.break()
|
56
|
+
th.join
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_blocking_mode
|
60
|
+
@conn.non_blocking = false
|
61
|
+
assert_equal(false, @conn.non_blocking?)
|
62
|
+
expect = []
|
63
|
+
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
64
|
+
expect[OCIBREAK] = "Invalid status"
|
65
|
+
if defined? Rubinius and Rubinius::VERSION >= "2.0"
|
66
|
+
# Rubinius 2.0.0.
|
67
|
+
# DBMS_LOCK.SLEEP blocks ruby threads which try to call C-API.
|
68
|
+
expect[SEND_BREAK] = TIME_TO_BREAK
|
69
|
+
else
|
70
|
+
# MRI and Rubinius 1.2.4.
|
71
|
+
# DBMS_LOCK.SLEEP blocks all ruby threads.
|
72
|
+
expect[SEND_BREAK] = TIME_IN_PLSQL + TIME_TO_BREAK
|
73
|
+
end
|
74
|
+
do_test_ocibreak(@conn, expect)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_non_blocking_mode
|
78
|
+
@conn.non_blocking = true
|
79
|
+
assert_equal(true, @conn.non_blocking?)
|
80
|
+
expect = []
|
81
|
+
if server_is_runing_on_windows?
|
82
|
+
if $oracle_server_version >= OCI8::ORAVER_9_0
|
83
|
+
# raise after sleeping #{TIME_IN_PLSQL} seconds.
|
84
|
+
expect[PLSQL_DONE] = "Invalid status"
|
85
|
+
expect[OCIBREAK] = TIME_IN_PLSQL
|
86
|
+
else
|
87
|
+
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
88
|
+
expect[OCIBREAK] = "Invalid status"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
# raise immediately by OCI8#break.
|
92
|
+
expect[PLSQL_DONE] = "Invalid status"
|
93
|
+
expect[OCIBREAK] = TIME_TO_BREAK
|
94
|
+
end
|
95
|
+
expect[SEND_BREAK] = TIME_TO_BREAK
|
96
|
+
do_test_ocibreak(@conn, expect)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_timeout
|
100
|
+
@conn.non_blocking = true
|
101
|
+
start_time = Time.now
|
102
|
+
|
103
|
+
if defined? Rubinius and Rubinius::VERSION < "2.0"
|
104
|
+
# Rubinius 1.2.4
|
105
|
+
expected = OCIBreak
|
106
|
+
else
|
107
|
+
# MRI and Rubinius 2.0.0
|
108
|
+
expected = Timeout::Error
|
109
|
+
end
|
110
|
+
assert_raise(expected) do
|
111
|
+
Timeout.timeout(1) do
|
112
|
+
@conn.exec("BEGIN DBMS_LOCK.SLEEP(5); END;")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
if server_is_runing_on_windows?
|
116
|
+
end_time = start_time + 5
|
117
|
+
else
|
118
|
+
end_time = start_time + 1
|
119
|
+
end
|
120
|
+
assert_in_delta(Time.now, end_time, 1)
|
121
|
+
@conn.exec("BEGIN NULL; END;")
|
122
|
+
assert_in_delta(Time.now, end_time, 1)
|
123
|
+
end
|
124
|
+
end
|
data/test/test_clob.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Low-level API
|
2
|
+
require 'oci8'
|
3
|
+
require 'test/unit'
|
4
|
+
require File.dirname(__FILE__) + '/config'
|
5
|
+
|
6
|
+
class TestCLob < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@conn = get_oci8_connection
|
10
|
+
drop_table('test_table')
|
11
|
+
@conn.exec('CREATE TABLE test_table (filename VARCHAR2(40), content CLOB)')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_insert
|
15
|
+
filename = File.basename($lobfile)
|
16
|
+
@conn.exec("DELETE FROM test_table WHERE filename = :1", filename)
|
17
|
+
@conn.exec("INSERT INTO test_table(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
18
|
+
cursor = @conn.exec("SELECT content FROM test_table WHERE filename = :1 FOR UPDATE", filename)
|
19
|
+
lob = cursor.fetch[0]
|
20
|
+
open($lobfile) do |f|
|
21
|
+
while s = f.read(1000)
|
22
|
+
lob.write(s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
lob.close
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_insert_with_flush
|
29
|
+
filename = File.basename($lobfile)
|
30
|
+
@conn.exec("DELETE FROM test_table WHERE filename = :1", filename)
|
31
|
+
@conn.exec("INSERT INTO test_table(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
32
|
+
cursor = @conn.exec("SELECT content FROM test_table WHERE filename = :1 FOR UPDATE", filename)
|
33
|
+
lob = cursor.fetch[0]
|
34
|
+
lob.sync = false
|
35
|
+
open($lobfile) do |f|
|
36
|
+
while s = f.read(1000)
|
37
|
+
lob.write(s)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
lob.flush
|
41
|
+
lob.close
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_insert_symbol
|
45
|
+
filename = 'test_symbol'
|
46
|
+
value = :foo_bar
|
47
|
+
@conn.exec("DELETE FROM test_table WHERE filename = :1", filename)
|
48
|
+
@conn.exec("INSERT INTO test_table(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
49
|
+
cursor = @conn.exec("SELECT content FROM test_table WHERE filename = :1 FOR UPDATE", filename)
|
50
|
+
lob = cursor.fetch[0]
|
51
|
+
lob.write(value)
|
52
|
+
lob.rewind
|
53
|
+
assert_equal(value.to_s, lob.read);
|
54
|
+
lob.close
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_read
|
58
|
+
test_insert() # first insert data.
|
59
|
+
filename = File.basename($lobfile)
|
60
|
+
cursor = @conn.exec("SELECT content FROM test_table WHERE filename = :1 FOR UPDATE", filename)
|
61
|
+
lob = cursor.fetch[0]
|
62
|
+
|
63
|
+
open($lobfile) do |f|
|
64
|
+
while buf = lob.read($lobreadnum)
|
65
|
+
fbuf = f.read(buf.size)
|
66
|
+
assert_equal(fbuf, buf)
|
67
|
+
# offset += buf.size will not work fine,
|
68
|
+
# Though buf.size counts in byte,
|
69
|
+
# offset and $lobreadnum count in character.
|
70
|
+
end
|
71
|
+
assert_equal(nil, buf)
|
72
|
+
assert(f.eof?)
|
73
|
+
assert(lob.eof?)
|
74
|
+
end
|
75
|
+
lob.close
|
76
|
+
end
|
77
|
+
|
78
|
+
# https://github.com/kubo/ruby-oci8/issues/20
|
79
|
+
def test_github_issue_20
|
80
|
+
lob1 = OCI8::CLOB.new(@conn, ' ' * (1024 * 1024))
|
81
|
+
begin
|
82
|
+
lob2 = OCI8::CLOB.new(@conn, ' ' * (128 * 1024 * 1024))
|
83
|
+
rescue OCIError
|
84
|
+
raise if $!.code != 24817
|
85
|
+
# ORA-24817: Unable to allocate the given chunk for current lob operation
|
86
|
+
GC.start
|
87
|
+
# allocate smaller size
|
88
|
+
lob2 = OCI8::CLOB.new(@conn, ' ' * (16 * 1024 * 1024))
|
89
|
+
end
|
90
|
+
lob1 = nil # lob1's value will be freed in GC.
|
91
|
+
lob2.read # GC must run here to reproduce the issue.
|
92
|
+
end
|
93
|
+
|
94
|
+
def teardown
|
95
|
+
drop_table('test_table')
|
96
|
+
@conn.logoff
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'oci8'
|
2
|
+
require 'test/unit'
|
3
|
+
require File.dirname(__FILE__) + '/config'
|
4
|
+
|
5
|
+
class TestConnectionPool < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def create_pool(min, max, incr)
|
8
|
+
OCI8::ConnectionPool.new(min, max, incr, $dbuser, $dbpass, $dbname)
|
9
|
+
rescue OCIError
|
10
|
+
raise if $!.code != 12516 && $!.code != 12520
|
11
|
+
sleep(5)
|
12
|
+
OCI8::ConnectionPool.new(min, max, incr, $dbuser, $dbpass, $dbname)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_connect
|
16
|
+
pool = create_pool(1, 5, 3)
|
17
|
+
assert_equal(1, pool.min)
|
18
|
+
assert_equal(5, pool.max)
|
19
|
+
assert_equal(3, pool.incr)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_reinitialize
|
23
|
+
pool = create_pool(1, 5, 3)
|
24
|
+
pool.reinitialize(2, 6, 4)
|
25
|
+
assert_equal(2, pool.min)
|
26
|
+
assert_equal(6, pool.max)
|
27
|
+
assert_equal(4, pool.incr)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_busy_and_open_count
|
31
|
+
check_busy_and_open_count(1, 5, 3)
|
32
|
+
check_busy_and_open_count(2, 4, 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_busy_and_open_count(min_cnt, max_cnt, incr_cnt)
|
36
|
+
msg = "create_pool(#{min_cnt}, #{max_cnt}, #{incr_cnt})"
|
37
|
+
# Create a connection pool.
|
38
|
+
pool = create_pool(min_cnt, max_cnt, incr_cnt)
|
39
|
+
assert_equal(min_cnt, pool.open_count, msg)
|
40
|
+
assert_equal(0, pool.busy_count, msg)
|
41
|
+
|
42
|
+
non_blocking = true
|
43
|
+
|
44
|
+
# Create connections from the pool.
|
45
|
+
conns = []
|
46
|
+
max_cnt.times do |cnt|
|
47
|
+
conn = OCI8.new($dbuser, $dbpass, pool)
|
48
|
+
if cnt == 0
|
49
|
+
unless conn.non_blocking?
|
50
|
+
non_blocking = false
|
51
|
+
assert_raise(RuntimeError) do
|
52
|
+
# This should raise "Could not set non-blocking mode to a connection allocated from OCI8::ConnectionPool."
|
53
|
+
conn.non_blocking = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
conns << conn
|
58
|
+
end
|
59
|
+
assert_equal(min_cnt, pool.open_count, msg)
|
60
|
+
assert_equal(0, pool.busy_count, msg)
|
61
|
+
|
62
|
+
# Execute blocking SQL statements sequentially.
|
63
|
+
max_cnt.times do |n|
|
64
|
+
thread = Thread.start do
|
65
|
+
conns[n].exec "BEGIN DBMS_LOCK.SLEEP(1); END;"
|
66
|
+
end
|
67
|
+
sleep(0.5)
|
68
|
+
assert_equal(min_cnt, pool.open_count, msg)
|
69
|
+
assert_equal(non_blocking ? 1 : 0, pool.busy_count, msg)
|
70
|
+
thread.join
|
71
|
+
end
|
72
|
+
assert_equal(min_cnt, pool.open_count, msg)
|
73
|
+
assert_equal(0, pool.busy_count, msg)
|
74
|
+
|
75
|
+
# Execute blocking SQL statements parallel to increment open_count.
|
76
|
+
threads = []
|
77
|
+
(min_cnt + 1).times do |n|
|
78
|
+
threads << Thread.start do
|
79
|
+
conns[n].exec "BEGIN DBMS_LOCK.SLEEP(5); END;"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
sleep(0.5)
|
83
|
+
assert_equal(non_blocking ? (min_cnt + incr_cnt) : min_cnt, pool.open_count, msg)
|
84
|
+
assert_equal(non_blocking ? (min_cnt + 1) : 0, pool.busy_count, msg)
|
85
|
+
|
86
|
+
# Execute blocking SQL statements parallel up to maximum.
|
87
|
+
(min_cnt + 1).upto(max_cnt - 1) do |n|
|
88
|
+
threads << Thread.start do
|
89
|
+
conns[n].exec "BEGIN DBMS_LOCK.SLEEP(4); END;"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
sleep(0.5)
|
93
|
+
assert_equal(non_blocking ? max_cnt : min_cnt, pool.open_count, msg)
|
94
|
+
assert_equal(non_blocking ? max_cnt : 0, pool.busy_count, msg)
|
95
|
+
|
96
|
+
#
|
97
|
+
threads.each do |thr|
|
98
|
+
thr.join
|
99
|
+
end
|
100
|
+
assert_equal(non_blocking ? max_cnt : min_cnt, pool.open_count, msg)
|
101
|
+
assert_equal(0, pool.busy_count, msg)
|
102
|
+
|
103
|
+
# Set timeout
|
104
|
+
pool.timeout = 1
|
105
|
+
sleep(1.5)
|
106
|
+
assert_equal(non_blocking ? max_cnt : min_cnt, pool.open_count, msg) # open_count doesn't shrink.
|
107
|
+
assert_equal(0, pool.busy_count, msg)
|
108
|
+
conns[0].ping # make a network roundtrip.
|
109
|
+
sleep(0.5)
|
110
|
+
# open_count shrinks.
|
111
|
+
# The decrement count depends on Oracle version.
|
112
|
+
assert_operator(pool.open_count, :<, max_cnt, msg)
|
113
|
+
assert_equal(0, pool.busy_count, msg)
|
114
|
+
|
115
|
+
# Close all conections.
|
116
|
+
conns.each do | conn |
|
117
|
+
conn.logoff
|
118
|
+
end
|
119
|
+
assert_equal(min_cnt, pool.open_count, msg)
|
120
|
+
assert_equal(0, pool.busy_count, msg)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_nowait
|
124
|
+
end
|
125
|
+
end
|