Repository URL to install this package:
|
Version:
0.4.4 ▾
|
# frozen_string_literal: true
require 'set'
require 'datasync/exceptions'
require 'datasync/sync_operation'
require 'datasync/sync_runner'
module Datasync
# Base mapper class
class Mapper
attr_accessor :title, :source_key, :source_proc, :target_key, :target_proc,
:mapping_proc, :match_fields, :match_situations, :target_key_from_db
def initialize
@handler = {}
@parser = {}
@formatter = {}
@limit = {}
@match_fields = []
@match_situations = []
@target_key_from_db = true
end
def parser(field, parse_proc)
@parser[field] = parse_proc
end
def formatter(field, format_proc)
@formatter[field] = format_proc
end
def handler(situation, handler)
@handler[situation] = handler
end
def limit(situation, maximum)
@limit[situation] = maximum
end
def limits
@limit
end
def handle(operation, situation, source, target)
@handler[situation].call(self, operation, situation, source, target) if @handler.key? situation
end
def parse(raw_source)
parsed_fields = @parser.map do |field, parser_proc|
value = raw_source[field]
parsed_value = parser_proc.call(value)
[field, parsed_value]
end
raw_source.merge Hash[parsed_fields]
rescue StandardError => e
raise ParserError, e.to_s
end
def map(...)
mapping_proc.call(...)
rescue StandardError => e
raise MapperError, e.to_s
end
def format(mapped_object)
formatted_fields = @formatter.map do |field, formatter_proc|
value = mapped_object[field]
formatted_value = formatter_proc.call(value)
[field, formatted_value]
end
mapped_object.merge Hash[formatted_fields]
rescue StandardError => e
raise FormatterError, e.to_s
end
def matching_valid?
return true if @match_situations.empty?
return false if @match_fields.empty?
true
end
def option(name, *)
raise OptionError, "Unknown option #{name}"
end
def validate! # rubocop:disable Metrics/CyclomaticComplexity
raise ValidationError, 'Title must be specified' unless @title
raise ValidationError, 'Source must be specified' unless @source_key && @source_proc
raise ValidationError, 'Target must be specified' unless @target_key && @target_proc
raise ValidationError, 'Matching is specified, but no fields' unless matching_valid?
raise ValidationError, 'Mapping must be specified' unless @mapping_proc
end
def sync!
operation = SyncRunner.new(sync_class.new(self))
operation.run!
operation
end
end
end