ruby-oci8 1.0.7-x86-mswin32-60 → 2.0.1-x86-mswin32-60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +1289 -383
- data/Makefile +48 -12
- data/NEWS +5 -419
- data/README +56 -385
- data/VERSION +1 -1
- data/dist-files +27 -27
- data/lib/.document +2 -0
- data/lib/dbd/OCI8.rb +2 -17
- data/lib/oci8.rb +48 -1622
- data/lib/oci8.rb.in +48 -1622
- data/lib/oci8/.document +5 -0
- data/lib/oci8/compat.rb +108 -0
- data/lib/oci8/datetime.rb +491 -0
- data/lib/oci8/encoding-init.rb +40 -0
- data/lib/oci8/encoding.yml +537 -0
- data/lib/oci8/metadata.rb +2077 -0
- data/lib/oci8/object.rb +548 -0
- data/lib/oci8/oci8.rb +798 -0
- data/lib/oci8/oracle_version.rb +144 -0
- data/lib/oci8lib_18.so +0 -0
- data/lib/oci8lib_191.so +0 -0
- data/metaconfig +3 -3
- data/ruby-oci8.gemspec +24 -15
- data/setup.rb +4 -4
- data/test/config.rb +64 -84
- data/test/test_all.rb +14 -21
- data/test/test_array_dml.rb +333 -0
- data/test/test_bind_raw.rb +18 -25
- data/test/test_bind_time.rb +78 -91
- data/test/test_break.rb +37 -35
- data/test/test_clob.rb +33 -89
- data/test/test_connstr.rb +5 -4
- data/test/test_datetime.rb +469 -0
- data/test/test_dbi.rb +99 -60
- data/test/test_dbi_clob.rb +3 -8
- data/test/test_metadata.rb +65 -51
- data/test/test_oci8.rb +151 -55
- data/test/test_oracle_version.rb +70 -0
- data/test/test_oradate.rb +76 -83
- data/test/test_oranumber.rb +405 -71
- data/test/test_rowid.rb +6 -11
- metadata +21 -25
- data/ext/oci8/oci8lib.so +0 -0
- data/ruby-oci8.spec +0 -62
- data/support/README +0 -4
- data/support/runit/assert.rb +0 -281
- data/support/runit/cui/testrunner.rb +0 -101
- data/support/runit/error.rb +0 -4
- data/support/runit/method_mappable.rb +0 -20
- data/support/runit/robserver.rb +0 -25
- data/support/runit/setuppable.rb +0 -15
- data/support/runit/teardownable.rb +0 -16
- data/support/runit/testcase.rb +0 -113
- data/support/runit/testfailure.rb +0 -25
- data/support/runit/testresult.rb +0 -121
- data/support/runit/testsuite.rb +0 -43
- data/support/runit/version.rb +0 -3
- data/test/test_describe.rb +0 -137
data/lib/oci8/.document
ADDED
data/lib/oci8/compat.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
#
|
2
|
+
# add compatible code with old versions.
|
3
|
+
#
|
4
|
+
|
5
|
+
OCI_STMT_SELECT = :select_stmt
|
6
|
+
OCI_STMT_UPDATE = :update_stmt
|
7
|
+
OCI_STMT_DELETE = :delete_stmt
|
8
|
+
OCI_STMT_INSERT = :insert_stmt
|
9
|
+
OCI_STMT_CREATE = :create_stmt
|
10
|
+
OCI_STMT_DROP = :drop_stmt
|
11
|
+
OCI_STMT_ALTER = :alter_stmt
|
12
|
+
OCI_STMT_BEGIN = :begin_stmt
|
13
|
+
OCI_STMT_DECLARE = :declare_stmt
|
14
|
+
|
15
|
+
class OCI8
|
16
|
+
|
17
|
+
STMT_SELECT = :select_stmt
|
18
|
+
STMT_UPDATE = :update_stmt
|
19
|
+
STMT_DELETE = :delete_stmt
|
20
|
+
STMT_INSERT = :insert_stmt
|
21
|
+
STMT_CREATE = :create_stmt
|
22
|
+
STMT_DROP = :drop_stmt
|
23
|
+
STMT_ALTER = :alter_stmt
|
24
|
+
STMT_BEGIN = :begin_stmt
|
25
|
+
STMT_DECLARE = :declare_stmt
|
26
|
+
|
27
|
+
RAW = :raw
|
28
|
+
|
29
|
+
# varchar, varchar2
|
30
|
+
SQLT_CHR = :varchar2
|
31
|
+
# number, double precision, float, real, numeric, int, integer, smallint
|
32
|
+
SQLT_NUM = :number
|
33
|
+
# long
|
34
|
+
SQLT_LNG = :long
|
35
|
+
# date
|
36
|
+
SQLT_DAT = :date
|
37
|
+
# raw
|
38
|
+
SQLT_BIN = :raw
|
39
|
+
# long raw
|
40
|
+
SQLT_LBI = :long_raw
|
41
|
+
# char
|
42
|
+
SQLT_AFC = :char
|
43
|
+
# binary_float
|
44
|
+
SQLT_IBFLOAT = :binary_float
|
45
|
+
# binary_double
|
46
|
+
SQLT_IBDOUBLE = :binary_double
|
47
|
+
# rowid
|
48
|
+
SQLT_RDD = :rowid
|
49
|
+
# clob
|
50
|
+
SQLT_CLOB = :clob
|
51
|
+
# blob
|
52
|
+
SQLT_BLOB = :blob
|
53
|
+
# bfile
|
54
|
+
SQLT_BFILE = :bfile
|
55
|
+
# ref cursor
|
56
|
+
SQLT_RSET = 116
|
57
|
+
# timestamp
|
58
|
+
SQLT_TIMESTAMP = :timestamp
|
59
|
+
# timestamp with time zone
|
60
|
+
SQLT_TIMESTAMP_TZ = :timestamp_tz
|
61
|
+
# interval year to month
|
62
|
+
SQLT_INTERVAL_YM = :interval_ym
|
63
|
+
# interval day to second
|
64
|
+
SQLT_INTERVAL_DS = :interval_ds
|
65
|
+
# timestamp with local time zone
|
66
|
+
SQLT_TIMESTAMP_LTZ = :timestamp_ltz
|
67
|
+
|
68
|
+
# mapping of sql type number to sql type name.
|
69
|
+
SQLT_NAMES = {}
|
70
|
+
constants.each do |name|
|
71
|
+
next if name.to_s.index("SQLT_") != 0
|
72
|
+
val = const_get name.intern
|
73
|
+
if val.is_a? Fixnum
|
74
|
+
SQLT_NAMES[val] = name
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# add alias compatible with 'Oracle7 Module for Ruby'.
|
79
|
+
alias autocommit autocommit?
|
80
|
+
|
81
|
+
class Cursor
|
82
|
+
def self.select_number_as=(val)
|
83
|
+
if val == Fixnum
|
84
|
+
@@bind_unknown_number = OCI8::BindType::Fixnum
|
85
|
+
elsif val == Integer
|
86
|
+
@@bind_unknown_number = OCI8::BindType::Integer
|
87
|
+
elsif val == Float
|
88
|
+
@@bind_unknown_number = OCI8::BindType::Float
|
89
|
+
else
|
90
|
+
raise ArgumentError, "must be Fixnum, Integer or Float"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.select_number_as
|
95
|
+
case @@bind_unknown_number
|
96
|
+
when OCI8::BindType::Fixnum
|
97
|
+
return Fixnum
|
98
|
+
when OCI8::BindType::Integer
|
99
|
+
return Integer
|
100
|
+
when OCI8::BindType::Float
|
101
|
+
return Float
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# add alias compatible with 'Oracle7 Module for Ruby'.
|
106
|
+
alias getColNames get_col_names
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,491 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class OCI8
|
4
|
+
|
5
|
+
module BindType
|
6
|
+
|
7
|
+
module Util # :nodoc:
|
8
|
+
|
9
|
+
@@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
|
+
|
13
|
+
@@default_timezone = :local
|
14
|
+
def self.default_timezone
|
15
|
+
@@default_timezone
|
16
|
+
end
|
17
|
+
|
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
|
+
def self.default_timezone=(tz)
|
25
|
+
if tz != :local and tz != :utc
|
26
|
+
raise ArgumentError, "expected :local or :utc but #{tz}"
|
27
|
+
end
|
28
|
+
@@default_timezone = tz
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def datetime_to_array(val, full)
|
34
|
+
# year
|
35
|
+
year = val.year
|
36
|
+
# month
|
37
|
+
if val.respond_to? :mon
|
38
|
+
month = val.mon
|
39
|
+
elsif val.respond_to? :month
|
40
|
+
month = val.month
|
41
|
+
else
|
42
|
+
raise "expect Time, Date or DateTime but #{val.class}"
|
43
|
+
end
|
44
|
+
# day
|
45
|
+
if val.respond_to? :mday
|
46
|
+
day = val.mday
|
47
|
+
elsif val.respond_to? :day
|
48
|
+
day = val.day
|
49
|
+
else
|
50
|
+
raise "expect Time, Date or DateTime but #{val.class}"
|
51
|
+
end
|
52
|
+
# hour
|
53
|
+
if val.respond_to? :hour
|
54
|
+
hour = val.hour
|
55
|
+
else
|
56
|
+
hour = 0
|
57
|
+
end
|
58
|
+
# minute
|
59
|
+
if val.respond_to? :min
|
60
|
+
minute = val.min
|
61
|
+
else
|
62
|
+
minute = 0
|
63
|
+
end
|
64
|
+
# second
|
65
|
+
if val.respond_to? :sec
|
66
|
+
sec = val.sec
|
67
|
+
else
|
68
|
+
sec = 0
|
69
|
+
end
|
70
|
+
return [year, month, day, hour, minute, sec] unless full
|
71
|
+
|
72
|
+
# sec_fraction
|
73
|
+
if val.respond_to? :sec_fraction
|
74
|
+
fsec = (val.sec_fraction * @@datetime_fsec_base).to_i
|
75
|
+
else
|
76
|
+
fsec = 0
|
77
|
+
end
|
78
|
+
# time zone
|
79
|
+
if val.respond_to? :offset
|
80
|
+
# DateTime
|
81
|
+
tz_min = (val.offset * 1440).to_i
|
82
|
+
elsif val.respond_to? :utc_offset
|
83
|
+
# Time
|
84
|
+
tz_min = val.utc_offset / 60
|
85
|
+
else
|
86
|
+
tz_hour = nil
|
87
|
+
tz_min = nil
|
88
|
+
end
|
89
|
+
if tz_min
|
90
|
+
if tz_min < 0
|
91
|
+
tz_min = - tz_min
|
92
|
+
tz_hour = - (tz_min / 60)
|
93
|
+
tz_min = (tz_min % 60)
|
94
|
+
else
|
95
|
+
tz_hour = tz_min / 60
|
96
|
+
tz_min = tz_min % 60
|
97
|
+
end
|
98
|
+
end
|
99
|
+
[year, month, day, hour, minute, sec, fsec, tz_hour, tz_min]
|
100
|
+
end
|
101
|
+
|
102
|
+
def ocidate_to_datetime(ary)
|
103
|
+
year, month, day, hour, minute, sec = ary
|
104
|
+
if @@default_timezone == :local
|
105
|
+
offset = @@datetime_offset
|
106
|
+
else
|
107
|
+
offset = 0
|
108
|
+
end
|
109
|
+
::DateTime.civil(year, month, day, hour, minute, sec, offset)
|
110
|
+
end
|
111
|
+
|
112
|
+
def ocidate_to_time(ary)
|
113
|
+
year, month, day, hour, minute, sec = ary
|
114
|
+
if year >= 139
|
115
|
+
begin
|
116
|
+
return ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
|
117
|
+
rescue StandardError
|
118
|
+
end
|
119
|
+
end
|
120
|
+
ocidate_to_datetime(ary)
|
121
|
+
end
|
122
|
+
|
123
|
+
if OCI8.oracle_client_version >= ORAVER_9_0
|
124
|
+
|
125
|
+
def ocitimestamp_to_datetime(ary)
|
126
|
+
year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
|
127
|
+
if sec >= 59 and fsec != 0
|
128
|
+
# convert to a DateTime via a String as a last resort.
|
129
|
+
if tz_hour >= 0 && tz_min >= 0
|
130
|
+
sign = ?+
|
131
|
+
else
|
132
|
+
sign = ?-
|
133
|
+
tz_hour = - tz_hour
|
134
|
+
tz_min = - tz_min
|
135
|
+
end
|
136
|
+
time_str = format("%04d-%02d-%02dT%02d:%02d:%02d.%09d%c%02d:%02d",
|
137
|
+
year, month, day, hour, minute, sec, fsec, sign, tz_hour, tz_min)
|
138
|
+
::DateTime.parse(time_str)
|
139
|
+
else
|
140
|
+
sec += fsec.to_r / 1000000000
|
141
|
+
offset = tz_hour.to_r / 24 + tz_min.to_r / 1440
|
142
|
+
::DateTime.civil(year, month, day, hour, minute, sec, offset)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def ocitimestamp_to_time(ary)
|
147
|
+
year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
|
148
|
+
|
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
|
153
|
+
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
|
161
|
+
end
|
162
|
+
end
|
163
|
+
ocitimestamp_to_datetime(ary)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class DateTimeViaOCIDate < OCI8::BindType::OCIDate
|
169
|
+
include OCI8::BindType::Util
|
170
|
+
|
171
|
+
def set(val) # :nodoc:
|
172
|
+
val &&= datetime_to_array(val, false)
|
173
|
+
super(val)
|
174
|
+
end
|
175
|
+
|
176
|
+
def get() # :nodoc:
|
177
|
+
val = super()
|
178
|
+
val ? ocidate_to_datetime(val) : nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class TimeViaOCIDate < OCI8::BindType::OCIDate
|
183
|
+
include OCI8::BindType::Util
|
184
|
+
|
185
|
+
def set(val) # :nodoc:
|
186
|
+
val &&= datetime_to_array(val, false)
|
187
|
+
super(val)
|
188
|
+
end
|
189
|
+
|
190
|
+
def get() # :nodoc:
|
191
|
+
val = super()
|
192
|
+
val ? ocidate_to_time(val) : nil
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
if OCI8.oracle_client_version >= ORAVER_9_0
|
197
|
+
class DateTimeViaOCITimestamp < OCI8::BindType::OCITimestamp
|
198
|
+
include OCI8::BindType::Util
|
199
|
+
|
200
|
+
def set(val) # :nodoc:
|
201
|
+
val &&= datetime_to_array(val, true)
|
202
|
+
super(val)
|
203
|
+
end
|
204
|
+
|
205
|
+
def get() # :nodoc:
|
206
|
+
val = super()
|
207
|
+
val ? ocitimestamp_to_datetime(val) : nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
class TimeViaOCITimestamp < OCI8::BindType::OCITimestamp
|
212
|
+
include OCI8::BindType::Util
|
213
|
+
|
214
|
+
def set(val) # :nodoc:
|
215
|
+
val &&= datetime_to_array(val, true)
|
216
|
+
super(val)
|
217
|
+
end
|
218
|
+
|
219
|
+
def get() # :nodoc:
|
220
|
+
val = super()
|
221
|
+
val ? ocitimestamp_to_time(val) : nil
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
#--
|
228
|
+
# OCI8::BindType::DateTime
|
229
|
+
#++
|
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.
|
233
|
+
#
|
234
|
+
# == Select
|
235
|
+
#
|
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.
|
242
|
+
#
|
243
|
+
# You can change the session time zone by executing the following SQL.
|
244
|
+
#
|
245
|
+
# ALTER SESSION SET TIME_ZONE='-05:00'
|
246
|
+
#
|
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
|
304
|
+
#
|
305
|
+
class DateTime
|
306
|
+
if OCI8.oracle_client_version >= ORAVER_9_0
|
307
|
+
def self.create(con, val, param, max_array_size)
|
308
|
+
if true # TODO: check Oracle server version
|
309
|
+
DateTimeViaOCITimestamp.new(con, val, param, max_array_size)
|
310
|
+
else
|
311
|
+
DateTimeViaOCIDate.new(con, val, param, max_array_size)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
else
|
315
|
+
def self.create(con, val, param, max_array_size)
|
316
|
+
DateTimeViaOCIDate.new(con, val, param, max_array_size)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
class Time
|
322
|
+
if OCI8.oracle_client_version >= ORAVER_9_0
|
323
|
+
def self.create(con, val, param, max_array_size)
|
324
|
+
if true # TODO: check Oracle server version
|
325
|
+
TimeViaOCITimestamp.new(con, val, param, max_array_size)
|
326
|
+
else
|
327
|
+
TimeViaOCIDate.new(con, val, param, max_array_size)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
else
|
331
|
+
def self.create(con, val, param, max_array_size)
|
332
|
+
TimeViaOCIDate.new(con, val, param, max_array_size)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
if OCI8.oracle_client_version >= ORAVER_9_0
|
338
|
+
#--
|
339
|
+
# OCI8::BindType::IntervalYM
|
340
|
+
#++
|
341
|
+
#
|
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.
|
345
|
+
#
|
346
|
+
# == Select
|
347
|
+
#
|
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.
|
351
|
+
#
|
352
|
+
# == Bind
|
353
|
+
#
|
354
|
+
# You cannot bind as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
|
355
|
+
# It must be bound explicitly with :interval_ym.
|
356
|
+
#
|
357
|
+
# # output bind variable
|
358
|
+
# cursor = conn.parse(<<-EOS)
|
359
|
+
# BEGIN
|
360
|
+
# :interval := (:ts1 - :ts2) YEAR TO MONTH;
|
361
|
+
# END;
|
362
|
+
# EOS
|
363
|
+
# cursor.bind_param(:interval, nil, :interval_ym)
|
364
|
+
# cursor.bind_param(:ts1, DateTime.parse('1969-11-19 06:54:35 00:00'))
|
365
|
+
# cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
|
366
|
+
# cursor.exec
|
367
|
+
# cursor[:interval] # => 4 (months)
|
368
|
+
# cursor.close
|
369
|
+
#
|
370
|
+
# # input bind variable
|
371
|
+
# cursor = conn.parse(<<-EOS)
|
372
|
+
# BEGIN
|
373
|
+
# :ts1 := :ts2 + :interval;
|
374
|
+
# END;
|
375
|
+
# EOS
|
376
|
+
# cursor.bind_param(:ts1, nil, DateTime)
|
377
|
+
# cursor.bind_param(:ts2, Date.parse('1969-11-19'))
|
378
|
+
# cursor.bind_param(:interval, 4, :interval_ym)
|
379
|
+
# cursor.exec
|
380
|
+
# cursor[:ts1].strftime('%Y-%m-%d') # => 1970-03-19
|
381
|
+
# cursor.close
|
382
|
+
#
|
383
|
+
class IntervalYM < OCI8::BindType::OCIIntervalYM
|
384
|
+
def set(val) # :nodoc:
|
385
|
+
unless val.nil?
|
386
|
+
val = [val / 12, val % 12]
|
387
|
+
end
|
388
|
+
super(val)
|
389
|
+
end
|
390
|
+
def get() # :nodoc:
|
391
|
+
val = super()
|
392
|
+
return nil if val.nil?
|
393
|
+
year, month = val
|
394
|
+
year * 12 + month
|
395
|
+
end
|
396
|
+
end # OCI8::BindType::IntervalYM
|
397
|
+
|
398
|
+
#--
|
399
|
+
# OCI8::BindType::IntervalDS
|
400
|
+
#++
|
401
|
+
#
|
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.
|
405
|
+
#
|
406
|
+
# == Select
|
407
|
+
#
|
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]#-.
|
414
|
+
#
|
415
|
+
# == Bind
|
416
|
+
#
|
417
|
+
# You cannot bind as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
|
418
|
+
# It must be bound explicitly with :interval_ds.
|
419
|
+
#
|
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')
|
423
|
+
# cursor = conn.parse(<<-EOS)
|
424
|
+
# BEGIN
|
425
|
+
# :itv := (:ts1 - :ts2) DAY TO SECOND;
|
426
|
+
# END;
|
427
|
+
# EOS
|
428
|
+
# cursor.bind_param(:itv, nil, :interval_ds)
|
429
|
+
# cursor.bind_param(:ts1, ts1)
|
430
|
+
# cursor.bind_param(:ts2, ts2)
|
431
|
+
# cursor.exec
|
432
|
+
# cursor[:itv] # == ts1 - ts2
|
433
|
+
# cursor.close
|
434
|
+
#
|
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
|
439
|
+
# cursor = conn.parse(<<-EOS)
|
440
|
+
# BEGIN
|
441
|
+
# :ts1 := :ts2 + :itv;
|
442
|
+
# END;
|
443
|
+
# EOS
|
444
|
+
# cursor.bind_param(:ts1, nil, DateTime)
|
445
|
+
# cursor.bind_param(:ts2, ts2)
|
446
|
+
# cursor.bind_param(:itv, itv, :interval_ds)
|
447
|
+
# cursor.exec
|
448
|
+
# cursor[:ts1].strftime('%Y-%m-%d %H:%M:%S') # => 1969-11-19 06:54:35
|
449
|
+
# cursor.close
|
450
|
+
#
|
451
|
+
class IntervalDS < OCI8::BindType::OCIIntervalDS
|
452
|
+
@@hour = 1 / 24.to_r
|
453
|
+
@@minute = @@hour / 60
|
454
|
+
@@sec = @@minute / 60
|
455
|
+
@@fsec = @@sec / 1000000000
|
456
|
+
|
457
|
+
def set(val) # :nodoc:
|
458
|
+
unless val.nil?
|
459
|
+
if val < 0
|
460
|
+
is_minus = true
|
461
|
+
val = -val
|
462
|
+
else
|
463
|
+
is_minus = false
|
464
|
+
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
|
469
|
+
fsec, val = (val * 1000000000).divmod 1
|
470
|
+
if is_minus
|
471
|
+
day = - day
|
472
|
+
hour = - hour
|
473
|
+
minute = - minute
|
474
|
+
sec = - sec
|
475
|
+
fsec = - fsec
|
476
|
+
end
|
477
|
+
val = [day, hour, minute, sec, fsec]
|
478
|
+
end
|
479
|
+
super(val)
|
480
|
+
end
|
481
|
+
|
482
|
+
def get() # :nodoc:
|
483
|
+
val = super()
|
484
|
+
return nil if val.nil?
|
485
|
+
day, hour, minute, sec, fsec = val
|
486
|
+
day + (hour * @@hour) + (minute * @@minute) + (sec * @@sec) + (fsec * @@fsec)
|
487
|
+
end
|
488
|
+
end # OCI8::BindType::IntervalDS
|
489
|
+
end
|
490
|
+
end # OCI8::BindType
|
491
|
+
end # OCI8
|