ruby-oci8 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/ChangeLog +569 -0
  2. data/Makefile +51 -0
  3. data/NEWS +322 -0
  4. data/README +415 -0
  5. data/VERSION +1 -0
  6. data/dist-files +70 -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/ext/oci8/MANIFEST +22 -0
  13. data/ext/oci8/attr.c +415 -0
  14. data/ext/oci8/bind.c +194 -0
  15. data/ext/oci8/const.c +165 -0
  16. data/ext/oci8/define.c +53 -0
  17. data/ext/oci8/describe.c +81 -0
  18. data/ext/oci8/descriptor.c +39 -0
  19. data/ext/oci8/env.c +276 -0
  20. data/ext/oci8/error.c +234 -0
  21. data/ext/oci8/extconf.rb +118 -0
  22. data/ext/oci8/handle.c +262 -0
  23. data/ext/oci8/lob.c +386 -0
  24. data/ext/oci8/oci8.c +137 -0
  25. data/ext/oci8/oci8.h +345 -0
  26. data/ext/oci8/ocinumber.c +117 -0
  27. data/ext/oci8/oraconf.rb +1026 -0
  28. data/ext/oci8/oradate.c +426 -0
  29. data/ext/oci8/oranumber.c +445 -0
  30. data/ext/oci8/param.c +37 -0
  31. data/ext/oci8/post-config.rb +5 -0
  32. data/ext/oci8/server.c +182 -0
  33. data/ext/oci8/session.c +99 -0
  34. data/ext/oci8/stmt.c +624 -0
  35. data/ext/oci8/svcctx.c +229 -0
  36. data/lib/DBD/OCI8/OCI8.rb +549 -0
  37. data/lib/oci8.rb.in +1605 -0
  38. data/metaconfig +142 -0
  39. data/pre-distclean.rb +7 -0
  40. data/ruby-oci8.gemspec +54 -0
  41. data/ruby-oci8.spec +62 -0
  42. data/setup.rb +1331 -0
  43. data/support/README +4 -0
  44. data/support/runit/assert.rb +281 -0
  45. data/support/runit/cui/testrunner.rb +101 -0
  46. data/support/runit/error.rb +4 -0
  47. data/support/runit/method_mappable.rb +20 -0
  48. data/support/runit/robserver.rb +25 -0
  49. data/support/runit/setuppable.rb +15 -0
  50. data/support/runit/teardownable.rb +16 -0
  51. data/support/runit/testcase.rb +113 -0
  52. data/support/runit/testfailure.rb +25 -0
  53. data/support/runit/testresult.rb +121 -0
  54. data/support/runit/testsuite.rb +43 -0
  55. data/support/runit/version.rb +3 -0
  56. data/test/README +4 -0
  57. data/test/config.rb +129 -0
  58. data/test/test_all.rb +43 -0
  59. data/test/test_bind_raw.rb +53 -0
  60. data/test/test_bind_time.rb +191 -0
  61. data/test/test_break.rb +81 -0
  62. data/test/test_clob.rb +101 -0
  63. data/test/test_connstr.rb +80 -0
  64. data/test/test_dbi.rb +317 -0
  65. data/test/test_dbi_clob.rb +56 -0
  66. data/test/test_describe.rb +137 -0
  67. data/test/test_metadata.rb +243 -0
  68. data/test/test_oci8.rb +273 -0
  69. data/test/test_oradate.rb +263 -0
  70. data/test/test_oranumber.rb +149 -0
  71. metadata +118 -0
@@ -0,0 +1,137 @@
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 TestDescribe < RUNIT::TestCase
8
+
9
+ def setup
10
+ # initialize oracle as object mode.
11
+ # This is workaround to use OCIDescribeAny in Oracle 8.0.5 on Linux.
12
+ # This bug was fixed in 8.0.6 and 8i.
13
+ @env, @svc, @stmt = setup_lowapi()
14
+ @desc = @env.alloc(OCIDescribe)
15
+ end
16
+
17
+ def test_describe_sequence
18
+ begin
19
+ @stmt.prepare("DROP SEQUENCE test_sequence").execute(@svc)
20
+ rescue OCIError
21
+ raise if $!.code != 2289 # sequence does not exist
22
+ end
23
+ minvalue = 1
24
+ maxvalue = 1234567890123456789012345678 # bignum
25
+ incr = 777
26
+ sql = <<-EOS
27
+ CREATE SEQUENCE test_sequence
28
+ MINVALUE #{minvalue}
29
+ MAXVALUE #{maxvalue}
30
+ INCREMENT BY #{incr}
31
+ ORDER
32
+ EOS
33
+ @stmt.prepare(sql).execute(@svc)
34
+ @desc.describeAny(@svc, "test_sequence", OCI_PTYPE_SEQ)
35
+ parm = @desc.attrGet(OCI_ATTR_PARAM)
36
+ # common part
37
+ assert_equal(OCI_PTYPE_SEQ, parm.attrGet(OCI_ATTR_PTYPE))
38
+ # specific part
39
+ assert_instance_of(Fixnum, parm.attrGet(OCI_ATTR_OBJID))
40
+ assert_equal(minvalue, parm.attrGet(OCI_ATTR_MIN))
41
+ assert_equal(maxvalue, parm.attrGet(OCI_ATTR_MAX))
42
+ assert_equal(incr, parm.attrGet(OCI_ATTR_INCR))
43
+ assert_kind_of(Integer, parm.attrGet(OCI_ATTR_CACHE))
44
+ assert_equal(true, parm.attrGet(OCI_ATTR_ORDER))
45
+ assert_kind_of(Integer, parm.attrGet(OCI_ATTR_HW_MARK))
46
+ @stmt.prepare("DROP SEQUENCE test_sequence").execute(@svc)
47
+ end
48
+
49
+ def test_describe_synonym
50
+ begin
51
+ @stmt.prepare("DROP SYNONYM test_synonym").execute(@svc)
52
+ rescue OCIError
53
+ raise if $!.code != 1434 # private synonym to be dropped does not exist
54
+ end
55
+ @stmt.prepare("CREATE SYNONYM test_synonym FOR foo.bar@baz").execute(@svc)
56
+ @desc.describeAny(@svc, "test_synonym", OCI_PTYPE_SYN)
57
+ parm = @desc.attrGet(OCI_ATTR_PARAM)
58
+ # common part
59
+ assert_equal(OCI_PTYPE_SYN, parm.attrGet(OCI_ATTR_PTYPE))
60
+ # specific part
61
+ assert_instance_of(Fixnum, parm.attrGet(OCI_ATTR_OBJID))
62
+ assert_equal("FOO", parm.attrGet(OCI_ATTR_SCHEMA_NAME))
63
+ assert_equal("BAR", parm.attrGet(OCI_ATTR_NAME))
64
+ assert_equal("BAZ", parm.attrGet(OCI_ATTR_LINK))
65
+ @stmt.prepare("DROP SYNONYM test_synonym").execute(@svc)
66
+ end
67
+
68
+ def test_describe_table_and_columns
69
+ drop_table('test_table')
70
+ sql = <<-EOS
71
+ CREATE TABLE test_table
72
+ (C CHAR(10) NOT NULL,
73
+ V VARCHAR2(20),
74
+ N NUMBER(10, 2),
75
+ D DATE)
76
+ STORAGE (
77
+ INITIAL 4k
78
+ NEXT 4k
79
+ MINEXTENTS 1
80
+ MAXEXTENTS UNLIMITED
81
+ PCTINCREASE 0)
82
+ EOS
83
+ @stmt.prepare(sql).execute(@svc)
84
+ @desc.describeAny(@svc, "test_table", OCI_PTYPE_TABLE)
85
+ tab_parm = @desc.attrGet(OCI_ATTR_PARAM)
86
+ col_list = tab_parm.attrGet(OCI_ATTR_LIST_COLUMNS)
87
+ num_cols = tab_parm.attrGet(OCI_ATTR_NUM_COLS)
88
+ # common part for table
89
+ assert_equal(OCI_PTYPE_TABLE, tab_parm.attrGet(OCI_ATTR_PTYPE))
90
+ # specific part for table
91
+ assert_instance_of(Fixnum, tab_parm.attrGet(OCI_ATTR_OBJID))
92
+ assert_equal(4, num_cols)
93
+ # common part for column list
94
+ assert_equal(OCI_PTYPE_LIST, col_list.attrGet(OCI_ATTR_PTYPE))
95
+
96
+ col = Array.new(num_cols)
97
+ 1.upto(num_cols) do |i|
98
+ col[i] = col_list.paramGet(i)
99
+ assert_equal(OCI_PTYPE_COL, col[1].attrGet(OCI_ATTR_PTYPE))
100
+ end
101
+ assert_equal(10, col[1].attrGet(OCI_ATTR_DATA_SIZE))
102
+ assert_equal(20, col[2].attrGet(OCI_ATTR_DATA_SIZE))
103
+ assert_equal(22, col[3].attrGet(OCI_ATTR_DATA_SIZE))
104
+ assert_equal(7, col[4].attrGet(OCI_ATTR_DATA_SIZE))
105
+ assert_equal(OCI_TYPECODE_CHAR, col[1].attrGet(OCI_ATTR_DATA_TYPE))
106
+ assert_equal(OCI_TYPECODE_VARCHAR, col[2].attrGet(OCI_ATTR_DATA_TYPE))
107
+ assert_equal(OCI_TYPECODE_NUMBER, col[3].attrGet(OCI_ATTR_DATA_TYPE))
108
+ assert_equal(OCI_TYPECODE_DATE, col[4].attrGet(OCI_ATTR_DATA_TYPE))
109
+ assert_equal("C", col[1].attrGet(OCI_ATTR_NAME))
110
+ assert_equal("V", col[2].attrGet(OCI_ATTR_NAME))
111
+ assert_equal("N", col[3].attrGet(OCI_ATTR_NAME))
112
+ assert_equal("D", col[4].attrGet(OCI_ATTR_NAME))
113
+ assert_equal(0, col[1].attrGet(OCI_ATTR_PRECISION))
114
+ assert_equal(0, col[2].attrGet(OCI_ATTR_PRECISION))
115
+ assert_equal(10, col[3].attrGet(OCI_ATTR_PRECISION))
116
+ assert_equal(0, col[4].attrGet(OCI_ATTR_PRECISION))
117
+ assert_equal(0, col[1].attrGet(OCI_ATTR_SCALE))
118
+ assert_equal(0, col[2].attrGet(OCI_ATTR_SCALE))
119
+ assert_equal(2, col[3].attrGet(OCI_ATTR_SCALE))
120
+ assert_equal(0, col[4].attrGet(OCI_ATTR_SCALE))
121
+ assert_equal(false, col[1].attrGet(OCI_ATTR_IS_NULL))
122
+ assert_equal(true, col[2].attrGet(OCI_ATTR_IS_NULL))
123
+ assert_equal(true, col[3].attrGet(OCI_ATTR_IS_NULL))
124
+ assert_equal(true, col[4].attrGet(OCI_ATTR_IS_NULL))
125
+ drop_table('test_table')
126
+ end
127
+
128
+ def teardown
129
+ @stmt.free()
130
+ @svc.logoff()
131
+ @env.free()
132
+ end
133
+ end
134
+
135
+ if $0 == __FILE__
136
+ RUNIT::CUI::TestRunner.run(TestDescribe.suite())
137
+ end
@@ -0,0 +1,243 @@
1
+ require 'oci8'
2
+ require 'runit/testcase'
3
+ require 'runit/cui/testrunner'
4
+ require File.dirname(__FILE__) + '/config'
5
+
6
+ class TestMetadata < RUNIT::TestCase
7
+
8
+ def setup
9
+ @conn = get_oci_connection()
10
+ end
11
+
12
+ def teardown
13
+ @conn.logoff
14
+ end
15
+
16
+ def test_metadata
17
+ # data_size factor for nchar charset_form.
18
+ cursor = @conn.exec("select CAST('1' AS NCHAR(1)) from dual")
19
+ cfrm = cursor.column_metadata[0].data_size
20
+ if $oracle_version >= 900
21
+ # data_size factor for char semantics.
22
+ cursor = @conn.exec("select CAST('1' AS CHAR(1 char)) from dual")
23
+ csem = cursor.column_metadata[0].data_size
24
+ end
25
+
26
+ coldef =
27
+ [
28
+ # oracle_version, definition, data_type, csfrm, null,csem?,csize, data_size,prec,scale,fsprec,lfprec
29
+ [800, "CHAR(10) NOT NULL", :char, :implicit, false, false, 10, 10, 0, 0, 0, 0],
30
+ [900, "CHAR(10 CHAR)", :char, :implicit, true, true, 10, 10 * csem, 0, 0, 0, 0],
31
+ [800, "NCHAR(10)", :char, :nchar, true, true, 10, 10 * cfrm, 0, 0, 0, 0],
32
+ [800, "VARCHAR2(10)", :varchar2, :implicit, true, false, 10, 10, 0, 0, 0, 0],
33
+ [900, "VARCHAR2(10 CHAR)", :varchar2, :implicit, true, true, 10, 10 * csem, 0, 0, 0, 0],
34
+ [800, "NVARCHAR2(10)", :varchar2, :nchar, true, true, 10, 10 * cfrm, 0, 0, 0, 0],
35
+ [800, "RAW(10)", :raw, nil, true, false, 0, 10, 0, 0, 0, 0],
36
+
37
+ # Don't check data_size of CLOB, NCLOB and BLOB.
38
+ #
39
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
40
+ # +----------+-----------+
41
+ # | | data_size |
42
+ # +----------+-----------+
43
+ # | implicit | 4000 | <= OCI8::Cursor#column_metadata
44
+ # | explicit | 86 | <= OCI8.describe_table('table_name').columns
45
+ # +----------+-----------+
46
+ [800, "CLOB", :clob, :implicit, true, false, 0, :nc, 0, 0, 0, 0],
47
+ [800, "NCLOB", :clob, :nchar, true, false, 0, :nc, 0, 0, 0, 0],
48
+ [800, "BLOB", :blob, nil, true, false, 0, :nc, 0, 0, 0, 0],
49
+
50
+ [800, "BFILE", :bfile, nil, true, false, 0, 530, 0, 0, 0, 0],
51
+
52
+ # Don't check fsprecision and lfprecision for NUMBER and FLOAT
53
+ #
54
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
55
+ # +---------------------------+-------------+-------------+
56
+ # | | fsprecision | lfprecision |
57
+ # +----------------+----------+-------------+-------------+
58
+ # | NUMBER | implicit | 129 | 0 |
59
+ # | | explicit | 0 | 129 |
60
+ # +----------------+----------+-------------+-------------+
61
+ # | NUMBER(10) | implicit | 0 | 10 |
62
+ # | | explicit | 10 | 0 |
63
+ # +----------------+----------+-------------+-------------+
64
+ # | NUMBER(10,2) | implicit | 2 | 10 |
65
+ # | | explicit | 10 | 2 |
66
+ # +----------------+----------+-------------+-------------+
67
+ # | FLOAT | implicit | 129 | 126 |
68
+ # | | explicit | 126 | 129 |
69
+ # +----------------+----------+-------------+-------------+
70
+ # | FLOAT(10) | implicit | 129 | 10 |
71
+ # | | explicit | 10 | 129 |
72
+ # +----------------+----------+-------------+-------------+
73
+ [800, "NUMBER", :number, nil, true, false, 0, 22, 0, -127, :nc, :nc],
74
+ [800, "NUMBER(10)", :number, nil, true, false, 0, 22, 10, 0, :nc, :nc],
75
+ [800, "NUMBER(10,2)", :number, nil, true, false, 0, 22, 10, 2, :nc, :nc],
76
+ [800, "FLOAT", :number, nil, true, false, 0, 22, 126, -127, :nc, :nc],
77
+ [800, "FLOAT(10)", :number, nil, true, false, 0, 22, 10, -127, :nc, :nc],
78
+
79
+ [1000,"BINARY_FLOAT", :binary_float, nil, true, false, 0, 4, 0, 0, 0, 0],
80
+ [1000,"BINARY_DOUBLE", :binary_double, nil, true, false, 0, 8, 0, 0, 0, 0],
81
+ [800, "DATE", :date, nil, true, false, 0, 7, 0, 0, 0, 0],
82
+
83
+ # Don't check precision and lfprecision for TIMESTAMP
84
+ #
85
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
86
+ # +----------------------------------------------+-----------+-------------+
87
+ # | | precision | lfprecision |
88
+ # +-----------------------------------+----------+-----------+-------------+
89
+ # | TIMESTAMP | implicit | 0 | 0 |
90
+ # | | explicit | 6 | 6 |
91
+ # +-----------------------------------+----------+-----------+-------------+
92
+ # | TIMESTAMP(9) | implicit | 0 | 0 |
93
+ # | | explicit | 9 | 9 |
94
+ # +-----------------------------------+----------+-----------+-------------+
95
+ # | TIMESTAMP WITH TIME ZONE | implicit | 0 | 0 |
96
+ # | | explicit | 6 | 6 |
97
+ # +-----------------------------------+----------+-----------+-------------+
98
+ # | TIMESTAMP(9) WITH TIME ZONE | implicit | 0 | 0 |
99
+ # | | explicit | 9 | 9 |
100
+ # +-----------------------------------+----------+-----------+-------------+
101
+ # | TIMESTAMP WITH LOCAL TIME ZONE | implicit | 0 | 0 |
102
+ # | | explicit | 6 | 6 |
103
+ # +-----------------------------------+----------+-----------+-------------+
104
+ # | TIMESTAMP(9) WITH LOCAL TIME ZONE | implicit | 0 | 0 |
105
+ # | | explicit | 9 | 9 |
106
+ # +-----------------------------------+----------+-----------+-------------+
107
+ [900, "TIMESTAMP", :timestamp, nil, true, false, 0, 11, :nc, 6, 6, :nc],
108
+ [900, "TIMESTAMP(9)", :timestamp, nil, true, false, 0, 11, :nc, 9, 9, :nc],
109
+ [900, "TIMESTAMP WITH TIME ZONE", :timestamp_tz, nil, true, false, 0, 13, :nc, 6, 6, :nc],
110
+ [900, "TIMESTAMP(9) WITH TIME ZONE", :timestamp_tz, nil, true, false, 0, 13, :nc, 9, 9, :nc],
111
+ [900, "TIMESTAMP WITH LOCAL TIME ZONE", :timestamp_ltz, nil, true, false, 0, 11, :nc, 6, 6, :nc],
112
+ [900, "TIMESTAMP(9) WITH LOCAL TIME ZONE", :timestamp_ltz, nil, true, false, 0, 11, :nc, 9, 9, :nc],
113
+
114
+ # Don't check scale and fsprecision for INTERVAL YEAR TO MONTH
115
+ #
116
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
117
+ # +-----------------------------------------+-----------+-------------+
118
+ # | | scale | fsprecision |
119
+ # +------------------------------+----------+-----------+-------------+
120
+ # | INTERVAL YEAR TO MONTH | implicit | 0 | 0 |
121
+ # | | explicit | 2 | 2 |
122
+ # +------------------------------+----------+-----------+-------------+
123
+ # | INTERVAL YEAR(4) TO MONTH | implicit | 0 | 0 |
124
+ # | | explicit | 4 | 4 |
125
+ # +------------------------------+----------+-----------+-------------+
126
+ [900, "INTERVAL YEAR TO MONTH", :interval_ym, nil, true, false, 0, 5, 2, :nc, :nc, 2],
127
+ [900, "INTERVAL YEAR(4) TO MONTH", :interval_ym, nil, true, false, 0, 5, 4, :nc, :nc, 4],
128
+
129
+ # Don't check precision and scale for INTERVAL DAY TO SECOND
130
+ #
131
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
132
+ # +-----------------------------------------+-----------+-----------+
133
+ # | | precision | scale |
134
+ # +------------------------------+----------+-----------+-----------+
135
+ # | INTERVAL DAY TO SECOND | implicit | 2 | 6 |
136
+ # | | explicit | 6 | 2 |
137
+ # +------------------------------+----------+-----------+-----------+
138
+ # | INTERVAL DAY(4) TO SECOND(9) | implicit | 4 | 9 |
139
+ # | | explicit | 9 | 4 |
140
+ # +------------------------------+----------+-----------+-----------+
141
+ [900, "INTERVAL DAY TO SECOND", :interval_ds, nil, true, false, 0, 11, :nc, :nc, 6, 2],
142
+ [900, "INTERVAL DAY(4) TO SECOND(9)",:interval_ds, nil, true, false, 0, 11, :nc, :nc, 9, 4],
143
+ ]
144
+
145
+ coldef.reject! do |c| c[0] > $oracle_version end
146
+
147
+ drop_table('test_table')
148
+ sql = <<-EOS
149
+ CREATE TABLE test_table (#{i = 0; coldef.collect do |c| i += 1; "C#{i} " + c[1]; end.join(',')})
150
+ STORAGE (
151
+ INITIAL 100k
152
+ NEXT 100k
153
+ MINEXTENTS 1
154
+ MAXEXTENTS UNLIMITED
155
+ PCTINCREASE 0)
156
+ EOS
157
+ @conn.exec(sql)
158
+
159
+ @conn.describe_table('test_table').columns.each_with_index do |md, i|
160
+ # common
161
+ assert_equal("C#{i + 1}", md.name, "'#{coldef[i][1]}': name")
162
+ assert_equal(coldef[i][1], md.type_string, "'#{coldef[i][1]}': type_string")
163
+ assert_equal(coldef[i][2], md.data_type, "'#{coldef[i][1]}': data_type")
164
+ assert_equal(coldef[i][3], md.charset_form, "'#{coldef[i][1]}': charset_form")
165
+ assert_equal(coldef[i][4], md.nullable?, "'#{coldef[i][1]}': nullable? ")
166
+ # string type
167
+ if $oracle_version >= 900
168
+ assert_equal(coldef[i][5], md.char_used?, "'#{coldef[i][1]}': char_used? ")
169
+ assert_equal(coldef[i][6], md.char_size, "'#{coldef[i][1]}': char_size")
170
+ end
171
+ assert_equal(coldef[i][7], md.data_size, "'#{coldef[i][1]}': data_size") if coldef[i][7] != :nc
172
+ # number, timestamp and interval type
173
+ assert_equal(coldef[i][8], md.precision, "'#{coldef[i][1]}': precision") if coldef[i][8] != :nc
174
+ assert_equal(coldef[i][9], md.scale, "'#{coldef[i][1]}': scale") if coldef[i][9] != :nc
175
+ assert_equal(coldef[i][10], md.fsprecision, "'#{coldef[i][1]}': fsprecision") if coldef[i][10] != :nc
176
+ assert_equal(coldef[i][11], md.lfprecision, "'#{coldef[i][1]}': lfprecision") if coldef[i][11] != :nc
177
+ end
178
+
179
+ # temporarily change OCI8::BindType::Mapping.
180
+ saved_mapping = {}
181
+ [OCI8::SQLT_TIMESTAMP_TZ,
182
+ OCI8::SQLT_TIMESTAMP_LTZ,
183
+ OCI8::SQLT_INTERVAL_YM,
184
+ OCI8::SQLT_INTERVAL_DS].each do |sqlt_type|
185
+ saved_mapping[sqlt_type] = OCI8::BindType::Mapping[sqlt_type]
186
+ OCI8::BindType::Mapping[sqlt_type] = OCI8::BindType::String
187
+ end
188
+ begin
189
+ cursor = @conn.exec("SELECT * FROM test_table")
190
+ ensure
191
+ saved_mapping.each do |key, val|
192
+ OCI8::BindType::Mapping[key] = val
193
+ end
194
+ end
195
+ cursor.column_metadata.each_with_index do |md, i|
196
+ # common
197
+ assert_equal("C#{i + 1}", md.name, "'#{coldef[i][1]}': name")
198
+ assert_equal(coldef[i][1], md.type_string, "'#{coldef[i][1]}': type_string")
199
+ assert_equal(coldef[i][2], md.data_type, "'#{coldef[i][1]}': data_type")
200
+ assert_equal(coldef[i][3], md.charset_form, "'#{coldef[i][1]}': charset_form")
201
+ assert_equal(coldef[i][4], md.nullable?, "'#{coldef[i][1]}': nullable? ")
202
+ # string type
203
+ if $oracle_version >= 900
204
+ assert_equal(coldef[i][5], md.char_used?, "'#{coldef[i][1]}': char_used? ")
205
+ assert_equal(coldef[i][6], md.char_size, "'#{coldef[i][1]}': char_size")
206
+ end
207
+ assert_equal(coldef[i][7], md.data_size, "'#{coldef[i][1]}': data_size") if coldef[i][7] != :nc
208
+ # number, timestamp and interval type
209
+ assert_equal(coldef[i][8], md.precision, "'#{coldef[i][1]}': precision") if coldef[i][8] != :nc
210
+ assert_equal(coldef[i][9], md.scale, "'#{coldef[i][1]}': scale") if coldef[i][9] != :nc
211
+ assert_equal(coldef[i][10], md.fsprecision, "'#{coldef[i][1]}': fsprecision") if coldef[i][10] != :nc
212
+ assert_equal(coldef[i][11], md.lfprecision, "'#{coldef[i][1]}': lfprecision") if coldef[i][11] != :nc
213
+ end
214
+
215
+ drop_table('test_table')
216
+ end
217
+
218
+ def test_error_describe_table
219
+ drop_table('test_table')
220
+ begin
221
+ @conn.describe_table('test_table')
222
+ assert_fail("expects ORA-4043 but no error")
223
+ rescue OCIError
224
+ assert_fail("expects ORA-4043 but ORA-#{$!.code}") if $!.code != 4043
225
+ end
226
+ @conn.exec('create sequence test_table')
227
+ begin
228
+ begin
229
+ @conn.describe_table('test_table')
230
+ assert_fail('expects ORA-4043 but no error')
231
+ rescue OCIError
232
+ assert_fail("expects ORA-4043 but ORA-#{$!.code}") if $!.code != 4043
233
+ end
234
+ ensure
235
+ @conn.exec('drop sequence test_table')
236
+ end
237
+ end
238
+
239
+ end # TestMetadata
240
+
241
+ if $0 == __FILE__
242
+ RUNIT::CUI::TestRunner.run(TestMetadata.suite())
243
+ end
@@ -0,0 +1,273 @@
1
+ require 'oci8'
2
+ require 'runit/testcase'
3
+ require 'runit/cui/testrunner'
4
+ require File.dirname(__FILE__) + '/config'
5
+
6
+ class TestOCI8 < RUNIT::TestCase
7
+
8
+ def setup
9
+ @conn = get_oci_connection()
10
+ end
11
+
12
+ def teardown
13
+ @conn.logoff
14
+ end
15
+
16
+ def test_select
17
+ drop_table('test_table')
18
+ sql = <<-EOS
19
+ CREATE TABLE test_table
20
+ (C CHAR(10) NOT NULL,
21
+ V VARCHAR2(20),
22
+ N NUMBER(10, 2),
23
+ D1 DATE, D2 DATE, D3 DATE, D4 DATE,
24
+ INT NUMBER(30), BIGNUM NUMBER(30))
25
+ STORAGE (
26
+ INITIAL 4k
27
+ NEXT 4k
28
+ MINEXTENTS 1
29
+ MAXEXTENTS UNLIMITED
30
+ PCTINCREASE 0)
31
+ EOS
32
+ @conn.exec(sql)
33
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D1, :D2, :D3, :D4, :INT, :BIGNUM)")
34
+ 1.upto(10) do |i|
35
+ if i == 1
36
+ dt = [nil, OraDate]
37
+ else
38
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
39
+ end
40
+ cursor.exec(format("%10d", i * 10), i.to_s, i, dt, dt, dt, dt, i * 11111111111, i * 10000000000)
41
+ end
42
+ cursor.close
43
+ cursor = @conn.parse("SELECT * FROM test_table ORDER BY c")
44
+ cursor.define(5, Time) # define 5th column as Time
45
+ cursor.define(6, Date) # define 6th column as Date
46
+ cursor.define(7, DateTime) if defined? DateTime # define 7th column as DateTime
47
+ cursor.define(8, Integer) # define 8th column as Integer
48
+ cursor.define(9, Bignum) # define 9th column as Bignum
49
+ cursor.exec
50
+ assert_equal(["C", "V", "N", "D1", "D2", "D3", "D4", "INT", "BIGNUM"], cursor.get_col_names)
51
+ 1.upto(10) do |i|
52
+ rv = cursor.fetch
53
+ assert_equal(format("%10d", i * 10), rv[0])
54
+ assert_equal(i.to_s, rv[1])
55
+ assert_equal(i, rv[2])
56
+ if i == 1
57
+ assert_nil(rv[3])
58
+ assert_nil(rv[4])
59
+ assert_nil(rv[5])
60
+ assert_nil(rv[6])
61
+ else
62
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
63
+ assert_equal(dt, rv[3])
64
+ assert_equal(dt.to_time, rv[4])
65
+ assert_equal(dt.to_date, rv[5])
66
+ assert_equal(dt.to_datetime, rv[6]) if defined? DateTime
67
+ end
68
+ assert_equal(i * 11111111111, rv[7])
69
+ assert_equal(i * 10000000000, rv[8])
70
+ end
71
+ assert_nil(cursor.fetch)
72
+
73
+ # fetch_hash with block
74
+ cursor.exec
75
+ i = 1
76
+ cursor.fetch_hash do |row|
77
+ assert_equal(format("%10d", i * 10), row['C'])
78
+ assert_equal(i.to_s, row['V'])
79
+ assert_equal(i, row['N'])
80
+ if i == 1
81
+ assert_nil(row['D1'])
82
+ assert_nil(row['D2'])
83
+ assert_nil(row['D3'])
84
+ assert_nil(row['D4'])
85
+ else
86
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
87
+ assert_equal(dt, row['D1'])
88
+ assert_equal(dt.to_time, row['D2'])
89
+ assert_equal(dt.to_date, row['D3'])
90
+ assert_equal(dt.to_datetime, row['D4']) if defined? DateTime
91
+ end
92
+ assert_equal(i * 11111111111, row['INT'])
93
+ assert_equal(i * 10000000000, row['BIGNUM'])
94
+ i += 1
95
+ end
96
+ assert_equal(i, 11)
97
+
98
+ cursor.close
99
+ drop_table('test_table')
100
+ end
101
+
102
+ def test_bind_cursor
103
+ drop_table('test_table')
104
+ sql = <<-EOS
105
+ CREATE TABLE test_table
106
+ (C CHAR(10) NOT NULL,
107
+ V VARCHAR2(20),
108
+ N NUMBER(10, 2),
109
+ D1 DATE, D2 DATE, D3 DATE,
110
+ INT NUMBER(30), BIGNUM NUMBER(30))
111
+ STORAGE (
112
+ INITIAL 4k
113
+ NEXT 4k
114
+ MINEXTENTS 1
115
+ MAXEXTENTS UNLIMITED
116
+ PCTINCREASE 0)
117
+ EOS
118
+ @conn.exec(sql)
119
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D1, :D2, :D3, :INT, :BIGNUM)")
120
+ 1.upto(10) do |i|
121
+ if i == 1
122
+ dt = [nil, OraDate]
123
+ else
124
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
125
+ end
126
+ cursor.exec(format("%10d", i * 10), i.to_s, i, dt, dt, dt, i, i)
127
+ end
128
+ cursor.close
129
+ plsql = @conn.parse("BEGIN OPEN :cursor FOR SELECT * FROM test_table ORDER BY c; END;")
130
+ plsql.bind_param(':cursor', OCI8::Cursor)
131
+ plsql.exec
132
+ cursor = plsql[':cursor']
133
+ cursor.define(5, Time) # define 5th column as Time
134
+ cursor.define(6, Date) # define 6th column as Date
135
+ cursor.define(7, Integer) # define 7th column as Integer
136
+ cursor.define(8, Bignum) # define 8th column as Integer
137
+ assert_equal(["C", "V", "N", "D1", "D2", "D3", "INT", "BIGNUM"], cursor.get_col_names)
138
+ 1.upto(10) do |i|
139
+ rv = cursor.fetch
140
+ assert_equal(format("%10d", i * 10), rv[0])
141
+ assert_equal(i.to_s, rv[1])
142
+ assert_equal(i, rv[2])
143
+ if i == 1
144
+ assert_nil(rv[3])
145
+ assert_nil(rv[4])
146
+ assert_nil(rv[5])
147
+ else
148
+ dt = OraDate.new(2000 + i, 8, 3, 23, 59, 59)
149
+ assert_equal(dt, rv[3])
150
+ assert_equal(dt.to_time, rv[4])
151
+ assert_equal(dt.to_date, rv[5])
152
+ end
153
+ assert_equal(i, rv[6])
154
+ assert_equal(i, rv[7])
155
+ end
156
+ assert_nil(cursor.fetch)
157
+ cursor.close
158
+ drop_table('test_table')
159
+ end
160
+
161
+ def test_cursor_in_result_set
162
+ drop_table('test_table')
163
+ sql = <<-EOS
164
+ CREATE TABLE test_table (N NUMBER(10, 2))
165
+ STORAGE (
166
+ INITIAL 4k
167
+ NEXT 4k
168
+ MINEXTENTS 1
169
+ MAXEXTENTS UNLIMITED
170
+ PCTINCREASE 0)
171
+ EOS
172
+ @conn.exec(sql)
173
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:1)")
174
+ 1.upto(10) do |i|
175
+ cursor.exec(i)
176
+ end
177
+ cursor.close
178
+ cursor = @conn.exec(<<EOS)
179
+ select a.n, cursor (select a.n + b.n
180
+ from test_table b
181
+ order by n)
182
+ from test_table a
183
+ order by n
184
+ EOS
185
+ 1.upto(10) do |i|
186
+ row = cursor.fetch
187
+ assert_equal(i, row[0])
188
+ cursor_in_result_set = row[1]
189
+ 1.upto(10) do |j|
190
+ row2 = cursor_in_result_set.fetch
191
+ assert_equal(i + j, row2[0])
192
+ end
193
+ assert_nil(cursor_in_result_set.fetch) # check end of row data
194
+ cursor_in_result_set.close
195
+ end
196
+ assert_nil(cursor.fetch) # check end of row data
197
+ drop_table('test_table')
198
+ end
199
+
200
+ if $oracle_version >= 1000
201
+ # Oracle 10g or upper
202
+ def test_binary_float
203
+ cursor = @conn.parse("select CAST(:1 AS BINARY_FLOAT), CAST(:2 AS BINARY_DOUBLE) from dual")
204
+ bind_val = -1.0
205
+ cursor.bind_param(1, 10.0, OCI8::SQLT_IBDOUBLE)
206
+ cursor.bind_param(2, nil, OCI8::SQLT_IBDOUBLE)
207
+ while bind_val < 10.0
208
+ cursor[2] = bind_val
209
+ cursor.exec
210
+ rv = cursor.fetch
211
+ assert_equal(10.0, rv[0])
212
+ assert_equal(bind_val, rv[1])
213
+ bind_val += 1.234
214
+ end
215
+ [-1.0/0.0, # -Infinite
216
+ +1.0/0.0, # +Infinite
217
+ 0.0/0.0 # NaN
218
+ ].each do |num|
219
+ cursor[1] = num
220
+ cursor[2] = num
221
+ cursor.exec
222
+ rv = cursor.fetch
223
+ if num.nan?
224
+ assert(rv[0].nan?)
225
+ assert(rv[1].nan?)
226
+ else
227
+ assert_equal(num, rv[0])
228
+ assert_equal(num, rv[1])
229
+ end
230
+ end
231
+ cursor.close
232
+ end
233
+ end
234
+
235
+ def test_clob_nclob_and_blob
236
+ drop_table('test_table')
237
+ sql = <<-EOS
238
+ CREATE TABLE test_table (id number(5), C CLOB, NC NCLOB, B BLOB)
239
+ STORAGE (
240
+ INITIAL 100k
241
+ NEXT 100k
242
+ MINEXTENTS 1
243
+ MAXEXTENTS UNLIMITED
244
+ PCTINCREASE 0)
245
+ EOS
246
+ @conn.exec(sql)
247
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:1, :2, :3, :4)")
248
+ 0.upto(9) do |i|
249
+ val = format('%d', i) * 4096
250
+ cursor.exec(i, OCI8::CLOB.new(@conn, val), OCI8::NCLOB.new(@conn, val), OCI8::BLOB.new(@conn, val))
251
+ end
252
+ cursor.close
253
+ cursor = @conn.exec("select * from test_table order by id")
254
+ 0.upto(9) do |i|
255
+ rv = cursor.fetch
256
+ val = format('%d', i) * 4096
257
+ assert_equal(i, rv[0])
258
+ assert_instance_of(OCI8::CLOB, rv[1])
259
+ assert_instance_of(OCI8::NCLOB, rv[2])
260
+ assert_instance_of(OCI8::BLOB, rv[3])
261
+ assert_equal(val, rv[1].read)
262
+ assert_equal(val, rv[2].read)
263
+ assert_equal(val, rv[3].read)
264
+ end
265
+ assert_nil(cursor.fetch)
266
+ cursor.close
267
+ drop_table('test_table')
268
+ end
269
+ end # TestOCI8
270
+
271
+ if $0 == __FILE__
272
+ RUNIT::CUI::TestRunner.run(TestOCI8.suite())
273
+ end