ruby-oci8 2.2.4.1-x86-mingw32 → 2.2.5-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/ChangeLog +51 -1
- data/NEWS +58 -0
- data/README.md +4 -1
- data/dist-files +6 -2
- data/docs/bind-array-to-in_cond.md +1 -1
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/lib/oci8/bindtype.rb +1 -1
- data/lib/oci8/check_load_error.rb +16 -4
- data/lib/oci8/cursor.rb +2 -4
- data/lib/oci8/oci8.rb +19 -24
- 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/oci8lib_240.so +0 -0
- data/test/setup_test_package.sql +59 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_oranumber.rb +3 -3
- metadata +13 -10
data/ChangeLog
CHANGED
@@ -1,7 +1,57 @@
|
|
1
|
+
2017-10-21 Kubo Takehiro <kubo@jiubao.org>
|
2
|
+
* NEWS: Add changes between 2.2.4.1 and 2.2.5
|
3
|
+
* lib/oci8/version.rb: Update to 2.2.5
|
4
|
+
* docs/number-type-mapping.md: minor fix
|
5
|
+
* dist-files: Add files.
|
6
|
+
|
7
|
+
2017-10-18 Kubo Takehiro <kubo@jiubao.org>
|
8
|
+
* docs/number-type-mapping.md, README.md, dist-files: Add document
|
9
|
+
about the mapping between Oracle number types and Ruby classes.
|
10
|
+
|
11
|
+
2017-10-17 Kubo Takehiro <kubo@jiubao.org>
|
12
|
+
* lib/oci8/check_load_error.rb: Check error reason when loading
|
13
|
+
failed with 'The specified module could not be found' on Windows.
|
14
|
+
|
15
|
+
2017-10-17 Kubo Takehiro <kubo@jiubao.org>
|
16
|
+
* lib/oci8/check_load_error.rb: Fix LoadError while trying to check
|
17
|
+
errors in "require 'oci8lib_230.so'" on cygwin 2.8 or later.
|
18
|
+
(related to github issue #176)
|
19
|
+
|
20
|
+
2017-10-17 Kubo Takehiro <kubo@jiubao.org>
|
21
|
+
* ext/oci8/ocinumber.c, test/test_oranumber.rb:
|
22
|
+
Add OraNumber#has_fractional_part?.
|
23
|
+
|
24
|
+
2017-10-01 Kubo Takehiro <kubo@jiubao.org>
|
25
|
+
* ext/oci8/plthook_elf.c: Update plthook to use prelinked
|
26
|
+
libclntsh.so on Linux.
|
27
|
+
(github issue #172)
|
28
|
+
|
29
|
+
2017-09-27 Kubo Takehiro <kubo@jiubao.org>
|
30
|
+
* ext/oci8/oci8lib.c: Change order to load libclntsh when runtime
|
31
|
+
api check is enabled on Unix.
|
32
|
+
|
33
|
+
2017-09-24 Kubo Takehiro <kubo@jiubao.org>
|
34
|
+
* ext/oci8/oci8lib.c: Try to load $ORACLE_HOME/lib/libclntsh.so also
|
35
|
+
when runtime api check is enabled on Unix.
|
36
|
+
|
37
|
+
2017-09-23 Kubo Takehiro <kubo@jiubao.org>
|
38
|
+
* lib/oci8/cursor.rb: Don't call unnecessary __paramGet(i) when a
|
39
|
+
cursor is executed more than once.
|
40
|
+
(pointed by OMOTO Kenji at github issue #171)
|
41
|
+
|
42
|
+
2017-07-09 Kubo Takehiro <kubo@jiubao.org>
|
43
|
+
* ext/oci8/apiwrap.yml, ext/oci8/oci8.c, lib/oci8/oci8.rb:
|
44
|
+
Delete unused code using OCILogon2 and OCILogoff.
|
45
|
+
|
46
|
+
2017-07-09 Kubo Takehiro <kubo@jiubao.org>
|
47
|
+
* ext/oci8/error.c: Delete OCIError#initialize defined by C code
|
48
|
+
to suppress warning: method redefined; discarding old initialize.
|
49
|
+
(github issue #168)
|
50
|
+
|
1
51
|
2017-06-17 Kubo Takehiro <kubo@jiubao.org>
|
2
52
|
* NEWS: Add changes between 2.2.4 and 2.2.4.1
|
3
53
|
* lib/oci8/version.rb: Update to 2.2.4.1
|
4
|
-
* lib/oci8/
|
54
|
+
* lib/oci8/properties.rb: Fix URL links
|
5
55
|
* docs/hanging-after-inactivity.md: Revised
|
6
56
|
|
7
57
|
2017-06-16 Kubo Takehiro <kubo@jiubao.org>
|
data/NEWS
CHANGED
@@ -1,5 +1,63 @@
|
|
1
1
|
# @markup markdown
|
2
2
|
|
3
|
+
2.2.5
|
4
|
+
=====
|
5
|
+
|
6
|
+
New Features
|
7
|
+
------------
|
8
|
+
|
9
|
+
### Try to load $ORACLE_HOME/lib/libclntsh.so also when runtime api check is enabled on Unix.
|
10
|
+
|
11
|
+
When ruby-oci8 is configured with `--with-runtime-check`, it loads Oracle client
|
12
|
+
library and checks available functions in the library at runtime. This feature was
|
13
|
+
added to release Windows binary gems which cannot know Oracle version at compile time.
|
14
|
+
This is available also on Unix. However it tries to load libraries in LD_LIBRARY_PATH only.
|
15
|
+
From this version, it tries to load $ORACLE_HOME/lib/libclntsh.so also.
|
16
|
+
|
17
|
+
### Check error reasons when loading failed with 'The specified module could not be found' on Windows.
|
18
|
+
|
19
|
+
The error messages are same when OCI.DLL isn't found and when Visual
|
20
|
+
C++ runtime library depended on by OCI.DLL isn't found. From this
|
21
|
+
version, ruby-oci8 distinguishes the difference and prints other message
|
22
|
+
for the latter case.
|
23
|
+
|
24
|
+
Fixed issue
|
25
|
+
-----------
|
26
|
+
|
27
|
+
### Fix segmentation fault when Oracle client library is prelinked.
|
28
|
+
|
29
|
+
When Oracle instant client rpm package is used on RHEL5 or RHEL6,
|
30
|
+
Oracle client library is modified by [prelink][] and ruby-oci8 crashed
|
31
|
+
with segmentation fault. This is not due to Oracle, but due to
|
32
|
+
plthook used by ruby-oci8. The plthook was fixed to work with
|
33
|
+
prelinked libraries.
|
34
|
+
(github issue #172)
|
35
|
+
|
36
|
+
[prelink]: https://en.wikipedia.org/wiki/Prelink#Linux
|
37
|
+
|
38
|
+
### Fix not to hide the original error message of LoadError on recent cygwin.
|
39
|
+
|
40
|
+
Ruby-oci8 tries to check error messages when `require 'oci8lib_xxx.so` fails.
|
41
|
+
However the message was hidden by an exception while checking on cygwin.
|
42
|
+
(github issue #176)
|
43
|
+
|
44
|
+
### Don't call unnecessary __paramGet(i) when a cursor is executed more than once.
|
45
|
+
|
46
|
+
pointed by OMOTO Kenji
|
47
|
+
(github issue #171)
|
48
|
+
|
49
|
+
### Suppress warning: method redefined; discarding old initialize.
|
50
|
+
|
51
|
+
(github issue #168)
|
52
|
+
|
53
|
+
Other Changes
|
54
|
+
-------------
|
55
|
+
|
56
|
+
### Add document about the mapping between Oracle number types and Ruby classes.
|
57
|
+
|
58
|
+
See {file:docs/number-type-mapping.md Number Type Mapping between Oracle and Ruby}.
|
59
|
+
(github issue #173)
|
60
|
+
|
3
61
|
2.2.4.1
|
4
62
|
=======
|
5
63
|
|
data/README.md
CHANGED
@@ -24,7 +24,9 @@ See {file:NEWS}.
|
|
24
24
|
Sample one-liner
|
25
25
|
----------------
|
26
26
|
|
27
|
-
|
27
|
+
When you have an Oracle database server to which `sqlplus scott/tiger` can connect
|
28
|
+
and `scott` user has `emp` table, you can select `emp` and print rows
|
29
|
+
as CSV by the followig one liner.
|
28
30
|
|
29
31
|
ruby -r oci8 -e "OCI8.new('scott', 'tiger').exec('select * from emp') do |r| puts r.join(','); end"
|
30
32
|
|
@@ -50,6 +52,7 @@ Report issues
|
|
50
52
|
Other documents
|
51
53
|
---------------
|
52
54
|
|
55
|
+
* {file:docs/number-type-mapping.md Number Type Mapping between Oracle and Ruby}
|
53
56
|
* {file:docs/timeout-parameters.md Timeout Parameters}
|
54
57
|
* {file:docs/conflicts-local-connections-and-processes.md Conflicts between Local Connections and Child Process Handling on Unix}
|
55
58
|
* {file:docs/hanging-after-inactivity.md Hanging After a Long Period of Inactivity}
|
data/dist-files
CHANGED
@@ -11,12 +11,14 @@ pre-distclean.rb
|
|
11
11
|
ruby-oci8.gemspec
|
12
12
|
setup.rb
|
13
13
|
docs/bind-array-to-in_cond.md
|
14
|
+
docs/conflicts-local-connections-and-processes.md
|
15
|
+
docs/hanging-after-inactivity.md
|
14
16
|
docs/install-binary-package.md
|
15
17
|
docs/install-full-client.md
|
16
18
|
docs/install-instant-client.md
|
17
19
|
docs/install-on-osx.md
|
18
|
-
docs/
|
19
|
-
docs/
|
20
|
+
docs/ldap-auth-and-function-interposition.md
|
21
|
+
docs/number-type-mapping.md
|
20
22
|
docs/osx-install-dev-tools.png
|
21
23
|
docs/platform-specific-issues.md
|
22
24
|
docs/report-installation-issue.md
|
@@ -81,10 +83,12 @@ lib/ruby-oci8.rb
|
|
81
83
|
test/README
|
82
84
|
test/config.rb
|
83
85
|
test/setup_test_object.sql
|
86
|
+
test/setup_test_package.sql
|
84
87
|
test/test_all.rb
|
85
88
|
test/test_appinfo.rb
|
86
89
|
test/test_array_dml.rb
|
87
90
|
test/test_bind_array.rb
|
91
|
+
test/test_bind_boolean.rb
|
88
92
|
test/test_bind_raw.rb
|
89
93
|
test/test_bind_string.rb
|
90
94
|
test/test_bind_time.rb
|
@@ -27,7 +27,7 @@ The above code is rewritten as follows:
|
|
27
27
|
|
28
28
|
ids = [ ... ] # an arbitrary-length array containing user IDs.
|
29
29
|
|
30
|
-
in_cond = OCI8::in_cond(:id, ids)
|
30
|
+
in_cond = OCI8::in_cond(:id, ids)
|
31
31
|
cursor = conn.exec("select * from users where id in (#{in_cond.names})", *in_cond.values)
|
32
32
|
|
33
33
|
or
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# @title LDAP Authentication and Function Interposition
|
2
|
+
|
3
|
+
LDAP Authentication and Function Interposition
|
4
|
+
==============================================
|
5
|
+
|
6
|
+
Problems
|
7
|
+
--------
|
8
|
+
|
9
|
+
The following code may trigger segmentation faults or unexpected behaviours.
|
10
|
+
|
11
|
+
require 'pg' # or any modules using LDAP such as ActiveLdap
|
12
|
+
require 'oci8'
|
13
|
+
|
14
|
+
conn = OCI8.new('username/password@dbname.example.com')
|
15
|
+
...
|
16
|
+
|
17
|
+
It happens when all the following conditions are satisfied.
|
18
|
+
|
19
|
+
* The platform is Unix
|
20
|
+
* The PostgreSQL client library, which `pg` depends, was compiled with LDAP support.
|
21
|
+
* LDAP authentication is used to connect to an Oracle server.
|
22
|
+
|
23
|
+
It is caused by function interposition as follows:
|
24
|
+
|
25
|
+
* The ruby process loads `pq` and its depending libraries such as
|
26
|
+
`libpq.so`(PostgreSQL client library) and `libldap_r.so`(LDAP library).
|
27
|
+
* Then it loads `oci8` and its depending libraries such as
|
28
|
+
`libclntsh.so`(Oracle client library).
|
29
|
+
* When LDAP authentication is used, `libclntsh.so` tries to use
|
30
|
+
LDAP functions in the library.
|
31
|
+
* However it uses LDAP functions in `libldap_r.so` because the function
|
32
|
+
in the firstly loaded library is used when more than one library exports
|
33
|
+
functions whose names are same.
|
34
|
+
* It triggers segmentation faults or unexpected behaviours because
|
35
|
+
implementations of LDAP functions are different even though their names
|
36
|
+
are same.
|
37
|
+
|
38
|
+
The reverse may cause same results by the following code.
|
39
|
+
|
40
|
+
require 'oci8'
|
41
|
+
require 'pg'
|
42
|
+
|
43
|
+
... connect to PostgreSQL using LDAP ...
|
44
|
+
|
45
|
+
### Note for macOS
|
46
|
+
|
47
|
+
Libraries in two-level namespaces are free from function interposition on macOS.
|
48
|
+
See the second paragraph of [this document][mach-o]. If `TWOLEVEL` is
|
49
|
+
found in the output of `otool -hV /path/to/library`, it is in a
|
50
|
+
two-level namespace. Otherwise it is in a single-level (flat) namespace.
|
51
|
+
|
52
|
+
Oracle client library (`libclntsh.dylib.12.1`) is in a flat namespace.
|
53
|
+
It suffers from function interposition.
|
54
|
+
|
55
|
+
$ otool -hV libclntsh.dylib.12.1
|
56
|
+
Mach header
|
57
|
+
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
58
|
+
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 19 2360 DYLDLINK NO_REEXPORTED_DYLIBS MH_HAS_TLV_DESCRIPTORS
|
59
|
+
|
60
|
+
PostgreSQL client library (`libpq.5.dylib`) installed by [brew][] depends on an OS-supplied LDAP library.
|
61
|
+
|
62
|
+
$ otool -L libpq.5.dylib
|
63
|
+
libpq.5.dylib:
|
64
|
+
/usr/local/opt/postgresql/lib/libpq.5.dylib (compatibility version 5.0.0, current version 5.9.0)
|
65
|
+
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
|
66
|
+
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
|
67
|
+
/System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos (compatibility version 5.0.0, current version 6.0.0)
|
68
|
+
/System/Library/Frameworks/LDAP.framework/Versions/A/LDAP (compatibility version 1.0.0, current version 2.4.0)
|
69
|
+
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
|
70
|
+
|
71
|
+
The OS-supplied LDAP library is in a two-level namespace.
|
72
|
+
|
73
|
+
$ otool -hV /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP
|
74
|
+
Mach header
|
75
|
+
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
76
|
+
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 22 2528 NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS APP_EXTENSION_SAFE
|
77
|
+
|
78
|
+
As a result, the PostgreSQL client library is free from function interposition.
|
79
|
+
|
80
|
+
Solution 1
|
81
|
+
----------
|
82
|
+
|
83
|
+
If you don't connect to PostgreSQL using LDAP, use the following code.
|
84
|
+
|
85
|
+
require 'oci8' # This must be before "require 'pg'".
|
86
|
+
require 'pg'
|
87
|
+
|
88
|
+
conn = OCI8.new('username/password@dbname.example.com')
|
89
|
+
...
|
90
|
+
... connect to a PostgreSQL server ...
|
91
|
+
|
92
|
+
Oracle client library uses LDAP functions in `libclntsh.so` because `libclntsh.so`
|
93
|
+
is loaded before `libldap_r.so`.
|
94
|
+
|
95
|
+
Don't connect to PostgreSQL using LDAP because `libpq.so` tries to use
|
96
|
+
LDAP functions in `libldap_r.so` but faultily uses functions in `libclntsh.so`.
|
97
|
+
|
98
|
+
Note for macOS: This fixes all function interposition issues if the LDAP library
|
99
|
+
in a two-level namespace.
|
100
|
+
|
101
|
+
Solution 2
|
102
|
+
----------
|
103
|
+
|
104
|
+
If LDAP is used to connect to both Oracle and PostgreSQL and the platform
|
105
|
+
is Linux or macOS, use ruby-oci8 2.2.4 or later and use the following code.
|
106
|
+
|
107
|
+
require 'pg'
|
108
|
+
require 'oci8' # This must be after "require 'pg'".
|
109
|
+
|
110
|
+
conn = OCI8.new('username/password@dbname.example.com')
|
111
|
+
...
|
112
|
+
... connect to a PostgreSQL server using LDAP ...
|
113
|
+
|
114
|
+
PostgreSQL client library uses LDAP functions in `libldap_r.so` because `libldap_r.so`
|
115
|
+
is loaded before `libclntsh.so`.
|
116
|
+
|
117
|
+
Oracle client library uses LDAP functions in `libclntsh.so` because ruby-oci8
|
118
|
+
forcedly modifies PLT (Procedure Linkage Table) entries to point to
|
119
|
+
functions in `libclntsh.so` if they point to functions in other libraries.
|
120
|
+
(PLT is equivalent to IAT (Import Address Table) on Windows.)
|
121
|
+
|
122
|
+
[mach-o]: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html
|
123
|
+
[brew]: http://brew.sh/
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# @title Number Type Mapping between Oracle and Ruby
|
2
|
+
|
3
|
+
Number Type Mapping between Oracle and Ruby
|
4
|
+
===========================================
|
5
|
+
|
6
|
+
Default mapping
|
7
|
+
---------------
|
8
|
+
|
9
|
+
Oracle numbers in select statements are fetched as followings by default:
|
10
|
+
|
11
|
+
| Oracle Data Type | Ruby Class |
|
12
|
+
|---|---|
|
13
|
+
| NUMBER(prec) or NUMBER(prec, 0) | Integer |
|
14
|
+
| NUMBER(prec, scale) where prec < 15 and scale != 0 | Float |
|
15
|
+
| NUMBER(prec, scale) where prec >= 15 and scale != 0 | BigDecimal |
|
16
|
+
| FLOAT or FLOAT(prec) | Float |
|
17
|
+
| NUMBER without precision and scale | BigDecimal |
|
18
|
+
| number type returned by functions or calculated number | BigDecimal |
|
19
|
+
| BINARY_FLOAT | Float |
|
20
|
+
| BINARY_DOUBLE | Float |
|
21
|
+
|
22
|
+
When the data type is within Integer or Float class, it is fetched
|
23
|
+
as Integer or Float. Otherwise, BigDecimal.
|
24
|
+
|
25
|
+
Note that the mapping is determined by the column definition in
|
26
|
+
select statements, not by the actual value fetched.
|
27
|
+
For example the column in `select count(*) from table_name` is
|
28
|
+
fetched as BigDecimal because it is returned from `count` function.
|
29
|
+
|
30
|
+
The mapping is customizable by `OCI8::BindType::Mapping`.
|
31
|
+
The default values of Oracle number data type mapping are:
|
32
|
+
|
33
|
+
# NUMBER or FLOAT data type, used for the first six rows in the above table
|
34
|
+
OCI8::BindType::Mapping[:number] = OCI8::BindType::Number
|
35
|
+
# BINARY_FLOAT data type, used for the seventh row in the above table
|
36
|
+
OCI8::BindType::Mapping[:binary_float] = OCI8::BindType::BinaryDouble
|
37
|
+
# BINARY_DOUBLE data type, used for the eighth row in the above table
|
38
|
+
OCI8::BindType::Mapping[:binary_double] = OCI8::BindType::BinaryDouble
|
39
|
+
|
40
|
+
`OCI8::BindType::Number` checks precision and scale to determine
|
41
|
+
ruby class. The first four rows in the above table are hard-coded.
|
42
|
+
The fifth and sixth rows are, however, customizable by
|
43
|
+
`OCI8::BindType::Mapping[:number_no_prec_setting]` and
|
44
|
+
`OCI8::BindType::Mapping[:number_unknown_prec]` respectively.
|
45
|
+
|
46
|
+
The default values are:
|
47
|
+
|
48
|
+
OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::BigDecimal
|
49
|
+
OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::BigDecimal
|
50
|
+
|
51
|
+
The mapping may be changed as follows in future.
|
52
|
+
|
53
|
+
| Oracle Data Type | Ruby Class |
|
54
|
+
|---|---|
|
55
|
+
| NUMBER(prec) or NUMBER(prec, 0) | Integer |
|
56
|
+
| other NUMBER | OraNumber |
|
57
|
+
| BINARY_FLOAT | Float |
|
58
|
+
| BINARY_DOUBLE | Float |
|
59
|
+
|
60
|
+
Customize mapping
|
61
|
+
-----------------
|
62
|
+
|
63
|
+
Add the following code to fetch all number or float columns as {OraNumber}.
|
64
|
+
|
65
|
+
OCI8::BindType::Mapping[:number] = OCI8::BindType::OraNumber
|
66
|
+
|
67
|
+
Otherwise, add the following code to customize the fifth and sixth rows only
|
68
|
+
in the above table.
|
69
|
+
|
70
|
+
OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::OraNumber
|
71
|
+
OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::OraNumber
|
72
|
+
|
73
|
+
If you want to fetch numbers as Integer or Float by its actual value, use
|
74
|
+
the following code:
|
75
|
+
|
76
|
+
# Fetch numbers as Integer when their fractional part is zero.
|
77
|
+
# Otherwise, Float. For example when a column contains 10 and
|
78
|
+
# 10.1, they are fetched as Integer and Float respectively.
|
79
|
+
OCI8::BindType::Mapping[:number] = OCI8::BindType::BasicNumberType
|
data/lib/oci8/bindtype.rb
CHANGED
@@ -8,17 +8,29 @@ class OCI8
|
|
8
8
|
|
9
9
|
require 'Win32API'
|
10
10
|
MAX_PATH = 260
|
11
|
-
GetModuleFileNameA = Win32API.new('kernel32', 'GetModuleFileNameA', 'PPL', 'L')
|
12
|
-
GetSystemDirectoryA = Win32API.new('kernel32', 'GetSystemDirectoryA', 'PL', 'L')
|
13
|
-
GetWindowsDirectoryA = Win32API.new('kernel32', 'GetWindowsDirectoryA', 'PL', 'L')
|
11
|
+
GetModuleFileNameA = Win32API.new('kernel32.dll', 'GetModuleFileNameA', 'PPL', 'L')
|
12
|
+
GetSystemDirectoryA = Win32API.new('kernel32.dll', 'GetSystemDirectoryA', 'PL', 'L')
|
13
|
+
GetWindowsDirectoryA = Win32API.new('kernel32.dll', 'GetWindowsDirectoryA', 'PL', 'L')
|
14
|
+
LoadLibraryExA = Win32API.new('kernel32.dll', 'LoadLibraryExA', 'PPL', 'P')
|
15
|
+
FreeLibrary = Win32API.new('kernel32.dll', 'FreeLibrary', 'P', 'L')
|
16
|
+
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020
|
14
17
|
|
15
18
|
def self.check_os_specific_load_error(exc)
|
16
19
|
case exc.message
|
17
|
-
when /^193: / # "
|
20
|
+
when /^OCI\.DLL: 193\(/, /^193: / # "OCI.DLL: 193(%1 is not a valid Win32 application.)" in English
|
18
21
|
check_win32_pe_arch(exc.message.split(' - ')[1], "ruby-oci8")
|
19
22
|
dll_load_path_list.each do |path|
|
20
23
|
check_win32_pe_arch(File.join(path, '\OCI.DLL'), "Oracle client")
|
21
24
|
end
|
25
|
+
when /^OCI.DLL: 126\(/, /^126: / # "OCI.DLL: 126(The specified module could not be found.)" in English
|
26
|
+
handle = LoadLibraryExA.call('OCI.DLL', nil, LOAD_LIBRARY_AS_IMAGE_RESOURCE)
|
27
|
+
unless handle.null?
|
28
|
+
FreeLibrary.call(handle)
|
29
|
+
raise LoadError, <<EOS
|
30
|
+
OCI.DLL is in the PATH but its dependent modules are not found.
|
31
|
+
See http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-instant-client.md#Windows
|
32
|
+
EOS
|
33
|
+
end
|
22
34
|
end
|
23
35
|
end # self.check_os_specific_load_error
|
24
36
|
|
data/lib/oci8/cursor.rb
CHANGED
@@ -125,7 +125,8 @@ class OCI8
|
|
125
125
|
case type
|
126
126
|
when :select_stmt
|
127
127
|
__execute(0)
|
128
|
-
define_columns()
|
128
|
+
define_columns() if @column_metadata.size == 0
|
129
|
+
@column_metadata.size
|
129
130
|
else
|
130
131
|
__execute(1)
|
131
132
|
row_count
|
@@ -526,9 +527,6 @@ class OCI8
|
|
526
527
|
def define_one_column(pos, param)
|
527
528
|
bindobj = make_bind_object(param)
|
528
529
|
__define(pos, bindobj)
|
529
|
-
if old = @define_handles[pos - 1]
|
530
|
-
old.send(:free)
|
531
|
-
end
|
532
530
|
@define_handles[pos - 1] = bindobj
|
533
531
|
end
|
534
532
|
|
data/lib/oci8/oci8.rb
CHANGED
@@ -113,7 +113,7 @@ class OCI8
|
|
113
113
|
if dbname.is_a? OCI8::ConnectionPool
|
114
114
|
@pool = dbname # to prevent GC from freeing the connection pool.
|
115
115
|
dbname = dbname.send(:pool_name)
|
116
|
-
attach_mode |= 0x0200 # OCI_CPOOL
|
116
|
+
attach_mode |= 0x0200 # OCI_CPOOL
|
117
117
|
else
|
118
118
|
tcp_connect_timeout = OCI8::properties[:tcp_connect_timeout]
|
119
119
|
connect_timeout = OCI8::properties[:connect_timeout]
|
@@ -124,32 +124,27 @@ class OCI8
|
|
124
124
|
end
|
125
125
|
if stmt_cache_size
|
126
126
|
# enable statement caching
|
127
|
-
attach_mode |= 0x0004 # OCI_STMT_CACHE
|
127
|
+
attach_mode |= 0x0004 # OCI_STMT_CACHE
|
128
128
|
end
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
self.recv_timeout = OCI8::properties[:recv_timeout] if OCI8::properties[:recv_timeout]
|
147
|
-
end
|
148
|
-
session_begin(cred ? cred : OCI_CRED_RDBMS, auth_mode)
|
149
|
-
else
|
150
|
-
# logon by the OCI function OCILogon2().
|
151
|
-
logon2(username, password, dbname, attach_mode)
|
130
|
+
# logon by the OCI function OCISessionBegin().
|
131
|
+
allocate_handles()
|
132
|
+
@session_handle.send(:attr_set_string, OCI_ATTR_USERNAME, username) if username
|
133
|
+
@session_handle.send(:attr_set_string, OCI_ATTR_PASSWORD, password) if password
|
134
|
+
if @@oracle_client_version >= ORAVER_11_1
|
135
|
+
# Sets the driver name displayed in V$SESSION_CONNECT_INFO.CLIENT_DRIVER
|
136
|
+
# if both the client and the server are Oracle 11g or upper.
|
137
|
+
# Only the first 8 chracters "ruby-oci" are displayed when the Oracle
|
138
|
+
# server version is lower than 12.0.1.2.
|
139
|
+
# 424: OCI_ATTR_DRIVER_NAME
|
140
|
+
@session_handle.send(:attr_set_string, 424, "ruby-oci8 : #{OCI8::VERSION}")
|
141
|
+
end
|
142
|
+
server_attach(dbname, attach_mode)
|
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]
|
152
146
|
end
|
147
|
+
session_begin(cred ? cred : OCI_CRED_RDBMS, auth_mode)
|
153
148
|
|
154
149
|
if stmt_cache_size
|
155
150
|
# set statement cache size
|
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
CHANGED
Binary file
|
data/lib/oci8lib_240.so
CHANGED
Binary file
|
@@ -0,0 +1,59 @@
|
|
1
|
+
create or replace package rb_test_pkg is
|
2
|
+
package_version pls_integer := 1;
|
3
|
+
|
4
|
+
type array_of_integer is array(50) of integer;
|
5
|
+
type table_of_pls_integer is table of pls_integer;
|
6
|
+
type table_of_boolean is table of boolean;
|
7
|
+
type indexed_table_of_varchar2 is table of varchar2(10) index by varchar2(5);
|
8
|
+
type rec1 is record (i pls_integer, j integer);
|
9
|
+
type rec2 is record (b boolean, it indexed_table_of_varchar2, rec rec1);
|
10
|
+
type table_of_rec1 is table of rec1;
|
11
|
+
type table_of_rec2 is table of rec2;
|
12
|
+
|
13
|
+
function sum_table_of_pls_integer(tbl in table_of_pls_integer) return pls_integer;
|
14
|
+
function add_rec1_values(tbl in table_of_rec1) return pls_integer;
|
15
|
+
procedure out_rec1_values(tbl out table_of_rec1);
|
16
|
+
end;
|
17
|
+
/
|
18
|
+
create or replace package body rb_test_pkg is
|
19
|
+
function sum_table_of_pls_integer(tbl in table_of_pls_integer) return pls_integer is
|
20
|
+
i pls_integer;
|
21
|
+
ret pls_integer := 0;
|
22
|
+
begin
|
23
|
+
for i in tbl.first..tbl.last loop
|
24
|
+
ret := ret + tbl(i);
|
25
|
+
end loop;
|
26
|
+
return ret;
|
27
|
+
end;
|
28
|
+
|
29
|
+
function add_rec1_values(tbl in table_of_rec1) return pls_integer is
|
30
|
+
i pls_integer;
|
31
|
+
ret pls_integer := 0;
|
32
|
+
begin
|
33
|
+
for i in tbl.first..tbl.last loop
|
34
|
+
ret := ret + nvl(tbl(i).i, 0) + nvl(tbl(i).j, 0);
|
35
|
+
end loop;
|
36
|
+
return ret;
|
37
|
+
end;
|
38
|
+
|
39
|
+
procedure out_rec1_values(tbl out table_of_rec1) is
|
40
|
+
i pls_integer;
|
41
|
+
rec1val rec1;
|
42
|
+
begin
|
43
|
+
tbl := table_of_rec1();
|
44
|
+
for i in 1..20 loop
|
45
|
+
tbl.extend;
|
46
|
+
if i mod 6 != 0 then
|
47
|
+
if i mod 3 != 0 then
|
48
|
+
rec1val.i := i;
|
49
|
+
rec1val.j := i;
|
50
|
+
else
|
51
|
+
rec1val.i := null;
|
52
|
+
rec1val.j := null;
|
53
|
+
end if;
|
54
|
+
tbl(i) := rec1val;
|
55
|
+
end if;
|
56
|
+
end loop;
|
57
|
+
end;
|
58
|
+
end;
|
59
|
+
/
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Low-level API
|
2
|
+
require 'oci8'
|
3
|
+
require File.dirname(__FILE__) + '/config'
|
4
|
+
|
5
|
+
class TestBindBoolean < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@conn = get_oci8_connection()
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_set_raw
|
11
|
+
stmt = <<EOS
|
12
|
+
DECLARE
|
13
|
+
bool_val boolean;
|
14
|
+
int_val pls_integer;
|
15
|
+
BEGIN
|
16
|
+
bool_val := :in;
|
17
|
+
IF bool_val THEN
|
18
|
+
int_val := 1;
|
19
|
+
ELSE
|
20
|
+
int_val := 0;
|
21
|
+
END IF;
|
22
|
+
:out := int_val;
|
23
|
+
END;
|
24
|
+
EOS
|
25
|
+
# explicit bind
|
26
|
+
cursor = @conn.parse(stmt)
|
27
|
+
cursor.bind_param(:in, nil, TrueClass)
|
28
|
+
cursor.bind_param(:out, nil, Integer)
|
29
|
+
|
30
|
+
cursor[:in] = true
|
31
|
+
cursor.exec
|
32
|
+
assert_equal(1, cursor[:out])
|
33
|
+
|
34
|
+
cursor[:in] = false
|
35
|
+
cursor.exec
|
36
|
+
assert_equal(0, cursor[:out])
|
37
|
+
|
38
|
+
# implicit bind
|
39
|
+
do_block_cnt = 0
|
40
|
+
@conn.exec(stmt, true, 0) do |in_val, out_val|
|
41
|
+
assert_equal(true, in_val)
|
42
|
+
assert_equal(1, out_val)
|
43
|
+
do_block_cnt += 1
|
44
|
+
end
|
45
|
+
|
46
|
+
@conn.exec(stmt, false, 0) do |in_val, out_val|
|
47
|
+
assert_equal(false, in_val)
|
48
|
+
assert_equal(0, out_val)
|
49
|
+
do_block_cnt += 1
|
50
|
+
end
|
51
|
+
assert_equal(2, do_block_cnt)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_get_raw
|
55
|
+
stmt = <<EOS
|
56
|
+
DECLARE
|
57
|
+
int_val pls_integer;
|
58
|
+
bool_val boolean;
|
59
|
+
BEGIN
|
60
|
+
int_val := :in;
|
61
|
+
IF int_val <> 0 THEN
|
62
|
+
bool_val := TRUE;
|
63
|
+
ELSE
|
64
|
+
bool_val := FALSE;
|
65
|
+
END IF;
|
66
|
+
:out := bool_val;
|
67
|
+
END;
|
68
|
+
EOS
|
69
|
+
cursor = @conn.parse(stmt)
|
70
|
+
cursor.bind_param(:in, nil, Integer)
|
71
|
+
cursor.bind_param(:out, nil, TrueClass)
|
72
|
+
|
73
|
+
cursor[:in] = 1
|
74
|
+
cursor.exec
|
75
|
+
assert_equal(true, cursor[:out])
|
76
|
+
|
77
|
+
cursor[:in] = 0
|
78
|
+
cursor.exec
|
79
|
+
assert_equal(false, cursor[:out])
|
80
|
+
|
81
|
+
do_block_cnt = 0
|
82
|
+
@conn.exec(stmt, 1, true) do |in_val, out_val|
|
83
|
+
assert_equal(1, in_val)
|
84
|
+
assert_equal(true, out_val)
|
85
|
+
do_block_cnt += 1
|
86
|
+
end
|
87
|
+
|
88
|
+
@conn.exec(stmt, 0, true) do |in_val, out_val|
|
89
|
+
assert_equal(0, in_val)
|
90
|
+
assert_equal(false, out_val)
|
91
|
+
do_block_cnt += 1
|
92
|
+
end
|
93
|
+
assert_equal(2, do_block_cnt)
|
94
|
+
end
|
95
|
+
|
96
|
+
def teardown
|
97
|
+
@conn.logoff
|
98
|
+
end
|
99
|
+
end
|
data/test/test_oranumber.rb
CHANGED
@@ -738,9 +738,9 @@ EOS
|
|
738
738
|
LARGE_RANGE_VALUES
|
739
739
|
end
|
740
740
|
|
741
|
-
def
|
742
|
-
assert_equal(false, OraNumber(10.0).
|
743
|
-
assert_equal(true, OraNumber(10.1).
|
741
|
+
def test_has_fractional_part
|
742
|
+
assert_equal(false, OraNumber(10.0).has_fractional_part?)
|
743
|
+
assert_equal(true, OraNumber(10.1).has_fractional_part?)
|
744
744
|
end
|
745
745
|
|
746
746
|
def test_float_conversion_type_ruby
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-oci8
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
|
11
|
-
version: 2.2.4.1
|
9
|
+
- 5
|
10
|
+
version: 2.2.5
|
12
11
|
platform: x86-mingw32
|
13
12
|
authors:
|
14
13
|
- Kubo Takehiro
|
@@ -16,7 +15,7 @@ autorequire:
|
|
16
15
|
bindir: bin
|
17
16
|
cert_chain: []
|
18
17
|
|
19
|
-
date: 2017-
|
18
|
+
date: 2017-10-21 00:00:00 +09:00
|
20
19
|
default_executable:
|
21
20
|
dependencies: []
|
22
21
|
|
@@ -44,12 +43,14 @@ files:
|
|
44
43
|
- ruby-oci8.gemspec
|
45
44
|
- setup.rb
|
46
45
|
- docs/bind-array-to-in_cond.md
|
46
|
+
- docs/conflicts-local-connections-and-processes.md
|
47
|
+
- docs/hanging-after-inactivity.md
|
47
48
|
- docs/install-binary-package.md
|
48
49
|
- docs/install-full-client.md
|
49
50
|
- docs/install-instant-client.md
|
50
51
|
- docs/install-on-osx.md
|
51
|
-
- docs/
|
52
|
-
- docs/
|
52
|
+
- docs/ldap-auth-and-function-interposition.md
|
53
|
+
- docs/number-type-mapping.md
|
53
54
|
- docs/osx-install-dev-tools.png
|
54
55
|
- docs/platform-specific-issues.md
|
55
56
|
- docs/report-installation-issue.md
|
@@ -77,10 +78,12 @@ files:
|
|
77
78
|
- test/README
|
78
79
|
- test/config.rb
|
79
80
|
- test/setup_test_object.sql
|
81
|
+
- test/setup_test_package.sql
|
80
82
|
- test/test_all.rb
|
81
83
|
- test/test_appinfo.rb
|
82
84
|
- test/test_array_dml.rb
|
83
85
|
- test/test_bind_array.rb
|
86
|
+
- test/test_bind_boolean.rb
|
84
87
|
- test/test_bind_raw.rb
|
85
88
|
- test/test_bind_string.rb
|
86
89
|
- test/test_bind_time.rb
|
@@ -103,11 +106,11 @@ files:
|
|
103
106
|
- test/test_package_type.rb
|
104
107
|
- test/test_rowid.rb
|
105
108
|
- lib/oci8lib_191.so
|
106
|
-
- lib/oci8lib_210.so
|
107
109
|
- lib/oci8lib_200.so
|
108
|
-
- lib/
|
109
|
-
- lib/oci8lib_230.so
|
110
|
+
- lib/oci8lib_210.so
|
110
111
|
- lib/oci8lib_220.so
|
112
|
+
- lib/oci8lib_230.so
|
113
|
+
- lib/oci8lib_240.so
|
111
114
|
has_rdoc: true
|
112
115
|
homepage: http://www.rubydoc.info/github/kubo/ruby-oci8
|
113
116
|
licenses:
|