ruby-oci8 1.0.7-x86-mswin32-60 → 2.0.1-x86-mswin32-60
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 +1289 -383
- data/Makefile +48 -12
- data/NEWS +5 -419
- data/README +56 -385
- data/VERSION +1 -1
- data/dist-files +27 -27
- data/lib/.document +2 -0
- data/lib/dbd/OCI8.rb +2 -17
- data/lib/oci8.rb +48 -1622
- data/lib/oci8.rb.in +48 -1622
- data/lib/oci8/.document +5 -0
- data/lib/oci8/compat.rb +108 -0
- data/lib/oci8/datetime.rb +491 -0
- data/lib/oci8/encoding-init.rb +40 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2077 -0
- data/lib/oci8/object.rb +548 -0
- data/lib/oci8/oci8.rb +798 -0
- data/lib/oci8/oracle_version.rb +144 -0
- data/lib/oci8lib_18.so +0 -0
- data/lib/oci8lib_191.so +0 -0
- data/metaconfig +3 -3
- data/ruby-oci8.gemspec +24 -15
- data/setup.rb +4 -4
- data/test/config.rb +64 -84
- data/test/test_all.rb +14 -21
- data/test/test_array_dml.rb +333 -0
- data/test/test_bind_raw.rb +18 -25
- data/test/test_bind_time.rb +78 -91
- data/test/test_break.rb +37 -35
- data/test/test_clob.rb +33 -89
- data/test/test_connstr.rb +5 -4
- data/test/test_datetime.rb +469 -0
- data/test/test_dbi.rb +99 -60
- data/test/test_dbi_clob.rb +3 -8
- data/test/test_metadata.rb +65 -51
- data/test/test_oci8.rb +151 -55
- data/test/test_oracle_version.rb +70 -0
- data/test/test_oradate.rb +76 -83
- data/test/test_oranumber.rb +405 -71
- data/test/test_rowid.rb +6 -11
- metadata +21 -25
- data/ext/oci8/oci8lib.so +0 -0
- data/ruby-oci8.spec +0 -62
- data/support/README +0 -4
- data/support/runit/assert.rb +0 -281
- data/support/runit/cui/testrunner.rb +0 -101
- data/support/runit/error.rb +0 -4
- data/support/runit/method_mappable.rb +0 -20
- data/support/runit/robserver.rb +0 -25
- data/support/runit/setuppable.rb +0 -15
- data/support/runit/teardownable.rb +0 -16
- data/support/runit/testcase.rb +0 -113
- data/support/runit/testfailure.rb +0 -25
- data/support/runit/testresult.rb +0 -121
- data/support/runit/testsuite.rb +0 -43
- data/support/runit/version.rb +0 -3
- data/test/test_describe.rb +0 -137
data/test/test_break.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
# High-level API
|
2
2
|
require 'oci8'
|
3
|
-
require '
|
4
|
-
require 'runit/cui/testrunner'
|
3
|
+
require 'test/unit'
|
5
4
|
require File.dirname(__FILE__) + '/config'
|
6
5
|
|
7
|
-
class TestBreak <
|
6
|
+
class TestBreak < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@conn = get_oci8_connection
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
@conn.logoff
|
14
|
+
end
|
8
15
|
|
9
16
|
def report(str)
|
10
17
|
printf "%d: %s\n", (Time.now - $start_time), str
|
@@ -14,8 +21,8 @@ class TestBreak < RUNIT::TestCase
|
|
14
21
|
OCIBREAK = 2
|
15
22
|
SEND_BREAK = 3
|
16
23
|
|
17
|
-
TIME_IN_PLSQL =
|
18
|
-
TIME_TO_BREAK =
|
24
|
+
TIME_IN_PLSQL = 5
|
25
|
+
TIME_TO_BREAK = 2
|
19
26
|
MARGIN = 0.1
|
20
27
|
|
21
28
|
def do_test_ocibreak(conn, expect)
|
@@ -24,58 +31,53 @@ class TestBreak < RUNIT::TestCase
|
|
24
31
|
th = Thread.start do
|
25
32
|
begin
|
26
33
|
conn.exec("BEGIN DBMS_LOCK.SLEEP(#{TIME_IN_PLSQL}); END;")
|
27
|
-
assert_equal(expect[PLSQL_DONE], (Time.now - $start_time + MARGIN).to_i)
|
34
|
+
assert_equal(expect[PLSQL_DONE], (Time.now - $start_time + MARGIN).to_i, 'PLSQL_DONE')
|
28
35
|
rescue OCIBreak
|
29
|
-
assert_equal(expect[OCIBREAK], (Time.now - $start_time + MARGIN).to_i)
|
36
|
+
assert_equal(expect[OCIBREAK], (Time.now - $start_time + MARGIN).to_i, 'OCIBREAK')
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
40
|
+
sleep(0.01) # make a time to run DBMS_LOCK.SLEEP
|
33
41
|
sleep(TIME_TO_BREAK)
|
34
|
-
assert_equal(expect[SEND_BREAK], (Time.now - $start_time + MARGIN).to_i)
|
42
|
+
assert_equal(expect[SEND_BREAK], (Time.now - $start_time + MARGIN).to_i, 'SEND_BREAK')
|
35
43
|
conn.break()
|
36
44
|
th.join
|
37
45
|
end
|
38
46
|
|
39
|
-
def test_set_blocking_mode
|
40
|
-
conn = get_oci_connection()
|
41
|
-
conn.non_blocking = true
|
42
|
-
assert_equal(true, conn.non_blocking?)
|
43
|
-
conn.non_blocking = false
|
44
|
-
assert_equal(false, conn.non_blocking?)
|
45
|
-
conn.non_blocking = true
|
46
|
-
assert_equal(true, conn.non_blocking?)
|
47
|
-
conn.logoff()
|
48
|
-
end
|
49
|
-
|
50
47
|
def test_blocking_mode
|
51
|
-
conn =
|
52
|
-
conn.non_blocking
|
48
|
+
@conn.non_blocking = false
|
49
|
+
assert_equal(false, @conn.non_blocking?)
|
53
50
|
expect = []
|
54
51
|
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
55
52
|
expect[OCIBREAK] = "Invalid status"
|
56
53
|
expect[SEND_BREAK] = TIME_IN_PLSQL + TIME_TO_BREAK
|
57
|
-
do_test_ocibreak(conn, expect)
|
58
|
-
conn.logoff()
|
54
|
+
do_test_ocibreak(@conn, expect)
|
59
55
|
end
|
60
56
|
|
61
57
|
def test_non_blocking_mode
|
62
|
-
|
63
|
-
conn.
|
58
|
+
is_windows_server = false
|
59
|
+
@conn.exec('select banner from v$version') do |row|
|
60
|
+
is_windows_server = true if row[0].include? 'Windows'
|
61
|
+
end
|
62
|
+
|
63
|
+
@conn.non_blocking = true
|
64
|
+
assert_equal(true, @conn.non_blocking?)
|
64
65
|
expect = []
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
if is_windows_server
|
67
|
+
if $oracle_server_version >= OCI8::ORAVER_9_0
|
68
|
+
# raise after sleeping #{TIME_IN_PLSQL} seconds.
|
69
|
+
expect[PLSQL_DONE] = "Invalid status"
|
70
|
+
expect[OCIBREAK] = TIME_IN_PLSQL
|
71
|
+
else
|
72
|
+
expect[PLSQL_DONE] = TIME_IN_PLSQL
|
73
|
+
expect[OCIBREAK] = "Invalid status"
|
74
|
+
end
|
69
75
|
else
|
70
76
|
# raise immediately by OCI8#break.
|
77
|
+
expect[PLSQL_DONE] = "Invalid status"
|
71
78
|
expect[OCIBREAK] = TIME_TO_BREAK
|
72
79
|
end
|
73
80
|
expect[SEND_BREAK] = TIME_TO_BREAK
|
74
|
-
do_test_ocibreak(conn, expect)
|
75
|
-
conn.logoff()
|
81
|
+
do_test_ocibreak(@conn, expect)
|
76
82
|
end
|
77
83
|
end
|
78
|
-
|
79
|
-
if $0 == __FILE__
|
80
|
-
RUNIT::CUI::TestRunner.run(TestBreak.suite())
|
81
|
-
end
|
data/test/test_clob.rb
CHANGED
@@ -1,122 +1,66 @@
|
|
1
1
|
# Low-level API
|
2
2
|
require 'oci8'
|
3
|
-
require '
|
4
|
-
require 'runit/cui/testrunner'
|
3
|
+
require 'test/unit'
|
5
4
|
require File.dirname(__FILE__) + '/config'
|
6
5
|
|
7
|
-
class TestCLob <
|
6
|
+
class TestCLob < Test::Unit::TestCase
|
8
7
|
|
9
8
|
def setup
|
10
|
-
@
|
9
|
+
@conn = get_oci8_connection
|
11
10
|
end
|
12
11
|
|
13
12
|
def test_insert
|
14
13
|
filename = File.basename($lobfile)
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
|
19
|
-
@stmt.prepare("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())")
|
20
|
-
@stmt.bindByPos(1, String, filename.size).set(filename)
|
21
|
-
@stmt.execute(@svc)
|
22
|
-
|
23
|
-
lob = @env.alloc(OCILobLocator)
|
24
|
-
@stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
|
25
|
-
@stmt.bindByPos(1, String, filename.size).set(filename)
|
26
|
-
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
27
|
-
@stmt.execute(@svc, 1)
|
28
|
-
offset = 1 # count by charactor, not byte.
|
14
|
+
@conn.exec("DELETE FROM test_clob WHERE filename = :1", filename)
|
15
|
+
@conn.exec("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
16
|
+
cursor = @conn.exec("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)
|
17
|
+
lob = cursor.fetch[0]
|
29
18
|
open($lobfile) do |f|
|
30
19
|
while f.gets()
|
31
|
-
|
32
|
-
offset += num_of_chars
|
20
|
+
lob.write($_)
|
33
21
|
end
|
34
22
|
end
|
35
|
-
lob.
|
23
|
+
lob.close
|
36
24
|
end
|
37
25
|
|
38
|
-
def
|
26
|
+
def test_insert_with_flush
|
39
27
|
filename = File.basename($lobfile)
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
lob = @env.alloc(OCILobLocator)
|
49
|
-
@stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
|
50
|
-
@stmt.bindByPos(1, String, filename.size).set(filename)
|
51
|
-
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
52
|
-
@stmt.execute(@svc, 1)
|
53
|
-
lob.open(@svc)
|
54
|
-
begin
|
55
|
-
offset = 1 # count by charactor, not byte.
|
56
|
-
open($lobfile) do |f|
|
57
|
-
while f.gets()
|
58
|
-
offset += lob.write(@svc, offset, $_)
|
59
|
-
end
|
28
|
+
@conn.exec("DELETE FROM test_clob WHERE filename = :1", filename)
|
29
|
+
@conn.exec("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())", filename)
|
30
|
+
cursor = @conn.exec("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)
|
31
|
+
lob = cursor.fetch[0]
|
32
|
+
lob.sync = false
|
33
|
+
open($lobfile) do |f|
|
34
|
+
while f.gets()
|
35
|
+
lob.write($_)
|
60
36
|
end
|
61
|
-
ensure
|
62
|
-
lob.close(@svc)
|
63
37
|
end
|
64
|
-
lob.
|
65
|
-
|
66
|
-
|
67
|
-
def test_insert_symbol
|
68
|
-
filename = 'test_symbol'
|
69
|
-
value = :foo_bar
|
70
|
-
@stmt.prepare("DELETE FROM test_clob WHERE filename = :1")
|
71
|
-
@stmt.bindByPos(1, String, filename.size).set(filename)
|
72
|
-
@stmt.execute(@svc)
|
73
|
-
|
74
|
-
@stmt.prepare("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())")
|
75
|
-
@stmt.bindByPos(1, String, filename.size).set(filename)
|
76
|
-
@stmt.execute(@svc)
|
77
|
-
|
78
|
-
lob = @env.alloc(OCILobLocator)
|
79
|
-
@stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
|
80
|
-
@stmt.bindByPos(1, String, filename.size).set(filename)
|
81
|
-
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
82
|
-
@stmt.execute(@svc, 1)
|
83
|
-
lob.write(@svc, 1, value)
|
84
|
-
assert_equal(value.to_s, lob.read(@svc, 1, 30))
|
85
|
-
lob.free()
|
38
|
+
lob.flush
|
39
|
+
lob.close
|
86
40
|
end
|
87
41
|
|
88
42
|
def test_read
|
89
|
-
filename = File.basename($lobfile)
|
90
43
|
test_insert() # first insert data.
|
91
|
-
|
92
|
-
@
|
93
|
-
|
94
|
-
@stmt.defineByPos(1, OCI_TYPECODE_CLOB, lob)
|
95
|
-
@stmt.execute(@svc, 1)
|
44
|
+
filename = File.basename($lobfile)
|
45
|
+
cursor = @conn.exec("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)
|
46
|
+
lob = cursor.fetch[0]
|
96
47
|
|
97
48
|
open($lobfile) do |f|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
# Though buf.size counts in byte,
|
105
|
-
# offset and $lobreadnum count in character.
|
49
|
+
while buf = lob.read($lobreadnum)
|
50
|
+
fbuf = f.read(buf.size)
|
51
|
+
assert_equal(fbuf, buf)
|
52
|
+
# offset += buf.size will not work fine,
|
53
|
+
# Though buf.size counts in byte,
|
54
|
+
# offset and $lobreadnum count in character.
|
106
55
|
end
|
107
56
|
assert_equal(nil, buf)
|
108
|
-
|
57
|
+
assert(f.eof?)
|
58
|
+
assert(lob.eof?)
|
109
59
|
end
|
110
|
-
lob.
|
60
|
+
lob.close
|
111
61
|
end
|
112
62
|
|
113
63
|
def teardown
|
114
|
-
@
|
115
|
-
@svc.logoff()
|
116
|
-
@env.free()
|
64
|
+
@conn.logoff
|
117
65
|
end
|
118
66
|
end
|
119
|
-
|
120
|
-
if $0 == __FILE__
|
121
|
-
RUNIT::CUI::TestRunner.run(TestCLob.suite())
|
122
|
-
end
|
data/test/test_connstr.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'oci8'
|
2
|
-
require '
|
3
|
-
require 'runit/cui/testrunner'
|
2
|
+
require 'test/unit'
|
4
3
|
require File.dirname(__FILE__) + '/config'
|
5
4
|
|
6
|
-
class TestConnStr <
|
5
|
+
class TestConnStr < Test::Unit::TestCase
|
7
6
|
TEST_CASES =
|
8
7
|
[
|
9
8
|
# success cases:
|
@@ -69,7 +68,7 @@ class TestConnStr < RUNIT::TestCase
|
|
69
68
|
result = obj.instance_eval { parse_connect_string(test_case[0]) }
|
70
69
|
assert_equal(test_case[1], result, test_case[0])
|
71
70
|
when Class
|
72
|
-
|
71
|
+
assert_raises(test_case[1]) do
|
73
72
|
result = obj.instance_eval { parse_connect_string(test_case[0]) }
|
74
73
|
end
|
75
74
|
else
|
@@ -78,3 +77,5 @@ class TestConnStr < RUNIT::TestCase
|
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
80
|
+
|
81
|
+
Test::Unit::AutoRunner.run() if $0 == __FILE__
|
@@ -0,0 +1,469 @@
|
|
1
|
+
require 'oci8'
|
2
|
+
require 'test/unit'
|
3
|
+
require File.dirname(__FILE__) + '/config'
|
4
|
+
require 'scanf'
|
5
|
+
|
6
|
+
class TestDateTime < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def timezone_string(tzh, tzm)
|
9
|
+
if tzh >= 0
|
10
|
+
format("+%02d:%02d", tzh, tzm)
|
11
|
+
else
|
12
|
+
format("-%02d:%02d", -tzh, -tzm)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
@conn = get_oci8_connection
|
18
|
+
@local_timezone = timezone_string(*((::Time.now.utc_offset / 60).divmod 60))
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
@conn.logoff
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_date_select
|
26
|
+
['2005-12-31 23:59:59',
|
27
|
+
'2006-01-01 00:00:00'].each do |date|
|
28
|
+
@conn.exec(<<-EOS) do |row|
|
29
|
+
SELECT TO_DATE('#{date}', 'YYYY-MM-DD HH24:MI:SS') FROM dual
|
30
|
+
EOS
|
31
|
+
assert_equal(Time.local(*date.scanf("%d-%d-%d %d:%d:%d.%06d")), row[0])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_date_out_bind
|
37
|
+
cursor = @conn.parse(<<-EOS)
|
38
|
+
BEGIN
|
39
|
+
:out := TO_DATE(:in, 'YYYY-MM-DD HH24:MI:SS');
|
40
|
+
END;
|
41
|
+
EOS
|
42
|
+
cursor.bind_param(:out, nil, DateTime)
|
43
|
+
cursor.bind_param(:in, nil, String, 36)
|
44
|
+
['2005-12-31 23:59:59',
|
45
|
+
'2006-01-01 00:00:00'].each do |date|
|
46
|
+
cursor[:in] = date
|
47
|
+
cursor.exec
|
48
|
+
assert_equal(DateTime.parse(date + @local_timezone), cursor[:out])
|
49
|
+
end
|
50
|
+
cursor.close
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_date_in_bind
|
54
|
+
cursor = @conn.parse(<<-EOS)
|
55
|
+
DECLARE
|
56
|
+
dt date;
|
57
|
+
BEGIN
|
58
|
+
dt := :in;
|
59
|
+
:out := TO_CHAR(dt, 'YYYY-MM-DD HH24:MI:SS');
|
60
|
+
END;
|
61
|
+
EOS
|
62
|
+
cursor.bind_param(:out, nil, String, 33)
|
63
|
+
cursor.bind_param(:in, nil, DateTime)
|
64
|
+
['2005-12-31 23:59:59',
|
65
|
+
'2006-01-01 00:00:00'].each do |date|
|
66
|
+
cursor[:in] = DateTime.parse(date + @local_timezone)
|
67
|
+
cursor.exec
|
68
|
+
assert_equal(date, cursor[:out])
|
69
|
+
end
|
70
|
+
cursor.close
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_timestamp_select
|
74
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
75
|
+
|
76
|
+
['2005-12-31 23:59:59.999999000',
|
77
|
+
'2006-01-01 00:00:00.000000000'].each do |date|
|
78
|
+
@conn.exec(<<-EOS) do |row|
|
79
|
+
SELECT TO_TIMESTAMP('#{date}', 'YYYY-MM-DD HH24:MI:SS.FF') FROM dual
|
80
|
+
EOS
|
81
|
+
assert_equal(Time.local(*date.scanf("%d-%d-%d %d:%d:%d.%06d")), row[0])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_timestamp_out_bind
|
87
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
88
|
+
|
89
|
+
cursor = @conn.parse(<<-EOS)
|
90
|
+
BEGIN
|
91
|
+
:out := TO_TIMESTAMP(:in, 'YYYY-MM-DD HH24:MI:SS.FF');
|
92
|
+
END;
|
93
|
+
EOS
|
94
|
+
cursor.bind_param(:out, nil, DateTime)
|
95
|
+
cursor.bind_param(:in, nil, String, 36)
|
96
|
+
['2005-12-31 23:59:59.999999000',
|
97
|
+
'2006-01-01 00:00:00.000000000'].each do |date|
|
98
|
+
cursor[:in] = date
|
99
|
+
cursor.exec
|
100
|
+
assert_equal(DateTime.parse(date + @local_timezone), cursor[:out])
|
101
|
+
end
|
102
|
+
cursor.close
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_timestamp_in_bind
|
106
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
107
|
+
|
108
|
+
cursor = @conn.parse(<<-EOS)
|
109
|
+
BEGIN
|
110
|
+
:out := TO_CHAR(:in, 'YYYY-MM-DD HH24:MI:SS.FF');
|
111
|
+
END;
|
112
|
+
EOS
|
113
|
+
cursor.bind_param(:out, nil, String, 33)
|
114
|
+
cursor.bind_param(:in, nil, DateTime)
|
115
|
+
['2005-12-31 23:59:59.999999000',
|
116
|
+
'2006-01-01 00:00:00.000000000'].each do |date|
|
117
|
+
cursor[:in] = DateTime.parse(date + @local_timezone)
|
118
|
+
cursor.exec
|
119
|
+
assert_equal(date, cursor[:out])
|
120
|
+
end
|
121
|
+
cursor.close
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_timestamp_tz_select
|
125
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
126
|
+
|
127
|
+
['2005-12-31 23:59:59.999999000 +08:30',
|
128
|
+
'2006-01-01 00:00:00.000000000 -08:30'].each do |date|
|
129
|
+
@conn.exec(<<-EOS) do |row|
|
130
|
+
SELECT TO_TIMESTAMP_TZ('#{date}', 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM') FROM dual
|
131
|
+
EOS
|
132
|
+
assert_equal(DateTime.parse(date), row[0])
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_timestamp_tz_out_bind
|
138
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
139
|
+
|
140
|
+
cursor = @conn.parse(<<-EOS)
|
141
|
+
BEGIN
|
142
|
+
:out := TO_TIMESTAMP_TZ(:in, 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM');
|
143
|
+
END;
|
144
|
+
EOS
|
145
|
+
cursor.bind_param(:out, nil, DateTime)
|
146
|
+
cursor.bind_param(:in, nil, String, 36)
|
147
|
+
['2005-12-31 23:59:59.999999000 +08:30',
|
148
|
+
'2006-01-01 00:00:00.000000000 -08:30'].each do |date|
|
149
|
+
cursor[:in] = date
|
150
|
+
cursor.exec
|
151
|
+
assert_equal(DateTime.parse(date), cursor[:out])
|
152
|
+
end
|
153
|
+
cursor.close
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_timestamp_tz_in_bind
|
157
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
158
|
+
|
159
|
+
cursor = @conn.parse(<<-EOS)
|
160
|
+
BEGIN
|
161
|
+
:out := TO_CHAR(:in, 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM');
|
162
|
+
END;
|
163
|
+
EOS
|
164
|
+
cursor.bind_param(:out, nil, String, 36)
|
165
|
+
cursor.bind_param(:in, nil, DateTime)
|
166
|
+
['2005-12-31 23:59:59.999999000 +08:30',
|
167
|
+
'2006-01-01 00:00:00.000000000 -08:30'].each do |date|
|
168
|
+
cursor[:in] = DateTime.parse(date)
|
169
|
+
cursor.exec
|
170
|
+
assert_equal(date, cursor[:out])
|
171
|
+
end
|
172
|
+
cursor.close
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_datetype_duck_typing
|
176
|
+
cursor = @conn.parse("BEGIN :out := :in; END;")
|
177
|
+
cursor.bind_param(:in, nil, DateTime)
|
178
|
+
cursor.bind_param(:out, nil, DateTime)
|
179
|
+
obj = Object.new
|
180
|
+
# test year, month, day
|
181
|
+
def obj.year; 2006; end
|
182
|
+
def obj.month; 12; end
|
183
|
+
def obj.day; 31; end
|
184
|
+
cursor[:in] = obj
|
185
|
+
cursor.exec
|
186
|
+
assert_equal(DateTime.parse('2006-12-31 00:00:00' + @local_timezone), cursor[:out])
|
187
|
+
# test hour
|
188
|
+
def obj.hour; 23; end
|
189
|
+
cursor[:in] = obj
|
190
|
+
cursor.exec
|
191
|
+
assert_equal(DateTime.parse('2006-12-31 23:00:00' + @local_timezone), cursor[:out])
|
192
|
+
# test min
|
193
|
+
def obj.min; 59; end
|
194
|
+
cursor[:in] = obj
|
195
|
+
cursor.exec
|
196
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:00' + @local_timezone), cursor[:out])
|
197
|
+
# test sec
|
198
|
+
def obj.sec; 59; end
|
199
|
+
cursor[:in] = obj
|
200
|
+
cursor.exec
|
201
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:59' + @local_timezone), cursor[:out])
|
202
|
+
|
203
|
+
# sec_fraction and timezone are available on Oracle 9i or later
|
204
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
205
|
+
|
206
|
+
# test sec_fraction
|
207
|
+
def obj.sec_fraction; DateTime.parse('0001-01-01 00:00:00.000001').sec_fraction * 999999 ; end
|
208
|
+
cursor[:in] = obj
|
209
|
+
cursor.exec
|
210
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:59.999999' + @local_timezone), cursor[:out])
|
211
|
+
# test utc_offset (Time)
|
212
|
+
def obj.utc_offset; @utc_offset; end
|
213
|
+
obj.instance_variable_set(:@utc_offset, 9 * 60 * 60)
|
214
|
+
cursor[:in] = obj
|
215
|
+
cursor.exec
|
216
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:59.999999 +09:00'), cursor[:out])
|
217
|
+
obj.instance_variable_set(:@utc_offset, -5 * 60 * 60)
|
218
|
+
cursor[:in] = obj
|
219
|
+
cursor.exec
|
220
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:59.999999 -05:00'), cursor[:out])
|
221
|
+
# test offset (DateTime)
|
222
|
+
def obj.offset; @offset; end
|
223
|
+
obj.instance_variable_set(:@offset, 9.to_r / 24)
|
224
|
+
cursor[:in] = obj
|
225
|
+
cursor.exec
|
226
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:59.999999 +09:00'), cursor[:out])
|
227
|
+
obj.instance_variable_set(:@offset, -5.to_r / 24)
|
228
|
+
cursor[:in] = obj
|
229
|
+
cursor.exec
|
230
|
+
assert_equal(DateTime.parse('2006-12-31 23:59:59.999999 -05:00'), cursor[:out])
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_timezone
|
234
|
+
if $oracle_version >= OCI8::ORAVER_9_0
|
235
|
+
# temporarily change the mapping to test OCI8::BindType::Util.default_timezone.
|
236
|
+
OCI8::BindType::Mapping[:date] = OCI8::BindType::TimeViaOCIDate
|
237
|
+
end
|
238
|
+
begin
|
239
|
+
assert_raise(ArgumentError) do
|
240
|
+
OCI8::BindType::Util.default_timezone = :invalid_value
|
241
|
+
end
|
242
|
+
|
243
|
+
[:local, :utc].each do |tz|
|
244
|
+
OCI8::BindType::Util.default_timezone = tz
|
245
|
+
@conn.exec("select sysdate, to_date('2008-01-02', 'yyyy-mm-dd') from dual") do |row|
|
246
|
+
row.each do |dt|
|
247
|
+
assert_kind_of(Time, dt)
|
248
|
+
assert_equal(tz, dt.utc? ? :utc : :local)
|
249
|
+
end
|
250
|
+
assert_equal(2008, row[1].year)
|
251
|
+
assert_equal(1, row[1].month)
|
252
|
+
assert_equal(2, row[1].day)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
ensure
|
256
|
+
OCI8::BindType::Util.default_timezone = :local
|
257
|
+
if $oracle_version >= OCI8::ORAVER_9_0
|
258
|
+
OCI8::BindType::Mapping[:date] = OCI8::BindType::Time
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
if $oracle_version >= OCI8::ORAVER_9_0
|
263
|
+
ses_tz = nil
|
264
|
+
@conn.exec('select sessiontimezone from dual') do |row|
|
265
|
+
ses_tz = row[0]
|
266
|
+
end
|
267
|
+
|
268
|
+
begin
|
269
|
+
['+09:00', '+00:00', '-05:00'].each do |tz|
|
270
|
+
@conn.exec("alter session set time_zone = '#{tz}'")
|
271
|
+
@conn.exec("select current_timestamp, sysdate, to_timestamp('2008-01-02', 'yyyy-mm-dd') from dual") do |row|
|
272
|
+
row.each do |dt|
|
273
|
+
case dt
|
274
|
+
when Time
|
275
|
+
assert_equal(tz, timezone_string(*((dt.utc_offset / 60).divmod 60)))
|
276
|
+
when DateTime
|
277
|
+
assert_equal(tz, dt.zone)
|
278
|
+
else
|
279
|
+
flunk "unexpedted type #{dt.class}"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
assert_equal(2008, row[2].year)
|
283
|
+
assert_equal(1, row[2].month)
|
284
|
+
assert_equal(2, row[2].day)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
ensure
|
288
|
+
@conn.exec("alter session set time_zone = '#{ses_tz}'")
|
289
|
+
end
|
290
|
+
else
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_interval_ym_select
|
295
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
296
|
+
|
297
|
+
[['2006-01-01', '2004-03-01'],
|
298
|
+
['2006-01-01', '2005-03-01'],
|
299
|
+
['2006-01-01', '2006-03-01'],
|
300
|
+
['2006-01-01', '2007-03-01']
|
301
|
+
].each do |date1, date2|
|
302
|
+
@conn.exec(<<-EOS) do |row|
|
303
|
+
SELECT (TO_TIMESTAMP('#{date1}', 'YYYY-MM-DD')
|
304
|
+
- TO_TIMESTAMP('#{date2}', 'YYYY-MM-DD')) YEAR TO MONTH
|
305
|
+
FROM dual
|
306
|
+
EOS
|
307
|
+
assert_equal(DateTime.parse(date1), DateTime.parse(date2) >> row[0])
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_interval_ym_out_bind
|
313
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
314
|
+
|
315
|
+
cursor = @conn.parse(<<-EOS)
|
316
|
+
DECLARE
|
317
|
+
ts1 TIMESTAMP;
|
318
|
+
ts2 TIMESTAMP;
|
319
|
+
BEGIN
|
320
|
+
ts1 := TO_TIMESTAMP(:in1, 'YYYY-MM-DD');
|
321
|
+
ts2 := TO_TIMESTAMP(:in2, 'YYYY-MM-DD');
|
322
|
+
:out := (ts1 - ts2) YEAR TO MONTH;
|
323
|
+
END;
|
324
|
+
EOS
|
325
|
+
cursor.bind_param(:out, nil, :interval_ym)
|
326
|
+
cursor.bind_param(:in1, nil, String, 36)
|
327
|
+
cursor.bind_param(:in2, nil, String, 36)
|
328
|
+
[['2006-01-01', '2004-03-01'],
|
329
|
+
['2006-01-01', '2005-03-01'],
|
330
|
+
['2006-01-01', '2006-03-01'],
|
331
|
+
['2006-01-01', '2007-03-01']
|
332
|
+
].each do |date1, date2|
|
333
|
+
cursor[:in1] = date1
|
334
|
+
cursor[:in2] = date2
|
335
|
+
cursor.exec
|
336
|
+
assert_equal(DateTime.parse(date1), DateTime.parse(date2) >> cursor[:out])
|
337
|
+
end
|
338
|
+
cursor.close
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_interval_ym_in_bind
|
342
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
343
|
+
|
344
|
+
cursor = @conn.parse(<<-EOS)
|
345
|
+
DECLARE
|
346
|
+
ts1 TIMESTAMP;
|
347
|
+
BEGIN
|
348
|
+
ts1 := TO_TIMESTAMP(:in1, 'YYYY-MM-DD');
|
349
|
+
:out := TO_CHAR(ts1 + :in2, 'YYYY-MM-DD');
|
350
|
+
END;
|
351
|
+
EOS
|
352
|
+
cursor.bind_param(:out, nil, String, 36)
|
353
|
+
cursor.bind_param(:in1, nil, String, 36)
|
354
|
+
cursor.bind_param(:in2, nil, :interval_ym)
|
355
|
+
[['2006-01-01', -22],
|
356
|
+
['2006-01-01', -10],
|
357
|
+
['2006-01-01', +2],
|
358
|
+
['2006-01-01', +12]
|
359
|
+
].each do |date, interval|
|
360
|
+
cursor[:in1] = date
|
361
|
+
cursor[:in2] = interval
|
362
|
+
cursor.exec
|
363
|
+
assert_equal(DateTime.parse(date) >> interval, DateTime.parse(cursor[:out]))
|
364
|
+
end
|
365
|
+
cursor.close
|
366
|
+
end
|
367
|
+
|
368
|
+
def test_interval_ds_select
|
369
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
370
|
+
|
371
|
+
[['2006-01-01', '2004-03-01'],
|
372
|
+
['2006-01-01', '2005-03-01'],
|
373
|
+
['2006-01-01', '2006-03-01'],
|
374
|
+
['2006-01-01', '2007-03-01'],
|
375
|
+
['2006-01-01', '2006-01-01 23:00:00'],
|
376
|
+
['2006-01-01', '2006-01-01 00:59:00'],
|
377
|
+
['2006-01-01', '2006-01-01 00:00:59'],
|
378
|
+
['2006-01-01', '2006-01-01 00:00:00.999999'],
|
379
|
+
['2006-01-01', '2006-01-01 23:59:59.999999'],
|
380
|
+
['2006-01-01', '2005-12-31 23:00:00'],
|
381
|
+
['2006-01-01', '2005-12-31 00:59:00'],
|
382
|
+
['2006-01-01', '2005-12-31 00:00:59'],
|
383
|
+
['2006-01-01', '2005-12-31 00:00:00.999999'],
|
384
|
+
['2006-01-01', '2005-12-31 23:59:59.999999']
|
385
|
+
].each do |date1, date2|
|
386
|
+
@conn.exec(<<-EOS) do |row|
|
387
|
+
SELECT (TO_TIMESTAMP('#{date1}', 'YYYY-MM-DD HH24:MI:SS.FF')
|
388
|
+
- TO_TIMESTAMP('#{date2}', 'YYYY-MM-DD HH24:MI:SS.FF')) DAY(3) TO SECOND
|
389
|
+
FROM dual
|
390
|
+
EOS
|
391
|
+
assert_equal(DateTime.parse(date1) - DateTime.parse(date2), row[0])
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_interval_ds_out_bind
|
397
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
398
|
+
|
399
|
+
cursor = @conn.parse(<<-EOS)
|
400
|
+
DECLARE
|
401
|
+
ts1 TIMESTAMP;
|
402
|
+
ts2 TIMESTAMP;
|
403
|
+
BEGIN
|
404
|
+
ts1 := TO_TIMESTAMP(:in1, 'YYYY-MM-DD HH24:MI:SS.FF');
|
405
|
+
ts2 := TO_TIMESTAMP(:in2, 'YYYY-MM-DD HH24:MI:SS.FF');
|
406
|
+
:out := (ts1 - ts2) DAY TO SECOND(9);
|
407
|
+
END;
|
408
|
+
EOS
|
409
|
+
cursor.bind_param(:out, nil, :interval_ds)
|
410
|
+
cursor.bind_param(:in1, nil, String, 36)
|
411
|
+
cursor.bind_param(:in2, nil, String, 36)
|
412
|
+
[['2006-01-01', '2004-03-01'],
|
413
|
+
['2006-01-01', '2005-03-01'],
|
414
|
+
['2006-01-01', '2006-03-01'],
|
415
|
+
['2006-01-01', '2007-03-01'],
|
416
|
+
['2006-01-01', '2006-01-01 23:00:00'],
|
417
|
+
['2006-01-01', '2006-01-01 00:59:00'],
|
418
|
+
['2006-01-01', '2006-01-01 00:00:59'],
|
419
|
+
['2006-01-01', '2006-01-01 00:00:00.999999'],
|
420
|
+
['2006-01-01', '2006-01-01 23:59:59.999999'],
|
421
|
+
['2006-01-01', '2005-12-31 23:00:00'],
|
422
|
+
['2006-01-01', '2005-12-31 00:59:00'],
|
423
|
+
['2006-01-01', '2005-12-31 00:00:59'],
|
424
|
+
['2006-01-01', '2005-12-31 00:00:00.999999'],
|
425
|
+
['2006-01-01', '2005-12-31 23:59:59.999999']
|
426
|
+
].each do |date1, date2|
|
427
|
+
cursor[:in1] = date1
|
428
|
+
cursor[:in2] = date2
|
429
|
+
cursor.exec
|
430
|
+
assert_equal(DateTime.parse(date1) - DateTime.parse(date2), cursor[:out])
|
431
|
+
end
|
432
|
+
cursor.close
|
433
|
+
end
|
434
|
+
|
435
|
+
def test_interval_ds_in_bind
|
436
|
+
return if $oracle_version < OCI8::ORAVER_9_0
|
437
|
+
|
438
|
+
cursor = @conn.parse(<<-EOS)
|
439
|
+
DECLARE
|
440
|
+
ts1 TIMESTAMP;
|
441
|
+
BEGIN
|
442
|
+
ts1 := TO_TIMESTAMP(:in1, 'YYYY-MM-DD HH24:MI:SS.FF');
|
443
|
+
:out := TO_CHAR(ts1 + :in2, 'YYYY-MM-DD HH24:MI:SS.FF');
|
444
|
+
END;
|
445
|
+
EOS
|
446
|
+
cursor.bind_param(:out, nil, String, 36)
|
447
|
+
cursor.bind_param(:in1, nil, String, 36)
|
448
|
+
cursor.bind_param(:in2, nil, :interval_ds)
|
449
|
+
[['2006-01-01', -22],
|
450
|
+
['2006-01-01', -10],
|
451
|
+
['2006-01-01', +2],
|
452
|
+
['2006-01-01', +12],
|
453
|
+
['2006-01-01', -1.to_r / 24], # one hour
|
454
|
+
['2006-01-01', -1.to_r / (24*60)], # one minute
|
455
|
+
['2006-01-01', -1.to_r / (24*60*60)], # one second
|
456
|
+
['2006-01-01', -999999.to_r / (24*60*60*1000000)], # 0.999999 seconds
|
457
|
+
['2006-01-01', +1.to_r / 24], # one hour
|
458
|
+
['2006-01-01', +1.to_r / (24*60)], # one minute
|
459
|
+
['2006-01-01', +1.to_r / (24*60*60)], # one second
|
460
|
+
['2006-01-01', +999999.to_r / (24*60*60*1000000)] # 0.999999 seconds
|
461
|
+
].each do |date, interval|
|
462
|
+
cursor[:in1] = date
|
463
|
+
cursor[:in2] = interval
|
464
|
+
cursor.exec
|
465
|
+
assert_equal(DateTime.parse(date) + interval, DateTime.parse(cursor[:out]))
|
466
|
+
end
|
467
|
+
cursor.close
|
468
|
+
end
|
469
|
+
end # TestOCI8
|