module Sequel::Postgres::ExtendedDateSupport
Constants
- CONVERT_TYPES
:nocov:
- DATETIME_YEAR_1
- INFINITE_DATETIME_VALUES
- INFINITE_TIMESTAMP_STRINGS
- MINUS_DATE_INFINITY
- PLUS_DATE_INFINITY
- RATIONAL_60
- TIME_CAN_PARSE_BC
- TIME_YEAR_1
Attributes
Whether infinite timestamps/dates should be converted on retrieval. By default, no conversion is done, so an error is raised if you attempt to retrieve an infinite timestamp/date. You can set this to :nil to convert to nil, :string to leave as a string, or :float to convert to an infinite float.
Public Class Methods
Add dataset methods and update the conversion proces for dates and timestamps.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 34 def self.extended(db) db.extend_datasets(DatasetMethods) procs = db.conversion_procs procs[1082] = ::Sequel.method(:string_to_date) procs[1184] = procs[1114] = db.method(:to_application_timestamp) if ocps = db.instance_variable_get(:@oid_convertor_map) # Clear the oid convertor map entries for timestamps if they # exist, so it will regenerate new ones that use this extension. # This is only taken when using the jdbc adapter. Sequel.synchronize do ocps.delete(1184) ocps.delete(1114) end end end
Public Instance Methods
Handle BC dates and times in bound variables. This is necessary for Date values when using both the postgres and jdbc adapters, but also necessary for Time values on jdbc.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 53 def bound_variable_arg(arg, conn) case arg when Time, Date @default_dataset.literal_date_or_time(arg) else super end end
Set whether to allow infinite timestamps/dates. Make sure the conversion proc for date reflects that setting.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 70 def convert_infinite_timestamps=(v) @convert_infinite_timestamps = case v when Symbol v when 'nil' :nil when 'string' :string when 'date' :date when 'float' :float when String, true typecast_value_boolean(v) else false end pr = old_pr = Sequel.method(:string_to_date) if @convert_infinite_timestamps pr = lambda do |val| case val when *INFINITE_TIMESTAMP_STRINGS infinite_timestamp_value(val) else old_pr.call(val) end end end add_conversion_proc(1082, pr) end
Handle BC dates in timestamps by moving the BC from after the time to after the date, to appease ruby's date parser. If #convert_infinite_timestamps is true and the value is infinite, return an appropriate value based on the #convert_infinite_timestamps setting.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 106 def to_application_timestamp(value) if value.is_a?(String) && (m = /((?:[-+]\d\d:\d\d)(:\d\d)?)?( BC)?\z/.match(value)) && (m[2] || m[3]) if m[3] value = value.sub(' BC', '').sub(' ', ' BC ') end if m[2] dt = if Sequel.datetime_class == DateTime DateTime.parse(value) elsif TIME_CAN_PARSE_BC Time.parse(value) # :nocov: else DateTime.parse(value).to_time # :nocov: end Sequel.convert_output_timestamp(dt, Sequel.application_timezone) else super(value) end elsif convert_infinite_timestamps case value when *INFINITE_TIMESTAMP_STRINGS infinite_timestamp_value(value) else super end else super end end
Private Instance Methods
Return an appropriate value for the given infinite timestamp string.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 141 def infinite_timestamp_value(value) case convert_infinite_timestamps when :nil nil when :string value when :date value == 'infinity' ? PLUS_DATE_INFINITY : MINUS_DATE_INFINITY else value == 'infinity' ? PLUS_INFINITY : MINUS_INFINITY end end
If the value is an infinite value (either an infinite float or a string returned by by PostgreSQL for an infinite date), return it without converting it if #convert_infinite_timestamps is set.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 157 def typecast_value_date(value) if convert_infinite_timestamps case value when *INFINITE_DATETIME_VALUES value else super end else super end end
If the value is an infinite value (either an infinite float or a string returned by by PostgreSQL for an infinite timestamp), return it without converting it if #convert_infinite_timestamps is set.
# File lib/sequel/extensions/pg_extended_date_support.rb, line 173 def typecast_value_datetime(value) if convert_infinite_timestamps case value when *INFINITE_DATETIME_VALUES value else super end else super end end