ruby-oci8 2.2.4.1-x86-mingw32 → 2.2.5-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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/version.rb: Fix URL links
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
- Connect to scott/tiger, select `emp` and print as CSV format.
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/conflicts-local-connections-and-processes.md
19
- docs/hanging-after-inactivity.md
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
@@ -49,7 +49,7 @@ class OCI8
49
49
 
50
50
  class BasicNumberType < OCI8::BindType::OraNumber
51
51
  def get()
52
- (val = super()) && (val.has_decimal_part? ? val.to_f : val.to_i)
52
+ (val = super()) && (val.has_fractional_part? ? val.to_f : val.to_i)
53
53
  end
54
54
  end
55
55
 
@@ -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: / # "193: %1 is not a valid Win32 application." in English
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 and OCI_LOGON2_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 and OCI_LOGON2_STMTCACHE
127
+ attach_mode |= 0x0004 # OCI_STMT_CACHE
128
128
  end
129
129
 
130
- if true
131
- # logon by the OCI function OCISessionBegin().
132
- allocate_handles()
133
- @session_handle.send(:attr_set_string, OCI_ATTR_USERNAME, username) if username
134
- @session_handle.send(:attr_set_string, OCI_ATTR_PASSWORD, password) if password
135
- if @@oracle_client_version >= ORAVER_11_1
136
- # Sets the driver name displayed in V$SESSION_CONNECT_INFO.CLIENT_DRIVER
137
- # if both the client and the server are Oracle 11g or upper.
138
- # Only the first 8 chracters "ruby-oci" are displayed when the Oracle
139
- # server version is lower than 12.0.1.2.
140
- # 424: OCI_ATTR_DRIVER_NAME
141
- @session_handle.send(:attr_set_string, 424, "ruby-oci8 : #{OCI8::VERSION}")
142
- end
143
- server_attach(dbname, attach_mode)
144
- if OCI8.oracle_client_version >= OCI8::ORAVER_11_1
145
- self.send_timeout = OCI8::properties[:send_timeout] if OCI8::properties[:send_timeout]
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
@@ -1,3 +1,3 @@
1
1
  class OCI8
2
- VERSION = "2.2.4.1"
2
+ VERSION = "2.2.5"
3
3
  end
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
@@ -738,9 +738,9 @@ EOS
738
738
  LARGE_RANGE_VALUES
739
739
  end
740
740
 
741
- def test_has_decimal_part
742
- assert_equal(false, OraNumber(10.0).has_decimal_part?)
743
- assert_equal(true, OraNumber(10.1).has_decimal_part?)
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: 109
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 4
10
- - 1
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-06-17 00:00:00 +09:00
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/conflicts-local-connections-and-processes.md
52
- - docs/hanging-after-inactivity.md
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/oci8lib_240.so
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: