ruby-oci8 2.1.5.1-x64-mingw32 → 2.1.7-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.
- checksums.yaml +4 -4
- data/ChangeLog +123 -0
- data/NEWS +54 -0
- data/README.md +9 -6
- data/VERSION +1 -1
- data/docs/install-full-client.md +2 -4
- data/docs/install-instant-client.md +14 -9
- data/docs/report-installation-issue.md +1 -1
- data/lib/oci8.rb +10 -19
- data/lib/oci8.rb.in +8 -17
- data/lib/oci8/cursor.rb +2 -0
- data/lib/oci8/metadata.rb +87 -9
- data/lib/oci8/object.rb +23 -0
- data/lib/oci8lib_200.so +0 -0
- data/lib/oci8lib_210.so +0 -0
- data/ruby-oci8.gemspec +1 -1
- data/test/config.rb +76 -66
- data/test/test_all.rb +4 -6
- data/test/test_appinfo.rb +2 -3
- data/test/test_array_dml.rb +6 -7
- data/test/test_bind_raw.rb +1 -2
- data/test/test_bind_string.rb +1 -2
- data/test/test_bind_time.rb +1 -2
- data/test/test_break.rb +2 -3
- data/test/test_clob.rb +1 -2
- data/test/test_connection_pool.rb +2 -3
- data/test/test_connstr.rb +1 -4
- data/test/test_datetime.rb +2 -3
- data/test/test_dbi.rb +1 -2
- data/test/test_dbi_clob.rb +6 -6
- data/test/test_encoding.rb +1 -2
- data/test/test_error.rb +1 -2
- data/test/test_metadata.rb +2086 -898
- data/test/test_object.rb +8 -11
- data/test/test_oci8.rb +1 -2
- data/test/test_oracle_version.rb +1 -3
- data/test/test_oradate.rb +1 -2
- data/test/test_oranumber.rb +5 -6
- data/test/test_rowid.rb +1 -2
- metadata +6 -5
data/lib/oci8/metadata.rb
CHANGED
@@ -89,6 +89,15 @@ class OCI8
|
|
89
89
|
# attr_get_oradate(OCI_ATTR_TIMESTAMP)
|
90
90
|
#end
|
91
91
|
|
92
|
+
# Returns the database link name if the object is at the remote host.
|
93
|
+
# Note that this is available only when the object is returned by OCI8#describe_* methods.
|
94
|
+
#
|
95
|
+
# @return [String or nil] database link name
|
96
|
+
# @since 2.1.7
|
97
|
+
def obj_link
|
98
|
+
@obj_link
|
99
|
+
end
|
100
|
+
|
92
101
|
# @private
|
93
102
|
def inspect
|
94
103
|
"#<#{self.class.name}:(#{obj_id}) #{obj_schema}.#{obj_name}>"
|
@@ -110,7 +119,7 @@ class OCI8
|
|
110
119
|
Proc.new do |p|
|
111
120
|
if p.charset_form == :nchar
|
112
121
|
"NVARCHAR2(#{p.char_size})"
|
113
|
-
elsif p.char_used?
|
122
|
+
elsif p.respond_to?(:char_used?) && p.char_used?
|
114
123
|
"VARCHAR2(#{p.char_size} CHAR)"
|
115
124
|
else
|
116
125
|
"VARCHAR2(#{p.data_size})"
|
@@ -248,6 +257,12 @@ class OCI8
|
|
248
257
|
"TIMESTAMP(#{fsprecision}) WITH LOCAL TIME ZONE"
|
249
258
|
end
|
250
259
|
end]
|
260
|
+
DATA_TYPE_MAP[245] = [:record,
|
261
|
+
Proc.new do |p|
|
262
|
+
"#{p.schema_name}.#{p.type_name}"
|
263
|
+
end]
|
264
|
+
DATA_TYPE_MAP[252] = [:boolean, "BOOLEAN"]
|
265
|
+
DATA_TYPE_MAP[266] = [:pls_integer, "PLS_INTEGER"]
|
251
266
|
|
252
267
|
def __data_type # :nodoc:
|
253
268
|
return @data_type if defined? @data_type
|
@@ -337,6 +352,9 @@ class OCI8
|
|
337
352
|
#when 228; :sysfirst # OCI_TYPECODE_SYSFIRST
|
338
353
|
#when 235; :syslast # OCI_TYPECODE_SYSLAST
|
339
354
|
when 266; :pls_integer # OCI_TYPECODE_PLS_INTEGER
|
355
|
+
when 250; :record # OCI_TYPECODE_RECORD
|
356
|
+
when 251; :itable # OCI_TYPECODE_ITABLE
|
357
|
+
when 252; :boolean # OCI_TYPECODE_BOOLEAN
|
340
358
|
end
|
341
359
|
end
|
342
360
|
end
|
@@ -632,6 +650,12 @@ class OCI8
|
|
632
650
|
end
|
633
651
|
private :list_subprograms
|
634
652
|
|
653
|
+
# package type list
|
654
|
+
def list_types # :nodoc:
|
655
|
+
__param(137) # OCI_ATTR_LIST_PKG_TYPES
|
656
|
+
end
|
657
|
+
private :list_types
|
658
|
+
|
635
659
|
# Returns +true+ if the package subprograms have
|
636
660
|
# {invoker's rights}[http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/subprograms.htm#i18574].
|
637
661
|
# Otherwise, +false+.
|
@@ -647,6 +671,22 @@ class OCI8
|
|
647
671
|
prog.instance_variable_set(:@is_standalone, false)
|
648
672
|
end
|
649
673
|
end
|
674
|
+
|
675
|
+
if OCI8.oracle_client_version < ORAVER_12_1
|
676
|
+
def types
|
677
|
+
raise "This version of the Oracle client does not support PL/SQL package type descriptions."
|
678
|
+
end
|
679
|
+
else
|
680
|
+
# Returns an array of types defined within the Package.
|
681
|
+
#
|
682
|
+
# @return [array of OCI8::Metadata::Type]
|
683
|
+
# @since 2.1.6
|
684
|
+
def types
|
685
|
+
@types ||= list_types.to_a.each do |type|
|
686
|
+
type.instance_variable_set(:@is_standalone, false)
|
687
|
+
end
|
688
|
+
end
|
689
|
+
end
|
650
690
|
end
|
651
691
|
|
652
692
|
# Information about types
|
@@ -851,6 +891,15 @@ class OCI8
|
|
851
891
|
attr_get_string(OCI_ATTR_SUPERTYPE_NAME) if is_subtype?
|
852
892
|
end
|
853
893
|
|
894
|
+
# Returns the package name if the type is a package type.
|
895
|
+
# Otherwise, +nil+.
|
896
|
+
#
|
897
|
+
# @return [String or nil]
|
898
|
+
# @since 2.1.6
|
899
|
+
def package_name
|
900
|
+
attr_get_string(12, false) # OCI_ATTR_PACKAGE_NAME
|
901
|
+
end
|
902
|
+
|
854
903
|
# Returns attribute information of the type.
|
855
904
|
#
|
856
905
|
# @return [array of OCI8::Metadata::TypeAttr]
|
@@ -1199,6 +1248,7 @@ class OCI8
|
|
1199
1248
|
# schema name of the synonym translation
|
1200
1249
|
def schema_name
|
1201
1250
|
@schema_name ||= attr_get_string(OCI_ATTR_SCHEMA_NAME)
|
1251
|
+
@schema_name.size == 0 ? nil : @schema_name
|
1202
1252
|
end
|
1203
1253
|
|
1204
1254
|
# object name of the synonym translation
|
@@ -1214,11 +1264,7 @@ class OCI8
|
|
1214
1264
|
|
1215
1265
|
# full-qualified synonym translation name with schema, object and database link name.
|
1216
1266
|
def translated_name
|
1217
|
-
|
1218
|
-
schema_name + '.' + name
|
1219
|
-
else
|
1220
|
-
schema_name + '.' + name + '@' + link
|
1221
|
-
end
|
1267
|
+
(schema_name ? schema_name + '.' : '') + name + (link ? '@' + link : '')
|
1222
1268
|
end
|
1223
1269
|
|
1224
1270
|
def inspect # :nodoc:
|
@@ -1487,10 +1533,21 @@ class OCI8
|
|
1487
1533
|
end
|
1488
1534
|
|
1489
1535
|
# Indicates whether an argument has a default
|
1536
|
+
#
|
1537
|
+
# @return [1 or 0]
|
1538
|
+
# @deprecated
|
1490
1539
|
def has_default
|
1491
1540
|
attr_get_ub1(OCI_ATTR_HAS_DEFAULT)
|
1492
1541
|
end
|
1493
1542
|
|
1543
|
+
# Indicates whether an argument has a default
|
1544
|
+
#
|
1545
|
+
# @return [true or false]
|
1546
|
+
# @since 2.1.6
|
1547
|
+
def has_default?
|
1548
|
+
__boolean(OCI_ATTR_HAS_DEFAULT)
|
1549
|
+
end
|
1550
|
+
|
1494
1551
|
# The list of arguments at the next level (when the argument is
|
1495
1552
|
# of a record or table type).
|
1496
1553
|
def list_arguments
|
@@ -1648,8 +1705,9 @@ class OCI8
|
|
1648
1705
|
#when OCI_LTYPE_TABLE_ALIAS; offset = ?
|
1649
1706
|
#when OCI_LTYPE_VARIABLE_TYPE; offset = ?
|
1650
1707
|
#when OCI_LTYPE_NAME_VALUE; offset = ?
|
1708
|
+
when 15; offset = 0 # OCI_LTYPE_PACKAGE_TYPE
|
1651
1709
|
else
|
1652
|
-
raise NotImplementedError, "unsupported list type #{
|
1710
|
+
raise NotImplementedError, "unsupported list type #{ltype}"
|
1653
1711
|
end
|
1654
1712
|
ary = []
|
1655
1713
|
0.upto(num_params - 1) do |i|
|
@@ -1994,7 +2052,13 @@ class OCI8
|
|
1994
2052
|
# @param [String] object_name
|
1995
2053
|
# @return [a subclass of OCI8::Metadata::Base]
|
1996
2054
|
def describe_any(object_name)
|
1997
|
-
|
2055
|
+
if /^PUBLIC\.(.*)/i =~ object_name
|
2056
|
+
md = __describe($1, OCI8::Metadata::Unknown, true)
|
2057
|
+
raise OCIError.new(4043, object_name) if md.obj_schema != 'PUBLIC'
|
2058
|
+
md
|
2059
|
+
else
|
2060
|
+
__describe(object_name, OCI8::Metadata::Unknown, true)
|
2061
|
+
end
|
1998
2062
|
end
|
1999
2063
|
# Returns table or view information. If the name is a current schema's synonym
|
2000
2064
|
# name or a public synonym name, it returns table or view information which
|
@@ -2011,6 +2075,9 @@ class OCI8
|
|
2011
2075
|
__describe(table_name, OCI8::Metadata::Table, false)
|
2012
2076
|
else
|
2013
2077
|
# check tables, views, synonyms and public synonyms.
|
2078
|
+
|
2079
|
+
# follow synonyms up to 20 times to prevent infinite loop
|
2080
|
+
# caused by recursive synonyms.
|
2014
2081
|
recursive_level = 20
|
2015
2082
|
recursive_level.times do
|
2016
2083
|
metadata = __describe(table_name, OCI8::Metadata::Unknown, true)
|
@@ -2019,6 +2086,11 @@ class OCI8
|
|
2019
2086
|
return metadata
|
2020
2087
|
when OCI8::Metadata::Synonym
|
2021
2088
|
table_name = metadata.translated_name
|
2089
|
+
if metadata.obj_link and metadata.link.nil?
|
2090
|
+
# table_name is a synonym in a remote database for an object in the
|
2091
|
+
# remote database itself.
|
2092
|
+
table_name = "#{table_name}@#{metadata.obj_link}"
|
2093
|
+
end
|
2022
2094
|
else
|
2023
2095
|
raise OCIError.new(4043, table_name) # ORA-04043: object %s does not exist
|
2024
2096
|
end
|
@@ -2066,7 +2138,13 @@ class OCI8
|
|
2066
2138
|
# @param [String] synonym_name
|
2067
2139
|
# @return [OCI8::Metadata::Synonym]
|
2068
2140
|
def describe_synonym(synonym_name, check_public_also = true)
|
2069
|
-
|
2141
|
+
if /^PUBLIC\.(.*)/i =~ synonym_name
|
2142
|
+
md = __describe($1, OCI8::Metadata::Synonym, true)
|
2143
|
+
raise OCIError.new(4043, synonym_name) if md.obj_schema != 'PUBLIC'
|
2144
|
+
md
|
2145
|
+
else
|
2146
|
+
__describe(synonym_name, OCI8::Metadata::Synonym, check_public_also)
|
2147
|
+
end
|
2070
2148
|
end
|
2071
2149
|
# Returns sequence information
|
2072
2150
|
#
|
data/lib/oci8/object.rb
CHANGED
@@ -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
|
data/lib/oci8lib_200.so
CHANGED
Binary file
|
data/lib/oci8lib_210.so
ADDED
Binary file
|
data/ruby-oci8.gemspec
CHANGED
@@ -19,7 +19,7 @@ spec = Gem::Specification.new do |s|
|
|
19
19
|
s.version = File.read('VERSION').strip
|
20
20
|
s.summary = 'Ruby interface for Oracle using OCI8 API'
|
21
21
|
s.email = 'kubo@jiubao.org'
|
22
|
-
s.homepage = '
|
22
|
+
s.homepage = 'https://github.com/kubo/ruby-oci8/'
|
23
23
|
s.rubyforge_project = 'ruby-oci8'
|
24
24
|
s.description = <<EOS
|
25
25
|
ruby-oci8 is a ruby interface for Oracle using OCI8 API. It is available with Oracle8i, Oracle9i, Oracle10g, Oracle11g and Oracle Instant Client.
|
data/test/config.rb
CHANGED
@@ -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
|
-
|
112
|
-
module Unit
|
113
|
-
class TestCase
|
126
|
+
class Minitest::Test
|
114
127
|
|
115
|
-
|
116
|
-
|
128
|
+
def get_oci8_connection()
|
129
|
+
OCI8.new($dbuser, $dbpass, $dbname)
|
117
130
|
rescue OCIError
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
137
|
-
|
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 !=
|
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
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
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
|
-
|
data/test/test_all.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
srcdir = File.dirname(__FILE__)
|
2
2
|
|
3
3
|
require 'oci8'
|
4
|
-
require 'test/unit'
|
5
4
|
require "#{srcdir}/config"
|
6
5
|
|
7
6
|
require "#{srcdir}/test_oradate"
|
@@ -30,6 +29,10 @@ if OCI8.respond_to? :encoding
|
|
30
29
|
require "#{srcdir}/test_encoding"
|
31
30
|
end
|
32
31
|
|
32
|
+
if $oracle_version >= OCI8::ORAVER_12_1
|
33
|
+
require "#{srcdir}/test_package_type"
|
34
|
+
end
|
35
|
+
|
33
36
|
# Ruby/DBI
|
34
37
|
begin
|
35
38
|
require 'dbi'
|
@@ -47,8 +50,3 @@ unless dbi_not_found
|
|
47
50
|
require "#{srcdir}/test_dbi_clob"
|
48
51
|
end
|
49
52
|
end
|
50
|
-
|
51
|
-
#Test::Unit::AutoRunner.run(true, true)
|
52
|
-
if defined? Test::Unit::AutoRunner
|
53
|
-
Test::Unit::AutoRunner.run()
|
54
|
-
end
|
data/test/test_appinfo.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'oci8'
|
2
|
-
require 'test/unit'
|
3
2
|
require File.dirname(__FILE__) + '/config'
|
4
3
|
|
5
|
-
class TestAppInfo < Test
|
4
|
+
class TestAppInfo < Minitest::Test
|
6
5
|
|
7
6
|
def setup
|
8
7
|
@conn = get_oci8_connection
|
@@ -14,7 +13,7 @@ class TestAppInfo < Test::Unit::TestCase
|
|
14
13
|
@conn.client_identifier = client_id
|
15
14
|
assert_equal(client_id, @conn.select_one("SELECT SYS_CONTEXT('USERENV', 'CLIENT_IDENTIFIER') FROM DUAL")[0]);
|
16
15
|
# check the first character
|
17
|
-
|
16
|
+
assert_raises ArgumentError do
|
18
17
|
@conn.client_identifier = ':bad_identifier'
|
19
18
|
end
|
20
19
|
|