ruby-oci8 2.2.1-x86-mingw32 → 2.2.2-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.
data/.yardopts CHANGED
@@ -11,9 +11,4 @@
11
11
  NEWS
12
12
  COPYING
13
13
  COPYING_old
14
- docs/install-full-client.md
15
- docs/install-instant-client.md
16
- docs/install-binary-package.md
17
- docs/install-on-osx.md
18
- docs/platform-specific-issues.md
19
- docs/report-installation-issue.md
14
+ docs/*.md
data/ChangeLog CHANGED
@@ -1,3 +1,101 @@
1
+ 2016-04-24 Kubo Takehiro <kubo@jiubao.org>
2
+ * mkpkg-win32.rb: Added to compile mingw32 packages.
3
+ * dist-files: Updated to include docs/report-installation-issue.md.
4
+
5
+ 2016-04-24 Kubo Takehiro <kubo@jiubao.org>
6
+ * NEWS: Add changes between 2.2.1 and 2.2.2.
7
+ * lib/oci8/version.rb: update to 2.2.2.
8
+
9
+ 2016-04-24 Kubo Takehiro <kubo@jiubao.org>
10
+ * docs/report-installation-issue.md: Use RbConfig::CONFIG instead of
11
+ deprecated Config::CONFIG.
12
+
13
+ 2016-04-24 Kubo Takehiro <kubo@jiubao.org>
14
+ * lib/oci8/oci8.rb: Add OCI8::in_cond and OCI8:InCondBindHelper.
15
+ * test/test_all.rb, test/test_bind_array.rb: Add test of OCI8::in_cond.
16
+ * README.md, docs/bind-array-to-in_cond.md: Add document of OCI8::in_cond.
17
+
18
+ 2016-04-10 Kubo Takehiro <kubo@jiubao.org>
19
+ * lib/oci8/connection_pool.rb: update document.
20
+
21
+ 2016-03-27 Kubo Takehiro <kubo@jiubao.org>
22
+ * lib/oci8/object.rb: Suppress warning: instance variable
23
+ @name_to_tdo not initialized.
24
+
25
+ 2016-03-27 Kubo Takehiro <kubo@jiubao.org>
26
+ * ext/oci8/apiwrap.yml, ext/oci8/metadata.c, ext/oci8/object.c,
27
+ ext/oci8/oci8.h, lib/oci8/object.rb, test/setup_test_object.sql,
28
+ test/test_object.rb: Check object type from each object instance
29
+ when an Oracle object is got from a bind parameter.
30
+ (github issue #119)
31
+
32
+ 2016-03-27 Kubo Takehiro <kubo@jiubao.org>
33
+ * lib/ruby-oci8.rb: Added for 'Bundler.require'.
34
+ (github issue #114)
35
+ * dist-files: Add lib/ruby-oci8.rb.
36
+
37
+ 2016-03-27 Kubo Takehiro <kubo@jiubao.org>
38
+ * README.md, docs/timeout-parameters.md, lib/oci8/oci8.rb:
39
+ Update documents about timeout parameters.
40
+
41
+ 2016-03-18 Kubo Takehiro <kubo@jiubao.org>
42
+ * ext/oci8/oraconf.rb: Fix for mswin64.
43
+
44
+ 2016-03-15 Kubo Takehiro <kubo@jiubao.org>
45
+ * docs/conflicts-local-connections-and-processes.md: Add a document
46
+ about conflicts between local connections and child process
47
+ handling on Unix.
48
+ * README.md: Add a link to a newly added file.
49
+
50
+ 2016-03-13 Kubo Takehiro <kubo@jiubao.org>
51
+ * ruby-oci8.gemspec: Change the license name in gemspec to suppress the
52
+ following warning.
53
+ WARNING: license value '2-clause BSD-style license' is invalid.
54
+ Use a license identifier from http://spdx.org/licenses or 'Nonstandard'
55
+ for a nonstandard license.
56
+
57
+ 2016-01-29 Kubo Takehiro <kubo@jiubao.org>
58
+ * lib/oci8/oci8.rb, lib/oci8/properties.rb: Rename outbound_connect_timeout in
59
+ OCI8::properties to connect_timeout.
60
+ * docs/timeout-parameters.md: Revise document.
61
+
62
+ 2015-12-20 Kubo Takehiro <kubo@jiubao.org>
63
+ * lib/oci8/cursor.rb: Use OCI_ATTR_UB8_ROW_COUNT to get the number of processed rows
64
+ if Oracle client version is 12c or upper.
65
+
66
+ 2015-12-20 Kubo Takehiro <kubo@jiubao.org>
67
+ * lib/oci8/oci8.rb, lib/oci8/properties.rb, test/test_connstr.rb:
68
+ Support tcp_connect_timeout, connect_timeout, send_timeout and
69
+ recv_timeout in OCI8::properties.
70
+ * .yardopts, dist-files, docs/timeout-parameters.md: Add document
71
+ about timeout parameters.
72
+
73
+ 2015-12-19 Kubo Takehiro <kubo@jiubao.org>
74
+ * lib/oci8/oci8.rb, lib/oci8/ocihandle.rb: Support SYSBACKUP, SYSDG
75
+ and SYSKM privileges.
76
+ (github issue #110)
77
+
78
+ 2015-12-19 Kubo Takehiro <kubo@jiubao.org>
79
+ * ext/oci8/plthook_win32.c: Fix bug introduced by the previous commit
80
+ for mingw32 64-bit compiler.
81
+ (github issue #113)
82
+
83
+ 2015-12-18 Kubo Takehiro <kubo@jiubao.org>
84
+ * ext/oci8/plthook_win32.c, ext/oci8/extconf.rb: Import the latest
85
+ plthook_win32.c for cygwin. Ruby-oci8 had not been compiled on
86
+ cygwin since 2.1.8.
87
+ (github issue #113)
88
+
89
+ 2015-12-18 Kubo Takehiro <kubo@jiubao.org>
90
+ * ext/oci8/oraconf.rb: Fix a linkage error on cygwin and mingw32
91
+ when installing without `--with-runtime-check`.
92
+ This bug was introduced in ruby-oci8 2.2.1.
93
+ (github issue #113)
94
+
95
+ 2015-11-28 Kubo Takehiro <kubo@jiubao.org>
96
+ * ext/oci8/oraconf.rb: Check the default value of DYLD_FALLBACK_LIBRARY_PATH
97
+ after checking OCI_DIR. (OS X only)
98
+
1
99
  2015-11-01 Kubo Takehiro <kubo@jiubao.org>
2
100
  * NEWS: Add changes between 2.2.0.2 and 2.2.1.
3
101
  * lib/oci8/version.rb: update to 2.2.1.
data/NEWS CHANGED
@@ -1,5 +1,52 @@
1
1
  # @markup markdown
2
2
 
3
+ 2.2.2
4
+ =====
5
+
6
+ New Features
7
+ ------------
8
+
9
+ ### Add OCI8::in_cond
10
+
11
+ This is a helper method to bind an array to parameters in IN-conditions.
12
+ See {file:docs/bind-array-to-in_cond.md Bind an Array to IN-condition}
13
+
14
+ ### Add timeout parameters in OCI8::properties
15
+
16
+ See {file:docs/timeout-parameters.md Timeout Parameters}
17
+
18
+ ### Support SYSBACKUP, SYSDG and SYSKM privileges.
19
+
20
+ For example:
21
+
22
+ OCI8.new(username, password, database, :SYSBACKUP)
23
+
24
+ (github issue #110)
25
+
26
+ ### Support {OCI8::Cursor#row_count} over 4G (Oracle 12c client only)
27
+
28
+ Fixed Issues
29
+ ------------
30
+
31
+ ### Fix type mapping of subtypes of Oracle object
32
+
33
+ github issue #119
34
+
35
+ ### Fix compile error on cygwin since ruby-oci8 2.1.8.
36
+
37
+ github issue #113
38
+
39
+ ### Fix compile error when the ruby was compiled by Visual Studio 64bit.
40
+
41
+ Other Changes
42
+ -------------
43
+
44
+ - Suppress warning: instance variable @name_to_tdo not initialized.
45
+
46
+
47
+ - Check the default value of DYLD_FALLBACK_LIBRARY_PATH after checking OCI_DIR on installation. (OS X only)
48
+
49
+
3
50
  2.2.1
4
51
  =====
5
52
 
@@ -9,7 +56,7 @@ New Features
9
56
  ### Add OCI8::Metadata::Boolean
10
57
 
11
58
  Support boolean type binding. This feature requires Oracle 12c client and server.
12
- This doens't work when either Oracle server or client is 11g or lower.
59
+ Binding a boolean value fails when either Oracle server or client is 11g or lower.
13
60
 
14
61
  Fixed Issues
15
62
  ------------
data/README.md CHANGED
@@ -41,6 +41,13 @@ Report issues
41
41
  * {file:docs/report-installation-issue.md Report Installation Issues}
42
42
  * [The issues page on github](https://github.com/kubo/ruby-oci8/issues)
43
43
 
44
+ Other documents
45
+ ===============
46
+
47
+ * {file:docs/timeout-parameters.md Timeout Parameters}
48
+ * {file:docs/conflicts-local-connections-and-processes.md Conflicts between Local Connections and Child Process Handling on Unix}
49
+ * {file:docs/bind-array-to-in_cond.md Bind an Array to IN-condition}
50
+
44
51
  License
45
52
  =======
46
53
 
data/dist-files CHANGED
@@ -10,13 +10,16 @@ metaconfig
10
10
  pre-distclean.rb
11
11
  ruby-oci8.gemspec
12
12
  setup.rb
13
+ docs/bind-array-to-in_cond.md
13
14
  docs/install-binary-package.md
14
15
  docs/install-full-client.md
15
16
  docs/install-instant-client.md
16
17
  docs/install-on-osx.md
18
+ docs/conflicts-local-connections-and-processes.md
17
19
  docs/osx-install-dev-tools.png
18
20
  docs/platform-specific-issues.md
19
21
  docs/report-installation-issue.md
22
+ docs/timeout-parameters.md
20
23
  ext/oci8/.document
21
24
  ext/oci8/MANIFEST
22
25
  ext/oci8/apiwrap.c.tmpl
@@ -73,6 +76,7 @@ lib/oci8/ocihandle.rb
73
76
  lib/oci8/oracle_version.rb
74
77
  lib/oci8/properties.rb
75
78
  lib/oci8/version.rb
79
+ lib/ruby-oci8.rb
76
80
  test/README
77
81
  test/config.rb
78
82
  test/setup_test_object.sql
@@ -0,0 +1,38 @@
1
+ @ Bind an Array to IN-condition
2
+
3
+ Bind an Array to IN-condition
4
+ =============================
5
+
6
+ Binding an arbitrary-length array to IN-condition is not simple.
7
+ You need to create an SQL statement containing a comma-separated
8
+ list whose length is same with the input data.
9
+
10
+ Example:
11
+
12
+ ids = [ ... ] # an arbitrary-length array containing user IDs.
13
+
14
+ place_holder_string = Array.new(ids.length) {|index| ":id_#{index}"}.join(', ')
15
+ # place_holder_string is:
16
+ # ":id_0" if ids.length == 1
17
+ # ":id_0, :id_1" if ids.length == 2
18
+ # ...
19
+ cursor = conn.parse("select * from users where id in (#{place_holder_string})")
20
+ ids.each_with_index do |id, index|
21
+ cursor.bind_param("id#{index}", id) # bind each element
22
+ end
23
+ cursor.exec()
24
+
25
+ However this is awkward. So {OCI8.in_cond} was added in ruby-oci8 2.2.2.
26
+ The above code is rewritten as follows:
27
+
28
+ ids = [ ... ] # an arbitrary-length array containing user IDs.
29
+
30
+ in_cond = OCI8::in_cond(:id, ids)]
31
+ cursor = conn.exec("select * from users where id in (#{in_cond.names})", *in_cond.values)
32
+
33
+ or
34
+
35
+ ids = [ ... ] # an arbitrary-length array containing user IDs.
36
+
37
+ in_cond = OCI8::in_cond(:id, ids, Integer) # set the data type explicitly
38
+ cursor = conn.exec("select * from users where id in (#{in_cond.names})", *in_cond.values)
@@ -0,0 +1,95 @@
1
+ # @title Conflicts between Local Connections and Child Process Handling on Unix
2
+
3
+ Background
4
+ ==========
5
+
6
+ When a local (not-TCP) Oracle connection is established on Unix,
7
+ Oracle client library changes signal handlers in the process to reap
8
+ all dead child processes. However it conflicts with child process
9
+ handling in ruby.
10
+
11
+ Problem 1: It trashes child process handling of Open3::popen.
12
+ ==========
13
+
14
+ require 'oci8'
15
+ require 'open3'
16
+
17
+ Open3::popen3('true') do |i, o, e, w|
18
+ p w.value
19
+ end
20
+
21
+ conn = OCI8.new(username, password)
22
+ puts "establish a local connection"
23
+
24
+ Open3::popen3('true') do |i, o, e, w|
25
+ p w.value
26
+ end
27
+
28
+ The above code outputs the following result:
29
+
30
+ #<Process::Status: pid 19236 exit 0>
31
+ establish a local connection
32
+ nil
33
+
34
+ `w.value` after a local connection doesn't work because Oracle reaps
35
+ the child process on the process termination before ruby detects it.
36
+
37
+ Problem 2: It creates defunct processes after disconnection if signal handlers are reset.
38
+ ==========
39
+
40
+ The `system` function overwrites signal handlers.
41
+ It fixes the problem 1 as follows.
42
+
43
+ require 'oci8'
44
+ require 'open3'
45
+
46
+ Open3::popen3('true') do |i, o, e, w|
47
+ p w.value
48
+ end
49
+
50
+ conn = OCI8.new(username, password) # Signal handlers are changed here.
51
+ puts "establish a local connection"
52
+ system('true') # Signal handlers are reset here.
53
+
54
+ Open3::popen3('true') do |i, o, e, w|
55
+ p w.value
56
+ end
57
+
58
+ The above code outputs the following result:
59
+
60
+ #<Process::Status: pid 19652 exit 0>
61
+ establish a local connection
62
+ #<Process::Status: pid 19656 exit 0>
63
+
64
+ `w.value` after a local connection works.
65
+
66
+ However it makes another problem.
67
+
68
+ require 'oci8'
69
+
70
+ conn = OCI8.new(username, password) # Signal handlers are changed here.
71
+ # An Oracle server process is created here.
72
+ puts "establish a local connection"
73
+ system('true') # Signal handlers are reset here.
74
+
75
+ conn.logoff # The Oracle server process exits and become defunct.
76
+
77
+ # ... do other stuffs...
78
+
79
+ If a program repeatedly creates a local connection and disconnects it,
80
+ the number of defunct processes increases gradually.
81
+
82
+ Solution: BEQUEATH_DETACH=YES
83
+ ==========
84
+
85
+ By setting [BEQUEATH_DETACH=YES][] in `sqlnet.ora`, Oracle client library
86
+ doesn't change signal handlers. The above two problems are fixed.
87
+
88
+ Oracle client library reads `sqlnet.ora` in the following locations:
89
+
90
+ * `$TNS_ADMIN/sqlnet.ora` if the environment variable `TNS_ADMIN`
91
+ is set and `$TNS_ADMIN/sqlnet.ora` exists.
92
+ Otherwise, `$ORACLE_HOME/network/admin/sqlnet.ora`.
93
+ * `$HOME/.sqlnet.ora`
94
+
95
+ [BEQUEATH_DETACH=YES]: https://docs.oracle.com/database/121/NETRF/sqlnet.htm#NETRF183
@@ -20,14 +20,14 @@ If it is a new one, post the following information to [github][].
20
20
 
21
21
  file `which ruby`
22
22
  ruby --version
23
- ruby -r rbconfig -e "p Config::CONFIG['host']"
24
- ruby -r rbconfig -e "p Config::CONFIG['CC']"
25
- ruby -r rbconfig -e "p Config::CONFIG['CFLAGS']"
26
- ruby -r rbconfig -e "p Config::CONFIG['LDSHARED']"
27
- ruby -r rbconfig -e "p Config::CONFIG['LDFLAGS']"
28
- ruby -r rbconfig -e "p Config::CONFIG['DLDLAGS']"
29
- ruby -r rbconfig -e "p Config::CONFIG['LIBS']"
30
- ruby -r rbconfig -e "p Config::CONFIG['GNU_LD']"
23
+ ruby -r rbconfig -e "p RbConfig::CONFIG['host']"
24
+ ruby -r rbconfig -e "p RbConfig::CONFIG['CC']"
25
+ ruby -r rbconfig -e "p RbConfig::CONFIG['CFLAGS']"
26
+ ruby -r rbconfig -e "p RbConfig::CONFIG['LDSHARED']"
27
+ ruby -r rbconfig -e "p RbConfig::CONFIG['LDFLAGS']"
28
+ ruby -r rbconfig -e "p RbConfig::CONFIG['DLDLAGS']"
29
+ ruby -r rbconfig -e "p RbConfig::CONFIG['LIBS']"
30
+ ruby -r rbconfig -e "p RbConfig::CONFIG['GNU_LD']"
31
31
 
32
32
  # if you use gcc,
33
33
  gcc --print-prog-name=ld
@@ -0,0 +1,91 @@
1
+ # @title Timeout Parameters
2
+
3
+ Timeout Parameters
4
+ ==================
5
+
6
+ The following timeout parameters are available since ruby-oci8 2.2.2.
7
+
8
+ * tcp_connect_timeout
9
+ * connect_timeout
10
+ * send_timeout
11
+ * recv_timeout
12
+
13
+ For example:
14
+
15
+ OCI8.properties[:tcp_connect_timeout] = 10
16
+ OCI8.properties[:connect_timeout] = 15
17
+ OCI8.properties[:send_timeout] = 60
18
+ OCI8.properties[:recv_timeout] = 60
19
+
20
+ These parameters are applied only to TCP/IP connections.
21
+
22
+ The first two parameters `tcp_connect_timeout` and `connect_timeout`
23
+ are applied only to [connect descriptors][connect descriptor] using [Easy Connect Naming Method][EZCONNECT].
24
+ If you use a net service name, you should set [TRANSPORT_CONNECT_TIMEOUT][] and/or
25
+ [CONNECT_TIMEOUT][] in the address descriptor in `tnsnames.ora` instead of these parameters.
26
+ If you use easy connect naming method without any of `port`, `service_name`, `server` and `instance_name`,
27
+ you need to use `//host` to distinguish it from a net service name.
28
+
29
+ The next two parameters `send_timeout` and `recv_timeout` are available on Oracle 11g client
30
+ or upper. Use these parameters to prevent a ruby process from being blocked by poor quality network.
31
+ Otherwise, the ruby process may be blocked until TCP keepalive time (2 hours).
32
+
33
+ tcp_connect_timeout
34
+ -------------------
35
+
36
+ `tcp_connect_timeout` is equivalent to [TCP.CONNECT_TIMEOUT][] in the client-side `sqlnet.ora` and
37
+ [TRANSPORT_CONNECT_TIMEOUT][] in the address descriptor.
38
+ See description about [TCP.CONNECT_TIMEOUT][] and [TRANSPORT_CONNECT_TIMEOUT][].
39
+
40
+ connect_timeout
41
+ ---------------
42
+
43
+ `connect_timeout` is equivalent to [SQLNET.OUTBOUND_CONNECT_TIMEOUT][] in the client-side `sqlnet.ora`
44
+ and [CONNECT_TIMEOUT][] in the address description.
45
+ See description about [SQLNET.OUTBOUND_CONNECT_TIMEOUT][] and [CONNECT_TIMEOUT][].
46
+
47
+ Note: this parameter isn't equivalent to login timeout. It needs the following three
48
+ steps to establish a database connection.
49
+
50
+ 1. Establish a TCP/IP connection.
51
+ 2. Establish an [Oracle Net][] connection on the TCP/IP connection.
52
+ 3. Authenticate and authorize the database user.
53
+
54
+ `tcp_connect_timeout` sets the timeout of the first step.
55
+ `connect_timeout` sets the total timeout of the first and the second steps.
56
+ There is no timeout parameter to limit the maximum time of all three steps.
57
+
58
+ Use `send_timeout` and `recv_timeout` in case that a TCP/IP connection stalls
59
+ in the third step.
60
+
61
+ send_timeout
62
+ ------------
63
+
64
+ `send_timeout` is equivalent to [SQLNET.SEND_TIMEOUT][] in the client-side `sqlnet.ora`.
65
+ See description about [SQLNET.SEND_TIMEOUT][].
66
+
67
+ Note that the connection becomes unusable on timeout.
68
+
69
+ See also {OCI8#send_timeout=}.
70
+
71
+ recv_timeout
72
+ ------------
73
+
74
+ `recv_timeout` is equivalent to [SQLNET.RECV_TIMEOUT][] in the client-side `sqlnet.ora`.
75
+ See description about [SQLNET.RECV_TIMEOUT][].
76
+
77
+ Note that the connection becomes unusable on timeout.
78
+
79
+ See also {OCI8#recv_timeout=}.
80
+
81
+ Note: This parameter must be larger than the longest SQL execution time in your applications.
82
+
83
+ [TCP.CONNECT_TIMEOUT]: http://docs.oracle.com/database/121/NETRF/sqlnet.htm#BIIDDACA
84
+ [SQLNET.OUTBOUND_CONNECT_TIMEOUT]: https://docs.oracle.com/database/121/NETRF/sqlnet.htm#NETRF427
85
+ [SQLNET.SEND_TIMEOUT]: http://docs.oracle.com/database/121/NETRF/sqlnet.htm#NETRF228
86
+ [SQLNET.RECV_TIMEOUT]: http://docs.oracle.com/database/121/NETRF/sqlnet.htm#NETRF227
87
+ [connect descriptor]: https://docs.oracle.com/database/121/NETRF/glossary.htm#BGBEDFBF
88
+ [EZCONNECT]: https://docs.oracle.com/database/121/NETAG/naming.htm#NETAG255
89
+ [CONNECT_TIMEOUT]: https://docs.oracle.com/database/121/NETRF/tnsnames.htm#NETRF666
90
+ [TRANSPORT_CONNECT_TIMEOUT]: https://docs.oracle.com/database/121/NETRF/tnsnames.htm#NETRF1982
91
+ [Oracle Net]: https://en.wikipedia.org/wiki/Oracle_Net_Services#Oracle_Net
@@ -13,17 +13,88 @@ class OCI8
13
13
  #
14
14
  # This is equivalent to Oracle JDBC Driver {OCI Connection Pooling}[http://docs.oracle.com/cd/E11882_01/java.112/e16548/ociconpl.htm#JJDBC28789].
15
15
  #
16
- # Usage:
16
+ # Note that this is different with generally called connection pooling.
17
+ # Generally connection pooling caches connections in a pool.
18
+ # When an application needs a new connection, a connection is got from
19
+ # the pool. So that the amount of time to establish a connection is
20
+ # reduced. However connection pooling in ruby-oci8 is different with
21
+ # above.
22
+ #
23
+ # One Oracle connection is devided into two layers: One is physical
24
+ # connection such as TCP/IP. The other is logical connection which
25
+ # is used by an application. The connection pooling in ruby-oci8
26
+ # caches physical connections in a pool, not logical connections.
27
+ # When an application needs a new connection, a logical connection
28
+ # is created via a physical connection, which needs time to
29
+ # establish a connection unlike generally called connection pooling.
30
+ # When an application sends a query via a logical connection, a
31
+ # physical connection is got from the pool. The physical connection
32
+ # returns to the pool automatically when the query finishes.
33
+ # As long as logical connections are used sequentially, only one
34
+ # physical connection is used. When an application sends
35
+ # queries at a time, it needs more than one physical connection
36
+ # because one physical connection cannot transmit more then one
37
+ # query at a time.
38
+ #
39
+ # Example:
17
40
  # # Create a connection pool.
41
+ # # The number of initial physical connections: 1
42
+ # # The number of maximum physical connections: 5
43
+ # # the connection increment parameter: 2
18
44
  # # username and password are required to establish an implicit primary session.
19
45
  # cpool = OCI8::ConnectionPool.new(1, 5, 2, username, password, database)
20
46
  #
21
- # # Get a session from the pool.
47
+ # # The number of physical connections: 1
48
+ # # The number of logical connections: 0
49
+ #
50
+ # # Create a session.
22
51
  # # Pass the connection pool to the third argument.
23
52
  # conn1 = OCI8.new(username, password, cpool)
24
53
  #
25
- # # Get another session.
54
+ # # One logical connection was created.
55
+ # # The number of physical connections: 1
56
+ # # The number of logical connections: 1
57
+ #
58
+ # # Create another session.
26
59
  # conn2 = OCI8.new(username, password, cpool)
60
+ #
61
+ # # Another logical connection was created.
62
+ # # The number of physical connections: 1
63
+ # # The number of logical connections: 2
64
+ #
65
+ # # Use conn1 and conn2 sequentially
66
+ # conn1.exec('...')
67
+ # conn2.exec('...')
68
+ #
69
+ # # Both logical connections use one physical connection.
70
+ # # The number of physical connections: 1
71
+ # # The number of logical connections: 2
72
+ #
73
+ # thr1 = Thread.new do
74
+ # conn1.exec('...')
75
+ # end
76
+ # thr2 = Thread.new do
77
+ # conn2.exec('...')
78
+ # end
79
+ # thr1.join
80
+ # thr2.join
81
+ #
82
+ # # Logical connections cannot use one physical connection at a time.
83
+ # # So that the number of physical connections is incremented.
84
+ # # The number of physical connections: 3
85
+ # # The number of logical connections: 2
86
+ #
87
+ # conn1.logoff
88
+ #
89
+ # # One logical connection was closed.
90
+ # # The number of physical connections: 3
91
+ # # The number of logical connections: 1
92
+ #
93
+ # conn2.logoff
94
+ #
95
+ # # All logical connections were closed.
96
+ # # The number of physical connections: 3
97
+ # # The number of logical connections: 0
27
98
  #
28
99
  class ConnectionPool
29
100
 
@@ -384,12 +384,19 @@ class OCI8
384
384
  attr_set_ub4(11, rows) # OCI_ATTR_PREFETCH_ROWS(11)
385
385
  end
386
386
 
387
- # Returns the number of processed rows.
388
- #
389
- # @return [Integer]
390
- def row_count
391
- # http://docs.oracle.com/cd/E11882_01/appdev.112/e10646/ociaahan.htm#sthref5498
392
- attr_get_ub4(9) # OCI_ATTR_ROW_COUNT(9)
387
+ if OCI8::oracle_client_version >= ORAVER_12_1
388
+ # Returns the number of processed rows.
389
+ #
390
+ # @return [Integer]
391
+ def row_count
392
+ # https://docs.oracle.com/database/121/LNOCI/ociaahan.htm#sthref5774
393
+ attr_get_ub8(457) # OCI_ATTR_UB8_ROW_COUNT(457)
394
+ end
395
+ else
396
+ def row_count
397
+ # http://docs.oracle.com/cd/E11882_01/appdev.112/e10646/ociaahan.htm#sthref5498
398
+ attr_get_ub4(9) # OCI_ATTR_ROW_COUNT(9)
399
+ end
393
400
  end
394
401
 
395
402
  # Returns the text of the SQL statement prepared in the cursor.
@@ -78,7 +78,8 @@ EOS
78
78
  #
79
79
  # @private
80
80
  def get_tdo_by_typename(typename)
81
- tdo = @name_to_tdo && @name_to_tdo[typename]
81
+ @name_to_tdo ||= {}
82
+ tdo = @name_to_tdo[typename]
82
83
  return tdo if tdo
83
84
 
84
85
  metadata = describe_any(typename)
@@ -383,8 +384,10 @@ EOS
383
384
 
384
385
  case metadata.typecode
385
386
  when :named_type
387
+ @is_final_type = metadata.is_final_type?
386
388
  initialize_named_type(con, metadata)
387
389
  when :named_collection
390
+ @is_final_type = true
388
391
  initialize_named_collection(con, metadata)
389
392
  end
390
393
  end
@@ -63,9 +63,9 @@ class OCI8
63
63
  #
64
64
  # === connecting as a privileged user
65
65
  #
66
- # Set :SYSDBA or :SYSOPER to +privilege+, otherwise
67
- # "username/password as sysdba" or "username/password as sysoper"
68
- # as a single argument.
66
+ # Set :SYSDBA, :SYSOPER, :SYSASM, :SYSBACKUP, :SYSDG or :SYSKM
67
+ # to +privilege+, otherwise "username/password as sysdba",
68
+ # "username/password as sysoper", etc. as a single argument.
69
69
  #
70
70
  # OCI8.new('sys', 'change_on_install', nil, :SYSDBA)
71
71
  # or
@@ -96,29 +96,15 @@ class OCI8
96
96
  #
97
97
  def initialize(*args)
98
98
  if args.length == 1
99
- username, password, dbname, mode = parse_connect_string(args[0])
99
+ username, password, dbname, privilege = parse_connect_string(args[0])
100
100
  else
101
- username, password, dbname, mode = args
101
+ username, password, dbname, privilege = args
102
102
  end
103
103
 
104
104
  if username.nil? and password.nil?
105
105
  cred = OCI_CRED_EXT
106
106
  end
107
- case mode
108
- when :SYSDBA
109
- mode = OCI_SYSDBA
110
- when :SYSOPER
111
- mode = OCI_SYSOPER
112
- when :SYSASM
113
- if OCI8.oracle_client_version < OCI8::ORAVER_11_1
114
- raise "SYSASM is not supported on Oracle version #{OCI8.oracle_client_version}"
115
- end
116
- mode = OCI_SYSASM
117
- when nil
118
- # do nothing
119
- else
120
- raise "unknown privilege type #{mode}"
121
- end
107
+ auth_mode = to_auth_mode(privilege)
122
108
 
123
109
  stmt_cache_size = OCI8.properties[:statement_cache_size]
124
110
  stmt_cache_size = nil if stmt_cache_size == 0
@@ -128,6 +114,12 @@ class OCI8
128
114
  @pool = dbname # to prevent GC from freeing the connection pool.
129
115
  dbname = dbname.send(:pool_name)
130
116
  attach_mode |= 0x0200 # OCI_CPOOL and OCI_LOGON2_CPOOL
117
+ else
118
+ tcp_connect_timeout = OCI8::properties[:tcp_connect_timeout]
119
+ connect_timeout = OCI8::properties[:connect_timeout]
120
+ if tcp_connect_timeout || connect_timeout
121
+ dbname = to_connect_descriptor(dbname, tcp_connect_timeout, connect_timeout)
122
+ end
131
123
  end
132
124
  if stmt_cache_size
133
125
  # enable statement caching
@@ -148,7 +140,11 @@ class OCI8
148
140
  @session_handle.send(:attr_set_string, 424, "ruby-oci8 : #{OCI8::VERSION}")
149
141
  end
150
142
  server_attach(dbname, attach_mode)
151
- session_begin(cred ? cred : OCI_CRED_RDBMS, mode ? mode : OCI_DEFAULT)
143
+ if OCI8.oracle_client_version >= OCI8::ORAVER_11_1
144
+ self.send_timeout = OCI8::properties[:send_timeout] if OCI8::properties[:send_timeout]
145
+ self.recv_timeout = OCI8::properties[:recv_timeout] if OCI8::properties[:recv_timeout]
146
+ end
147
+ session_begin(cred ? cred : OCI_CRED_RDBMS, auth_mode)
152
148
  else
153
149
  # logon by the OCI function OCILogon2().
154
150
  logon2(username, password, dbname, attach_mode)
@@ -389,6 +385,10 @@ class OCI8
389
385
  # Zero means no timeout.
390
386
  # This is equivalent to {http://docs.oracle.com/database/121/NETRF/sqlnet.htm#NETRF228 SQLNET.SEND_TIMEOUT} in client-side sqlnet.ora.
391
387
  #
388
+ # If you need to set send timeout while establishing a connection, use {file:docs/timeout-parameters.md timeout parameters in OCI8::properties} instead.
389
+ #
390
+ # Note that the connection becomes unusable on timeout.
391
+ #
392
392
  # If you have trouble by setting this, don't use it because it uses
393
393
  # {http://blog.jiubao.org/2015/01/undocumented-oci-handle-attributes.html an undocumented OCI handle attribute}.
394
394
  #
@@ -417,6 +417,10 @@ class OCI8
417
417
  # Zero means no timeout.
418
418
  # This is equivalent to {http://docs.oracle.com/database/121/NETRF/sqlnet.htm#NETRF227 SQLNET.RECV_TIMEOUT} in client-side sqlnet.ora.
419
419
  #
420
+ # If you need to set receive timeout while establishing a connection, use {file:docs/timeout-parameters.md timeout parameters in OCI8::properties} instead.
421
+ #
422
+ # Note that the connection becomes unusable on timeout.
423
+ #
420
424
  # If you have trouble by setting this, don't use it because it uses
421
425
  # {http://blog.jiubao.org/2015/01/undocumented-oci-handle-attributes.html an undocumented OCI handle attribute}.
422
426
  #
@@ -442,6 +446,138 @@ class OCI8
442
446
  raise NotImplementedError, 'revc_timeout= is unimplemented in this Oracle version'
443
447
  end
444
448
  end
449
+
450
+ # A helper class to bind an array to paramters in IN-condition.
451
+ #
452
+ # See {file:docs/bind-array-to-in_cond.md Bind an Array to IN-condition}
453
+ class InCondBindHelper
454
+ def initialize(bind_name_prefix, array, type = nil, length = nil)
455
+ bind_name_prefix = bind_name_prefix.to_s
456
+ if bind_name_prefix !~ /^\w+$/
457
+ raise ArgumentError, "The first argument doesn't consist of alphanumeric characters and underscores."
458
+ end
459
+ if array.empty?
460
+ # This doesn't match anything.
461
+ # However in-condition requires at least one value.
462
+ @bind_names = ":#{bind_name_prefix}_0"
463
+ @bind_values = [[nil, type.nil? ? String : type, length]]
464
+ else
465
+ @bind_names = Array.new(array.length) do |index|
466
+ ":#{bind_name_prefix}_#{index}"
467
+ end.join(', ')
468
+ first_non_nil = array.find do |e|
469
+ !e.nil?
470
+ end
471
+ first_non_nil = '' if first_non_nil.nil?
472
+ @bind_values = array.collect do |elem|
473
+ if elem.nil? and type.nil?
474
+ [elem, first_non_nil.class]
475
+ else
476
+ [elem, type, length]
477
+ end
478
+ end
479
+ end
480
+ end
481
+
482
+ def names
483
+ @bind_names
484
+ end
485
+
486
+ def values
487
+ @bind_values
488
+ end
489
+ end
490
+
491
+ # Creates a helper object to bind an array to paramters in IN-condition.
492
+ #
493
+ # See {file:docs/bind-array-to-in_cond.md Bind an Array to IN-condition}
494
+ #
495
+ # @param [Symbol] bind_name_prefix prefix of the place holder name
496
+ # @param [Object] array an array of values to be bound.
497
+ # @param [Class] type data type. This is used as the third argument of {OCI8::Cursor#bind_param}.
498
+ # @param [Integer] length maximum bind length for string values. This is used as the fourth argument of {OCI8::Cursor#bind_param}.
499
+ # @return [OCI8::InCondBindHelper]
500
+ def self.in_cond(bind_name_prefix, array, type = nil, length = nil)
501
+ InCondBindHelper.new(bind_name_prefix, array, type, length)
502
+ end
503
+
504
+ private
505
+
506
+ # Converts the specified privilege name to the value passed to the
507
+ # fifth argument of OCISessionBegin().
508
+ #
509
+ # @private
510
+ def to_auth_mode(privilege)
511
+ case privilege
512
+ when :SYSDBA
513
+ 0x00000002 # OCI_SYSDBA in oci.h
514
+ when :SYSOPER
515
+ 0x00000004 # OCI_SYSOPER in oci.h
516
+ when :SYSASM
517
+ if OCI8.oracle_client_version < OCI8::ORAVER_11_1
518
+ raise "SYSASM is not supported on Oracle version #{OCI8.oracle_client_version}"
519
+ end
520
+ 0x00008000 # OCI_SYSASM in oci.h
521
+ when :SYSBACKUP
522
+ if OCI8.oracle_client_version < OCI8::ORAVER_12_1
523
+ raise "SYSBACKUP is not supported on Oracle version #{OCI8.oracle_client_version}"
524
+ end
525
+ 0x00020000 # OCI_SYSBKP in oci.h
526
+ when :SYSDG
527
+ if OCI8.oracle_client_version < OCI8::ORAVER_12_1
528
+ raise "SYSDG is not supported on Oracle version #{OCI8.oracle_client_version}"
529
+ end
530
+ 0x00040000 # OCI_SYSDGD in oci.h
531
+ when :SYSKM
532
+ if OCI8.oracle_client_version < OCI8::ORAVER_12_1
533
+ raise "SYSKM is not supported on Oracle version #{OCI8.oracle_client_version}"
534
+ end
535
+ 0x00080000 # OCI_SYSKMT in oci.h
536
+ when nil
537
+ 0 # OCI_DEFAULT
538
+ else
539
+ raise "unknown privilege type #{privilege}"
540
+ end
541
+ end
542
+
543
+ @@easy_connect_naming_regex = %r{
544
+ ^
545
+ (//)? # preceding double-slash($1)
546
+ (?:\[([\h:]+)\]|([^\s:/]+)) # IPv6 enclosed by square brackets($2) or hostname($3)
547
+ (?::(\d+))? # port($4)
548
+ (?:
549
+ /
550
+ ([^\s:/]+)? # service name($5)
551
+ (?::([^\s:/]+))? # server($6)
552
+ (?:/([^\s:/]+))? # instance name($7)
553
+ )?
554
+ $
555
+ }x
556
+
557
+ # Parse easy connect string as described in https://docs.oracle.com/database/121/NETAG/naming.htm
558
+ # and add TRANSPORT_CONNECT_TIMEOUT or CONNECT_TIMEOUT.
559
+ #
560
+ # @private
561
+ def to_connect_descriptor(database, tcp_connect_timeout, connect_timeout)
562
+ if @@easy_connect_naming_regex =~ database && ($1 || $2 || $4 || $5 || $6 || $7)
563
+ connect_data = []
564
+ connect_data << "(SERVICE_NAME=#$5)"
565
+ connect_data << "(SERVER=#$6)" if $6
566
+ connect_data << "(INSTANCE_NAME=#$7)" if $7
567
+ desc = []
568
+ desc << "(CONNECT_DATA=#{connect_data.join})"
569
+ desc << "(ADDRESS=(PROTOCOL=TCP)(HOST=#{$2 || $3})(PORT=#{$4 || 1521}))"
570
+ if tcp_connect_timeout
571
+ desc << "(TRANSPORT_CONNECT_TIMEOUT=#{tcp_connect_timeout})"
572
+ end
573
+ if connect_timeout
574
+ desc << "(CONNECT_TIMEOUT=#{connect_timeout})"
575
+ end
576
+ "(DESCRIPTION=#{desc.join})"
577
+ else
578
+ database
579
+ end
580
+ end
445
581
  end
446
582
 
447
583
  class OCIError
@@ -425,22 +425,6 @@ class OCIHandle
425
425
  # @private
426
426
  OCI_CRED_EXT = 2
427
427
 
428
- #################################
429
- #
430
- # Authentication Modes
431
- #
432
- #################################
433
-
434
- # for SYSDBA authorization
435
- # @private
436
- OCI_SYSDBA = 0x0002
437
- # for SYSOPER authorization
438
- # @private
439
- OCI_SYSOPER = 0x0004
440
- # for SYSASM authorization
441
- # @private
442
- OCI_SYSASM = 0x8000
443
-
444
428
  #################################
445
429
  #
446
430
  # OCI Parameter Types
@@ -13,6 +13,10 @@ class OCI8
13
13
  :statement_cache_size => 0,
14
14
  :events_mode => ((OCI8.__get_prop(2) & 4) != 0), # 4 <- OCI_EVENTS in oci.h
15
15
  :cancel_read_at_exit => false,
16
+ :tcp_connect_timeout => nil,
17
+ :connect_timeout => nil,
18
+ :send_timeout => nil,
19
+ :recv_timeout => nil,
16
20
  }
17
21
 
18
22
  # @private
@@ -53,6 +57,11 @@ class OCI8
53
57
  when :cancel_read_at_exit
54
58
  val = val ? true : false
55
59
  OCI8.__set_prop(3, val)
60
+ when :tcp_connect_timeout, :connect_timeout, :send_timeout, :recv_timeout
61
+ if !val.nil?
62
+ val = val.to_i
63
+ raise ArgumentError, "The property value for :#{name} must be nil or a positive integer." if val <= 0
64
+ end
56
65
  end
57
66
  super(name, val)
58
67
  end
@@ -132,6 +141,30 @@ class OCI8
132
141
  #
133
142
  # *Since:* 2.1.8
134
143
  #
144
+ # [:tcp_connect_timeout]
145
+ #
146
+ # See {file:docs/timeout-parameters.md}
147
+ #
148
+ # *Since:* 2.2.2
149
+ #
150
+ # [:connect_timeout]
151
+ #
152
+ # See {file:docs/timeout-parameters.md}
153
+ #
154
+ # *Since:* 2.2.2
155
+ #
156
+ # [:send_timeout]
157
+ #
158
+ # See {file:docs/timeout-parameters.md}
159
+ #
160
+ # *Since:* 2.2.2
161
+ #
162
+ # [:recv_timeout]
163
+ #
164
+ # See {file:docs/timeout-parameters.md}
165
+ #
166
+ # *Since:* 2.2.2
167
+ #
135
168
  # @return [a customized Hash]
136
169
  # @since 2.0.5
137
170
  #
@@ -1,3 +1,3 @@
1
1
  class OCI8
2
- VERSION = "2.2.1"
2
+ VERSION = "2.2.2"
3
3
  end
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ if caller[0] !~ /\/bundler\/runtime\.rb:\d+:in `require'/
2
+ warn "Don't requie 'ruby-oci8'. Use \"require 'oci8'\" instead. 'ruby-oci8.rb' was added only for 'Bundler.require'."
3
+ end
4
+ require 'oci8'
@@ -37,7 +37,7 @@ EOS
37
37
  s.has_rdoc = 'yard'
38
38
  s.authors = ['Kubo Takehiro']
39
39
  s.platform = gem_platform
40
- s.license = '2-clause BSD-style license'
40
+ s.license = 'BSD-2-Clause'
41
41
  files = File.read('dist-files').split("\n")
42
42
  if gem_platform == Gem::Platform::RUBY
43
43
  s.extensions << 'ext/oci8/extconf.rb'
@@ -10,6 +10,10 @@ drop type rb_test_obj_elem_array
10
10
  /
11
11
  drop type rb_test_obj_elem
12
12
  /
13
+ drop type rb_test_obj_sub
14
+ /
15
+ drop type rb_test_obj_base
16
+ /
13
17
  create type rb_test_obj_elem as object (
14
18
  x integer,
15
19
  y integer
@@ -116,7 +120,7 @@ create or replace type body rb_test_obj is
116
120
 
117
121
  static function test_object_version return integer is
118
122
  begin
119
- return 2;
123
+ return 3;
120
124
  end;
121
125
 
122
126
  static function class_func(n number) return rb_test_obj is
@@ -167,5 +171,21 @@ begin
167
171
  end loop;
168
172
  end;
169
173
  /
170
- commit
174
+
175
+ create type rb_test_obj_base as object (
176
+ id varchar2(30)
177
+ ) not final
178
+ /
179
+ create type rb_test_obj_sub under rb_test_obj_base (
180
+ subid varchar2(30)
181
+ ) final
182
+ /
183
+ create or replace function rb_test_obj_get_object(get_base integer) return rb_test_obj_base is
184
+ begin
185
+ if get_base = 0 then
186
+ return rb_test_obj_base('base');
187
+ else
188
+ return rb_test_obj_sub('sub', 'subid');
189
+ end if;
190
+ end;
171
191
  /
@@ -5,6 +5,7 @@ require "#{srcdir}/config"
5
5
 
6
6
  require "#{srcdir}/test_oradate"
7
7
  require "#{srcdir}/test_oranumber"
8
+ require "#{srcdir}/test_bind_array.rb"
8
9
  require "#{srcdir}/test_bind_string"
9
10
  require "#{srcdir}/test_bind_time"
10
11
  require "#{srcdir}/test_bind_raw"
@@ -75,4 +75,130 @@ class TestConnStr < Minitest::Test
75
75
  end
76
76
  end
77
77
  end
78
+
79
+ # https://docs.oracle.com/database/121/NETAG/naming.htm#BABJBFHJ
80
+ DESC_TEST_CASE =
81
+ [
82
+ # Cannot distinguish net service names from easy connect strings in this case.
83
+ ["sales-server", nil, nil, "sales-server"],
84
+ # Easy Connect string with host.
85
+ ["//sales-server", nil, nil, <<EOS],
86
+ (DESCRIPTION=
87
+ (CONNECT_DATA=
88
+ (SERVICE_NAME=))
89
+ (ADDRESS=
90
+ (PROTOCOL=TCP)
91
+ (HOST=sales-server)
92
+ (PORT=1521)))
93
+ EOS
94
+ # Easy Connect string with host and port.
95
+ ["sales-server:3456", nil, nil, <<EOS],
96
+ (DESCRIPTION=
97
+ (CONNECT_DATA=
98
+ (SERVICE_NAME=))
99
+ (ADDRESS=
100
+ (PROTOCOL=TCP)
101
+ (HOST=sales-server)
102
+ (PORT=3456)))
103
+ EOS
104
+ # The host name is sales-server and the service name is sales.
105
+ ["sales-server/sales", nil, nil, <<EOS],
106
+ (DESCRIPTION=
107
+ (CONNECT_DATA=
108
+ (SERVICE_NAME=sales))
109
+ (ADDRESS=
110
+ (PROTOCOL=TCP)
111
+ (HOST=sales-server)
112
+ (PORT=1521)))
113
+ EOS
114
+ # Easy Connect string with IPv6 address.
115
+ ["[2001:0db8:0:0::200C:417A]:80/sales", nil, nil, <<EOS],
116
+ (DESCRIPTION=
117
+ (CONNECT_DATA=
118
+ (SERVICE_NAME=sales))
119
+ (ADDRESS=
120
+ (PROTOCOL=TCP)
121
+ (HOST=2001:0db8:0:0::200C:417A)
122
+ (PORT=80)))
123
+ EOS
124
+ # Easy Connect string with IPv6 host address.
125
+ ["sales-server:80/sales", nil, nil, <<EOS],
126
+ (DESCRIPTION=
127
+ (CONNECT_DATA=
128
+ (SERVICE_NAME=sales))
129
+ (ADDRESS=
130
+ (PROTOCOL=TCP)
131
+ (HOST=sales-server)
132
+ (PORT=80)))
133
+ EOS
134
+ # Easy Connect string with host, service name, and server.
135
+ ["sales-server/sales:dedicated/inst1", nil, nil, <<EOS],
136
+ (DESCRIPTION=
137
+ (CONNECT_DATA=
138
+ (SERVICE_NAME=sales)
139
+ (SERVER=dedicated)
140
+ (INSTANCE_NAME=inst1))
141
+ (ADDRESS=
142
+ (PROTOCOL=TCP)
143
+ (HOST=sales-server)
144
+ (PORT=1521)))
145
+ EOS
146
+ ["sales-server//inst1", nil, nil, <<EOS],
147
+ (DESCRIPTION=
148
+ (CONNECT_DATA=
149
+ (SERVICE_NAME=)
150
+ (INSTANCE_NAME=inst1))
151
+ (ADDRESS=
152
+ (PROTOCOL=TCP)
153
+ (HOST=sales-server)
154
+ (PORT=1521)))
155
+ EOS
156
+ #
157
+ ["sales-server/sales", 20, nil, <<EOS],
158
+ (DESCRIPTION=
159
+ (CONNECT_DATA=
160
+ (SERVICE_NAME=sales))
161
+ (ADDRESS=
162
+ (PROTOCOL=TCP)
163
+ (HOST=sales-server)
164
+ (PORT=1521))
165
+ (TRANSPORT_CONNECT_TIMEOUT=20))
166
+ EOS
167
+ #
168
+ ["sales-server/sales", nil, 30, <<EOS],
169
+ (DESCRIPTION=
170
+ (CONNECT_DATA=
171
+ (SERVICE_NAME=sales))
172
+ (ADDRESS=
173
+ (PROTOCOL=TCP)
174
+ (HOST=sales-server)
175
+ (PORT=1521))
176
+ (CONNECT_TIMEOUT=30))
177
+ EOS
178
+ #
179
+ ["sales-server/sales", 20, 30, <<EOS],
180
+ (DESCRIPTION=
181
+ (CONNECT_DATA=
182
+ (SERVICE_NAME=sales))
183
+ (ADDRESS=
184
+ (PROTOCOL=TCP)
185
+ (HOST=sales-server)
186
+ (PORT=1521))
187
+ (TRANSPORT_CONNECT_TIMEOUT=20)
188
+ (CONNECT_TIMEOUT=30))
189
+ EOS
190
+ ]
191
+
192
+ def test_connect_descriptor
193
+ obj = OCI8.allocate # create an uninitialized object.
194
+ DESC_TEST_CASE.each do |test_case|
195
+ easy_connect_string = test_case[0]
196
+ tcp_connnect_timeout= test_case[1]
197
+ outbound_connnect_timeout = test_case[2]
198
+ expected_result = test_case[3].gsub(/\s/, '')
199
+ # use instance_eval to call a private method to_connect_descriptor
200
+ result = obj.instance_eval { to_connect_descriptor(easy_connect_string, tcp_connnect_timeout, outbound_connnect_timeout) }
201
+ assert_equal(expected_result, result, easy_connect_string)
202
+ end
203
+ end
78
204
  end
@@ -22,7 +22,7 @@ begin
22
22
 
23
23
  begin
24
24
  version = RbTestObj.test_object_version(conn)
25
- error_message = "Invalid test object version" if version != 2
25
+ error_message = "Invalid test object version" if version != 3
26
26
  rescue NoMethodError
27
27
  raise unless $!.to_s.include?('test_object_version')
28
28
  error_message = "rb_test_obj.test_object_version is not declared."
@@ -48,6 +48,12 @@ EOS
48
48
  class RbTestIntArray < OCI8::Object::Base
49
49
  end
50
50
 
51
+ class RbTestObjBase < OCI8::Object::Base
52
+ end
53
+
54
+ class RbTestObjSub < RbTestObjBase
55
+ end
56
+
51
57
  class TestObj1 < Minitest::Test
52
58
  Delta = 0.00001
53
59
 
@@ -456,4 +462,23 @@ EOS
456
462
  assert_equal(ary ? ary[2] : nil, csr[:out3])
457
463
  end
458
464
  end
465
+
466
+ def test_get_subtype
467
+ csr = @conn.parse("BEGIN :result := rb_test_obj_get_object(:1); END;")
468
+ csr.bind_param(1, nil, RbTestObjBase)
469
+ csr.bind_param(2, nil, Integer)
470
+
471
+ csr[2] = 0
472
+ csr.exec
473
+ val = csr[1]
474
+ assert_instance_of(RbTestObjBase, val)
475
+ assert_equal(val.id, 'base')
476
+
477
+ csr[2] = 1
478
+ csr.exec
479
+ val = csr[1]
480
+ assert_instance_of(RbTestObjSub, val)
481
+ assert_equal(val.id, 'sub')
482
+ assert_equal(val.subid, 'subid')
483
+ end
459
484
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-oci8
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 1
10
- version: 2.2.1
9
+ - 2
10
+ version: 2.2.2
11
11
  platform: x86-mingw32
12
12
  authors:
13
13
  - Kubo Takehiro
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2015-11-01 00:00:00 +09:00
18
+ date: 2016-04-24 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -42,13 +42,16 @@ files:
42
42
  - pre-distclean.rb
43
43
  - ruby-oci8.gemspec
44
44
  - setup.rb
45
+ - docs/bind-array-to-in_cond.md
45
46
  - docs/install-binary-package.md
46
47
  - docs/install-full-client.md
47
48
  - docs/install-instant-client.md
48
49
  - docs/install-on-osx.md
50
+ - docs/conflicts-local-connections-and-processes.md
49
51
  - docs/osx-install-dev-tools.png
50
52
  - docs/platform-specific-issues.md
51
53
  - docs/report-installation-issue.md
54
+ - docs/timeout-parameters.md
52
55
  - lib/.document
53
56
  - lib/oci8.rb
54
57
  - lib/dbd/OCI8.rb
@@ -68,6 +71,7 @@ files:
68
71
  - lib/oci8/oracle_version.rb
69
72
  - lib/oci8/properties.rb
70
73
  - lib/oci8/version.rb
74
+ - lib/ruby-oci8.rb
71
75
  - test/README
72
76
  - test/config.rb
73
77
  - test/setup_test_object.sql
@@ -96,12 +100,13 @@ files:
96
100
  - test/test_rowid.rb
97
101
  - lib/oci8lib_220.so
98
102
  - lib/oci8lib_191.so
103
+ - lib/oci8lib_230.so
99
104
  - lib/oci8lib_200.so
100
105
  - lib/oci8lib_210.so
101
106
  has_rdoc: true
102
107
  homepage: http://www.rubydoc.info/github/kubo/ruby-oci8
103
108
  licenses:
104
- - 2-clause BSD-style license
109
+ - BSD-2-Clause
105
110
  post_install_message:
106
111
  rdoc_options: []
107
112