/** * Creates filtered table representation. * @param Nette\Database\Connection * @param string database table name */ public function __construct(Nette\Database\Connection $connection, $table, Nette\Database\IReflection $reflection, Nette\Caching\IStorage $cacheStorage = NULL) { $this->name = $table; $this->connection = $connection; $this->reflection = $reflection; $this->cache = $cacheStorage ? new Nette\Caching\Cache($cacheStorage, 'Nette.Database.' . md5($connection->getDsn())) : NULL; $this->primary = $reflection->getPrimary($table); $this->sqlBuilder = new SqlBuilder($table, $connection, $reflection); $this->refCache =& $this->getRefTable($refPath)->globalRefCache[$refPath]; }
protected function buildJoins($val, $inner = FALSE) { $joins = array(); preg_match_all('~\\b([a-z][\\w.:]*[.:])([a-z]\\w*|\\*)(\\s+IS\\b|\\s*<=>)?~i', $val, $matches); foreach ($matches[1] as $names) { $parent = $parentAlias = $this->tableName; if ($names !== "{$parent}.") { // case-sensitive preg_match_all('~\\b([a-z][\\w]*|\\*)([.:])~i', $names, $matches, PREG_SET_ORDER); foreach ($matches as $match) { list(, $name, $delimiter) = $match; if ($delimiter === ':') { list($table, $primary) = $this->databaseReflection->getHasManyReference($parent, $name); $column = $this->databaseReflection->getPrimary($parent); } else { list($table, $column) = $this->databaseReflection->getBelongsToReference($parent, $name); $primary = $this->databaseReflection->getPrimary($table); } $joins[$name] = ' ' . (!isset($joins[$name]) && $inner && !isset($match[3]) ? 'INNER' : 'LEFT') . ' JOIN ' . $this->driver->delimite($table) . ($table !== $name ? ' AS ' . $this->driver->delimite($name) : '') . ' ON ' . $this->driver->delimite($parentAlias) . '.' . $this->driver->delimite($column) . ' = ' . $this->driver->delimite($name) . '.' . $this->driver->delimite($primary); $parent = $table; $parentAlias = $name; } } } return $joins; }
public function parseJoinsCb(& $joins, $match) { $chain = $match['chain']; if (!empty($chain[0]) && ($chain[0] !== '.' || $chain[0] !== ':')) { $chain = '.' . $chain; // unified chain format } $parent = $parentAlias = $this->tableName; if ($chain == ".{$parent}") { // case-sensitive return "{$parent}.{$match['column']}"; } preg_match_all('~ (?(DEFINE) (?P<word> [\w_]*[a-z][\w_]* ) ) (?P<del> [.:])?(?P<key> (?&word))(\((?P<throughColumn> (?&word))\))? ~xi', $chain, $keyMatches, PREG_SET_ORDER); foreach ($keyMatches as $keyMatch) { if ($keyMatch['del'] === ':') { if (isset($keyMatch['throughColumn'])) { $table = $keyMatch['key']; list(, $primary) = $this->databaseReflection->getBelongsToReference($table, $keyMatch['throughColumn']); } else { list($table, $primary) = $this->databaseReflection->getHasManyReference($parent, $keyMatch['key']); } $column = $this->databaseReflection->getPrimary($parent); } else { list($table, $column) = $this->databaseReflection->getBelongsToReference($parent, $keyMatch['key']); $primary = $this->databaseReflection->getPrimary($table); } $joins[$table . $column] = array($table, $keyMatch['key'] ?: $table, $parentAlias, $column, $primary); $parent = $table; $parentAlias = $keyMatch['key']; } return ($keyMatch['key'] ?: $table) . ".{$match['column']}"; }
/** * Sets database reflection. * @return Connection provides a fluent interface */ public function setDatabaseReflection(IReflection $databaseReflection) { $databaseReflection->setConnection($this); $this->databaseReflection = $databaseReflection; return $this; }