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::EntityBuildermapping - an instance of
JetSet::Mappingcontainer -
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::Sessionprefix -
(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 |
# 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| container.register(entity_mapping.type) 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"
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/jet_set/mapper.rb', line 30 def map(type, row_hash, session, prefix = type.name.underscore) entity_name = type.name.underscore.to_sym entity_mapping = @mapping.get(entity_name) row = Row.new(row_hash, entity_mapping.fields, prefix) object = @container.resolve(entity_name) entity = @entity_builder.create(object) entity.load_attributes!(row.attributes) row.reference_names.each do |reference_name| if entity_mapping.references.key? reference_name.to_sym type = entity_mapping.references[reference_name.to_sym].type entity.set_reference! reference_name, map(type, row_hash, session, reference_name) end 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+
55 56 57 58 59 60 61 62 63 64 65 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 |
# File 'lib/jet_set/mapper.rb', line 55 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 |