ruby-oci8 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +569 -0
- data/Makefile +51 -0
- data/NEWS +322 -0
- data/README +415 -0
- data/VERSION +1 -0
- data/dist-files +70 -0
- data/doc/api.en.html +527 -0
- data/doc/api.en.rd +554 -0
- data/doc/api.ja.html +525 -0
- data/doc/api.ja.rd +557 -0
- data/doc/manual.css +35 -0
- data/ext/oci8/MANIFEST +22 -0
- data/ext/oci8/attr.c +415 -0
- data/ext/oci8/bind.c +194 -0
- data/ext/oci8/const.c +165 -0
- data/ext/oci8/define.c +53 -0
- data/ext/oci8/describe.c +81 -0
- data/ext/oci8/descriptor.c +39 -0
- data/ext/oci8/env.c +276 -0
- data/ext/oci8/error.c +234 -0
- data/ext/oci8/extconf.rb +118 -0
- data/ext/oci8/handle.c +262 -0
- data/ext/oci8/lob.c +386 -0
- data/ext/oci8/oci8.c +137 -0
- data/ext/oci8/oci8.h +345 -0
- data/ext/oci8/ocinumber.c +117 -0
- data/ext/oci8/oraconf.rb +1026 -0
- data/ext/oci8/oradate.c +426 -0
- data/ext/oci8/oranumber.c +445 -0
- data/ext/oci8/param.c +37 -0
- data/ext/oci8/post-config.rb +5 -0
- data/ext/oci8/server.c +182 -0
- data/ext/oci8/session.c +99 -0
- data/ext/oci8/stmt.c +624 -0
- data/ext/oci8/svcctx.c +229 -0
- data/lib/DBD/OCI8/OCI8.rb +549 -0
- data/lib/oci8.rb.in +1605 -0
- data/metaconfig +142 -0
- data/pre-distclean.rb +7 -0
- data/ruby-oci8.gemspec +54 -0
- data/ruby-oci8.spec +62 -0
- data/setup.rb +1331 -0
- data/support/README +4 -0
- data/support/runit/assert.rb +281 -0
- data/support/runit/cui/testrunner.rb +101 -0
- data/support/runit/error.rb +4 -0
- data/support/runit/method_mappable.rb +20 -0
- data/support/runit/robserver.rb +25 -0
- data/support/runit/setuppable.rb +15 -0
- data/support/runit/teardownable.rb +16 -0
- data/support/runit/testcase.rb +113 -0
- data/support/runit/testfailure.rb +25 -0
- data/support/runit/testresult.rb +121 -0
- data/support/runit/testsuite.rb +43 -0
- data/support/runit/version.rb +3 -0
- data/test/README +4 -0
- data/test/config.rb +129 -0
- data/test/test_all.rb +43 -0
- data/test/test_bind_raw.rb +53 -0
- data/test/test_bind_time.rb +191 -0
- data/test/test_break.rb +81 -0
- data/test/test_clob.rb +101 -0
- data/test/test_connstr.rb +80 -0
- data/test/test_dbi.rb +317 -0
- data/test/test_dbi_clob.rb +56 -0
- data/test/test_describe.rb +137 -0
- data/test/test_metadata.rb +243 -0
- data/test/test_oci8.rb +273 -0
- data/test/test_oradate.rb +263 -0
- data/test/test_oranumber.rb +149 -0
- metadata +118 -0
data/test/test_all.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'runit/testsuite'
|
2
|
+
require 'runit/cui/testrunner'
|
3
|
+
|
4
|
+
srcdir = File.dirname(__FILE__)
|
5
|
+
|
6
|
+
# Low-level API
|
7
|
+
require "#{srcdir}/test_oradate"
|
8
|
+
require "#{srcdir}/test_oranumber"
|
9
|
+
require "#{srcdir}/test_describe"
|
10
|
+
require "#{srcdir}/test_bind_time"
|
11
|
+
require "#{srcdir}/test_bind_raw"
|
12
|
+
if $test_clob
|
13
|
+
require "#{srcdir}/test_clob"
|
14
|
+
end
|
15
|
+
|
16
|
+
# High-level API
|
17
|
+
require "#{srcdir}/test_break"
|
18
|
+
require "#{srcdir}/test_oci8"
|
19
|
+
require "#{srcdir}/test_connstr"
|
20
|
+
require "#{srcdir}/test_metadata"
|
21
|
+
|
22
|
+
# Ruby/DBI
|
23
|
+
begin
|
24
|
+
require 'dbi'
|
25
|
+
is_dbi_loaded = true
|
26
|
+
rescue LoadError
|
27
|
+
is_dbi_loaded = false
|
28
|
+
end
|
29
|
+
if is_dbi_loaded
|
30
|
+
require "#{srcdir}/test_dbi"
|
31
|
+
if $test_clob
|
32
|
+
require "#{srcdir}/test_dbi_clob"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
suite = RUNIT::TestSuite.new
|
37
|
+
ObjectSpace.each_object(Class) { |klass|
|
38
|
+
if klass.ancestors.include?(RUNIT::TestCase)
|
39
|
+
suite.add_test(klass.suite)
|
40
|
+
end
|
41
|
+
}
|
42
|
+
#RUNIT::CUI::TestRunner.quiet_mode = true
|
43
|
+
RUNIT::CUI::TestRunner.run(suite)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Low-level API
|
2
|
+
require 'oci8'
|
3
|
+
require 'runit/testcase'
|
4
|
+
require 'runit/cui/testrunner'
|
5
|
+
require File.dirname(__FILE__) + '/config'
|
6
|
+
|
7
|
+
class TestBindRaw < RUNIT::TestCase
|
8
|
+
CHECK_TARGET = [
|
9
|
+
["0123456789:;<=>?", "303132333435363738393A3B3C3D3E3F"],
|
10
|
+
["@ABCDEFGHIJKLMNO", "404142434445464748494A4B4C4D4E4F"],
|
11
|
+
["PQRSTUVWXYZ[\\]^_", "505152535455565758595A5B5C5D5E5F"],
|
12
|
+
["`abcdefghijklmno", "606162636465666768696A6B6C6D6E6F"],
|
13
|
+
["pqrstuvwxyz{|}~", "707172737475767778797A7B7C7D7E"],
|
14
|
+
]
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@env, @svc, @stmt = setup_lowapi()
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_set_raw
|
21
|
+
@stmt.prepare("BEGIN :hex := RAWTOHEX(:raw); END;")
|
22
|
+
raw_in = @stmt.bindByName(":raw", OCI_TYPECODE_RAW, 16)
|
23
|
+
hex_out = @stmt.bindByName(":hex", String, 32)
|
24
|
+
|
25
|
+
CHECK_TARGET.each do |raw, hex|
|
26
|
+
raw_in.set(raw)
|
27
|
+
@stmt.execute(@svc)
|
28
|
+
assert_equal(hex, hex_out.get())
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_get_raw
|
33
|
+
@stmt.prepare("BEGIN :raw := HEXTORAW(:hex); END;")
|
34
|
+
hex_in = @stmt.bindByName(":hex", String, 32)
|
35
|
+
raw_out = @stmt.bindByName(":raw", OCI_TYPECODE_RAW, 16)
|
36
|
+
|
37
|
+
CHECK_TARGET.each do |raw, hex|
|
38
|
+
hex_in.set(hex)
|
39
|
+
@stmt.execute(@svc)
|
40
|
+
assert_equal(raw, raw_out.get())
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def teardown
|
45
|
+
@stmt.free()
|
46
|
+
@svc.logoff()
|
47
|
+
@env.free()
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if $0 == __FILE__
|
52
|
+
RUNIT::CUI::TestRunner.run(TestBindRaw.suite())
|
53
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# Low-level API
|
2
|
+
require 'oci8'
|
3
|
+
require 'runit/testcase'
|
4
|
+
require 'runit/cui/testrunner'
|
5
|
+
require File.dirname(__FILE__) + '/config'
|
6
|
+
|
7
|
+
class TestBindTime < RUNIT::TestCase
|
8
|
+
|
9
|
+
YEAR_CHECK_TARGET = [1971, 1989, 2002, 2037]
|
10
|
+
MON_CHECK_TARGET = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
11
|
+
DAY_CHECK_TARGET = [1, 10, 20, 31] # days of January.
|
12
|
+
HOUR_CHECK_TARGET = [0, 6, 12, 18, 23]
|
13
|
+
MIN_CHECK_TARGET = [0, 15, 30, 45, 59]
|
14
|
+
SEC_CHECK_TARGET = [0, 15, 30, 45, 59]
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@env, @svc, @stmt = setup_lowapi()
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_set_year
|
21
|
+
@stmt.prepare("BEGIN :year := TO_NUMBER(TO_CHAR(:time, 'SYYYY'), '9999'); END;")
|
22
|
+
time_in = @stmt.bindByName(":time", Time)
|
23
|
+
year_out = @stmt.bindByName(":year", Fixnum)
|
24
|
+
YEAR_CHECK_TARGET.each do |i|
|
25
|
+
# set year
|
26
|
+
time = Time.local(i, 1)
|
27
|
+
# check result via oracle.
|
28
|
+
time_in.set(time)
|
29
|
+
@stmt.execute(@svc)
|
30
|
+
assert_equal(i, year_out.get())
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_get_year
|
35
|
+
@stmt.prepare("BEGIN :time := TO_DATE(TO_CHAR(:year, '0999'), 'SYYYY'); END;")
|
36
|
+
year_in = @stmt.bindByName(":year", Fixnum)
|
37
|
+
time_out = @stmt.bindByName(":time", Time)
|
38
|
+
YEAR_CHECK_TARGET.each do |i|
|
39
|
+
# set time via oracle.
|
40
|
+
year_in.set(i)
|
41
|
+
@stmt.execute(@svc)
|
42
|
+
# check Time#year
|
43
|
+
assert_equal(i, time_out.get.year)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_set_mon
|
48
|
+
@stmt.prepare("BEGIN :mon := TO_NUMBER(TO_CHAR(:time, 'MM'), '99'); END;")
|
49
|
+
time_in = @stmt.bindByName(":time", Time)
|
50
|
+
mon_out = @stmt.bindByName(":mon", Fixnum)
|
51
|
+
MON_CHECK_TARGET.each do |i|
|
52
|
+
# set mon
|
53
|
+
time = Time.local(2001, i)
|
54
|
+
# check result via oracle.
|
55
|
+
time_in.set(time)
|
56
|
+
@stmt.execute(@svc)
|
57
|
+
assert_equal(i, mon_out.get())
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_get_mon
|
62
|
+
@stmt.prepare("BEGIN :time := TO_DATE(TO_CHAR(:mon, '99'), 'MM'); END;")
|
63
|
+
mon_in = @stmt.bindByName(":mon", Fixnum)
|
64
|
+
time_out = @stmt.bindByName(":time", Time)
|
65
|
+
MON_CHECK_TARGET.each do |i|
|
66
|
+
# set time via oracle.
|
67
|
+
mon_in.set(i)
|
68
|
+
@stmt.execute(@svc)
|
69
|
+
# check Time#mon
|
70
|
+
assert_equal(i, time_out.get.mon)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_set_day
|
75
|
+
@stmt.prepare("BEGIN :day := TO_NUMBER(TO_CHAR(:time, 'DD'), '99'); END;")
|
76
|
+
time_in = @stmt.bindByName(":time", Time)
|
77
|
+
day_out = @stmt.bindByName(":day", Fixnum)
|
78
|
+
DAY_CHECK_TARGET.each do |i|
|
79
|
+
# set day
|
80
|
+
time = Time.local(2001, 1, i)
|
81
|
+
# check result via oracle.
|
82
|
+
time_in.set(time)
|
83
|
+
@stmt.execute(@svc)
|
84
|
+
assert_equal(i, day_out.get())
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_get_day
|
89
|
+
@stmt.prepare("BEGIN :time := TO_DATE('200101' || TO_CHAR(:day, 'FM00'), 'YYYYMMDD'); END;")
|
90
|
+
day_in = @stmt.bindByName(":day", Fixnum)
|
91
|
+
time_out = @stmt.bindByName(":time", Time)
|
92
|
+
DAY_CHECK_TARGET.each do |i|
|
93
|
+
# set time via oracle.
|
94
|
+
day_in.set(i)
|
95
|
+
@stmt.execute(@svc)
|
96
|
+
# check Time#day
|
97
|
+
assert_equal(i, time_out.get.day)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_set_hour
|
102
|
+
@stmt.prepare("BEGIN :hour := TO_NUMBER(TO_CHAR(:time, 'HH24'), '99'); END;")
|
103
|
+
time_in = @stmt.bindByName(":time", Time)
|
104
|
+
hour_out = @stmt.bindByName(":hour", Fixnum)
|
105
|
+
HOUR_CHECK_TARGET.each do |i|
|
106
|
+
# set hour
|
107
|
+
time = Time.local(2001, 1, 1, i)
|
108
|
+
# check result via oracle.
|
109
|
+
time_in.set(time)
|
110
|
+
@stmt.execute(@svc)
|
111
|
+
assert_equal(i, hour_out.get())
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_get_hour
|
116
|
+
@stmt.prepare("BEGIN :time := TO_DATE(TO_CHAR(:hour, '99'), 'HH24'); END;")
|
117
|
+
hour_in = @stmt.bindByName(":hour", Fixnum)
|
118
|
+
time_out = @stmt.bindByName(":time", Time)
|
119
|
+
HOUR_CHECK_TARGET.each do |i|
|
120
|
+
# set time via oracle.
|
121
|
+
hour_in.set(i)
|
122
|
+
@stmt.execute(@svc)
|
123
|
+
# check Time#hour
|
124
|
+
assert_equal(i, time_out.get.hour)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_set_min
|
129
|
+
@stmt.prepare("BEGIN :min := TO_NUMBER(TO_CHAR(:time, 'MI'), '99'); END;")
|
130
|
+
time_in = @stmt.bindByName(":time", Time)
|
131
|
+
min_out = @stmt.bindByName(":min", Fixnum)
|
132
|
+
MIN_CHECK_TARGET.each do |i|
|
133
|
+
# set min
|
134
|
+
time = Time.local(2001, 1, 1, 0, i)
|
135
|
+
# check result via oracle.
|
136
|
+
time_in.set(time)
|
137
|
+
@stmt.execute(@svc)
|
138
|
+
assert_equal(i, min_out.get())
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_get_min
|
143
|
+
@stmt.prepare("BEGIN :time := TO_DATE(TO_CHAR(:min, '99'), 'MI'); END;")
|
144
|
+
min_in = @stmt.bindByName(":min", Fixnum)
|
145
|
+
time_out = @stmt.bindByName(":time", Time)
|
146
|
+
MIN_CHECK_TARGET.each do |i|
|
147
|
+
# set time via oracle.
|
148
|
+
min_in.set(i)
|
149
|
+
@stmt.execute(@svc)
|
150
|
+
# check Time#min
|
151
|
+
assert_equal(i, time_out.get.min)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_set_sec
|
156
|
+
@stmt.prepare("BEGIN :sec := TO_NUMBER(TO_CHAR(:time, 'SS'), '99'); END;")
|
157
|
+
time_in = @stmt.bindByName(":time", Time)
|
158
|
+
sec_out = @stmt.bindByName(":sec", Fixnum)
|
159
|
+
SEC_CHECK_TARGET.each do |i|
|
160
|
+
# set sec
|
161
|
+
time = Time.local(2001, 1, 1, 0, 0, i)
|
162
|
+
# check result via oracle.
|
163
|
+
time_in.set(time)
|
164
|
+
@stmt.execute(@svc)
|
165
|
+
assert_equal(i, sec_out.get())
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_get_sec
|
170
|
+
@stmt.prepare("BEGIN :time := TO_DATE(TO_CHAR(:sec, '99'), 'SS'); END;")
|
171
|
+
sec_in = @stmt.bindByName(":sec", Fixnum)
|
172
|
+
time_out = @stmt.bindByName(":time", Time)
|
173
|
+
SEC_CHECK_TARGET.each do |i|
|
174
|
+
# set time via oracle.
|
175
|
+
sec_in.set(i)
|
176
|
+
@stmt.execute(@svc)
|
177
|
+
# check Time#sec
|
178
|
+
assert_equal(i, time_out.get.sec)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def teardown
|
183
|
+
@stmt.free()
|
184
|
+
@svc.logoff()
|
185
|
+
@env.free()
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
if $0 == __FILE__
|
190
|
+
RUNIT::CUI::TestRunner.run(TestBindTime.suite())
|
191
|
+
end
|
data/test/test_break.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# High-level API
|
2
|
+
require 'oci8'
|
3
|
+
require 'runit/testcase'
|
4
|
+
require 'runit/cui/testrunner'
|
5
|
+
require File.dirname(__FILE__) + '/config'
|
6
|
+
|
7
|
+
class TestBreak < RUNIT::TestCase
|
8
|
+
|
9
|
+
def report(str)
|
10
|
+
printf "%d: %s\n", (Time.now - $start_time), str
|
11
|
+
end
|
12
|
+
|
13
|
+
PLSQL_DONE = 1
|
14
|
+
OCIBREAK = 2
|
15
|
+
SEND_BREAK = 3
|
16
|
+
|
17
|
+
TIME_IN_PLSQL = 3
|
18
|
+
TIME_TO_BREAK = 1
|
19
|
+
MARGIN = 0.1
|
20
|
+
|
21
|
+
def do_test_ocibreak(conn, expect)
|
22
|
+
$start_time = Time.now
|
23
|
+
|
24
|
+
th = Thread.start do
|
25
|
+
begin
|
26
|
+
conn.exec("BEGIN DBMS_LOCK.SLEEP(#{TIME_IN_PLSQL}); END;")
|
27
|
+
assert_equal(expect[PLSQL_DONE], (Time.now - $start_time + MARGIN).to_i)
|
28
|
+
rescue OCIBreak
|
29
|
+
assert_equal(expect[OCIBREAK], (Time.now - $start_time + MARGIN).to_i)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
sleep(TIME_TO_BREAK)
|
34
|
+
assert_equal(expect[SEND_BREAK], (Time.now - $start_time + MARGIN).to_i)
|
35
|
+
conn.break()
|
36
|
+
th.join
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_set_blocking_mode
|
40
|
+
conn = get_oci_connection()
|
41
|
+
conn.non_blocking = true
|
42
|
+
assert_equal(true, conn.non_blocking?)
|
43
|
+
conn.non_blocking = false
|
44
|
+
assert_equal(false, conn.non_blocking?)
|
45
|
+
conn.non_blocking = true
|
46
|
+
assert_equal(true, conn.non_blocking?)
|
47
|
+
conn.logoff()
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_blocking_mode
|
51
|
+
conn = get_oci_connection()
|
52
|
+
conn.non_blocking = false
|
53
|
+
expect = []
|
54
|
+
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
55
|
+
expect[OCIBREAK] = "Invalid status"
|
56
|
+
expect[SEND_BREAK] = TIME_IN_PLSQL + TIME_TO_BREAK
|
57
|
+
do_test_ocibreak(conn, expect)
|
58
|
+
conn.logoff()
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_non_blocking_mode
|
62
|
+
conn = get_oci_connection()
|
63
|
+
conn.non_blocking = true
|
64
|
+
expect = []
|
65
|
+
expect[PLSQL_DONE] = "Invalid status"
|
66
|
+
if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/
|
67
|
+
# raise after sleeping #{TIME_IN_PLSQL} seconds.
|
68
|
+
expect[OCIBREAK] = TIME_IN_PLSQL
|
69
|
+
else
|
70
|
+
# raise immediately by OCI8#break.
|
71
|
+
expect[OCIBREAK] = TIME_TO_BREAK
|
72
|
+
end
|
73
|
+
expect[SEND_BREAK] = TIME_TO_BREAK
|
74
|
+
do_test_ocibreak(conn, expect)
|
75
|
+
conn.logoff()
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
if $0 == __FILE__
|
80
|
+
RUNIT::CUI::TestRunner.run(TestBreak.suite())
|
81
|
+
end
|
data/test/test_clob.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Low-level API
|
2
|
+
require 'oci8'
|
3
|
+
require 'runit/testcase'
|
4
|
+
require 'runit/cui/testrunner'
|
5
|
+
require File.dirname(__FILE__) + '/config'
|
6
|
+
|
7
|
+
class TestCLob < RUNIT::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@env, @svc, @stmt = setup_lowapi()
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_insert
|
14
|
+
filename = File.basename($lobfile)
|
15
|
+
@stmt.prepare("DELETE FROM test_clob WHERE filename = :1")
|
16
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
17
|
+
@stmt.execute(@svc)
|
18
|
+
|
19
|
+
@stmt.prepare("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())")
|
20
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
21
|
+
@stmt.execute(@svc)
|
22
|
+
|
23
|
+
lob = @env.alloc(OCILobLocator)
|
24
|
+
@stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
|
25
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
26
|
+
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
27
|
+
@stmt.execute(@svc, 1)
|
28
|
+
offset = 1 # count by charactor, not byte.
|
29
|
+
open($lobfile) do |f|
|
30
|
+
while f.gets()
|
31
|
+
num_of_chars = lob.write(@svc, offset, $_)
|
32
|
+
offset += num_of_chars
|
33
|
+
end
|
34
|
+
end
|
35
|
+
lob.free()
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_insert_with_open_close
|
39
|
+
filename = File.basename($lobfile)
|
40
|
+
@stmt.prepare("DELETE FROM test_clob WHERE filename = :1")
|
41
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
42
|
+
@stmt.execute(@svc)
|
43
|
+
|
44
|
+
@stmt.prepare("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())")
|
45
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
46
|
+
@stmt.execute(@svc)
|
47
|
+
|
48
|
+
lob = @env.alloc(OCILobLocator)
|
49
|
+
@stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
|
50
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
51
|
+
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
52
|
+
@stmt.execute(@svc, 1)
|
53
|
+
lob.open(@svc)
|
54
|
+
begin
|
55
|
+
offset = 1 # count by charactor, not byte.
|
56
|
+
open($lobfile) do |f|
|
57
|
+
while f.gets()
|
58
|
+
offset += lob.write(@svc, offset, $_)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
ensure
|
62
|
+
lob.close(@svc)
|
63
|
+
end
|
64
|
+
lob.free()
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_read
|
68
|
+
filename = File.basename($lobfile)
|
69
|
+
test_insert() # first insert data.
|
70
|
+
lob = @env.alloc(OCILobLocator)
|
71
|
+
@stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
|
72
|
+
@stmt.bindByPos(1, String, filename.size).set(filename)
|
73
|
+
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
74
|
+
@stmt.execute(@svc, 1)
|
75
|
+
|
76
|
+
open($lobfile) do |f|
|
77
|
+
offset = 1
|
78
|
+
while buf = lob.read(@svc, offset, $lobreadnum)
|
79
|
+
fbuf = f.read(buf.size)
|
80
|
+
assert_equal(fbuf, buf)
|
81
|
+
offset += $lobreadnum
|
82
|
+
# offset += buf.size will not work fine,
|
83
|
+
# Though buf.size counts in byte,
|
84
|
+
# offset and $lobreadnum count in character.
|
85
|
+
end
|
86
|
+
assert_equal(nil, buf)
|
87
|
+
assert_equal(true, f.eof?)
|
88
|
+
end
|
89
|
+
lob.free()
|
90
|
+
end
|
91
|
+
|
92
|
+
def teardown
|
93
|
+
@stmt.free()
|
94
|
+
@svc.logoff()
|
95
|
+
@env.free()
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
if $0 == __FILE__
|
100
|
+
RUNIT::CUI::TestRunner.run(TestCLob.suite())
|
101
|
+
end
|