/** * @param $path string * @param $prefix string * @return string */ public function buildColumn($path, $prefix = '') { $join = $this->joins->add($path); $link_join = $this->joins->getIdLinkJoin($path); if (isset($link_join)) { $column = $link_join->foreign_alias . DOT . 'id'; } elseif (isset($join)) { if ($join->type === Join::LINK) { $column = $join->foreign_alias . DOT . BQ . rLastParse($path, DOT, 1, true) . BQ; } else { $property = $this->joins->getStartingClass()->getProperty($path); $column = $property && $property->getAnnotation('link')->value == Link_Annotation::COLLECTION ? $join->master_column : $join->foreign_column; $column = $join->foreign_alias . DOT . BQ . $column . BQ; } } else { list($master_path, $foreign_column) = Builder::splitPropertyPath($path); if (!$master_path && $foreign_column == 'id') { $class = $this->joins->getStartingClassName(); $i = 0; while ($class = (new Link_Class($class))->getLinkedClassName()) { $i++; } $tx = 't' . $i; } else { $tx = 't0'; } $column = !$master_path || $master_path === 'id' ? $tx . DOT . BQ . $prefix . $foreign_column . BQ : $this->joins->getAlias($master_path) . DOT . BQ . $prefix . $foreign_column . BQ; } return $column; }
/** * Build the columns list, based on properties paths * * @return string * @todo factorize */ public function build() { if (isset($this->properties)) { $sql_columns = ''; $first_property = true; foreach ($this->properties as $key_path => $path) { if ($path instanceof Func\Column) { $sql_columns .= $this->buildDaoSelectFunction($key_path, $path, $first_property); } else { $join = $this->joins->add($path); $sql_columns .= $join && $join->type !== Join::LINK ? $this->buildObjectColumns($path, $join, $first_property) : $this->buildNextColumn($path, $join, $first_property); } $sql_columns .= $this->append(is_numeric($key_path) ? $path : $key_path); } } elseif ($this->joins->getJoins()) { $class_name = $this->joins->getStartingClassName(); /** @var $properties Reflection_Property[] */ $properties = []; $column_names = []; foreach ((new Reflection_Class($class_name))->getProperties([T_EXTENDS, T_USE]) as $property) { $storage = $property->getAnnotation('storage')->value; $type = $property->getType(); if (!$property->isStatic() && !($type->isClass() && $type->isMultiple())) { $column_names[$property->name] = $storage; $properties[$property->name] = $property; if ($storage !== $property->name) { $has_storage = true; } } } $sql_columns = ''; foreach ($this->joins->getLinkedJoins() as $join) { if (isset($has_storage)) { foreach ((new Reflection_Class($join->foreign_class))->getProperties([T_EXTENDS, T_USE]) as $property) { if (!$property->isStatic() && isset($column_names[$property->name]) && !isset($already[$property->name])) { if (!$sql_columns) { $sql_columns .= $join->foreign_alias . '.id, '; } $column_name = $column_names[$property->name]; $id = $property->getType()->isClass() ? 'id_' : ''; $already[$property->name] = true; $sql_columns .= $join->foreign_alias . DOT . BQ . $id . $column_name . BQ; if ($column_name !== $property->name && $this->resolve_aliases) { $sql_columns .= ' AS ' . BQ . $id . $property->name . BQ; } $sql_columns .= ', '; } } } else { $sql_columns .= $join->foreign_alias . '.*, '; } } // the main table comes last, as fields with the same name must have the main value (ie 'id') if (isset($has_storage)) { if (!(new Link_Class($this->joins->getStartingClassName()))->getAnnotation('link')->value) { $sql_columns .= 't0.id, '; } foreach ($column_names as $property_name => $column_name) { if (!isset($already[$property_name])) { $already[$property_name] = true; $id = $properties[$property_name]->getType()->isClass() ? 'id_' : ''; $sql_columns .= 't0.' . BQ . $id . $column_name . BQ; if ($column_name !== $property_name && $this->resolve_aliases) { $sql_columns .= ' AS ' . BQ . $id . $property_name . BQ; } $sql_columns .= ', '; } } $sql_columns = substr($sql_columns, 0, -2); } else { $sql_columns .= 't0.*'; } } else { $sql_columns = '*'; } return $sql_columns; }