Module: Sequel::Postgres::ExtendedDateSupport

Defined in:
lib/sequel/extensions/pg_extended_date_support.rb

Defined Under Namespace

Modules: DatasetMethods

Constant Summary collapse

DATETIME_YEAR_1 =
DateTime.new(1)
TIME_YEAR_1 =
Time.at(-62135596800).utc
INFINITE_TIMESTAMP_STRINGS =
['infinity'.freeze, '-infinity'.freeze].freeze
INFINITE_DATETIME_VALUES =
([PLUS_INFINITY, MINUS_INFINITY] + INFINITE_TIMESTAMP_STRINGS).freeze
PLUS_DATE_INFINITY =
Date::Infinity.new
MINUS_DATE_INFINITY =
-PLUS_DATE_INFINITY
RATIONAL_60 =
Rational(60)
TIME_CAN_PARSE_BC =
RUBY_VERSION >= '2.5'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#convert_infinite_timestampsObject

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.



67
68
69
# File 'lib/sequel/extensions/pg_extended_date_support.rb', line 67

def convert_infinite_timestamps
  @convert_infinite_timestamps
end

Class Method Details

.extended(db) ⇒ Object

Add dataset methods and update the conversion proces for dates and timestamps.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/sequel/extensions/pg_extended_date_support.rb', line 35

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

Instance Method Details

#bound_variable_arg(arg, conn) ⇒ Object

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.



54
55
56
57
58
59
60
61
# File 'lib/sequel/extensions/pg_extended_date_support.rb', line 54

def bound_variable_arg(arg, conn)
  case arg
  when Time, Date
    @default_dataset.literal_date_or_time(arg)
  else
    super
  end
end

#to_application_timestamp(value) ⇒ Object

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.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/sequel/extensions/pg_extended_date_support.rb', line 107

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