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 +1 -6
- data/ChangeLog +98 -0
- data/NEWS +48 -1
- data/README.md +7 -0
- data/dist-files +4 -0
- data/docs/bind-array-to-in_cond.md +38 -0
- data/docs/conflicts-local-connections-and-processes.md +95 -0
- data/docs/report-installation-issue.md +8 -8
- data/docs/timeout-parameters.md +91 -0
- data/lib/oci8/connection_pool.rb +74 -3
- data/lib/oci8/cursor.rb +13 -6
- data/lib/oci8/object.rb +4 -1
- data/lib/oci8/oci8.rb +157 -21
- data/lib/oci8/ocihandle.rb +0 -16
- data/lib/oci8/properties.rb +33 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8lib_191.so +0 -0
- data/lib/oci8lib_200.so +0 -0
- data/lib/oci8lib_210.so +0 -0
- data/lib/oci8lib_220.so +0 -0
- data/lib/oci8lib_230.so +0 -0
- data/lib/ruby-oci8.rb +4 -0
- data/ruby-oci8.gemspec +1 -1
- data/test/setup_test_object.sql +22 -2
- data/test/test_all.rb +1 -0
- data/test/test_connstr.rb +126 -0
- data/test/test_object.rb +26 -1
- metadata +10 -5
data/.yardopts
CHANGED
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
|
-
|
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
|
24
|
-
ruby -r rbconfig -e "p
|
25
|
-
ruby -r rbconfig -e "p
|
26
|
-
ruby -r rbconfig -e "p
|
27
|
-
ruby -r rbconfig -e "p
|
28
|
-
ruby -r rbconfig -e "p
|
29
|
-
ruby -r rbconfig -e "p
|
30
|
-
ruby -r rbconfig -e "p
|
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
|
data/lib/oci8/connection_pool.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
# #
|
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
|
-
# #
|
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
|
|
data/lib/oci8/cursor.rb
CHANGED
@@ -384,12 +384,19 @@ class OCI8
|
|
384
384
|
attr_set_ub4(11, rows) # OCI_ATTR_PREFETCH_ROWS(11)
|
385
385
|
end
|
386
386
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
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.
|
data/lib/oci8/object.rb
CHANGED
@@ -78,7 +78,8 @@ EOS
|
|
78
78
|
#
|
79
79
|
# @private
|
80
80
|
def get_tdo_by_typename(typename)
|
81
|
-
|
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
|
data/lib/oci8/oci8.rb
CHANGED
@@ -63,9 +63,9 @@ class OCI8
|
|
63
63
|
#
|
64
64
|
# === connecting as a privileged user
|
65
65
|
#
|
66
|
-
# Set :SYSDBA
|
67
|
-
#
|
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,
|
99
|
+
username, password, dbname, privilege = parse_connect_string(args[0])
|
100
100
|
else
|
101
|
-
username, password, dbname,
|
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
|
-
|
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
|
-
|
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
|
data/lib/oci8/ocihandle.rb
CHANGED
@@ -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
|
data/lib/oci8/properties.rb
CHANGED
@@ -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
|
#
|
data/lib/oci8/version.rb
CHANGED
data/lib/oci8lib_191.so
CHANGED
Binary file
|
data/lib/oci8lib_200.so
CHANGED
Binary file
|
data/lib/oci8lib_210.so
CHANGED
Binary file
|
data/lib/oci8lib_220.so
CHANGED
Binary file
|
data/lib/oci8lib_230.so
ADDED
Binary file
|
data/lib/ruby-oci8.rb
ADDED
data/ruby-oci8.gemspec
CHANGED
@@ -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-
|
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'
|
data/test/setup_test_object.sql
CHANGED
@@ -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
|
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
|
-
|
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
|
/
|
data/test/test_all.rb
CHANGED
data/test/test_connstr.rb
CHANGED
@@ -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
|
data/test/test_object.rb
CHANGED
@@ -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 !=
|
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:
|
4
|
+
hash: 3
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 2.2.
|
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:
|
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-
|
109
|
+
- BSD-2-Clause
|
105
110
|
post_install_message:
|
106
111
|
rdoc_options: []
|
107
112
|
|