ruby-oci8 2.1.5.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +17 -0
  3. data/COPYING +30 -0
  4. data/COPYING_old +64 -0
  5. data/ChangeLog +2779 -0
  6. data/Makefile +92 -0
  7. data/NEWS +660 -0
  8. data/README.md +43 -0
  9. data/VERSION +1 -0
  10. data/dist-files +91 -0
  11. data/docs/install-binary-package.md +40 -0
  12. data/docs/install-full-client.md +116 -0
  13. data/docs/install-instant-client.md +167 -0
  14. data/docs/platform-specific-issues.md +197 -0
  15. data/docs/report-installation-issue.md +50 -0
  16. data/lib/.document +1 -0
  17. data/lib/dbd/OCI8.rb +591 -0
  18. data/lib/oci8.rb +147 -0
  19. data/lib/oci8.rb.in +147 -0
  20. data/lib/oci8/.document +8 -0
  21. data/lib/oci8/bindtype.rb +350 -0
  22. data/lib/oci8/compat.rb +113 -0
  23. data/lib/oci8/connection_pool.rb +108 -0
  24. data/lib/oci8/cursor.rb +564 -0
  25. data/lib/oci8/datetime.rb +605 -0
  26. data/lib/oci8/encoding-init.rb +79 -0
  27. data/lib/oci8/encoding.yml +537 -0
  28. data/lib/oci8/metadata.rb +2092 -0
  29. data/lib/oci8/object.rb +605 -0
  30. data/lib/oci8/oci8.rb +560 -0
  31. data/lib/oci8/ocihandle.rb +607 -0
  32. data/lib/oci8/oracle_version.rb +143 -0
  33. data/lib/oci8/properties.rb +134 -0
  34. data/lib/oci8lib_200.so +0 -0
  35. data/metaconfig +142 -0
  36. data/pre-distclean.rb +7 -0
  37. data/ruby-oci8.gemspec +80 -0
  38. data/setup.rb +1333 -0
  39. data/test/README +42 -0
  40. data/test/config.rb +184 -0
  41. data/test/setup_test_object.sql +171 -0
  42. data/test/test_all.rb +54 -0
  43. data/test/test_appinfo.rb +63 -0
  44. data/test/test_array_dml.rb +333 -0
  45. data/test/test_bind_raw.rb +46 -0
  46. data/test/test_bind_string.rb +106 -0
  47. data/test/test_bind_time.rb +178 -0
  48. data/test/test_break.rb +124 -0
  49. data/test/test_clob.rb +98 -0
  50. data/test/test_connection_pool.rb +125 -0
  51. data/test/test_connstr.rb +81 -0
  52. data/test/test_datetime.rb +581 -0
  53. data/test/test_dbi.rb +366 -0
  54. data/test/test_dbi_clob.rb +53 -0
  55. data/test/test_encoding.rb +104 -0
  56. data/test/test_error.rb +88 -0
  57. data/test/test_metadata.rb +1485 -0
  58. data/test/test_object.rb +462 -0
  59. data/test/test_oci8.rb +489 -0
  60. data/test/test_oracle_version.rb +70 -0
  61. data/test/test_oradate.rb +256 -0
  62. data/test/test_oranumber.rb +787 -0
  63. data/test/test_rowid.rb +33 -0
  64. metadata +109 -0
@@ -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
@@ -0,0 +1,1485 @@
1
+ require 'oci8'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/config'
4
+
5
+ class TestMetadata < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @conn = get_oci8_connection
9
+ end
10
+
11
+ def teardown
12
+ @conn.logoff
13
+ end
14
+
15
+ def drop_type(name, drop_body = false)
16
+ if drop_body
17
+ begin
18
+ @conn.exec("DROP TYPE BODY #{name}")
19
+ rescue OCIError
20
+ raise if $!.code != 4043
21
+ end
22
+ end
23
+ begin
24
+ @conn.exec("DROP TYPE #{name}")
25
+ rescue OCIError
26
+ raise if $!.code != 4043
27
+ end
28
+ end
29
+
30
+ class DatatypeData
31
+ @@attributes =
32
+ [:data_type_string,
33
+ :data_type,
34
+ :charset_form,
35
+ :nullable?,
36
+ :data_size,
37
+ :precision,
38
+ :scale,
39
+ ]
40
+ @@attributes +=
41
+ [
42
+ :char_used?,
43
+ :char_size,
44
+ :fsprecision,
45
+ :lfprecision,
46
+ ] if $oracle_version >= OCI8::ORAVER_9_0
47
+
48
+ @@attributes.each do |attr|
49
+ define_method attr do
50
+ @table[attr]
51
+ end
52
+ end
53
+
54
+ def self.attributes
55
+ @@attributes
56
+ end
57
+
58
+ def initialize(hash = {})
59
+ @table = hash
60
+ end
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
73
+ end
74
+ end
75
+ end
76
+
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
94
+ end
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
+
601
+ def test_error_describe_table
602
+ drop_table('test_table')
603
+ begin
604
+ @conn.describe_table('test_table')
605
+ flunk("expects ORA-4043 but no error")
606
+ rescue OCIError
607
+ flunk("expects ORA-4043 but ORA-#{$!.code}") if $!.code != 4043
608
+ end
609
+ @conn.exec('create sequence test_table')
610
+ begin
611
+ begin
612
+ @conn.describe_table('test_table')
613
+ flunk('expects ORA-4043 but no error')
614
+ rescue OCIError
615
+ flunk("expects ORA-4043 but ORA-#{$!.code}") if $!.code != 4043
616
+ end
617
+ ensure
618
+ @conn.exec('drop sequence test_table')
619
+ end
620
+ end
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
+ assert_instance_of(OCI8::Metadata::Procedure, desc[1])
898
+ assert_equal(nil, desc[1].obj_id)
899
+ assert_equal('TEST_PROC', desc[1].obj_name)
900
+ assert_equal(nil, desc[1].obj_schema)
901
+ assert_equal(true, desc[1].is_invoker_rights?)
902
+ assert_equal(1, desc[1].overload_id)
903
+ assert_instance_of(Array, desc[1].arguments)
904
+ assert_equal(1, desc[1].arguments.length)
905
+ assert_instance_of(OCI8::Metadata::Argument, desc[1].arguments[0])
906
+ end # test_procedure_metadata
907
+
908
+ def test_function_metadata
909
+ @conn.exec(<<-EOS)
910
+ CREATE OR REPLACE FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER IS
911
+ BEGIN
912
+ RETURN arg1;
913
+ END;
914
+ EOS
915
+ [
916
+ @conn.describe_any('test_func'),
917
+ @conn.describe_function('test_func'),
918
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
919
+ obj.obj_name == 'TEST_FUNC'
920
+ end
921
+ ].each do |desc|
922
+ assert_instance_of(OCI8::Metadata::Function, desc)
923
+ assert_object_id('TEST_FUNC', desc.obj_id)
924
+ assert_equal('TEST_FUNC', desc.obj_name)
925
+ assert_equal('TEST_FUNC', desc.name)
926
+ assert_equal(@conn.username, desc.obj_schema)
927
+ assert_equal(false, desc.is_invoker_rights?)
928
+ assert_equal(nil, desc.overload_id)
929
+ assert_instance_of(Array, desc.arguments)
930
+ assert_equal(3, desc.arguments.length)
931
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
932
+ end
933
+
934
+ @conn.exec(<<-EOS)
935
+ CREATE OR REPLACE FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER
936
+ AUTHID CURRENT_USER
937
+ IS
938
+ BEGIN
939
+ RETURN arg1;
940
+ END;
941
+ EOS
942
+ [
943
+ @conn.describe_any('test_func'),
944
+ @conn.describe_function('test_func'),
945
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
946
+ obj.obj_name == 'TEST_FUNC'
947
+ end
948
+ ].each do |desc|
949
+ assert_instance_of(OCI8::Metadata::Function, desc)
950
+ assert_object_id('TEST_FUNC', desc.obj_id)
951
+ assert_equal('TEST_FUNC', desc.obj_name)
952
+ assert_equal(@conn.username, desc.obj_schema)
953
+ assert_equal(true, desc.is_invoker_rights?)
954
+ assert_equal(nil, desc.overload_id)
955
+ assert_instance_of(Array, desc.arguments)
956
+ assert_equal(3, desc.arguments.length)
957
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
958
+ end
959
+
960
+ @conn.exec('DROP FUNCTION test_func');
961
+
962
+ @conn.exec(<<-EOS)
963
+ CREATE OR REPLACE PACKAGE TEST_PKG IS
964
+ FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER;
965
+ END;
966
+ EOS
967
+ desc = @conn.describe_package('test_pkg').subprograms[0]
968
+ assert_instance_of(OCI8::Metadata::Function, desc)
969
+ assert_equal(nil, desc.obj_id)
970
+ assert_equal('TEST_FUNC', desc.obj_name)
971
+ assert_equal(nil, desc.obj_schema)
972
+ assert_equal(false, desc.is_invoker_rights?)
973
+ assert_equal(0, desc.overload_id)
974
+ assert_instance_of(Array, desc.arguments)
975
+ assert_equal(3, desc.arguments.length)
976
+ assert_instance_of(OCI8::Metadata::Argument, desc.arguments[0])
977
+
978
+ @conn.exec(<<-EOS)
979
+ CREATE OR REPLACE PACKAGE TEST_PKG AUTHID CURRENT_USER
980
+ IS
981
+ FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER;
982
+ FUNCTION test_func(arg1 IN INTEGER) RETURN NUMBER;
983
+ END;
984
+ EOS
985
+ desc = @conn.describe_package('test_pkg').subprograms
986
+ assert_instance_of(OCI8::Metadata::Function, desc[0])
987
+ assert_equal(nil, desc[0].obj_id)
988
+ assert_equal('TEST_FUNC', desc[0].obj_name)
989
+ assert_equal(nil, desc[0].obj_schema)
990
+ assert_equal(true, desc[0].is_invoker_rights?)
991
+ assert_equal(2, desc[0].overload_id)
992
+ assert_instance_of(Array, desc[0].arguments)
993
+ assert_equal(3, desc[0].arguments.length)
994
+ assert_instance_of(OCI8::Metadata::Argument, desc[0].arguments[0])
995
+
996
+ assert_instance_of(OCI8::Metadata::Function, desc[1])
997
+ assert_equal(nil, desc[1].obj_id)
998
+ assert_equal('TEST_FUNC', desc[1].obj_name)
999
+ assert_equal(nil, desc[1].obj_schema)
1000
+ assert_equal(true, desc[1].is_invoker_rights?)
1001
+ assert_equal(1, desc[1].overload_id)
1002
+ assert_instance_of(Array, desc[1].arguments)
1003
+ assert_equal(2, desc[1].arguments.length)
1004
+ assert_instance_of(OCI8::Metadata::Argument, desc[1].arguments[0])
1005
+ end # test_function_metadata
1006
+
1007
+ def test_package_metadata
1008
+ @conn.exec(<<-EOS)
1009
+ CREATE OR REPLACE PACKAGE TEST_PKG IS
1010
+ FUNCTION test_func(arg1 IN INTEGER, arg2 OUT varchar2) RETURN NUMBER;
1011
+ END;
1012
+ EOS
1013
+ [
1014
+ @conn.describe_any('test_pkg'),
1015
+ @conn.describe_package('test_pkg'),
1016
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1017
+ obj.obj_name == 'TEST_PKG'
1018
+ end
1019
+ ].each do |desc|
1020
+ assert_instance_of(OCI8::Metadata::Package, desc)
1021
+ assert_object_id('TEST_PKG', desc.obj_id)
1022
+ assert_equal('TEST_PKG', desc.obj_name)
1023
+ assert_equal(@conn.username, desc.obj_schema)
1024
+ assert_equal(false, desc.is_invoker_rights?)
1025
+ assert_instance_of(Array, desc.subprograms)
1026
+ assert_equal(1, desc.subprograms.length)
1027
+ assert_instance_of(OCI8::Metadata::Function, desc.subprograms[0])
1028
+ end
1029
+
1030
+ @conn.exec(<<-EOS)
1031
+ CREATE OR REPLACE PACKAGE TEST_PKG AUTHID CURRENT_USER IS
1032
+ PROCEDURE test_proc(arg1 IN INTEGER, arg2 OUT varchar2);
1033
+ END;
1034
+ EOS
1035
+ [
1036
+ @conn.describe_any('test_pkg'),
1037
+ @conn.describe_package('test_pkg'),
1038
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1039
+ obj.obj_name == 'TEST_PKG'
1040
+ end
1041
+ ].each do |desc|
1042
+ assert_instance_of(OCI8::Metadata::Package, desc)
1043
+ assert_object_id('TEST_PKG', desc.obj_id)
1044
+ assert_equal('TEST_PKG', desc.obj_name)
1045
+ assert_equal(@conn.username, desc.obj_schema)
1046
+ assert_equal(true, desc.is_invoker_rights?)
1047
+ assert_instance_of(Array, desc.subprograms)
1048
+ assert_equal(1, desc.subprograms.length)
1049
+ assert_instance_of(OCI8::Metadata::Procedure, desc.subprograms[0])
1050
+ end
1051
+ end # test_package_metadata
1052
+
1053
+ def test_type_metadata
1054
+ drop_type('TEST_TYPE_ORDER_METHOD')
1055
+ drop_type('TEST_TYPE_MAP_METHOD')
1056
+ drop_type('TEST_TYPE_HAS_BFILE')
1057
+ drop_type('TEST_TYPE_HAS_BLOB')
1058
+ drop_type('TEST_TYPE_HAS_NCLOB')
1059
+ drop_type('TEST_TYPE_HAS_CLOB')
1060
+ drop_type('TEST_TYPE_INCOMPLETE')
1061
+ drop_type('TEST_TYPE_GRANDCHILD')
1062
+ drop_type('TEST_TYPE_VARRAY')
1063
+ drop_type('TEST_TYPE_NESTEAD_TABLE')
1064
+ drop_type('TEST_TYPE_CHILD')
1065
+ drop_type('TEST_TYPE_PARENT')
1066
+ expected_values = []
1067
+
1068
+ @conn.exec(<<-EOS)
1069
+ CREATE TYPE test_type_parent AS OBJECT (
1070
+ col1 number(38,0),
1071
+ col2 varchar2(60)
1072
+ )
1073
+ NOT INSTANTIABLE
1074
+ NOT FINAL
1075
+ EOS
1076
+ expected_values << {
1077
+ :obj_name => 'TEST_TYPE_PARENT',
1078
+ :typecode => :named_type,
1079
+ :collection_typecode => nil,
1080
+ :is_incomplete_type? => false,
1081
+ :is_system_type? => false,
1082
+ :is_predefined_type? => false,
1083
+ :is_transient_type? => false,
1084
+ :is_system_generated_type? => false,
1085
+ :has_nested_table? => false,
1086
+ :has_lob? => false,
1087
+ :has_file? => false,
1088
+ :collection_element => nil,
1089
+ :num_type_attrs => 2,
1090
+ :num_type_methods => 0,
1091
+ :map_method => nil,
1092
+ :order_method => nil,
1093
+ :is_invoker_rights? => false,
1094
+ :is_final_type? => false,
1095
+ :is_instantiable_type? => false,
1096
+ :is_subtype? => false,
1097
+ :supertype_schema_name => nil,
1098
+ :supertype_name => nil,
1099
+ :type_attrs => [:array, 2, OCI8::Metadata::TypeAttr],
1100
+ :type_methods => [:array, 0],
1101
+ }
1102
+ @conn.exec(<<-EOS)
1103
+ CREATE TYPE test_type_child UNDER test_type_parent (
1104
+ lob BLOB
1105
+ )
1106
+ NOT FINAL
1107
+ EOS
1108
+ expected_values << {
1109
+ :obj_name => 'TEST_TYPE_CHILD',
1110
+ :typecode => :named_type,
1111
+ :collection_typecode => nil,
1112
+ :is_incomplete_type? => false,
1113
+ :is_system_type? => false,
1114
+ :is_predefined_type? => false,
1115
+ :is_transient_type? => false,
1116
+ :is_system_generated_type? => false,
1117
+ :has_nested_table? => false,
1118
+ :has_lob? => true,
1119
+ :has_file? => false,
1120
+ :collection_element => nil,
1121
+ :num_type_attrs => 3,
1122
+ :num_type_methods => 0,
1123
+ :map_method => nil,
1124
+ :order_method => nil,
1125
+ :is_invoker_rights? => false,
1126
+ :is_final_type? => false,
1127
+ :is_instantiable_type? => true,
1128
+ :is_subtype? => true,
1129
+ :supertype_schema_name => @conn.username,
1130
+ :supertype_name => 'TEST_TYPE_PARENT',
1131
+ :type_attrs => [:array, 3, OCI8::Metadata::TypeAttr],
1132
+ :type_methods => [:array, 0],
1133
+ }
1134
+ @conn.exec(<<-EOS)
1135
+ CREATE TYPE test_type_nestead_table AS TABLE OF test_type_child
1136
+ EOS
1137
+ expected_values << {
1138
+ :obj_name => 'TEST_TYPE_NESTEAD_TABLE',
1139
+ :typecode => :named_collection,
1140
+ :collection_typecode => :table,
1141
+ :is_incomplete_type? => false,
1142
+ :is_system_type? => false,
1143
+ :is_predefined_type? => false,
1144
+ :is_transient_type? => false,
1145
+ :is_system_generated_type? => false,
1146
+ :has_nested_table? => true,
1147
+ :has_lob? => true,
1148
+ :has_file? => false,
1149
+ :collection_element => [:type, OCI8::Metadata::Collection],
1150
+ :num_type_attrs => 0,
1151
+ :num_type_methods => 0,
1152
+ :map_method => nil,
1153
+ :order_method => nil,
1154
+ :is_invoker_rights? => false,
1155
+ :is_final_type? => true,
1156
+ :is_instantiable_type? => true,
1157
+ :is_subtype? => false,
1158
+ :supertype_schema_name => nil,
1159
+ :supertype_name => nil,
1160
+ :type_attrs => [:array, 0],
1161
+ :type_methods => [:array, 0],
1162
+ }
1163
+ @conn.exec(<<-EOS)
1164
+ CREATE TYPE test_type_varray AS VARRAY(10) OF test_type_child
1165
+ EOS
1166
+ expected_values << {
1167
+ :obj_name => 'TEST_TYPE_VARRAY',
1168
+ :typecode => :named_collection,
1169
+ :collection_typecode => :varray,
1170
+ :is_incomplete_type? => false,
1171
+ :is_system_type? => false,
1172
+ :is_predefined_type? => false,
1173
+ :is_transient_type? => false,
1174
+ :is_system_generated_type? => false,
1175
+ :has_nested_table? => false,
1176
+ :has_lob? => true,
1177
+ :has_file? => false,
1178
+ :collection_element => [:type, OCI8::Metadata::Collection],
1179
+ :num_type_attrs => 0,
1180
+ :num_type_methods => 0,
1181
+ :map_method => nil,
1182
+ :order_method => nil,
1183
+ :is_invoker_rights? => false,
1184
+ :is_final_type? => true,
1185
+ :is_instantiable_type? => true,
1186
+ :is_subtype? => false,
1187
+ :supertype_schema_name => nil,
1188
+ :supertype_name => nil,
1189
+ :type_attrs => [:array, 0],
1190
+ :type_methods => [:array, 0],
1191
+ }
1192
+ @conn.exec(<<-EOS)
1193
+ CREATE TYPE test_type_grandchild UNDER test_type_child (
1194
+ table_column test_type_nestead_table,
1195
+ file_column BFILE
1196
+ )
1197
+ EOS
1198
+ expected_values << {
1199
+ :obj_name => 'TEST_TYPE_GRANDCHILD',
1200
+ :typecode => :named_type,
1201
+ :collection_typecode => nil,
1202
+ :is_incomplete_type? => false,
1203
+ :is_system_type? => false,
1204
+ :is_predefined_type? => false,
1205
+ :is_transient_type? => false,
1206
+ :is_system_generated_type? => false,
1207
+ :has_nested_table? => true,
1208
+ :has_lob? => true,
1209
+ :has_file? => true,
1210
+ :collection_element => nil,
1211
+ :num_type_attrs => 5,
1212
+ :num_type_methods => 0,
1213
+ :map_method => nil,
1214
+ :order_method => nil,
1215
+ :is_invoker_rights? => false,
1216
+ :is_final_type? => true,
1217
+ :is_instantiable_type? => true,
1218
+ :is_subtype? => true,
1219
+ :supertype_schema_name => @conn.username,
1220
+ :supertype_name => 'TEST_TYPE_CHILD',
1221
+ :type_attrs => [:array, 5, OCI8::Metadata::TypeAttr],
1222
+ :type_methods => [:array, 0],
1223
+ }
1224
+ @conn.exec(<<-EOS)
1225
+ CREATE TYPE test_type_incomplete
1226
+ EOS
1227
+ expected_values << {
1228
+ :obj_name => 'TEST_TYPE_INCOMPLETE',
1229
+ :typecode => :named_type,
1230
+ :collection_typecode => nil,
1231
+ :is_incomplete_type? => true,
1232
+ :is_system_type? => false,
1233
+ :is_predefined_type? => false,
1234
+ :is_transient_type? => false,
1235
+ :is_system_generated_type? => false,
1236
+ :has_nested_table? => false,
1237
+ :has_lob? => false,
1238
+ :has_file? => false,
1239
+ :collection_element => nil,
1240
+ :num_type_attrs => 0,
1241
+ :num_type_methods => 0,
1242
+ :map_method => nil,
1243
+ :order_method => nil,
1244
+ :is_invoker_rights? => false,
1245
+ :is_final_type? => true,
1246
+ :is_instantiable_type? => true,
1247
+ :is_subtype? => false,
1248
+ :supertype_schema_name => nil,
1249
+ :supertype_name => nil,
1250
+ :type_attrs => [:array, 0],
1251
+ :type_methods => [:array, 0],
1252
+ }
1253
+
1254
+ @conn.exec(<<-EOS)
1255
+ CREATE TYPE test_type_has_clob AS OBJECT (lob CLOB)
1256
+ EOS
1257
+ expected_values << {
1258
+ :obj_name => 'TEST_TYPE_HAS_CLOB',
1259
+ :has_lob? => true,
1260
+ :has_file? => false,
1261
+ }
1262
+ if $oracle_version >= OCI8::ORAVER_9_2
1263
+ @conn.exec(<<-EOS)
1264
+ CREATE TYPE test_type_has_nclob AS OBJECT (lob NCLOB)
1265
+ EOS
1266
+ expected_values << {
1267
+ :obj_name => 'TEST_TYPE_HAS_NCLOB',
1268
+ :has_lob? => true,
1269
+ :has_file? => false,
1270
+ }
1271
+ end
1272
+ @conn.exec(<<-EOS)
1273
+ CREATE TYPE test_type_has_blob AS OBJECT (lob BLOB)
1274
+ EOS
1275
+ expected_values << {
1276
+ :obj_name => 'TEST_TYPE_HAS_BLOB',
1277
+ :has_lob? => true,
1278
+ :has_file? => false,
1279
+ }
1280
+ @conn.exec(<<-EOS)
1281
+ CREATE TYPE test_type_has_bfile AS OBJECT (lob BFILE)
1282
+ EOS
1283
+ expected_values << {
1284
+ :obj_name => 'TEST_TYPE_HAS_BFILE',
1285
+ :has_lob? => false,
1286
+ :has_file? => true,
1287
+ }
1288
+ @conn.exec(<<-EOS)
1289
+ CREATE TYPE test_type_map_method AS OBJECT (
1290
+ x integer,
1291
+ y integer,
1292
+ MAP MEMBER FUNCTION area RETURN NUMBER
1293
+ )
1294
+ EOS
1295
+ expected_values << {
1296
+ :obj_name => 'TEST_TYPE_MAP_METHOD',
1297
+ :map_method => [:type, OCI8::Metadata::TypeMethod],
1298
+ :order_method => nil,
1299
+ }
1300
+ @conn.exec(<<-EOS)
1301
+ CREATE TYPE test_type_order_method AS OBJECT (
1302
+ x integer,
1303
+ y integer,
1304
+ ORDER MEMBER FUNCTION match(l test_type_order_method) RETURN INTEGER
1305
+ )
1306
+ EOS
1307
+ expected_values << {
1308
+ :obj_name => 'TEST_TYPE_ORDER_METHOD',
1309
+ :map_method => nil,
1310
+ :order_method => [:type, OCI8::Metadata::TypeMethod],
1311
+ }
1312
+
1313
+ expected_values.each do |elem|
1314
+ [
1315
+ @conn.describe_any(elem[:obj_name]),
1316
+ @conn.describe_type(elem[:obj_name]),
1317
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1318
+ obj.obj_name == elem[:obj_name]
1319
+ end,
1320
+ ].each do |desc|
1321
+ assert_object_id(elem[:obj_name], desc.obj_id)
1322
+ assert_equal(@conn.username, desc.obj_schema)
1323
+ assert_equal(elem[:obj_name], desc.name)
1324
+ assert_equal(@conn.username, desc.schema_name)
1325
+
1326
+ elem.each do |key, val|
1327
+ msg = elem[:obj_name] + '.' + key.to_s
1328
+ if val.is_a? Array
1329
+ case val[0]
1330
+ when :array
1331
+ assert_instance_of(Array, desc.send(key), msg)
1332
+ assert_equal(val[1], desc.send(key).length)
1333
+ assert_instance_of(val[2], desc.send(key)[0]) if val[1] > 0
1334
+ when :type
1335
+ assert_instance_of(val[1], desc.send(key), msg)
1336
+ else
1337
+ raise "Invalid test case: #{elem[:obj_name]}.#{key} : #{val[0]}"
1338
+ end
1339
+ else
1340
+ assert_equal(val, desc.send(key), msg)
1341
+ end
1342
+ end
1343
+ end
1344
+ end
1345
+
1346
+ drop_type('TEST_TYPE_ORDER_METHOD')
1347
+ drop_type('TEST_TYPE_MAP_METHOD')
1348
+ drop_type('TEST_TYPE_HAS_BFILE')
1349
+ drop_type('TEST_TYPE_HAS_BLOB')
1350
+ drop_type('TEST_TYPE_HAS_NCLOB')
1351
+ drop_type('TEST_TYPE_HAS_CLOB')
1352
+ drop_type('TEST_TYPE_INCOMPLETE')
1353
+ drop_type('TEST_TYPE_GRANDCHILD')
1354
+ drop_type('TEST_TYPE_VARRAY')
1355
+ drop_type('TEST_TYPE_NESTEAD_TABLE')
1356
+ drop_type('TEST_TYPE_CHILD')
1357
+ drop_type('TEST_TYPE_PARENT')
1358
+ end # test_type_metadata
1359
+
1360
+ def test_column_metadata
1361
+ if $oracle_version < OCI8::ORAVER_8_1
1362
+ begin
1363
+ @conn.describe_table('tab').columns
1364
+ rescue RuntimeError
1365
+ assert_equal("This feature is unavailable on Oracle 8.0", $!.to_s)
1366
+ end
1367
+ return
1368
+ end
1369
+
1370
+ coldef = @@column_test_data.find_all do |c|
1371
+ c.available?(@conn)
1372
+ end
1373
+
1374
+ drop_table('test_table')
1375
+ sql = <<-EOS
1376
+ CREATE TABLE test_table (#{idx = 0; coldef.collect do |c| idx += 1; "C#{idx} " + c.data_type_string; end.join(',')})
1377
+ STORAGE (
1378
+ INITIAL 100k
1379
+ NEXT 100k
1380
+ MINEXTENTS 1
1381
+ MAXEXTENTS UNLIMITED
1382
+ PCTINCREASE 0)
1383
+ EOS
1384
+ @conn.exec(sql)
1385
+
1386
+ [
1387
+ @conn.describe_any('test_table').columns,
1388
+ @conn.describe_table('test_table').columns,
1389
+ @conn.describe_schema(@conn.username).objects.detect do |obj|
1390
+ obj.obj_name == 'TEST_TABLE'
1391
+ end.columns,
1392
+ @conn.exec('select * from test_table').column_metadata,
1393
+ ].each do |columns|
1394
+ columns.each_with_index do |column, i|
1395
+ assert_equal("C#{i + 1}", column.name, "'#{coldef[i].data_type_string}': name")
1396
+ DatatypeData.attributes.each do |attr|
1397
+ expected_val = coldef[i].send(attr)
1398
+ if expected_val != :skip
1399
+ assert_equal(expected_val, column.send(attr), "'#{coldef[i].data_type_string}': #{attr})")
1400
+ end
1401
+ end
1402
+ end
1403
+ end
1404
+ drop_table('test_table')
1405
+ end # test_column_metadata
1406
+
1407
+ def assert_sequence(sequence_name, desc)
1408
+ # defined in OCI8::Metadata::Base
1409
+ assert_object_id(sequence_name, desc.obj_id)
1410
+ assert_equal(sequence_name, desc.obj_name, 'obj_name')
1411
+ assert_equal(@conn.username, desc.obj_schema, 'obj_schema')
1412
+ # defined in OCI8::Metadata::Sequence
1413
+ assert_object_id(sequence_name, desc.objid)
1414
+ min, max, incr, cache, order = @conn.select_one(<<EOS, sequence_name)
1415
+ select min_value, max_value, increment_by, cache_size, order_flag
1416
+ from user_sequences
1417
+ where sequence_name = :1
1418
+ EOS
1419
+ min = min.to_i
1420
+ max = max.to_i
1421
+ incr = incr.to_i
1422
+ cache = cache.to_i
1423
+ order = order == 'Y'
1424
+ currval = @conn.select_one("select cast(#{sequence_name}.currval as integer) from dual")[0]
1425
+
1426
+ assert_equal(min, desc.min, 'min')
1427
+ assert_equal(max, desc.max, 'max')
1428
+ assert_equal(incr, desc.incr, 'incr')
1429
+ assert_equal(cache, desc.cache, 'cache')
1430
+ assert_equal(order, desc.order?, 'order?')
1431
+ assert_operator(currval, :<=, desc.hw_mark, 'hw_mark')
1432
+ end
1433
+
1434
+ def test_sequence
1435
+ begin
1436
+ @conn.exec("DROP SEQUENCE TEST_SEQ_OCI8")
1437
+ rescue OCIError
1438
+ raise if $!.code != 2289 # ORA-02289: sequence does not exist
1439
+ end
1440
+ @conn.exec(<<-EOS)
1441
+ CREATE SEQUENCE TEST_SEQ_OCI8
1442
+ INCREMENT BY 2
1443
+ START WITH 998
1444
+ MAXVALUE 1000
1445
+ MINVALUE 10
1446
+ CYCLE
1447
+ CACHE 5
1448
+ ORDER
1449
+ EOS
1450
+ @conn.select_one('select test_seq_oci8.nextval from dual')
1451
+ assert_sequence('TEST_SEQ_OCI8', @conn.describe_any('test_seq_oci8'))
1452
+ @conn.select_one('select test_seq_oci8.nextval from dual')
1453
+ assert_sequence('TEST_SEQ_OCI8', @conn.describe_sequence('test_seq_oci8'))
1454
+ @conn.select_one('select test_seq_oci8.nextval from dual')
1455
+ assert_sequence('TEST_SEQ_OCI8', @conn.describe_schema(@conn.username).objects.detect do |obj|
1456
+ obj.obj_name == 'TEST_SEQ_OCI8'
1457
+ end)
1458
+
1459
+ @conn.exec("DROP SEQUENCE TEST_SEQ_OCI8")
1460
+ @conn.exec(<<-EOS)
1461
+ CREATE SEQUENCE TEST_SEQ_OCI8
1462
+ INCREMENT BY -1
1463
+ NOMAXVALUE
1464
+ NOMINVALUE
1465
+ NOCYCLE
1466
+ NOCACHE
1467
+ NOORDER
1468
+ EOS
1469
+ # @conn.describe_any('test_seq_oci8').min is:
1470
+ # -99999999999999999999999999 on Oracle 10gR2
1471
+ # -999999999999999999999999999 on Oracle 11gR2
1472
+
1473
+ @conn.select_one('select test_seq_oci8.nextval from dual')
1474
+ assert_sequence('TEST_SEQ_OCI8', @conn.describe_any('test_seq_oci8'))
1475
+ @conn.select_one('select test_seq_oci8.nextval from dual')
1476
+ assert_sequence('TEST_SEQ_OCI8', @conn.describe_sequence('test_seq_oci8'))
1477
+ @conn.select_one('select test_seq_oci8.nextval from dual')
1478
+ assert_sequence('TEST_SEQ_OCI8', @conn.describe_schema(@conn.username).objects.detect do |obj|
1479
+ obj.obj_name == 'TEST_SEQ_OCI8'
1480
+ end)
1481
+
1482
+ @conn.exec("DROP SEQUENCE TEST_SEQ_OCI8")
1483
+ end
1484
+
1485
+ end # TestMetadata