Class: JetSet::Mapper
- Inherits:
-
Object
- Object
- JetSet::Mapper
- Defined in:
- lib/jet_set/mapper.rb
Overview
A converter of a data rows to object model according to a mapping.
Instance Method Summary collapse
-
#initialize(entity_builder, mapping, container) ⇒ Mapper
constructor
- Parameters:
entity_builder
- an instance of
JetSet::EntityBuilder
mapping
- an instance of
JetSet::Mapping
container
-
IoC container (
Hypo::Container
) for resolving entity dependencies.
- an instance of
- an instance of
- Parameters:
-
#map(type, row_hash, session, prefix = type.name.underscore) ⇒ Object
- Converts a table row to an object Parameters:
type
- entity type defined in the mapping
row_hash
- hash representation of table row
session
- instance of
JetSet::Session
prefix
-
(optional) custom prefix for extracting the type attributes, i.e.“customer” for query: “SELECT u.name AS customer__name from users u”.
- instance of
- hash representation of table row
- entity type defined in the mapping
- Converts a table row to an object Parameters:
-
#map_association(target, name, rows, session) ⇒ Object
Constructs object model relationships between of complex objects.
Constructor Details
#initialize(entity_builder, mapping, container) ⇒ Mapper
Parameters:
+entity_builder+:: an instance of +JetSet::EntityBuilder+
+mapping+:: an instance of +JetSet::Mapping+
+container+:: IoC container (+Hypo::Container+) for resolving entity dependencies
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/jet_set/mapper.rb', line 12 def initialize(entity_builder, mapping, container) @entity_builder = entity_builder @mapping = mapping @container = container @mapping.entity_mappings.values.each do |entity_mapping| entity_name = "jet_set__#{entity_mapping.type.name.underscore}".to_sym container.register(entity_mapping.type, entity_name) end end |
Instance Method Details
#map(type, row_hash, session, prefix = type.name.underscore) ⇒ Object
Converts a table row to an object Parameters:
+type+:: entity type defined in the mapping
+row_hash+:: hash representation of table row
+session+:: instance of +JetSet::Session+
+prefix+:: (optional) custom prefix for extracting the type attributes,
i.e."customer" for query:
"SELECT u.name AS customer__name from users u"
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/jet_set/mapper.rb', line 31 def map(type, row_hash, session, prefix = type.name.underscore) entity_name = type.name.underscore.to_sym resolve_name = "jet_set__#{type.name.underscore}".to_sym entity_mapping = @mapping.get(entity_name) row = Row.new(row_hash, entity_mapping.fields, prefix) reference_hash = {} row.reference_names.each do |reference_name| if entity_mapping.references.key? reference_name.to_sym reference_id_name = reference_name + '__id' unless row_hash[reference_id_name.to_sym].nil? type = entity_mapping.references[reference_name.to_sym].type reference_hash[reference_name.to_sym] = map(type, row_hash, session, reference_name) end end end object = @container.resolve(resolve_name, row.attributes_hash.merge(reference_hash)) entity = @entity_builder.create(object) entity.load_attributes!(row.attributes) reference_hash.each do |key, value| entity.set_reference! key.to_s, value end session.attach(entity) entity end |
#map_association(target, name, rows, session) ⇒ Object
Constructs object model relationships between of complex objects. Parameters:
+target+:: an instance or an array of entity instances
+name+:: name of the target attribute to bind
+rows+:: an array of database rows (hashes)
+session+:: an instance of +JetSet::Session+
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/jet_set/mapper.rb', line 66 def map_association(target, name, rows, session) singular_name = name.to_s.singularize.to_sym entity_mapping = @mapping.get(singular_name) if target.is_a? Array relations = {} target_name = target[0].class.name.underscore back_relations = {} if rows.length > 0 target_id_name = "#{target_name.underscore}_id" target_reference = entity_mapping.references[target_name.to_sym] rows.each do |row| relation = map(entity_mapping.type, row, session, singular_name.to_s) target_id = row[target_id_name.to_sym] if target_id.nil? raise MapperError, "Field \"#{target_id_name}\" is not defined in the query but it's required to construct \"#{name} to #{target_name}\" association. Just add it to SELECT clause." end relations[target_id] ||= [] relations[target_id] << relation back_relations[relation.id] = target.select{|t| t.id == target_id} end target.each do |entry| target_id = entry.id relation_objects = relations[target_id] if relation_objects if target_reference relation_objects.each {|obj| obj.set_reference!(target_reference.name, entry)} end # set forward collection relation entry.set_collection!(name, relations[target_id]) # set reverse collection relation if it's present if entity_mapping.collections[target_name.pluralize.to_sym] relation_objects.each{|obj| obj.set_collection!(target_name.pluralize.to_sym, back_relations[obj.id])} end end end end ids = [] relations.values.each do |associations| ids << associations.map{|a| a.id} end {result: relations, ids: ids.flatten.uniq} else result = rows.map do |row| map(entity_mapping.type, row, session, singular_name.to_s) end target.set_collection!(name, result) {result: result, ids: result.map {|i| i.id}} end end |