ruby-oci8 2.1.5.1-x64-mingw32

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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +17 -0
  3. data/COPYING +30 -0
  4. data/COPYING_old +64 -0
  5. data/ChangeLog +2779 -0
  6. data/Makefile +92 -0
  7. data/NEWS +660 -0
  8. data/README.md +43 -0
  9. data/VERSION +1 -0
  10. data/dist-files +91 -0
  11. data/docs/install-binary-package.md +40 -0
  12. data/docs/install-full-client.md +116 -0
  13. data/docs/install-instant-client.md +167 -0
  14. data/docs/platform-specific-issues.md +197 -0
  15. data/docs/report-installation-issue.md +50 -0
  16. data/lib/.document +1 -0
  17. data/lib/dbd/OCI8.rb +591 -0
  18. data/lib/oci8.rb +147 -0
  19. data/lib/oci8.rb.in +147 -0
  20. data/lib/oci8/.document +8 -0
  21. data/lib/oci8/bindtype.rb +350 -0
  22. data/lib/oci8/compat.rb +113 -0
  23. data/lib/oci8/connection_pool.rb +108 -0
  24. data/lib/oci8/cursor.rb +564 -0
  25. data/lib/oci8/datetime.rb +605 -0
  26. data/lib/oci8/encoding-init.rb +79 -0
  27. data/lib/oci8/encoding.yml +537 -0
  28. data/lib/oci8/metadata.rb +2092 -0
  29. data/lib/oci8/object.rb +605 -0
  30. data/lib/oci8/oci8.rb +560 -0
  31. data/lib/oci8/ocihandle.rb +607 -0
  32. data/lib/oci8/oracle_version.rb +143 -0
  33. data/lib/oci8/properties.rb +134 -0
  34. data/lib/oci8lib_200.so +0 -0
  35. data/metaconfig +142 -0
  36. data/pre-distclean.rb +7 -0
  37. data/ruby-oci8.gemspec +80 -0
  38. data/setup.rb +1333 -0
  39. data/test/README +42 -0
  40. data/test/config.rb +184 -0
  41. data/test/setup_test_object.sql +171 -0
  42. data/test/test_all.rb +54 -0
  43. data/test/test_appinfo.rb +63 -0
  44. data/test/test_array_dml.rb +333 -0
  45. data/test/test_bind_raw.rb +46 -0
  46. data/test/test_bind_string.rb +106 -0
  47. data/test/test_bind_time.rb +178 -0
  48. data/test/test_break.rb +124 -0
  49. data/test/test_clob.rb +98 -0
  50. data/test/test_connection_pool.rb +125 -0
  51. data/test/test_connstr.rb +81 -0
  52. data/test/test_datetime.rb +581 -0
  53. data/test/test_dbi.rb +366 -0
  54. data/test/test_dbi_clob.rb +53 -0
  55. data/test/test_encoding.rb +104 -0
  56. data/test/test_error.rb +88 -0
  57. data/test/test_metadata.rb +1485 -0
  58. data/test/test_object.rb +462 -0
  59. data/test/test_oci8.rb +489 -0
  60. data/test/test_oracle_version.rb +70 -0
  61. data/test/test_oradate.rb +256 -0
  62. data/test/test_oranumber.rb +787 -0
  63. data/test/test_rowid.rb +33 -0
  64. metadata +109 -0
@@ -0,0 +1,70 @@
1
+ require 'oci8'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/config'
4
+
5
+ class TestOracleVersion < Test::Unit::TestCase
6
+
7
+ def test_init
8
+ oraver = OCI8::OracleVersion.new('8.1.6.2.3')
9
+ assert_equal(8, oraver.major)
10
+ assert_equal(1, oraver.minor)
11
+ assert_equal(6, oraver.update)
12
+ assert_equal(2, oraver.patch)
13
+ assert_equal(3, oraver.port_update)
14
+
15
+ oraver = OCI8::OracleVersion.new('8.1.6')
16
+ assert_equal(8, oraver.major)
17
+ assert_equal(1, oraver.minor)
18
+ assert_equal(6, oraver.update)
19
+ assert_equal(0, oraver.patch)
20
+ assert_equal(0, oraver.port_update)
21
+
22
+ oraver = OCI8::OracleVersion.new('10')
23
+ assert_equal(10, oraver.major)
24
+ assert_equal(0, oraver.minor)
25
+ assert_equal(0, oraver.update)
26
+ assert_equal(0, oraver.patch)
27
+ assert_equal(0, oraver.port_update)
28
+
29
+ oraver = OCI8::OracleVersion.new(0x08106203)
30
+ assert_equal(8, oraver.major)
31
+ assert_equal(1, oraver.minor)
32
+ assert_equal(6, oraver.update)
33
+ assert_equal(2, oraver.patch)
34
+ assert_equal(3, oraver.port_update)
35
+ end
36
+
37
+ def test_compare
38
+ oraver = OCI8::OracleVersion.new('8.1.6.2.3')
39
+ assert_operator(oraver, :==, OCI8::OracleVersion.new('8.1.6.2.3'))
40
+ assert_operator(oraver, :<, OCI8::OracleVersion.new('9.1.6.2.3'))
41
+ assert_operator(oraver, :<, OCI8::OracleVersion.new('8.2.6.2.3'))
42
+ assert_operator(oraver, :<, OCI8::OracleVersion.new('8.1.7.2.3'))
43
+ assert_operator(oraver, :<, OCI8::OracleVersion.new('8.1.6.3.3'))
44
+ assert_operator(oraver, :<, OCI8::OracleVersion.new('8.1.6.2.4'))
45
+ assert_operator(oraver, :>, OCI8::OracleVersion.new('7.1.6.2.3'))
46
+ assert_operator(oraver, :>, OCI8::OracleVersion.new('8.0.6.2.3'))
47
+ assert_operator(oraver, :>, OCI8::OracleVersion.new('8.1.5.2.3'))
48
+ assert_operator(oraver, :>, OCI8::OracleVersion.new('8.1.6.1.3'))
49
+ assert_operator(oraver, :>, OCI8::OracleVersion.new('8.1.6.2.2'))
50
+ end
51
+
52
+ def test_to_s
53
+ oraver = OCI8::OracleVersion.new('8.1.6.2.3')
54
+ assert_equal('8.1.6.2.3', oraver.to_s)
55
+ end
56
+
57
+ def test_to_i
58
+ oraver = OCI8::OracleVersion.new('8.1.6.2.3')
59
+ assert_equal(0x08106203, oraver.to_i)
60
+ end
61
+
62
+ def test_eql
63
+ oraver = OCI8::OracleVersion.new('8.1.6.2.3')
64
+ assert_equal(true, oraver.eql?(OCI8::OracleVersion.new('8.1.6.2.3')))
65
+ assert_equal(false, oraver.eql?(OCI8::OracleVersion.new('8.2.6.2.3')))
66
+ assert_equal(false, oraver.eql?('8.1.6.2.3'))
67
+ end
68
+ end
69
+
70
+ Test::Unit::AutoRunner.run() if $0 == __FILE__
@@ -0,0 +1,256 @@
1
+ # Low-level API
2
+ require 'oci8'
3
+ require 'test/unit'
4
+ require File.dirname(__FILE__) + '/config'
5
+
6
+ class TestOraDate < Test::Unit::TestCase
7
+
8
+ YEAR_CHECK_TARGET = [-4712, -1, 1, 1192, 1868, 2002, 9999]
9
+ MONTH_CHECK_TARGET = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
10
+ DAY_CHECK_TARGET = [1, 10, 20, 31] # days of January.
11
+ HOUR_CHECK_TARGET = [0, 6, 12, 18, 23]
12
+ MINUTE_CHECK_TARGET = [0, 15, 30, 45, 59]
13
+ SECOND_CHECK_TARGET = [0, 15, 30, 45, 59]
14
+
15
+ def setup
16
+ @conn = get_oci8_connection
17
+ end
18
+
19
+ def check_oradate(target, year, month, day, hour, minute, second)
20
+ assert_equal(year, target.year)
21
+ assert_equal(month, target.month)
22
+ assert_equal(day, target.day)
23
+ assert_equal(hour, target.hour)
24
+ assert_equal(minute, target.minute)
25
+ assert_equal(second, target.second)
26
+ end
27
+
28
+ def test_new()
29
+ check_oradate(OraDate.new(), 1, 1, 1, 0, 0, 0)
30
+ end
31
+
32
+ def test_set_year
33
+ cursor = @conn.parse("BEGIN :year := TO_NUMBER(TO_CHAR(:date, 'SYYYY'), '9999'); END;")
34
+ cursor.bind_param(:date, OraDate)
35
+ cursor.bind_param(:year, Fixnum)
36
+ date = OraDate.new()
37
+ YEAR_CHECK_TARGET.each do |i|
38
+ # set year
39
+ date.year = i
40
+ # check result via oracle.
41
+ cursor[:date] = date
42
+ cursor.exec
43
+ assert_equal(i, cursor[:year])
44
+ end
45
+ end
46
+
47
+ def test_get_year
48
+ cursor = @conn.parse("BEGIN :date := TO_DATE(TO_CHAR(:year, '0999'), 'SYYYY'); END;")
49
+ cursor.bind_param(:year, Fixnum)
50
+ cursor.bind_param(:date, OraDate)
51
+ YEAR_CHECK_TARGET.each do |i|
52
+ # set date via oracle.
53
+ cursor[:year] = i
54
+ cursor.exec
55
+ # check OraDate#year
56
+ assert_equal(i, cursor[:date].year)
57
+ end
58
+ end
59
+
60
+ def test_set_month
61
+ cursor = @conn.parse("BEGIN :month := TO_NUMBER(TO_CHAR(:date, 'MM'), '99'); END;")
62
+ cursor.bind_param(:date, OraDate)
63
+ cursor.bind_param(:month, Fixnum)
64
+ date = OraDate.new()
65
+ MONTH_CHECK_TARGET.each do |i|
66
+ # set month
67
+ date.month = i
68
+ # check result via oracle.
69
+ cursor[:date] = date
70
+ cursor.exec
71
+ assert_equal(i, cursor[:month])
72
+ end
73
+ end
74
+
75
+ def test_get_month
76
+ cursor = @conn.parse("BEGIN :date := TO_DATE(TO_CHAR(:month, '99'), 'MM'); END;")
77
+ cursor.bind_param(:month, Fixnum)
78
+ cursor.bind_param(:date, OraDate)
79
+ MONTH_CHECK_TARGET.each do |i|
80
+ # set date via oracle.
81
+ cursor[:month] = i
82
+ cursor.exec
83
+ # check OraDate#month
84
+ assert_equal(i, cursor[:date].month)
85
+ end
86
+ end
87
+
88
+ def test_set_day
89
+ cursor = @conn.parse("BEGIN :day := TO_NUMBER(TO_CHAR(:date, 'DD'), '99'); END;")
90
+ cursor.bind_param(:date, OraDate)
91
+ cursor.bind_param(:day, Fixnum)
92
+ date = OraDate.new()
93
+ DAY_CHECK_TARGET.each do |i|
94
+ # set day
95
+ date.day = i
96
+ # check result via oracle.
97
+ cursor[:date] = date
98
+ cursor.exec
99
+ assert_equal(i, cursor[:day])
100
+ end
101
+ end
102
+
103
+ def test_get_day
104
+ cursor = @conn.parse("BEGIN :date := TO_DATE('200101' || TO_CHAR(:day, 'FM00'), 'YYYYMMDD'); END;")
105
+ cursor.bind_param(:day, Fixnum)
106
+ cursor.bind_param(:date, OraDate)
107
+ DAY_CHECK_TARGET.each do |i|
108
+ # set date via oracle.
109
+ cursor[:day] = i
110
+ cursor.exec
111
+ # check OraDate#day
112
+ assert_equal(i, cursor[:date].day)
113
+ end
114
+ end
115
+
116
+ def test_set_hour
117
+ cursor = @conn.parse("BEGIN :hour := TO_NUMBER(TO_CHAR(:date, 'HH24'), '99'); END;")
118
+ cursor.bind_param(:date, OraDate)
119
+ cursor.bind_param(:hour, Fixnum)
120
+ date = OraDate.new()
121
+ HOUR_CHECK_TARGET.each do |i|
122
+ # set hour
123
+ date.hour = i
124
+ # check result via oracle.
125
+ cursor[:date] = date
126
+ cursor.exec
127
+ assert_equal(i, cursor[:hour])
128
+ end
129
+ end
130
+
131
+ def test_get_hour
132
+ cursor = @conn.parse("BEGIN :date := TO_DATE(TO_CHAR(:hour, '99'), 'HH24'); END;")
133
+ cursor.bind_param(:hour, Fixnum)
134
+ cursor.bind_param(:date, OraDate)
135
+ HOUR_CHECK_TARGET.each do |i|
136
+ # set date via oracle.
137
+ cursor[:hour] = i
138
+ cursor.exec
139
+ # check OraDate#hour
140
+ assert_equal(i, cursor[:date].hour)
141
+ end
142
+ end
143
+
144
+ def test_set_minute
145
+ cursor = @conn.parse("BEGIN :minute := TO_NUMBER(TO_CHAR(:date, 'MI'), '99'); END;")
146
+ cursor.bind_param(:date, OraDate)
147
+ cursor.bind_param(:minute, Fixnum)
148
+ date = OraDate.new()
149
+ MINUTE_CHECK_TARGET.each do |i|
150
+ # set minute
151
+ date.minute = i
152
+ # check result via oracle.
153
+ cursor[:date] = date
154
+ cursor.exec
155
+ assert_equal(i, cursor[:minute])
156
+ end
157
+ end
158
+
159
+ def test_get_minute
160
+ cursor = @conn.parse("BEGIN :date := TO_DATE(TO_CHAR(:minute, '99'), 'MI'); END;")
161
+ cursor.bind_param(:minute, Fixnum)
162
+ cursor.bind_param(:date, OraDate)
163
+ MINUTE_CHECK_TARGET.each do |i|
164
+ # set date via oracle.
165
+ cursor[:minute] = i
166
+ cursor.exec
167
+ # check OraDate#minute
168
+ assert_equal(i, cursor[:date].minute)
169
+ end
170
+ end
171
+
172
+ def test_set_second
173
+ cursor = @conn.parse("BEGIN :second := TO_NUMBER(TO_CHAR(:date, 'SS'), '99'); END;")
174
+ cursor.bind_param(:date, OraDate)
175
+ cursor.bind_param(:second, Fixnum)
176
+ date = OraDate.new()
177
+ SECOND_CHECK_TARGET.each do |i|
178
+ # set second
179
+ date.second = i
180
+ # check result via oracle.
181
+ cursor[:date] = date
182
+ cursor.exec
183
+ assert_equal(i, cursor[:second])
184
+ end
185
+ end
186
+
187
+ def test_get_second
188
+ cursor = @conn.parse("BEGIN :date := TO_DATE(TO_CHAR(:second, '99'), 'SS'); END;")
189
+ cursor.bind_param(:second, Fixnum)
190
+ cursor.bind_param(:date, OraDate)
191
+ SECOND_CHECK_TARGET.each do |i|
192
+ # set date via oracle.
193
+ cursor[:second] = i
194
+ cursor.exec
195
+ # check OraDate#second
196
+ assert_equal(i, cursor[:date].second)
197
+ end
198
+ end
199
+
200
+ def test_compare
201
+ d1 = OraDate.new(2003,03,15,18,55,35)
202
+ d2 = OraDate.new(2003,03,15,18,55,35)
203
+ assert_equal(d1, d2)
204
+ assert_operator(d1, :<, OraDate.new(2004,03,15,18,55,35))
205
+ assert_operator(d1, :<, OraDate.new(2003,04,15,18,55,35))
206
+ assert_operator(d1, :<, OraDate.new(2003,03,16,18,55,35))
207
+ assert_operator(d1, :<, OraDate.new(2003,03,15,19,55,35))
208
+ assert_operator(d1, :<, OraDate.new(2003,03,15,18,56,35))
209
+ assert_operator(d1, :<, OraDate.new(2003,03,15,18,55,36))
210
+
211
+ assert_operator(OraDate.new(2002,03,15,18,55,35), :<, d1)
212
+ assert_operator(OraDate.new(2003,02,15,18,55,35), :<, d1)
213
+ assert_operator(OraDate.new(2003,03,14,18,55,35), :<, d1)
214
+ assert_operator(OraDate.new(2003,03,15,17,55,35), :<, d1)
215
+ assert_operator(OraDate.new(2003,03,15,18,54,35), :<, d1)
216
+ assert_operator(OraDate.new(2003,03,15,18,55,34), :<, d1)
217
+ end
218
+
219
+ def test_to_time
220
+ year, month, day, hour, minute, second = [2003,03,15,18,55,35]
221
+ dt = OraDate.new(year, month, day, hour, minute, second)
222
+ tm = Time.local(year, month, day, hour, minute, second)
223
+ assert_equal(tm, dt.to_time)
224
+
225
+ # year, month, day, hour, minute, second = [1900,1,1,0,0,0]
226
+ # dt = OraDate.new(year, month, day, hour, minute, second)
227
+ # assert_exception(RangeError) { dt.to_time }
228
+ end
229
+
230
+ def test_to_date
231
+ [[2003,03,15], [1900,1,1], [-4712, 1, 1]].each do |year, month, day|
232
+ odt = OraDate.new(year, month, day)
233
+ rdt = Date.new(year, month, day)
234
+ assert_equal(rdt, odt.to_date)
235
+ end
236
+ end
237
+
238
+ def test_dup
239
+ [[2003,03,15], [1900,1,1], [-4712, 1, 1]].each do |year, month, day|
240
+ dt = OraDate.new(year, month, day)
241
+ assert_equal(dt, dt.dup)
242
+ assert_equal(dt, dt.clone)
243
+ end
244
+ end
245
+
246
+ def test_marshal
247
+ [[2003,03,15], [1900,1,1], [-4712, 1, 1]].each do |year, month, day|
248
+ dt = OraDate.new(year, month, day)
249
+ assert_equal(dt, Marshal.load(Marshal.dump(dt)))
250
+ end
251
+ end
252
+
253
+ def teardown
254
+ @conn.logoff
255
+ end
256
+ end
@@ -0,0 +1,787 @@
1
+ # Low-level API
2
+ require 'oci8'
3
+ require 'test/unit'
4
+ require File.dirname(__FILE__) + '/config'
5
+ require 'yaml'
6
+ require 'bigdecimal'
7
+ require 'rational'
8
+
9
+ class TestOraNumber < Test::Unit::TestCase
10
+
11
+ LARGE_RANGE_VALUES = [
12
+ "12345678901234567890123456789012345678",
13
+ "1234567890123456789012345678901234567",
14
+ "1234567890123456789012345678901234567.8",
15
+ "12.345678901234567890123456789012345678",
16
+ "1.2345678901234567890123456789012345678",
17
+ "1.234567890123456789012345678901234567",
18
+ "0.0000000000000000000000000000000000001",
19
+ "0.000000000000000000000000000000000001",
20
+ "0",
21
+ "2147483647", # max of 32 bit signed value
22
+ "2147483648", # max of 32 bit signed value + 1
23
+ "-2147483648", # min of 32 bit signed value
24
+ "-2147483649", # min of 32 bit signed value - 1
25
+ "9223372036854775807", # max of 64 bit signed value
26
+ "9223372036854775808", # max of 64 bit signed value + 1
27
+ "-9223372036854775808", # min of 64 bit signed value
28
+ "-9223372036854775809", # min of 64 bit signed value - 1
29
+ "-12345678901234567890123456789012345678",
30
+ "-1234567890123456789012345678901234567",
31
+ "-123456789012345678901234567890123456",
32
+ "-1234567890123456789012345678901234567.8",
33
+ "-12.345678901234567890123456789012345678",
34
+ "-1.2345678901234567890123456789012345678",
35
+ "-0.0000000000000000000000000000000000001",
36
+ "-0.000000000000000000000000000000000001",
37
+ "-0.00000000000000000000000000000000001",
38
+ "1",
39
+ "20",
40
+ "300",
41
+ "-1",
42
+ "-20",
43
+ "-300",
44
+ "1.123",
45
+ "12.123",
46
+ "123.123",
47
+ "1.1",
48
+ "1.12",
49
+ "1.123",
50
+ "-1.123",
51
+ "-12.123",
52
+ "-123.123",
53
+ "-1.1",
54
+ "-1.12",
55
+ "-1.123",
56
+ ]
57
+
58
+ SMALL_RANGE_VALUES = [
59
+ "10",
60
+ "3",
61
+ "3.14159265358979323846", # PI
62
+ "2",
63
+ "1.57079632679489661923", # PI/2
64
+ "0.5",
65
+ "0.0000000001",
66
+ "0",
67
+ "-0.0000000001",
68
+ "-0.5",
69
+ "-1.57079632679489661923", # -PI/2
70
+ "-2",
71
+ "-3.14159265358979323846", # -PI
72
+ "-3",
73
+ "-10",
74
+ ]
75
+
76
+ def compare_with_float(values, rettype, proc1, proc2 = nil)
77
+ proc2 = proc1 if proc2.nil?
78
+ values.each do |x|
79
+ expected_val = proc1.call(x.to_f)
80
+ actual_val = proc2.call(OraNumber.new(x))
81
+ assert_kind_of(rettype, actual_val)
82
+ delta = [expected_val.abs * 1.0e-12, 1.0e-14].max
83
+ assert_in_delta(expected_val, actual_val, delta, x)
84
+ end
85
+ end
86
+
87
+ def compare_with_float2(values, proc_args, proc1, proc2 = nil)
88
+ proc2 = proc1 if proc2.nil?
89
+ values.each do |x|
90
+ proc_args.each do |y|
91
+ expected_val = proc1.call(x.to_f, y)
92
+ actual_val = proc2.call(OraNumber.new(x), y)
93
+ begin
94
+ delta = [expected_val.abs * 1.0e-12, 1.0e-14].max
95
+ rescue
96
+ puts '-----------'
97
+ p x
98
+ p y
99
+ p expected_val
100
+ puts '-----------'
101
+ raise $!
102
+ end
103
+ # explicity convert actual_val to a Float to prevent
104
+ # SEGV in OCINumberSub() if the Oracle client vesion
105
+ # is less than 10.2.0.4.
106
+ if defined? ::MiniTest and OCI8.oracle_client_version < OCI8::OracleVersion.new('10.2.0.4')
107
+ actual_val = actual_val.to_f
108
+ end
109
+ assert_in_delta(expected_val, actual_val, delta, x)
110
+ end
111
+ end
112
+ end
113
+
114
+ def test_in_bind
115
+ conn = get_oci8_connection
116
+ begin
117
+ conn.exec("alter session set nls_numeric_characters = '.,'")
118
+ cursor = conn.parse("BEGIN :out := TO_CHAR(:in); END;")
119
+ cursor.bind_param(:out, nil, String, 40)
120
+ cursor.bind_param(:in, OraNumber)
121
+ LARGE_RANGE_VALUES.each do |val|
122
+ cursor[:in] = OraNumber.new(val)
123
+ cursor.exec
124
+ # convert 0.0001 and -0.0001 to .0001 and -.0001 respectively
125
+ val = $1+'.'+$2 if /(-?)0\.(.*)/ =~ val
126
+ assert_equal(val, cursor[:out])
127
+ end
128
+ # Infinity and -Infinity
129
+ ['~', '-~'].each do |val|
130
+ cursor[:in] = OraNumber.new(val)
131
+ cursor.exec
132
+ assert_equal(val, cursor[:out])
133
+ end
134
+ if OCI8::oracle_client_version >= OCI8::ORAVER_10_1
135
+ cursor = conn.parse(<<EOS)
136
+ BEGIN
137
+ IF (:in_oranum = CAST(:in_binary_double AS NUMBER)) THEN
138
+ :result := 'match';
139
+ ELSE
140
+ :result := 'unmatch';
141
+ END IF;
142
+ END;
143
+ EOS
144
+ cursor.bind_param(:in_oranum, nil, OraNumber)
145
+ cursor.bind_param(:in_binary_double, nil, :binary_double)
146
+ cursor.bind_param(:result, nil, String, 7)
147
+ [['~', 1.0/0.0], ['-~', -1.0/0.0]].each do |val|
148
+ cursor[:in_oranum] = OraNumber.new(val[0])
149
+ cursor[:in_binary_double] = val[1]
150
+ cursor.exec
151
+ assert_equal(cursor[:result], 'match')
152
+ end
153
+ end
154
+
155
+ ensure
156
+ conn.logoff
157
+ end
158
+ end
159
+
160
+ def test_out_bind
161
+ conn = get_oci8_connection
162
+ begin
163
+ conn.exec("alter session set nls_numeric_characters = '.,'")
164
+ cursor = conn.parse("BEGIN :out := TO_NUMBER(:in); END;")
165
+ cursor.bind_param(:out, OraNumber)
166
+ cursor.bind_param(:in, nil, String, 40)
167
+ LARGE_RANGE_VALUES.each do |val|
168
+ cursor[:in] = val
169
+ cursor.exec
170
+ assert_equal(OraNumber.new(val), cursor[:out])
171
+ end
172
+ # Infinity and -Infinity
173
+ if OCI8::oracle_client_version >= OCI8::ORAVER_10_1
174
+ cursor = conn.parse("BEGIN :out := CAST(:in AS NUMBER); END;")
175
+ cursor.bind_param(:out, OraNumber)
176
+ cursor.bind_param(:in, nil, :binary_double)
177
+ [['~', 1.0/0.0], ['-~', -1.0/0.0]].each do |val|
178
+ cursor[:in] = val[1]
179
+ cursor.exec
180
+ assert_equal(OraNumber.new(val[0]), cursor[:out])
181
+ end
182
+ end
183
+ ensure
184
+ conn.logoff
185
+ end
186
+ end
187
+
188
+ def test_bind_basic_number_type
189
+ conn = get_oci8_connection
190
+ bind_type = OCI8::BindType::Mapping[:number]
191
+ begin
192
+ OCI8::BindType::Mapping[:number] = OCI8::BindType::BasicNumberType
193
+ assert_kind_of(NilClass, conn.select_one('select CAST(NULL AS NUMBER) from dual')[0])
194
+ assert_kind_of(Integer, conn.select_one('select 0.0 from dual')[0])
195
+ assert_kind_of(Integer, conn.select_one('select 10.0 from dual')[0])
196
+ assert_kind_of(Float, conn.select_one('select 10.1 from dual')[0])
197
+ ensure
198
+ conn.logoff
199
+ OCI8::BindType::Mapping[:number] = bind_type
200
+ end
201
+ end
202
+
203
+ def test_dup
204
+ (LARGE_RANGE_VALUES + ['~', '-~']).each do |x|
205
+ n = OraNumber.new(x)
206
+ assert_equal(n, n.dup)
207
+ assert_equal(n, n.clone)
208
+ end
209
+ end
210
+
211
+ def test_marshal
212
+ (LARGE_RANGE_VALUES + ['~', '-~']).each do |x|
213
+ n = OraNumber.new(x)
214
+ assert_equal(n, Marshal.load(Marshal.dump(n)))
215
+ end
216
+ end
217
+
218
+ def test_yaml
219
+ (LARGE_RANGE_VALUES + ['~', '-~']).each do |x|
220
+ n = OraNumber.new(x)
221
+ assert_equal(n, YAML.load(YAML.dump(n)))
222
+ end
223
+ end
224
+
225
+ # OCI8::Math.acos(x) -> ocinumber
226
+ def test_math_acos
227
+ test_values = []
228
+ -1.0.step(1.0, 0.01) do |n|
229
+ test_values << n
230
+ end
231
+ compare_with_float(test_values, OraNumber,
232
+ Proc.new {|n| Math::acos(n)},
233
+ Proc.new {|n| OCI8::Math::acos(n)})
234
+ end
235
+
236
+ # OCI8::Math.asin(x) -> ocinumber
237
+ def test_math_asin
238
+ test_values = []
239
+ -1.0.step(1.0, 0.01) do |n|
240
+ test_values << n
241
+ end
242
+ compare_with_float(test_values, OraNumber,
243
+ Proc.new {|n| Math::asin(n)},
244
+ Proc.new {|n| OCI8::Math::asin(n)})
245
+ end
246
+
247
+ # OCI8::Math.atan(x) -> ocinumber
248
+ def test_math_atan
249
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
250
+ Proc.new {|n| Math::atan(n)},
251
+ Proc.new {|n| OCI8::Math::atan(n)})
252
+ end
253
+
254
+ # OCI8::Math.atan2(y, x) -> ocinumber
255
+ def test_math_atan2
256
+ # Prior to ruby 1.9.2:
257
+ # Following method calls' return values depend on the underneath C library
258
+ # implementation.
259
+ #
260
+ # Math::atan2(+0.0, +0.0)
261
+ # Math::atan2(-0.0, +0.0)
262
+ # Math::atan2(+0.0, -0.0)
263
+ # Math::atan2(-0.0, -0.0)
264
+ #
265
+ # They are +0.0, -0.0, +PI and -PI respectively as far as I checked them on
266
+ # Windows and Linux.
267
+ #
268
+ # After ruby 1.9.2:
269
+ # They all raise a Math::DomainError exception.
270
+ #
271
+ # In contrast to Math::atan2, OCI8::Math::atan2(0, 0) allways returns 0 because
272
+ # OraNumber doesn't have the difference between +0 and -0.
273
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
274
+ Proc.new {|x, y| (x.to_f == 0 && y.to_f == 0) ? 0 : Math::atan2(x, y.to_f)},
275
+ Proc.new {|x, y| OCI8::Math::atan2(x, y.to_f)})
276
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
277
+ Proc.new {|x, y| (x.to_f == 0 && y.to_f == 0) ? 0 : Math::atan2(y.to_f, x)},
278
+ Proc.new {|x, y| OCI8::Math::atan2(y.to_f, x)})
279
+ end
280
+
281
+ # OCI8::Math.cos(x) -> ocinumber
282
+ def test_math_cos
283
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
284
+ Proc.new {|n| Math::cos(n)},
285
+ Proc.new {|n| OCI8::Math::cos(n)})
286
+ end
287
+
288
+ # OCI8::Math.cosh(x) -> ocinumber
289
+ def test_math_cosh
290
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
291
+ Proc.new {|n| Math::cosh(n)},
292
+ Proc.new {|n| OCI8::Math::cosh(n)})
293
+ end
294
+
295
+ # OCI8::Math.exp(x) -> ocinumber
296
+ def test_exp
297
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
298
+ Proc.new {|n| Math::exp(n)},
299
+ Proc.new {|n| OCI8::Math::exp(n)})
300
+ end
301
+
302
+ # OCI8::Math.log(numeric) -> ocinumber
303
+ # OCI8::Math.log(numeric, base_num) -> ocinumber
304
+ def test_log
305
+ test_values = LARGE_RANGE_VALUES.reject do |x|
306
+ # reject minus and zero values
307
+ x[0,1] == '-' || x == '0'
308
+ end
309
+ compare_with_float(test_values, OraNumber,
310
+ Proc.new {|n| Math::log(n)},
311
+ Proc.new {|n| OCI8::Math::log(n)})
312
+ compare_with_float(test_values, OraNumber,
313
+ Proc.new {|n| Math::log(n)/Math::log(3)},
314
+ Proc.new {|n| OCI8::Math::log(n, 3)})
315
+ end
316
+
317
+ # OCI8::Math.log10(numeric) -> ocinumber
318
+ def test_log10
319
+ test_values = LARGE_RANGE_VALUES.reject do |x|
320
+ # reject minus and zero values
321
+ x[0,1] == '-' || x == '0'
322
+ end
323
+ compare_with_float(test_values, OraNumber,
324
+ Proc.new {|n| Math::log10(n)},
325
+ Proc.new {|n| OCI8::Math::log10(n)})
326
+ end
327
+
328
+ # OCI8::Math.sin(x) -> ocinumber
329
+ def test_math_sin
330
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
331
+ Proc.new {|n| Math::sin(n)},
332
+ Proc.new {|n| OCI8::Math::sin(n)})
333
+ end
334
+
335
+ # OCI8::Math.sinh(x) -> ocinumber
336
+ def test_math_sinh
337
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
338
+ Proc.new {|n| Math::sinh(n)},
339
+ Proc.new {|n| OCI8::Math::sinh(n)})
340
+ end
341
+
342
+ # OCI8::Math.sqrt(numeric) -> ocinumber
343
+ def test_sqrt
344
+ test_values = LARGE_RANGE_VALUES.reject do |x|
345
+ # reject minus values
346
+ x[0,1] == '-'
347
+ end
348
+ compare_with_float(test_values, OraNumber,
349
+ Proc.new {|n| Math::sqrt(n)},
350
+ Proc.new {|n| OCI8::Math::sqrt(n)})
351
+ end
352
+
353
+ # OCI8::Math.tan(x) -> ocinumber
354
+ def test_math_tan
355
+ test_values = SMALL_RANGE_VALUES.reject do |x|
356
+ # reject PI/2 and -PI/2.
357
+ # Those values are +inf and -info
358
+ radian = x.to_f
359
+ (radian.abs - Math::PI/2).abs < 0.000001
360
+ end
361
+ compare_with_float(test_values, OraNumber,
362
+ Proc.new {|n| Math::tan(n)},
363
+ Proc.new {|n| OCI8::Math::tan(n)})
364
+ end
365
+
366
+ # OCI8::Math.tanh() -> ocinumber
367
+ def test_math_tanh
368
+ compare_with_float(SMALL_RANGE_VALUES, OraNumber,
369
+ Proc.new {|n| Math::tanh(n)},
370
+ Proc.new {|n| OCI8::Math::tanh(n)})
371
+ end
372
+
373
+ # onum % other -> onum
374
+ # def test_mod
375
+
376
+ # onum * other -> onum
377
+ def test_mul
378
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
379
+ Proc.new {|x, y| x * y.to_f})
380
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
381
+ Proc.new {|x, y| y.to_f * x})
382
+ end
383
+
384
+ # onum ** other -> onum
385
+ def test_pow
386
+ base_values = SMALL_RANGE_VALUES.reject do |x|
387
+ # reject minus and zero values
388
+ x[0,1] == '-' || x == '0'
389
+ end
390
+ compare_with_float2(base_values, SMALL_RANGE_VALUES,
391
+ Proc.new {|x, y| x ** y.to_f})
392
+ compare_with_float2(SMALL_RANGE_VALUES, base_values,
393
+ Proc.new {|x, y| y.to_f ** x})
394
+ end
395
+
396
+ # onum + other -> onum
397
+ def test_add
398
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
399
+ Proc.new {|x, y| x + y.to_f})
400
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
401
+ Proc.new {|x, y| y.to_f + x})
402
+ end
403
+
404
+ # onum - other -> onum
405
+ def test_minus
406
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
407
+ Proc.new {|x, y| x - y.to_f})
408
+ compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
409
+ Proc.new {|x, y| y.to_f - x})
410
+ end
411
+
412
+ # -ocinumber -> ocinumber
413
+ def test_uminus
414
+ compare_with_float(LARGE_RANGE_VALUES, OraNumber, Proc.new {|n| -n})
415
+ end
416
+
417
+ # onum / other -> onum
418
+ # TODO: test_div
419
+
420
+ # onum <=> other -> -1, 0, +1
421
+ def test_cmp
422
+ assert_equal(-1, 1 <=> OraNumber(2))
423
+ assert_equal(-1, 1.0 <=> OraNumber(2))
424
+ assert_equal(-1, BigDecimal("1") <=> OraNumber(2))
425
+ assert_equal(-1, Rational(1) <=> OraNumber(2))
426
+ assert_equal(0, 2 <=> OraNumber(2))
427
+ assert_equal(0, 2.0 <=> OraNumber(2))
428
+ assert_equal(0, BigDecimal("2") <=> OraNumber(2))
429
+ assert_equal(0, Rational(2) <=> OraNumber(2))
430
+ assert_equal(1, 3 <=> OraNumber(2))
431
+ assert_equal(1, 3.0 <=> OraNumber(2))
432
+ assert_equal(1, BigDecimal("3") <=> OraNumber(2))
433
+ assert_equal(1, Rational(3) <=> OraNumber(2))
434
+ end
435
+
436
+ # onum.abs -> ocinumber
437
+ def test_abs
438
+ compare_with_float(LARGE_RANGE_VALUES, OraNumber, Proc.new {|n| n.abs})
439
+ end
440
+
441
+ # onum.ceil -> integer
442
+ def test_ceil
443
+ compare_with_float(LARGE_RANGE_VALUES, Integer, Proc.new {|n| n.ceil})
444
+ end
445
+
446
+ # onum.floor -> integer
447
+ def test_floor
448
+ compare_with_float(LARGE_RANGE_VALUES, Integer, Proc.new {|n| n.floor})
449
+ end
450
+
451
+ # onum.round -> integer
452
+ # onum.round(decplace) -> onum
453
+ def test_round
454
+ compare_with_float(LARGE_RANGE_VALUES, Integer, Proc.new {|n| n.round})
455
+ compare_with_float(LARGE_RANGE_VALUES, OraNumber,
456
+ Proc.new {|n| (n * 10).round * 0.1},
457
+ Proc.new {|n| n.round(1)})
458
+ compare_with_float(LARGE_RANGE_VALUES, OraNumber,
459
+ Proc.new {|n| (n * 100).round * 0.01},
460
+ Proc.new {|n| n.round(2)})
461
+ compare_with_float(LARGE_RANGE_VALUES, OraNumber,
462
+ Proc.new {|n| (n * 0.1).round * 10},
463
+ Proc.new {|n| n.round(-1)})
464
+ end
465
+
466
+ # onum.round_prec(digits) -> ocinumber
467
+ def test_round_prec
468
+ if OCI8::oracle_client_version >= OCI8::ORAVER_8_1
469
+ # Oracle 8.1 client or upper
470
+ compare_with_float2(LARGE_RANGE_VALUES, [1, 2, 3, 5, 10, 20],
471
+ Proc.new {|x, y|
472
+ return 0.0 if x == 0.0
473
+ factor = 10 ** (Math::log10(x.abs).to_i - y + 1)
474
+ (x / factor).round * factor
475
+ },
476
+ Proc.new {|x, y| x.round_prec(y)})
477
+ else
478
+ # Oracle 8.0 client
479
+ assert_raise NoMethodError do
480
+ OraNumber.new(1).round_prec(1)
481
+ end
482
+ end
483
+ end
484
+
485
+ # onum.shift(fixnum) -> ocinumber
486
+ def test_shift
487
+ if OCI8::oracle_client_version >= OCI8::ORAVER_8_1
488
+ # Oracle 8.1 client or upper
489
+ compare_with_float2(LARGE_RANGE_VALUES, [-5, -4, -3, -1, 0, 1, 2, 3, 4, 5],
490
+ Proc.new {|x, y| x * (10 ** y)},
491
+ Proc.new {|x, y| x.shift(y)})
492
+ else
493
+ # Oracle 8.0 client
494
+ assert_raise NoMethodError do
495
+ OraNumber.new(1).shift(1)
496
+ end
497
+ end
498
+ end
499
+
500
+ # onum.to_char(fmt = nil, nls_params = nil) -> string
501
+ def test_to_char
502
+ onum = OraNumber.new(123.45)
503
+ assert_equal(' 123.4500', onum.to_char('99999.9999'))
504
+ assert_equal(' 0123.4500', onum.to_char('90000.0009'))
505
+ assert_equal(' 00123.4500', onum.to_char('00000.0000'))
506
+ assert_equal('123.45', onum.to_char('FM99999.9999'))
507
+ assert_equal('0123.450', onum.to_char('FM90000.0009'))
508
+ assert_equal('00123.4500', onum.to_char('FM00000.0000'))
509
+ assert_equal(' -123.4500',(-onum).to_char('99999.9999'))
510
+ assert_equal(' -0123.4500',(-onum).to_char('90000.0009'))
511
+ assert_equal('-00123.4500',(-onum).to_char('00000.0000'))
512
+ assert_equal('-123.45', (-onum).to_char('FM99999.9999'))
513
+ assert_equal('-0123.450', (-onum).to_char('FM90000.0009'))
514
+ assert_equal('-00123.4500',(-onum).to_char('FM00000.0000'))
515
+ assert_equal(' 0,123.4500', onum.to_char('0G000D0000', "NLS_NUMERIC_CHARACTERS = '.,'"))
516
+ assert_equal(' 0.123,4500', onum.to_char('0G000D0000', "NLS_NUMERIC_CHARACTERS = ',.'"))
517
+ assert_equal('Ducat123.45', onum.to_char('FML9999.999', "NLS_CURRENCY = 'Ducat'"))
518
+ end
519
+
520
+ # onum.to_f -> float
521
+ def test_to_f
522
+ LARGE_RANGE_VALUES.each do |x|
523
+ expected_val = x.to_f
524
+ actual_val = OraNumber.new(x).to_f
525
+ delta = [expected_val.abs * 1.0e-12, 1.0e-14].max
526
+ assert_in_delta(expected_val, actual_val, delta, x)
527
+ end
528
+ end
529
+
530
+ # onum.to_i -> integer
531
+ def test_to_i
532
+ LARGE_RANGE_VALUES.each do |x|
533
+ expected_val = x.to_i
534
+ actual_val = OraNumber.new(x).to_i
535
+ assert_equal(expected_val, actual_val, x)
536
+ end
537
+ end
538
+
539
+ # onum.to_s -> string
540
+ def test_to_s
541
+ LARGE_RANGE_VALUES.each do |x|
542
+ expected_val = x
543
+ actual_val = OraNumber.new(x).to_s
544
+ assert_equal(expected_val, actual_val, x)
545
+ end
546
+
547
+ conn = get_oci8_connection()
548
+ begin
549
+ cursor = conn.parse('select to_number(:1) from dual')
550
+ cursor.define(1, OraNumber)
551
+ cursor.bind_param(1, nil, String, 200)
552
+ [
553
+ "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # 1E125
554
+ "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # 1E124
555
+ "234567890234567890234567890234567890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
556
+ "23456789023456789023456789023456789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
557
+ "2345678902345678902345678902345678900",
558
+ "234567890234567890234567890234567890",
559
+ "23456789023456789023456789023456789",
560
+ "2345678902345678902345678902345678.9",
561
+ "234567890234567890234567890234567.89",
562
+ "23.456789023456789023456789023456789",
563
+ "2.3456789023456789023456789023456789",
564
+ "0.23456789023456789023456789023456789", # 2.34..snip..E-1
565
+ "0.023456789023456789023456789023456789", # 2.34..snip..E-2
566
+ "0.0023456789023456789023456789023456789", # 2.34..snip..E-3
567
+ "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023456789023456789023456789023456789", # 2.34..snip..E-130
568
+ "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", # 1E-129
569
+ "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", # 1E-130
570
+ ].each do |str|
571
+ cursor[1] = str
572
+ cursor.exec
573
+ onum = cursor.fetch[0]
574
+ assert_equal(str, onum.to_s, "test data: " + str)
575
+
576
+ str = '-' + str
577
+ cursor[1] = str
578
+ cursor.exec
579
+ onum = cursor.fetch[0]
580
+ assert_equal(str, onum.to_s, "test data: " + str)
581
+ end
582
+ ensure
583
+ conn.logoff
584
+ end
585
+ end
586
+
587
+ # onum.truncate -> integer
588
+ # onum.truncate(decplace) -> ocinumber
589
+ # TODO: test_truncate
590
+
591
+ # onum.zero? -> true or false
592
+ def test_zero_p
593
+ LARGE_RANGE_VALUES.each do |x|
594
+ expected_val = x.to_f.zero?
595
+ actual_val = OraNumber.new(x).zero?
596
+ assert_equal(expected_val, actual_val, x)
597
+ end
598
+ end
599
+
600
+ def test_new_from_string
601
+ conn = get_oci8_connection()
602
+ begin
603
+ cursor = conn.parse('select to_number(:1) from dual')
604
+ cursor.define(1, OraNumber)
605
+ cursor.bind_param(1, nil, String, 200)
606
+ [
607
+ "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # 1E125
608
+ "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", # 1E124
609
+ "234567890234567890234567890234567890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
610
+ "23456789023456789023456789023456789000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
611
+ "2345678902345678902345678902345678900",
612
+ "234567890234567890234567890234567890",
613
+ "23456789023456789023456789023456789",
614
+ "2345678902345678902345678902345678.9",
615
+ "234567890234567890234567890234567.89",
616
+ "23.456789023456789023456789023456789",
617
+ "2.3456789023456789023456789023456789",
618
+ "0.23456789023456789023456789023456789", # 2.34..snip..E-1
619
+ "0.023456789023456789023456789023456789", # 2.34..snip..E-2
620
+ "0.0023456789023456789023456789023456789", # 2.34..snip..E-3
621
+ "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023456789023456789023456789023456789", # 2.34..snip..E-130
622
+ "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", # 1E-129
623
+ "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", # 1E-130
624
+
625
+ # leading spaces
626
+ " 123",
627
+ # trailing spaces
628
+ "123 ",
629
+ "123.456 ",
630
+ "123E10 ",
631
+ "123.456E10 ",
632
+ # scientific notation
633
+ "1234567890000e-9",
634
+ "123456789000e-8",
635
+ "123456789e-5",
636
+ "12345.6789e-1",
637
+ "12.3456789e+1",
638
+ "0.0000123456789E7",
639
+ # round to zero
640
+ "1E-131",
641
+ # overflow
642
+ "1E126",
643
+ "10E125",
644
+ "100000000000E115",
645
+ "1E+126",
646
+ # invalid number
647
+ "",
648
+ " ",
649
+ "abc",
650
+ "1E10a",
651
+ "11E10a",
652
+ "1.1.1",
653
+ # round down
654
+ "444444444444444444444444444444444444444444444444440000",
655
+ "44444444444444444444444444444444444444444444444444000",
656
+ "44444444444444444444444444.444444444444444444444444",
657
+ "4444444444444444444444444.4444444444444444444444444",
658
+ "0.000000044444444444444444444444444444444444444444444444444",
659
+ "0.00000044444444444444444444444444444444444444444444444444",
660
+ # round up
661
+ "555555555555555555555555555555555555555555555555550000",
662
+ "55555555555555555555555555555555555555555555555555000",
663
+ "55555555555555555555555555.555555555555555555555555",
664
+ "5555555555555555555555555.5555555555555555555555555",
665
+ "0.000000055555555555555555555555555555555555555555555555555",
666
+ "0.00000055555555555555555555555555555555555555555555555555",
667
+ "999999999999999999999999999999999999999999999999990000",
668
+ "99999999999999999999999999999999999999999999999999000",
669
+ "99999999999999999999999999.999999999999999999999999",
670
+ "9999999999999999999999999.9999999999999999999999999",
671
+ "0.000000099999999999999999999999999999999999999999999999999",
672
+ "0.00000099999999999999999999999999999999999999999999999999",
673
+ # overflow by round up
674
+ "999999999999999999999999999999999999999999999999999999999900000000000000000000000000000000000000000000000000000000000000000000",
675
+ ].each do |str|
676
+ run_test_new_from_string(cursor, str)
677
+ run_test_new_from_string(cursor, '-' + str)
678
+ end
679
+ ensure
680
+ conn.logoff
681
+ end
682
+ end
683
+
684
+ def run_test_new_from_string(cursor, str)
685
+ cursor[1] = str
686
+ onum = nil
687
+ begin
688
+ cursor.exec
689
+ onum = cursor.fetch[0]
690
+ rescue OCIError => oraerr
691
+ begin
692
+ OraNumber.new(str)
693
+ flunk("exception expected but none was thrown. test data: " + str)
694
+ rescue
695
+ assert_equal(oraerr.to_s, $!.to_s, "test data: " + str)
696
+ end
697
+ end
698
+ if onum
699
+ assert_equal(onum.dump, OraNumber.new(str).dump, "test data: " + str)
700
+ end
701
+ end
702
+
703
+ def test_new_from_bigdecimal
704
+ ["+Infinity", "-Infinity", "NaN"].each do |n|
705
+ assert_raise TypeError do
706
+ OraNumber.new(BigDecimal.new(n))
707
+ end
708
+ end
709
+
710
+ LARGE_RANGE_VALUES.each do |val|
711
+ assert_equal(val, OraNumber.new(BigDecimal.new(val)).to_s)
712
+ end
713
+ end
714
+
715
+ def test_new_from_rational
716
+ [
717
+ [Rational(1, 2), "0.5"],
718
+ [Rational(3, 5), "0.6"],
719
+ [Rational(10, 3), "3.33333333333333333333333333333333333333"],
720
+ [Rational(20, 3), "6.66666666666666666666666666666666666667"],
721
+ ].each do |ary|
722
+ assert_equal(ary[1], OraNumber.new(ary[0]).to_s)
723
+ end
724
+ end
725
+
726
+ def test_dump
727
+ conn = get_oci8_connection
728
+ begin
729
+ cursor = conn.parse("select dump(to_number(:1)) from dual")
730
+ cursor.bind_param(1, nil, String, 40)
731
+ LARGE_RANGE_VALUES.each do |val|
732
+ cursor[1] = val
733
+ cursor.exec
734
+ assert_equal(cursor.fetch[0], OraNumber.new(val).dump)
735
+ end
736
+ ensure
737
+ conn.logoff
738
+ end
739
+ LARGE_RANGE_VALUES
740
+ end
741
+
742
+ def test_has_decimal_part
743
+ assert_equal(false, OraNumber(10.0).has_decimal_part?)
744
+ assert_equal(true, OraNumber(10.1).has_decimal_part?)
745
+ end
746
+
747
+ def test_float_conversion_type_ruby
748
+ orig = OCI8.properties[:float_conversion_type]
749
+ conn = get_oci8_connection
750
+ begin
751
+ OCI8.properties[:float_conversion_type] = :ruby
752
+ # Oracle Number -> Ruby Float
753
+ cursor = conn.parse('begin :out := :in; end;')
754
+ cursor.bind_param(:in, nil, String, 50)
755
+ cursor.bind_param(:out, nil, Float)
756
+ LARGE_RANGE_VALUES.each do |n|
757
+ cursor[:in] = n
758
+ cursor.exec
759
+ assert_equal(n.to_f, cursor[:out])
760
+ end
761
+ cursor.close
762
+ # Ruby Float -> Oracle Number
763
+ LARGE_RANGE_VALUES.each do |n|
764
+ float_val = n.to_f
765
+ expected_val = float_val.to_s
766
+ # convert
767
+ if /(-?)(\d).(\d+)e([+-]?\d+)/ =~ expected_val
768
+ sign = $1
769
+ int = $2
770
+ frac = $3
771
+ shift = $4.to_i
772
+ if frac.length <= shift
773
+ expected_val = sign + int + frac + '0' * (shift - frac.length)
774
+ elsif shift < 0
775
+ expected_val = sign + '0.' + '0' * (-shift - 1) + int + frac
776
+ expected_val.gsub!(/0+$/, '')
777
+ end
778
+ end
779
+ expected_val.gsub!(/\.0$/, '')
780
+ assert_equal(expected_val, OraNumber(float_val).to_s, "n = #{n}, float_val.to_s = #{float_val.to_s}")
781
+ end
782
+ ensure
783
+ OCI8.properties[:float_conversion_type] = orig
784
+ conn.logoff
785
+ end
786
+ end
787
+ end