ruby-oci8 2.0.6-x86-mingw32 → 2.1.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,118 @@
1
+ #--
2
+ # connection_pool.rb -- OCI8::ConnectionPool
3
+ #
4
+ # Copyright (C) 2010 KUBO Takehiro <kubo@jiubao.org>
5
+ #++
6
+
7
+ class OCI8
8
+
9
+ # Connection pooling is the use of a group (the pool) of reusable
10
+ # physical connections by several sessions to balance loads.
11
+ # See: {Oracle Call Interface Manual}[http://docs.oracle.com/cd/E11882_01/appdev.112/e10646/oci09adv.htm#sthref1479]
12
+ #
13
+ # This is equivalent to Oracle JDBC Driver {OCI Connection Pooling}[http://docs.oracle.com/cd/E11882_01/java.112/e16548/ociconpl.htm#JJDBC28789].
14
+ #
15
+ # Usage:
16
+ # # Create a connection pool.
17
+ # # username and password are required to establish an implicit primary session.
18
+ # cpool = OCI8::ConnectionPool.new(1, 5, 2, username, password, database)
19
+ #
20
+ # # Get a session from the pool.
21
+ # # Pass the connection pool to the third argument.
22
+ # conn1 = OCI8.new(username, password, cpool)
23
+ #
24
+ # # Get another session.
25
+ # conn2 = OCI8.new(username, password, cpool)
26
+ #
27
+ class ConnectionPool
28
+
29
+ # call-seq:
30
+ # timeout -> integer
31
+ #
32
+ # Connections idle for more than this time value (in seconds) are
33
+ # terminated, to maintain an optimum number of open
34
+ # connections. If it is zero, the connections are never timed out.
35
+ # The default value is zero.
36
+ #
37
+ # <b>Note:</b> Shrinkage of the pool only occurs when there is a network
38
+ # round trip. If there are no operations, then the connections
39
+ # stay alive.
40
+ def timeout
41
+ attr_get_ub4(OCI_ATTR_CONN_TIMEOUT)
42
+ end
43
+
44
+ # call-seq:
45
+ # timeout = integer
46
+ #
47
+ # Changes the timeout in seconds to terminate idle connections.
48
+ def timeout=(val)
49
+ attr_set_ub4(OCI_ATTR_CONN_TIMEOUT, val)
50
+ end
51
+
52
+ # call-seq:
53
+ # nowait? -> true or false
54
+ #
55
+ # If true, an error is thrown when all the connections in the pool
56
+ # are busy and the number of connections has already reached the
57
+ # maximum. Otherwise the call waits till it gets a connection.
58
+ # The default value is false.
59
+ def nowait?
60
+ attr_get_ub1(OCI_ATTR_CONN_NOWAIT) != 0
61
+ end
62
+
63
+ # call-seq:
64
+ # nowait = true or false
65
+ #
66
+ # Changes the behavior when all the connections in the pool
67
+ # are busy and the number of connections has already reached the
68
+ # maximum.
69
+ def nowait=(val)
70
+ attr_set_ub1(OCI_ATTR_CONN_NOWAIT, val ? 1 : 0)
71
+ end
72
+
73
+ # call-seq:
74
+ # busy_count -> integer
75
+ #
76
+ # Returns the number of busy physical connections.
77
+ def busy_count
78
+ attr_get_ub4(OCI_ATTR_CONN_BUSY_COUNT)
79
+ end
80
+
81
+ # call-seq:
82
+ # open_count -> integer
83
+ #
84
+ # Returns the number of open physical connections.
85
+ def open_count
86
+ attr_get_ub4(OCI_ATTR_CONN_OPEN_COUNT)
87
+ end
88
+
89
+ # call-seq:
90
+ # min -> integer
91
+ #
92
+ # Returns the number of minimum physical connections.
93
+ def min
94
+ attr_get_ub4(OCI_ATTR_CONN_MIN)
95
+ end
96
+
97
+ # call-seq:
98
+ # max -> integer
99
+ #
100
+ # Returns the number of maximum physical connections.
101
+ def max
102
+ attr_get_ub4(OCI_ATTR_CONN_MAX)
103
+ end
104
+
105
+ # call-seq:
106
+ # incr -> integer
107
+ #
108
+ # Returns the connection increment parameter.
109
+ def incr
110
+ attr_get_ub4(OCI_ATTR_CONN_INCR)
111
+ end
112
+
113
+ #
114
+ def destroy
115
+ free
116
+ end
117
+ end
118
+ end
@@ -59,7 +59,7 @@ class OCI8
59
59
 
60
60
  private
61
61
 
62
- def datetime_to_array(val, full)
62
+ def datetime_to_array(val, datatype)
63
63
  return nil if val.nil?
64
64
 
65
65
  # year
@@ -98,7 +98,7 @@ class OCI8
98
98
  else
99
99
  sec = 0
100
100
  end
101
- return [year, month, day, hour, minute, sec] unless full
101
+ return [year, month, day, hour, minute, sec] if datatype == :date
102
102
 
103
103
  # fractional second
104
104
  if val.respond_to? :sec_fraction
@@ -110,6 +110,8 @@ class OCI8
110
110
  else
111
111
  fsec = 0
112
112
  end
113
+ return [year, month, day, hour, minute, sec, fsec, nil, nil] if datatype == :timestamp
114
+
113
115
  # time zone
114
116
  if val.respond_to? :offset
115
117
  # DateTime
@@ -134,147 +136,91 @@ class OCI8
134
136
  [year, month, day, hour, minute, sec, fsec, tz_hour, tz_min]
135
137
  end
136
138
 
137
- def ocidate_to_datetime(ary)
139
+ def array_to_datetime(ary, timezone)
138
140
  return nil if ary.nil?
139
141
 
140
- year, month, day, hour, minute, sec = ary
141
- if @@default_timezone == :local
142
- if ::DateTime.respond_to? :local_offset
143
- offset = ::DateTime.local_offset # Use a method defined by active support.
142
+ year, month, day, hour, minute, sec, nsec, tz_hour, tz_min = ary
143
+ sec += nsec.to_r / 1000000000 if nsec and nsec != 0
144
+ if tz_hour and tz_min
145
+ offset = tz_hour.to_r / 24 + tz_min.to_r / 1440
146
+ else
147
+ if @@default_timezone == :local
148
+ if ::DateTime.respond_to? :local_offset
149
+ offset = ::DateTime.local_offset # Use a method defined by active support.
150
+ else
151
+ # Do as active support does.
152
+ offset = ::Time.local(2007).utc_offset.to_r / 86400
153
+ end
144
154
  else
145
- # Do as active support does.
146
- offset = ::Time.local(2007).utc_offset.to_r / 86400
155
+ offset = 0
147
156
  end
148
- else
149
- offset = 0
150
157
  end
151
- ::DateTime.civil(year, month, day, hour, minute, sec, offset)
152
- end
153
158
 
154
- def ocidate_to_time(ary)
155
- return nil if ary.nil?
156
-
157
- year, month, day, hour, minute, sec = ary
158
- if @@time_new_accepts_timezone || year >= 139 || year < 0
159
- begin
160
- return ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
161
- rescue StandardError
159
+ if @@datetime_has_fractional_second_bug and sec >= 59 and nsec != 0
160
+ # convert to a DateTime via a String as a workaround
161
+ if offset >= 0
162
+ sign = ?+
163
+ else
164
+ sign = ?-
165
+ offset = - offset;
162
166
  end
167
+ tz_min = (offset * 1440).to_i
168
+ tz_hour, tz_min = tz_min.divmod 60
169
+ time_str = format("%04d-%02d-%02dT%02d:%02d:%02d.%09d%c%02d:%02d",
170
+ year, month, day, hour, minute, sec, nsec, sign, tz_hour, tz_min)
171
+ ::DateTime.parse(time_str)
172
+ else
173
+ ::DateTime.civil(year, month, day, hour, minute, sec, offset)
163
174
  end
164
- ocidate_to_datetime(ary)
165
175
  end
166
176
 
167
- if OCI8.oracle_client_version >= ORAVER_9_0
177
+ if @@time_new_accepts_timezone
168
178
 
169
- def ocitimestamp_to_datetime(ary)
179
+ # after ruby 1.9.2
180
+ def array_to_time(ary, timezone)
170
181
  return nil if ary.nil?
171
182
 
172
- year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
173
- if @@datetime_has_fractional_second_bug and sec >= 59 and fsec != 0
174
- # convert to a DateTime via a String as a workaround
175
- if tz_hour >= 0 && tz_min >= 0
176
- sign = ?+
177
- else
178
- sign = ?-
179
- tz_hour = - tz_hour
180
- tz_min = - tz_min
181
- end
182
- time_str = format("%04d-%02d-%02dT%02d:%02d:%02d.%09d%c%02d:%02d",
183
- year, month, day, hour, minute, sec, fsec, sign, tz_hour, tz_min)
184
- ::DateTime.parse(time_str)
183
+ year, month, day, hour, minute, sec, nsec, tz_hour, tz_min = ary
184
+ nsec ||= 0
185
+
186
+ if timezone
187
+ usec = (nsec == 0) ? 0 : nsec.to_r / 1000
188
+ ::Time.send(timezone, year, month, day, hour, minute, sec, usec)
185
189
  else
186
- sec += fsec.to_r / 1000000000
187
- offset = tz_hour.to_r / 24 + tz_min.to_r / 1440
188
- ::DateTime.civil(year, month, day, hour, minute, sec, offset)
190
+ sec += nsec.to_r / 1_000_000_000 if nsec != 0
191
+ utc_offset = tz_hour * 3600 + tz_min * 60
192
+ ::Time.new(year, month, day, hour, minute, sec, utc_offset)
189
193
  end
190
194
  end
191
195
 
192
- if @@time_new_accepts_timezone
193
-
194
- # after ruby 1.9.2
195
- def ocitimestamp_to_time(ary)
196
- return nil if ary.nil?
197
-
198
- year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
199
-
200
- sec += fsec / Rational(1000000000)
201
- utc_offset = tz_hour * 3600 + tz_min * 60
202
- return ::Time.new(year, month, day, hour, minute, sec, utc_offset)
203
- end
196
+ else
204
197
 
205
- else
198
+ # prior to ruby 1.9.2
199
+ def array_to_time(ary, timezone)
200
+ return nil if ary.nil?
206
201
 
207
- # prior to ruby 1.9.2
208
- def ocitimestamp_to_time(ary)
209
- return nil if ary.nil?
210
-
211
- year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
212
-
213
- if year >= 139 || year < 0
214
- begin
215
- if tz_hour == 0 and tz_min == 0
216
- return ::Time.utc(year, month, day, hour, minute, sec, fsec / Rational(1000))
217
- else
218
- tm = ::Time.local(year, month, day, hour, minute, sec, fsec / Rational(1000))
219
- return tm if tm.utc_offset == tz_hour * 3600 + tz_min * 60
220
- end
221
- rescue StandardError
202
+ year, month, day, hour, minute, sec, nsec, tz_hour, tz_min = ary
203
+ nsec ||= 0
204
+ usec = (nsec == 0) ? 0 : nsec.to_r / 1000
205
+ begin
206
+ if timezone
207
+ return ::Time.send(:timezone, year, month, day, hour, minute, sec, usec)
208
+ else
209
+ if tz_hour == 0 and tz_min == 0
210
+ tm = ::Time.utc(year, month, day, hour, minute, sec, usec)
211
+ # Time.utc(99, ...) returns a time object the year of which is 1999.
212
+ # 'tm.year == year' checks such cases.
213
+ return tm if tm.year == year
214
+ else
215
+ tm = ::Time.local(year, month, day, hour, minute, sec, usec)
216
+ return tm if tm.utc_offset == tz_hour * 3600 + tz_min * 60 and tm.year == year
222
217
  end
223
218
  end
224
- ocitimestamp_to_datetime(ary)
219
+ rescue StandardError
225
220
  end
226
-
227
- end
228
- end
229
- end
230
-
231
- class DateTimeViaOCIDate < OCI8::BindType::OCIDate # :nodoc:
232
- include OCI8::BindType::Util
233
-
234
- def set(val) # :nodoc:
235
- super(datetime_to_array(val, false))
236
- end
237
-
238
- def get() # :nodoc:
239
- ocidate_to_datetime(super())
240
- end
241
- end
242
-
243
- class TimeViaOCIDate < OCI8::BindType::OCIDate # :nodoc:
244
- include OCI8::BindType::Util
245
-
246
- def set(val) # :nodoc:
247
- super(datetime_to_array(val, false))
248
- end
249
-
250
- def get() # :nodoc:
251
- ocidate_to_time(super())
252
- end
253
- end
254
-
255
- if OCI8.oracle_client_version >= ORAVER_9_0
256
- class DateTimeViaOCITimestampTZ < OCI8::BindType::OCITimestampTZ # :nodoc:
257
- include OCI8::BindType::Util
258
-
259
- def set(val) # :nodoc:
260
- super(datetime_to_array(val, true))
221
+ array_to_datetime(ary, timezone)
261
222
  end
262
223
 
263
- def get() # :nodoc:
264
- ocitimestamp_to_datetime(super())
265
- end
266
- end
267
-
268
- class TimeViaOCITimestampTZ < OCI8::BindType::OCITimestampTZ # :nodoc:
269
- include OCI8::BindType::Util
270
-
271
- def set(val) # :nodoc:
272
- super(datetime_to_array(val, true))
273
- end
274
-
275
- def get() # :nodoc:
276
- ocitimestamp_to_time(super())
277
- end
278
224
  end
279
225
  end
280
226
 
@@ -339,19 +285,39 @@ class OCI8
339
285
  # If you are in the regions where daylight saving time is adopted,
340
286
  # you should use OCI8::BindType::Time.
341
287
  #
342
- class DateTime
343
- if OCI8.oracle_client_version >= ORAVER_9_0
344
- def self.create(con, val, param, max_array_size) # :nodoc:
345
- if true # TODO: check Oracle server version
346
- DateTimeViaOCITimestampTZ.new(con, val, param, max_array_size)
347
- else
348
- DateTimeViaOCIDate.new(con, val, param, max_array_size)
349
- end
350
- end
351
- else
352
- def self.create(con, val, param, max_array_size) # :nodoc:
353
- DateTimeViaOCIDate.new(con, val, param, max_array_size)
354
- end
288
+ class DateTime < OCI8::BindType::OCITimestampTZ
289
+ include OCI8::BindType::Util
290
+
291
+ def set(val) # :nodoc:
292
+ super(datetime_to_array(val, :timestamp_tz))
293
+ end
294
+
295
+ def get() # :nodoc:
296
+ array_to_datetime(super(), nil)
297
+ end
298
+ end
299
+
300
+ class LocalDateTime < OCI8::BindType::OCITimestamp
301
+ include OCI8::BindType::Util
302
+
303
+ def set(val) # :nodoc:
304
+ super(datetime_to_array(val, :timestamp))
305
+ end
306
+
307
+ def get() # :nodoc:
308
+ array_to_datetime(super(), :local)
309
+ end
310
+ end
311
+
312
+ class UTCDateTime < OCI8::BindType::OCITimestamp
313
+ include OCI8::BindType::Util
314
+
315
+ def set(val) # :nodoc:
316
+ super(datetime_to_array(val, :timestamp))
317
+ end
318
+
319
+ def get() # :nodoc:
320
+ array_to_datetime(super(), :utc)
355
321
  end
356
322
  end
357
323
 
@@ -418,210 +384,228 @@ class OCI8
418
384
  # # or
419
385
  # OCI8::BindType.default_timezone = :utc
420
386
  #
421
- class Time
422
- if OCI8.oracle_client_version >= ORAVER_9_0
423
- def self.create(con, val, param, max_array_size) # :nodoc:
424
- if true # TODO: check Oracle server version
425
- TimeViaOCITimestampTZ.new(con, val, param, max_array_size)
426
- else
427
- TimeViaOCIDate.new(con, val, param, max_array_size)
428
- end
429
- end
430
- else
431
- def self.create(con, val, param, max_array_size) # :nodoc:
432
- TimeViaOCIDate.new(con, val, param, max_array_size)
433
- end
387
+ class Time < OCI8::BindType::OCITimestampTZ
388
+ include OCI8::BindType::Util
389
+
390
+ def set(val) # :nodoc:
391
+ super(datetime_to_array(val, :timestamp_tz))
392
+ end
393
+
394
+ def get() # :nodoc:
395
+ array_to_time(super(), nil)
434
396
  end
435
397
  end
436
398
 
437
- if OCI8.oracle_client_version >= ORAVER_9_0
438
- #--
439
- # OCI8::BindType::IntervalYM
440
- #++
441
- #
442
- # This is a helper class to select or bind Oracle data type
443
- # <tt>INTERVAL YEAR TO MONTH</tt>. The retrieved value is
444
- # the number of months between two timestamps.
445
- #
446
- # The value can be applied to \DateTime#>> to shift months.
447
- # It can be applied to \Time#months_since if activisupport has
448
- # been loaded.
449
- #
450
- # === How to select <tt>INTERVAL YEAR TO MONTH</tt>
451
- #
452
- # <tt>INTERVAL YEAR TO MONTH</tt> is selected as an Integer.
453
- #
454
- # conn.exec("select (current_timestamp - hiredate) year to month from emp") do |hired_months|
455
- # puts "hired_months = #{hired_months}"
456
- # end
457
- #
458
- # == How to bind <tt>INTERVAL YEAR TO MONTH</tt>
459
- #
460
- # You cannot bind a bind variable as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
461
- # It must be bound explicitly by OCI8::Cursor#bind_param.
462
- #
463
- # # output bind variable
464
- # cursor = conn.parse(<<-EOS)
465
- # BEGIN
466
- # :interval := (:ts1 - :ts2) YEAR TO MONTH;
467
- # END;
468
- # EOS
469
- # cursor.bind_param(:interval, nil, :interval_ym)
470
- # cursor.bind_param(:ts1, DateTime.parse('1969-11-19 06:54:35 00:00'))
471
- # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
472
- # cursor.exec
473
- # cursor[:interval] # => 4 (months)
474
- # cursor.close
475
- #
476
- # # input bind variable
477
- # cursor = conn.parse(<<-EOS)
478
- # BEGIN
479
- # :ts1 := :ts2 + :interval;
480
- # END;
481
- # EOS
482
- # cursor.bind_param(:ts1, nil, DateTime)
483
- # cursor.bind_param(:ts2, Date.parse('1969-11-19'))
484
- # cursor.bind_param(:interval, 4, :interval_ym)
485
- # cursor.exec
486
- # cursor[:ts1].strftime('%Y-%m-%d') # => 1970-03-19
487
- # cursor.close
488
- #
489
- class IntervalYM < OCI8::BindType::OCIIntervalYM
490
- def set(val) # :nodoc:
491
- unless val.nil?
492
- val = [val / 12, val % 12]
493
- end
494
- super(val)
495
- end
496
- def get() # :nodoc:
497
- val = super()
498
- return nil if val.nil?
499
- year, month = val
500
- year * 12 + month
399
+ class LocalTime < OCI8::BindType::OCITimestamp
400
+ include OCI8::BindType::Util
401
+
402
+ def set(val) # :nodoc:
403
+ super(datetime_to_array(val, :timestamp))
404
+ end
405
+
406
+ def get() # :nodoc:
407
+ array_to_time(super(), :local)
408
+ end
409
+ end
410
+
411
+ class UTCTime < OCI8::BindType::OCITimestamp
412
+ include OCI8::BindType::Util
413
+
414
+ def set(val) # :nodoc:
415
+ super(datetime_to_array(val, :timestamp))
416
+ end
417
+
418
+ def get() # :nodoc:
419
+ array_to_time(super(), :utc)
420
+ end
421
+ end
422
+
423
+ #--
424
+ # OCI8::BindType::IntervalYM
425
+ #++
426
+ #
427
+ # This is a helper class to select or bind Oracle data type
428
+ # <tt>INTERVAL YEAR TO MONTH</tt>. The retrieved value is
429
+ # the number of months between two timestamps.
430
+ #
431
+ # The value can be applied to \DateTime#>> to shift months.
432
+ # It can be applied to \Time#months_since if activisupport has
433
+ # been loaded.
434
+ #
435
+ # === How to select <tt>INTERVAL YEAR TO MONTH</tt>
436
+ #
437
+ # <tt>INTERVAL YEAR TO MONTH</tt> is selected as an Integer.
438
+ #
439
+ # conn.exec("select (current_timestamp - hiredate) year to month from emp") do |hired_months|
440
+ # puts "hired_months = #{hired_months}"
441
+ # end
442
+ #
443
+ # == How to bind <tt>INTERVAL YEAR TO MONTH</tt>
444
+ #
445
+ # You cannot bind a bind variable as <tt>INTERVAL YEAR TO MONTH</tt> implicitly.
446
+ # It must be bound explicitly by OCI8::Cursor#bind_param.
447
+ #
448
+ # # output bind variable
449
+ # cursor = conn.parse(<<-EOS)
450
+ # BEGIN
451
+ # :interval := (:ts1 - :ts2) YEAR TO MONTH;
452
+ # END;
453
+ # EOS
454
+ # cursor.bind_param(:interval, nil, :interval_ym)
455
+ # cursor.bind_param(:ts1, DateTime.parse('1969-11-19 06:54:35 00:00'))
456
+ # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
457
+ # cursor.exec
458
+ # cursor[:interval] # => 4 (months)
459
+ # cursor.close
460
+ #
461
+ # # input bind variable
462
+ # cursor = conn.parse(<<-EOS)
463
+ # BEGIN
464
+ # :ts1 := :ts2 + :interval;
465
+ # END;
466
+ # EOS
467
+ # cursor.bind_param(:ts1, nil, DateTime)
468
+ # cursor.bind_param(:ts2, Date.parse('1969-11-19'))
469
+ # cursor.bind_param(:interval, 4, :interval_ym)
470
+ # cursor.exec
471
+ # cursor[:ts1].strftime('%Y-%m-%d') # => 1970-03-19
472
+ # cursor.close
473
+ #
474
+ class IntervalYM < OCI8::BindType::OCIIntervalYM
475
+ def set(val) # :nodoc:
476
+ unless val.nil?
477
+ val = [val / 12, val % 12]
501
478
  end
502
- end # OCI8::BindType::IntervalYM
479
+ super(val)
480
+ end
481
+ def get() # :nodoc:
482
+ val = super()
483
+ return nil if val.nil?
484
+ year, month = val
485
+ year * 12 + month
486
+ end
487
+ end # OCI8::BindType::IntervalYM
503
488
 
504
- #--
505
- # OCI8::BindType::IntervalDS
506
- #++
507
- #
508
- # (new in 2.0)
509
- #
510
- # This is a helper class to select or bind Oracle data type
511
- # <tt>INTERVAL DAY TO SECOND</tt>. The retrieved value is
512
- # the number of seconds between two typestamps as a \Float.
513
- #
514
- # Note that it is the number days as a \Rational if
515
- # OCI8::BindType::IntervalDS.unit is :day or the ruby-oci8
516
- # version is prior to 2.0.3.
517
- #
518
- # == How to bind <tt>INTERVAL DAY TO SECOND</tt>
489
+ #--
490
+ # OCI8::BindType::IntervalDS
491
+ #++
492
+ #
493
+ # (new in 2.0)
494
+ #
495
+ # This is a helper class to select or bind Oracle data type
496
+ # <tt>INTERVAL DAY TO SECOND</tt>. The retrieved value is
497
+ # the number of seconds between two typestamps as a \Float.
498
+ #
499
+ # Note that it is the number days as a \Rational if
500
+ # OCI8::BindType::IntervalDS.unit is :day or the ruby-oci8
501
+ # version is prior to 2.0.3.
502
+ #
503
+ # == How to bind <tt>INTERVAL DAY TO SECOND</tt>
504
+ #
505
+ # You cannot bind a bind variable as <tt>INTERVAL DAY TO SECOND</tt>
506
+ # implicitly. It must be bound explicitly by OCI8::Cursor#bind_param.
507
+ #
508
+ # # output bind variable
509
+ # cursor = conn.parse(<<-EOS)
510
+ # BEGIN
511
+ # :interval := (:ts1 - :ts2) DAY TO SECOND(9);
512
+ # END;
513
+ # EOS
514
+ # cursor.bind_param(:interval, nil, :interval_ds)
515
+ # cursor.bind_param(:ts1, DateTime.parse('1969-11-19 06:54:35 00:00'))
516
+ # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
517
+ # cursor.exec
518
+ # cursor[:interval] # => 10492615.0 seconds
519
+ # cursor.close
520
+ #
521
+ # # input bind variable
522
+ # cursor = conn.parse(<<-EOS)
523
+ # BEGIN
524
+ # :ts1 := :ts2 + :interval;
525
+ # END;
526
+ # EOS
527
+ # cursor.bind_param(:ts1, nil, DateTime)
528
+ # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
529
+ # cursor.bind_param(:interval, 10492615.0, :interval_ds)
530
+ # cursor.exec
531
+ # cursor[:ts1].strftime('%Y-%m-%d %H:%M:%S') # => 1969-11-19 06:54:35
532
+ # cursor.close
533
+ #
534
+ class IntervalDS < OCI8::BindType::OCIIntervalDS
535
+ @@hour = 1 / 24.to_r
536
+ @@minute = @@hour / 60
537
+ @@sec = @@minute / 60
538
+ @@fsec = @@sec / 1000000000
539
+ @@unit = :second
540
+
541
+ # call-seq:
542
+ # OCI8::BindType::IntervalDS.unit -> :second or :day
519
543
  #
520
- # You cannot bind a bind variable as <tt>INTERVAL DAY TO SECOND</tt>
521
- # implicitly. It must be bound explicitly by OCI8::Cursor#bind_param.
544
+ # (new in 2.0.3)
522
545
  #
523
- # # output bind variable
524
- # cursor = conn.parse(<<-EOS)
525
- # BEGIN
526
- # :interval := (:ts1 - :ts2) DAY TO SECOND(9);
527
- # END;
528
- # EOS
529
- # cursor.bind_param(:interval, nil, :interval_ds)
530
- # cursor.bind_param(:ts1, DateTime.parse('1969-11-19 06:54:35 00:00'))
531
- # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
532
- # cursor.exec
533
- # cursor[:interval] # => 10492615.0 seconds
534
- # cursor.close
546
+ # Retrieves the unit of interval.
547
+ def self.unit
548
+ @@unit
549
+ end
550
+
551
+ # call-seq:
552
+ # OCI8::BindType::IntervalDS.unit = :second or :day
535
553
  #
536
- # # input bind variable
537
- # cursor = conn.parse(<<-EOS)
538
- # BEGIN
539
- # :ts1 := :ts2 + :interval;
540
- # END;
541
- # EOS
542
- # cursor.bind_param(:ts1, nil, DateTime)
543
- # cursor.bind_param(:ts2, DateTime.parse('1969-07-20 20:17:40 00:00'))
544
- # cursor.bind_param(:interval, 10492615.0, :interval_ds)
545
- # cursor.exec
546
- # cursor[:ts1].strftime('%Y-%m-%d %H:%M:%S') # => 1969-11-19 06:54:35
547
- # cursor.close
554
+ # (new in 2.0.3)
548
555
  #
549
- class IntervalDS < OCI8::BindType::OCIIntervalDS
550
- @@hour = 1 / 24.to_r
551
- @@minute = @@hour / 60
552
- @@sec = @@minute / 60
553
- @@fsec = @@sec / 1000000000
554
- @@unit = :second
555
-
556
- # call-seq:
557
- # OCI8::BindType::IntervalDS.unit -> :second or :day
558
- #
559
- # (new in 2.0.3)
560
- #
561
- # Retrieves the unit of interval.
562
- def self.unit
563
- @@unit
556
+ # Changes the unit of interval. :second is the default.
557
+ def self.unit=(val)
558
+ case val
559
+ when :second, :day
560
+ @@unit = val
561
+ else
562
+ raise 'unit should be :second or :day'
564
563
  end
564
+ end
565
565
 
566
- # call-seq:
567
- # OCI8::BindType::IntervalDS.unit = :second or :day
568
- #
569
- # (new in 2.0.3)
570
- #
571
- # Changes the unit of interval. :second is the default.
572
- def self.unit=(val)
573
- case val
574
- when :second, :day
575
- @@unit = val
566
+ def set(val) # :nodoc:
567
+ unless val.nil?
568
+ if val < 0
569
+ is_minus = true
570
+ val = -val
576
571
  else
577
- raise 'unit should be :second or :day'
578
- end
579
- end
580
-
581
- def set(val) # :nodoc:
582
- unless val.nil?
583
- if val < 0
584
- is_minus = true
585
- val = -val
586
- else
587
- is_minus = false
588
- end
589
- if @@unit == :second
590
- day, val = val.divmod 86400
591
- hour, val = val.divmod 3600
592
- minute, val = val.divmod 60
593
- sec, val = val.divmod 1
594
- else
595
- day, val = val.divmod 1
596
- hour, val = (val * 24).divmod 1
597
- minute, val = (val * 60).divmod 1
598
- sec, val = (val * 60).divmod 1
599
- end
600
- fsec, val = (val * 1000000000).divmod 1
601
- if is_minus
602
- day = - day
603
- hour = - hour
604
- minute = - minute
605
- sec = - sec
606
- fsec = - fsec
607
- end
608
- val = [day, hour, minute, sec, fsec]
572
+ is_minus = false
609
573
  end
610
- super(val)
611
- end
612
-
613
- def get() # :nodoc:
614
- val = super()
615
- return nil if val.nil?
616
- day, hour, minute, sec, fsec = val
617
574
  if @@unit == :second
618
- fsec = fsec / 1000000000.0
619
- day * 86400 + hour * 3600 + minute * 60 + sec + fsec
575
+ day, val = val.divmod 86400
576
+ hour, val = val.divmod 3600
577
+ minute, val = val.divmod 60
578
+ sec, val = val.divmod 1
620
579
  else
621
- day + (hour * @@hour) + (minute * @@minute) + (sec * @@sec) + (fsec * @@fsec)
580
+ day, val = val.divmod 1
581
+ hour, val = (val * 24).divmod 1
582
+ minute, val = (val * 60).divmod 1
583
+ sec, val = (val * 60).divmod 1
584
+ end
585
+ fsec, val = (val * 1000000000).divmod 1
586
+ if is_minus
587
+ day = - day
588
+ hour = - hour
589
+ minute = - minute
590
+ sec = - sec
591
+ fsec = - fsec
622
592
  end
593
+ val = [day, hour, minute, sec, fsec]
623
594
  end
624
- end # OCI8::BindType::IntervalDS
625
- end
595
+ super(val)
596
+ end
597
+
598
+ def get() # :nodoc:
599
+ val = super()
600
+ return nil if val.nil?
601
+ day, hour, minute, sec, fsec = val
602
+ if @@unit == :second
603
+ fsec = fsec / 1000000000.0
604
+ day * 86400 + hour * 3600 + minute * 60 + sec + fsec
605
+ else
606
+ day + (hour * @@hour) + (minute * @@minute) + (sec * @@sec) + (fsec * @@fsec)
607
+ end
608
+ end
609
+ end # OCI8::BindType::IntervalDS
626
610
  end # OCI8::BindType
627
611
  end # OCI8