ruby-oci8 2.0.4-x86-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.
Files changed (52) hide show
  1. data/ChangeLog +1912 -0
  2. data/Makefile +96 -0
  3. data/NEWS +223 -0
  4. data/README +86 -0
  5. data/VERSION +1 -0
  6. data/dist-files +77 -0
  7. data/doc/api.en.html +527 -0
  8. data/doc/api.en.rd +554 -0
  9. data/doc/api.ja.html +525 -0
  10. data/doc/api.ja.rd +557 -0
  11. data/doc/manual.css +35 -0
  12. data/lib/.document +1 -0
  13. data/lib/dbd/OCI8.rb +591 -0
  14. data/lib/oci8.rb +82 -0
  15. data/lib/oci8.rb.in +82 -0
  16. data/lib/oci8/.document +5 -0
  17. data/lib/oci8/bindtype.rb +319 -0
  18. data/lib/oci8/compat.rb +113 -0
  19. data/lib/oci8/datetime.rb +619 -0
  20. data/lib/oci8/encoding-init.rb +40 -0
  21. data/lib/oci8/encoding.yml +537 -0
  22. data/lib/oci8/metadata.rb +2077 -0
  23. data/lib/oci8/object.rb +562 -0
  24. data/lib/oci8/oci8.rb +571 -0
  25. data/lib/oci8/oracle_version.rb +144 -0
  26. data/lib/oci8lib_18.so +0 -0
  27. data/lib/oci8lib_191.so +0 -0
  28. data/metaconfig +142 -0
  29. data/pre-distclean.rb +7 -0
  30. data/ruby-oci8.gemspec +63 -0
  31. data/setup.rb +1331 -0
  32. data/test/README +4 -0
  33. data/test/config.rb +109 -0
  34. data/test/test_all.rb +50 -0
  35. data/test/test_appinfo.rb +63 -0
  36. data/test/test_array_dml.rb +333 -0
  37. data/test/test_bind_raw.rb +46 -0
  38. data/test/test_bind_time.rb +178 -0
  39. data/test/test_break.rb +83 -0
  40. data/test/test_clob.rb +79 -0
  41. data/test/test_connstr.rb +81 -0
  42. data/test/test_datetime.rb +622 -0
  43. data/test/test_dbi.rb +366 -0
  44. data/test/test_dbi_clob.rb +53 -0
  45. data/test/test_encoding.rb +100 -0
  46. data/test/test_metadata.rb +257 -0
  47. data/test/test_oci8.rb +434 -0
  48. data/test/test_oracle_version.rb +70 -0
  49. data/test/test_oradate.rb +256 -0
  50. data/test/test_oranumber.rb +655 -0
  51. data/test/test_rowid.rb +33 -0
  52. metadata +108 -0
@@ -0,0 +1,257 @@
1
+ require 'oci8'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/config'
4
+
5
+ class TestMetadata < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @conn = get_oci8_connection
9
+ end
10
+
11
+ def teardown
12
+ @conn.logoff
13
+ end
14
+
15
+ def test_metadata
16
+ if $oracle_version < OCI8::ORAVER_8_1
17
+ begin
18
+ @conn.describe_table('tab').columns
19
+ rescue RuntimeError
20
+ assert_equal("This feature is unavailable on Oracle 8.0", $!.to_s)
21
+ end
22
+ return
23
+ end
24
+
25
+ # data_size factor for nchar charset_form.
26
+ cursor = @conn.exec("select N'1' from dual")
27
+ cfrm = cursor.column_metadata[0].data_size
28
+ if $oracle_version >= OCI8::ORAVER_9_0
29
+ # data_size factor for char semantics.
30
+ cursor = @conn.exec("select CAST('1' AS CHAR(1 char)) from dual")
31
+ csem = cursor.column_metadata[0].data_size
32
+ else
33
+ csem = 1
34
+ end
35
+
36
+ ora80 = OCI8::ORAVER_8_0
37
+ ora81 = OCI8::ORAVER_8_1
38
+ ora90 = OCI8::ORAVER_9_0
39
+ ora101 = OCI8::ORAVER_10_1
40
+ coldef =
41
+ [
42
+ # oracle_version, definition, data_type, csfrm, null?,csem?,csize, data_size,prec,scale,fsprec,lfprec
43
+ [ora80, "CHAR(10) NOT NULL", :char, :implicit, false, false, 10, 10, 0, 0, 0, 0],
44
+ [ora90, "CHAR(10 CHAR)", :char, :implicit, true, true, 10, 10 * csem, 0, 0, 0, 0],
45
+ [ora80, "NCHAR(10)", :char, :nchar, true, true, 10, 10 * cfrm, 0, 0, 0, 0],
46
+ [ora80, "VARCHAR2(10)", :varchar2, :implicit, true, false, 10, 10, 0, 0, 0, 0],
47
+ [ora90, "VARCHAR2(10 CHAR)", :varchar2, :implicit, true, true, 10, 10 * csem, 0, 0, 0, 0],
48
+ [ora80, "NVARCHAR2(10)", :varchar2, :nchar, true, true, 10, 10 * cfrm, 0, 0, 0, 0],
49
+ [ora80, "RAW(10)", :raw, nil, true, false, 0, 10, 0, 0, 0, 0],
50
+
51
+ # Don't check data_size of CLOB, NCLOB and BLOB.
52
+ #
53
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
54
+ # +----------+-----------+
55
+ # | | data_size |
56
+ # +----------+-----------+
57
+ # | implicit | 4000 | <= OCI8::Cursor#column_metadata
58
+ # | explicit | 86 | <= OCI8.describe_table('table_name').columns
59
+ # +----------+-----------+
60
+ [ora81, "CLOB", :clob, :implicit, true, false, 0, :nc, 0, 0, 0, 0],
61
+ [ora81, "NCLOB", :clob, :nchar, true, false, 0, :nc, 0, 0, 0, 0],
62
+ [ora80, "BLOB", :blob, nil, true, false, 0, :nc, 0, 0, 0, 0],
63
+
64
+ [ora80, "BFILE", :bfile, nil, true, false, 0, 530, 0, 0, 0, 0],
65
+
66
+ # Don't check fsprecision and lfprecision for NUMBER and FLOAT
67
+ #
68
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
69
+ # +---------------------------+-------------+-------------+
70
+ # | | fsprecision | lfprecision |
71
+ # +----------------+----------+-------------+-------------+
72
+ # | NUMBER | implicit | 129 | 0 |
73
+ # | | explicit | 0 | 129 |
74
+ # +----------------+----------+-------------+-------------+
75
+ # | NUMBER(10) | implicit | 0 | 10 |
76
+ # | | explicit | 10 | 0 |
77
+ # +----------------+----------+-------------+-------------+
78
+ # | NUMBER(10,2) | implicit | 2 | 10 |
79
+ # | | explicit | 10 | 2 |
80
+ # +----------------+----------+-------------+-------------+
81
+ # | FLOAT | implicit | 129 | 126 |
82
+ # | | explicit | 126 | 129 |
83
+ # +----------------+----------+-------------+-------------+
84
+ # | FLOAT(10) | implicit | 129 | 10 |
85
+ # | | explicit | 10 | 129 |
86
+ # +----------------+----------+-------------+-------------+
87
+ [ora80, "NUMBER", :number, nil, true, false, 0, 22, 0, $oracle_version >= ora90 ? -127 : 0, :nc, :nc],
88
+ [ora80, "NUMBER(10)", :number, nil, true, false, 0, 22, 10, 0, :nc, :nc],
89
+ [ora80, "NUMBER(10,2)", :number, nil, true, false, 0, 22, 10, 2, :nc, :nc],
90
+ [ora80, "FLOAT", :number, nil, true, false, 0, 22, 126, -127, :nc, :nc],
91
+ [ora80, "FLOAT(10)", :number, nil, true, false, 0, 22, 10, -127, :nc, :nc],
92
+
93
+ [ora101,"BINARY_FLOAT", :binary_float, nil, true, false, 0, 4, 0, 0, 0, 0],
94
+ [ora101,"BINARY_DOUBLE", :binary_double, nil, true, false, 0, 8, 0, 0, 0, 0],
95
+ [ora80, "DATE", :date, nil, true, false, 0, 7, 0, 0, 0, 0],
96
+
97
+ # Don't check precision and lfprecision for TIMESTAMP
98
+ #
99
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
100
+ # +----------------------------------------------+-----------+-------------+
101
+ # | | precision | lfprecision |
102
+ # +-----------------------------------+----------+-----------+-------------+
103
+ # | TIMESTAMP | implicit | 0 | 0 |
104
+ # | | explicit | 6 | 6 |
105
+ # +-----------------------------------+----------+-----------+-------------+
106
+ # | TIMESTAMP(9) | implicit | 0 | 0 |
107
+ # | | explicit | 9 | 9 |
108
+ # +-----------------------------------+----------+-----------+-------------+
109
+ # | TIMESTAMP WITH TIME ZONE | implicit | 0 | 0 |
110
+ # | | explicit | 6 | 6 |
111
+ # +-----------------------------------+----------+-----------+-------------+
112
+ # | TIMESTAMP(9) WITH TIME ZONE | implicit | 0 | 0 |
113
+ # | | explicit | 9 | 9 |
114
+ # +-----------------------------------+----------+-----------+-------------+
115
+ # | TIMESTAMP WITH LOCAL TIME ZONE | implicit | 0 | 0 |
116
+ # | | explicit | 6 | 6 |
117
+ # +-----------------------------------+----------+-----------+-------------+
118
+ # | TIMESTAMP(9) WITH LOCAL TIME ZONE | implicit | 0 | 0 |
119
+ # | | explicit | 9 | 9 |
120
+ # +-----------------------------------+----------+-----------+-------------+
121
+ [ora90, "TIMESTAMP", :timestamp, nil, true, false, 0, 11, :nc, 6, 6, :nc],
122
+ [ora90, "TIMESTAMP(9)", :timestamp, nil, true, false, 0, 11, :nc, 9, 9, :nc],
123
+ [ora90, "TIMESTAMP WITH TIME ZONE", :timestamp_tz, nil, true, false, 0, 13, :nc, 6, 6, :nc],
124
+ [ora90, "TIMESTAMP(9) WITH TIME ZONE", :timestamp_tz, nil, true, false, 0, 13, :nc, 9, 9, :nc],
125
+ [ora90, "TIMESTAMP WITH LOCAL TIME ZONE", :timestamp_ltz, nil, true, false, 0, 11, :nc, 6, 6, :nc],
126
+ [ora90, "TIMESTAMP(9) WITH LOCAL TIME ZONE", :timestamp_ltz, nil, true, false, 0, 11, :nc, 9, 9, :nc],
127
+
128
+ # Don't check scale and fsprecision for INTERVAL YEAR TO MONTH
129
+ #
130
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
131
+ # +-----------------------------------------+-----------+-------------+
132
+ # | | scale | fsprecision |
133
+ # +------------------------------+----------+-----------+-------------+
134
+ # | INTERVAL YEAR TO MONTH | implicit | 0 | 0 |
135
+ # | | explicit | 2 | 2 |
136
+ # +------------------------------+----------+-----------+-------------+
137
+ # | INTERVAL YEAR(4) TO MONTH | implicit | 0 | 0 |
138
+ # | | explicit | 4 | 4 |
139
+ # +------------------------------+----------+-----------+-------------+
140
+ [ora90, "INTERVAL YEAR TO MONTH", :interval_ym, nil, true, false, 0, 5, 2, :nc, :nc, 2],
141
+ [ora90, "INTERVAL YEAR(4) TO MONTH", :interval_ym, nil, true, false, 0, 5, 4, :nc, :nc, 4],
142
+
143
+ # Don't check precision and scale for INTERVAL DAY TO SECOND
144
+ #
145
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
146
+ # +-----------------------------------------+-----------+-----------+
147
+ # | | precision | scale |
148
+ # +------------------------------+----------+-----------+-----------+
149
+ # | INTERVAL DAY TO SECOND | implicit | 2 | 6 |
150
+ # | | explicit | 6 | 2 |
151
+ # +------------------------------+----------+-----------+-----------+
152
+ # | INTERVAL DAY(4) TO SECOND(9) | implicit | 4 | 9 |
153
+ # | | explicit | 9 | 4 |
154
+ # +------------------------------+----------+-----------+-----------+
155
+ [ora90, "INTERVAL DAY TO SECOND", :interval_ds, nil, true, false, 0, 11, :nc, :nc, 6, 2],
156
+ [ora90, "INTERVAL DAY(4) TO SECOND(9)",:interval_ds, nil, true, false, 0, 11, :nc, :nc, 9, 4],
157
+ ]
158
+
159
+ coldef.reject! do |c| c[0] > $oracle_version end
160
+
161
+ drop_table('test_table')
162
+ sql = <<-EOS
163
+ CREATE TABLE test_table (#{idx = 0; coldef.collect do |c| idx += 1; "C#{idx} " + c[1]; end.join(',')})
164
+ STORAGE (
165
+ INITIAL 100k
166
+ NEXT 100k
167
+ MINEXTENTS 1
168
+ MAXEXTENTS UNLIMITED
169
+ PCTINCREASE 0)
170
+ EOS
171
+ @conn.exec(sql)
172
+
173
+ @conn.describe_table('test_table').columns.each_with_index do |md, i|
174
+ # common
175
+ assert_equal("C#{i + 1}", md.name, "'#{coldef[i][1]}': name")
176
+ assert_equal(coldef[i][1], md.type_string, "'#{coldef[i][1]}': type_string")
177
+ assert_equal(coldef[i][2], md.data_type, "'#{coldef[i][1]}': data_type")
178
+ assert_equal(coldef[i][3], md.charset_form, "'#{coldef[i][1]}': charset_form")
179
+ assert_equal(coldef[i][4], md.nullable?, "'#{coldef[i][1]}': nullable? ")
180
+ # string type
181
+ if $oracle_version >= OCI8::ORAVER_9_0
182
+ assert_equal(coldef[i][5], md.char_used?, "'#{coldef[i][1]}': char_used? ")
183
+ assert_equal(coldef[i][6], md.char_size, "'#{coldef[i][1]}': char_size")
184
+ end
185
+ assert_equal(coldef[i][7], md.data_size, "'#{coldef[i][1]}': data_size") if coldef[i][7] != :nc
186
+ # number, timestamp and interval type
187
+ assert_equal(coldef[i][8], md.precision, "'#{coldef[i][1]}': precision") if coldef[i][8] != :nc
188
+ assert_equal(coldef[i][9], md.scale, "'#{coldef[i][1]}': scale") if coldef[i][9] != :nc
189
+ if $oracle_version >= OCI8::ORAVER_9_0
190
+ assert_equal(coldef[i][10], md.fsprecision, "'#{coldef[i][1]}': fsprecision") if coldef[i][10] != :nc
191
+ assert_equal(coldef[i][11], md.lfprecision, "'#{coldef[i][1]}': lfprecision") if coldef[i][11] != :nc
192
+ end
193
+ end
194
+
195
+ # temporarily change OCI8::BindType::Mapping.
196
+ saved_mapping = {}
197
+ [OCI8::SQLT_TIMESTAMP_TZ,
198
+ OCI8::SQLT_TIMESTAMP_LTZ,
199
+ OCI8::SQLT_INTERVAL_YM,
200
+ OCI8::SQLT_INTERVAL_DS].each do |sqlt_type|
201
+ saved_mapping[sqlt_type] = OCI8::BindType::Mapping[sqlt_type]
202
+ OCI8::BindType::Mapping[sqlt_type] = OCI8::BindType::String
203
+ end
204
+ begin
205
+ cursor = @conn.exec("SELECT * FROM test_table")
206
+ ensure
207
+ saved_mapping.each do |key, val|
208
+ OCI8::BindType::Mapping[key] = val
209
+ end
210
+ end
211
+ cursor.column_metadata.each_with_index do |md, i|
212
+ # common
213
+ assert_equal("C#{i + 1}", md.name, "'#{coldef[i][1]}': name")
214
+ assert_equal(coldef[i][1], md.type_string, "'#{coldef[i][1]}': type_string")
215
+ assert_equal(coldef[i][2], md.data_type, "'#{coldef[i][1]}': data_type")
216
+ assert_equal(coldef[i][3], md.charset_form, "'#{coldef[i][1]}': charset_form")
217
+ assert_equal(coldef[i][4], md.nullable?, "'#{coldef[i][1]}': nullable? ")
218
+ # string type
219
+ if $oracle_version >= OCI8::ORAVER_9_0
220
+ assert_equal(coldef[i][5], md.char_used?, "'#{coldef[i][1]}': char_used? ")
221
+ assert_equal(coldef[i][6], md.char_size, "'#{coldef[i][1]}': char_size")
222
+ end
223
+ assert_equal(coldef[i][7], md.data_size, "'#{coldef[i][1]}': data_size") if coldef[i][7] != :nc
224
+ # number, timestamp and interval type
225
+ assert_equal(coldef[i][8], md.precision, "'#{coldef[i][1]}': precision") if coldef[i][8] != :nc
226
+ assert_equal(coldef[i][9], md.scale, "'#{coldef[i][1]}': scale") if coldef[i][9] != :nc
227
+ if $oracle_version >= OCI8::ORAVER_9_0
228
+ assert_equal(coldef[i][10], md.fsprecision, "'#{coldef[i][1]}': fsprecision") if coldef[i][10] != :nc
229
+ assert_equal(coldef[i][11], md.lfprecision, "'#{coldef[i][1]}': lfprecision") if coldef[i][11] != :nc
230
+ end
231
+ end
232
+
233
+ drop_table('test_table')
234
+ end
235
+
236
+ def test_error_describe_table
237
+ drop_table('test_table')
238
+ begin
239
+ @conn.describe_table('test_table')
240
+ flunk("expects ORA-4043 but no error")
241
+ rescue OCIError
242
+ flunk("expects ORA-4043 but ORA-#{$!.code}") if $!.code != 4043
243
+ end
244
+ @conn.exec('create sequence test_table')
245
+ begin
246
+ begin
247
+ @conn.describe_table('test_table')
248
+ flunk('expects ORA-4043 but no error')
249
+ rescue OCIError
250
+ flunk("expects ORA-4043 but ORA-#{$!.code}") if $!.code != 4043
251
+ end
252
+ ensure
253
+ @conn.exec('drop sequence test_table')
254
+ end
255
+ end
256
+
257
+ end # TestMetadata
@@ -0,0 +1,434 @@
1
+ require 'oci8'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/config'
4
+ require 'bigdecimal'
5
+ require 'rational'
6
+
7
+ class TestOCI8 < 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 test_rename
18
+ drop_table('test_table')
19
+ drop_table('test_rename_table')
20
+ sql = <<-EOS
21
+ CREATE TABLE test_rename_table
22
+ (C CHAR(10) NOT NULL)
23
+ EOS
24
+ @conn.exec(sql)
25
+ @conn.exec("RENAME test_rename_table TO test_table")
26
+ drop_table('test_rename_table')
27
+ end
28
+
29
+ # USE_DYNAMIC_FETCH doesn't work well...
30
+ # This test is disabled.
31
+ def _test_long_type
32
+ drop_table('test_table')
33
+ @conn.exec('CREATE TABLE test_table (id number(38), lng long)')
34
+ test_data1 = 'a' * 70000
35
+ test_data2 = 'b' * 3000
36
+ test_data3 = nil
37
+ test_data4 = 'c' * 70000
38
+ @conn.exec('insert into test_table values (:1, :2)', 1, test_data1)
39
+ @conn.exec('insert into test_table values (:1, :2)', 2, [test_data2, :long])
40
+ @conn.exec('insert into test_table values (:1, :2)', 3, [nil, :long])
41
+ @conn.exec('insert into test_table values (:1, :2)', 4, [test_data4, :long])
42
+
43
+ [8000, 65535, 65536, 80000].each do |read_len|
44
+ @conn.long_read_len = read_len
45
+ cursor = @conn.parse('SELECT lng from test_table order by id')
46
+ cursor.exec
47
+ assert_equal(test_data1, cursor.fetch[0])
48
+ assert_equal(test_data2, cursor.fetch[0])
49
+ assert_equal(test_data3, cursor.fetch[0])
50
+ assert_equal(test_data4, cursor.fetch[0])
51
+ cursor.close
52
+ end
53
+ drop_table('test_table')
54
+ end
55
+
56
+ def test_long_type
57
+ @conn.long_read_len = 80000
58
+ drop_table('test_table')
59
+ @conn.exec('CREATE TABLE test_table (id number(38), lng long)')
60
+ test_data1 = 'a' * 70000
61
+ test_data2 = 'b' * 3000
62
+ test_data3 = nil
63
+ test_data4 = 'c' * 70000
64
+ @conn.exec('insert into test_table values (:1, :2)', 1, test_data1)
65
+ @conn.exec('insert into test_table values (:1, :2)', 2, [test_data2, :long])
66
+ @conn.exec('insert into test_table values (:1, :2)', 3, [nil, :long])
67
+ @conn.exec('insert into test_table values (:1, :2)', 4, [test_data4, :long])
68
+
69
+ cursor = @conn.parse('SELECT lng from test_table order by id')
70
+ cursor.exec
71
+ assert_equal(test_data1, cursor.fetch[0])
72
+ assert_equal(test_data2, cursor.fetch[0])
73
+ assert_equal(test_data3, cursor.fetch[0])
74
+ assert_equal(test_data4, cursor.fetch[0])
75
+ cursor.close
76
+ drop_table('test_table')
77
+ end
78
+
79
+ def test_select
80
+ drop_table('test_table')
81
+ sql = <<-EOS
82
+ CREATE TABLE test_table
83
+ (C CHAR(10) NOT NULL,
84
+ V VARCHAR2(20),
85
+ N NUMBER(10, 2),
86
+ D1 DATE, D2 DATE, D3 DATE, D4 DATE,
87
+ INT NUMBER(30), BIGNUM NUMBER(30))
88
+ STORAGE (
89
+ INITIAL 4k
90
+ NEXT 4k
91
+ MINEXTENTS 1
92
+ MAXEXTENTS UNLIMITED
93
+ PCTINCREASE 0)
94
+ EOS
95
+ @conn.exec(sql)
96
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D1, :D2, :D3, :D4, :INT, :BIGNUM)")
97
+ 1.upto(10) do |i|
98
+ if i == 1
99
+ dt = [nil, OraDate]
100
+ else
101
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
102
+ end
103
+ cursor.exec(format("%10d", i * 10), i.to_s, i, dt, dt, dt, dt, i * 11111111111, i * 10000000000)
104
+ end
105
+ cursor.close
106
+ cursor = @conn.parse("SELECT * FROM test_table ORDER BY c")
107
+ cursor.define(5, Time) # define 5th column as Time
108
+ cursor.define(6, Date) # define 6th column as Date
109
+ cursor.define(7, DateTime) # define 7th column as DateTime
110
+ cursor.define(8, Integer) # define 8th column as Integer
111
+ cursor.define(9, Bignum) # define 9th column as Bignum
112
+ cursor.exec
113
+ assert_equal(["C", "V", "N", "D1", "D2", "D3", "D4", "INT", "BIGNUM"], cursor.get_col_names)
114
+ 1.upto(10) do |i|
115
+ rv = cursor.fetch
116
+ assert_equal(format("%10d", i * 10), rv[0])
117
+ assert_equal(i.to_s, rv[1])
118
+ assert_equal(i, rv[2])
119
+ if i == 1
120
+ assert_nil(rv[3])
121
+ assert_nil(rv[4])
122
+ assert_nil(rv[5])
123
+ assert_nil(rv[6])
124
+ else
125
+ tm = Time.local(2000 + i, 8, 3, 23, 59, 59)
126
+ dt = Date.civil(2000 + i, 8, 3)
127
+ dttm = DateTime.civil(2000 + i, 8, 3, 23, 59, 59, Time.now.utc_offset.to_r/86400)
128
+ assert_equal(tm, rv[3])
129
+ assert_equal(tm, rv[4])
130
+ assert_equal(dt, rv[5])
131
+ assert_equal(dttm, rv[6])
132
+ end
133
+ assert_equal(i * 11111111111, rv[7])
134
+ assert_equal(i * 10000000000, rv[8])
135
+ end
136
+ assert_nil(cursor.fetch)
137
+
138
+ # fetch_hash with block
139
+ cursor.exec
140
+ i = 1
141
+ cursor.fetch_hash do |row|
142
+ assert_equal(format("%10d", i * 10), row['C'])
143
+ assert_equal(i.to_s, row['V'])
144
+ assert_equal(i, row['N'])
145
+ if i == 1
146
+ assert_nil(row['D1'])
147
+ assert_nil(row['D2'])
148
+ assert_nil(row['D3'])
149
+ assert_nil(row['D4'])
150
+ else
151
+ tm = Time.local(2000 + i, 8, 3, 23, 59, 59)
152
+ dt = Date.civil(2000 + i, 8, 3)
153
+ dttm = DateTime.civil(2000 + i, 8, 3, 23, 59, 59, Time.now.utc_offset.to_r/86400)
154
+ assert_equal(tm, row['D1'])
155
+ assert_equal(tm, row['D2'])
156
+ assert_equal(dt, row['D3'])
157
+ assert_equal(dttm, row['D4'])
158
+ end
159
+ assert_equal(i * 11111111111, row['INT'])
160
+ assert_equal(i * 10000000000, row['BIGNUM'])
161
+ i += 1
162
+ end
163
+ assert_equal(11, i)
164
+
165
+ cursor.close
166
+ drop_table('test_table')
167
+ end
168
+
169
+ def test_bind_cursor
170
+ # FIXME: check again after upgrading Oracle 9.2 to 9.2.0.4.
171
+ return if $oracle_version < OCI8::ORAVER_10_1
172
+
173
+ drop_table('test_table')
174
+ sql = <<-EOS
175
+ CREATE TABLE test_table
176
+ (C CHAR(10) NOT NULL,
177
+ V VARCHAR2(20),
178
+ N NUMBER(10, 2),
179
+ D1 DATE, D2 DATE, D3 DATE,
180
+ INT NUMBER(30), BIGNUM NUMBER(30))
181
+ STORAGE (
182
+ INITIAL 4k
183
+ NEXT 4k
184
+ MINEXTENTS 1
185
+ MAXEXTENTS UNLIMITED
186
+ PCTINCREASE 0)
187
+ EOS
188
+ @conn.exec(sql)
189
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D1, :D2, :D3, :INT, :BIGNUM)")
190
+ 1.upto(10) do |i|
191
+ if i == 1
192
+ dt = [nil, OraDate]
193
+ else
194
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
195
+ end
196
+ cursor.exec(format("%10d", i * 10), i.to_s, i, dt, dt, dt, i, i)
197
+ end
198
+ cursor.close
199
+ plsql = @conn.parse("BEGIN OPEN :cursor FOR SELECT * FROM test_table ORDER BY c; END;")
200
+ plsql.bind_param(':cursor', nil, OCI8::Cursor)
201
+ plsql.exec
202
+ cursor = plsql[':cursor']
203
+ cursor.define(5, Time) # define 5th column as Time
204
+ cursor.define(6, Date) # define 6th column as Date
205
+ cursor.define(7, Integer) # define 7th column as Integer
206
+ cursor.define(8, Bignum) # define 8th column as Integer
207
+ assert_equal(["C", "V", "N", "D1", "D2", "D3", "INT", "BIGNUM"], cursor.get_col_names)
208
+ 1.upto(10) do |i|
209
+ rv = cursor.fetch
210
+ assert_equal(format("%10d", i * 10), rv[0])
211
+ assert_equal(i.to_s, rv[1])
212
+ assert_equal(i, rv[2])
213
+ if i == 1
214
+ assert_nil(rv[3])
215
+ assert_nil(rv[4])
216
+ assert_nil(rv[5])
217
+ else
218
+ dttm = DateTime.civil(2000 + i, 8, 3, 23, 59, 59, Time.now.utc_offset.to_r/86400)
219
+ tm = Time.local(2000 + i, 8, 3, 23, 59, 59)
220
+ dt = Date.civil(2000 + i, 8, 3)
221
+ assert_equal(tm, rv[3])
222
+ assert_equal(tm, rv[4])
223
+ assert_equal(dt, rv[5])
224
+ end
225
+ assert_equal(i, rv[6])
226
+ assert_equal(i, rv[7])
227
+ end
228
+ assert_nil(cursor.fetch)
229
+ cursor.close
230
+ drop_table('test_table')
231
+ end
232
+
233
+ def test_cursor_in_result_set
234
+ drop_table('test_table')
235
+ sql = <<-EOS
236
+ CREATE TABLE test_table (N NUMBER(10, 2))
237
+ STORAGE (
238
+ INITIAL 4k
239
+ NEXT 4k
240
+ MINEXTENTS 1
241
+ MAXEXTENTS UNLIMITED
242
+ PCTINCREASE 0)
243
+ EOS
244
+ @conn.exec(sql)
245
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:1)")
246
+ 1.upto(10) do |i|
247
+ cursor.exec(i)
248
+ end
249
+ cursor.close
250
+ cursor = @conn.exec(<<EOS)
251
+ select a.n, cursor (select a.n + b.n
252
+ from test_table b
253
+ order by n)
254
+ from test_table a
255
+ order by n
256
+ EOS
257
+ 1.upto(10) do |i|
258
+ row = cursor.fetch
259
+ assert_equal(i, row[0])
260
+ cursor_in_result_set = row[1]
261
+ 1.upto(10) do |j|
262
+ row2 = cursor_in_result_set.fetch
263
+ assert_equal(i + j, row2[0])
264
+ end
265
+ assert_nil(cursor_in_result_set.fetch) # check end of row data
266
+ cursor_in_result_set.close
267
+ end
268
+ assert_nil(cursor.fetch) # check end of row data
269
+ drop_table('test_table')
270
+ end
271
+
272
+ def test_binary_float
273
+ return if $oracle_version < OCI8::ORAVER_10_1
274
+
275
+ # Oracle 10g or upper
276
+ cursor = @conn.parse("select CAST(:1 AS BINARY_FLOAT), CAST(:2 AS BINARY_DOUBLE) from dual")
277
+ bind_val = -1.0
278
+ cursor.bind_param(1, 10.0, :binary_double)
279
+ cursor.bind_param(2, nil, :binary_double)
280
+ while bind_val < 10.0
281
+ cursor[2] = bind_val
282
+ cursor.exec
283
+ rv = cursor.fetch
284
+ assert_equal(10.0, rv[0])
285
+ assert_equal(bind_val, rv[1])
286
+ bind_val += 1.234
287
+ end
288
+ [-1.0/0.0, # -Infinite
289
+ +1.0/0.0, # +Infinite
290
+ 0.0/0.0 # NaN
291
+ ].each do |num|
292
+ cursor[1] = num
293
+ cursor[2] = num
294
+ cursor.exec
295
+ rv = cursor.fetch
296
+ if num.nan?
297
+ assert(rv[0].nan?)
298
+ assert(rv[1].nan?)
299
+ else
300
+ assert_equal(num, rv[0])
301
+ assert_equal(num, rv[1])
302
+ end
303
+ end
304
+ cursor.close
305
+ end
306
+
307
+ def test_clob_nclob_and_blob
308
+ return if OCI8::oracle_client_version < OCI8::ORAVER_8_1
309
+
310
+ drop_table('test_table')
311
+ sql = <<-EOS
312
+ CREATE TABLE test_table (id number(5), C CLOB, NC NCLOB, B BLOB)
313
+ STORAGE (
314
+ INITIAL 100k
315
+ NEXT 100k
316
+ MINEXTENTS 1
317
+ MAXEXTENTS UNLIMITED
318
+ PCTINCREASE 0)
319
+ EOS
320
+ @conn.exec(sql)
321
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:1, :2, :3, :4)")
322
+ 0.upto(9) do |i|
323
+ val = format('%d', i) * 4096
324
+ cursor.exec(i, OCI8::CLOB.new(@conn, val), OCI8::NCLOB.new(@conn, val), OCI8::BLOB.new(@conn, val))
325
+ end
326
+ cursor.close
327
+ cursor = @conn.exec("select * from test_table order by id")
328
+ 0.upto(9) do |i|
329
+ rv = cursor.fetch
330
+ val = format('%d', i) * 4096
331
+ assert_equal(i, rv[0])
332
+ assert_instance_of(OCI8::CLOB, rv[1])
333
+ assert_instance_of(OCI8::NCLOB, rv[2])
334
+ assert_instance_of(OCI8::BLOB, rv[3])
335
+ assert_equal(val, rv[1].read)
336
+ assert_equal(val.length, rv[2].size)
337
+ assert_equal(val, rv[2].read)
338
+ assert_equal(val, rv[3].read)
339
+ end
340
+ assert_nil(cursor.fetch)
341
+ cursor.close
342
+ drop_table('test_table')
343
+ end
344
+
345
+ def test_select_number
346
+ drop_table('test_table')
347
+ @conn.exec(<<EOS)
348
+ CREATE TABLE test_table (n NUMBER, n20 NUMBER(20), n14_2 NUMBER(14,2), n15_2 NUMBER(15,2), flt FLOAT)
349
+ STORAGE (
350
+ INITIAL 100k
351
+ NEXT 100k
352
+ MINEXTENTS 1
353
+ MAXEXTENTS UNLIMITED
354
+ PCTINCREASE 0)
355
+ EOS
356
+ @conn.exec(<<EOS)
357
+ INSERT INTO test_table values(12345678901234, 12345678901234567890, 123456789012.34, 1234567890123.45, 1234.5)
358
+ EOS
359
+ @conn.exec("select * from test_table") do |row|
360
+ assert_equal(row[0], 12345678901234)
361
+ assert_equal(row[1], 12345678901234567890)
362
+ assert_equal(row[2], 123456789012.34)
363
+ assert_equal(row[3], BigDecimal("1234567890123.45"))
364
+ assert_equal(row[4], 1234.5)
365
+ assert_instance_of(BigDecimal, row[0])
366
+ assert_instance_of(Bignum, row[1])
367
+ assert_instance_of(Float, row[2])
368
+ assert_instance_of(BigDecimal, row[3])
369
+ assert_instance_of(Float, row[4])
370
+ end
371
+ drop_table('test_table')
372
+ end
373
+
374
+ def test_bind_number_with_implicit_conversions
375
+ src = [1, 1.2, BigDecimal("1.2"), Rational(12, 10)]
376
+ int = [1, 1, 1, 1]
377
+ flt = [1, 1.2, 1.2, 1.2]
378
+ dec = [BigDecimal("1"), BigDecimal("1.2"), BigDecimal("1.2"), BigDecimal("1.2")]
379
+ rat = [Rational(1), Rational(12, 10), Rational(12, 10), Rational(12, 10)]
380
+
381
+ cursor = @conn.parse("begin :1 := :2; end;")
382
+
383
+ # Float
384
+ cursor.bind_param(1, nil, Float)
385
+ cursor.bind_param(2, nil, Float)
386
+ src.each_with_index do |s, idx|
387
+ cursor[2] = s
388
+ cursor.exec
389
+ assert_equal(cursor[1], flt[idx])
390
+ assert_kind_of(Float, cursor[1])
391
+ end
392
+
393
+ # Fixnum
394
+ cursor.bind_param(1, nil, Fixnum)
395
+ cursor.bind_param(2, nil, Fixnum)
396
+ src.each_with_index do |s, idx|
397
+ cursor[2] = s
398
+ cursor.exec
399
+ assert_equal(cursor[1], int[idx])
400
+ assert_kind_of(Fixnum, cursor[1])
401
+ end
402
+
403
+ # Integer
404
+ cursor.bind_param(1, nil, Integer)
405
+ cursor.bind_param(2, nil, Integer)
406
+ src.each_with_index do |s, idx|
407
+ cursor[2] = s
408
+ cursor.exec
409
+ assert_equal(cursor[1], int[idx])
410
+ assert_kind_of(Integer, cursor[1])
411
+ end
412
+
413
+ # BigDecimal
414
+ cursor.bind_param(1, nil, BigDecimal)
415
+ cursor.bind_param(2, nil, BigDecimal)
416
+ src.each_with_index do |s, idx|
417
+ cursor[2] = s
418
+ cursor.exec
419
+ assert_equal(cursor[1], dec[idx])
420
+ assert_kind_of(BigDecimal, cursor[1])
421
+ end
422
+
423
+ # Rational
424
+ cursor.bind_param(1, nil, Rational)
425
+ cursor.bind_param(2, nil, Rational)
426
+ src.each_with_index do |s, idx|
427
+ cursor[2] = s
428
+ cursor.exec
429
+ assert_equal(cursor[1], rat[idx])
430
+ assert_kind_of(Rational, cursor[1])
431
+ end
432
+ end
433
+
434
+ end # TestOCI8