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.
Files changed (58) hide show
  1. data/ChangeLog +1289 -383
  2. data/Makefile +48 -12
  3. data/NEWS +5 -419
  4. data/README +56 -385
  5. data/VERSION +1 -1
  6. data/dist-files +27 -27
  7. data/lib/.document +2 -0
  8. data/lib/dbd/OCI8.rb +2 -17
  9. data/lib/oci8.rb +48 -1622
  10. data/lib/oci8.rb.in +48 -1622
  11. data/lib/oci8/.document +5 -0
  12. data/lib/oci8/compat.rb +108 -0
  13. data/lib/oci8/datetime.rb +491 -0
  14. data/lib/oci8/encoding-init.rb +40 -0
  15. data/lib/oci8/encoding.yml +537 -0
  16. data/lib/oci8/metadata.rb +2077 -0
  17. data/lib/oci8/object.rb +548 -0
  18. data/lib/oci8/oci8.rb +798 -0
  19. data/lib/oci8/oracle_version.rb +144 -0
  20. data/lib/oci8lib_18.so +0 -0
  21. data/lib/oci8lib_191.so +0 -0
  22. data/metaconfig +3 -3
  23. data/ruby-oci8.gemspec +24 -15
  24. data/setup.rb +4 -4
  25. data/test/config.rb +64 -84
  26. data/test/test_all.rb +14 -21
  27. data/test/test_array_dml.rb +333 -0
  28. data/test/test_bind_raw.rb +18 -25
  29. data/test/test_bind_time.rb +78 -91
  30. data/test/test_break.rb +37 -35
  31. data/test/test_clob.rb +33 -89
  32. data/test/test_connstr.rb +5 -4
  33. data/test/test_datetime.rb +469 -0
  34. data/test/test_dbi.rb +99 -60
  35. data/test/test_dbi_clob.rb +3 -8
  36. data/test/test_metadata.rb +65 -51
  37. data/test/test_oci8.rb +151 -55
  38. data/test/test_oracle_version.rb +70 -0
  39. data/test/test_oradate.rb +76 -83
  40. data/test/test_oranumber.rb +405 -71
  41. data/test/test_rowid.rb +6 -11
  42. metadata +21 -25
  43. data/ext/oci8/oci8lib.so +0 -0
  44. data/ruby-oci8.spec +0 -62
  45. data/support/README +0 -4
  46. data/support/runit/assert.rb +0 -281
  47. data/support/runit/cui/testrunner.rb +0 -101
  48. data/support/runit/error.rb +0 -4
  49. data/support/runit/method_mappable.rb +0 -20
  50. data/support/runit/robserver.rb +0 -25
  51. data/support/runit/setuppable.rb +0 -15
  52. data/support/runit/teardownable.rb +0 -16
  53. data/support/runit/testcase.rb +0 -113
  54. data/support/runit/testfailure.rb +0 -25
  55. data/support/runit/testresult.rb +0 -121
  56. data/support/runit/testsuite.rb +0 -43
  57. data/support/runit/version.rb +0 -3
  58. data/test/test_describe.rb +0 -137
@@ -1,10 +1,17 @@
1
1
  # High-level API
2
2
  require 'oci8'
3
- require 'runit/testcase'
4
- require 'runit/cui/testrunner'
3
+ require 'test/unit'
5
4
  require File.dirname(__FILE__) + '/config'
6
5
 
7
- class TestBreak < RUNIT::TestCase
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 = 3
18
- TIME_TO_BREAK = 1
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 = get_oci_connection()
52
- conn.non_blocking = false
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
- conn = get_oci_connection()
63
- conn.non_blocking = true
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
- expect[PLSQL_DONE] = "Invalid status"
66
- if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/
67
- # raise after sleeping #{TIME_IN_PLSQL} seconds.
68
- expect[OCIBREAK] = TIME_IN_PLSQL
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
@@ -1,122 +1,66 @@
1
1
  # Low-level API
2
2
  require 'oci8'
3
- require 'runit/testcase'
4
- require 'runit/cui/testrunner'
3
+ require 'test/unit'
5
4
  require File.dirname(__FILE__) + '/config'
6
5
 
7
- class TestCLob < RUNIT::TestCase
6
+ class TestCLob < Test::Unit::TestCase
8
7
 
9
8
  def setup
10
- @env, @svc, @stmt = setup_lowapi()
9
+ @conn = get_oci8_connection
11
10
  end
12
11
 
13
12
  def test_insert
14
13
  filename = File.basename($lobfile)
15
- @stmt.prepare("DELETE FROM test_clob WHERE filename = :1")
16
- @stmt.bindByPos(1, String, filename.size).set(filename)
17
- @stmt.execute(@svc)
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
- num_of_chars = lob.write(@svc, offset, $_)
32
- offset += num_of_chars
20
+ lob.write($_)
33
21
  end
34
22
  end
35
- lob.free()
23
+ lob.close
36
24
  end
37
25
 
38
- def test_insert_with_open_close
26
+ def test_insert_with_flush
39
27
  filename = File.basename($lobfile)
40
- @stmt.prepare("DELETE FROM test_clob WHERE filename = :1")
41
- @stmt.bindByPos(1, String, filename.size).set(filename)
42
- @stmt.execute(@svc)
43
-
44
- @stmt.prepare("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())")
45
- @stmt.bindByPos(1, String, filename.size).set(filename)
46
- @stmt.execute(@svc)
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.free()
65
- end
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
- lob = @env.alloc(OCILobLocator)
92
- @stmt.prepare("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE")
93
- @stmt.bindByPos(1, String, filename.size).set(filename)
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
- offset = 1
99
- while buf = lob.read(@svc, offset, $lobreadnum)
100
- fbuf = f.read(buf.size)
101
- assert_equal(fbuf, buf)
102
- offset += $lobreadnum
103
- # offset += buf.size will not work fine,
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
- assert_equal(true, f.eof?)
57
+ assert(f.eof?)
58
+ assert(lob.eof?)
109
59
  end
110
- lob.free()
60
+ lob.close
111
61
  end
112
62
 
113
63
  def teardown
114
- @stmt.free()
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
@@ -1,9 +1,8 @@
1
1
  require 'oci8'
2
- require 'runit/testcase'
3
- require 'runit/cui/testrunner'
2
+ require 'test/unit'
4
3
  require File.dirname(__FILE__) + '/config'
5
4
 
6
- class TestConnStr < RUNIT::TestCase
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
- assert_exception(test_case[1], test_case[0]) do
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