ruby-oci8 2.1.5.1-x64-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.
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