protected function column_alias_sql(Dao $dao, Column $column, Q $q, $alias = true) { $column_str = $alias ? $column->table_alias() . '.' . $this->quotation($column->column()) : $this->quotation($column->column()); if ($q->ignore_case()) { return 'upper(' . $column_str . ')'; } return $column_str; }
protected final function __new__() { if (func_num_args() == 1) { foreach (func_get_arg(0) as $n => $v) { switch ($n) { case '_has_hierarchy_': case '_class_id_': case '_hierarchy_': $this->{$n} = $v; break; default: } } } $p = get_class($this); if (!isset($this->_class_id_)) { $this->_class_id_ = $p; } if (isset(self::$_dao_[$this->_class_id_])) { foreach (self::$_dao_[$this->_class_id_]->_has_dao_ as $name => $dao) { $this->{$name}($dao); } return; } if (!isset(self::$_co_anon_[$p])) { $readonly = static::anon('readonly', false); $anon = array(static::anon('database'), static::anon('table'), static::anon('create', !$readonly) === true, static::anon('update', !$readonly) === true, static::anon('delete', !$readonly) === true, null, false, false); if (empty($anon[0])) { $conf = explode("\\", $p); $def = \org\rhaco\Conf::get('connection'); while (!isset($def[implode('.', $conf)]) && !empty($conf)) { array_pop($conf); } if (empty($conf) && !isset($def['*'])) { throw new \org\rhaco\store\db\exception\DaoConnectionException('could not find the connection settings `' . $p . '`'); } $anon[0] = empty($conf) ? '*' : implode('.', $conf); } if (empty($anon[1])) { $table_class = $p; $parent_class = get_parent_class($p); $ref = new \ReflectionClass($parent_class); while (true) { $ref = new \ReflectionClass($parent_class); if (__CLASS__ == $parent_class || $ref->isAbstract()) { break; } $table_class = $parent_class; $parent_class = get_parent_class($parent_class); } $table_class = preg_replace("/^.*\\\\(.+)\$/", "\\1", $table_class); $anon[1] = strtolower($table_class[0]); for ($i = 1; $i < strlen($table_class); $i++) { $anon[1] .= ctype_lower($table_class[$i]) ? $table_class[$i] : '_' . strtolower($table_class[$i]); } } $config = self::get_con($anon[0], $p); if (!isset(self::$_connections_[$anon[0]])) { throw new \RuntimeException('connection fail ' . str_replace("\\", '.', get_class($this))); } static::set_module(self::$_connections_[$anon[0]]->connection_module()); $anon[5] = isset($config['prefix']) ? $config['prefix'] : ''; $anon[6] = isset($config['upper']) && $config['upper'] === true; $anon[7] = isset($config['lower']) && $config['lower'] === true; self::$_co_anon_[$p] = $anon; self::$_co_anon_[$p][1] = self::set_table_name(self::$_co_anon_[$p][1], $p); } $has_hierarchy = isset($this->_hierarchy_) ? $this->_hierarchy_ - 1 : $this->_has_hierarchy_; $root_table_alias = 't' . self::$_cnt_++; $_columns_ = $_self_columns_ = $_where_columns_ = $_conds_ = $_join_conds_ = $_alias_ = $_has_many_conds_ = $_has_dao_ = array(); $prop = $last_cond_column = array(); $ref = new \ReflectionClass($this); foreach ($ref->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $prop) { $props[] = $prop->getName(); } while (!empty($props)) { $name = array_shift($props); if ($name[0] != '_' && $this->prop_anon($name, 'extra') !== true) { $anon_cond = $this->prop_anon($name, 'cond'); $column_type = $this->prop_anon($name, 'type'); $column = new Column(); $column->name($name); $column->column($this->prop_anon($name, 'column', $name)); $column->column_alias('c' . self::$_cnt_++); if ($anon_cond === null) { if (ctype_upper($column_type[0]) && class_exists($column_type) && is_subclass_of($column_type, __CLASS__)) { throw new \RuntimeException('undef ' . $name . ' annotation `cond`'); } $column->table($this->table()); $column->table_alias($root_table_alias); $column->primary($this->prop_anon($name, 'primary', false)); $column->auto($column_type === 'serial'); $_columns_[] = $column; $_self_columns_[$name] = $column; $_alias_[$column->column_alias()] = $name; } else { if (false !== strpos($anon_cond, '(')) { $is_has = class_exists($column_type) && is_subclass_of($column_type, __CLASS__); $is_has_many = $is_has && $this->prop_anon($name, 'attr') === 'a'; if ((!$is_has || $has_hierarchy > 0) && preg_match("/^(.+)\\((.*)\\)(.*)\$/", $anon_cond, $match)) { list(, $self_var, $conds_string, $has_var) = $match; $conds = array(); $ref_table = $ref_table_alias = null; if (!empty($conds_string)) { foreach (explode(',', $conds_string) as $key => $cond) { $tcc = explode('.', $cond, 3); switch (sizeof($tcc)) { case 1: $conds[] = Column::cond_instance($tcc[0], 'c' . self::$_cnt_++, $this->table(), $root_table_alias); break; case 2: list($t, $c1) = $tcc; $ref_table = self::set_table_name($t, $p); $ref_table_alias = 't' . self::$_cnt_++; $conds[] = Column::cond_instance($c1, 'c' . self::$_cnt_++, $ref_table, $ref_table_alias); break; case 3: list($t, $c1, $c2) = $tcc; $ref_table = self::set_table_name($t, $p); $ref_table_alias = 't' . self::$_cnt_++; $conds[] = Column::cond_instance($c1, 'c' . self::$_cnt_++, $ref_table, $ref_table_alias); $conds[] = Column::cond_instance($c2, 'c' . self::$_cnt_++, $ref_table, $ref_table_alias); break; default: throw new \LogicException('annotation error : `' . $name . '`'); } } } if ($is_has_many) { if (empty($has_var)) { throw new \LogicException('annotation error : `' . $name . '`'); } $dao = new $column_type(array('_class_id_' => $p . '___' . self::$_cnt_++)); $_has_many_conds_[$name] = array($dao, $has_var, $self_var); } else { $self_db = true; if ($is_has) { if (empty($has_var)) { throw new \LogicException('annotation error : `' . $name . '`'); } $dao = new $column_type(array('_class_id_' => $p . '___' . self::$_cnt_++, '_hierarchy_' => $has_hierarchy)); $this->{$name}($dao); if ($dao->table() == $this->table()) { $_has_dao_[$name] = $dao; $_columns_ = array_merge($_columns_, $dao->columns()); $_conds_ = array_merge($_conds_, $dao->conds()); $this->prop_anon($name, 'has', true, true); foreach ($dao->columns() as $column) { $_alias_[$column->column_alias()] = $name; } $has_column = $dao->base_column($dao->columns(), $has_var); $conds[] = Column::cond_instance($has_column->column(), 'c' . self::$_cnt_++, $has_column->table(), $has_column->table_alias()); array_unshift($conds, Column::cond_instance($self_var, 'c' . self::$_cnt_++, $this->table(), $root_table_alias)); } else { $_has_many_conds_[$name] = array($dao, $has_var, $self_var); $self_db = false; } } else { if ($self_var[0] == '@') { $cond_var = null; $cond_name = substr($self_var, 1); if (strpos($cond_name, '.') !== false) { list($cond_name, $cond_var) = explode('.', $cond_name); } if (!isset($last_cond_column[$cond_name]) && in_array($cond_name, $props)) { $props[] = $name; continue; } $cond_column = clone $last_cond_column[$cond_name]; if (isset($cond_var)) { $cond_column->column($cond_var); $cond_column->column_alias('c' . self::$_cnt_++); } array_unshift($conds, $cond_column); } else { array_unshift($conds, Column::cond_instance($self_var, 'c' . self::$_cnt_++, $this->table(), $root_table_alias)); } $column->table($ref_table); $column->table_alias($ref_table_alias); $_alias_[$column->column_alias()] = $name; if (!$this->prop_anon($name, 'join', false)) { $_columns_[] = $column; } $_where_columns_[$name] = $column; } if ($self_db) { if (sizeof($conds) % 2 != 0) { throw new \RuntimeException($name . '[' . $column_type . '] is illegal condition'); } if ($this->prop_anon($name, 'join', false)) { $this->prop_anon($name, 'get', false, true); $this->prop_anon($name, 'set', false, true); for ($i = 0; $i < sizeof($conds); $i += 2) { $_join_conds_[$name][] = array($conds[$i], $conds[$i + 1]); } } else { for ($i = 0; $i < sizeof($conds); $i += 2) { $_conds_[] = array($conds[$i], $conds[$i + 1]); } } } if (!empty($conds)) { $cond_column = clone $conds[sizeof($conds) - 1]; $cond_column->column($column->column()); $cond_column->column_alias('c' . self::$_cnt_++); $last_cond_column[$name] = $cond_column; } } } } else { if ($anon_cond[0] === '@') { $cond_name = substr($anon_cond, 1); if (in_array($cond_name, $props)) { $props[] = $name; continue; } $c = $this->base_column($_columns_, substr($anon_cond, 1)); $column->table($c->table()); $column->table_alias($c->table_alias()); $_columns_[] = $column; $_where_columns_[$name] = $column; $_alias_[$column->column_alias()] = $name; } } } } } self::$_dao_[$this->_class_id_] = (object) array('_columns_' => $_columns_, '_self_columns_' => $_self_columns_, '_where_columns_' => $_where_columns_, '_conds_' => $_conds_, '_join_conds_' => $_join_conds_, '_alias_' => $_alias_, '_has_dao_' => $_has_dao_, '_has_many_conds_' => $_has_many_conds_); }