Class: ActiveGraph::Shared::TypeConverters::DurationConverter

Inherits:
BaseConverter
  • Object
show all
Defined in:
lib/active_graph/shared/type_converters.rb

Overview

Converts ActiveSupport::Duration to/from the driver-native Neo4j::Driver::Types::Duration. Kept for backwards compatibility: since driver 6.2.1 a Neo4j duration is a Types::Duration, but models may still declare type: ActiveSupport::Duration. The mapping is field-to-field (parts <-> months/days/seconds/nanoseconds) and value-exact; the only soft spot is a fractional calendar month, which has no exact finer form and degrades to seconds via ActiveSupport's own rate.

Class Method Summary collapse

Methods inherited from BaseConverter

converted?, #supports_array?

Class Method Details

.convert_typeObject



197
198
199
# File 'lib/active_graph/shared/type_converters.rb', line 197

def convert_type
  ActiveSupport::Duration
end

.db_typeObject



201
202
203
# File 'lib/active_graph/shared/type_converters.rb', line 201

def db_type
  Neo4j::Driver::Types::Duration
end

.to_db(value) ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/active_graph/shared/type_converters.rb', line 205

def to_db(value)
  parts = Hash.new(0).merge(value.parts)
  months_f = parts[:years] * 12 + parts[:months]
  days_f = parts[:weeks] * 7 + parts[:days]
  months = months_f.to_i
  days = days_f.to_i
  # whole calendar units stay put; fractional months/days cascade into
  # seconds rather than truncating (which would lose magnitude)
  seconds = parts[:hours] * 3600 + parts[:minutes] * 60 + parts[:seconds] +
            (months_f - months) * ActiveSupport::Duration::SECONDS_PER_MONTH +
            (days_f - days) * ActiveSupport::Duration::SECONDS_PER_DAY
  Neo4j::Driver::Types::Duration.new(months, days, seconds.floor, ((seconds % 1) * 1_000_000_000).round)
end

.to_ruby(value) ⇒ Object



219
220
221
222
223
224
225
226
# File 'lib/active_graph/shared/type_converters.rb', line 219

def to_ruby(value)
  return value if value.is_a?(ActiveSupport::Duration)
  # map each Neo4j field back to its ActiveSupport unit, field-to-field,
  # so the calendar structure survives the round trip
  ActiveSupport::Duration.months(value.months) +
    ActiveSupport::Duration.days(value.days) +
    ActiveSupport::Duration.seconds(value.seconds + Rational(value.nanoseconds, 1_000_000_000))
end