Commit de35c62c by Qiang Xue

RAR WIP

parent a8be9ce4
...@@ -107,6 +107,34 @@ class ActiveQuery extends BaseQuery ...@@ -107,6 +107,34 @@ class ActiveQuery extends BaseQuery
return $class::getDbConnection(); return $class::getDbConnection();
} }
public function asArray($value = true)
{
$this->asArray = $value;
return $this;
}
public function with()
{
$this->with = func_get_args();
if (isset($this->with[0]) && is_array($this->with[0])) {
// the parameter is given as an array
$this->with = $this->with[0];
}
return $this;
}
public function index($column)
{
$this->index = $column;
return $this;
}
public function scopes($names)
{
$this->scopes = $names;
return $this;
}
/** /**
* Sets the parameters about query caching. * Sets the parameters about query caching.
* This is a shortcut method to {@link CDbConnection::cache()}. * This is a shortcut method to {@link CDbConnection::cache()}.
...@@ -153,13 +181,14 @@ class ActiveQuery extends BaseQuery ...@@ -153,13 +181,14 @@ class ActiveQuery extends BaseQuery
$command = $db->createCommand($this->sql, $this->params); $command = $db->createCommand($this->sql, $this->params);
$rows = $command->queryAll(); $rows = $command->queryAll();
$records = $this->createRecords($rows); $records = $this->createRecords($rows);
if ($records !== array()) {
foreach ($this->with as $name => $config) { foreach ($this->with as $name => $config) {
$relation = $model->$name(); $relation = $model->$name();
foreach ($config as $p => $v) { foreach ($config as $p => $v) {
$relation->$p = $v; $relation->$p = $v;
}
$relation->findWith($records);
} }
$relation->findWith($records);
} }
return $records; return $records;
......
...@@ -68,11 +68,10 @@ abstract class ActiveRecord extends Model ...@@ -68,11 +68,10 @@ abstract class ActiveRecord extends Model
public static function model() public static function model()
{ {
$className = get_called_class(); $className = get_called_class();
if (isset(self::$_models[$className])) { if (!isset(self::$_models[$className])) {
return self::$_models[$className]; self::$_models[$className] = new static;
} else {
return self::$_models[$className] = new static;
} }
return self::$_models[$className];
} }
/** /**
...@@ -387,6 +386,7 @@ abstract class ActiveRecord extends Model ...@@ -387,6 +386,7 @@ abstract class ActiveRecord extends Model
return new HasOneRelation(array( return new HasOneRelation(array(
'modelClass' => $class, 'modelClass' => $class,
'parentClass' => get_class($this), 'parentClass' => get_class($this),
'parentRecords' => array($this),
'link' => $link, 'link' => $link,
)); ));
} }
...@@ -396,6 +396,7 @@ abstract class ActiveRecord extends Model ...@@ -396,6 +396,7 @@ abstract class ActiveRecord extends Model
return new HasManyRelation(array( return new HasManyRelation(array(
'modelClass' => $class, 'modelClass' => $class,
'parentClass' => get_class($this), 'parentClass' => get_class($this),
'parentRecords' => array($this),
'link' => $link, 'link' => $link,
)); ));
} }
...@@ -405,6 +406,7 @@ abstract class ActiveRecord extends Model ...@@ -405,6 +406,7 @@ abstract class ActiveRecord extends Model
return new ManyManyRelation(array( return new ManyManyRelation(array(
'modelClass' => $class, 'modelClass' => $class,
'parentClass' => get_class($this), 'parentClass' => get_class($this),
'parentRecords' => array($this),
'leftLink' => $leftLink, 'leftLink' => $leftLink,
'joinTable' => $joinTable, 'joinTable' => $joinTable,
'rightLink' => $rightLink, 'rightLink' => $rightLink,
......
...@@ -5,10 +5,14 @@ namespace yii\db\ar; ...@@ -5,10 +5,14 @@ namespace yii\db\ar;
class Relation extends ActiveQuery class Relation extends ActiveQuery
{ {
public $parentClass; public $parentClass;
public $parentRecords;
public function findWith($records) public function findWith(&$parentRecords)
{ {
$this->andWhere(array('in', $links, $keys));
$records = $this->find();
foreach ($records as $record) {
// find the matching parent record(s)
// insert into the parent records(s)
}
} }
} }
...@@ -469,16 +469,16 @@ class QueryBuilder extends \yii\base\Object ...@@ -469,16 +469,16 @@ class QueryBuilder extends \yii\base\Object
public function buildCondition($condition) public function buildCondition($condition)
{ {
static $builders = array( static $builders = array(
'and' => 'buildAndCondition', 'AND' => 'buildAndCondition',
'or' => 'buildAndCondition', 'OR' => 'buildAndCondition',
'between' => 'buildBetweenCondition', 'BETWEEN' => 'buildBetweenCondition',
'not between' => 'buildBetweenCondition', 'NOT BETWEEN' => 'buildBetweenCondition',
'in' => 'buildInCondition', 'IN' => 'buildInCondition',
'not in' => 'buildInCondition', 'NOT IN' => 'buildInCondition',
'like' => 'buildLikeCondition', 'LIKE' => 'buildLikeCondition',
'not like' => 'buildLikeCondition', 'NOT LIKE' => 'buildLikeCondition',
'or like' => 'buildLikeCondition', 'OR LIKE' => 'buildLikeCondition',
'or not like' => 'buildLikeCondition', 'OR NOT LIKE' => 'buildLikeCondition',
); );
if (!is_array($condition)) { if (!is_array($condition)) {
...@@ -487,7 +487,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -487,7 +487,7 @@ class QueryBuilder extends \yii\base\Object
return ''; return '';
} }
if (isset($condition[0])) { // operator format: operator, operand 1, operand 2, ... if (isset($condition[0])) { // operator format: operator, operand 1, operand 2, ...
$operator = $condition[0]; $operator = strtoupper($condition[0]);
if (isset($builders[$operator])) { if (isset($builders[$operator])) {
$method = $builders[$operator]; $method = $builders[$operator];
array_shift($condition); array_shift($condition);
...@@ -534,7 +534,6 @@ class QueryBuilder extends \yii\base\Object ...@@ -534,7 +534,6 @@ class QueryBuilder extends \yii\base\Object
} }
} }
if ($parts !== array()) { if ($parts !== array()) {
$operator = strtoupper($operator);
return '(' . implode(") $operator (", $parts) . ')'; return '(' . implode(") $operator (", $parts) . ')';
} else { } else {
return ''; return '';
...@@ -570,22 +569,62 @@ class QueryBuilder extends \yii\base\Object ...@@ -570,22 +569,62 @@ class QueryBuilder extends \yii\base\Object
$values = array($values); $values = array($values);
} }
if ($values === array()) { if ($values === array() || $column === array()) {
return $operator === 'in' ? '0=1' : ''; return $operator === 'in' ? '0=1' : '';
} }
if (is_array($column)) {
if (count($column) > 1) {
return $this->buildCompositeInCondition($operator, $column, $values);
} else {
$column = reset($column);
foreach ($values as $i => $value) {
if (is_array($value)) {
$values[$i] = isset($value[$column]) ? $value[$column] : null;
} else {
$values[$i] = null;
}
}
}
}
foreach ($values as $i => $value) { foreach ($values as $i => $value) {
$values[$i] = is_string($value) ? $this->connection->quoteValue($value) : (string)$value; if ($value === null) {
$values[$i] = 'NULL';
} else {
$values[$i] = is_string($value) ? $this->connection->quoteValue($value) : (string)$value;
}
} }
if (strpos($column, '(') === false) { if (strpos($column, '(') === false) {
$column = $this->quoteColumnName($column); $column = $this->quoteColumnName($column);
} }
$operator = strtoupper($operator);
return "$column $operator (" . implode(', ', $values) . ')'; return "$column $operator (" . implode(', ', $values) . ')';
} }
protected function buildCompositeInCondition($operator, $columns, $values)
{
foreach ($columns as $i => $column) {
if (strpos($column, '(') === false) {
$columns[$i] = $this->quoteColumnName($column);
}
}
$vss = array();
foreach ($values as $value) {
$vs = array();
foreach ($columns as $column) {
if (isset($value[$column])) {
$vs[] = is_string($value[$column]) ? $this->connection->quoteValue($value[$column]) : (string)$value[$column];
} else {
$vs[] = 'NULL';
}
}
$vss[] = '(' . implode(', ', $vs) . ')';
}
return '(' . implode(', ', $columns) . ") $operator (" . implode(', ', $vss) . ')';
}
private function buildLikeCondition($operator, $operands) private function buildLikeCondition($operator, $operands)
{ {
if (!isset($operands[0], $operands[1])) { if (!isset($operands[0], $operands[1])) {
...@@ -599,21 +638,20 @@ class QueryBuilder extends \yii\base\Object ...@@ -599,21 +638,20 @@ class QueryBuilder extends \yii\base\Object
} }
if ($values === array()) { if ($values === array()) {
return $operator === 'like' || $operator === 'or like' ? '0=1' : ''; return $operator === 'LIKE' || $operator === 'OR LIKE' ? '0=1' : '';
} }
if ($operator === 'like' || $operator === 'not like') { if ($operator === 'LIKE' || $operator === 'NOT LIKE') {
$andor = ' AND '; $andor = ' AND ';
} else { } else {
$andor = ' OR '; $andor = ' OR ';
$operator = $operator === 'or like' ? 'like' : 'not like'; $operator = $operator === 'OR LIKE' ? 'LIKE' : 'NOT LIKE';
} }
if (strpos($column, '(') === false) { if (strpos($column, '(') === false) {
$column = $this->quoteColumnName($column); $column = $this->quoteColumnName($column);
} }
$operator = strtoupper($operator);
$parts = array(); $parts = array();
foreach ($values as $value) { foreach ($values as $value) {
$parts[] = "$column $operator " . $this->connection->quoteValue($value); $parts[] = "$column $operator " . $this->connection->quoteValue($value);
...@@ -730,7 +768,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -730,7 +768,7 @@ class QueryBuilder extends \yii\base\Object
$table = $driver->quoteTableName($table); $table = $driver->quoteTableName($table);
} }
} }
$joins[$i] = strtoupper($join[0]) . ' ' . $table; $joins[$i] = $join[0] . ' ' . $table;
if (isset($join[2])) { if (isset($join[2])) {
$condition = $this->buildCondition($join[2]); $condition = $this->buildCondition($join[2]);
if ($condition !== '') { if ($condition !== '') {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment