class InventoryRefresh::InventoryCollection::DataStorage

Attributes

data[RW]

@return [Array<InventoryObject>] objects of the InventoryCollection in an Array

index_proxy[R]
inventory_collection[R]

Public Class Methods

new(inventory_collection, secondary_refs) click to toggle source

@param inventory_collection [InventoryRefresh::InventoryCollection] InventoryCollection object we want the storage

for

@param secondary_refs [Hash] Secondary_refs in format {:name_of_the_ref => [:attribute1, :attribute2]}

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 31
def initialize(inventory_collection, secondary_refs)
  @inventory_collection = inventory_collection
  @data                 = []

  @index_proxy = InventoryRefresh::InventoryCollection::Index::Proxy.new(inventory_collection, secondary_refs)
end

Public Instance Methods

<<(inventory_object) click to toggle source

Adds passed InventoryObject into the InventoryCollection's storage

@param inventory_object [InventoryRefresh::InventoryObject] @return [InventoryRefresh::InventoryCollection] Returns current InventoryCollection, to allow chaining

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 42
def <<(inventory_object)
  if inventory_object.manager_uuid.present? && !primary_index.find(inventory_object.manager_uuid)
    data << inventory_object

    # TODO(lsmola) Maybe we do not need the secondary indexes here?
    # Maybe we should index it like LocalDb indexes, on demand, and storing what was
    # indexed? Maybe we should allow only lazy access and no direct find from a parser. Since for streaming
    # refresh, things won't be parsed together and no full state will be taken.
    build_primary_index_for(inventory_object)
    build_secondary_indexes_for(inventory_object)
  end
  inventory_collection
end
Also aliased as: push
build(hash) click to toggle source

Finds of builds a new InventoryObject. By building it, we also put in into the InventoryCollection's storage.

@param hash [Hash] Hash that needs to contain attributes defined in :manager_ref of the

InventoryCollection

@return [InventoryRefresh::InventoryObject] Found or built InventoryObject object

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 78
def build(hash)
  hash, uuid, inventory_object = primary_index_scan(hash)

  # Return InventoryObject if found in primary index
  return inventory_object unless inventory_object.nil?

  # We will take existing skeletal record, so we don't duplicate references for saving. We can have duplicated
  # reference from local_db index, (if we are using .find in parser, that causes N+1 db queries), but that is ok,
  # since that one is not being saved.
  inventory_object = skeletal_primary_index.delete(uuid)

  # We want to update the skeletal record with actual data
  inventory_object&.assign_attributes(hash)

  # Build the InventoryObject
  inventory_object ||= new_inventory_object(enrich_data(hash))

  # Store new InventoryObject and return it
  push(inventory_object)
  inventory_object
end
build_partial(hash) click to toggle source

Finds of builds a new InventoryObject with incomplete data.

@param hash [Hash] Hash that needs to contain attributes defined in :manager_ref of the

InventoryCollection

@return [InventoryRefresh::InventoryObject] Found or built InventoryObject object

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 105
def build_partial(hash)
  skeletal_primary_index.build(hash)
end
find_or_build(manager_uuid) click to toggle source

Finds of builds a new InventoryObject. By building it, we also put in into the InventoryCollection's storage.

@param manager_uuid [String] manager_uuid of the InventoryObject @return [InventoryRefresh::InventoryObject] Found or built InventoryObject

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 62
def find_or_build(manager_uuid)
  raise "The uuid consists of #{manager_ref.size} attributes, please find_or_build_by method" if manager_ref.size > 1

  find_or_build_by(manager_ref.first => manager_uuid)
end
find_or_build_by(hash) click to toggle source

(see build)

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 69
def find_or_build_by(hash)
  build(hash)
end
from_hash(inventory_objects_data, available_inventory_collections) click to toggle source
# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 120
def from_hash(inventory_objects_data, available_inventory_collections)
  InventoryRefresh::InventoryCollection::Serialization
    .new(inventory_collection)
    .from_hash(inventory_objects_data, available_inventory_collections)
end
push(inventory_object)
Alias for: <<
to_a() click to toggle source

Returns array of built InventoryObject objects

@return [Array<InventoryRefresh::InventoryObject>] Array of built InventoryObject objects

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 112
def to_a
  data
end
to_hash() click to toggle source
# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 116
def to_hash
  InventoryRefresh::InventoryCollection::Serialization.new(inventory_collection).to_hash
end

Private Instance Methods

assert_all_keys_present(hash) click to toggle source
# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 144
def assert_all_keys_present(hash)
  if manager_ref.any? { |x| !hash.key?(x) }
    raise "Needed find_or_build_by keys are: #{manager_ref}, data provided: #{hash}"
  end
end
assert_only_primary_index(data) click to toggle source
# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 150
def assert_only_primary_index(data)
  named_ref.each do |key|
    if data[key].kind_of?(InventoryRefresh::InventoryObjectLazy) && !data[key].primary?
      raise "Wrong index for key :#{key}, all references under this index must point to default :ref called"\
            " :manager_ref. Any other :ref is not valid. This applies also to nested lazy links."
    end
  end
end
enrich_data(hash) click to toggle source

Returns new hash enriched by (see InventoryRefresh::InventoryCollection#default_values) hash

@param hash [Hash] Input hash @return [Hash] Enriched hash by (see InventoryRefresh::InventoryCollection#default_values)

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 163
def enrich_data(hash)
  # This is 25% faster than default_values.merge(hash)
  {}.merge!(default_values).merge!(hash)
end
primary_index_scan(hash) click to toggle source

Scans primary index for existing InventoryObject, that would be equivalent to passed hash. It also returns enriched data and uuid, so we do not have to compute it multiple times.

@param hash [Hash] Attributes for the InventoryObject @return [Array(Hash, String, InventoryRefresh::InventoryObject)] Returns enriched data, uuid and InventoryObject if found (otherwise nil)

# File lib/inventory_refresh/inventory_collection/data_storage.rb, line 134
def primary_index_scan(hash)
  hash = enrich_data(hash)

  assert_all_keys_present(hash)
  assert_only_primary_index(hash)

  uuid = ::InventoryRefresh::InventoryCollection::Reference.build_stringified_reference(hash, named_ref)
  return hash, uuid, primary_index.find(uuid)
end