ruby-oci8 2.0.4-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. data/ChangeLog +1912 -0
  2. data/Makefile +96 -0
  3. data/NEWS +223 -0
  4. data/README +86 -0
  5. data/VERSION +1 -0
  6. data/dist-files +77 -0
  7. data/doc/api.en.html +527 -0
  8. data/doc/api.en.rd +554 -0
  9. data/doc/api.ja.html +525 -0
  10. data/doc/api.ja.rd +557 -0
  11. data/doc/manual.css +35 -0
  12. data/lib/.document +1 -0
  13. data/lib/dbd/OCI8.rb +591 -0
  14. data/lib/oci8.rb +82 -0
  15. data/lib/oci8.rb.in +82 -0
  16. data/lib/oci8/.document +5 -0
  17. data/lib/oci8/bindtype.rb +319 -0
  18. data/lib/oci8/compat.rb +113 -0
  19. data/lib/oci8/datetime.rb +619 -0
  20. data/lib/oci8/encoding-init.rb +40 -0
  21. data/lib/oci8/encoding.yml +537 -0
  22. data/lib/oci8/metadata.rb +2077 -0
  23. data/lib/oci8/object.rb +562 -0
  24. data/lib/oci8/oci8.rb +571 -0
  25. data/lib/oci8/oracle_version.rb +144 -0
  26. data/lib/oci8lib_18.so +0 -0
  27. data/lib/oci8lib_191.so +0 -0
  28. data/metaconfig +142 -0
  29. data/pre-distclean.rb +7 -0
  30. data/ruby-oci8.gemspec +63 -0
  31. data/setup.rb +1331 -0
  32. data/test/README +4 -0
  33. data/test/config.rb +109 -0
  34. data/test/test_all.rb +50 -0
  35. data/test/test_appinfo.rb +63 -0
  36. data/test/test_array_dml.rb +333 -0
  37. data/test/test_bind_raw.rb +46 -0
  38. data/test/test_bind_time.rb +178 -0
  39. data/test/test_break.rb +83 -0
  40. data/test/test_clob.rb +79 -0
  41. data/test/test_connstr.rb +81 -0
  42. data/test/test_datetime.rb +622 -0
  43. data/test/test_dbi.rb +366 -0
  44. data/test/test_dbi_clob.rb +53 -0
  45. data/test/test_encoding.rb +100 -0
  46. data/test/test_metadata.rb +257 -0
  47. data/test/test_oci8.rb +434 -0
  48. data/test/test_oracle_version.rb +70 -0
  49. data/test/test_oradate.rb +256 -0
  50. data/test/test_oranumber.rb +655 -0
  51. data/test/test_rowid.rb +33 -0
  52. metadata +108 -0
@@ -0,0 +1,35 @@
1
+ h1 {
2
+ color: #000080;
3
+ background: #e0e0ff;
4
+ border-color: #8080d0;
5
+ border-style: solid;
6
+ border-top-style: none;
7
+ border-left-style: none;
8
+ border-bottom-width: thick;
9
+ border-right-width: thin;
10
+ padding-top: 0.2em;
11
+ padding-bottom: 0.2em;
12
+ text-align: center
13
+ }
14
+ h2 {
15
+ color: #000080;
16
+ background: #e0e0ff;
17
+ border-color: #8080d0;
18
+ border-style: solid;
19
+ border-top-style: none;
20
+ border-left-style: none;
21
+ border-bottom-width: thick;
22
+ border-right-width: thin;
23
+ }
24
+ code {
25
+ color: blue
26
+ }
27
+ var {
28
+ color: brown
29
+ }
30
+ dt {
31
+ color: red
32
+ }
33
+ pre {
34
+ background: #e0ffff
35
+ }
@@ -0,0 +1 @@
1
+ oci8
@@ -0,0 +1,591 @@
1
+ #
2
+ # DBD::OCI8
3
+ #
4
+ # Copyright (c) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
5
+ #
6
+ # copied some code from DBD::Oracle.
7
+ # DBD::Oracle's copyright is as follows:
8
+ # --------------------- begin -------------------
9
+ #
10
+ # Copyright (c) 2001, 2002, 2003, 2004 Michael Neumann <mneumann@ntecs.de>
11
+ #
12
+ # All rights reserved.
13
+ #
14
+ # Redistribution and use in source and binary forms, with or without
15
+ # modification, are permitted provided that the following conditions
16
+ # are met:
17
+ # 1. Redistributions of source code must retain the above copyright
18
+ # notice, this list of conditions and the following disclaimer.
19
+ # 2. Redistributions in binary form must reproduce the above copyright
20
+ # notice, this list of conditions and the following disclaimer in the
21
+ # documentation and/or other materials provided with the distribution.
22
+ # 3. The name of the author may not be used to endorse or promote products
23
+ # derived from this software without specific prior written permission.
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
26
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28
+ # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
31
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33
+ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+ #
36
+ # --------------------- end -------------------
37
+
38
+ require 'oci8'
39
+
40
+ module DBI # :nodoc:
41
+ module DBD # :nodoc:
42
+ module OCI8
43
+
44
+ VERSION = "0.1"
45
+ USED_DBD_VERSION = "0.4"
46
+
47
+ def self.driver_name
48
+ "OCI8"
49
+ end
50
+
51
+ # type converstion handler to bind values. (ruby-dbi 0.4)
52
+ if DBI.const_defined?(:TypeUtil)
53
+ DBI::TypeUtil.register_conversion("OCI8") do |obj|
54
+ case obj
55
+ when ::TrueClass
56
+ ['1', false]
57
+ when ::FalseClass
58
+ ['0', false]
59
+ else
60
+ [obj, false]
61
+ end
62
+ end
63
+ end
64
+
65
+ # no type converstion is required for result set. (ruby-dbi 0.4)
66
+ class NoTypeConversion
67
+ def self.parse(obj)
68
+ obj
69
+ end
70
+ end
71
+
72
+ module Util
73
+
74
+ ERROR_MAP = {
75
+ 1 => DBI::IntegrityError, # unique constraint violated
76
+ 900 => DBI::ProgrammingError, # invalid SQL statement
77
+ 904 => DBI::ProgrammingError, # invalid identifier
78
+ 905 => DBI::ProgrammingError, # missing keyword
79
+ 923 => DBI::ProgrammingError, # FROM keyword not found where expected
80
+ 936 => DBI::ProgrammingError, # missing expression
81
+ 942 => DBI::ProgrammingError, # table or view does not exist
82
+ 2290 => DBI::IntegrityError, # check constraint violated
83
+ 2291 => DBI::IntegrityError, # parent key not found
84
+ 2292 => DBI::IntegrityError, # child record found
85
+ 2293 => DBI::IntegrityError, # check constraint violated
86
+ }
87
+
88
+ def raise_dbierror(err) # :nodoc:
89
+ if err.is_a? OCIError
90
+ exc = ERROR_MAP[err.code] || DBI::DatabaseError
91
+ raise exc.new(err.message, err.code)
92
+ else
93
+ raise DBI::DatabaseError.new(err.message, -1)
94
+ end
95
+ rescue DBI::DatabaseError => exc
96
+ exc.set_backtrace(err.backtrace)
97
+ raise
98
+ end
99
+
100
+ def column_metadata_to_column_info(col)
101
+ sql_type, type_name, precision, scale =
102
+ case col.data_type
103
+ when :char
104
+ [SQL_CHAR, col.charset_form == :nchar ? "NCHAR" : "CHAR", col.data_size, nil]
105
+ when :varchar2
106
+ [SQL_VARCHAR, col.charset_form == :nchar ? "NVARCHAR2" : "VARCHAR2", col.data_size, nil]
107
+ when :raw
108
+ [SQL_VARBINARY, "RAW", col.data_size, nil]
109
+ when :long
110
+ [SQL_LONGVARCHAR, "LONG", 4000, nil]
111
+ when :long_raw
112
+ [SQL_LONGVARBINARY, "LONG RAW", 4000, nil]
113
+ when :clob
114
+ [SQL_CLOB, col.charset_form == :nchar ? "NCLOB" : "CLOB", 4000, nil]
115
+ when :blob
116
+ [SQL_BLOB, "BLOB", 4000, nil]
117
+ when :bfile
118
+ [SQL_BLOB, "BFILE", 4000, nil]
119
+ when :number
120
+ if col.scale == -127 && col.precision != 0
121
+ # To convert from binary to decimal precision, multiply n by 0.30103.
122
+ [SQL_FLOAT, "FLOAT", (col.precision * 0.30103).ceil , nil]
123
+ elsif col.precision == 0
124
+ # NUMBER or calculated value (eg. col * 1.2).
125
+ [SQL_NUMERIC, "NUMBER", 38, nil]
126
+ else
127
+ [SQL_NUMERIC, "NUMBER", col.precision, col.scale]
128
+ end
129
+ when :binary_float
130
+ # (23 * 0.30103).ceil => 7
131
+ [SQL_FLOAT, "BINARY_FLOAT", 7, nil]
132
+ when :binary_double
133
+ # (52 * 0.30103).ceil => 16
134
+ [SQL_DOUBLE, "BINARY_DOUBLE", 16, nil]
135
+ when :date
136
+ # yyyy-mm-dd hh:mi:ss
137
+ [SQL_DATE, "DATE", 19, nil]
138
+ when :timestamp
139
+ # yyyy-mm-dd hh:mi:ss.SSSS
140
+ [SQL_TIMESTAMP, "TIMESTAMP", 20 + col.fsprecision, nil]
141
+ when :timestamp_tz
142
+ # yyyy-mm-dd hh:mi:ss.SSSS +HH:MM
143
+ [SQL_TIMESTAMP, "TIMESTAMP WITH TIME ZONE", 27 + col.fsprecision, nil]
144
+ when :timestamp_ltz
145
+ # yyyy-mm-dd hh:mi:ss.SSSS
146
+ [SQL_TIMESTAMP, "TIMESTAMP WITH LOCAL TIME ZONE", 20 + col.fsprecision, nil]
147
+ when :interval_ym
148
+ # yyyy-mm
149
+ [SQL_OTHER, 'INTERVAL YEAR TO MONTH', col.lfprecision + 3, nil]
150
+ when :interval_ds
151
+ # dd hh:mi:ss.SSSSS
152
+ [SQL_OTHER, 'INTERVAL DAY TO SECOND', col.lfprecision + 10 + col.fsprecision, nil]
153
+ else
154
+ [SQL_OTHER, col.data_type.to_s, nil, nil]
155
+ end
156
+ {'name' => col.name,
157
+ 'sql_type' => sql_type,
158
+ 'type_name' => type_name,
159
+ 'nullable' => col.nullable?,
160
+ 'precision' => precision,
161
+ 'scale' => scale,
162
+ 'dbi_type' => NoTypeConversion,
163
+ }
164
+ end
165
+ private :column_metadata_to_column_info
166
+ end
167
+
168
+ class Driver < DBI::BaseDriver # :nodoc:
169
+ include Util
170
+
171
+ def initialize
172
+ super(USED_DBD_VERSION)
173
+ end
174
+
175
+ # external OS authentication
176
+ # (contributed by Dan Fitch)
177
+ def default_user
178
+ [nil, nil]
179
+ end
180
+
181
+ def connect( dbname, user, auth, attr )
182
+ handle = ::OCI8.new(user, auth, dbname, attr['Privilege'])
183
+ handle.non_blocking = true if attr['NonBlocking']
184
+ return Database.new(handle, attr)
185
+ rescue OCIException => err
186
+ raise_dbierror(err)
187
+ end
188
+ end
189
+
190
+ class Database < DBI::BaseDatabase
191
+ include Util
192
+
193
+ def disconnect
194
+ @handle.logoff
195
+ rescue OCIException => err
196
+ raise_dbierror(err)
197
+ end
198
+
199
+ def prepare( statement )
200
+ # convert ?-style parameters to :1, :2 etc.
201
+ prep_statement = DBI::SQL::PreparedStatement.new(DummyQuoter.new, statement)
202
+ if prep_statement.unbound.size > 0
203
+ arr = (1..(prep_statement.unbound.size)).collect{|i| ":#{i}"}
204
+ statement = prep_statement.bind( arr )
205
+ end
206
+ cursor = @handle.parse(statement)
207
+ Statement.new(cursor)
208
+ rescue OCIException => err
209
+ raise_dbierror(err)
210
+ end
211
+
212
+ def ping
213
+ @handle.exec("BEGIN NULL; END;")
214
+ true
215
+ rescue
216
+ false
217
+ end
218
+
219
+ def commit
220
+ @handle.commit()
221
+ rescue OCIException => err
222
+ raise_dbierror(err)
223
+ end
224
+
225
+ def rollback
226
+ @handle.rollback()
227
+ rescue OCIException => err
228
+ raise_dbierror(err)
229
+ end
230
+
231
+ def tables
232
+ stmt = execute("SELECT object_name FROM user_objects where object_type in ('TABLE', 'VIEW')")
233
+ rows = stmt.fetch_all || []
234
+ stmt.finish
235
+ rows.collect {|row| row[0]}
236
+ end
237
+
238
+ # SQLs are copied from DBD::Oracle.
239
+ def columns(table)
240
+ tab = @handle.describe_table(table)
241
+ cols = tab.columns
242
+ cols.collect! do |col|
243
+ column_metadata_to_column_info(col)
244
+ end
245
+
246
+ dbh = DBI::DatabaseHandle.new(self)
247
+
248
+ primaries = {}
249
+ dbh.select_all(<<EOS, tab.obj_schema, tab.obj_name) do |row|
250
+ select column_name
251
+ from all_cons_columns a, all_constraints b
252
+ where a.owner = b.owner
253
+ and a.constraint_name = b.constraint_name
254
+ and a.table_name = b.table_name
255
+ and b.constraint_type = 'P'
256
+ and b.owner = :1
257
+ and b.table_name = :2
258
+ EOS
259
+ primaries[row[0]] = true
260
+ end
261
+
262
+ indices = {}
263
+ uniques = {}
264
+ dbh.select_all(<<EOS, tab.obj_schema, tab.obj_name) do |row|
265
+ select a.column_name, a.index_name, b.uniqueness
266
+ from all_ind_columns a, all_indexes b
267
+ where a.index_name = b.index_name
268
+ and a.index_owner = b.owner
269
+ and a.table_owner = :1
270
+ and a.table_name = :2
271
+ EOS
272
+ col_name, index_name, uniqueness = row
273
+ indices[col_name] = true
274
+ uniques[col_name] = true if uniqueness == 'UNIQUE'
275
+ end
276
+
277
+ dbh.select_all(<<EOS, tab.obj_schema, tab.obj_name).collect do |row|
278
+ select column_id, column_name, data_default
279
+ from all_tab_columns
280
+ where owner = :1
281
+ and table_name = :2
282
+ EOS
283
+ col_id, col_name, default = row
284
+
285
+ col = cols[col_id.to_i - 1]
286
+ col_name = col['name']
287
+
288
+ if default && default[0] == ?'
289
+ default = default[1..-2].gsub(/''/, "'")
290
+ end
291
+
292
+ col['indexed'] = indices[col_name] || false
293
+ col['primary'] = primaries[col_name] || false
294
+ col['unique'] = uniques[col_name] || false
295
+ col['default'] = default
296
+ col
297
+ end
298
+ rescue OCIException => err
299
+ raise_dbierror(err)
300
+ end
301
+
302
+ def [](attr)
303
+ case attr
304
+ when 'AutoCommit'
305
+ @handle.autocommit?
306
+ end
307
+ end
308
+
309
+ def []=(attr, value)
310
+ case attr
311
+ when 'AutoCommit'
312
+ @handle.autocommit = value
313
+ end
314
+ end
315
+
316
+ private
317
+
318
+ class DummyQuoter # :nodoc:
319
+ # dummy to substitute ?-style parameter markers by :1 :2 etc.
320
+ def quote(str)
321
+ str
322
+ end
323
+ end
324
+ end
325
+
326
+ class Statement < DBI::BaseStatement
327
+ include Util
328
+
329
+ def initialize(cursor)
330
+ @cursor = cursor
331
+ end
332
+
333
+ def bind_param( param, value, attribs)
334
+ if attribs.nil? || attribs['type'].nil?
335
+ if value.nil?
336
+ @cursor.bind_param(param, nil, String, 1)
337
+ else
338
+ @cursor.bind_param(param, value)
339
+ end
340
+ else
341
+ case attribs['type']
342
+ when SQL_BINARY
343
+ type = OCI_TYPECODE_RAW
344
+ else
345
+ type = attribs['type']
346
+ end
347
+ @cursor.bind_param(param, value, type)
348
+ end
349
+ rescue OCIException => err
350
+ raise_dbierror(err)
351
+ end
352
+
353
+ def execute
354
+ @cursor.exec
355
+ rescue OCIException => err
356
+ raise_dbierror(err)
357
+ end
358
+
359
+ def finish
360
+ @cursor.close
361
+ rescue OCIException => err
362
+ raise_dbierror(err)
363
+ end
364
+
365
+ def fetch
366
+ @cursor.fetch
367
+ rescue OCIException => err
368
+ raise_dbierror(err)
369
+ end
370
+
371
+ def column_info
372
+ # minimum implementation.
373
+ @cursor.column_metadata.collect do |md|
374
+ col = column_metadata_to_column_info(md)
375
+ col['indexed'] = nil
376
+ col['primary'] = nil
377
+ col['unique'] = nil
378
+ col['default'] = nil
379
+ col
380
+ end
381
+ rescue OCIException => err
382
+ raise_dbierror(err)
383
+ end
384
+
385
+ def rows
386
+ @cursor.row_count
387
+ rescue OCIException => err
388
+ raise_dbierror(err)
389
+ end
390
+
391
+ def __rowid
392
+ @cursor.rowid
393
+ end
394
+
395
+ def __define(pos, type, length = nil)
396
+ @cursor.define(pos, type, length)
397
+ self
398
+ end
399
+
400
+ def __bind_value(param)
401
+ @cursor[param]
402
+ end
403
+ end
404
+
405
+ # DBI_STMT_NEW_ARGS is DBI::StatementHandle.new's arguments except +handle+.
406
+ #
407
+ # FYI: DBI::StatementHandle.new method signatures are follows:
408
+ # 0.2.2: handle, fetchable=false, prepared=true
409
+ # 0.4.0: handle, fetchable=false, prepared=true, convert_types=true
410
+ # 0.4.1: handle, fetchable=false, prepared=true, convert_types=true, executed=false
411
+ begin
412
+ DBI::StatementHandle.new(nil, false, true, true, true)
413
+ # dbi 0.4.1
414
+ DBI_STMT_NEW_ARGS = [true, true, true, true] # :nodoc:
415
+ rescue ArgumentError
416
+ # dbi 0.4.0 or lower
417
+ DBI_STMT_NEW_ARGS = [true] # :nodoc:
418
+ end
419
+
420
+ if defined? ::OCI8::BindType::Base
421
+ ##
422
+ ## ruby-oci8 2.0 bind classes.
423
+ ##
424
+
425
+ module BindType # :nodoc:
426
+
427
+ # helper class to define/bind DBI::Date.
428
+ class DBIDate < ::OCI8::BindType::OraDate
429
+ def set(val)
430
+ # convert val to an OraDate,
431
+ # then set it to the bind handle.
432
+ super(val && OraDate.new(val.year, val.month, val.day))
433
+ end
434
+ def get()
435
+ # get an Oradate from the bind handle,
436
+ # then convert it to a DBI::Date.
437
+ val = super()
438
+ return nil if val.nil?
439
+ DBI::Date.new(val.year, val.month, val.day)
440
+ end
441
+ end
442
+
443
+ # helper class to define/bind DBI::Timestamp.
444
+ #
445
+ # To fetch all Oracle's DATE columns as DBI::Timestamp:
446
+ # ::OCI8::BindType::Mapping[OCI8::SQLT_DAT] = ::DBI::DBD::OCI8::BindType::DBITimestamp
447
+ #
448
+ class DBITimestamp < ::OCI8::BindType::OraDate
449
+ def set(val)
450
+ # convert val to an OraDate,
451
+ # then set it to the bind handle.
452
+ super(val && OraDate.new(val.year, val.month, val.day,
453
+ val.respond_to?(:hour) ? val.hour : 0,
454
+ val.respond_to?(:min) ? val.min : 0,
455
+ val.respond_to?(:sec) ? val.sec : 0))
456
+ end
457
+ def get()
458
+ # get an Oradate from the bind handle,
459
+ # then convert it to a DBI::Timestamp.
460
+ val = super()
461
+ return nil if val.nil?
462
+ DBI::Timestamp.new(val.year, val.month, val.day, val.hour, val.minute, val.second)
463
+ end
464
+ end
465
+
466
+ # helper class to bind ref cursor as DBI::StatementHandle.
467
+ #
468
+ # # Create package
469
+ # dbh.execute(<<EOS)
470
+ # create or replace package test_pkg is
471
+ # type ref_cursor is ref cursor;
472
+ # procedure tab_table(csr out ref_cursor);
473
+ # end;
474
+ # EOS
475
+ #
476
+ # # Create package body
477
+ # dbh.execute(<<EOS)
478
+ # create or replace package body test_pkg is
479
+ # procedure tab_table(csr out ref_cursor) is
480
+ # begin
481
+ # open csr for select * from tab;
482
+ # end;
483
+ # end;
484
+ # EOS
485
+ #
486
+ # # Execute test_pkg.tab_table.
487
+ # # The first parameter is bound as DBI::StatementHandle.
488
+ # plsql = dbh.execute("begin test_pkg.tab_table(?); end;", DBI::StatementHandle)
489
+ #
490
+ # # Get the first parameter, which is a DBI::StatementHandle.
491
+ # sth = plsql.func(:bind_value, 1)
492
+ #
493
+ # # fetch column data.
494
+ # sth.fetch_all
495
+ #
496
+ class DBIStatementHandle < ::OCI8::BindType::Cursor
497
+ def set(val)
498
+ if val.is_a? DBI::StatementHandle
499
+ # get OCI8::Cursor
500
+ val = val.instance_eval do @handle end
501
+ val = val.instance_eval do @cursor end
502
+ end
503
+ super(val)
504
+ end
505
+ def get()
506
+ val = super
507
+ return nil if val.nil?
508
+ stmt = DBI::DBD::OCI8::Statement.new(val)
509
+ DBI::StatementHandle.new(stmt, *DBI_STMT_NEW_ARGS)
510
+ end
511
+ end
512
+ end # BindType
513
+
514
+ else
515
+ ##
516
+ ## ruby-oci8 1.0 bind classes.
517
+ ##
518
+
519
+ module BindType # :nodoc:
520
+ DBIDate = Object.new
521
+ class << DBIDate
522
+ def fix_type(env, val, length, precision, scale)
523
+ # bind as an OraDate
524
+ [::OCI8::SQLT_DAT, val, nil]
525
+ end
526
+ def decorate(b)
527
+ def b.set(val)
528
+ # convert val to an OraDate,
529
+ # then set it to the bind handle.
530
+ super(val && OraDate.new(val.year, val.month, val.day))
531
+ end
532
+ def b.get()
533
+ # get an Oradate from the bind handle,
534
+ # then convert it to a DBI::Date.
535
+ (val = super()) && DBI::Date.new(val.year, val.month, val.day)
536
+ end
537
+ end
538
+ end
539
+
540
+ DBITimestamp = Object.new
541
+ class << DBITimestamp
542
+ def fix_type(env, val, length, precision, scale)
543
+ # bind as an OraDate
544
+ [::OCI8::SQLT_DAT, val, nil]
545
+ end
546
+ def decorate(b)
547
+ def b.set(val)
548
+ # convert val to an OraDate,
549
+ # then set it to the bind handle.
550
+ super(val && OraDate.new(val.year, val.month, val.day,
551
+ val.respond_to?(:hour) ? val.hour : 0,
552
+ val.respond_to?(:min) ? val.min : 0,
553
+ val.respond_to?(:sec) ? val.sec : 0))
554
+ end
555
+ def b.get()
556
+ # get an Oradate from the bind handle,
557
+ # then convert it to a DBI::Timestamp.
558
+ (val = super()) && DBI::Timestamp.new(val.year, val.month, val.day, val.hour, val.minute, val.second)
559
+ end
560
+ end
561
+ end
562
+
563
+ DBIStatementHandle = Object.new
564
+ class << DBIStatementHandle
565
+ def fix_type(env, val, length, precision, scale)
566
+ raise NotImplementedError unless val.nil?
567
+ [::OCI8::SQLT_RSET, nil, env.alloc(OCIStmt)]
568
+ end
569
+ def decorate(b)
570
+ def b.set(val)
571
+ raise NotImplementedError
572
+ end
573
+ def b.get()
574
+ val = super
575
+ return val if val.nil?
576
+ cur = ::OCI8::Cursor.new(@env, @svc, @ctx, val)
577
+ stmt = DBI::DBD::OCI8::Statement.new(cur)
578
+ DBI::StatementHandle.new(stmt, *DBI_STMT_NEW_ARGS)
579
+ end
580
+ end
581
+ end
582
+ end # BindType
583
+ end
584
+
585
+ ::OCI8::BindType::Mapping[DBI::Date] = BindType::DBIDate
586
+ ::OCI8::BindType::Mapping[DBI::Timestamp] = BindType::DBITimestamp
587
+ ::OCI8::BindType::Mapping[DBI::StatementHandle] = BindType::DBIStatementHandle
588
+
589
+ end # module OCI8
590
+ end # module DBD
591
+ end # module DBI