ruby-oci8 2.1.5 → 2.1.6

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.
@@ -124,6 +124,7 @@ static VALUE attr_get_common(int argc, VALUE *argv, VALUE self, enum datatype da
124
124
  oci8_base_t *base = DATA_PTR(self);
125
125
  VALUE attr_type;
126
126
  VALUE strict;
127
+ VALUE args[6];
127
128
  union {
128
129
  ub1 ub1val;
129
130
  ub2 ub2val;
@@ -140,6 +141,10 @@ static VALUE attr_get_common(int argc, VALUE *argv, VALUE self, enum datatype da
140
141
  ub4 size = 0;
141
142
  sword rv;
142
143
 
144
+ if (base->type == 0) {
145
+ return Qnil;
146
+ }
147
+
143
148
  v.ub8val = MAGIC_NUMBER;
144
149
  rb_scan_args(argc, argv, "11", &attr_type, &strict);
145
150
  if (argc == 1) {
@@ -193,13 +198,13 @@ static VALUE attr_get_common(int argc, VALUE *argv, VALUE self, enum datatype da
193
198
  case DATATYPE_ORADATE:
194
199
  if (NIL_P(cOraDate))
195
200
  cOraDate = rb_eval_string("OraDate");
196
- return rb_funcall(cOraDate, oci8_id_new, 6,
197
- INT2FIX((v.ub1ptr[0] - 100) * 100 + (v.ub1ptr[1] - 100)),
198
- INT2FIX(v.ub1ptr[2]),
199
- INT2FIX(v.ub1ptr[3]),
200
- INT2FIX(v.ub1ptr[4] - 1),
201
- INT2FIX(v.ub1ptr[5] - 1),
202
- INT2FIX(v.ub1ptr[6] - 1));
201
+ args[0] = INT2FIX((v.ub1ptr[0] - 100) * 100 + (v.ub1ptr[1] - 100));
202
+ args[1] = INT2FIX(v.ub1ptr[2]);
203
+ args[2] = INT2FIX(v.ub1ptr[3]);
204
+ args[3] = INT2FIX(v.ub1ptr[4] - 1);
205
+ args[4] = INT2FIX(v.ub1ptr[5] - 1);
206
+ args[5] = INT2FIX(v.ub1ptr[6] - 1);
207
+ return rb_class_new_instance(6, args, cOraDate);
203
208
  }
204
209
  return Qnil;
205
210
  }
@@ -334,8 +334,9 @@ Backtrace:
334
334
  #{$!.backtrace.join("\n ")}
335
335
  ---------------------------------------------------
336
336
  See:
337
- * http://ruby-oci8.rubyforge.org/#{lang}/HowToInstall.html
338
- * http://ruby-oci8.rubyforge.org/#{lang}/ReportInstallProblem.html
337
+ * http://ruby-oci8.rubyforge.org/en/file.install-full-client.html for Oracle full client
338
+ * http://ruby-oci8.rubyforge.org/en/file.install-instant-client.html for Oracle instant client
339
+ * http://ruby-oci8.rubyforge.org/en/file.report-installation-issue.html to report an issue.
339
340
 
340
341
  EOS
341
342
  exc = RuntimeError.new
@@ -391,7 +392,7 @@ EOS
391
392
  when /mswin32|cygwin|mingw32|bccwin32/
392
393
  oci_basename = 'oci'
393
394
  oci_glob_postfix = ''
394
- nls_data_basename = ['oraociei11', 'oraociicus11', 'oraociei10', 'oraociicus10']
395
+ nls_data_basename = ['oraociei*', 'oraociicus*']
395
396
  @@ld_envs = %w[PATH]
396
397
  so_ext = 'dll'
397
398
  check_proc = make_proc_to_check_cpu(is_32bit ? :i386 : :x86_64)
@@ -523,7 +524,7 @@ EOS
523
524
  if ld_path
524
525
  nls_data_ext ||= so_ext # nls_data_ext is same with so_ext by default.
525
526
  nls_data_basename.each do |basename|
526
- if File.exist?(File.join(ld_path, "#{basename}.#{nls_data_ext}"))
527
+ if Dir.glob(File.join(ld_path, "#{basename}.#{nls_data_ext}")).size > 0
527
528
  puts " #{file} looks like an instant client."
528
529
  return ld_path
529
530
  end
@@ -645,12 +646,13 @@ EOS
645
646
 
646
647
  def get_libs(lib_dir)
647
648
  case RUBY_PLATFORM
648
- when /cygwin/
649
+ when /cygwin|x64-mingw32/
650
+ regex = ([nil].pack('P').size == 8) ? / T (OCI\w+)/ : / T _(OCI\w+)/
649
651
  open("OCI.def", "w") do |f|
650
652
  f.puts("EXPORTS")
651
653
  open("|nm #{lib_dir}/MSVC/OCI.LIB") do |r|
652
654
  while line = r.gets
653
- f.puts($') if line =~ / T _/
655
+ f.puts($1) if regex =~ line
654
656
  end
655
657
  end
656
658
  end
@@ -61,7 +61,7 @@ static VALUE oci8_stmt_initialize(VALUE self, VALUE svc, VALUE sql)
61
61
  if (!NIL_P(sql) && oracle_client_version >= ORAVER_9_2) {
62
62
  OCI8SafeStringValue(sql);
63
63
 
64
- rv = OCIStmtPrepare2(svcctx->base.hp.svc, &stmt->base.hp.stmt, oci8_errhp, RSTRING_ORATEXT(sql), RSTRING_LEN(sql), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT);
64
+ rv = OCIStmtPrepare2_nb(svcctx, svcctx->base.hp.svc, &stmt->base.hp.stmt, oci8_errhp, RSTRING_ORATEXT(sql), RSTRING_LEN(sql), NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT);
65
65
  if (IS_OCI_ERROR(rv)) {
66
66
  chker2(rv, &svcctx->base);
67
67
  }
@@ -342,7 +342,7 @@ static void bind_stmt_init_elem(oci8_bind_t *obind, VALUE svc)
342
342
  ub4 idx = 0;
343
343
 
344
344
  do {
345
- oho[idx].obj = rb_funcall(cOCIStmt, oci8_id_new, 1, svc);
345
+ oho[idx].obj = rb_class_new_instance(1, &svc, cOCIStmt);
346
346
  h = DATA_PTR(oho[idx].obj);
347
347
  oho[idx].hp = h->hp.ptr;
348
348
  } while (++idx < obind->maxar_sz);
@@ -50,8 +50,6 @@ when 'ruby'
50
50
  # if it wasn't explicitly changed by the configure option --with-ruby-version.
51
51
  #
52
52
  case RUBY_VERSION
53
- when /^2\.0/
54
- so_basename += RUBY_VERSION.gsub(/\W/, '')
55
53
  when /^1\.9\.0/
56
54
  raise 'unsupported ruby version: 1.9.0'
57
55
  when /^1\.9/
@@ -59,20 +57,10 @@ when 'ruby'
59
57
  when /^1\.8/
60
58
  so_basename += '18'
61
59
  else
62
- raise 'unsupported ruby version: ' + RUBY_VERSION
60
+ so_basename += RUBY_VERSION.gsub(/\W/, '')
63
61
  end
64
62
  when 'rbx'
65
- # "rbx -X18" and "rbx -X19" use different C header files.
66
- case RUBY_VERSION
67
- when /^2\.0/
68
- so_basename += 'rbx20'
69
- when /^1\.9/
70
- so_basename += 'rbx19'
71
- when /^1\.8/
72
- so_basename += 'rbx18'
73
- else
74
- raise 'unsupported language mode: ' + RUBY_VERSION
75
- end
63
+ so_basename += 'rbx'
76
64
  when 'jruby'
77
65
  raise "Ruby-oci8 doesn't support jruby because its C extension support is in development in jruby 1.6 and deprecated in jruby 1.7."
78
66
  else
@@ -104,6 +92,8 @@ class OCI8
104
92
  ORAVER_10_2 = OCI8::OracleVersion.new(10, 2)
105
93
  # @private
106
94
  ORAVER_11_1 = OCI8::OracleVersion.new(11, 1)
95
+ # @private
96
+ ORAVER_12_1 = OCI8::OracleVersion.new(12, 1)
107
97
 
108
98
  # @private
109
99
  @@oracle_client_version = OCI8::OracleVersion.new(self.oracle_client_vernum)
@@ -478,6 +478,8 @@ class OCI8
478
478
  elsif key.class == Class && key < OCI8::Object::Base
479
479
  param = @con.get_tdo_by_class(key)
480
480
  key = :named_type
481
+ elsif key == :named_type
482
+ param = @con.get_tdo_by_typename(param[:length])
481
483
  end
482
484
  when OCI8::Metadata::Base
483
485
  key = param.data_type
@@ -110,7 +110,7 @@ class OCI8
110
110
  Proc.new do |p|
111
111
  if p.charset_form == :nchar
112
112
  "NVARCHAR2(#{p.char_size})"
113
- elsif p.char_used?
113
+ elsif p.respond_to?(:char_used?) && p.char_used?
114
114
  "VARCHAR2(#{p.char_size} CHAR)"
115
115
  else
116
116
  "VARCHAR2(#{p.data_size})"
@@ -248,6 +248,12 @@ class OCI8
248
248
  "TIMESTAMP(#{fsprecision}) WITH LOCAL TIME ZONE"
249
249
  end
250
250
  end]
251
+ DATA_TYPE_MAP[245] = [:record,
252
+ Proc.new do |p|
253
+ "#{p.schema_name}.#{p.type_name}"
254
+ end]
255
+ DATA_TYPE_MAP[252] = [:boolean, "BOOLEAN"]
256
+ DATA_TYPE_MAP[266] = [:pls_integer, "PLS_INTEGER"]
251
257
 
252
258
  def __data_type # :nodoc:
253
259
  return @data_type if defined? @data_type
@@ -337,6 +343,9 @@ class OCI8
337
343
  #when 228; :sysfirst # OCI_TYPECODE_SYSFIRST
338
344
  #when 235; :syslast # OCI_TYPECODE_SYSLAST
339
345
  when 266; :pls_integer # OCI_TYPECODE_PLS_INTEGER
346
+ when 250; :record # OCI_TYPECODE_RECORD
347
+ when 251; :itable # OCI_TYPECODE_ITABLE
348
+ when 252; :boolean # OCI_TYPECODE_BOOLEAN
340
349
  end
341
350
  end
342
351
  end
@@ -632,6 +641,12 @@ class OCI8
632
641
  end
633
642
  private :list_subprograms
634
643
 
644
+ # package type list
645
+ def list_types # :nodoc:
646
+ __param(137) # OCI_ATTR_LIST_PKG_TYPES
647
+ end
648
+ private :list_types
649
+
635
650
  # Returns +true+ if the package subprograms have
636
651
  # {invoker's rights}[http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/subprograms.htm#i18574].
637
652
  # Otherwise, +false+.
@@ -647,6 +662,22 @@ class OCI8
647
662
  prog.instance_variable_set(:@is_standalone, false)
648
663
  end
649
664
  end
665
+
666
+ if OCI8.oracle_client_version < ORAVER_12_1
667
+ def types
668
+ raise "This version of the Oracle client does not support PL/SQL package type descriptions."
669
+ end
670
+ else
671
+ # Returns an array of types defined within the Package.
672
+ #
673
+ # @return [array of OCI8::Metadata::Type]
674
+ # @since 2.1.6
675
+ def types
676
+ @types ||= list_types.to_a.each do |type|
677
+ type.instance_variable_set(:@is_standalone, false)
678
+ end
679
+ end
680
+ end
650
681
  end
651
682
 
652
683
  # Information about types
@@ -851,6 +882,15 @@ class OCI8
851
882
  attr_get_string(OCI_ATTR_SUPERTYPE_NAME) if is_subtype?
852
883
  end
853
884
 
885
+ # Returns the package name if the type is a package type.
886
+ # Otherwise, +nil+.
887
+ #
888
+ # @return [String or nil]
889
+ # @since 2.1.6
890
+ def package_name
891
+ attr_get_string(12, false) # OCI_ATTR_PACKAGE_NAME
892
+ end
893
+
854
894
  # Returns attribute information of the type.
855
895
  #
856
896
  # @return [array of OCI8::Metadata::TypeAttr]
@@ -1199,6 +1239,7 @@ class OCI8
1199
1239
  # schema name of the synonym translation
1200
1240
  def schema_name
1201
1241
  @schema_name ||= attr_get_string(OCI_ATTR_SCHEMA_NAME)
1242
+ @schema_name.size == 0 ? nil : @schema_name
1202
1243
  end
1203
1244
 
1204
1245
  # object name of the synonym translation
@@ -1214,11 +1255,7 @@ class OCI8
1214
1255
 
1215
1256
  # full-qualified synonym translation name with schema, object and database link name.
1216
1257
  def translated_name
1217
- if link.nil?
1218
- schema_name + '.' + name
1219
- else
1220
- schema_name + '.' + name + '@' + link
1221
- end
1258
+ (schema_name ? schema_name + '.' : '') + name + (link ? '@' + link : '')
1222
1259
  end
1223
1260
 
1224
1261
  def inspect # :nodoc:
@@ -1487,10 +1524,21 @@ class OCI8
1487
1524
  end
1488
1525
 
1489
1526
  # Indicates whether an argument has a default
1527
+ #
1528
+ # @return [1 or 0]
1529
+ # @deprecated
1490
1530
  def has_default
1491
1531
  attr_get_ub1(OCI_ATTR_HAS_DEFAULT)
1492
1532
  end
1493
1533
 
1534
+ # Indicates whether an argument has a default
1535
+ #
1536
+ # @return [true or false]
1537
+ # @since 2.1.6
1538
+ def has_default?
1539
+ __boolean(OCI_ATTR_HAS_DEFAULT)
1540
+ end
1541
+
1494
1542
  # The list of arguments at the next level (when the argument is
1495
1543
  # of a record or table type).
1496
1544
  def list_arguments
@@ -1648,8 +1696,9 @@ class OCI8
1648
1696
  #when OCI_LTYPE_TABLE_ALIAS; offset = ?
1649
1697
  #when OCI_LTYPE_VARIABLE_TYPE; offset = ?
1650
1698
  #when OCI_LTYPE_NAME_VALUE; offset = ?
1699
+ when 15; offset = 0 # OCI_LTYPE_PACKAGE_TYPE
1651
1700
  else
1652
- raise NotImplementedError, "unsupported list type #{list.ltype}"
1701
+ raise NotImplementedError, "unsupported list type #{ltype}"
1653
1702
  end
1654
1703
  ary = []
1655
1704
  0.upto(num_params - 1) do |i|
@@ -1994,7 +2043,13 @@ class OCI8
1994
2043
  # @param [String] object_name
1995
2044
  # @return [a subclass of OCI8::Metadata::Base]
1996
2045
  def describe_any(object_name)
1997
- __describe(object_name, OCI8::Metadata::Unknown, true)
2046
+ if /^PUBLIC\.(.*)/i =~ object_name
2047
+ md = __describe($1, OCI8::Metadata::Unknown, true)
2048
+ raise OCIError.new(4043, object_name) if md.obj_schema != 'PUBLIC'
2049
+ md
2050
+ else
2051
+ __describe(object_name, OCI8::Metadata::Unknown, true)
2052
+ end
1998
2053
  end
1999
2054
  # Returns table or view information. If the name is a current schema's synonym
2000
2055
  # name or a public synonym name, it returns table or view information which
@@ -2066,7 +2121,13 @@ class OCI8
2066
2121
  # @param [String] synonym_name
2067
2122
  # @return [OCI8::Metadata::Synonym]
2068
2123
  def describe_synonym(synonym_name, check_public_also = true)
2069
- __describe(synonym_name, OCI8::Metadata::Synonym, check_public_also)
2124
+ if /^PUBLIC\.(.*)/i =~ synonym_name
2125
+ md = __describe($1, OCI8::Metadata::Synonym, true)
2126
+ raise OCIError.new(4043, synonym_name) if md.obj_schema != 'PUBLIC'
2127
+ md
2128
+ else
2129
+ __describe(synonym_name, OCI8::Metadata::Synonym, check_public_also)
2130
+ end
2070
2131
  end
2071
2132
  # Returns sequence information
2072
2133
  #
@@ -71,6 +71,29 @@ EOS
71
71
  OCI8::TDO.new(self, metadata, klass)
72
72
  end
73
73
 
74
+ # Returns the type descriptor object which correspond to the given type name.
75
+ #
76
+ # @param [String] typename
77
+ # @return [OCI8::TDO]
78
+ #
79
+ # @private
80
+ def get_tdo_by_typename(typename)
81
+ tdo = @name_to_tdo && @name_to_tdo[typename]
82
+ return tdo if tdo
83
+
84
+ metadata = describe_any(typename)
85
+ if metadata.is_a? OCI8::Metadata::Synonym
86
+ metadata = describe_any(metadata.translated_name)
87
+ end
88
+ unless metadata.is_a? OCI8::Metadata::Type
89
+ raise "unknown typename #{typename}"
90
+ end
91
+ tdo = get_tdo_by_metadata(metadata)
92
+
93
+ @name_to_tdo[typename] = tdo
94
+ tdo
95
+ end
96
+
74
97
  # A helper class to bind arguments.
75
98
  #
76
99
  # @private
@@ -57,7 +57,7 @@ EOS
57
57
  if so_vers[0] < '2.0.0'
58
58
  s.required_ruby_version = "~> #{so_vermin}"
59
59
  else
60
- s.required_ruby_version = "= #{so_vermin}"
60
+ s.required_ruby_version = "~> #{so_vermin}.0"
61
61
  end
62
62
  else
63
63
  puts "Binary gem for ruby #{so_vers.join(', ')}"
@@ -18,6 +18,21 @@ $lobreadnum = 256 # counts in charactors
18
18
 
19
19
  # don't modify below.
20
20
 
21
+ begin
22
+ require 'minitest/autorun'
23
+ Minitest = MiniTest unless defined? Minitest
24
+ Minitest::Test = Minitest::Unit::TestCase unless defined? Minitest::Test
25
+ rescue LoadError
26
+ require 'test/unit'
27
+ module Minitest
28
+ Test = ::Test::Unit::TestCase
29
+ Assertions = ::Test::Unit::Assertions
30
+ module Assertions
31
+ alias refute_nil assert_not_nil
32
+ end
33
+ end
34
+ end
35
+
21
36
  # $oracle_server_version: database compatible level of the Oracle server.
22
37
  # $oracle_client_version: Oracle client library version for which oci8 is compiled.
23
38
  # $oracle_version: lower value of $oracle_server_version and $oracle_client_version.
@@ -108,77 +123,72 @@ def convert_to_datetime(year, month, day, hour, minute, sec, subsec, timezone)
108
123
  end
109
124
  end
110
125
 
111
- module Test
112
- module Unit
113
- class TestCase
126
+ class Minitest::Test
114
127
 
115
- def get_oci8_connection()
116
- OCI8.new($dbuser, $dbpass, $dbname)
128
+ def get_oci8_connection()
129
+ OCI8.new($dbuser, $dbpass, $dbname)
117
130
  rescue OCIError
118
- raise if $!.code != 12516 && $!.code != 12520
119
- # sleep a few second and try again if
120
- # the error code is ORA-12516 or ORA-12520.
121
- #
122
- # ORA-12516 - TNS:listener could not find available handler with
123
- # matching protocol stack
124
- # ORA-12520 - TNS:listener could not find available handler for
125
- # requested type of server
126
- #
127
- # Thanks to Christopher Jones.
128
- #
129
- # Ref: The Underground PHP and Oracle Manual (page 175 in vesion 1.4)
130
- # http://www.oracle.com/technology/tech/php/pdf/underground-php-oracle-manual.pdf
131
- #
132
- sleep(5)
133
- OCI8.new($dbuser, $dbpass, $dbname)
134
- end
131
+ raise if $!.code != 12516 && $!.code != 12520
132
+ # sleep a few second and try again if
133
+ # the error code is ORA-12516 or ORA-12520.
134
+ #
135
+ # ORA-12516 - TNS:listener could not find available handler with
136
+ # matching protocol stack
137
+ # ORA-12520 - TNS:listener could not find available handler for
138
+ # requested type of server
139
+ #
140
+ # Thanks to Christopher Jones.
141
+ #
142
+ # Ref: The Underground PHP and Oracle Manual (page 175 in vesion 1.4)
143
+ # http://www.oracle.com/technology/tech/php/pdf/underground-php-oracle-manual.pdf
144
+ #
145
+ sleep(5)
146
+ OCI8.new($dbuser, $dbpass, $dbname)
147
+ end
148
+
149
+ def get_dbi_connection()
150
+ DBI.connect("dbi:OCI8:#{$dbname}", $dbuser, $dbpass, 'AutoCommit' => false)
151
+ rescue DBI::DatabaseError
152
+ raise if $!.err != 12516 && $!.err != 12520
153
+ # same as get_oci8_connection()
154
+ sleep(5)
155
+ DBI.connect("dbi:OCI8:#{$dbname}", $dbuser, $dbpass, 'AutoCommit' => false)
156
+ end
135
157
 
136
- def get_dbi_connection()
137
- DBI.connect("dbi:OCI8:#{$dbname}", $dbuser, $dbpass, 'AutoCommit' => false)
158
+ def drop_table(table_name)
159
+ if $oracle_server_version < OCI8::ORAVER_10_1
160
+ # Oracle 8 - 9i
161
+ sql = "DROP TABLE #{table_name}"
162
+ else
163
+ # Oracle 10g -
164
+ sql = "DROP TABLE #{table_name} PURGE"
165
+ end
166
+
167
+ if defined? @conn
168
+ begin
169
+ @conn.exec(sql)
170
+ rescue OCIError
171
+ raise if $!.code != 942 # table or view does not exist
172
+ end
173
+ elsif instance_variable_get(:@dbh)
174
+ begin
175
+ @dbh.do(sql)
138
176
  rescue DBI::DatabaseError
139
- raise if $!.err != 12516 && $!.err != 12520
140
- # same as get_oci8_connection()
141
- sleep(5)
142
- DBI.connect("dbi:OCI8:#{$dbname}", $dbuser, $dbpass, 'AutoCommit' => false)
177
+ raise if $!.err != 942 # table or view does not exist
143
178
  end
179
+ end
180
+ end # drop_table
144
181
 
145
- def drop_table(table_name)
146
- if $oracle_server_version < OCI8::ORAVER_10_1
147
- # Oracle 8 - 9i
148
- sql = "DROP TABLE #{table_name}"
149
- else
150
- # Oracle 10g -
151
- sql = "DROP TABLE #{table_name} PURGE"
152
- end
153
-
154
- if defined? @conn
155
- begin
156
- @conn.exec(sql)
157
- rescue OCIError
158
- raise if $!.code != 942 # table or view does not exist
159
- end
160
- elsif instance_variable_get(:@dbh)
161
- begin
162
- @dbh.do(sql)
163
- rescue DBI::DatabaseError
164
- raise if $!.err != 942 # table or view does not exist
165
- end
166
- end
167
- end # drop_table
168
-
169
- def drop_type(type_name)
170
- begin
171
- @conn.exec("DROP TYPE BODY #{type_name}")
172
- rescue OCIError
173
- raise if $!.code != 4043
174
- end
175
- begin
176
- @conn.exec("DROP TYPE #{type_name}")
177
- rescue OCIError
178
- raise if $!.code != 4043
179
- end
180
- end # drop_type
182
+ def drop_type(type_name)
183
+ begin
184
+ @conn.exec("DROP TYPE BODY #{type_name}")
185
+ rescue OCIError
186
+ raise if $!.code != 4043
181
187
  end
182
- end
188
+ begin
189
+ @conn.exec("DROP TYPE #{type_name}")
190
+ rescue OCIError
191
+ raise if $!.code != 4043
192
+ end
193
+ end # drop_type
183
194
  end
184
-