module Eco module API class Session class BatchStatus < Common::Session::BaseSession TYPES = [:exact, :search] attr_reader :queue, :method, :type attr_reader :root class << self def valid_type?(value) TYPES.include?(value) end end def initialize(e, queue:, method:, type: :exact) super(e) fatal("In batch operations you must batch an array. Received: #{queue}") unless queue && queue.is_a?(Array) self.type = type @method = method @queue = queue @hash = @queue.each_with_index.map do |entry, i| [entry, i] end.to_h @responses = [] @person_match = [] @people_match = Array.new(@queue.length, []) end def root=(object) @root = object end def type=(value) fatal("Invalid :type '#{value}. You must specify type: as one of #{TYPES} ") unless self.class.valid_type?(value) @type = value end def [](key) @responses[to_index(key)] end def []=(key, response) @responses[to_index(key)] = response end def person(key) return self[key].result if success?(key) nil end def person_match(key) @person_match[to_index(key)] end def set_person_match(key, person) @person_match[to_index(key)] = person end def people_match(key) @people_match[to_index(key)] end def set_people_match(key, people) @people_match[to_index(key)] = people end def received?(key) !!self[key] end def success?(key) self[key]&.success? end def people fatal "This batch wasn't a 'get'. Can't obtain people without 'get' method" unless method == :get if type == :exact out = Array(queue.length) @responses.each_with_index do |respose, i| out[i] = response.result end elsif type == :search out = [] queue.each_with_index.map do |entry, i| pers = person(entry) pers ||= person_match(entry) out += pers ? [pers] : people_match(entry) end end out end def error_queries queue.each_with_index.map do |query,i| unless self[i] pp "Error: query with no response. You might have duplicated entries in your queue.\n" msg = "Queue length: #{queue.length}\n" msg += "Query with no response. Person: #{person_ref(query)}\n" queue.map do |entry| if entry.id == query.id || entry.external_id == query.external_id || entry.email == query.email msg += "It could be this peson entry: #{person_ref(entry)}\n" end end raise msg end self[i].success? ? nil : query end.compact end def errors? queue.any? {|query| !self[query].success?} end def errors_count error_queries.length end def str_error(key) msg = "" unless success?(key) i = to_index(key) entry = queue[i] response = self[i] msg = "Error #{response.status}: #{response.body}\n" msg += "-- Failed to batch #{method} (entry #{i+1}). Person: #{person_ref(entry)}" end msg end def str_errors(sort: :by_status) queries = error_queries if sort == :by_status queries = error_queries.sort_by do |query| self[query].status end end strs = [] if queries.length > 0 strs = queries.map {|query| str_error(query)} end strs end def print_error(key) unless success?(key) logger.error(str_error(key)) end end def print_errors(sort: :by_status) strs = str_errors(sort: sort) if strs.length > 0 logger.info() logger.error("There were #{strs.length} errors:\n" + strs.join("\n")) else logger.info("There were no errors for the current batch '#{method}'!! ;)") end end private def person_ref(entry) is_person = entry.is_a?(Ecoportal::API::Internal::Person) || entry.is_a?(Ecoportal::API::V1::Person) ref = nil ref = "'#{entry.name}' ('#{entry.external_id}': '#{entry.email}')" if is_person ref end def to_index(key) key.is_a?(Integer) ? valid_index(index: key) : valid_index(entry: key) end def valid_index(index: nil, entry: nil) index ||= @hash[entry] unless index && index < @queue.length fatal "You must provide either the index or the original entry object of the batch" end index end end end end end