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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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