Browse Source

RAR WIP

tags/2.0.0-beta
Qiang Xue 12 years ago
parent
commit
de35c62c4e
  1. 41
      framework/db/ar/ActiveQuery.php
  2. 10
      framework/db/ar/ActiveRecord.php
  3. 10
      framework/db/ar/Relation.php
  4. 78
      framework/db/dao/QueryBuilder.php

41
framework/db/ar/ActiveQuery.php

@ -107,6 +107,34 @@ class ActiveQuery extends BaseQuery
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.
* This is a shortcut method to {@link CDbConnection::cache()}.
@ -153,13 +181,14 @@ class ActiveQuery extends BaseQuery
$command = $db->createCommand($this->sql, $this->params);
$rows = $command->queryAll();
$records = $this->createRecords($rows);
foreach ($this->with as $name => $config) {
$relation = $model->$name();
foreach ($config as $p => $v) {
$relation->$p = $v;
if ($records !== array()) {
foreach ($this->with as $name => $config) {
$relation = $model->$name();
foreach ($config as $p => $v) {
$relation->$p = $v;
}
$relation->findWith($records);
}
$relation->findWith($records);
}
return $records;

10
framework/db/ar/ActiveRecord.php

@ -68,11 +68,10 @@ abstract class ActiveRecord extends Model
public static function model()
{
$className = get_called_class();
if (isset(self::$_models[$className])) {
return self::$_models[$className];
} else {
return self::$_models[$className] = new static;
if (!isset(self::$_models[$className])) {
self::$_models[$className] = new static;
}
return self::$_models[$className];
}
/**
@ -387,6 +386,7 @@ abstract class ActiveRecord extends Model
return new HasOneRelation(array(
'modelClass' => $class,
'parentClass' => get_class($this),
'parentRecords' => array($this),
'link' => $link,
));
}
@ -396,6 +396,7 @@ abstract class ActiveRecord extends Model
return new HasManyRelation(array(
'modelClass' => $class,
'parentClass' => get_class($this),
'parentRecords' => array($this),
'link' => $link,
));
}
@ -405,6 +406,7 @@ abstract class ActiveRecord extends Model
return new ManyManyRelation(array(
'modelClass' => $class,
'parentClass' => get_class($this),
'parentRecords' => array($this),
'leftLink' => $leftLink,
'joinTable' => $joinTable,
'rightLink' => $rightLink,

10
framework/db/ar/Relation.php

@ -5,10 +5,14 @@ namespace yii\db\ar;
class Relation extends ActiveQuery
{
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)
}
}
}

78
framework/db/dao/QueryBuilder.php

@ -469,16 +469,16 @@ class QueryBuilder extends \yii\base\Object
public function buildCondition($condition)
{
static $builders = array(
'and' => 'buildAndCondition',
'or' => 'buildAndCondition',
'between' => 'buildBetweenCondition',
'not between' => 'buildBetweenCondition',
'in' => 'buildInCondition',
'not in' => 'buildInCondition',
'like' => 'buildLikeCondition',
'not like' => 'buildLikeCondition',
'or like' => 'buildLikeCondition',
'or not like' => 'buildLikeCondition',
'AND' => 'buildAndCondition',
'OR' => 'buildAndCondition',
'BETWEEN' => 'buildBetweenCondition',
'NOT BETWEEN' => 'buildBetweenCondition',
'IN' => 'buildInCondition',
'NOT IN' => 'buildInCondition',
'LIKE' => 'buildLikeCondition',
'NOT LIKE' => 'buildLikeCondition',
'OR LIKE' => 'buildLikeCondition',
'OR NOT LIKE' => 'buildLikeCondition',
);
if (!is_array($condition)) {
@ -487,7 +487,7 @@ class QueryBuilder extends \yii\base\Object
return '';
}
if (isset($condition[0])) { // operator format: operator, operand 1, operand 2, ...
$operator = $condition[0];
$operator = strtoupper($condition[0]);
if (isset($builders[$operator])) {
$method = $builders[$operator];
array_shift($condition);
@ -534,7 +534,6 @@ class QueryBuilder extends \yii\base\Object
}
}
if ($parts !== array()) {
$operator = strtoupper($operator);
return '(' . implode(") $operator (", $parts) . ')';
} else {
return '';
@ -570,22 +569,62 @@ class QueryBuilder extends \yii\base\Object
$values = array($values);
}
if ($values === array()) {
if ($values === array() || $column === array()) {
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) {
$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) {
$column = $this->quoteColumnName($column);
}
$operator = strtoupper($operator);
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)
{
if (!isset($operands[0], $operands[1])) {
@ -599,21 +638,20 @@ class QueryBuilder extends \yii\base\Object
}
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 ';
} else {
$andor = ' OR ';
$operator = $operator === 'or like' ? 'like' : 'not like';
$operator = $operator === 'OR LIKE' ? 'LIKE' : 'NOT LIKE';
}
if (strpos($column, '(') === false) {
$column = $this->quoteColumnName($column);
}
$operator = strtoupper($operator);
$parts = array();
foreach ($values as $value) {
$parts[] = "$column $operator " . $this->connection->quoteValue($value);
@ -730,7 +768,7 @@ class QueryBuilder extends \yii\base\Object
$table = $driver->quoteTableName($table);
}
}
$joins[$i] = strtoupper($join[0]) . ' ' . $table;
$joins[$i] = $join[0] . ' ' . $table;
if (isset($join[2])) {
$condition = $this->buildCondition($join[2]);
if ($condition !== '') {

Loading…
Cancel
Save