3 namespace DataAccess\DataMapper
;
5 use Domain\Entities\IDivineEntity
;
6 use DataAccess\IDatabaseFactory
;
7 use DataAccess\DataMapper\IDataMapper
;
8 use DataAccess\Queries\IQueryBuilder
;
9 use DataAccess\DataMapper\Helpers\AbstractPopulationHelper
;
12 class DataMapper
implements IDataMapper
17 public function __construct($maps, IDatabaseFactory
$databaseFactory)
19 $this->_db
= $databaseFactory->createInstance();
20 $this->_maps
= include $maps;
23 public function map($entityName, IQueryBuilder
$queryBuilder)
25 $queryString = $queryBuilder->buildQuery();
27 $statement = $this->_db
->prepare(sprintf($queryString,
28 $this->_maps
[$entityName]['table']
31 $statement->execute();
32 $rows = $statement->fetchAll();
36 foreach($rows as $row)
38 $className = $this->_maps
[$entityName]['class']; //the entity to instantiate and return
39 $constructors = AbstractPopulationHelper
::getConstrutorArray($this->_maps
, $entityName, $row, $this->_db
);
41 if(count($constructors) == 0)
43 $class = new $className;
45 $r = new ReflectionClass($className);
46 $class = $r->newInstanceArgs($constructors);
49 $class->setId($row['id']);
50 $entities[$row['id']] = $class;
56 public function save(IDivineEntity
$entity)
58 $queries = AbstractPopulationHelper
::generateUpdateSaveQuery($this->_maps
, $entity, $entity->getId(), $this->_db
);
61 $flattened_tables = array();
62 foreach($queries as $index => $query)
64 $this_table = $query['table'];
65 $this_columns = $query['columns'];
67 for($i = $index+
1; $i<count($queries); $i++
)
69 if($queries[$i]['table'] == $this_table && !in_array($queries[$i]['table'], $flattened_tables) && !isset($query['id'])) //only merge create queries, updates are fine to run multiple times
71 $this_columns = array_merge($this_columns, $queries[$i]['columns']);
75 if(!in_array($this_table, $flattened_tables))
77 $flattened_tables[] = $this_table;
78 $prepared = isset($query['prepared']) ?
$query['prepared'] : null
;
79 $id = isset($query['id']) ?
$query['id'] : null
;
80 $flattened[] = array('columns' => $this_columns, 'table' => $this_table, 'prepared' => $prepared, 'id' => $id);
86 foreach($flattened as $info)
88 if(isset($info['id']))
90 $query = $info['prepared'];
91 $query = substr($query, 0, -2);
92 $query .= sprintf(' WHERE id=%u', $info['id']);
94 $query = sprintf('INSERT INTO %s (%s) VALUES (%s)',
96 implode(', ', array_keys($info['columns'])),
97 implode(', ', $info['columns']));
103 // if($queries['TYPE'] == AbstractPopulationHelper::QUERY_TYPE_CREATE)
106 foreach($queries as $index => $query)
109 if (preg_match_all('/'.preg_quote('%').'(.*?)'.preg_quote('%').'/s', $query, $matches)) {
110 foreach($matches[1] as $index_ref)
112 if($index_ref != 'MAIN_QUERY_ID')
114 $index_id = str_replace('INDEX_REF_', '', $index_ref);
115 $query = str_replace('%INDEX_REF_' . $index_id . '%', $idMap['INDEX_REF_' . $index_id], $query);
124 $statement = $this->_db
->prepare($query);
125 $statement->execute();
126 $refIndex = $index+
1;
127 $idMap['INDEX_REF_' . $refIndex] = $this->_db
->lastInsertId();
128 unset($queries[$index]);
130 //update query so that other references are resolved.
131 $queries[$index] = $query;
135 //at this point we have queries left that depend on the main query id
136 foreach($queries as $query)
138 $query = str_replace('%MAIN_QUERY_ID%', end($idMap), $query);
139 $statement = $this->_db
->prepare($query);
140 $statement->execute();
146 public function remove(IDivineEntity
$entity) {