mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-17 14:57:23 +08:00
finished draft implementation of new AR.
This commit is contained in:
@@ -66,14 +66,15 @@ class ActiveQuery extends BaseQuery
|
||||
{
|
||||
$command = $this->createCommand();
|
||||
$rows = $command->queryAll();
|
||||
if ($rows === array()) {
|
||||
if ($rows !== array()) {
|
||||
$models = $this->createModels($rows);
|
||||
if (!empty($this->with)) {
|
||||
$this->fetchRelatedModels($models, $this->with);
|
||||
}
|
||||
return $models;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$models = $this->createModels($rows);
|
||||
if (!empty($this->with)) {
|
||||
$this->fetchRelatedModels($models, $this->with);
|
||||
}
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,11 +87,7 @@ class ActiveQuery extends BaseQuery
|
||||
{
|
||||
$command = $this->createCommand();
|
||||
$row = $command->queryRow();
|
||||
if ($row === false) {
|
||||
return false;
|
||||
} elseif ($this->asArray) {
|
||||
return $row;
|
||||
} else {
|
||||
if ($row !== false && !$this->asArray) {
|
||||
/** @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$model = $class::create($row);
|
||||
@@ -100,6 +97,8 @@ class ActiveQuery extends BaseQuery
|
||||
$model = $models[0];
|
||||
}
|
||||
return $model;
|
||||
} else {
|
||||
return $row === false ? null : $row;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,17 +125,13 @@ class ActiveQuery extends BaseQuery
|
||||
|
||||
/**
|
||||
* Creates a DB command that can be used to execute this query.
|
||||
* @param Connection $db the database connection used to generate the SQL statement.
|
||||
* If this parameter is not given, the `db` application component will be used.
|
||||
* @return Command the created DB command instance.
|
||||
*/
|
||||
public function createCommand($db = null)
|
||||
public function createCommand()
|
||||
{
|
||||
/** @var $modelClass ActiveRecord */
|
||||
$modelClass = $this->modelClass;
|
||||
if ($db === null) {
|
||||
$db = $modelClass::getDbConnection();
|
||||
}
|
||||
$db = $modelClass::getDbConnection();
|
||||
if ($this->sql === null) {
|
||||
if ($this->from === null) {
|
||||
$tableName = $modelClass::tableName();
|
||||
|
||||
@@ -878,7 +878,7 @@ abstract class ActiveRecord extends Model
|
||||
public static function create($row)
|
||||
{
|
||||
$record = static::instantiate($row);
|
||||
$columns = static::model()->getTableSchema()->columns;
|
||||
$columns = static::getTableSchema()->columns;
|
||||
foreach ($row as $name => $value) {
|
||||
if (isset($columns[$name])) {
|
||||
$record->_attributes[$name] = $value;
|
||||
|
||||
@@ -59,12 +59,21 @@ class ActiveRelation extends ActiveQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function createCommand($db = null)
|
||||
public function createCommand()
|
||||
{
|
||||
if ($this->primaryModel !== null) {
|
||||
$this->filterByPrimaryModels(array($this->primaryModel));
|
||||
if ($this->via !== null) {
|
||||
/** @var $viaQuery ActiveRelation */
|
||||
$viaName = $this->via;
|
||||
$viaQuery = $this->$viaName();
|
||||
$primaryModels = array($this->primaryModel);
|
||||
$viaModels = $viaQuery->findWith($viaName, $primaryModels);
|
||||
$this->filterByModels($viaModels);
|
||||
} else {
|
||||
$this->filterByModels(array($this->primaryModel));
|
||||
}
|
||||
}
|
||||
return parent::createCommand($db);
|
||||
return parent::createCommand();
|
||||
}
|
||||
|
||||
public function findWith($name, &$primaryModels)
|
||||
@@ -74,44 +83,81 @@ class ActiveRelation extends ActiveQuery
|
||||
}
|
||||
|
||||
if ($this->via !== null) {
|
||||
/** @var $viaQuery ActiveRelation */
|
||||
$viaName = $this->via;
|
||||
$viaQuery = $this->$viaName();
|
||||
$viaModels = $viaQuery->findWith($viaName, $primaryModels);
|
||||
$this->filterByModels($viaModels);
|
||||
} else {
|
||||
$this->filterByModels($primaryModels);
|
||||
}
|
||||
|
||||
$this->filterByPrimaryModels($primaryModels);
|
||||
|
||||
if (count($primaryModels) === 1 && !$this->multiple) {
|
||||
$model = $this->one();
|
||||
foreach ($primaryModels as $i => $primaryModel) {
|
||||
$primaryModels[$i][$name] = $this->one();
|
||||
$primaryModels[$i][$name] = $model;
|
||||
}
|
||||
return array($model);
|
||||
} else {
|
||||
$models = $this->all();
|
||||
$this->bindModels($name, $primaryModels, $models);
|
||||
if (isset($viaModels, $viaQuery)) {
|
||||
$buckets = $this->buildBuckets($models, $this->link, $viaModels, $viaQuery->link);
|
||||
} else {
|
||||
$buckets = $this->buildBuckets($models, $this->link);
|
||||
}
|
||||
|
||||
foreach ($primaryModels as $i => $primaryModel) {
|
||||
if (isset($viaQuery)) {
|
||||
$key = $this->getModelKey($primaryModel, array_values($viaQuery->link));
|
||||
} else {
|
||||
$key = $this->getModelKey($primaryModel, array_values($this->link));
|
||||
}
|
||||
if (isset($buckets[$key])) {
|
||||
$primaryModels[$i][$name] = $buckets[$key];
|
||||
} else {
|
||||
$primaryModels[$i][$name] = $this->multiple ? array() : null;
|
||||
}
|
||||
}
|
||||
return $models;
|
||||
}
|
||||
}
|
||||
|
||||
protected function bindModels($name, &$primaryModels, $models)
|
||||
protected function buildBuckets($models, $link, $viaModels = null, $viaLink = null)
|
||||
{
|
||||
$buckets = array();
|
||||
foreach ($models as $i => $model) {
|
||||
$key = $this->getModelKey($model, array_keys($this->link));
|
||||
$key = $this->getModelKey($model, array_keys($link));
|
||||
if ($this->index !== null) {
|
||||
$buckets[$key][$i] = $model;
|
||||
} else {
|
||||
$buckets[$key][] = $model;
|
||||
}
|
||||
}
|
||||
|
||||
if ($viaModels !== null) {
|
||||
$viaBuckets = array();
|
||||
foreach ($viaModels as $viaModel) {
|
||||
$key1 = $this->getModelKey($viaModel, array_keys($viaLink));
|
||||
$key2 = $this->getModelKey($viaModel, array_values($link));
|
||||
if (isset($buckets[$key2])) {
|
||||
foreach ($buckets[$key2] as $i => $bucket) {
|
||||
if ($this->index !== null) {
|
||||
$viaBuckets[$key1][$i] = $bucket;
|
||||
} else {
|
||||
$viaBuckets[$key1][] = $bucket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$buckets = $viaBuckets;
|
||||
}
|
||||
|
||||
if (!$this->multiple) {
|
||||
foreach ($buckets as $i => $bucket) {
|
||||
$buckets[$i] = reset($bucket);
|
||||
}
|
||||
}
|
||||
foreach ($primaryModels as $i => $primaryModel) {
|
||||
$key = $this->getModelKey($primaryModel, array_values($this->link));
|
||||
if (isset($buckets[$key])) {
|
||||
$primaryModels[$i][$name] = $buckets[$key];
|
||||
} else {
|
||||
$primaryModels[$i][$name] = $this->multiple ? array() : null;
|
||||
}
|
||||
}
|
||||
return $buckets;
|
||||
}
|
||||
|
||||
protected function getModelKey($model, $attributes)
|
||||
@@ -128,13 +174,13 @@ class ActiveRelation extends ActiveQuery
|
||||
}
|
||||
}
|
||||
|
||||
protected function filterByPrimaryModels($primaryModels)
|
||||
protected function filterByModels($models)
|
||||
{
|
||||
$attributes = array_keys($this->link);
|
||||
$values = array();
|
||||
if (isset($links[1])) {
|
||||
// composite keys
|
||||
foreach ($primaryModels as $model) {
|
||||
foreach ($models as $model) {
|
||||
$v = array();
|
||||
foreach ($this->link as $attribute => $link) {
|
||||
$v[$attribute] = is_array($model) ? $model[$link] : $model->$link;
|
||||
@@ -144,7 +190,7 @@ class ActiveRelation extends ActiveQuery
|
||||
} else {
|
||||
// single key
|
||||
$attribute = $this->link[$links[0]];
|
||||
foreach ($primaryModels as $model) {
|
||||
foreach ($models as $model) {
|
||||
$values[] = is_array($model) ? $model[$attribute] : $model->$attribute;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
namespace yii\test;
|
||||
|
||||
require_once('PHPUnit/Runner/Version.php');
|
||||
spl_autoload_unregister(array('YiiBase','autoload'));
|
||||
require_once('PHPUnit/Autoload.php');
|
||||
spl_autoload_register(array('YiiBase','autoload')); // put yii's autoloader at the end
|
||||
|
||||
/**
|
||||
* TestCase is the base class for all test case classes.
|
||||
|
||||
Reference in New Issue
Block a user