ruby-oci8 2.2.4.1 → 2.2.5
Sign up to get free protection for your applications and to get access to all the features.
- 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/ext/oci8/apiwrap.yml +0 -22
- data/ext/oci8/error.c +18 -33
- data/ext/oci8/oci8.c +0 -99
- data/ext/oci8/oci8lib.c +38 -30
- data/ext/oci8/ocinumber.c +11 -7
- data/ext/oci8/plthook_elf.c +384 -300
- 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/test/setup_test_package.sql +59 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_oranumber.rb +3 -3
- metadata +9 -6
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
@@ -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
@@ -5,9 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 2.2.4.1
|
8
|
+
- 5
|
9
|
+
version: 2.2.5
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Kubo Takehiro
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2017-
|
17
|
+
date: 2017-10-21 00:00:00 +09:00
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|
@@ -43,12 +42,14 @@ files:
|
|
43
42
|
- ruby-oci8.gemspec
|
44
43
|
- setup.rb
|
45
44
|
- docs/bind-array-to-in_cond.md
|
45
|
+
- docs/conflicts-local-connections-and-processes.md
|
46
|
+
- docs/hanging-after-inactivity.md
|
46
47
|
- docs/install-binary-package.md
|
47
48
|
- docs/install-full-client.md
|
48
49
|
- docs/install-instant-client.md
|
49
50
|
- docs/install-on-osx.md
|
50
|
-
- docs/
|
51
|
-
- docs/
|
51
|
+
- docs/ldap-auth-and-function-interposition.md
|
52
|
+
- docs/number-type-mapping.md
|
52
53
|
- docs/osx-install-dev-tools.png
|
53
54
|
- docs/platform-specific-issues.md
|
54
55
|
- docs/report-installation-issue.md
|
@@ -113,10 +114,12 @@ files:
|
|
113
114
|
- test/README
|
114
115
|
- test/config.rb
|
115
116
|
- test/setup_test_object.sql
|
117
|
+
- test/setup_test_package.sql
|
116
118
|
- test/test_all.rb
|
117
119
|
- test/test_appinfo.rb
|
118
120
|
- test/test_array_dml.rb
|
119
121
|
- test/test_bind_array.rb
|
122
|
+
- test/test_bind_boolean.rb
|
120
123
|
- test/test_bind_raw.rb
|
121
124
|
- test/test_bind_string.rb
|
122
125
|
- test/test_bind_time.rb
|