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 +121 -0
- data/Makefile +11 -4
- data/NEWS +126 -0
- data/VERSION +1 -1
- data/lib/.document +0 -1
- data/lib/oci8.rb +2 -2
- data/lib/oci8.rb.in +1 -1
- data/lib/oci8/.document +2 -2
- data/lib/oci8/bindtype.rb +32 -8
- data/lib/oci8/compat.rb +5 -0
- data/lib/oci8/datetime.rb +284 -160
- data/lib/oci8/object.rb +18 -4
- data/lib/oci8/oci8.rb +24 -4
- data/lib/oci8lib_18.so +0 -0
- data/lib/oci8lib_191.so +0 -0
- data/test/test_appinfo.rb +34 -0
- data/test/test_clob.rb +13 -0
- data/test/test_datetime.rb +160 -7
- data/test/test_oci8.rb +31 -3
- data/test/test_oranumber.rb +12 -7
- metadata +2 -2
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
|
-
|
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.
|
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.
|
1
|
+
2.0.3
|
data/lib/.document
CHANGED
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
|
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.
|
80
|
+
VERSION = '2.0.3'
|
81
81
|
CLIENT_VERSION = '1020'
|
82
82
|
end
|
data/lib/oci8.rb.in
CHANGED
data/lib/oci8/.document
CHANGED
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::
|
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.
|
267
|
-
# for
|
268
|
-
OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::
|
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.
|
280
|
-
# for
|
281
|
-
OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::
|
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
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
|
-
|
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
|
-
|
147
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
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
|
-
|
173
|
-
super(val)
|
223
|
+
super(datetime_to_array(val, false))
|
174
224
|
end
|
175
225
|
|
176
226
|
def get() # :nodoc:
|
177
|
-
|
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
|
-
|
187
|
-
super(val)
|
235
|
+
super(datetime_to_array(val, false))
|
188
236
|
end
|
189
237
|
|
190
238
|
def get() # :nodoc:
|
191
|
-
|
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
|
-
|
202
|
-
super(val)
|
248
|
+
super(datetime_to_array(val, true))
|
203
249
|
end
|
204
250
|
|
205
251
|
def get() # :nodoc:
|
206
|
-
|
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
|
-
|
216
|
-
super(val)
|
260
|
+
super(datetime_to_array(val, true))
|
217
261
|
end
|
218
262
|
|
219
263
|
def get() # :nodoc:
|
220
|
-
|
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
|
231
|
-
#
|
232
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
251
|
-
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
#
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
260
|
-
#
|
261
|
-
#
|
262
|
-
#
|
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
|
343
|
-
#
|
344
|
-
#
|
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
|
-
#
|
440
|
+
# <tt>INTERVAL YEAR TO MONTH</tt> is selected as an Integer.
|
347
441
|
#
|
348
|
-
#
|
349
|
-
#
|
350
|
-
#
|
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
|
-
# ==
|
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
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
409
|
-
# is
|
410
|
-
#
|
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
|
-
# ==
|
506
|
+
# == How to bind <tt>INTERVAL DAY TO SECOND</tt>
|
416
507
|
#
|
417
|
-
# You cannot bind as <tt>INTERVAL
|
418
|
-
# It must be bound explicitly
|
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
|
-
# :
|
514
|
+
# :interval := (:ts1 - :ts2) DAY TO SECOND(9);
|
426
515
|
# END;
|
427
516
|
# EOS
|
428
|
-
# cursor.bind_param(:
|
429
|
-
# cursor.bind_param(:ts1,
|
430
|
-
# cursor.bind_param(: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[:
|
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 + :
|
527
|
+
# :ts1 := :ts2 + :interval;
|
442
528
|
# END;
|
443
529
|
# EOS
|
444
530
|
# cursor.bind_param(:ts1, nil, DateTime)
|
445
|
-
# cursor.bind_param(:ts2,
|
446
|
-
# cursor.bind_param(:
|
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
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
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
|
-
|
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
|