ruby-oci8 2.0.4-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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