ManageIQ/inventory_refresh

View on GitHub
lib/inventory_refresh/inventory_collection/references_storage.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
module InventoryRefresh
  class InventoryCollection
    class ReferencesStorage
      # @return [Hash] A set of InventoryObjects manager_uuids, which tells us which InventoryObjects were
      #         referenced by other InventoryObjects using a lazy_find.
      attr_reader :references

      # @return [Set] A set of InventoryObject attributes names, which tells us InventoryObject attributes
      #         were referenced by other InventoryObject objects using a lazy_find with :key.
      attr_reader :attribute_references

      def initialize(index_proxy)
        @index_proxy                   = index_proxy
        @references                    = {}
        @references[primary_index_ref] = {}
        @attribute_references          = Set.new
      end

      # Adds reference to the storage. The reference can be already existing, otherwise we attempt to build it.
      #
      # @param reference_data [InventoryRefresh::InventoryCollection::References, Hash, Object] Either existing Reference
      #        object, or data we will build the reference object from. For InventoryCollection with :manager_ref size
      #        bigger than 1, it's required to pass a Hash.
      # @param key [String] If the reference comes from a InventoryObjectLazy, pointing to specific attribute using :key
      #        we want to record what attribute was referenced.
      # @param ref [Symbol] A key to specific reference, if it's a reference pointing to something else than primary
      #        index.
      def add_reference(reference_data, key: nil, ref: nil)
        reference           = build_reference(reference_data, ref)
        specific_references = references[reference.ref] ||= {}

        specific_references[reference.stringified_reference] = reference

        # If we access an attribute of the value, using a :key, we want to keep a track of that
        attribute_references << key if key
      end

      # Adds reference to the storage. The reference can be already existing, otherwise we attempt to build it. This is
      # simplified version of add_reference, not allowing to define :key or :ref.
      #
      # @param reference_data [InventoryRefresh::InventoryCollection::References, Hash, Object] Either existing Reference
      #        object, or data we will build the reference object from. For InventoryCollection with :manager_ref size
      #        bigger than 1, it's required to pass a Hash.
      def <<(reference_data)
        add_reference(reference_data)
      end

      # Adds array of references to the storage. The reference can be already existing, otherwise we attempt to build
      # it.
      #
      # @param references_array [Array] Array of reference objects acceptable by add_reference method.
      # @param ref [Symbol] A key to specific reference, if it's a reference pointing to something else than primary
      #        index.
      # @return [InventoryRefresh::InventoryCollection::ReferencesStorage] Returns self
      def merge!(references_array, ref: nil)
        references_array.each { |reference_data| add_reference(reference_data, :ref => ref) }
        self
      end

      # @return [Hash{String => InventoryRefresh::InventoryCollection::Reference}] Hash of indexed Reference objects
      def primary_references
        references[primary_index_ref]
      end

      # Builds a Reference object
      #
      # @param reference_data [InventoryRefresh::InventoryCollection::References, Hash, Object] Either existing Reference
      #        object, or data we will build the reference object from. For InventoryCollection with :manager_ref size
      #        bigger than 1, it's required to pass a Hash.
      def build_reference(reference_data, ref = nil)
        ref ||= primary_index_ref
        return reference_data if reference_data.kind_of?(::InventoryRefresh::InventoryCollection::Reference)

        ::InventoryRefresh::InventoryCollection::Reference.new(reference_data, ref, named_ref(ref))
      end

      # Builds string uuid from passed Hash and keys
      #
      # @param hash [Hash] Hash data
      # @param keys [Array<Symbol>] Indexes into the Hash data
      # @return [String] Concatenated values on keys from data
      def build_stringified_reference(hash, keys)
        ::InventoryRefresh::InventoryCollection::Reference.build_stringified_reference(hash, keys)
      end

      # Builds string uuid from passed Object and keys
      #
      # @param record [ApplicationRecord] ActiveRecord record
      # @param keys [Array<Symbol>] Indexes into the Hash data
      # @return [String] Concatenated values on keys from data
      def build_stringified_reference_for_record(record, keys)
        ::InventoryRefresh::InventoryCollection::Reference.build_stringified_reference_for_record(record, keys)
      end

      private

      # @return [InventoryRefresh::InventoryCollection::Index::Proxy] Index::Proxy object associated to this reference
      #         storage
      attr_reader :index_proxy

      delegate :named_ref,
               :primary_index_ref,
               :to => :index_proxy
    end
  end
end