ruby-oci8 2.0.6-x86-mingw32 → 2.1.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,8 +17,8 @@ class TestConnStr < Test::Unit::TestCase
17
17
  ["", ArgumentError],
18
18
  ["foo bar/baz", ArgumentError],
19
19
  ["foo@bar/baz", ArgumentError],
20
- # raise error in connecting but no error in parse_connect_string.
21
- ["foo/bar as sysdbaaa", ["foo", "bar", nil, "sysdbaaa"]],
20
+ # parse_connect_string doesn't check validity of privilege.
21
+ ["foo/bar as foo_bar", ["foo", "bar", nil, :FOO_BAR]],
22
22
 
23
23
  ##
24
24
  ## following test cases are contributed by Shiwei Zhang.
@@ -96,8 +96,6 @@ EOS
96
96
  end
97
97
 
98
98
  def test_timestamp_select
99
- return if $oracle_version < OCI8::ORAVER_9_0
100
-
101
99
  ['2005-12-31 23:59:59.999999000',
102
100
  '2006-01-01 00:00:00.000000000'].each do |date|
103
101
  @conn.exec(<<-EOS) do |row|
@@ -109,8 +107,6 @@ EOS
109
107
  end
110
108
 
111
109
  def test_timestamp_out_bind
112
- return if $oracle_version < OCI8::ORAVER_9_0
113
-
114
110
  cursor = @conn.parse(<<-EOS)
115
111
  BEGIN
116
112
  :out := TO_TIMESTAMP(:in, 'YYYY-MM-DD HH24:MI:SS.FF');
@@ -128,8 +124,6 @@ EOS
128
124
  end
129
125
 
130
126
  def test_timestamp_in_bind
131
- return if $oracle_version < OCI8::ORAVER_9_0
132
-
133
127
  cursor = @conn.parse(<<-EOS)
134
128
  BEGIN
135
129
  :out := TO_CHAR(:in, 'YYYY-MM-DD HH24:MI:SS.FF');
@@ -147,8 +141,6 @@ EOS
147
141
  end
148
142
 
149
143
  def test_timestamp_tz_select
150
- return if $oracle_version < OCI8::ORAVER_9_0
151
-
152
144
  ['2005-12-31 23:59:59.999999000 +08:30',
153
145
  '2006-01-01 00:00:00.000000000 -08:30'].each do |date|
154
146
  @conn.exec(<<-EOS) do |row|
@@ -165,8 +157,6 @@ EOS
165
157
  end
166
158
 
167
159
  def test_timestamp_tz_out_bind
168
- return if $oracle_version < OCI8::ORAVER_9_0
169
-
170
160
  cursor = @conn.parse(<<-EOS)
171
161
  BEGIN
172
162
  :out := TO_TIMESTAMP_TZ(:in, 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM');
@@ -184,8 +174,6 @@ EOS
184
174
  end
185
175
 
186
176
  def test_timestamp_tz_in_bind
187
- return if $oracle_version < OCI8::ORAVER_9_0
188
-
189
177
  cursor = @conn.parse(<<-EOS)
190
178
  BEGIN
191
179
  :out := TO_CHAR(:in, 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM');
@@ -230,9 +218,6 @@ EOS
230
218
  cursor.exec
231
219
  assert_equal(DateTime.parse('2006-12-31 23:59:59' + @local_timezone), cursor[:out])
232
220
 
233
- # sec_fraction and timezone are available on Oracle 9i or later
234
- return if $oracle_version < OCI8::ORAVER_9_0
235
-
236
221
  # test sec_fraction
237
222
  def obj.sec_fraction; DateTime.parse('0001-01-01 00:00:00.000001').sec_fraction * 999999 ; end
238
223
  cursor[:in] = obj
@@ -261,15 +246,13 @@ EOS
261
246
  end
262
247
 
263
248
  def test_timezone
264
- if $oracle_version >= OCI8::ORAVER_9_0
265
- # temporarily change the mapping to test OCI8::BindType::Util.default_timezone.
266
- OCI8::BindType::Mapping[:date] = OCI8::BindType::TimeViaOCIDate
267
- end
268
249
  begin
250
+ # temporarily change the mapping to test OCI8::BindType::Util.default_timezone.
269
251
  assert_raise(ArgumentError) do
270
252
  OCI8::BindType::Util.default_timezone = :invalid_value
271
253
  end
272
254
 
255
+ =begin
273
256
  [:local, :utc].each do |tz|
274
257
  OCI8::BindType::Util.default_timezone = tz
275
258
  @conn.exec("select sysdate, to_date('2008-01-02', 'yyyy-mm-dd') from dual") do |row|
@@ -282,49 +265,42 @@ EOS
282
265
  assert_equal(2, row[1].day)
283
266
  end
284
267
  end
268
+ =end
285
269
  ensure
286
270
  OCI8::BindType::Util.default_timezone = :local
287
- if $oracle_version >= OCI8::ORAVER_9_0
288
- OCI8::BindType::Mapping[:date] = OCI8::BindType::Time
289
- end
290
271
  end
291
272
 
292
- if $oracle_version >= OCI8::ORAVER_9_0
293
- ses_tz = nil
294
- @conn.exec('select sessiontimezone from dual') do |row|
295
- ses_tz = row[0]
296
- end
273
+ ses_tz = nil
274
+ @conn.exec('select sessiontimezone from dual') do |row|
275
+ ses_tz = row[0]
276
+ end
297
277
 
298
- begin
299
- ['+09:00', '+00:00', '-05:00'].each do |tz|
300
- @conn.exec("alter session set time_zone = '#{tz}'")
301
- @conn.exec("select current_timestamp, sysdate, to_timestamp('2008-01-02', 'yyyy-mm-dd') from dual") do |row|
302
- row.each do |dt|
303
- case dt
304
- when Time
305
- assert_equal(tz, timezone_string(*((dt.utc_offset / 60).divmod 60)))
306
- when DateTime
307
- tz = tz.gsub(/:/, '') if RUBY_VERSION <= '1.8.5'
308
- assert_equal(tz, dt.zone)
309
- else
310
- flunk "unexpedted type #{dt.class}"
311
- end
278
+ begin
279
+ ['+09:00', '+00:00', '-05:00'].each do |tz|
280
+ @conn.exec("alter session set time_zone = '#{tz}'")
281
+ @conn.exec("select current_timestamp, sysdate, to_timestamp('2008-01-02', 'yyyy-mm-dd') from dual") do |row|
282
+ row.each do |dt|
283
+ case dt
284
+ when Time
285
+ assert_equal(tz, timezone_string(*((dt.utc_offset / 60).divmod 60)))
286
+ when DateTime
287
+ tz = tz.gsub(/:/, '') if RUBY_VERSION <= '1.8.5'
288
+ assert_equal(tz, dt.zone)
289
+ else
290
+ flunk "unexpedted type #{dt.class}"
312
291
  end
313
- assert_equal(2008, row[2].year)
314
- assert_equal(1, row[2].month)
315
- assert_equal(2, row[2].day)
316
292
  end
293
+ assert_equal(2008, row[2].year)
294
+ assert_equal(1, row[2].month)
295
+ assert_equal(2, row[2].day)
317
296
  end
318
- ensure
319
- @conn.exec("alter session set time_zone = '#{ses_tz}'")
320
297
  end
321
- else
298
+ ensure
299
+ @conn.exec("alter session set time_zone = '#{ses_tz}'")
322
300
  end
323
301
  end
324
302
 
325
303
  def test_interval_ym_select
326
- return if $oracle_version < OCI8::ORAVER_9_0
327
-
328
304
  [['2006-01-01', '2004-03-01'],
329
305
  ['2006-01-01', '2005-03-01'],
330
306
  ['2006-01-01', '2006-03-01'],
@@ -341,8 +317,6 @@ EOS
341
317
  end
342
318
 
343
319
  def test_interval_ym_out_bind
344
- return if $oracle_version < OCI8::ORAVER_9_0
345
-
346
320
  cursor = @conn.parse(<<-EOS)
347
321
  DECLARE
348
322
  ts1 TIMESTAMP;
@@ -370,8 +344,6 @@ EOS
370
344
  end
371
345
 
372
346
  def test_interval_ym_in_bind
373
- return if $oracle_version < OCI8::ORAVER_9_0
374
-
375
347
  cursor = @conn.parse(<<-EOS)
376
348
  DECLARE
377
349
  ts1 TIMESTAMP;
@@ -402,8 +374,6 @@ EOS
402
374
  end
403
375
 
404
376
  def test_interval_ds_select
405
- return if $oracle_version < OCI8::ORAVER_9_0
406
-
407
377
  [['2006-01-01', '2004-03-01'],
408
378
  ['2006-01-01', '2005-03-01'],
409
379
  ['2006-01-01', '2006-03-01'],
@@ -430,8 +400,6 @@ EOS
430
400
  end
431
401
 
432
402
  def test_interval_ds_out_bind
433
- return if $oracle_version < OCI8::ORAVER_9_0
434
-
435
403
  cursor = @conn.parse(<<-EOS)
436
404
  DECLARE
437
405
  ts1 TIMESTAMP;
@@ -469,14 +437,12 @@ EOS
469
437
  end
470
438
 
471
439
  def test_interval_ds_in_bind
472
- return if $oracle_version < OCI8::ORAVER_9_0
473
-
474
440
  cursor = @conn.parse(<<-EOS)
475
441
  DECLARE
476
442
  ts1 TIMESTAMP;
477
443
  BEGIN
478
444
  ts1 := TO_TIMESTAMP(:in1, 'YYYY-MM-DD HH24:MI:SS.FF');
479
- :out := TO_CHAR(ts1 + :in2, 'YYYY-MM-DD HH24:MI:SS.FF6');
445
+ :out := TO_CHAR(ts1 + :in2, 'YYYY-MM-DD HH24:MI:SS.FF');
480
446
  END;
481
447
  EOS
482
448
  cursor.bind_param(:out, nil, String, 36)
@@ -505,8 +471,6 @@ EOS
505
471
  end
506
472
 
507
473
  def test_days_interval_ds_select
508
- return if $oracle_version < OCI8::ORAVER_9_0
509
-
510
474
  [['2006-01-01', '2004-03-01'],
511
475
  ['2006-01-01', '2005-03-01'],
512
476
  ['2006-01-01', '2006-03-01'],
@@ -538,8 +502,6 @@ EOS
538
502
  end
539
503
 
540
504
  def test_days_interval_ds_out_bind
541
- return if $oracle_version < OCI8::ORAVER_9_0
542
-
543
505
  cursor = @conn.parse(<<-EOS)
544
506
  DECLARE
545
507
  ts1 TIMESTAMP;
@@ -582,8 +544,6 @@ EOS
582
544
  end
583
545
 
584
546
  def test_days_interval_ds_in_bind
585
- return if $oracle_version < OCI8::ORAVER_9_0
586
-
587
547
  cursor = @conn.parse(<<-EOS)
588
548
  DECLARE
589
549
  ts1 TIMESTAMP;
@@ -45,9 +45,9 @@ EOS
45
45
  assert_equal("\xab\xcd", (data = row[6].read), 'BLOB')
46
46
  assert_equal(ascii_8bit, data.encoding);
47
47
 
48
- if OCI8.encoding.name == "UTF-8"
49
- utf_8 = "\u00A1\u00A2\u00A3\u00A4\u00A5\u00A6\u00A7\u00A8\u00A9"
50
- iso_8859_1 = utf_8.encode("ISO-8859-1")
48
+ if OCI8.encoding.name == "UTF-8" and ['WE8ISO8859P1', 'WE8ISO8859P15', 'AL32UTF8', 'UTF8'].include? @conn.database_charset_name
49
+ utf_8 = "\u00A1\u00A2\u00A3\u00A5\u00A7\u00A9"
50
+ iso_8859_1 = utf_8.encode("ISO-8859-15")
51
51
  # CLOB
52
52
  lob = row[4]
53
53
  lob.rewind
@@ -66,11 +66,15 @@ EOS
66
66
  lob.write(iso_8859_1) # written without encoding conversion
67
67
  lob.rewind
68
68
  assert_equal(iso_8859_1.force_encoding('ASCII-8BIT'), lob.read)
69
+ else
70
+ warn "Skip some asserts because the database character set is neither WE8ISO8859P1, WE8ISO8859P15, AL32UTF8 nor UTF8." if OCI8.encoding.name == "UTF-8"
69
71
  end
70
72
  end
71
73
  drop_table('test_table')
72
74
  end
73
75
 
76
+ warn "Skip some tests which runs only when NLS_CHARACTERSETS is unicode." if OCI8.encoding.name != "UTF-8"
77
+
74
78
  if OCI8.encoding.name == "UTF-8"
75
79
  def test_bind_string_with_code_conversion
76
80
  drop_table('test_table')
@@ -0,0 +1,88 @@
1
+ require 'oci8'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/config'
4
+
5
+ class TestError < Test::Unit::TestCase
6
+ def setup
7
+ @conn = get_oci8_connection
8
+ end
9
+
10
+ def teardown
11
+ @conn.logoff
12
+ end
13
+
14
+ def test_sql_parse_error
15
+ sql = 'select * from'
16
+ begin
17
+ @conn.exec(sql) # raises "ORA-00903: invalid table name"
18
+ rescue OCIException
19
+ assert_instance_of(OCIError, $!)
20
+ assert_match(/^ORA-00903: /, $!.to_s)
21
+ assert_equal(903, $!.code)
22
+ assert_equal(13, $!.parse_error_offset)
23
+ assert_equal(13, $!.parseErrorOffset) # barkward compatibility
24
+ assert_equal(sql, $!.sql)
25
+ end
26
+ end
27
+
28
+ def test_plsql_parse_error
29
+ sql = <<EOS
30
+ BEGIN
31
+ SELECT dummy INTO l_dummy FROM dual WHERE 1=2;
32
+ END;
33
+ EOS
34
+ begin
35
+ @conn.exec(sql) # raises "ORA-06550: line 2, column 21"
36
+ rescue OCIException
37
+ assert_instance_of(OCIError, $!)
38
+ assert_match(/^ORA-06550: /, $!.to_s)
39
+ assert_equal(6550, $!.code)
40
+ assert_equal(26, $!.parse_error_offset)
41
+ assert_equal(26, $!.parseErrorOffset) # barkward compatibility
42
+ assert_equal(sql, $!.sql)
43
+ end
44
+ end
45
+
46
+ def test_plsql_error_in_execution
47
+ sql = <<EOS
48
+ DECLARE
49
+ l_dummy VARCHAR2(50);
50
+ BEGIN
51
+ SELECT * INTO l_dummy
52
+ FROM (SELECT DUMMY FROM DUAL
53
+ UNION ALL
54
+ SELECT DUMMY FROM DUAL);
55
+ END;
56
+ EOS
57
+ begin
58
+ @conn.exec(sql) # raises "ORA-01422: exact fetch returns more than requested number of rows"
59
+ rescue OCIException
60
+ assert_instance_of(OCIError, $!)
61
+ assert_match(/^ORA-01422: /, $!.to_s)
62
+ assert_equal(1422, $!.code)
63
+ assert_equal(0, $!.parse_error_offset)
64
+ assert_equal(0, $!.parseErrorOffset) # barkward compatibility
65
+ assert_equal(sql, $!.sql)
66
+ end
67
+ end
68
+
69
+ def test_nodata
70
+ sql = <<EOS
71
+ DECLARE
72
+ l_dummy VARCHAR2(50);
73
+ BEGIN
74
+ SELECT dummy INTO l_dummy FROM dual WHERE 1=2;
75
+ END;
76
+ EOS
77
+ begin
78
+ @conn.exec(sql) # raises "ORA-01403: no data found"
79
+ rescue OCIException
80
+ assert_instance_of(OCINoData, $!)
81
+ assert_match(/^ORA-01403: /, $!.to_s)
82
+ assert_equal(1403, $!.code)
83
+ assert_equal(0, $!.parse_error_offset)
84
+ assert_equal(0, $!.parseErrorOffset) # barkward compatibility
85
+ assert_equal(sql, $!.sql)
86
+ end
87
+ end
88
+ end
@@ -12,227 +12,592 @@ class TestMetadata < Test::Unit::TestCase
12
12
  @conn.logoff
13
13
  end
14
14
 
15
- def test_metadata
16
- if $oracle_version < OCI8::ORAVER_8_1
15
+ def drop_type(name, drop_body = false)
16
+ if drop_body
17
17
  begin
18
- @conn.describe_table('tab').columns
19
- rescue RuntimeError
20
- assert_equal("This feature is unavailable on Oracle 8.0", $!.to_s)
18
+ @conn.exec("DROP TYPE BODY #{name}")
19
+ rescue OCIError
20
+ raise if $!.code != 4043
21
21
  end
22
- return
23
22
  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
23
+ begin
24
+ @conn.exec("DROP TYPE #{name}")
25
+ rescue OCIError
26
+ raise if $!.code != 4043
34
27
  end
28
+ end
35
29
 
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],
30
+ class DatatypeData
31
+ @@attributes =
32
+ [:data_type_string,
33
+ :data_type,
34
+ :charset_form,
35
+ :nullable?,
36
+ :data_size,
37
+ :precision,
38
+ :scale,
157
39
  ]
40
+ @@attributes +=
41
+ [
42
+ :char_used?,
43
+ :char_size,
44
+ :fsprecision,
45
+ :lfprecision,
46
+ ] if $oracle_version >= OCI8::ORAVER_9_0
158
47
 
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
48
+ @@attributes.each do |attr|
49
+ define_method attr do
50
+ @table[attr]
192
51
  end
193
52
  end
194
53
 
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
54
+ def self.attributes
55
+ @@attributes
203
56
  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
57
+
58
+ def initialize(hash = {})
59
+ @table = hash
210
60
  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
61
+
62
+ def available?(conn)
63
+ return false if $oracle_version < @table[:oraver]
64
+ if /^(\w+)\.(\w+)$/ =~ @table[:data_type_string]
65
+ if conn.select_one('select 1 from all_objects where owner = :1 and object_name = :2', $1, $2)
66
+ true
67
+ else
68
+ warn "skip a test for unsupported datatype: #{@table[:data_type_string]}."
69
+ false
70
+ end
71
+ else
72
+ true
230
73
  end
231
74
  end
75
+ end
232
76
 
233
- drop_table('test_table')
77
+ # Get data_size of NCHAR(1) and that of CHAR(1 CHAR).
78
+ # They depend on the database character set and the
79
+ # client character set.
80
+ conn = OCI8.new($dbuser, $dbpass, $dbname)
81
+ begin
82
+ cursor = conn.exec("select N'1' from dual")
83
+ # cfrm: data_size of NCHAR(1).
84
+ cfrm = cursor.column_metadata[0].data_size
85
+ if $oracle_version >= OCI8::ORAVER_9_0
86
+ # csem: data_size of CHAR(1 CHAR).
87
+ cursor = conn.exec("select CAST('1' AS CHAR(1 char)) from dual")
88
+ csem = cursor.column_metadata[0].data_size
89
+ else
90
+ csem = 1
91
+ end
92
+ ensure
93
+ conn.logoff
234
94
  end
235
95
 
96
+ ora80 = OCI8::ORAVER_8_0
97
+ ora81 = OCI8::ORAVER_8_1
98
+ ora90 = OCI8::ORAVER_9_0
99
+ ora101 = OCI8::ORAVER_10_1
100
+
101
+ @@column_test_data =
102
+ [
103
+ DatatypeData.new(:data_type_string => "CHAR(10) NOT NULL",
104
+ :oraver => ora80,
105
+ :data_type => :char,
106
+ :charset_form => :implicit,
107
+ :nullable? => false,
108
+ :char_used? => false,
109
+ :char_size => 10,
110
+ :data_size => 10,
111
+ :precision => 0,
112
+ :scale => 0,
113
+ :fsprecision => 0,
114
+ :lfprecision => 0
115
+ ),
116
+ DatatypeData.new(:data_type_string => "CHAR(10 CHAR)",
117
+ :oraver => ora90,
118
+ :data_type => :char,
119
+ :charset_form => :implicit,
120
+ :nullable? => true,
121
+ :char_used? => true,
122
+ :char_size => 10,
123
+ :data_size => 10 * csem,
124
+ :precision => 0,
125
+ :scale => 0,
126
+ :fsprecision => 0,
127
+ :lfprecision => 0
128
+ ),
129
+ DatatypeData.new(:data_type_string => "NCHAR(10)",
130
+ :oraver => ora80,
131
+ :data_type => :char,
132
+ :charset_form => :nchar,
133
+ :nullable? => true,
134
+ :char_used? => true,
135
+ :char_size => 10,
136
+ :data_size => 10 * cfrm,
137
+ :precision => 0,
138
+ :scale => 0,
139
+ :fsprecision => 0,
140
+ :lfprecision => 0
141
+ ),
142
+ DatatypeData.new(:data_type_string => "VARCHAR2(10)",
143
+ :oraver => ora80,
144
+ :data_type => :varchar2,
145
+ :charset_form => :implicit,
146
+ :nullable? => true,
147
+ :char_used? => false,
148
+ :char_size => 10,
149
+ :data_size => 10,
150
+ :precision => 0,
151
+ :scale => 0,
152
+ :fsprecision => 0,
153
+ :lfprecision => 0
154
+ ),
155
+ DatatypeData.new(:data_type_string => "VARCHAR2(10 CHAR)",
156
+ :oraver => ora90,
157
+ :data_type => :varchar2,
158
+ :charset_form => :implicit,
159
+ :nullable? => true,
160
+ :char_used? => true,
161
+ :char_size => 10,
162
+ :data_size => 10 * csem,
163
+ :precision => 0,
164
+ :scale => 0,
165
+ :fsprecision => 0,
166
+ :lfprecision => 0
167
+ ),
168
+ DatatypeData.new(:data_type_string => "NVARCHAR2(10)",
169
+ :oraver => ora80,
170
+ :data_type => :varchar2,
171
+ :charset_form => :nchar,
172
+ :nullable? => true,
173
+ :char_used? => true,
174
+ :char_size => 10,
175
+ :data_size => 10 * cfrm,
176
+ :precision => 0,
177
+ :scale => 0,
178
+ :fsprecision => 0,
179
+ :lfprecision => 0
180
+ ),
181
+ DatatypeData.new(:data_type_string => "RAW(10)",
182
+ :oraver => ora80,
183
+ :data_type => :raw,
184
+ :charset_form => nil,
185
+ :nullable? => true,
186
+ :char_used? => false,
187
+ :char_size => 0,
188
+ :data_size => 10,
189
+ :precision => 0,
190
+ :scale => 0,
191
+ :fsprecision => 0,
192
+ :lfprecision => 0
193
+ ),
194
+
195
+ # Skip tests for data_size of CLOB, NCLOB and BLOB
196
+ # because their values depend on how they are described.
197
+ #
198
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
199
+ # +----------------+-----------+
200
+ # | | data_size |
201
+ # +----------------+-----------+
202
+ # | implicitly(*1) | 4000 |
203
+ # | explicitly(*2) | 86 |
204
+ # +----------------+-----------+
205
+ #
206
+ # *1 explicitly described by column definition.
207
+ # *2 implicitly described by select list.
208
+ DatatypeData.new(:data_type_string => "CLOB",
209
+ :oraver => ora81,
210
+ :data_type => :clob,
211
+ :charset_form => :implicit,
212
+ :nullable? => true,
213
+ :char_used? => false,
214
+ :char_size => 0,
215
+ :data_size => :skip,
216
+ :precision => 0,
217
+ :scale => 0,
218
+ :fsprecision => 0,
219
+ :lfprecision => 0
220
+ ),
221
+ DatatypeData.new(:data_type_string => "NCLOB",
222
+ :oraver => ora81,
223
+ :data_type => :clob,
224
+ :charset_form => :nchar,
225
+ :nullable? => true,
226
+ :char_used? => false,
227
+ :char_size => 0,
228
+ :data_size => :skip,
229
+ :precision => 0,
230
+ :scale => 0,
231
+ :fsprecision => 0,
232
+ :lfprecision => 0
233
+ ),
234
+ DatatypeData.new(:data_type_string => "BLOB",
235
+ :oraver => ora80,
236
+ :data_type => :blob,
237
+ :charset_form => nil,
238
+ :nullable? => true,
239
+ :char_used? => false,
240
+ :char_size => 0,
241
+ :data_size => :skip,
242
+ :precision => 0,
243
+ :scale => 0,
244
+ :fsprecision => 0,
245
+ :lfprecision => 0
246
+ ),
247
+ DatatypeData.new(:data_type_string => "BFILE",
248
+ :oraver => ora80,
249
+ :data_type => :bfile,
250
+ :charset_form => nil,
251
+ :nullable? => true,
252
+ :char_used? => false,
253
+ :char_size => 0,
254
+ :data_size => 530,
255
+ :precision => 0,
256
+ :scale => 0,
257
+ :fsprecision => 0,
258
+ :lfprecision => 0
259
+ ),
260
+
261
+ # Skip tests for fsprecision and lfprecision for NUMBER and FLOAT
262
+ # because their values depend on how they are described.
263
+ #
264
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
265
+ # +-----------------------------+-------------+-------------+
266
+ # | | fsprecision | lfprecision |
267
+ # +----------------+------------+-------------+-------------+
268
+ # | NUMBER | implicitly | 129 | 0 |
269
+ # | | explicitly | 0 | 129 |
270
+ # +----------------+------------+-------------+-------------+
271
+ # | NUMBER(10) | implicitly | 0 | 10 |
272
+ # | | explicitly | 10 | 0 |
273
+ # +----------------+------------+-------------+-------------+
274
+ # | NUMBER(10,2) | implicitly | 2 | 10 |
275
+ # | | explicitly | 10 | 2 |
276
+ # +----------------+------------+-------------+-------------+
277
+ # | FLOAT | implicitly | 129 | 126 |
278
+ # | | explicitly | 126 | 129 |
279
+ # +----------------+------------+-------------+-------------+
280
+ # | FLOAT(10) | implicitly | 129 | 10 |
281
+ # | | explicitly | 10 | 129 |
282
+ # +----------------+------------+-------------+-------------+
283
+ DatatypeData.new(:data_type_string => "NUMBER",
284
+ :oraver => ora80,
285
+ :data_type => :number,
286
+ :charset_form => nil,
287
+ :nullable? => true,
288
+ :char_used? => false,
289
+ :char_size => 0,
290
+ :data_size => 22,
291
+ :precision => 0,
292
+ :scale => $oracle_version > ora90 ? -127 : 0,
293
+ :fsprecision => :skip,
294
+ :lfprecision => :skip
295
+ ),
296
+ DatatypeData.new(:data_type_string => "NUMBER(10)",
297
+ :oraver => ora80,
298
+ :data_type => :number,
299
+ :charset_form => nil,
300
+ :nullable? => true,
301
+ :char_used? => false,
302
+ :char_size => 0,
303
+ :data_size => 22,
304
+ :precision => 10,
305
+ :scale => 0,
306
+ :fsprecision => :skip,
307
+ :lfprecision => :skip
308
+ ),
309
+ DatatypeData.new(:data_type_string => "NUMBER(10,2)",
310
+ :oraver => ora80,
311
+ :data_type => :number,
312
+ :charset_form => nil,
313
+ :nullable? => true,
314
+ :char_used? => false,
315
+ :char_size => 0,
316
+ :data_size => 22,
317
+ :precision => 10,
318
+ :scale => 2,
319
+ :fsprecision => :skip,
320
+ :lfprecision => :skip
321
+ ),
322
+ DatatypeData.new(:data_type_string => "FLOAT",
323
+ :oraver => ora80,
324
+ :data_type => :number,
325
+ :charset_form => nil,
326
+ :nullable? => true,
327
+ :char_used? => false,
328
+ :char_size => 0,
329
+ :data_size => 22,
330
+ :precision => 126,
331
+ :scale => -127,
332
+ :fsprecision => :skip,
333
+ :lfprecision => :skip
334
+ ),
335
+ DatatypeData.new(:data_type_string => "FLOAT(10)",
336
+ :oraver => ora80,
337
+ :data_type => :number,
338
+ :charset_form => nil,
339
+ :nullable? => true,
340
+ :char_used? => false,
341
+ :char_size => 0,
342
+ :data_size => 22,
343
+ :precision => 10,
344
+ :scale => -127,
345
+ :fsprecision => :skip,
346
+ :lfprecision => :skip
347
+ ),
348
+ DatatypeData.new(:data_type_string => "BINARY_FLOAT",
349
+ :oraver => ora101,
350
+ :data_type => :binary_float,
351
+ :charset_form => nil,
352
+ :nullable? => true,
353
+ :char_used? => false,
354
+ :char_size => 0,
355
+ :data_size => 4,
356
+ :precision => 0,
357
+ :scale => 0,
358
+ :fsprecision => 0,
359
+ :lfprecision => 0
360
+ ),
361
+ DatatypeData.new(:data_type_string => "BINARY_DOUBLE",
362
+ :oraver => ora101,
363
+ :data_type => :binary_double,
364
+ :charset_form => nil,
365
+ :nullable? => true,
366
+ :char_used? => false,
367
+ :char_size => 0,
368
+ :data_size => 8,
369
+ :precision => 0,
370
+ :scale => 0,
371
+ :fsprecision => 0,
372
+ :lfprecision => 0
373
+ ),
374
+ DatatypeData.new(:data_type_string => "DATE",
375
+ :oraver => ora80,
376
+ :data_type => :date,
377
+ :charset_form => nil,
378
+ :nullable? => true,
379
+ :char_used? => false,
380
+ :char_size => 0,
381
+ :data_size => 7,
382
+ :precision => 0,
383
+ :scale => 0,
384
+ :fsprecision => 0,
385
+ :lfprecision => 0
386
+ ),
387
+
388
+ # Skip tests for precision and lfprecision for TIMESTAMP
389
+ # because their values depend on how they are described.
390
+ #
391
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
392
+ # +------------------------------------------------+-----------+-------------+
393
+ # | | precision | lfprecision |
394
+ # +-----------------------------------+------------+-----------+-------------+
395
+ # | TIMESTAMP | implicitly | 0 | 0 |
396
+ # | | explicitly | 6 | 6 |
397
+ # +-----------------------------------+------------+-----------+-------------+
398
+ # | TIMESTAMP(9) | implicitly | 0 | 0 |
399
+ # | | explicitly | 9 | 9 |
400
+ # +-----------------------------------+------------+-----------+-------------+
401
+ # | TIMESTAMP WITH TIME ZONE | implicitly | 0 | 0 |
402
+ # | | explicitly | 6 | 6 |
403
+ # +-----------------------------------+------------+-----------+-------------+
404
+ # | TIMESTAMP(9) WITH TIME ZONE | implicitly | 0 | 0 |
405
+ # | | explicitly | 9 | 9 |
406
+ # +-----------------------------------+------------+-----------+-------------+
407
+ # | TIMESTAMP WITH LOCAL TIME ZONE | implicitly | 0 | 0 |
408
+ # | | explicitly | 6 | 6 |
409
+ # +-----------------------------------+------------+-----------+-------------+
410
+ # | TIMESTAMP(9) WITH LOCAL TIME ZONE | implicitly | 0 | 0 |
411
+ # | | explicitly | 9 | 9 |
412
+ # +-----------------------------------+------------+-----------+-------------+
413
+ DatatypeData.new(:data_type_string => "TIMESTAMP",
414
+ :oraver => ora90,
415
+ :data_type => :timestamp,
416
+ :charset_form => nil,
417
+ :nullable? => true,
418
+ :char_used? => false,
419
+ :char_size => 0,
420
+ :data_size => 11,
421
+ :precision => :skip,
422
+ :scale => 6,
423
+ :fsprecision => 6,
424
+ :lfprecision => :skip
425
+ ),
426
+ DatatypeData.new(:data_type_string => "TIMESTAMP(9)",
427
+ :oraver => ora90,
428
+ :data_type => :timestamp,
429
+ :charset_form => nil,
430
+ :nullable? => true,
431
+ :char_used? => false,
432
+ :char_size => 0,
433
+ :data_size => 11,
434
+ :precision => :skip,
435
+ :scale => 9,
436
+ :fsprecision => 9,
437
+ :lfprecision => :skip
438
+ ),
439
+ DatatypeData.new(:data_type_string => "TIMESTAMP WITH TIME ZONE",
440
+ :oraver => ora90,
441
+ :data_type => :timestamp_tz,
442
+ :charset_form => nil,
443
+ :nullable? => true,
444
+ :char_used? => false,
445
+ :char_size => 0,
446
+ :data_size => 13,
447
+ :precision => :skip,
448
+ :scale => 6,
449
+ :fsprecision => 6,
450
+ :lfprecision => :skip
451
+ ),
452
+ DatatypeData.new(:data_type_string => "TIMESTAMP(9) WITH TIME ZONE",
453
+ :oraver => ora90,
454
+ :data_type => :timestamp_tz,
455
+ :charset_form => nil,
456
+ :nullable? => true,
457
+ :char_used? => false,
458
+ :char_size => 0,
459
+ :data_size => 13,
460
+ :precision => :skip,
461
+ :scale => 9,
462
+ :fsprecision => 9,
463
+ :lfprecision => :skip
464
+ ),
465
+ DatatypeData.new(:data_type_string => "TIMESTAMP WITH LOCAL TIME ZONE",
466
+ :oraver => ora90,
467
+ :data_type => :timestamp_ltz,
468
+ :charset_form => nil,
469
+ :nullable? => true,
470
+ :char_used? => false,
471
+ :char_size => 0,
472
+ :data_size => 11,
473
+ :precision => :skip,
474
+ :scale => 6,
475
+ :fsprecision => 6,
476
+ :lfprecision => :skip
477
+ ),
478
+ DatatypeData.new(:data_type_string => "TIMESTAMP(9) WITH LOCAL TIME ZONE",
479
+ :oraver => ora90,
480
+ :data_type => :timestamp_ltz,
481
+ :charset_form => nil,
482
+ :nullable? => true,
483
+ :char_used? => false,
484
+ :char_size => 0,
485
+ :data_size => 11,
486
+ :precision => :skip,
487
+ :scale => 9,
488
+ :fsprecision => 9,
489
+ :lfprecision => :skip
490
+ ),
491
+
492
+ # Skip tsets for scale and fsprecision for INTERVAL YEAR TO MONTH
493
+ # because their values depend on how they are described.
494
+ #
495
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
496
+ # +-------------------------------------------+-----------+-------------+
497
+ # | | scale | fsprecision |
498
+ # +------------------------------+------------+-----------+-------------+
499
+ # | INTERVAL YEAR TO MONTH | implicitly | 0 | 0 |
500
+ # | | explicitly | 2 | 2 |
501
+ # +------------------------------+------------+-----------+-------------+
502
+ # | INTERVAL YEAR(4) TO MONTH | implicitly | 0 | 0 |
503
+ # | | explicitly | 4 | 4 |
504
+ # +------------------------------+------------+-----------+-------------+
505
+ DatatypeData.new(:data_type_string => "INTERVAL YEAR TO MONTH",
506
+ :oraver => ora90,
507
+ :data_type => :interval_ym,
508
+ :charset_form => nil,
509
+ :nullable? => true,
510
+ :char_used? => false,
511
+ :char_size => 0,
512
+ :data_size => 5,
513
+ :precision => 2,
514
+ :scale => :skip,
515
+ :fsprecision => :skip,
516
+ :lfprecision => 2
517
+ ),
518
+ DatatypeData.new(:data_type_string => "INTERVAL YEAR(4) TO MONTH",
519
+ :oraver => ora90,
520
+ :data_type => :interval_ym,
521
+ :charset_form => nil,
522
+ :nullable? => true,
523
+ :char_used? => false,
524
+ :char_size => 0,
525
+ :data_size => 5,
526
+ :precision => 4,
527
+ :scale => :skip,
528
+ :fsprecision => :skip,
529
+ :lfprecision => 4
530
+ ),
531
+ # Skip tests for precision and scale for INTERVAL DAY TO SECOND
532
+ # because their values depend on how they are described.
533
+ #
534
+ # Oracle 10g XE 10.2.0.1.0 on Linux:
535
+ # +-------------------------------------------+-----------+-----------+
536
+ # | | precision | scale |
537
+ # +------------------------------+------------+-----------+-----------+
538
+ # | INTERVAL DAY TO SECOND | implicitly | 2 | 6 |
539
+ # | | explicitly | 6 | 2 |
540
+ # +------------------------------+------------+-----------+-----------+
541
+ # | INTERVAL DAY(4) TO SECOND(9) | implicitly | 4 | 9 |
542
+ # | | explicitly | 9 | 4 |
543
+ # +------------------------------+------------+-----------+-----------+
544
+ DatatypeData.new(:data_type_string => "INTERVAL DAY TO SECOND",
545
+ :oraver => ora90,
546
+ :data_type => :interval_ds,
547
+ :charset_form => nil,
548
+ :nullable? => true,
549
+ :char_used? => false,
550
+ :char_size => 0,
551
+ :data_size => 11,
552
+ :precision => :skip,
553
+ :scale => :skip,
554
+ :fsprecision => 6,
555
+ :lfprecision => 2
556
+ ),
557
+ DatatypeData.new(:data_type_string => "INTERVAL DAY(4) TO SECOND(9)",
558
+ :oraver => ora90,
559
+ :data_type => :interval_ds,
560
+ :charset_form => nil,
561
+ :nullable? => true,
562
+ :char_used? => false,
563
+ :char_size => 0,
564
+ :data_size => 11,
565
+ :precision => :skip,
566
+ :scale => :skip,
567
+ :fsprecision => 9,
568
+ :lfprecision => 4
569
+ ),
570
+ # Object Types
571
+ DatatypeData.new(:data_type_string => "MDSYS.SDO_GEOMETRY",
572
+ :oraver => ora101,
573
+ :data_type => :named_type,
574
+ :charset_form => nil,
575
+ :nullable? => true,
576
+ :char_used? => false,
577
+ :char_size => 0,
578
+ :data_size => :skip, # 1 when explicitly, 2000 when implicitly.
579
+ :precision => 0,
580
+ :scale => 0,
581
+ :fsprecision => 0,
582
+ :lfprecision => 0
583
+ ),
584
+ =begin # uncomment after ref is supported.
585
+ DatatypeData.new(:data_type_string => "REF MDSYS.SDO_GEOMETRY",
586
+ :oraver => ora101,
587
+ :data_type => :ref,
588
+ :charset_form => nil,
589
+ :nullable? => true,
590
+ :char_used? => false,
591
+ :char_size => 0,
592
+ :data_size => :skip,
593
+ :precision => 0,
594
+ :scale => 0,
595
+ :fsprecision => 0,
596
+ :lfprecision => 0,
597
+ ),
598
+ =end
599
+ ]
600
+
236
601
  def test_error_describe_table
237
602
  drop_table('test_table')
238
603
  begin
@@ -254,4 +619,791 @@ EOS
254
619
  end
255
620
  end
256
621
 
622
+ def assert_object_id(object_name, object_id, owner_name = nil)
623
+ owner_name ||= @conn.username
624
+ expected_val = @conn.select_one('select object_id from all_objects where owner = :1 and object_name = :2', owner_name, object_name)[0]
625
+ assert_equal(expected_val, object_id, "ID of #{object_name}")
626
+ end
627
+
628
+ def test_table_metadata
629
+ drop_table('test_table')
630
+
631
+ # Relational table
632
+ @conn.exec(<<-EOS)
633
+ CREATE TABLE test_table (col1 number(38,0), col2 varchar2(60))
634
+ STORAGE (
635
+ INITIAL 100k
636
+ NEXT 100k
637
+ MINEXTENTS 1
638
+ MAXEXTENTS UNLIMITED
639
+ PCTINCREASE 0)
640
+ EOS
641
+ [
642
+ @conn.describe_any('test_table'),
643
+ @conn.describe_table('test_table'),
644
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
645
+ obj.obj_name == 'TEST_TABLE'
646
+ end
647
+ ].each do |desc|
648
+ assert_object_id('TEST_TABLE', desc.obj_id)
649
+ assert_equal('TEST_TABLE', desc.obj_name)
650
+ assert_equal(@conn.username, desc.obj_schema)
651
+ assert_equal(2, desc.num_cols)
652
+ assert_nil(desc.type_metadata)
653
+ assert_equal(false, desc.is_temporary?)
654
+ assert_equal(false, desc.is_typed?)
655
+ assert_nil(desc.duration)
656
+ assert_not_nil(desc.dba)
657
+ assert_not_nil(desc.tablespace)
658
+ assert_equal(false, desc.clustered?)
659
+ assert_equal(false, desc.partitioned?)
660
+ assert_equal(false, desc.index_only?)
661
+ assert_instance_of(Array, desc.columns)
662
+ assert_instance_of(OCI8::Metadata::Column, desc.columns[0])
663
+ end
664
+ drop_table('test_table')
665
+
666
+ # Transaction-specific temporary table
667
+ @conn.exec(<<-EOS)
668
+ CREATE GLOBAL TEMPORARY TABLE test_table (col1 number(38,0), col2 varchar2(60))
669
+ EOS
670
+ [
671
+ @conn.describe_any('test_table'),
672
+ @conn.describe_table('test_table'),
673
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
674
+ obj.obj_name == 'TEST_TABLE'
675
+ end
676
+ ].each do |desc|
677
+ assert_object_id('TEST_TABLE', desc.obj_id)
678
+ assert_equal('TEST_TABLE', desc.obj_name)
679
+ assert_equal(@conn.username, desc.obj_schema)
680
+ assert_equal(2, desc.num_cols)
681
+ assert_nil(desc.type_metadata)
682
+ assert_equal(true, desc.is_temporary?)
683
+ assert_equal(false, desc.is_typed?)
684
+ assert_equal(:transaction, desc.duration)
685
+ assert_not_nil(desc.dba)
686
+ assert_not_nil(desc.tablespace)
687
+ assert_equal(false, desc.clustered?)
688
+ assert_equal(false, desc.partitioned?)
689
+ assert_equal(false, desc.index_only?)
690
+ assert_instance_of(Array, desc.columns)
691
+ assert_instance_of(OCI8::Metadata::Column, desc.columns[0])
692
+ end
693
+ drop_table('test_table')
694
+
695
+ # Session-specific temporary table
696
+ @conn.exec(<<-EOS)
697
+ CREATE GLOBAL TEMPORARY TABLE test_table (col1 number(38,0), col2 varchar2(60))
698
+ ON COMMIT PRESERVE ROWS
699
+ EOS
700
+ [
701
+ @conn.describe_any('test_table'),
702
+ @conn.describe_table('test_table'),
703
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
704
+ obj.obj_name == 'TEST_TABLE'
705
+ end
706
+ ].each do |desc|
707
+ assert_object_id('TEST_TABLE', desc.obj_id)
708
+ assert_equal('TEST_TABLE', desc.obj_name)
709
+ assert_equal(@conn.username, desc.obj_schema)
710
+ assert_equal(2, desc.num_cols)
711
+ assert_nil(desc.type_metadata)
712
+ assert_equal(true, desc.is_temporary?)
713
+ assert_equal(false, desc.is_typed?)
714
+ assert_equal(:session, desc.duration)
715
+ assert_not_nil(desc.dba)
716
+ assert_not_nil(desc.tablespace)
717
+ assert_equal(false, desc.clustered?)
718
+ assert_equal(false, desc.partitioned?)
719
+ assert_equal(false, desc.index_only?)
720
+ assert_instance_of(Array, desc.columns)
721
+ assert_instance_of(OCI8::Metadata::Column, desc.columns[0])
722
+ end
723
+ drop_table('test_table')
724
+
725
+ # Object table
726
+ @conn.exec(<<-EOS)
727
+ CREATE OR REPLACE TYPE test_type AS OBJECT (col1 number(38,0), col2 varchar2(60))
728
+ EOS
729
+ @conn.exec(<<-EOS)
730
+ CREATE TABLE test_table OF test_type
731
+ EOS
732
+ [
733
+ @conn.describe_any('test_table'),
734
+ @conn.describe_table('test_table'),
735
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
736
+ obj.obj_name == 'TEST_TABLE'
737
+ end
738
+ ].each do |desc|
739
+ assert_object_id('TEST_TABLE', desc.obj_id)
740
+ assert_equal('TEST_TABLE', desc.obj_name)
741
+ assert_equal(@conn.username, desc.obj_schema)
742
+ assert_equal(2, desc.num_cols)
743
+ assert_instance_of(OCI8::Metadata::Type, desc.type_metadata)
744
+ assert_equal(false, desc.is_temporary?)
745
+ assert_equal(true, desc.is_typed?)
746
+ assert_equal(nil, desc.duration)
747
+ assert_not_nil(desc.dba)
748
+ assert_not_nil(desc.tablespace)
749
+ assert_equal(false, desc.clustered?)
750
+ assert_equal(false, desc.partitioned?)
751
+ assert_equal(false, desc.index_only?)
752
+ assert_instance_of(Array, desc.columns)
753
+ assert_instance_of(OCI8::Metadata::Column, desc.columns[0])
754
+ end
755
+ drop_table('test_table')
756
+ @conn.exec('DROP TYPE TEST_TYPE')
757
+
758
+ # Index-organized table
759
+ @conn.exec(<<-EOS)
760
+ CREATE TABLE test_table (col1 number(38,0) PRIMARY KEY, col2 varchar2(60))
761
+ ORGANIZATION INDEX
762
+ EOS
763
+ [
764
+ @conn.describe_any('test_table'),
765
+ @conn.describe_table('test_table'),
766
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
767
+ obj.obj_name == 'TEST_TABLE'
768
+ end
769
+ ].each do |desc|
770
+ assert_object_id('TEST_TABLE', desc.obj_id)
771
+ assert_equal('TEST_TABLE', desc.obj_name)
772
+ assert_equal(@conn.username, desc.obj_schema)
773
+ assert_equal(2, desc.num_cols)
774
+ assert_nil(desc.type_metadata)
775
+ assert_equal(false, desc.is_temporary?)
776
+ assert_equal(false, desc.is_typed?)
777
+ assert_equal(nil, desc.duration)
778
+ assert_not_nil(desc.dba)
779
+ assert_not_nil(desc.tablespace)
780
+ assert_equal(false, desc.clustered?)
781
+ assert_equal(false, desc.partitioned?)
782
+ assert_equal(true, desc.index_only?)
783
+ assert_instance_of(Array, desc.columns)
784
+ assert_instance_of(OCI8::Metadata::Column, desc.columns[0])
785
+ end
786
+ drop_table('test_table')
787
+ end # test_table_metadata
788
+
789
+ def test_view_metadata
790
+ @conn.exec('CREATE OR REPLACE VIEW test_view as SELECT * FROM tab')
791
+ [
792
+ @conn.describe_any('test_view'),
793
+ @conn.describe_view('test_view'),
794
+ @conn.describe_table('test_view'),
795
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
796
+ obj.obj_name == 'TEST_VIEW'
797
+ end
798
+ ].each do |desc|
799
+ assert_object_id('TEST_VIEW', desc.obj_id)
800
+ assert_equal('TEST_VIEW', desc.obj_name)
801
+ assert_equal(@conn.username, desc.obj_schema)
802
+ assert_equal(3, desc.num_cols)
803
+ assert_instance_of(Array, desc.columns)
804
+ assert_instance_of(OCI8::Metadata::Column, desc.columns[0])
805
+ end
806
+ @conn.exec('DROP VIEW test_view')
807
+ end # test_view_metadata
808
+
809
+ def test_procedure_metadata
810
+ @conn.exec(<<-EOS)
811
+ CREATE OR REPLACE PROCEDURE test_proc(arg1 IN INTEGER, arg2 OUT varchar2) IS
812
+ BEGIN
813
+ NULL;
814
+ END;
815
+ EOS
816
+ [
817
+ @conn.describe_any('test_proc'),
818
+ @conn.describe_procedure('test_proc'),
819
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
820
+ obj.obj_name == 'TEST_PROC'
821
+ end
822
+ ].each do |desc|
823
+ assert_instance_of(OCI8::Metadata::Procedure, desc)
824
+ assert_object_id('TEST_PROC', desc.obj_id)
825
+ assert_equal('TEST_PROC', desc.obj_name)
826
+ assert_equal('TEST_PROC', desc.name)
827
+ assert_equal(@conn.username, desc.obj_schema)
828
+ assert_equal(false, desc.is_invoker_rights?)
829
+ assert_equal(nil, desc.overload_id)
830
+ assert_instance_of(Array, desc.arguments)
831
+ assert_equal(2, desc.arguments.length)
832
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
833
+ end
834
+
835
+ @conn.exec(<<-EOS)
836
+ CREATE OR REPLACE PROCEDURE test_proc(arg1 IN INTEGER, arg2 OUT varchar2)
837
+ AUTHID CURRENT_USER
838
+ IS
839
+ BEGIN
840
+ NULL;
841
+ END;
842
+ EOS
843
+ [
844
+ @conn.describe_any('test_proc'),
845
+ @conn.describe_procedure('test_proc'),
846
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
847
+ obj.obj_name == 'TEST_PROC'
848
+ end
849
+ ].each do |desc|
850
+ assert_instance_of(OCI8::Metadata::Procedure, desc)
851
+ assert_object_id('TEST_PROC', desc.obj_id)
852
+ assert_equal('TEST_PROC', desc.obj_name)
853
+ assert_equal(@conn.username, desc.obj_schema)
854
+ assert_equal(true, desc.is_invoker_rights?)
855
+ assert_equal(nil, desc.overload_id)
856
+ assert_instance_of(Array, desc.arguments)
857
+ assert_equal(2, desc.arguments.length)
858
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
859
+ end
860
+
861
+ @conn.exec('DROP PROCEDURE test_proc');
862
+
863
+ @conn.exec(<<-EOS)
864
+ CREATE OR REPLACE PACKAGE TEST_PKG IS
865
+ PROCEDURE test_proc(arg1 IN INTEGER, arg2 OUT varchar2);
866
+ END;
867
+ EOS
868
+ desc = @conn.describe_package('test_pkg').subprograms[0]
869
+ assert_instance_of(OCI8::Metadata::Procedure, desc)
870
+ assert_equal(nil, desc.obj_id)
871
+ assert_equal('TEST_PROC', desc.obj_name)
872
+ assert_equal(nil, desc.obj_schema)
873
+ assert_equal(false, desc.is_invoker_rights?)
874
+ assert_equal(0, desc.overload_id)
875
+ assert_instance_of(Array, desc.arguments)
876
+ assert_equal(2, desc.arguments.length)
877
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
878
+
879
+ @conn.exec(<<-EOS)
880
+ CREATE OR REPLACE PACKAGE TEST_PKG AUTHID CURRENT_USER
881
+ IS
882
+ PROCEDURE test_proc(arg1 IN INTEGER, arg2 OUT varchar2);
883
+ PROCEDURE test_proc(arg1 IN INTEGER);
884
+ END;
885
+ EOS
886
+ desc = @conn.describe_package('test_pkg').subprograms
887
+ assert_instance_of(OCI8::Metadata::Procedure, desc[0])
888
+ assert_equal(nil, desc[0].obj_id)
889
+ assert_equal('TEST_PROC', desc[0].obj_name)
890
+ assert_equal(nil, desc[0].obj_schema)
891
+ assert_equal(true, desc[0].is_invoker_rights?)
892
+ assert_equal(2, desc[0].overload_id)
893
+ assert_instance_of(Array, desc[0].arguments)
894
+ assert_equal(2, desc[0].arguments.length)
895
+ assert_instance_of(OCI8::Metadata::Argument, desc[0].arguments[0])
896
+
897
+ descs = @conn.describe_package('test_pkg').subprograms
898
+ assert_instance_of(OCI8::Metadata::Procedure, desc[1])
899
+ assert_equal(nil, desc[1].obj_id)
900
+ assert_equal('TEST_PROC', desc[1].obj_name)
901
+ assert_equal(nil, desc[1].obj_schema)
902
+ assert_equal(true, desc[1].is_invoker_rights?)
903
+ assert_equal(1, desc[1].overload_id)
904
+ assert_instance_of(Array, desc[1].arguments)
905
+ assert_equal(1, desc[1].arguments.length)
906
+ assert_instance_of(OCI8::Metadata::Argument, desc[1].arguments[0])
907
+ end # test_procedure_metadata
908
+
909
+ def test_function_metadata
910
+ @conn.exec(<<-EOS)
911
+ CREATE OR REPLACE FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER IS
912
+ BEGIN
913
+ RETURN arg1;
914
+ END;
915
+ EOS
916
+ [
917
+ @conn.describe_any('test_func'),
918
+ @conn.describe_function('test_func'),
919
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
920
+ obj.obj_name == 'TEST_FUNC'
921
+ end
922
+ ].each do |desc|
923
+ assert_instance_of(OCI8::Metadata::Function, desc)
924
+ assert_object_id('TEST_FUNC', desc.obj_id)
925
+ assert_equal('TEST_FUNC', desc.obj_name)
926
+ assert_equal('TEST_FUNC', desc.name)
927
+ assert_equal(@conn.username, desc.obj_schema)
928
+ assert_equal(false, desc.is_invoker_rights?)
929
+ assert_equal(nil, desc.overload_id)
930
+ assert_instance_of(Array, desc.arguments)
931
+ assert_equal(3, desc.arguments.length)
932
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
933
+ end
934
+
935
+ @conn.exec(<<-EOS)
936
+ CREATE OR REPLACE FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER
937
+ AUTHID CURRENT_USER
938
+ IS
939
+ BEGIN
940
+ RETURN arg1;
941
+ END;
942
+ EOS
943
+ [
944
+ @conn.describe_any('test_func'),
945
+ @conn.describe_function('test_func'),
946
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
947
+ obj.obj_name == 'TEST_FUNC'
948
+ end
949
+ ].each do |desc|
950
+ assert_instance_of(OCI8::Metadata::Function, desc)
951
+ assert_object_id('TEST_FUNC', desc.obj_id)
952
+ assert_equal('TEST_FUNC', desc.obj_name)
953
+ assert_equal(@conn.username, desc.obj_schema)
954
+ assert_equal(true, desc.is_invoker_rights?)
955
+ assert_equal(nil, desc.overload_id)
956
+ assert_instance_of(Array, desc.arguments)
957
+ assert_equal(3, desc.arguments.length)
958
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
959
+ end
960
+
961
+ @conn.exec('DROP FUNCTION test_func');
962
+
963
+ @conn.exec(<<-EOS)
964
+ CREATE OR REPLACE PACKAGE TEST_PKG IS
965
+ FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER;
966
+ END;
967
+ EOS
968
+ desc = @conn.describe_package('test_pkg').subprograms[0]
969
+ assert_instance_of(OCI8::Metadata::Function, desc)
970
+ assert_equal(nil, desc.obj_id)
971
+ assert_equal('TEST_FUNC', desc.obj_name)
972
+ assert_equal(nil, desc.obj_schema)
973
+ assert_equal(false, desc.is_invoker_rights?)
974
+ assert_equal(0, desc.overload_id)
975
+ assert_instance_of(Array, desc.arguments)
976
+ assert_equal(3, desc.arguments.length)
977
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
978
+
979
+ @conn.exec(<<-EOS)
980
+ CREATE OR REPLACE PACKAGE TEST_PKG AUTHID CURRENT_USER
981
+ IS
982
+ FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER;
983
+ FUNCTION test_func(arg1 IN INTEGER) RETURN NUMBER;
984
+ END;
985
+ EOS
986
+ desc = @conn.describe_package('test_pkg').subprograms
987
+ assert_instance_of(OCI8::Metadata::Function, desc[0])
988
+ assert_equal(nil, desc[0].obj_id)
989
+ assert_equal('TEST_FUNC', desc[0].obj_name)
990
+ assert_equal(nil, desc[0].obj_schema)
991
+ assert_equal(true, desc[0].is_invoker_rights?)
992
+ assert_equal(2, desc[0].overload_id)
993
+ assert_instance_of(Array, desc[0].arguments)
994
+ assert_equal(3, desc[0].arguments.length)
995
+ assert_instance_of(OCI8::Metadata::Argument, desc[0].arguments[0])
996
+
997
+ descs = @conn.describe_package('test_pkg').subprograms
998
+ assert_instance_of(OCI8::Metadata::Function, desc[1])
999
+ assert_equal(nil, desc[1].obj_id)
1000
+ assert_equal('TEST_FUNC', desc[1].obj_name)
1001
+ assert_equal(nil, desc[1].obj_schema)
1002
+ assert_equal(true, desc[1].is_invoker_rights?)
1003
+ assert_equal(1, desc[1].overload_id)
1004
+ assert_instance_of(Array, desc[1].arguments)
1005
+ assert_equal(2, desc[1].arguments.length)
1006
+ assert_instance_of(OCI8::Metadata::Argument, desc[1].arguments[0])
1007
+ end # test_function_metadata
1008
+
1009
+ def test_package_metadata
1010
+ @conn.exec(<<-EOS)
1011
+ CREATE OR REPLACE PACKAGE TEST_PKG IS
1012
+ FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER;
1013
+ END;
1014
+ EOS
1015
+ [
1016
+ @conn.describe_any('test_pkg'),
1017
+ @conn.describe_package('test_pkg'),
1018
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1019
+ obj.obj_name == 'TEST_PKG'
1020
+ end
1021
+ ].each do |desc|
1022
+ assert_instance_of(OCI8::Metadata::Package, desc)
1023
+ assert_object_id('TEST_PKG', desc.obj_id)
1024
+ assert_equal('TEST_PKG', desc.obj_name)
1025
+ assert_equal(@conn.username, desc.obj_schema)
1026
+ assert_equal(false, desc.is_invoker_rights?)
1027
+ assert_instance_of(Array, desc.subprograms)
1028
+ assert_equal(1, desc.subprograms.length)
1029
+ assert_instance_of(OCI8::Metadata::Function, desc.subprograms[0])
1030
+ end
1031
+
1032
+ @conn.exec(<<-EOS)
1033
+ CREATE OR REPLACE PACKAGE TEST_PKG AUTHID CURRENT_USER IS
1034
+ PROCEDURE test_proc(arg1 IN INTEGER, arg2 OUT varchar2);
1035
+ END;
1036
+ EOS
1037
+ [
1038
+ @conn.describe_any('test_pkg'),
1039
+ @conn.describe_package('test_pkg'),
1040
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1041
+ obj.obj_name == 'TEST_PKG'
1042
+ end
1043
+ ].each do |desc|
1044
+ assert_instance_of(OCI8::Metadata::Package, desc)
1045
+ assert_object_id('TEST_PKG', desc.obj_id)
1046
+ assert_equal('TEST_PKG', desc.obj_name)
1047
+ assert_equal(@conn.username, desc.obj_schema)
1048
+ assert_equal(true, desc.is_invoker_rights?)
1049
+ assert_instance_of(Array, desc.subprograms)
1050
+ assert_equal(1, desc.subprograms.length)
1051
+ assert_instance_of(OCI8::Metadata::Procedure, desc.subprograms[0])
1052
+ end
1053
+ end # test_package_metadata
1054
+
1055
+ def test_type_metadata
1056
+ drop_type('TEST_TYPE_ORDER_METHOD')
1057
+ drop_type('TEST_TYPE_MAP_METHOD')
1058
+ drop_type('TEST_TYPE_HAS_BFILE')
1059
+ drop_type('TEST_TYPE_HAS_BLOB')
1060
+ drop_type('TEST_TYPE_HAS_NCLOB')
1061
+ drop_type('TEST_TYPE_HAS_CLOB')
1062
+ drop_type('TEST_TYPE_INCOMPLETE')
1063
+ drop_type('TEST_TYPE_GRANDCHILD')
1064
+ drop_type('TEST_TYPE_VARRAY')
1065
+ drop_type('TEST_TYPE_NESTEAD_TABLE')
1066
+ drop_type('TEST_TYPE_CHILD')
1067
+ drop_type('TEST_TYPE_PARENT')
1068
+ expected_values = []
1069
+
1070
+ @conn.exec(<<-EOS)
1071
+ CREATE TYPE test_type_parent AS OBJECT (
1072
+ col1 number(38,0),
1073
+ col2 varchar2(60)
1074
+ )
1075
+ NOT INSTANTIABLE
1076
+ NOT FINAL
1077
+ EOS
1078
+ expected_values << {
1079
+ :obj_name => 'TEST_TYPE_PARENT',
1080
+ :typecode => :named_type,
1081
+ :collection_typecode => nil,
1082
+ :is_incomplete_type? => false,
1083
+ :is_system_type? => false,
1084
+ :is_predefined_type? => false,
1085
+ :is_transient_type? => false,
1086
+ :is_system_generated_type? => false,
1087
+ :has_nested_table? => false,
1088
+ :has_lob? => false,
1089
+ :has_file? => false,
1090
+ :collection_element => nil,
1091
+ :num_type_attrs => 2,
1092
+ :num_type_methods => 0,
1093
+ :map_method => nil,
1094
+ :order_method => nil,
1095
+ :is_invoker_rights? => false,
1096
+ :is_final_type? => false,
1097
+ :is_instantiable_type? => false,
1098
+ :is_subtype? => false,
1099
+ :supertype_schema_name => nil,
1100
+ :supertype_name => nil,
1101
+ :type_attrs => [:array, 2, OCI8::Metadata::TypeAttr],
1102
+ :type_methods => [:array, 0],
1103
+ }
1104
+ @conn.exec(<<-EOS)
1105
+ CREATE TYPE test_type_child UNDER test_type_parent (
1106
+ lob BLOB
1107
+ )
1108
+ NOT FINAL
1109
+ EOS
1110
+ expected_values << {
1111
+ :obj_name => 'TEST_TYPE_CHILD',
1112
+ :typecode => :named_type,
1113
+ :collection_typecode => nil,
1114
+ :is_incomplete_type? => false,
1115
+ :is_system_type? => false,
1116
+ :is_predefined_type? => false,
1117
+ :is_transient_type? => false,
1118
+ :is_system_generated_type? => false,
1119
+ :has_nested_table? => false,
1120
+ :has_lob? => true,
1121
+ :has_file? => false,
1122
+ :collection_element => nil,
1123
+ :num_type_attrs => 3,
1124
+ :num_type_methods => 0,
1125
+ :map_method => nil,
1126
+ :order_method => nil,
1127
+ :is_invoker_rights? => false,
1128
+ :is_final_type? => false,
1129
+ :is_instantiable_type? => true,
1130
+ :is_subtype? => true,
1131
+ :supertype_schema_name => @conn.username,
1132
+ :supertype_name => 'TEST_TYPE_PARENT',
1133
+ :type_attrs => [:array, 3, OCI8::Metadata::TypeAttr],
1134
+ :type_methods => [:array, 0],
1135
+ }
1136
+ @conn.exec(<<-EOS)
1137
+ CREATE TYPE test_type_nestead_table AS TABLE OF test_type_child
1138
+ EOS
1139
+ expected_values << {
1140
+ :obj_name => 'TEST_TYPE_NESTEAD_TABLE',
1141
+ :typecode => :named_collection,
1142
+ :collection_typecode => :table,
1143
+ :is_incomplete_type? => false,
1144
+ :is_system_type? => false,
1145
+ :is_predefined_type? => false,
1146
+ :is_transient_type? => false,
1147
+ :is_system_generated_type? => false,
1148
+ :has_nested_table? => true,
1149
+ :has_lob? => true,
1150
+ :has_file? => false,
1151
+ :collection_element => [:type, OCI8::Metadata::Collection],
1152
+ :num_type_attrs => 0,
1153
+ :num_type_methods => 0,
1154
+ :map_method => nil,
1155
+ :order_method => nil,
1156
+ :is_invoker_rights? => false,
1157
+ :is_final_type? => true,
1158
+ :is_instantiable_type? => true,
1159
+ :is_subtype? => false,
1160
+ :supertype_schema_name => nil,
1161
+ :supertype_name => nil,
1162
+ :type_attrs => [:array, 0],
1163
+ :type_methods => [:array, 0],
1164
+ }
1165
+ @conn.exec(<<-EOS)
1166
+ CREATE TYPE test_type_varray AS VARRAY(10) OF test_type_child
1167
+ EOS
1168
+ expected_values << {
1169
+ :obj_name => 'TEST_TYPE_VARRAY',
1170
+ :typecode => :named_collection,
1171
+ :collection_typecode => :varray,
1172
+ :is_incomplete_type? => false,
1173
+ :is_system_type? => false,
1174
+ :is_predefined_type? => false,
1175
+ :is_transient_type? => false,
1176
+ :is_system_generated_type? => false,
1177
+ :has_nested_table? => false,
1178
+ :has_lob? => true,
1179
+ :has_file? => false,
1180
+ :collection_element => [:type, OCI8::Metadata::Collection],
1181
+ :num_type_attrs => 0,
1182
+ :num_type_methods => 0,
1183
+ :map_method => nil,
1184
+ :order_method => nil,
1185
+ :is_invoker_rights? => false,
1186
+ :is_final_type? => true,
1187
+ :is_instantiable_type? => true,
1188
+ :is_subtype? => false,
1189
+ :supertype_schema_name => nil,
1190
+ :supertype_name => nil,
1191
+ :type_attrs => [:array, 0],
1192
+ :type_methods => [:array, 0],
1193
+ }
1194
+ @conn.exec(<<-EOS)
1195
+ CREATE TYPE test_type_grandchild UNDER test_type_child (
1196
+ table_column test_type_nestead_table,
1197
+ file_column BFILE
1198
+ )
1199
+ EOS
1200
+ expected_values << {
1201
+ :obj_name => 'TEST_TYPE_GRANDCHILD',
1202
+ :typecode => :named_type,
1203
+ :collection_typecode => nil,
1204
+ :is_incomplete_type? => false,
1205
+ :is_system_type? => false,
1206
+ :is_predefined_type? => false,
1207
+ :is_transient_type? => false,
1208
+ :is_system_generated_type? => false,
1209
+ :has_nested_table? => true,
1210
+ :has_lob? => true,
1211
+ :has_file? => true,
1212
+ :collection_element => nil,
1213
+ :num_type_attrs => 5,
1214
+ :num_type_methods => 0,
1215
+ :map_method => nil,
1216
+ :order_method => nil,
1217
+ :is_invoker_rights? => false,
1218
+ :is_final_type? => true,
1219
+ :is_instantiable_type? => true,
1220
+ :is_subtype? => true,
1221
+ :supertype_schema_name => @conn.username,
1222
+ :supertype_name => 'TEST_TYPE_CHILD',
1223
+ :type_attrs => [:array, 5, OCI8::Metadata::TypeAttr],
1224
+ :type_methods => [:array, 0],
1225
+ }
1226
+ @conn.exec(<<-EOS)
1227
+ CREATE TYPE test_type_incomplete
1228
+ EOS
1229
+ expected_values << {
1230
+ :obj_name => 'TEST_TYPE_INCOMPLETE',
1231
+ :typecode => :named_type,
1232
+ :collection_typecode => nil,
1233
+ :is_incomplete_type? => true,
1234
+ :is_system_type? => false,
1235
+ :is_predefined_type? => false,
1236
+ :is_transient_type? => false,
1237
+ :is_system_generated_type? => false,
1238
+ :has_nested_table? => false,
1239
+ :has_lob? => false,
1240
+ :has_file? => false,
1241
+ :collection_element => nil,
1242
+ :num_type_attrs => 0,
1243
+ :num_type_methods => 0,
1244
+ :map_method => nil,
1245
+ :order_method => nil,
1246
+ :is_invoker_rights? => false,
1247
+ :is_final_type? => true,
1248
+ :is_instantiable_type? => true,
1249
+ :is_subtype? => false,
1250
+ :supertype_schema_name => nil,
1251
+ :supertype_name => nil,
1252
+ :type_attrs => [:array, 0],
1253
+ :type_methods => [:array, 0],
1254
+ }
1255
+
1256
+ @conn.exec(<<-EOS)
1257
+ CREATE TYPE test_type_has_clob AS OBJECT (lob CLOB)
1258
+ EOS
1259
+ expected_values << {
1260
+ :obj_name => 'TEST_TYPE_HAS_CLOB',
1261
+ :has_lob? => true,
1262
+ :has_file? => false,
1263
+ }
1264
+ if $oracle_version >= OCI8::ORAVER_9_2
1265
+ @conn.exec(<<-EOS)
1266
+ CREATE TYPE test_type_has_nclob AS OBJECT (lob NCLOB)
1267
+ EOS
1268
+ expected_values << {
1269
+ :obj_name => 'TEST_TYPE_HAS_NCLOB',
1270
+ :has_lob? => true,
1271
+ :has_file? => false,
1272
+ }
1273
+ end
1274
+ @conn.exec(<<-EOS)
1275
+ CREATE TYPE test_type_has_blob AS OBJECT (lob BLOB)
1276
+ EOS
1277
+ expected_values << {
1278
+ :obj_name => 'TEST_TYPE_HAS_BLOB',
1279
+ :has_lob? => true,
1280
+ :has_file? => false,
1281
+ }
1282
+ @conn.exec(<<-EOS)
1283
+ CREATE TYPE test_type_has_bfile AS OBJECT (lob BFILE)
1284
+ EOS
1285
+ expected_values << {
1286
+ :obj_name => 'TEST_TYPE_HAS_BFILE',
1287
+ :has_lob? => false,
1288
+ :has_file? => true,
1289
+ }
1290
+ @conn.exec(<<-EOS)
1291
+ CREATE TYPE test_type_map_method AS OBJECT (
1292
+ x integer,
1293
+ y integer,
1294
+ MAP MEMBER FUNCTION area RETURN NUMBER
1295
+ )
1296
+ EOS
1297
+ expected_values << {
1298
+ :obj_name => 'TEST_TYPE_MAP_METHOD',
1299
+ :map_method => [:type, OCI8::Metadata::TypeMethod],
1300
+ :order_method => nil,
1301
+ }
1302
+ @conn.exec(<<-EOS)
1303
+ CREATE TYPE test_type_order_method AS OBJECT (
1304
+ x integer,
1305
+ y integer,
1306
+ ORDER MEMBER FUNCTION match(l test_type_order_method) RETURN INTEGER
1307
+ )
1308
+ EOS
1309
+ expected_values << {
1310
+ :obj_name => 'TEST_TYPE_ORDER_METHOD',
1311
+ :map_method => nil,
1312
+ :order_method => [:type, OCI8::Metadata::TypeMethod],
1313
+ }
1314
+
1315
+ expected_values.each do |elem|
1316
+ [
1317
+ @conn.describe_any(elem[:obj_name]),
1318
+ @conn.describe_type(elem[:obj_name]),
1319
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1320
+ obj.obj_name == elem[:obj_name]
1321
+ end,
1322
+ ].each do |desc|
1323
+ assert_object_id(elem[:obj_name], desc.obj_id)
1324
+ assert_equal(@conn.username, desc.obj_schema)
1325
+ assert_equal(elem[:obj_name], desc.name)
1326
+ assert_equal(@conn.username, desc.schema_name)
1327
+
1328
+ elem.each do |key, val|
1329
+ msg = elem[:obj_name] + '.' + key.to_s
1330
+ if val.is_a? Array
1331
+ case val[0]
1332
+ when :array
1333
+ assert_instance_of(Array, desc.send(key), msg)
1334
+ assert_equal(val[1], desc.send(key).length)
1335
+ assert_instance_of(val[2], desc.send(key)[0]) if val[1] > 0
1336
+ when :type
1337
+ assert_instance_of(val[1], desc.send(key), msg)
1338
+ else
1339
+ raise "Invalid test case: #{elem[:obj_name]}.#{key} : #{val[0]}"
1340
+ end
1341
+ else
1342
+ assert_equal(val, desc.send(key), msg)
1343
+ end
1344
+ end
1345
+ end
1346
+ end
1347
+
1348
+ drop_type('TEST_TYPE_ORDER_METHOD')
1349
+ drop_type('TEST_TYPE_MAP_METHOD')
1350
+ drop_type('TEST_TYPE_HAS_BFILE')
1351
+ drop_type('TEST_TYPE_HAS_BLOB')
1352
+ drop_type('TEST_TYPE_HAS_NCLOB')
1353
+ drop_type('TEST_TYPE_HAS_CLOB')
1354
+ drop_type('TEST_TYPE_INCOMPLETE')
1355
+ drop_type('TEST_TYPE_GRANDCHILD')
1356
+ drop_type('TEST_TYPE_VARRAY')
1357
+ drop_type('TEST_TYPE_NESTEAD_TABLE')
1358
+ drop_type('TEST_TYPE_CHILD')
1359
+ drop_type('TEST_TYPE_PARENT')
1360
+ end # test_type_metadata
1361
+
1362
+ def test_column_metadata
1363
+ if $oracle_version < OCI8::ORAVER_8_1
1364
+ begin
1365
+ @conn.describe_table('tab').columns
1366
+ rescue RuntimeError
1367
+ assert_equal("This feature is unavailable on Oracle 8.0", $!.to_s)
1368
+ end
1369
+ return
1370
+ end
1371
+
1372
+ coldef = @@column_test_data.find_all do |c|
1373
+ c.available?(@conn)
1374
+ end
1375
+
1376
+ drop_table('test_table')
1377
+ sql = <<-EOS
1378
+ CREATE TABLE test_table (#{idx = 0; coldef.collect do |c| idx += 1; "C#{idx} " + c.data_type_string; end.join(',')})
1379
+ STORAGE (
1380
+ INITIAL 100k
1381
+ NEXT 100k
1382
+ MINEXTENTS 1
1383
+ MAXEXTENTS UNLIMITED
1384
+ PCTINCREASE 0)
1385
+ EOS
1386
+ @conn.exec(sql)
1387
+
1388
+ [
1389
+ @conn.describe_any('test_table').columns,
1390
+ @conn.describe_table('test_table').columns,
1391
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1392
+ obj.obj_name == 'TEST_TABLE'
1393
+ end.columns,
1394
+ @conn.exec('select * from test_table').column_metadata,
1395
+ ].each do |columns|
1396
+ columns.each_with_index do |column, i|
1397
+ assert_equal("C#{i + 1}", column.name, "'#{coldef[i].data_type_string}': name")
1398
+ DatatypeData.attributes.each do |attr|
1399
+ expected_val = coldef[i].send(attr)
1400
+ if expected_val != :skip
1401
+ assert_equal(expected_val, column.send(attr), "'#{coldef[i].data_type_string}': #{attr})")
1402
+ end
1403
+ end
1404
+ end
1405
+ end
1406
+ drop_table('test_table')
1407
+ end # test_column_metadata
1408
+
257
1409
  end # TestMetadata