ruby-oci8 1.0.2-i386-mswin32

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 (49) hide show
  1. data/ChangeLog +569 -0
  2. data/Makefile +51 -0
  3. data/NEWS +322 -0
  4. data/README +415 -0
  5. data/VERSION +1 -0
  6. data/dist-files +70 -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/ext/oci8/oci8lib.so +0 -0
  13. data/lib/DBD/OCI8/OCI8.rb +549 -0
  14. data/lib/oci8.rb +1605 -0
  15. data/lib/oci8.rb.in +1605 -0
  16. data/metaconfig +142 -0
  17. data/pre-distclean.rb +7 -0
  18. data/ruby-oci8.gemspec +54 -0
  19. data/ruby-oci8.spec +62 -0
  20. data/setup.rb +1331 -0
  21. data/support/README +4 -0
  22. data/support/runit/assert.rb +281 -0
  23. data/support/runit/cui/testrunner.rb +101 -0
  24. data/support/runit/error.rb +4 -0
  25. data/support/runit/method_mappable.rb +20 -0
  26. data/support/runit/robserver.rb +25 -0
  27. data/support/runit/setuppable.rb +15 -0
  28. data/support/runit/teardownable.rb +16 -0
  29. data/support/runit/testcase.rb +113 -0
  30. data/support/runit/testfailure.rb +25 -0
  31. data/support/runit/testresult.rb +121 -0
  32. data/support/runit/testsuite.rb +43 -0
  33. data/support/runit/version.rb +3 -0
  34. data/test/README +4 -0
  35. data/test/config.rb +129 -0
  36. data/test/test_all.rb +43 -0
  37. data/test/test_bind_raw.rb +53 -0
  38. data/test/test_bind_time.rb +191 -0
  39. data/test/test_break.rb +81 -0
  40. data/test/test_clob.rb +101 -0
  41. data/test/test_connstr.rb +80 -0
  42. data/test/test_dbi.rb +317 -0
  43. data/test/test_dbi_clob.rb +56 -0
  44. data/test/test_describe.rb +137 -0
  45. data/test/test_metadata.rb +243 -0
  46. data/test/test_oci8.rb +273 -0
  47. data/test/test_oradate.rb +263 -0
  48. data/test/test_oranumber.rb +149 -0
  49. metadata +97 -0
data/doc/manual.css ADDED
@@ -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
+ }
Binary file
@@ -0,0 +1,549 @@
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.2"
46
+
47
+ module Util
48
+
49
+ ERROR_MAP = {
50
+ 1 => DBI::IntegrityError, # unique constraint violated
51
+ 900 => DBI::ProgrammingError, # invalid SQL statement
52
+ 904 => DBI::ProgrammingError, # invalid identifier
53
+ 905 => DBI::ProgrammingError, # missing keyword
54
+ 923 => DBI::ProgrammingError, # FROM keyword not found where expected
55
+ 936 => DBI::ProgrammingError, # missing expression
56
+ 942 => DBI::ProgrammingError, # table or view does not exist
57
+ 2290 => DBI::IntegrityError, # check constraint violated
58
+ 2291 => DBI::IntegrityError, # parent key not found
59
+ 2292 => DBI::IntegrityError, # child record found
60
+ 2293 => DBI::IntegrityError, # check constraint violated
61
+ }
62
+
63
+ def raise_dbierror(err) # :nodoc:
64
+ if err.is_a? OCIError
65
+ exc = ERROR_MAP[err.code] || DBI::DatabaseError
66
+ raise exc.new(err.message, err.code)
67
+ else
68
+ raise DBI::DatabaseError.new(err.message, -1)
69
+ end
70
+ rescue DBI::DatabaseError => exc
71
+ exc.set_backtrace(err.backtrace)
72
+ raise
73
+ end
74
+
75
+ def column_metadata_to_column_info(col)
76
+ sql_type, type_name, precision, scale =
77
+ case col.data_type
78
+ when :char
79
+ [SQL_CHAR, col.charset_form == :nchar ? "NCHAR" : "CHAR", col.data_size, nil]
80
+ when :varchar2
81
+ [SQL_VARCHAR, col.charset_form == :nchar ? "NVARCHAR2" : "VARCHAR2", col.data_size, nil]
82
+ when :raw
83
+ [SQL_VARBINARY, "RAW", col.data_size, nil]
84
+ when :long
85
+ [SQL_LONGVARCHAR, "LONG", 4000, nil]
86
+ when :long_raw
87
+ [SQL_LONGVARBINARY, "LONG RAW", 4000, nil]
88
+ when :clob
89
+ [SQL_CLOB, col.charset_form == :nchar ? "NCLOB" : "CLOB", 4000, nil]
90
+ when :blob
91
+ [SQL_BLOB, "BLOB", 4000, nil]
92
+ when :bfile
93
+ [SQL_BLOB, "BFILE", 4000, nil]
94
+ when :number
95
+ if col.scale == -127 && col.precision != 0
96
+ # To convert from binary to decimal precision, multiply n by 0.30103.
97
+ [SQL_FLOAT, "FLOAT", (col.precision * 0.30103).ceil , nil]
98
+ elsif col.precision == 0
99
+ # NUMBER or calculated value (eg. col * 1.2).
100
+ [SQL_NUMERIC, "NUMBER", 38, nil]
101
+ else
102
+ [SQL_NUMERIC, "NUMBER", col.precision, col.scale]
103
+ end
104
+ when :binary_float
105
+ # (23 * 0.30103).ceil => 7
106
+ [SQL_FLOAT, "BINARY_FLOAT", 7, nil]
107
+ when :binary_double
108
+ # (52 * 0.30103).ceil => 16
109
+ [SQL_DOUBLE, "BINARY_DOUBLE", 16, nil]
110
+ when :date
111
+ # yyyy-mm-dd hh:mi:ss
112
+ [SQL_DATE, "DATE", 19, nil]
113
+ when :timestamp
114
+ # yyyy-mm-dd hh:mi:ss.SSSS
115
+ [SQL_TIMESTAMP, "TIMESTAMP", 20 + col.fsprecision, nil]
116
+ when :timestamp_tz
117
+ # yyyy-mm-dd hh:mi:ss.SSSS +HH:MM
118
+ [SQL_TIMESTAMP, "TIMESTAMP WITH TIME ZONE", 27 + col.fsprecision, nil]
119
+ when :timestamp_ltz
120
+ # yyyy-mm-dd hh:mi:ss.SSSS
121
+ [SQL_TIMESTAMP, "TIMESTAMP WITH LOCAL TIME ZONE", 20 + col.fsprecision, nil]
122
+ when :interval_ym
123
+ # yyyy-mm
124
+ [SQL_OTHER, 'INTERVAL YEAR TO MONTH', col.lfprecision + 3, nil]
125
+ when :interval_ds
126
+ # dd hh:mi:ss.SSSSS
127
+ [SQL_OTHER, 'INTERVAL DAY TO SECOND', col.lfprecision + 10 + col.fsprecision, nil]
128
+ else
129
+ [SQL_OTHER, col.data_type.to_s, nil, nil]
130
+ end
131
+ {'name' => col.name,
132
+ 'sql_type' => sql_type,
133
+ 'type_name' => type_name,
134
+ 'nullable' => col.nullable?,
135
+ 'precision' => precision,
136
+ 'scale' => scale,
137
+ }
138
+ end
139
+ private :column_metadata_to_column_info
140
+ end
141
+
142
+ class Driver < DBI::BaseDriver # :nodoc:
143
+ include Util
144
+
145
+ def initialize
146
+ super(USED_DBD_VERSION)
147
+ end
148
+
149
+ # external OS authentication
150
+ # (contributed by Dan Fitch)
151
+ def default_user
152
+ [nil, nil]
153
+ end
154
+
155
+ def connect( dbname, user, auth, attr )
156
+ handle = ::OCI8.new(user, auth, dbname, attr['Privilege'])
157
+ handle.non_blocking = true if attr['NonBlocking']
158
+ return Database.new(handle, attr)
159
+ rescue OCIException => err
160
+ raise_dbierror(err)
161
+ end
162
+ end
163
+
164
+ class Database < DBI::BaseDatabase
165
+ include Util
166
+
167
+ def disconnect
168
+ @handle.logoff
169
+ rescue OCIException => err
170
+ raise_dbierror(err)
171
+ end
172
+
173
+ def prepare( statement )
174
+ # convert ?-style parameters to :1, :2 etc.
175
+ prep_statement = DBI::SQL::PreparedStatement.new(DummyQuoter.new, statement)
176
+ if prep_statement.unbound.size > 0
177
+ arr = (1..(prep_statement.unbound.size)).collect{|i| ":#{i}"}
178
+ statement = prep_statement.bind( arr )
179
+ end
180
+ cursor = @handle.parse(statement)
181
+ Statement.new(cursor)
182
+ rescue OCIException => err
183
+ raise_dbierror(err)
184
+ end
185
+
186
+ def ping
187
+ @handle.exec("BEGIN NULL; END;")
188
+ true
189
+ rescue
190
+ false
191
+ end
192
+
193
+ def commit
194
+ @handle.commit()
195
+ rescue OCIException => err
196
+ raise_dbierror(err)
197
+ end
198
+
199
+ def rollback
200
+ @handle.rollback()
201
+ rescue OCIException => err
202
+ raise_dbierror(err)
203
+ end
204
+
205
+ def tables
206
+ stmt = execute("SELECT object_name FROM user_objects where object_type in ('TABLE', 'VIEW')")
207
+ rows = stmt.fetch_all || []
208
+ stmt.finish
209
+ rows.collect {|row| row[0]}
210
+ end
211
+
212
+ # SQLs are copied from DBD::Oracle.
213
+ def columns(table)
214
+ tab = @handle.describe_table(table)
215
+ cols = tab.columns
216
+ cols.collect! do |col|
217
+ column_metadata_to_column_info(col)
218
+ end
219
+
220
+ dbh = DBI::DatabaseHandle.new(self)
221
+
222
+ pk_index_name = nil
223
+ dbh.select_all(<<EOS, tab.obj_schema, tab.obj_name) do |row|
224
+ select index_name
225
+ from all_constraints
226
+ where constraint_type = 'P'
227
+ and owner = :1
228
+ and table_name = :2
229
+ EOS
230
+ pk_index_name = row[0]
231
+ end
232
+
233
+ indices = {}
234
+ primaries = {}
235
+ uniques = {}
236
+ dbh.select_all(<<EOS, tab.obj_schema, tab.obj_name) do |row|
237
+ select a.column_name, a.index_name, b.uniqueness
238
+ from all_ind_columns a, all_indexes b
239
+ where a.index_name = b.index_name
240
+ and a.index_owner = b.owner
241
+ and a.table_owner = :1
242
+ and a.table_name = :2
243
+ EOS
244
+ col_name, index_name, uniqueness = row
245
+ indices[col_name] = true
246
+ primaries[col_name] = true if index_name == pk_index_name
247
+ uniques[col_name] = true if uniqueness == 'UNIQUE'
248
+ end
249
+
250
+ dbh.select_all(<<EOS, tab.obj_schema, tab.obj_name).collect do |row|
251
+ select column_id, column_name, data_default
252
+ from all_tab_columns
253
+ where owner = :1
254
+ and table_name = :2
255
+ EOS
256
+ col_id, col_name, default = row
257
+
258
+ col = cols[col_id.to_i - 1]
259
+ col_name = col['name']
260
+
261
+ if default && default[0] == ?'
262
+ default = default[1..-2].gsub(/''/, "'")
263
+ end
264
+
265
+ col['indexed'] = indices[col_name] || false
266
+ col['primary'] = primaries[col_name] || false
267
+ col['unique'] = uniques[col_name] || false
268
+ col['default'] = default
269
+ col
270
+ end
271
+ rescue OCIException => err
272
+ raise_dbierror(err)
273
+ end
274
+
275
+ def [](attr)
276
+ case attr
277
+ when 'AutoCommit'
278
+ @handle.autocommit?
279
+ end
280
+ end
281
+
282
+ def []=(attr, value)
283
+ case attr
284
+ when 'AutoCommit'
285
+ @handle.autocommit = value
286
+ end
287
+ end
288
+
289
+ private
290
+
291
+ class DummyQuoter # :nodoc:
292
+ # dummy to substitute ?-style parameter markers by :1 :2 etc.
293
+ def quote(str)
294
+ str
295
+ end
296
+ end
297
+ end
298
+
299
+ class Statement < DBI::BaseStatement
300
+ include Util
301
+
302
+ def initialize(cursor)
303
+ @cursor = cursor
304
+ end
305
+
306
+ def bind_param( param, value, attribs)
307
+ if attribs.nil? || attribs['type'].nil?
308
+ if value.nil?
309
+ @cursor.bind_param(param, nil, String, 1)
310
+ else
311
+ @cursor.bind_param(param, value)
312
+ end
313
+ else
314
+ case attribs['type']
315
+ when SQL_BINARY
316
+ type = OCI_TYPECODE_RAW
317
+ else
318
+ type = attribs['type']
319
+ end
320
+ @cursor.bind_param(param, value, type)
321
+ end
322
+ rescue OCIException => err
323
+ raise_dbierror(err)
324
+ end
325
+
326
+ def execute
327
+ @cursor.exec
328
+ rescue OCIException => err
329
+ raise_dbierror(err)
330
+ end
331
+
332
+ def finish
333
+ @cursor.close
334
+ rescue OCIException => err
335
+ raise_dbierror(err)
336
+ end
337
+
338
+ def fetch
339
+ @cursor.fetch
340
+ rescue OCIException => err
341
+ raise_dbierror(err)
342
+ end
343
+
344
+ def column_info
345
+ # minimum implementation.
346
+ @cursor.column_metadata.collect do |md|
347
+ col = column_metadata_to_column_info(md)
348
+ col['indexed'] = nil
349
+ col['primary'] = nil
350
+ col['unique'] = nil
351
+ col['default'] = nil
352
+ col
353
+ end
354
+ rescue OCIException => err
355
+ raise_dbierror(err)
356
+ end
357
+
358
+ def rows
359
+ @cursor.row_count
360
+ rescue OCIException => err
361
+ raise_dbierror(err)
362
+ end
363
+
364
+ def __rowid
365
+ @cursor.rowid
366
+ end
367
+
368
+ def __define(pos, type, length = nil)
369
+ @cursor.define(pos, type, length)
370
+ self
371
+ end
372
+
373
+ def __bind_value(param)
374
+ @cursor[param]
375
+ end
376
+ end
377
+
378
+ if defined? ::OCI8::BindType::Base
379
+ ##
380
+ ## ruby-oci8 2.0 bind classes.
381
+ ##
382
+
383
+ module BindType # :nodoc:
384
+
385
+ # helper class to define/bind DBI::Date.
386
+ class DBIDate < ::OCI8::BindType::OraDate
387
+ def set(val)
388
+ # convert val to an OraDate,
389
+ # then set it to the bind handle.
390
+ super(val && OraDate.new(val.year, val.month, val.day))
391
+ end
392
+ def get()
393
+ # get an Oradate from the bind handle,
394
+ # then convert it to a DBI::Date.
395
+ val = super()
396
+ return nil if val.nil?
397
+ DBI::Date.new(val.year, val.month, val.day)
398
+ end
399
+ end
400
+
401
+ # helper class to define/bind DBI::Timestamp.
402
+ #
403
+ # To fetch all Oracle's DATE columns as DBI::Timestamp:
404
+ # ::OCI8::BindType::Mapping[OCI8::SQLT_DAT] = ::DBI::DBD::OCI8::BindType::DBITimestamp
405
+ #
406
+ class DBITimestamp < ::OCI8::BindType::OraDate
407
+ def set(val)
408
+ # convert val to an OraDate,
409
+ # then set it to the bind handle.
410
+ super(val && OraDate.new(val.year, val.month, val.day,
411
+ val.respond_to?(:hour) ? val.hour : 0,
412
+ val.respond_to?(:min) ? val.min : 0,
413
+ val.respond_to?(:sec) ? val.sec : 0))
414
+ end
415
+ def get()
416
+ # get an Oradate from the bind handle,
417
+ # then convert it to a DBI::Timestamp.
418
+ val = super()
419
+ return nil if val.nil?
420
+ DBI::Timestamp.new(val.year, val.month, val.day, val.hour, val.minute, val.second)
421
+ end
422
+ end
423
+
424
+ # helper class to bind ref cursor as DBI::StatementHandle.
425
+ #
426
+ # # Create package
427
+ # dbh.execute(<<EOS)
428
+ # create or replace package test_pkg is
429
+ # type ref_cursor is ref cursor;
430
+ # procedure tab_table(csr out ref_cursor);
431
+ # end;
432
+ # EOS
433
+ #
434
+ # # Create package body
435
+ # dbh.execute(<<EOS)
436
+ # create or replace package body test_pkg is
437
+ # procedure tab_table(csr out ref_cursor) is
438
+ # begin
439
+ # open csr for select * from tab;
440
+ # end;
441
+ # end;
442
+ # EOS
443
+ #
444
+ # # Execute test_pkg.tab_table.
445
+ # # The first parameter is bound as DBI::StatementHandle.
446
+ # plsql = dbh.execute("begin test_pkg.tab_table(?); end;", DBI::StatementHandle)
447
+ #
448
+ # # Get the first parameter, which is a DBI::StatementHandle.
449
+ # sth = plsql.func(:bind_value, 1)
450
+ #
451
+ # # fetch column data.
452
+ # sth.fetch_all
453
+ #
454
+ class DBIStatementHandle < ::OCI8::BindType::Cursor
455
+ def set(val)
456
+ if val.is_a? DBI::StatementHandle
457
+ # get OCI8::Cursor
458
+ val = val.instance_eval do @handle end
459
+ val = val.instance_eval do @cursor end
460
+ end
461
+ super(val)
462
+ end
463
+ def get()
464
+ val = super
465
+ return nil if val.nil?
466
+ stmt = DBI::DBD::OCI8::Statement.new(val)
467
+ DBI::StatementHandle.new(stmt, true, false)
468
+ end
469
+ end
470
+ end # BindType
471
+
472
+ else
473
+ ##
474
+ ## ruby-oci8 1.0 bind classes.
475
+ ##
476
+
477
+ module BindType # :nodoc:
478
+ DBIDate = Object.new
479
+ class << DBIDate
480
+ def fix_type(env, val, length, precision, scale)
481
+ # bind as an OraDate
482
+ [::OCI8::SQLT_DAT, val, nil]
483
+ end
484
+ def decorate(b)
485
+ def b.set(val)
486
+ # convert val to an OraDate,
487
+ # then set it to the bind handle.
488
+ super(val && OraDate.new(val.year, val.month, val.day))
489
+ end
490
+ def b.get()
491
+ # get an Oradate from the bind handle,
492
+ # then convert it to a DBI::Date.
493
+ (val = super()) && DBI::Date.new(val.year, val.month, val.day)
494
+ end
495
+ end
496
+ end
497
+
498
+ DBITimestamp = Object.new
499
+ class << DBITimestamp
500
+ def fix_type(env, val, length, precision, scale)
501
+ # bind as an OraDate
502
+ [::OCI8::SQLT_DAT, val, nil]
503
+ end
504
+ def decorate(b)
505
+ def b.set(val)
506
+ # convert val to an OraDate,
507
+ # then set it to the bind handle.
508
+ super(val && OraDate.new(val.year, val.month, val.day,
509
+ val.respond_to?(:hour) ? val.hour : 0,
510
+ val.respond_to?(:min) ? val.min : 0,
511
+ val.respond_to?(:sec) ? val.sec : 0))
512
+ end
513
+ def b.get()
514
+ # get an Oradate from the bind handle,
515
+ # then convert it to a DBI::Timestamp.
516
+ (val = super()) && DBI::Timestamp.new(val.year, val.month, val.day, val.hour, val.minute, val.second)
517
+ end
518
+ end
519
+ end
520
+
521
+ DBIStatementHandle = Object.new
522
+ class << DBIStatementHandle
523
+ def fix_type(env, val, length, precision, scale)
524
+ raise NotImplementedError unless val.nil?
525
+ [::OCI8::SQLT_RSET, nil, env.alloc(OCIStmt)]
526
+ end
527
+ def decorate(b)
528
+ def b.set(val)
529
+ raise NotImplementedError
530
+ end
531
+ def b.get()
532
+ val = super
533
+ return val if val.nil?
534
+ cur = ::OCI8::Cursor.new(@env, @svc, @ctx, val)
535
+ stmt = DBI::DBD::OCI8::Statement.new(cur)
536
+ DBI::StatementHandle.new(stmt, true, false)
537
+ end
538
+ end
539
+ end
540
+ end # BindType
541
+ end
542
+
543
+ ::OCI8::BindType::Mapping[DBI::Date] = BindType::DBIDate
544
+ ::OCI8::BindType::Mapping[DBI::Timestamp] = BindType::DBITimestamp
545
+ ::OCI8::BindType::Mapping[DBI::StatementHandle] = BindType::DBIStatementHandle
546
+
547
+ end # module OCI8
548
+ end # module DBD
549
+ end # module DBI