Class: Torque::PostgreSQL::Adapter::OID::Interval

Inherits:
ActiveModel::Type::Value
  • Object
show all
Defined in:
lib/torque/postgresql/adapter/oid/interval.rb

Constant Summary collapse

CAST_PARTS =
[:years, :months, :days, :hours, :minutes, :seconds]

Instance Method Summary collapse

Instance Method Details

#assert_valid_value(value) ⇒ Object

Check if the user input has the correct format



70
71
72
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 70

def assert_valid_value(value)
  # TODO: Implement!
end

#cast(value) ⇒ Object

Accepts database-style string, numeric as seconds, array of parts padded to left, or a hash

Examples:

[12, 0, 0]
produces: 12 hours, 0 minutes, and 0 seconds

[nil, nil, 3, 0, 0, 0]
produces: 3 days, 0 hours, 0 minutes, and 0 seconds

{minutes: 12, seconds: 0}
produces: 12 minutes, and 0 seconds


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 25

def cast(value)
  return if value.blank?
  case value
  when ::String then deserialize(value)
  when ::ActiveSupport::Duration then value
  when ::Numeric
    parts = CAST_PARTS.map do |part|
      rest, value = value.divmod(1.send(part))
      rest == 0 ? nil : [part, rest]
    end
    parts_to_duration(parts.compact)
  when ::Array
    value.compact!
    parts = CAST_PARTS.drop(6 - value.size).zip(value).to_h
    parts_to_duration(parts)
  when ::Hash
    parts_to_duration(value)
  else
    value
  end
end

#deserialize(value) ⇒ Object

Uses the ActiveSupport::Duration::ISO8601Parser See ActiveSupport::Duration#parse The value must be Integer when no precision is given



50
51
52
53
54
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 50

def deserialize(value)
  return if value.blank?
  parts = ActiveSupport::Duration::ISO8601Parser.new(value).parse!
  parts_to_duration(parts)
end

#parts_to_duration(parts) ⇒ Object

Transform a list of parts into a duration object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 75

def parts_to_duration(parts)
  parts = parts.to_h.with_indifferent_access.slice(*CAST_PARTS)
  return 0.seconds if parts.blank?

  seconds = 0
  parts = parts.map do |part, num|
    num = num.to_i unless num.is_a?(Numeric)
    if num > 0
      seconds += num.send(part).value
      [part, num]
    end
  end
  ActiveSupport::Duration.new(seconds, parts.compact)
end

#serialize(value) ⇒ Object

Uses the ActiveSupport::Duration::ISO8601Serializer See ActiveSupport::Duration#iso8601



58
59
60
61
62
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 58

def serialize(value)
  return if value.blank?
  value = cast(value) unless value.is_a?(ActiveSupport::Duration)
  value.iso8601(precision: @scale)
end

#typeObject



9
10
11
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 9

def type
  :interval
end

#type_cast_for_schema(value) ⇒ Object

Always use the numeric value for schema dumper



65
66
67
# File 'lib/torque/postgresql/adapter/oid/interval.rb', line 65

def type_cast_for_schema(value)
  cast(value).value.inspect
end