ruby-oci8 2.0.2-x86-mswin32-60 → 2.0.3-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 CHANGED
@@ -1,3 +1,124 @@
1
+ 2009-10-21 KUBO Takehiro <kubo@jiubao.org>
2
+ * NEWS: add changes between 2.0.2 and 2.0.3.
3
+ * VERSION, Makefile: change the version to 2.0.3.
4
+ * ext/oci8/oci8.c: fix typo.
5
+ * ext/oci8/apiwrap.yml: add OCIIntervalFromText() prototype.
6
+
7
+ 2009-10-18 KUBO Takehiro <kubo@jiubao.org>
8
+ * ext/oci8/ocidatetime.c: Add workarounds for Oracle 9.2.0.1.
9
+ * lib/oci8/datetime.rb: Change the unit of OCI8::BindType::IntervalDS
10
+ from day to second. Add OCI8::BindType::IntervalDS.unit and
11
+ OCI8::BindType::IntervalDS.unit=.
12
+ * test/test_datetime.rb: Fix tests for the above changes.
13
+
14
+ 2009-10-17 KUBO Takehiro <kubo@jiubao.org>
15
+ * ext/oci8/oci8.c: Add a workaround for Oracle 9.2.0.1 when clearing
16
+ a client identifier.
17
+ * ext/oci8/oci8lib.c: Fix a segv when canceling a non-blocking
18
+ execution.
19
+ * test_appinfo.rb: Fix temporarily to prevent a segmentation fault
20
+ under Oracle 9.2.0.1.
21
+ * test/test_oci8.rb: Fix temporarily to prevent a segmentation fault
22
+ under Oracle 9.2.0.1. Fix for BigDecimal bundled in ruby 1.8.5.
23
+ * test/test_oranumber.rb: Fix for Oracle 9.2. Comparing float values
24
+ by <=> is too sensitive to use it in tests.
25
+
26
+ 2009-10-06 KUBO Takehiro <kubo@jiubao.org>
27
+ * ext/oci8/ocinumber.c: Add a global function OraNumber(obj) as a
28
+ shortcut of OraNumber.new(obj) as Rational and BigDecimal do.
29
+ Changes the return type of the four rules of arithmetic;
30
+ addition, subtraction, multiplication and division. It was
31
+ OraNumber, but now it depends on the operand.
32
+ * lib/oci8/bindtype.rb: Add OCI8::BindType::BigDecimal and
33
+ OCI8::BindType::Rational. Change the default data type for
34
+ number column which fit neither Integer nor Float from
35
+ OraNumber to BigDecimal.
36
+ * lib/oci8/oci8.rb: Fix for OCI8::BindType::Mapping to accept
37
+ a class name instead of the class object to support
38
+ OCI8::BindType::BigDecimal and OCI8::BindType::Rational without
39
+ requiring 'bigdecimal' and 'rational'.
40
+ * spec/oranumber_spec.rb: Add a spec file for OraNumber arithmetic.
41
+ * test/test_oci8.rb: Add tests for OCI8::BindType::BigDecimal and
42
+ OCI8::BindType::Rational.
43
+
44
+ 2009-10-04 KUBO Takehiro <kubo@jiubao.org>
45
+ * ext/oci8/oci8.c: Add constants missing in Oracle client prior to 10g.
46
+ * ext/oci8/oraconf.rb:
47
+ 1. Fix for ruby 1.8.5 with Oracle 8.x which needs some object
48
+ files to link with.
49
+ (reported by Jayson Cena)
50
+ 2. Revise the error message under the sudo environemnt.
51
+ 3. Print not only error message but also the error backtrace when
52
+ oraconf.rb fails.
53
+ * lib/oci8/object.rb: Fix to accept nil attribute in object type's
54
+ constructors. This works only for simple data types such as number,
55
+ string. But it doesn't for complex types such as object types.
56
+ (requested by Remi Gagnon)
57
+ * spec/object_type_spec.rb: Add a test for object type's constructors.
58
+
59
+ 2009-09-22 KUBO Takehiro <kubo@jiubao.org>
60
+ * lib/oci8/.document, lib/oci8/datetime.rb: 1. Add
61
+ OCI8::BindType.default_timezone and OCI8::BindType.default_timezone=.
62
+ 2. Change the logic to convert to Time and DateTime to adapt DST.
63
+ 3. Use new features of Time class in ruby 1.9.2 if they are available.
64
+ 4. Add rdoc comments.
65
+ * spec/fetch_datetime8_spec.rb, spec/fetch_datetime_spec.rb,
66
+ spec/fetch_time8_spec.rb, spec/fetch_time_spec.rb,
67
+ spec/spec_helper.rb: Add tests for OCI8::BindType::DateTime and
68
+ OCI8::BindType::Time.
69
+
70
+ 2009-09-13 KUBO Takehiro <kubo@jiubao.org>
71
+ * ext/oci8/lob.c, ext/oci8/oci8.h, test/test_clob.rb: Change
72
+ OCI8::LOB#write to accept an object which is not a String and
73
+ doesn't respond to 'to_str' as IO#write does.
74
+ (requested by Christopher Jones)
75
+
76
+ 2009-09-12 KUBO Takehiro <kubo@jiubao.org>
77
+ * ext/oci8/extconf.rb, lib/oci8.rb.in: Fixed for ruby 1.9.2 preview1.
78
+ (pointed by Raimonds Simanovskis)
79
+
80
+ 2009-09-12 KUBO Takehiro <kubo@jiubao.org>
81
+ * ext/oci8/oraconf.rb: Fixed to compile for AIX instant clients.
82
+ (reported by Kazuya Teramoto)
83
+
84
+ 2009-06-09 KUBO Takehiro <kubo@jiubao.org>
85
+ * ext/oci8/oci8lib.c: Change the initial polling interval of
86
+ non-blocking mode for ruby 1.8 from 100 msec to 10 msec, which
87
+ is same with ruby-oci8 1.0.
88
+ * ext/oci8/oci8.c: Change the default setting of non-blocking mode
89
+ for ruby 1.9 to true. Revise rdoc comments.
90
+
91
+ 2009-06-07 KUBO Takehiro <kubo@jiubao.org>
92
+ * ext/oci8/oci8.c: revise rdoc comments.
93
+
94
+ 2009-06-05 KUBO Takehiro <kubo@jiubao.org>
95
+ * Makefile: check rdoc version when making rdoc documentation.
96
+ The rdoc version must be 2.4.
97
+ * ext/oci8/.document, ext/oci8/oci8.c, lib/.document,
98
+ lib/oci8/.document, lib/oci8/oci8.rb: fix rdoc comments a bit.
99
+
100
+ 2009-05-24 KUBO Takehiro <kubo@jiubao.org>
101
+ * ext/oci8/object.c, lib/oci8/datetime.rb, lib/oci8/object.rb:
102
+ add DATE datatype support in object types.
103
+
104
+ 2009-05-19 KUBO Takehiro <kubo@jiubao.org>
105
+ * ext/oci8/bind.c: delete OCI8::BindType::Fixnum.
106
+ * lib/oci8/compat.rb: add OCI8::BindType::Fixnum as an alias
107
+ of OCI8::BindType::Integer.
108
+ * ext/oci8/extconf.rb: change extconf.rb's argument value of
109
+ '--with-oracle-version' to accept dotted version such as
110
+ '9.2.0.'
111
+ * ext/oci8/oraconf.rb: When extconf.rb fails and it is run
112
+ by sudo command, change the error message to notice that
113
+ 'sudo' may unset environment variables.
114
+
115
+ 2009-05-18 KUBO Takehiro <kubo@jiubao.org>
116
+ * ext/oci8/oci8.c: revise rdoc comments for OCI8#ping and
117
+ OCI8#client_identifier=. Add OCI8#module=, OCI8#action= and
118
+ OCI8#client_info.
119
+ * test/test_appinfo.rb: add test cases for OCI8#module=,
120
+ OCI8#action= and OCI8#client_info.
121
+
1
122
  2009-05-17 KUBO Takehiro <kubo@jiubao.org>
2
123
  * NEWS: add changes between 2.0.1 and 2.0.2.
3
124
  * VERSION: change version to 2.0.2.
data/Makefile CHANGED
@@ -1,5 +1,6 @@
1
1
  VERSION = `cat VERSION`
2
2
  RUBY = ruby -w
3
+ RDOC = rdoc
3
4
 
4
5
  all: build
5
6
 
@@ -30,10 +31,16 @@ format_c_source:
30
31
  astyle --options=none --style=linux --indent=spaces=4 --brackets=linux --suffix=none ext/oci8/*.[ch]
31
32
 
32
33
  # internal use only
33
- .PHONY: rdoc
34
+ .PHONY: rdoc check-rdoc-version run-rdoc
34
35
 
35
- rdoc:
36
- $(RUBY) custom-rdoc.rb -o rdoc -U README ext/oci8 lib
36
+ rdoc: check-rdoc-version run-rdoc
37
+
38
+ check-rdoc-version:
39
+ @echo check rdoc version
40
+ @expr match "`$(RDOC) --version`" '^rdoc 2\.4' > /dev/null || (echo 'rdoc version is not 2.4.'; exit 1)
41
+
42
+ run-rdoc:
43
+ TZ= $(RDOC) -o rdoc -c us-ascii --threads=1 -W http://ruby-oci8.rubyforge.org/svn/trunk/ruby-oci8/ ext/oci8 lib
37
44
 
38
45
  dist:
39
46
  -rm -rf ruby-oci8-$(VERSION)
@@ -52,7 +59,7 @@ dist-check: dist
52
59
  #
53
60
  RUBY_18 = c:\ruby
54
61
  RUBY_191 = c:\ruby-1.9.1
55
- GEMPKG = ruby-oci8-2.0.2-x86-mswin32-60.gem
62
+ GEMPKG = ruby-oci8-2.0.3-x86-mswin32-60.gem
56
63
 
57
64
  ext\oci8\oci8lib_18.so:
58
65
  $(RUBY_18)\bin\ruby -r fileutils -e "FileUtils.rm_rf('ruby18')"
data/NEWS CHANGED
@@ -1,3 +1,129 @@
1
+ 2.0.3:
2
+
3
+ * Imcompatible Changes
4
+
5
+ - Number column in a SQL statement
6
+
7
+ Changes the default data type for number column which fit neither
8
+ Integer nor Float from OraNumber to BigDecimal.
9
+
10
+ conn.exec("select 1.0 from dual") do |row|
11
+ p row[0] # => BigDecimal("1") if the ruby-oci8 version is 2.0.3.
12
+ # => OraNumber(1) if the version is 2.0.2.
13
+ end
14
+
15
+ - Priority of OraNumber within numerical types
16
+
17
+ The return types of basic arithmetic operations with other numerical
18
+ types are changed.
19
+
20
+ 2.0.3:
21
+ OraNumber + Integer => OraNumber (OraNumber wins.)
22
+ OraNumber + Float => Float (OraNumber loses.)
23
+ OraNumber + Rational => Rational (OraNumber loses.)
24
+ OraNumber + BigDecimal => BigDecimal (OraNumber loses.)
25
+
26
+ 2.0.2:
27
+ OraNumber + Integer => OraNumber (OraNumber wins always.)
28
+ OraNumber + Float => OraNumber
29
+ OraNumber + Rational => OraNumber
30
+ OraNumber + BigDecimal => OraNumber
31
+
32
+ - Interval day to second
33
+
34
+ The retrived value of Oracle data type "interval day to second"
35
+ was changed from the number of days as a Rational to the number
36
+ of seconds as a Float by default.
37
+ Use OCI8::BindType::IntervalDS.unit = :day to make it compatible
38
+ with the previous versions.
39
+
40
+ conn.exec("select to_dsinterval('0 00:00:01') from dual") do |row|
41
+ p row[0] # => 1.0 if the version is 2.0.3 and
42
+ # OCI8::BindType::IntervalDS.unit is :second.
43
+ # => (1/86400) if the version is 2.0.3 and
44
+ # OCI8::BindType::IntervalDS.unit is :day or
45
+ # the version is 2.0.2.
46
+ end
47
+
48
+ - Date, timestamp, timestamp with time zone data types and ruby 1.9.2
49
+
50
+ These data types are retrived always as Time values when the
51
+ ruby version is 1.9.2 because the Time class is enhanced to
52
+ represent any time zone and is free from year 2038 problem.
53
+
54
+ Prior to ruby 1.9.2, if the time cannot be represented by
55
+ Unix time or the time zone is neither utc nor local, they are
56
+ retrived as DateTime values.
57
+
58
+ - Non-blocking mode and ruby 1.9
59
+
60
+ non-blocking mode is enabled by default when the ruby is 1.9.
61
+
62
+ * New Features
63
+
64
+ - BigDecimal and Rational are availabe as bind values.
65
+
66
+ - New methods OCI8#module=, OCI8#action= and OCI8#client_info= are added.
67
+
68
+ These methods change the module name, the action name and the client_info
69
+ in the current session respectively.
70
+
71
+ After Oracle 10g client, these don't perform network round trips.
72
+ The change is reflected to the server by the next round trip such as
73
+ OCI8#exec, OCI8#ping, etc.
74
+
75
+ Prior to Oracle 10g client, these call PL/SQL functions such as
76
+ DBMS_APPLICATION_INFO.SET_MODULE, DBMS_APPLICATION_INFO.SET_ACTION,
77
+ and DBMS_APPLICATION_INFO.SET_CLIENT_INFO internally.
78
+ The change is reflected immediately by a network round trip.
79
+
80
+ - OCI8::BindType.default_timezone
81
+
82
+ The default time zone of Time or DateTime values.
83
+ This parameter is used only when
84
+ (1) date values are fetched and the Oracle client version is 8.x
85
+ or
86
+ (2) object types have date data type attributes.
87
+
88
+ Note that if the Oracle client version is 9i or upper, the time
89
+ zone is determined by the session time zone. The default value
90
+ is local time zone. You can change it to GMT by executing the
91
+ following SQL statement for each connection.
92
+
93
+ alter session set time_zone = '00:00'
94
+
95
+ * Other specification changes
96
+
97
+ - Add a global function OraNumber(obj) as a shortcut of OraNumber.new(obj)
98
+ as Rational and BigDecimal do.
99
+
100
+ - Fix to accept nil attribute in object type's
101
+ constructors. This works only for simple data types such as number,
102
+ string. But it doesn't for complex types such as object types.
103
+ (requested by Remi Gagnon)
104
+
105
+ - add DATE datatype support in object types.
106
+
107
+ - Change OCI8::LOB#write to accept an object which is not a String and
108
+ doesn't respond to 'to_str' as IO#write does.
109
+ (requested by Christopher Jones)
110
+
111
+ - Change the initial polling interval of
112
+ non-blocking mode for ruby 1.8 from 100 msec to 10 msec, which
113
+ is same with ruby-oci8 1.0.
114
+
115
+ * Fixed installation issues.
116
+
117
+ - Fix oraconf.rb for ruby 1.8.5 with Oracle 8.x which needs some object
118
+ files to link with.
119
+ (reported by Jayson Cena)
120
+
121
+ - Fix oraconf.rb for ruby 1.9.2 preview1.
122
+ (pointed by Raimonds Simanovskis)
123
+
124
+ - Fix oraconf.rb to compile for AIX instant clients.
125
+ (reported by Kazuya Teramoto)
126
+
1
127
  2.0.2:
2
128
 
3
129
  * add new methods
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.2
1
+ 2.0.3
data/lib/.document CHANGED
@@ -1,2 +1 @@
1
1
  oci8
2
- oci8.rb
data/lib/oci8.rb CHANGED
@@ -19,7 +19,7 @@ if RUBY_PLATFORM =~ /cygwin/
19
19
  end
20
20
 
21
21
  case RUBY_VERSION
22
- when /^1\.9\.1/
22
+ when /^1\.9/
23
23
  require 'oci8lib_191'
24
24
  when /^1\.8/
25
25
  require 'oci8lib_18'
@@ -77,6 +77,6 @@ require 'oci8/compat.rb'
77
77
  require 'oci8/object.rb'
78
78
 
79
79
  class OCI8
80
- VERSION = '2.0.2'
80
+ VERSION = '2.0.3'
81
81
  CLIENT_VERSION = '1020'
82
82
  end
data/lib/oci8.rb.in CHANGED
@@ -19,7 +19,7 @@ if RUBY_PLATFORM =~ /cygwin/
19
19
  end
20
20
 
21
21
  case RUBY_VERSION
22
- when /^1\.9\.1/
22
+ when /^1\.9/
23
23
  require 'oci8lib_191'
24
24
  when /^1\.8/
25
25
  require 'oci8lib_18'
data/lib/oci8/.document CHANGED
@@ -1,5 +1,5 @@
1
- oci8.rb
1
+ datetime.rb
2
2
  object.rb
3
3
  metadata.rb
4
4
  oracle_version.rb
5
-
5
+ oci8.rb
data/lib/oci8/bindtype.rb CHANGED
@@ -24,6 +24,28 @@ class OCI8
24
24
  end
25
25
  end
26
26
 
27
+ class BigDecimal < OCI8::BindType::OraNumber
28
+ @@bigdecimal_is_required = false
29
+ def get()
30
+ unless @@bigdecimal_is_required
31
+ require 'bigdecimal'
32
+ @@bigdecimal_is_required = true
33
+ end
34
+ (val = super()) && val.to_d
35
+ end
36
+ end
37
+
38
+ class Rational < OCI8::BindType::OraNumber
39
+ @@rational_is_required = false
40
+ def get()
41
+ unless @@rational_is_required
42
+ require 'rational'
43
+ @@rational_is_required = true
44
+ end
45
+ (val = super()) && val.to_r
46
+ end
47
+ end
48
+
27
49
  # get/set Number (for OCI8::SQLT_NUM)
28
50
  class Number
29
51
  def self.create(con, val, param, max_array_size)
@@ -54,8 +76,8 @@ class OCI8
54
76
  if precision < 15 # the precision of double.
55
77
  klass = OCI8::BindType::Float
56
78
  else
57
- # use BigDecimal instead?
58
- klass = OCI8::BindType::OraNumber
79
+ # use BigDecimal instead
80
+ klass = OCI8::BindType::BigDecimal
59
81
  end
60
82
  end
61
83
  klass.new(con, val, nil, max_array_size)
@@ -156,6 +178,8 @@ end
156
178
  # bind or explicitly define
157
179
  OCI8::BindType::Mapping[String] = OCI8::BindType::String
158
180
  OCI8::BindType::Mapping[OraNumber] = OCI8::BindType::OraNumber
181
+ OCI8::BindType::Mapping['BigDecimal'] = OCI8::BindType::BigDecimal
182
+ OCI8::BindType::Mapping['Rational'] = OCI8::BindType::Rational
159
183
  OCI8::BindType::Mapping[Fixnum] = OCI8::BindType::Integer
160
184
  OCI8::BindType::Mapping[Float] = OCI8::BindType::Float
161
185
  OCI8::BindType::Mapping[Integer] = OCI8::BindType::Integer
@@ -263,9 +287,9 @@ OCI8::BindType::Mapping[:number] = OCI8::BindType::Number
263
287
  # datatypes that have no explicit setting of their precision
264
288
  # and scale.
265
289
  #
266
- # The default mapping is Float for ruby-oci8 1.0. It is OraNumber
267
- # for ruby-oci8 2.0.
268
- OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::OraNumber
290
+ # The default mapping is Float for ruby-oci8 1.0, OraNumber for 2.0.0 ~ 2.0.2,
291
+ # BigDecimal for 2.0.3 ~.
292
+ OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::BigDecimal
269
293
 
270
294
  # mapping for number without precision and scale.
271
295
  #
@@ -276,9 +300,9 @@ OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::OraNumber
276
300
  # note: This is available only on Oracle 9.2.0.3 or above.
277
301
  # see: Oracle 9.2.0.x Patch Set Notes.
278
302
  #
279
- # The default mapping is Float for ruby-oci8 1.0. It is OraNumber
280
- # for ruby-oci8 2.0.
281
- OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::OraNumber
303
+ # The default mapping is Float for ruby-oci8 1.0, OraNumber for 2.0.0 ~ 2.0.2,
304
+ # BigDecimal for 2.0.3 ~.
305
+ OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::BigDecimal
282
306
 
283
307
  if defined? OCI8::BindType::BinaryDouble
284
308
  OCI8::BindType::Mapping[:binary_float] = OCI8::BindType::BinaryDouble
data/lib/oci8/compat.rb CHANGED
@@ -105,4 +105,9 @@ class OCI8
105
105
  # add alias compatible with 'Oracle7 Module for Ruby'.
106
106
  alias getColNames get_col_names
107
107
  end
108
+
109
+ module BindType
110
+ # alias to Integer for compatibility with ruby-oci8 1.0.
111
+ Fixnum = Integer
112
+ end
108
113
  end
data/lib/oci8/datetime.rb CHANGED
@@ -4,23 +4,44 @@ class OCI8
4
4
 
5
5
  module BindType
6
6
 
7
+ # call-seq:
8
+ # OCI8::BindType.default_timezone -> :local or :utc
9
+ #
10
+ # Returns the default time zone when using Oracle 8.x client.
11
+ # The value is unused when using Oracle 9i or upper client.
12
+ #
13
+ # See also: OCI8::BindType::Time
14
+ def self.default_timezone
15
+ OCI8::BindType::Util.default_timezone
16
+ end
17
+
18
+ # call-seq:
19
+ # OCI8::BindType.default_timezone = :local or :utc
20
+ #
21
+ # Sets the default time zone when using Oracle 8.x client.
22
+ # The value is unused when using Oracle 9i or upper client.
23
+ #
24
+ # See also: OCI8::BindType::Time
25
+ def self.default_timezone=(tz)
26
+ OCI8::BindType::Util.default_timezone = tz
27
+ end
28
+
7
29
  module Util # :nodoc:
8
30
 
9
31
  @@datetime_fsec_base = (1 / ::DateTime.parse('0001-01-01 00:00:00.000000001').sec_fraction).to_i
10
- @@time_offset = ::Time.now.utc_offset
11
- @@datetime_offset = ::DateTime.now.offset
12
32
 
13
33
  @@default_timezone = :local
34
+ begin
35
+ Time.new(2001, 1, 1, 0, 0, 0, '+00:00')
36
+ @@time_new_accepts_timezone = true # after ruby 1.9.2
37
+ rescue ArgumentError
38
+ @@time_new_accepts_timezone = false # prior to ruby 1.9.2
39
+ end
40
+
14
41
  def self.default_timezone
15
42
  @@default_timezone
16
43
  end
17
44
 
18
- # Determines default timezone of Time and DateTime retrived from Oracle.
19
- # This accepts :local or :utc. The default is :local.
20
- #
21
- # This parameter is used when both or either of Oracle server and client
22
- # version is Oracle 8i or lower. If both versions are Oracle 9i or upper,
23
- # the default timezone is determined by the session timezone.
24
45
  def self.default_timezone=(tz)
25
46
  if tz != :local and tz != :utc
26
47
  raise ArgumentError, "expected :local or :utc but #{tz}"
@@ -31,6 +52,8 @@ class OCI8
31
52
  private
32
53
 
33
54
  def datetime_to_array(val, full)
55
+ return nil if val.nil?
56
+
34
57
  # year
35
58
  year = val.year
36
59
  # month
@@ -100,9 +123,16 @@ class OCI8
100
123
  end
101
124
 
102
125
  def ocidate_to_datetime(ary)
126
+ return nil if ary.nil?
127
+
103
128
  year, month, day, hour, minute, sec = ary
104
129
  if @@default_timezone == :local
105
- offset = @@datetime_offset
130
+ if ::DateTime.respond_to? :local_offset
131
+ offset = ::DateTime.local_offset # Use a method defined by active support.
132
+ else
133
+ # Do as active support does.
134
+ offset = ::Time.local(2007).utc_offset.to_r / 86400
135
+ end
106
136
  else
107
137
  offset = 0
108
138
  end
@@ -110,8 +140,10 @@ class OCI8
110
140
  end
111
141
 
112
142
  def ocidate_to_time(ary)
143
+ return nil if ary.nil?
144
+
113
145
  year, month, day, hour, minute, sec = ary
114
- if year >= 139
146
+ if @@time_new_accepts_timezone || year >= 139 || year < 0
115
147
  begin
116
148
  return ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
117
149
  rescue StandardError
@@ -123,6 +155,8 @@ class OCI8
123
155
  if OCI8.oracle_client_version >= ORAVER_9_0
124
156
 
125
157
  def ocitimestamp_to_datetime(ary)
158
+ return nil if ary.nil?
159
+
126
160
  year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
127
161
  if sec >= 59 and fsec != 0
128
162
  # convert to a DateTime via a String as a last resort.
@@ -143,168 +177,159 @@ class OCI8
143
177
  end
144
178
  end
145
179
 
146
- def ocitimestamp_to_time(ary)
147
- year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
180
+ if @@time_new_accepts_timezone
181
+
182
+ # after ruby 1.9.2
183
+ def ocitimestamp_to_time(ary)
184
+ return nil if ary.nil?
148
185
 
149
- if tz_hour == 0 and tz_min == 0
150
- timezone = :utc
151
- elsif @@time_offset == tz_hour * 3600 + tz_min * 60
152
- timezone = :local
186
+ year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
187
+
188
+ sec += fsec / Rational(1000000000)
189
+ utc_offset = tz_hour * 3600 + tz_min * 60
190
+ return ::Time.new(year, month, day, hour, minute, sec, utc_offset)
153
191
  end
154
- if timezone and year >= 139
155
- begin
156
- # Ruby 1.9 Time class's resolution is nanosecond.
157
- # But the last argument type is millisecond.
158
- # 'fsec' is converted to a Float to pass sub-millisecond part.
159
- return ::Time.send(timezone, year, month, day, hour, minute, sec, fsec / 1000.0)
160
- rescue StandardError
192
+
193
+ else
194
+
195
+ # prior to ruby 1.9.2
196
+ def ocitimestamp_to_time(ary)
197
+ return nil if ary.nil?
198
+
199
+ year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
200
+
201
+ if year >= 139 || year < 0
202
+ begin
203
+ if tz_hour == 0 and tz_min == 0
204
+ return ::Time.utc(year, month, day, hour, minute, sec, fsec / Rational(1000))
205
+ else
206
+ tm = ::Time.local(year, month, day, hour, minute, sec, fsec / Rational(1000))
207
+ return tm if tm.utc_offset == tz_hour * 3600 + tz_min * 60
208
+ end
209
+ rescue StandardError
210
+ end
161
211
  end
212
+ ocitimestamp_to_datetime(ary)
162
213
  end
163
- ocitimestamp_to_datetime(ary)
214
+
164
215
  end
165
216
  end
166
217
  end
167
218
 
168
- class DateTimeViaOCIDate < OCI8::BindType::OCIDate
219
+ class DateTimeViaOCIDate < OCI8::BindType::OCIDate # :nodoc:
169
220
  include OCI8::BindType::Util
170
221
 
171
222
  def set(val) # :nodoc:
172
- val &&= datetime_to_array(val, false)
173
- super(val)
223
+ super(datetime_to_array(val, false))
174
224
  end
175
225
 
176
226
  def get() # :nodoc:
177
- val = super()
178
- val ? ocidate_to_datetime(val) : nil
227
+ ocidate_to_datetime(super())
179
228
  end
180
229
  end
181
230
 
182
- class TimeViaOCIDate < OCI8::BindType::OCIDate
231
+ class TimeViaOCIDate < OCI8::BindType::OCIDate # :nodoc:
183
232
  include OCI8::BindType::Util
184
233
 
185
234
  def set(val) # :nodoc:
186
- val &&= datetime_to_array(val, false)
187
- super(val)
235
+ super(datetime_to_array(val, false))
188
236
  end
189
237
 
190
238
  def get() # :nodoc:
191
- val = super()
192
- val ? ocidate_to_time(val) : nil
239
+ ocidate_to_time(super())
193
240
  end
194
241
  end
195
242
 
196
243
  if OCI8.oracle_client_version >= ORAVER_9_0
197
- class DateTimeViaOCITimestamp < OCI8::BindType::OCITimestamp
244
+ class DateTimeViaOCITimestamp < OCI8::BindType::OCITimestamp # :nodoc:
198
245
  include OCI8::BindType::Util
199
246
 
200
247
  def set(val) # :nodoc:
201
- val &&= datetime_to_array(val, true)
202
- super(val)
248
+ super(datetime_to_array(val, true))
203
249
  end
204
250
 
205
251
  def get() # :nodoc:
206
- val = super()
207
- val ? ocitimestamp_to_datetime(val) : nil
252
+ ocitimestamp_to_datetime(super())
208
253
  end
209
254
  end
210
255
 
211
- class TimeViaOCITimestamp < OCI8::BindType::OCITimestamp
256
+ class TimeViaOCITimestamp < OCI8::BindType::OCITimestamp # :nodoc:
212
257
  include OCI8::BindType::Util
213
258
 
214
259
  def set(val) # :nodoc:
215
- val &&= datetime_to_array(val, true)
216
- super(val)
260
+ super(datetime_to_array(val, true))
217
261
  end
218
262
 
219
263
  def get() # :nodoc:
220
- val = super()
221
- val ? ocitimestamp_to_time(val) : nil
264
+ ocitimestamp_to_time(super())
222
265
  end
223
266
  end
224
267
  end
225
268
 
226
-
227
269
  #--
228
270
  # OCI8::BindType::DateTime
229
271
  #++
230
- # This is a helper class to bind ruby's
231
- # DateTime[http://www.ruby-doc.org/core/classes/DateTime.html]
232
- # object as Oracle's <tt>TIMESTAMP WITH TIME ZONE</tt> datatype.
272
+ # This is a helper class to select or bind Oracle data types such as
273
+ # <tt>DATE</tt>, <tt>TIMESTAMP</tt>, <tt>TIMESTAMP WITH TIME ZONE</tt>
274
+ # and <tt>TIMESTAMP WITH LOCAL TIME ZONE</tt>. The retrieved value
275
+ # is a \DateTime.
276
+ #
277
+ # === How to select \DataTime values.
278
+ #
279
+ # <tt>DATE</tt>, <tt>TIMESTAMP</tt>, <tt>TIMESTAMP WITH TIME ZONE</tt>
280
+ # and <tt>TIMESTAMP WITH LOCAL TIME ZONE</tt> are selected as a \Time
281
+ # by default. You change the behaviour by explicitly calling
282
+ # OCI8::Cursor#define as follows:
283
+ #
284
+ # cursor = conn.parse("SELECT hiredate FROM emp")
285
+ # cursor.define(1, nil, DateTime)
286
+ # cursor.exec()
287
+ #
288
+ # Otherwise, you can change the default mapping for all queries.
233
289
  #
234
- # == Select
290
+ # # Changes the mapping for DATE
291
+ # OCI8::BindType::Mapping[OCI8::SQLT_DAT] = OCI8::BindType::DateTime
292
+ #
293
+ # # Changes the mapping for TIMESTAMP
294
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP] = OCI8::BindType::DateTime
295
+ #
296
+ # # Changes the mapping for TIMESTAMP WITH TIME ZONE
297
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_TZ] = OCI8::BindType::DateTime
298
+ #
299
+ # # Changes the mapping for TIMESTAMP WITH LOCAL TIME ZONE
300
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_LTZ] = OCI8::BindType::DateTime
235
301
  #
236
- # The fetched value for a <tt>DATE</tt>, <tt>TIMESTAMP</tt>, <tt>TIMESTAMP WITH
237
- # TIME ZONE</tt> or <tt>TIMESTAMP WITH LOCAL TIME ZONE</tt> column
238
- # is a DateTime[http://www.ruby-doc.org/core/classes/DateTime.html].
239
- # The time zone part is a session time zone if the Oracle datatype doesn't
240
- # have time zone information. The session time zone is the client machine's
241
- # time zone by default.
302
+ # === Note for default time zone
242
303
  #
243
- # You can change the session time zone by executing the following SQL.
304
+ # The retrieved value's time zone is determined by the session time zone
305
+ # if its data type is <tt>DATE</tt>, <tt>TIMESTAMP</tt> or <tt>TIMESTAMP
306
+ # WITH LOCAL TIME ZONE</tt>.
307
+ #
308
+ # The session time zone is same with local machine's by default.
309
+ # It is changed by the following SQL.
244
310
  #
245
311
  # ALTER SESSION SET TIME_ZONE='-05:00'
246
312
  #
247
- # == Bind
248
- #
249
- # To bind a DateTime[http://www.ruby-doc.org/core/classes/DateTime.html]
250
- # value implicitly:
251
- #
252
- # conn.exec("INSERT INTO lunar_landings(ship_name, landing_time) VALUES(:1, :2)",
253
- # 'Apollo 11',
254
- # DateTime.parse('1969-7-20 20:17:40 00:00'))
255
- #
256
- # The bind variable <code>:2</code> is bound as <tt>TIMESTAMP WITH TIME ZONE</tt> on Oracle.
257
- #
258
- # To bind explicitly:
259
- #
260
- # cursor = conn.exec("INSERT INTO lunar_landings(ship_name, landing_time) VALUES(:1, :2)")
261
- # cursor.bind_param(':1', nil, String, 60)
262
- # cursor.bind_param(':2', nil, DateTime)
263
- # [['Apollo 11', DateTime.parse('1969-07-20 20:17:40 00:00'))],
264
- # ['Apollo 12', DateTime.parse('1969-11-19 06:54:35 00:00'))],
265
- # ['Apollo 14', DateTime.parse('1971-02-05 09:18:11 00:00'))],
266
- # ['Apollo 15', DateTime.parse('1971-07-30 22:16:29 00:00'))],
267
- # ['Apollo 16', DateTime.parse('1972-04-21 02:23:35 00:00'))],
268
- # ['Apollo 17', DateTime.parse('1972-12-11 19:54:57 00:00'))]
269
- # ].each do |ship_name, landing_time|
270
- # cursor[':1'] = ship_name
271
- # cursor[':2'] = landing_time
272
- # cursor.exec
273
- # end
274
- # cursor.close
275
- #
276
- # On setting a object to the bind variable, you can use any object
277
- # which has at least three instance methods _year_, _mon_ (or _month_)
278
- # and _mday_ (or _day_). If the object responses to _hour_, _min_,
279
- # _sec_ or _sec_fraction_, the responsed values are used for hour,
280
- # minute, second or fraction of a second respectively.
281
- # If not, zeros are set. If the object responses to _offset_ or
282
- # _utc_offset_, it is used for time zone. If not, the session time
283
- # zone is used.
284
- #
285
- # The acceptable value are listed below.
286
- # _year_:: -4712 to 9999 [excluding year 0]
287
- # _mon_ (or _month_):: 0 to 12
288
- # _mday_ (or _day_):: 0 to 31 [depends on the month]
289
- # _hour_:: 0 to 23
290
- # _min_:: 0 to 59
291
- # _sec_:: 0 to 59
292
- # _sec_fraction_:: 0 to (999_999_999.to_r / (24*60*60* 1_000_000_000)) [999,999,999 nanoseconds]
293
- # _offset_:: (-12.to_r / 24) to (14.to_r / 24) [-12:00 to +14:00]
294
- # _utc_offset_:: -12*3600 <= utc_offset <= 24*3600 [-12:00 to +14:00]
295
- #
296
- # The output value of the bind varible is always a
297
- # DateTime[http://www.ruby-doc.org/core/classes/DateTime.html].
298
- #
299
- # cursor = conn.exec("BEGIN :ts := current_timestamp; END")
300
- # cursor.bind_param(:ts, nil, DateTime)
301
- # cursor.exec
302
- # cursor[:ts] # => a DateTime.
303
- # cursor.close
313
+ # === Note for Oracle 8.x client
314
+ #
315
+ # Timestamp data types and session time zone are new features in
316
+ # Oracle 9i. This class is available only to fetch or bind <tt>DATE</tt>
317
+ # when using Oracle 8.x client.
318
+ #
319
+ # The retrieved value's time zone is determined not by the session
320
+ # time zone, but by the OCI8::BindType.default_timezone
321
+ # The time zone can be changed as follows:
322
+ #
323
+ # OCI8::BindType.default_timezone = :local
324
+ # # or
325
+ # OCI8::BindType.default_timezone = :utc
326
+ #
327
+ # If you are in the regions where daylight saving time is adopted,
328
+ # you should use OCI8::BindType::Time.
304
329
  #
305
330
  class DateTime
306
331
  if OCI8.oracle_client_version >= ORAVER_9_0
307
- def self.create(con, val, param, max_array_size)
332
+ def self.create(con, val, param, max_array_size) # :nodoc:
308
333
  if true # TODO: check Oracle server version
309
334
  DateTimeViaOCITimestamp.new(con, val, param, max_array_size)
310
335
  else
@@ -312,15 +337,78 @@ class OCI8
312
337
  end
313
338
  end
314
339
  else
315
- def self.create(con, val, param, max_array_size)
340
+ def self.create(con, val, param, max_array_size) # :nodoc:
316
341
  DateTimeViaOCIDate.new(con, val, param, max_array_size)
317
342
  end
318
343
  end
319
344
  end
320
345
 
346
+ #--
347
+ # OCI8::BindType::Time
348
+ #++
349
+ # This is a helper class to select or bind Oracle data types such as
350
+ # <tt>DATE</tt>, <tt>TIMESTAMP</tt>, <tt>TIMESTAMP WITH TIME ZONE</tt>
351
+ # and <tt>TIMESTAMP WITH LOCAL TIME ZONE</tt>. The retrieved value
352
+ # is a \Time.
353
+ #
354
+ # === How to select \Time values.
355
+ #
356
+ # <tt>DATE</tt>, <tt>TIMESTAMP</tt>, <tt>TIMESTAMP WITH TIME ZONE</tt>
357
+ # and <tt>TIMESTAMP WITH LOCAL TIME ZONE</tt> are selected as a \Time
358
+ # by default. If the default behaviour is changed, you can select it
359
+ # as a \Time by explicitly calling OCI8::Cursor#define as follows:
360
+ #
361
+ # cursor = conn.parse("SELECT hiredate FROM emp")
362
+ # cursor.define(1, nil, Time)
363
+ # cursor.exec()
364
+ #
365
+ # === Note for ruby prior to 1.9.2
366
+ #
367
+ # If the retrieved value cannot be represented by \Time, it become
368
+ # a \DateTime. The fallback is done only when the ruby is before 1.9.2
369
+ # and one of the following conditions are met.
370
+ # - The timezone part is neither local nor utc.
371
+ # - The time is out of the time_t[http://en.wikipedia.org/wiki/Time_t].
372
+ #
373
+ # If the retrieved value has the precision of fractional second more
374
+ # than 6, the fractional second is truncated to microsecond, which
375
+ # is the precision of standard \Time class.
376
+ #
377
+ # To avoid this fractional second truncation:
378
+ # - Upgrade to ruby 1.9.2, whose \Time precision is nanosecond.
379
+ # - Otherwise, change the defalt mapping to use \DateTime as follows.
380
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP] = OCI8::BindType::DateTime
381
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_TZ] = OCI8::BindType::DateTime
382
+ # OCI8::BindType::Mapping[OCI8::SQLT_TIMESTAMP_LTZ] = OCI8::BindType::DateTime
383
+ #
384
+ # === Note for default time zone
385
+ #
386
+ # The retrieved value's time zone is determined by the session time zone
387
+ # if its data type is <tt>DATE</tt>, <tt>TIMESTAMP</tt> or <tt>TIMESTAMP
388
+ # WITH LOCAL TIME ZONE</tt>.
389
+ #
390
+ # The session time zone is same with local machine's by default.
391
+ # It is changed by the following SQL.
392
+ #
393
+ # ALTER SESSION SET TIME_ZONE='-05:00'
394
+ #
395
+ # === Note for Oracle 8.x client
396
+ #
397
+ # Timestamp data types and session time zone are new features in
398
+ # Oracle 9i. This class is available only to fetch or bind <tt>DATE</tt>
399
+ # when using Oracle 8.x client.
400
+ #
401
+ # The retrieved value's time zone is determined not by the session
402
+ # time zone, but by the OCI8::BindType.default_timezone
403
+ # The time zone can be changed as follows:
404
+ #
405
+ # OCI8::BindType.default_timezone = :local
406
+ # # or
407
+ # OCI8::BindType.default_timezone = :utc
408
+ #
321
409
  class Time
322
410
  if OCI8.oracle_client_version >= ORAVER_9_0
323
- def self.create(con, val, param, max_array_size)
411
+ def self.create(con, val, param, max_array_size) # :nodoc:
324
412
  if true # TODO: check Oracle server version
325
413
  TimeViaOCITimestamp.new(con, val, param, max_array_size)
326
414
  else
@@ -328,7 +416,7 @@ class OCI8
328
416
  end
329
417
  end
330
418
  else
331
- def self.create(con, val, param, max_array_size)
419
+ def self.create(con, val, param, max_array_size) # :nodoc:
332
420
  TimeViaOCIDate.new(con, val, param, max_array_size)
333
421
  end
334
422
  end
@@ -339,20 +427,26 @@ class OCI8
339
427
  # OCI8::BindType::IntervalYM
340
428
  #++
341
429
  #
342
- # This is a helper class to bind ruby's
343
- # Integer[http://www.ruby-doc.org/core/classes/Integer.html]
344
- # object as Oracle's <tt>INTERVAL YEAR TO MONTH</tt> datatype.
430
+ # This is a helper class to select or bind Oracle data type
431
+ # <tt>INTERVAL YEAR TO MONTH</tt>. The retrieved value is
432
+ # the number of months between two timestamps.
433
+ #
434
+ # The value can be applied to \DateTime#>> to shift months.
435
+ # It can be applied to \Time#months_since if activisupport has
436
+ # been loaded.
437
+ #
438
+ # === How to select <tt>INTERVAL YEAR TO MONTH</tt>
345
439
  #
346
- # == Select
440
+ # <tt>INTERVAL YEAR TO MONTH</tt> is selected as an Integer.
347
441
  #
348
- # The fetched value for a <tt>INTERVAL YEAR TO MONTH</tt> column
349
- # is an Integer[http://www.ruby-doc.org/core/classes/Integer.html]
350
- # which means the months between two timestamps.
442
+ # conn.exec("select (current_timestamp - hiredate) year to month from emp") do |hired_months|
443
+ # puts "hired_months = #{hired_months}"
444
+ # end
351
445
  #
352
- # == Bind
446
+ # == How to bind <tt>INTERVAL YEAR TO MONTH</tt>
353
447
  #
354
- # You cannot bind as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
355
- # It must be bound explicitly with :interval_ym.
448
+ # You cannot bind a bind variable as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
449
+ # It must be bound explicitly by OCI8::Cursor#bind_param.
356
450
  #
357
451
  # # output bind variable
358
452
  # cursor = conn.parse(<<-EOS)
@@ -399,51 +493,43 @@ class OCI8
399
493
  # OCI8::BindType::IntervalDS
400
494
  #++
401
495
  #
402
- # This is a helper class to bind ruby's
403
- # Rational[http://www.ruby-doc.org/core/classes/Rational.html]
404
- # object as Oracle's <tt>INTERVAL DAY TO SECOND</tt> datatype.
496
+ # (new in 2.0)
405
497
  #
406
- # == Select
498
+ # This is a helper class to select or bind Oracle data type
499
+ # <tt>INTERVAL DAY TO SECOND</tt>. The retrieved value is
500
+ # the number of seconds between two typestamps as a \Float.
407
501
  #
408
- # The fetched value for a <tt>INTERVAL DAY TO SECOND</tt> column
409
- # is a Rational[http://www.ruby-doc.org/core/classes/Rational.html]
410
- # or an Integer[http://www.ruby-doc.org/core/classes/Integer.html].
411
- # The value is usable to apply to
412
- # DateTime[http://www.ruby-doc.org/core/classes/DateTime.html]#+ and
413
- # DateTime[http://www.ruby-doc.org/core/classes/DateTime.html]#-.
502
+ # Note that it is the number days as a \Rational if
503
+ # OCI8::BindType::IntervalDS.unit is :day or the ruby-oci8
504
+ # version is prior to 2.0.3.
414
505
  #
415
- # == Bind
506
+ # == How to bind <tt>INTERVAL DAY TO SECOND</tt>
416
507
  #
417
- # You cannot bind as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
418
- # It must be bound explicitly with :interval_ds.
508
+ # You cannot bind a bind variable as <tt>INTERVAL DAY TO SECOND</tt>
509
+ # implicitly. It must be bound explicitly by OCI8::Cursor#bind_param.
419
510
  #
420
- # # output
421
- # ts1 = DateTime.parse('1969-11-19 06:54:35 00:00')
422
- # ts2 = DateTime.parse('1969-07-20 20:17:40 00:00')
511
+ # # output bind variable
423
512
  # cursor = conn.parse(<<-EOS)
424
513
  # BEGIN
425
- # :itv := (:ts1 - :ts2) DAY TO SECOND;
514
+ # :interval := (:ts1 - :ts2) DAY TO SECOND(9);
426
515
  # END;
427
516
  # EOS
428
- # cursor.bind_param(:itv, nil, :interval_ds)
429
- # cursor.bind_param(:ts1, ts1)
430
- # cursor.bind_param(:ts2, ts2)
517
+ # cursor.bind_param(:interval, nil, :interval_ds)
518
+ # cursor.bind_param(:ts1, DateTime.parse('1969-11-19 06:54:35 00:00'))
519
+ # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
431
520
  # cursor.exec
432
- # cursor[:itv] # == ts1 - ts2
521
+ # cursor[:interval] # => 10492615.0 seconds
433
522
  # cursor.close
434
523
  #
435
- # # input
436
- # ts2 = DateTime.parse('1969-07-20 20:17:40 00:00')
437
- # itv = 121 + 10.to_r/24 + 36.to_r/(24*60) + 55.to_r/(24*60*60)
438
- # # 121 days, 10 hours, 36 minutes, 55 seconds
524
+ # # input bind variable
439
525
  # cursor = conn.parse(<<-EOS)
440
526
  # BEGIN
441
- # :ts1 := :ts2 + :itv;
527
+ # :ts1 := :ts2 + :interval;
442
528
  # END;
443
529
  # EOS
444
530
  # cursor.bind_param(:ts1, nil, DateTime)
445
- # cursor.bind_param(:ts2, ts2)
446
- # cursor.bind_param(:itv, itv, :interval_ds)
531
+ # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
532
+ # cursor.bind_param(:interval, 10492615.0, :interval_ds)
447
533
  # cursor.exec
448
534
  # cursor[:ts1].strftime('%Y-%m-%d %H:%M:%S') # => 1969-11-19 06:54:35
449
535
  # cursor.close
@@ -453,6 +539,32 @@ class OCI8
453
539
  @@minute = @@hour / 60
454
540
  @@sec = @@minute / 60
455
541
  @@fsec = @@sec / 1000000000
542
+ @@unit = :second
543
+
544
+ # call-seq:
545
+ # OCI8::BindType::IntervalDS.unit -> :second or :day
546
+ #
547
+ # (new in 2.0.3)
548
+ #
549
+ # Retrieves the unit of interval.
550
+ def self.unit
551
+ @@unit
552
+ end
553
+
554
+ # call-seq:
555
+ # OCI8::BindType::IntervalDS.unit = :second or :day
556
+ #
557
+ # (new in 2.0.3)
558
+ #
559
+ # Changes the unit of interval. :second is the default.
560
+ def self.unit=(val)
561
+ case val
562
+ when :second, :day
563
+ @@unit = val
564
+ else
565
+ raise 'unit should be :second or :day'
566
+ end
567
+ end
456
568
 
457
569
  def set(val) # :nodoc:
458
570
  unless val.nil?
@@ -462,10 +574,17 @@ class OCI8
462
574
  else
463
575
  is_minus = false
464
576
  end
465
- day, val = val.divmod 1
466
- hour, val = (val * 24).divmod 1
467
- minute, val = (val * 60).divmod 1
468
- sec, val = (val * 60).divmod 1
577
+ if @@unit == :second
578
+ day, val = val.divmod 86400
579
+ hour, val = val.divmod 3600
580
+ minute, val = val.divmod 60
581
+ sec, val = val.divmod 1
582
+ else
583
+ day, val = val.divmod 1
584
+ hour, val = (val * 24).divmod 1
585
+ minute, val = (val * 60).divmod 1
586
+ sec, val = (val * 60).divmod 1
587
+ end
469
588
  fsec, val = (val * 1000000000).divmod 1
470
589
  if is_minus
471
590
  day = - day
@@ -483,7 +602,12 @@ class OCI8
483
602
  val = super()
484
603
  return nil if val.nil?
485
604
  day, hour, minute, sec, fsec = val
486
- day + (hour * @@hour) + (minute * @@minute) + (sec * @@sec) + (fsec * @@fsec)
605
+ if @@unit == :second
606
+ fsec = fsec / 1000000000.0
607
+ day * 86400 + hour * 3600 + minute * 60 + sec + fsec
608
+ else
609
+ day + (hour * @@hour) + (minute * @@minute) + (sec * @@sec) + (fsec * @@fsec)
610
+ end
487
611
  end
488
612
  end # OCI8::BindType::IntervalDS
489
613
  end