Class: Sequel::Postgres::IntervalDatabaseMethods::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/sequel/extensions/pg_interval.rb

Overview

Creates callable objects that convert strings into ActiveSupport::Duration instances.

Constant Summary collapse

USE_PARTS_ARRAY =

Whether ActiveSupport::Duration.new takes parts as array instead of hash

!defined?(ActiveSupport::VERSION::STRING) || ActiveSupport::VERSION::STRING < '5.1'
SECONDS_PER_MONTH =

:nocov:

2592000
SECONDS_PER_YEAR =
31557600

Instance Method Summary collapse

Instance Method Details

#call(string) ⇒ Object

Parse the interval input string into an ActiveSupport::Duration instance.

Raises:

  • (InvalidValue)

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
# File 'lib/sequel/extensions/pg_interval.rb', line 85

def call(string)
  raise(InvalidValue, "invalid or unhandled interval format: #{string.inspect}") unless matches = /\A([+-]?\d+ years?\s?)?([+-]?\d+ mons?\s?)?([+-]?\d+ days?\s?)?(?:(?:([+-])?(\d{2,10}):(\d\d):(\d\d(\.\d+)?))|([+-]?\d+ hours?\s?)?([+-]?\d+ mins?\s?)?([+-]?\d+(\.\d+)? secs?\s?)?)?\z/.match(string)

  value = 0
  parts = {}

  if v = matches[1]
    v = v.to_i
    value += SECONDS_PER_YEAR * v
    parts[:years] = v
  end
  if v = matches[2]
    v = v.to_i
    value += SECONDS_PER_MONTH * v
    parts[:months] = v
  end
  if v = matches[3]
    v = v.to_i
    value += 86400 * v
    parts[:days] = v
  end
  if matches[5]
    seconds = matches[5].to_i * 3600 + matches[6].to_i * 60
    seconds += matches[8] ? matches[7].to_f : matches[7].to_i
    seconds *= -1 if matches[4] == '-'
    value += seconds
    parts[:seconds] = seconds
  elsif matches[9] || matches[10] || matches[11]
    seconds = 0
    if v = matches[9]
      seconds += v.to_i * 3600
    end
    if v = matches[10]
      seconds += v.to_i * 60
    end
    if v = matches[11]
      seconds += matches[12] ? v.to_f : v.to_i
    end
    value += seconds
    parts[:seconds] = seconds
  end

  # :nocov:
  if USE_PARTS_ARRAY
    parts = parts.to_a
  end
  # :nocov:

  ActiveSupport::Duration.new(value, parts)
end