Class: Appfuel::Repository::Mapper

Inherits:
Object
  • Object
show all
Defined in:
lib/appfuel/storage/repository/mapper.rb

Overview

The mapping registry holds all entity to db mappings. Mappings are contained within a DbEntityMapEntry object and are arranged by entity name. Each entity will hold a hash where the keys are the attribute names and the value is the entry

Direct Known Subclasses

Db::Mapper, Memory::Mapper

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app_name, map = nil) ⇒ Mapper

Returns a new instance of Mapper.



10
11
12
13
14
15
16
# File 'lib/appfuel/storage/repository/mapper.rb', line 10

def initialize(app_name, map = nil)
  @container_root_name = app_name
  if !map.nil? && !map.instance_of?(MappingCollection)
    fail "repository mappings must be a MappingCollection"
  end
  @map = map
end

Instance Attribute Details

#container_root_nameObject (readonly)

Returns the value of attribute container_root_name.



8
9
10
# File 'lib/appfuel/storage/repository/mapper.rb', line 8

def container_root_name
  @container_root_name
end

Instance Method Details

#create_entity_hash(domain_attr, value) ⇒ Object

user.role.id

id, role, user


180
181
182
183
184
# File 'lib/appfuel/storage/repository/mapper.rb', line 180

def create_entity_hash(domain_attr, value)
  domain_attr.split('.').reverse.inject(value) do |result, nested_attr|
    {nested_attr => result}
  end
end

#entity?(entity_name) ⇒ Boolean

Determine if an entity has been added

Parameters:

  • entity (String)

Returns:

  • (Boolean)


41
42
43
# File 'lib/appfuel/storage/repository/mapper.rb', line 41

def entity?(entity_name)
  map.entity?(entity_name)
end

#entity_attr?(entity_name, entity_attr, type) ⇒ Boolean

Determine if an attribute is mapped for a given entity

Parameters:

  • entity (String)

    name of the entity

  • attr (String)

    name of the attribute

Returns:

  • (Boolean)


50
51
52
# File 'lib/appfuel/storage/repository/mapper.rb', line 50

def entity_attr?(entity_name, entity_attr, type)
  map.entity_attr?(type, entity_name, entity_attr)
end

#entity_container_name(type, entity_name) ⇒ Object



70
71
72
# File 'lib/appfuel/storage/repository/mapper.rb', line 70

def entity_container_name(type, entity_name)
  map.container_name(type, entity_name)
end

#entity_value(domain, domain_attr) ⇒ Object



169
170
171
172
173
174
# File 'lib/appfuel/storage/repository/mapper.rb', line 169

def entity_value(domain, domain_attr)
  value = resolve_entity_value(domain, domain_attr)
  value = nil if undefined?(value)

  value
end

#expr_conjunction?(value) ⇒ Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/appfuel/storage/repository/mapper.rb', line 200

def expr_conjunction?(value)
  value.instance_of?(ExprConjunction)
end

#fetch_storage_class(key) ⇒ Object



99
100
101
102
# File 'lib/appfuel/storage/repository/mapper.rb', line 99

def fetch_storage_class(key)
  app_container = Appfuel.app_container(container_root_name)
  app_container[key]
end

#mapHash

The map represents domain mappings to one or more storage systems. Currently one map represents all storage. So if you have a file, and database storage for a given domain the storage attributes are the same for each interface. This will load the repository mappings from the application container if no map as been manually set.

Examples:

a map has the following structure

{
  domain_name: {
    domain_attr1: <MappingEntry>,
    domain_attr1: <MappingEntry>
  }
  ...
}

Returns:

  • (Hash)


33
34
35
# File 'lib/appfuel/storage/repository/mapper.rb', line 33

def map
  @map ||= mappings_from_container
end

#resolve_entity_value(domain, domain_attr) ⇒ Object



190
191
192
193
194
195
196
197
198
# File 'lib/appfuel/storage/repository/mapper.rb', line 190

def resolve_entity_value(domain, domain_attr)
  chain  = domain_attr.split('.')
  target = domain
  chain.each do |attr_method|
    return nil unless target.respond_to?(attr_method)
    target = target.public_send(attr_method)
  end
  target
end

#storage_attr(entity_name, entity_attr, type) ⇒ String

Returns a column name for an entity’s attribute

Parameters:

  • entity_name (String)

    qualified entity name “<feature>.<entity>”

  • entity_attr (String)

    name of the attribute

Returns:

  • (String)

Raises:

  • (RuntimeError)

    when entity not found

  • (RuntimeError)

    when attr not found



62
63
64
# File 'lib/appfuel/storage/repository/mapper.rb', line 62

def storage_attr(entity_name, entity_attr, type)
  map.storage_attr(type, entity_name, entity_attr)
end

#storage_class(type, entity_name) ⇒ Object

Returns the storage class based on type mapping foo.bar, db: auth.foo_bar,

Parameters:

  • entity (String)

    name of the entity

  • attr (String)

    name of the attribute

Returns:

  • (Object)

Raises:

  • (RuntimeError)

    when entity not found

  • (RuntimeError)

    when attr not found

  • (Dry::Contriner::Error)

    when db_class is not registered



88
89
90
91
92
93
94
95
96
97
# File 'lib/appfuel/storage/repository/mapper.rb', line 88

def storage_class(type, entity_name)
  key = storage_key(type, entity_name)
  domain_container = entity_container_name(type, entity_name)
  unless container_root_name == domain_container
    fail "You can not access a mapping outside of this container " +
      "(mapper: #{container_root_name}, entry: #{domain_container})"
  end

  fetch_storage_class(key)
end

#storage_hash(storage) ⇒ Object



115
116
117
118
119
# File 'lib/appfuel/storage/repository/mapper.rb', line 115

def storage_hash(storage)
  return storage if storage.is_a?(Hash)
  fail "storage must implement to_h" unless storage.respond_to?(:to_h)
  storage.to_h
end

#storage_key(type, entity_name) ⇒ Object



66
67
68
# File 'lib/appfuel/storage/repository/mapper.rb', line 66

def storage_key(type, entity_name)
  map.storage_key(type, entity_name)
end

#storage_map(type, domain_name) ⇒ Object



74
75
76
# File 'lib/appfuel/storage/repository/mapper.rb', line 74

def storage_map(type, domain_name)
  map.storage_map(type, domain_name)
end

#to_entity_hash(domain_name, type, storage) ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/appfuel/storage/repository/mapper.rb', line 104

def to_entity_hash(domain_name, type, storage)
  entity_attrs = {}
  storage_data = storage_hash(storage)
  map.each_attr(type, domain_name) do |domain_attr, storage_attr, skip|
    next unless storage_data.key?(storage_attr)
    value = storage_data[storage_attr]
    update_entity_hash(domain_attr, value, entity_attrs)
  end
  entity_attrs
end

#to_storage(domain, type, opts = {}) ⇒ Hash

Convert the domain into a hash of storage attributes that represent. Each storage class has its own hash of mapped attributes. A domain can have more than one storage class.

Parameters:

  • domain (Appfuel::Domain::Entity)
  • type (Symbol)

    type of storage :db, :file, :memory etc…

  • opts (Hash) (defaults to: {})
  • exclued (Hash)

    a customizable set of options

Returns:

  • (Hash)

    each key is a storage class with a hash of column name/value



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/appfuel/storage/repository/mapper.rb', line 132

def to_storage(domain, type, opts = {})
  unless domain.respond_to?(:domain_name)
    fail "Domain entity must implement :domain_name"
  end

  excluded     = opts[:exclude] || []
  data         = {}
  domain_name  = domain.domain_name
  map.each_attr(type, domain_name) do |domain_attr, storage_attr, skip|
    next if excluded.include?(storage_attr) || skip == true

    data[storage_attr] = entity_value(domain, domain_attr)
  end

  data
end

#undefined?(value) ⇒ Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/appfuel/storage/repository/mapper.rb', line 186

def undefined?(value)
  value == Types::Undefined
end

#update_entity_hash(domain_attr, value, hash) ⇒ Object

user.role.id => user_role_id 99

{

 user: {
   role: {
     id: 99
     }
   }
 }

id


161
162
163
164
165
166
167
# File 'lib/appfuel/storage/repository/mapper.rb', line 161

def update_entity_hash(domain_attr, value, hash)
  if domain_attr.include?('.')
    hash.deep_merge!(create_entity_hash(domain_attr, value))
  else
    hash[domain_attr] = value
  end
end