ruby-oci8 2.2.1-x64-mingw32 → 2.2.2-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- 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_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 +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d7f83a39f4ae39e59a05d9269b9bed499207284
|
4
|
+
data.tar.gz: f2a3f0b8d4650cbcfbe58ad0d3d6d0b652d11d18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6c35fdeb795cd3bc0def2104e2bd83d789a966afc67617dc9f4f37210c31a64538c9028d9304d940b9e81c16aaab8385c6911153932a2dc364833dc9329f651
|
7
|
+
data.tar.gz: 2da0ed025102a16fbb368f6a3e8fa4083684c94e684b8617cd4c1cd569a2db7db5ae896545ffe21923320b9e45e78aecf64c15bbd9b1b61dcf89d3bfb6b67887
|
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_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,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-oci8
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: x64-mingw32
|
6
6
|
authors:
|
7
7
|
- Kubo Takehiro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
ruby-oci8 is a ruby interface for Oracle using OCI8 API. It is available with Oracle 10g or later including Oracle Instant Client.
|
@@ -30,13 +30,16 @@ files:
|
|
30
30
|
- pre-distclean.rb
|
31
31
|
- ruby-oci8.gemspec
|
32
32
|
- setup.rb
|
33
|
+
- docs/bind-array-to-in_cond.md
|
33
34
|
- docs/install-binary-package.md
|
34
35
|
- docs/install-full-client.md
|
35
36
|
- docs/install-instant-client.md
|
36
37
|
- docs/install-on-osx.md
|
38
|
+
- docs/conflicts-local-connections-and-processes.md
|
37
39
|
- docs/osx-install-dev-tools.png
|
38
40
|
- docs/platform-specific-issues.md
|
39
41
|
- docs/report-installation-issue.md
|
42
|
+
- docs/timeout-parameters.md
|
40
43
|
- lib/.document
|
41
44
|
- lib/oci8.rb
|
42
45
|
- lib/dbd/OCI8.rb
|
@@ -56,6 +59,7 @@ files:
|
|
56
59
|
- lib/oci8/oracle_version.rb
|
57
60
|
- lib/oci8/properties.rb
|
58
61
|
- lib/oci8/version.rb
|
62
|
+
- lib/ruby-oci8.rb
|
59
63
|
- test/README
|
60
64
|
- test/config.rb
|
61
65
|
- test/setup_test_object.sql
|
@@ -83,11 +87,12 @@ files:
|
|
83
87
|
- test/test_package_type.rb
|
84
88
|
- test/test_rowid.rb
|
85
89
|
- lib/oci8lib_220.so
|
90
|
+
- lib/oci8lib_230.so
|
86
91
|
- lib/oci8lib_200.so
|
87
92
|
- lib/oci8lib_210.so
|
88
93
|
homepage: http://www.rubydoc.info/github/kubo/ruby-oci8
|
89
94
|
licenses:
|
90
|
-
- 2-
|
95
|
+
- BSD-2-Clause
|
91
96
|
metadata: {}
|
92
97
|
post_install_message:
|
93
98
|
rdoc_options: []
|