1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-02 13:24:20 +01:00
fab-manager/app/services/footprint_service.rb

63 lines
2.4 KiB
Ruby
Raw Normal View History

2019-09-18 15:09:14 +02:00
# frozen_string_literal: true
require 'checksum'
2019-09-18 15:09:14 +02:00
# Provides helper methods to compute footprints
class FootprintService
class << self
# Compute the footprint
# @param klass a class inheriting from Footprintable
# @param item an instance of the provided class
# @param sort_on the items in database by the provided criterion, to find the previous one
def compute_footprint(klass, item, sort_on = 'id')
Checksum.text(FootprintService.footprint_data(klass, item, sort_on))
end
2020-07-21 19:25:21 +02:00
# Return the original data string used to compute the footprint
# @param klass a class inheriting from Footprintable
# @param item an instance of the provided class
# @param sort_on the items in database by the provided criterion, to find the previous one
def footprint_data(klass, item, sort_on = 'id')
raise TypeError unless item.is_a? klass
2019-09-18 15:09:14 +02:00
previous = klass.where("#{sort_on} < ?", item[sort_on])
.order("#{sort_on} DESC")
.limit(1)
2019-09-18 15:09:14 +02:00
columns = FootprintService.footprint_columns(klass)
2019-09-18 15:09:14 +02:00
"#{columns.map { |c| comparable(item[c]) }.join}#{previous.first ? previous.first.footprint : ''}"
end
2020-07-21 19:25:21 +02:00
# Return an ordered array of the columns used in the footprint computation
# @param klass a class inheriting from Footprintable
def footprint_columns(klass)
klass.columns.map(&:name).delete_if { |c| %w[footprint updated_at].concat(klass.columns_out_of_footprint).include? c }
end
# Logs a debugging message to help finding why a footprint is invalid
# @param klass a class inheriting from Footprintable
# @param item an instance of the provided class
def debug_footprint(klass, item)
columns = FootprintService.footprint_columns(klass)
current = FootprintService.footprint_data(klass, item)
saved = FootprintDebug.find_by(footprint: item.footprint, klass: klass.name)
puts "Debug footprint for #{klass} [ id: #{item.id} ]"
puts '-----------------------------------------'
puts "columns: [ #{columns.join(', ')} ]"
puts "current: #{current}"
puts " saved: #{saved&.data}"
puts '-----------------------------------------'
end
private
# Return a comparable value for jsonb fields (with keys ordered alphabetically)
def comparable(value)
return value unless value.class == Hash
2020-07-21 19:25:21 +02:00
value.sort.to_h
end
2019-09-18 15:09:14 +02:00
end
end