/** * Execute the query * @return array result set */ function find() { $outlet = $this->outlet; // get the 'from' $tmp = explode(' ', $this->from); $from = $tmp[0]; $from_aliased = count($tmp) > 1 ? $tmp[1] : $tmp[0]; $config = $this->outlet->getConfig(); $entity_config = $config->getEntity($from); $props = $entity_config->getProperties(); $from_props = $props; $select_cols = array(); foreach ($props as $key => $p) { $select_cols[] = "\n{" . $from_aliased . '.' . $key . '} as ' . $from_aliased . '_' . $key; } // get the include entities $with = array(); $with_aliased = array(); $join_q = ''; foreach ($this->with as $with_key => $j) { $tmp = explode(' ', $j); $with[$with_key] = $tmp[0]; $with_aliased[$with_key] = count($tmp) > 1 ? $tmp[1] : $tmp[0]; $assoc = $entity_config->getAssociation($with[$with_key]); if (!$assoc) { throw new OutletException('No association found with entity or alias [' . $with[$with_key] . ']'); } $props = $config->getEntity($assoc->getForeign())->getProperties(); foreach ($props as $key => $p) { $select_cols[] = "\n{" . $with_aliased[$with_key] . '.' . $key . '} as ' . $with_aliased[$with_key] . '_' . $key; } $aliased_join = $with_aliased[$with_key]; $join_q .= "LEFT JOIN {" . $assoc->getForeign() . " " . $aliased_join . "} ON {" . $from_aliased . '.' . $assoc->getKey() . "} = {" . $with_aliased[$with_key] . '.' . $assoc->getRefKey() . "} \n"; } $q = "SELECT " . implode(', ', $select_cols) . " \n"; if ($this->select) { $q .= ", " . $this->select; } $q .= " FROM {" . $this->from . "} \n"; $q .= $join_q; $q .= implode("\n", $this->joins); if ($this->query) { $q .= 'WHERE ' . $this->query . "\n"; } if ($this->groupBy) { $q .= 'GROUP BY ' . $this->groupBy . "\n"; } if ($this->orderby) { $q .= 'ORDER BY ' . $this->orderby . "\n"; } if ($this->having) { $q .= 'HAVING ' . $this->having . "\n"; } // TODO: Make it work on MS SQL // In SQL Server 2005 http://www.singingeels.com/Articles/Pagination_In_SQL_Server_2005.aspx if ($this->limit) { $q .= 'LIMIT ' . $this->limit; if ($this->offset) { $q .= ' OFFSET ' . $this->offset; } } $stmt = $outlet->query($q, $this->params); $res = array(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $data = array(); // Postgres returns columns as lowercase // TODO: Maybe everything should be converted to lower in query creation / processing to avoid this if ($outlet->getConnection()->getDialect() == 'pgsql') { foreach ($from_props as $key => $p) { $data[$p[0]] = $row[strtolower($from_aliased) . '_' . strtolower($key)]; } } else { foreach ($from_props as $key => $p) { $data[$p[0]] = $row[$from_aliased . '_' . $key]; } } $obj = $outlet->getEntityForRow($entity_config, $data); foreach ($with as $with_key => $w) { $a = $entity_config->getAssociation($w); if ($a) { $data = array(); $setter = $a->getSetter(); $foreign = $a->getForeign(); $with_entity = $config->getEntity($foreign); if ($a instanceof OutletOneToManyConfig) { // TODO: Implement... } elseif ($a instanceof OutletManyToManyConfig) { // TODO: Implement... } else { // Postgres returns columns as lowercase // TODO: Maybe everything should be converted to lower in query creation / processing to avoid this if ($outlet->getConnection()->getDialect() == 'pgsql') { foreach ($with_entity->getProperties() as $key => $p) { $data[$p[0]] = $row[strtolower($with_aliased[$with_key] . '_' . $key)]; } } else { foreach ($with_entity->getProperties() as $key => $p) { $data[$p[0]] = $row[$with_aliased[$with_key] . '_' . $key]; } } $f = $with_entity->getPkColumns(); // check to see if we found any data for the related entity // using the pk $data_returned = false; $pk_values = array(); foreach ($f as $k) { if (isset($data[$k])) { $data_returned = true; break; } } // only fill object if there was data returned if ($data_returned) { $obj->{$setter}($outlet->getEntityForRow($with_entity, $data)); } } } } $res[] = $obj; } return $res; }