ruby-oci8 2.2.4.1 → 2.2.11
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.
- checksums.yaml +7 -0
- data/ChangeLog +311 -1
- data/NEWS +278 -46
- data/README.md +5 -2
- data/dist-files +8 -4
- data/docs/bind-array-to-in_cond.md +1 -1
- data/docs/install-instant-client.md +2 -1
- data/docs/install-on-osx.md +29 -116
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +34 -22
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +366 -6
- data/ext/oci8/connection_pool.c +3 -3
- data/ext/oci8/error.c +18 -33
- data/ext/oci8/extconf.rb +7 -4
- data/ext/oci8/hook_funcs.c +128 -51
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +2 -2
- data/ext/oci8/object.c +72 -27
- data/ext/oci8/oci8.c +27 -119
- data/ext/oci8/oci8.h +21 -3
- data/ext/oci8/oci8lib.c +50 -37
- data/ext/oci8/ocihandle.c +2 -2
- data/ext/oci8/ocinumber.c +22 -16
- data/ext/oci8/oraconf.rb +130 -257
- data/ext/oci8/oradate.c +1 -1
- data/ext/oci8/plthook_elf.c +384 -300
- data/ext/oci8/plthook_osx.c +10 -10
- data/ext/oci8/stmt.c +51 -16
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +1 -15
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/cursor.rb +48 -17
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +10 -0
- data/lib/oci8/oci8.rb +26 -25
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +11 -4
- data/lib/ruby-oci8.rb +0 -3
- data/ruby-oci8.gemspec +2 -3
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +1 -1
- data/test/setup_test_object.sql +21 -13
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +1 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_break.rb +11 -9
- data/test/test_clob.rb +4 -16
- data/test/test_datetime.rb +8 -3
- data/test/test_object.rb +33 -9
- data/test/test_oci8.rb +169 -45
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +15 -3
- data/test/test_properties.rb +17 -0
- metadata +40 -57
- data/docs/osx-install-dev-tools.png +0 -0
- data/test/README +0 -42
data/lib/oci8/oracle_version.rb
CHANGED
@@ -66,6 +66,12 @@ class OCI8
|
|
66
66
|
major, minor, update, patch, port_update = arg.split('.').collect do |v|
|
67
67
|
v.to_i
|
68
68
|
end
|
69
|
+
elsif arg >= 0x12000000
|
70
|
+
major = (arg & 0xFF000000) >> 24
|
71
|
+
minor = (arg & 0x00FF0000) >> 16
|
72
|
+
update = (arg & 0x0000F000) >> 12
|
73
|
+
patch = (arg & 0x00000FF0) >> 4
|
74
|
+
port_update = (arg & 0x0000000F)
|
69
75
|
elsif arg >= 0x08000000
|
70
76
|
major = (arg & 0xFF000000) >> 24
|
71
77
|
minor = (arg & 0x00F00000) >> 20
|
@@ -80,7 +86,11 @@ class OCI8
|
|
80
86
|
@update = update || 0
|
81
87
|
@patch = patch || 0
|
82
88
|
@port_update = port_update || 0
|
83
|
-
@vernum =
|
89
|
+
@vernum = if @major >= 18
|
90
|
+
(@major << 24) | (@minor << 16) | (@update << 12) | (@patch << 4) | @port_update
|
91
|
+
else
|
92
|
+
(@major << 24) | (@minor << 20) | (@update << 12) | (@patch << 8) | @port_update
|
93
|
+
end
|
84
94
|
end
|
85
95
|
|
86
96
|
# Compares +self+ and +other+.
|
data/lib/oci8/version.rb
CHANGED
data/lib/oci8.rb
CHANGED
@@ -11,8 +11,11 @@ if RUBY_PLATFORM =~ /cygwin/
|
|
11
11
|
# Cygwin manages environment variables by itself.
|
12
12
|
# They don't synchroize with Win32's ones.
|
13
13
|
# This set some Oracle's environment variables to win32's enviroment.
|
14
|
-
require '
|
15
|
-
win32setenv =
|
14
|
+
require 'fiddle'
|
15
|
+
win32setenv = Fiddle::Function.new( Fiddle.dlopen('Kernel32.dll')['SetEnvironmentVariableA'],
|
16
|
+
[Fiddle::TYPE_VOIDP,Fiddle::TYPE_VOIDP],
|
17
|
+
Fiddle::TYPE_INT )
|
18
|
+
|
16
19
|
['NLS_LANG', 'TNS_ADMIN', 'LOCAL'].each do |name|
|
17
20
|
val = ENV[name]
|
18
21
|
win32setenv.call(name, val && val.dup)
|
@@ -63,6 +66,8 @@ when 'rbx'
|
|
63
66
|
so_basename += 'rbx'
|
64
67
|
when 'jruby'
|
65
68
|
raise "Ruby-oci8 doesn't support jruby because its C extension support is in development in jruby 1.6 and deprecated in jruby 1.7."
|
69
|
+
when 'truffleruby'
|
70
|
+
so_basename += 'truffleruby'
|
66
71
|
else
|
67
72
|
raise 'unsupported ruby engine: ' + RUBY_ENGINE
|
68
73
|
end
|
@@ -95,7 +100,7 @@ begin
|
|
95
100
|
|
96
101
|
ruby_arch = [nil].pack('P').size == 8 ? :x64 : :x86
|
97
102
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
98
|
-
if dll_arch.call(File.join(path, 'OCI.DLL')) == ruby_arch
|
103
|
+
if !path.empty? && dll_arch.call(File.join(path, 'OCI.DLL')) == ruby_arch
|
99
104
|
dll_dir = RubyInstaller::Runtime.add_dll_directory(path)
|
100
105
|
break
|
101
106
|
end
|
@@ -105,7 +110,7 @@ end
|
|
105
110
|
|
106
111
|
begin
|
107
112
|
require so_basename
|
108
|
-
rescue LoadError
|
113
|
+
rescue LoadError
|
109
114
|
require 'oci8/check_load_error'
|
110
115
|
OCI8::Util::check_load_error($!)
|
111
116
|
raise
|
@@ -140,6 +145,8 @@ class OCI8
|
|
140
145
|
ORAVER_11_1 = OCI8::OracleVersion.new(11, 1)
|
141
146
|
# @private
|
142
147
|
ORAVER_12_1 = OCI8::OracleVersion.new(12, 1)
|
148
|
+
# @private
|
149
|
+
ORAVER_18 = OCI8::OracleVersion.new(18)
|
143
150
|
|
144
151
|
# @private
|
145
152
|
@@oracle_client_version = OCI8::OracleVersion.new(self.oracle_client_vernum)
|
data/lib/ruby-oci8.rb
CHANGED
data/ruby-oci8.gemspec
CHANGED
@@ -34,7 +34,6 @@ spec = Gem::Specification.new do |s|
|
|
34
34
|
s.description = <<EOS
|
35
35
|
ruby-oci8 is a ruby interface for Oracle using OCI8 API. It is available with Oracle 10g or later including Oracle Instant Client.
|
36
36
|
EOS
|
37
|
-
s.has_rdoc = 'yard'
|
38
37
|
s.authors = ['Kubo Takehiro']
|
39
38
|
s.platform = gem_platform
|
40
39
|
s.license = 'BSD-2-Clause'
|
@@ -51,7 +50,7 @@ EOS
|
|
51
50
|
# add map files to analyze a core (minidump) file.
|
52
51
|
so_vers.each do |ver|
|
53
52
|
map_file = 'ext/oci8/oci8lib_#{ver}.map'
|
54
|
-
so_files << map_file if File.
|
53
|
+
so_files << map_file if File.exist? map_file
|
55
54
|
end
|
56
55
|
|
57
56
|
# least version in so_vers
|
@@ -79,7 +78,7 @@ EOS
|
|
79
78
|
end
|
80
79
|
files << 'lib/oci8.rb'
|
81
80
|
end
|
82
|
-
s.require_paths = ['lib'
|
81
|
+
s.require_paths = ['lib']
|
83
82
|
s.files = files
|
84
83
|
s.test_files = 'test/test_all.rb'
|
85
84
|
s.extra_rdoc_files = ['README.md']
|
data/setup.rb
CHANGED
@@ -189,7 +189,16 @@ class ConfigTable
|
|
189
189
|
'the make program to compile ruby extentions' ] ],
|
190
190
|
[ 'without-ext', [ 'no',
|
191
191
|
'yes/no',
|
192
|
-
'does not compile/install ruby extentions' ] ]
|
192
|
+
'does not compile/install ruby extentions' ] ],
|
193
|
+
[ 'with-instant-client-dir', ['',
|
194
|
+
'path',
|
195
|
+
'path to the Oracle instant client directory'] ],
|
196
|
+
[ 'with-instant-client-lib', ['',
|
197
|
+
'path',
|
198
|
+
'path to the Oracle instant client libraries'] ],
|
199
|
+
[ 'with-instant-client-include', ['',
|
200
|
+
'path',
|
201
|
+
'path to the Oracle instant client header files'] ]
|
193
202
|
]
|
194
203
|
multipackage_descripters = [
|
195
204
|
[ 'with', [ '',
|
@@ -277,7 +286,7 @@ class ConfigTable
|
|
277
286
|
|
278
287
|
def initialize_from_table
|
279
288
|
@table = {}
|
280
|
-
DESCRIPTER.each do |k, (default,
|
289
|
+
DESCRIPTER.each do |k, (default, *)|
|
281
290
|
@table[k] = default
|
282
291
|
end
|
283
292
|
end
|
data/test/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
Before running unit test:
|
2
|
+
|
3
|
+
1. Connect to Oracle as sys
|
4
|
+
```shell
|
5
|
+
$ sqlplus sys/<password_of_sys> as sysdba
|
6
|
+
SQL>
|
7
|
+
```
|
8
|
+
2. Create user ruby
|
9
|
+
```sql
|
10
|
+
SQL> CREATE USER ruby IDENTIFIED BY oci8 DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
|
11
|
+
SQL> alter user ruby quota unlimited on users;
|
12
|
+
```
|
13
|
+
3. Grant the privilege to connect and execute.
|
14
|
+
```sql
|
15
|
+
SQL> GRANT connect, resource, create view, create synonym TO ruby;
|
16
|
+
SQL> GRANT execute ON dbms_lock TO ruby;
|
17
|
+
```
|
18
|
+
4. Connect as ruby user.
|
19
|
+
```shell
|
20
|
+
$ sqlplus ruby/oci8
|
21
|
+
SQL>
|
22
|
+
```
|
23
|
+
5. Create object types
|
24
|
+
```sql
|
25
|
+
SQL> @test/setup_test_object.sql
|
26
|
+
SQL> @test/setup_test_package.sql
|
27
|
+
```
|
28
|
+
6. change $dbname in test/config.rb.
|
29
|
+
|
30
|
+
Then run the following command:
|
31
|
+
```shell
|
32
|
+
$ make check
|
33
|
+
```
|
34
|
+
or
|
35
|
+
```
|
36
|
+
$ nmake check (If your compiler is MS Visual C++.)
|
37
|
+
````
|
data/test/config.rb
CHANGED
@@ -134,7 +134,7 @@ class Minitest::Test
|
|
134
134
|
|
135
135
|
def get_oci8_connection()
|
136
136
|
OCI8.new($dbuser, $dbpass, $dbname)
|
137
|
-
|
137
|
+
rescue OCIError
|
138
138
|
raise if $!.code != 12516 && $!.code != 12520
|
139
139
|
# sleep a few second and try again if
|
140
140
|
# the error code is ORA-12516 or ORA-12520.
|
data/test/setup_test_object.sql
CHANGED
@@ -61,6 +61,8 @@ create type rb_test_obj as object (
|
|
61
61
|
obj_array_val rb_test_obj_elem_array,
|
62
62
|
obj_ary_of_ary_val rb_test_obj_elem_ary_of_ary,
|
63
63
|
date_val date,
|
64
|
+
timestamp_val timestamp(9),
|
65
|
+
timestamp_tz_val timestamp(9) with time zone,
|
64
66
|
-- date_array_val rb_test_date_array,
|
65
67
|
|
66
68
|
constructor function rb_test_obj(n number) return self as result,
|
@@ -72,19 +74,23 @@ create type rb_test_obj as object (
|
|
72
74
|
member procedure member_proc(n in integer)
|
73
75
|
)
|
74
76
|
/
|
75
|
-
create
|
76
|
-
|
77
|
+
create type body rb_test_obj is
|
77
78
|
constructor function rb_test_obj(n number) return self as result is
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
to_char(mod(round(n) * 5, 12) + 1, 'FM00') ||
|
82
|
-
to_char(mod(round(n) * 7, 27) + 1, 'FM00') ||
|
83
|
-
to_char(mod(round(n) * 9, 24), 'FM00') ||
|
84
|
-
to_char(mod(round(n) * 11, 60), 'FM00') ||
|
85
|
-
to_char(mod(round(n) * 13, 60), 'FM00'), 'yyyymmddhh24miss');
|
86
|
-
end;
|
79
|
+
str varchar(28);
|
80
|
+
ts timestamp(9);
|
81
|
+
ts_tz timestamp(9) with time zone;
|
87
82
|
begin
|
83
|
+
str := to_char(1990 + n, 'FM0000') ||
|
84
|
+
to_char(mod(round(n) * 5, 12) + 1, 'FM00') ||
|
85
|
+
to_char(mod(round(n) * 7, 27) + 1, 'FM00') ||
|
86
|
+
to_char(mod(round(n) * 9, 24), 'FM00') ||
|
87
|
+
to_char(mod(round(n) * 11, 60), 'FM00') ||
|
88
|
+
to_char(mod(round(n) * 13, 60), 'FM00') ||
|
89
|
+
to_char(mod(round(n) * 333333333, 1000000000), 'FM000000000');
|
90
|
+
ts := to_timestamp(str, 'yyyymmddhh24missff9');
|
91
|
+
str := str || to_char(mod(round(n) * 15, 24) - 11, 'FMS00') ||
|
92
|
+
to_char(mod(round(n) * 17, 60), 'FM00');
|
93
|
+
ts_tz := to_timestamp_tz(str, 'yyyymmddhh24missff9tzhtzm');
|
88
94
|
self.int_val := n;
|
89
95
|
self.flt_val := n;
|
90
96
|
self.num_val := n;
|
@@ -96,7 +102,9 @@ create or replace type body rb_test_obj is
|
|
96
102
|
self.nclob_val := to_clob(n);
|
97
103
|
self.blob_val := to_blob(utl_raw.cast_to_raw(to_char(n)));
|
98
104
|
self.obj_val := rb_test_obj_elem(n, n + 1);
|
99
|
-
self.date_val :=
|
105
|
+
self.date_val := ts;
|
106
|
+
self.timestamp_val := ts;
|
107
|
+
self.timestamp_tz_val := ts_tz;
|
100
108
|
if self.int_val != 1 then
|
101
109
|
self.int_array_val := rb_test_int_array(n, n + 1, n + 2);
|
102
110
|
self.flt_array_val := rb_test_flt_array(n, n + 1, n + 2);
|
@@ -120,7 +128,7 @@ create or replace type body rb_test_obj is
|
|
120
128
|
|
121
129
|
static function test_object_version return integer is
|
122
130
|
begin
|
123
|
-
return
|
131
|
+
return 4;
|
124
132
|
end;
|
125
133
|
|
126
134
|
static function class_func(n number) return rb_test_obj is
|
@@ -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
|
+
/
|
data/test/test_all.rb
CHANGED
@@ -26,6 +26,7 @@ require "#{srcdir}/test_oracle_version"
|
|
26
26
|
require "#{srcdir}/test_error"
|
27
27
|
require "#{srcdir}/test_connection_pool"
|
28
28
|
require "#{srcdir}/test_object"
|
29
|
+
require "#{srcdir}/test_properties.rb"
|
29
30
|
|
30
31
|
if OCI8.respond_to? :encoding
|
31
32
|
require "#{srcdir}/test_encoding"
|
@@ -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_break.rb
CHANGED
@@ -7,10 +7,12 @@ class TestBreak < Minitest::Test
|
|
7
7
|
|
8
8
|
def setup
|
9
9
|
@conn = get_oci8_connection
|
10
|
+
Thread.report_on_exception, @original_report_on_exception = false, Thread.report_on_exception if Thread.respond_to?(:report_on_exception)
|
10
11
|
end
|
11
12
|
|
12
13
|
def teardown
|
13
14
|
@conn.logoff
|
15
|
+
Thread.report_on_exception = @original_report_on_exception if Thread.respond_to?(:report_on_exception)
|
14
16
|
end
|
15
17
|
|
16
18
|
def report(str)
|
@@ -20,9 +22,8 @@ class TestBreak < Minitest::Test
|
|
20
22
|
@@server_is_runing_on_windows = nil
|
21
23
|
def server_is_runing_on_windows?
|
22
24
|
if @@server_is_runing_on_windows.nil?
|
23
|
-
|
24
|
-
|
25
|
-
@@server_is_runing_on_windows = true if row[0].include? 'Windows'
|
25
|
+
@conn.exec('select dbms_utility.port_string from dual') do |row|
|
26
|
+
@@server_is_runing_on_windows = row[0].include? '/WIN'
|
26
27
|
end
|
27
28
|
end
|
28
29
|
@@server_is_runing_on_windows
|
@@ -61,7 +62,7 @@ class TestBreak < Minitest::Test
|
|
61
62
|
expect = []
|
62
63
|
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
63
64
|
expect[OCIBREAK] = "Invalid status"
|
64
|
-
if defined? Rubinius and Rubinius::VERSION >= "2.0"
|
65
|
+
if (defined? Rubinius and Rubinius::VERSION >= "2.0") || (defined? RUBY_ENGINE and RUBY_ENGINE == "truffleruby")
|
65
66
|
# Rubinius 2.0.0.
|
66
67
|
# DBMS_LOCK.SLEEP blocks ruby threads which try to call C-API.
|
67
68
|
expect[SEND_BREAK] = TIME_TO_BREAK
|
@@ -98,6 +99,11 @@ class TestBreak < Minitest::Test
|
|
98
99
|
def test_timeout
|
99
100
|
@conn.non_blocking = true
|
100
101
|
start_time = Time.now
|
102
|
+
if server_is_runing_on_windows?
|
103
|
+
end_time = start_time + 5
|
104
|
+
else
|
105
|
+
end_time = start_time + 1
|
106
|
+
end
|
101
107
|
|
102
108
|
if defined? Rubinius and Rubinius::VERSION < "2.0"
|
103
109
|
# Rubinius 1.2.4
|
@@ -111,12 +117,8 @@ class TestBreak < Minitest::Test
|
|
111
117
|
@conn.exec("BEGIN DBMS_LOCK.SLEEP(5); END;")
|
112
118
|
end
|
113
119
|
end
|
114
|
-
if server_is_runing_on_windows?
|
115
|
-
end_time = start_time + 5
|
116
|
-
else
|
117
|
-
end_time = start_time + 1
|
118
|
-
end
|
119
120
|
assert_in_delta(Time.now, end_time, 1)
|
121
|
+
sleep(0.01) # for truffleruby. Is truffleruby too fast?
|
120
122
|
@conn.exec("BEGIN NULL; END;")
|
121
123
|
assert_in_delta(Time.now, end_time, 1)
|
122
124
|
end
|
data/test/test_clob.rb
CHANGED
@@ -24,22 +24,6 @@ class TestCLob < Minitest::Test
|
|
24
24
|
lob.close
|
25
25
|
end
|
26
26
|
|
27
|
-
def test_insert_with_flush
|
28
|
-
filename = File.basename($lobfile)
|
29
|
-
@conn.exec("DELETE FROM test_table WHERE filename = :1", filename)
|
30
|
-
@conn.exec("INSERT INTO test_table(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
31
|
-
cursor = @conn.exec("SELECT content FROM test_table WHERE filename = :1 FOR UPDATE", filename)
|
32
|
-
lob = cursor.fetch[0]
|
33
|
-
lob.sync = false
|
34
|
-
open($lobfile) do |f|
|
35
|
-
while s = f.read(1000)
|
36
|
-
lob.write(s)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
lob.flush
|
40
|
-
lob.close
|
41
|
-
end
|
42
|
-
|
43
27
|
def test_insert_symbol
|
44
28
|
filename = 'test_symbol'
|
45
29
|
value = :foo_bar
|
@@ -76,7 +60,11 @@ class TestCLob < Minitest::Test
|
|
76
60
|
|
77
61
|
# https://github.com/kubo/ruby-oci8/issues/20
|
78
62
|
def test_github_issue_20
|
63
|
+
# Skip this test if FULLTEST isn't set because it takes 4 minutes in my Linux box.
|
64
|
+
return if ENV['FULLTEST']
|
65
|
+
|
79
66
|
lob1 = OCI8::CLOB.new(@conn, ' ' * (1024 * 1024))
|
67
|
+
lob1.read(1) # to suppress `warning: assigned but unused variable - lob1`
|
80
68
|
begin
|
81
69
|
lob2 = OCI8::CLOB.new(@conn, ' ' * (128 * 1024 * 1024))
|
82
70
|
rescue OCIError
|
data/test/test_datetime.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'oci8'
|
2
2
|
require File.dirname(__FILE__) + '/config'
|
3
|
-
require 'scanf'
|
4
3
|
|
5
4
|
class TestDateTime < Minitest::Test
|
6
5
|
|
@@ -28,6 +27,12 @@ class TestDateTime < Minitest::Test
|
|
28
27
|
convert_to_datetime($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, subsec, $8)
|
29
28
|
end
|
30
29
|
|
30
|
+
# 'YYYY-MM-DD HH24:MI:SS' or 'YYYY-MM-DD HH24:MI:SS.FF6' to array
|
31
|
+
def string_to_array(str)
|
32
|
+
/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(?:\.(\d+))?/ =~ str
|
33
|
+
[$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, $7 ? $7.to_i / 1000 : 0]
|
34
|
+
end
|
35
|
+
|
31
36
|
def setup
|
32
37
|
@conn = get_oci8_connection
|
33
38
|
end
|
@@ -43,7 +48,7 @@ class TestDateTime < Minitest::Test
|
|
43
48
|
@conn.exec(<<-EOS) do |row|
|
44
49
|
SELECT TO_DATE('#{date}', 'YYYY-MM-DD HH24:MI:SS') FROM dual
|
45
50
|
EOS
|
46
|
-
assert_equal(Time.local(*date
|
51
|
+
assert_equal(Time.local(*string_to_array(date)), row[0])
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
@@ -94,7 +99,7 @@ EOS
|
|
94
99
|
@conn.exec(<<-EOS) do |row|
|
95
100
|
SELECT TO_TIMESTAMP('#{date}', 'YYYY-MM-DD HH24:MI:SS.FF') FROM dual
|
96
101
|
EOS
|
97
|
-
assert_equal(Time.local(*date
|
102
|
+
assert_equal(Time.local(*string_to_array(date)), row[0])
|
98
103
|
end
|
99
104
|
end
|
100
105
|
end
|
data/test/test_object.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'oci8'
|
2
2
|
require File.dirname(__FILE__) + '/config'
|
3
3
|
|
4
|
+
class Time
|
5
|
+
def inspect
|
6
|
+
self.strftime("%Y-%m-%d %H:%M:%S.%N %:z")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
4
10
|
conn = OCI8.new($dbuser, $dbpass, $dbname)
|
5
11
|
error_message = nil
|
6
12
|
begin
|
@@ -22,7 +28,7 @@ begin
|
|
22
28
|
|
23
29
|
begin
|
24
30
|
version = RbTestObj.test_object_version(conn)
|
25
|
-
error_message = "Invalid test object version" if version !=
|
31
|
+
error_message = "Invalid test object version" if version != 4
|
26
32
|
rescue NoMethodError
|
27
33
|
raise unless $!.to_s.include?('test_object_version')
|
28
34
|
error_message = "rb_test_obj.test_object_version is not declared."
|
@@ -100,7 +106,8 @@ class TestObj1 < Minitest::Test
|
|
100
106
|
attr_reader :obj_array_val
|
101
107
|
attr_reader :obj_ary_of_ary_val
|
102
108
|
attr_reader :date_val
|
103
|
-
|
109
|
+
attr_reader :timestamp_val
|
110
|
+
attr_reader :timestamp_tz_val
|
104
111
|
|
105
112
|
attr_accessor :assertions
|
106
113
|
|
@@ -109,16 +116,28 @@ class TestObj1 < Minitest::Test
|
|
109
116
|
@assertions = 0
|
110
117
|
end
|
111
118
|
|
112
|
-
def
|
119
|
+
def to_test_datetime(n, type)
|
113
120
|
year = (1990 + n).round
|
114
121
|
month = (n.round * 5) % 12 + 1
|
115
122
|
mday = (n.round * 7) % 27 + 1
|
116
123
|
hour = (n.round * 9) % 24
|
117
124
|
minute = (n.round * 11) % 60
|
118
125
|
sec = (n.round * 13) % 60
|
119
|
-
|
126
|
+
nsec = if type == :date
|
127
|
+
0
|
128
|
+
else
|
129
|
+
((n.round * 333_333_333) % 1_000_000_000).to_r / 1_000_000_000
|
130
|
+
end
|
131
|
+
tz = if type == :timestamp_tz
|
132
|
+
tzh = (n.round * 15) % 24 - 11
|
133
|
+
tzm = (n.round * 17) % 60
|
134
|
+
format('%+03d:%02d', tzh, tzm)
|
135
|
+
else
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
convert_to_time(year, month, mday, hour, minute, sec, nsec, tz)
|
120
139
|
end
|
121
|
-
private :
|
140
|
+
private :to_test_datetime
|
122
141
|
|
123
142
|
def next
|
124
143
|
@n += 1.2
|
@@ -135,7 +154,9 @@ class TestObj1 < Minitest::Test
|
|
135
154
|
@nclob_val = @str_val
|
136
155
|
@blob_val = @str_val
|
137
156
|
@obj_val = ExpectedValObjElem.new(@int_val, @int_val + 1)
|
138
|
-
@date_val =
|
157
|
+
@date_val = to_test_datetime(@n, :date)
|
158
|
+
@timestamp_val = to_test_datetime(@n, :timestamp)
|
159
|
+
@timestamp_tz_val = to_test_datetime(@n, :timestamp_tz)
|
139
160
|
if @int_val == 1
|
140
161
|
@int_array_val = nil
|
141
162
|
@flt_array_val = nil
|
@@ -199,7 +220,8 @@ class TestObj1 < Minitest::Test
|
|
199
220
|
obj_array_val = val[18]
|
200
221
|
obj_ary_of_ary_val = val[19]
|
201
222
|
date_val = val[20]
|
202
|
-
|
223
|
+
timestamp_val = val[21]
|
224
|
+
timestamp_tz_val = val[22]
|
203
225
|
else
|
204
226
|
assert_instance_of(RbTestObj, val)
|
205
227
|
int_val = val.int_val
|
@@ -223,7 +245,8 @@ class TestObj1 < Minitest::Test
|
|
223
245
|
obj_array_val = val.obj_array_val
|
224
246
|
obj_ary_of_ary_val = val.obj_ary_of_ary_val
|
225
247
|
date_val = val.date_val
|
226
|
-
|
248
|
+
timestamp_val = val.timestamp_val
|
249
|
+
timestamp_tz_val = val.timestamp_tz_val
|
227
250
|
end
|
228
251
|
|
229
252
|
assert_equal(@int_val, int_val)
|
@@ -267,7 +290,8 @@ class TestObj1 < Minitest::Test
|
|
267
290
|
assert_nil(obj_ary_of_ary_val)
|
268
291
|
end
|
269
292
|
assert_equal(@date_val, date_val)
|
270
|
-
|
293
|
+
assert_equal(@timestamp_val, timestamp_val)
|
294
|
+
assert_equal(@timestamp_tz_val, timestamp_tz_val)
|
271
295
|
end
|
272
296
|
|
273
297
|
def assert_array_in_delta(exp, val)
|