Browse Source

made link() and unlink() compatible with NoSQL AR

tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
c6c164dc71
  1. 47
      framework/yii/db/ActiveRecord.php
  2. 81
      framework/yii/redis/ActiveRecord.php

47
framework/yii/db/ActiveRecord.php

@ -1310,9 +1310,7 @@ class ActiveRecord extends Model
if (is_array($relation->via)) { if (is_array($relation->via)) {
/** @var $viaRelation ActiveRelation */ /** @var $viaRelation ActiveRelation */
list($viaName, $viaRelation) = $relation->via; list($viaName, $viaRelation) = $relation->via;
/** @var $viaClass ActiveRecord */
$viaClass = $viaRelation->modelClass; $viaClass = $viaRelation->modelClass;
$viaTable = $viaClass::tableName();
// unset $viaName so that it can be reloaded to reflect the change // unset $viaName so that it can be reloaded to reflect the change
unset($this->_related[strtolower($viaName)]); unset($this->_related[strtolower($viaName)]);
} else { } else {
@ -1329,8 +1327,19 @@ class ActiveRecord extends Model
foreach ($extraColumns as $k => $v) { foreach ($extraColumns as $k => $v) {
$columns[$k] = $v; $columns[$k] = $v;
} }
static::getDb()->createCommand() if (is_array($relation->via)) {
->insert($viaTable, $columns)->execute(); /** @var $viaClass ActiveRecord */
/** @var $record ActiveRecord */
$record = new $viaClass();
foreach($columns as $column => $value) {
$record->$column = $value;
}
$record->insert(false);
} else {
/** @var $viaTable string */
static::getDb()->createCommand()
->insert($viaTable, $columns)->execute();
}
} else { } else {
$p1 = $model->isPrimaryKey(array_keys($relation->link)); $p1 = $model->isPrimaryKey(array_keys($relation->link));
$p2 = $this->isPrimaryKey(array_values($relation->link)); $p2 = $this->isPrimaryKey(array_values($relation->link));
@ -1385,9 +1394,7 @@ class ActiveRecord extends Model
if (is_array($relation->via)) { if (is_array($relation->via)) {
/** @var $viaRelation ActiveRelation */ /** @var $viaRelation ActiveRelation */
list($viaName, $viaRelation) = $relation->via; list($viaName, $viaRelation) = $relation->via;
/** @var $viaClass ActiveRecord */
$viaClass = $viaRelation->modelClass; $viaClass = $viaRelation->modelClass;
$viaTable = $viaClass::tableName();
unset($this->_related[strtolower($viaName)]); unset($this->_related[strtolower($viaName)]);
} else { } else {
$viaRelation = $relation->via; $viaRelation = $relation->via;
@ -1400,15 +1407,29 @@ class ActiveRecord extends Model
foreach ($relation->link as $a => $b) { foreach ($relation->link as $a => $b) {
$columns[$b] = $model->$a; $columns[$b] = $model->$a;
} }
$command = static::getDb()->createCommand(); if (is_array($relation->via)) {
if ($delete) { /** @var $viaClass ActiveRecord */
$command->delete($viaTable, $columns)->execute(); if ($delete) {
$viaClass::deleteAll($columns);
} else {
$nulls = array();
foreach (array_keys($columns) as $a) {
$nulls[$a] = null;
}
$viaClass::updateAll($nulls, $columns);
}
} else { } else {
$nulls = array(); /** @var $viaTable string */
foreach (array_keys($columns) as $a) { $command = static::getDb()->createCommand();
$nulls[$a] = null; if ($delete) {
$command->delete($viaTable, $columns)->execute();
} else {
$nulls = array();
foreach (array_keys($columns) as $a) {
$nulls[$a] = null;
}
$command->update($viaTable, $nulls, $columns)->execute();
} }
$command->update($viaTable, $nulls, $columns)->execute();
} }
} else { } else {
$p1 = $model->isPrimaryKey(array_keys($relation->link)); $p1 = $model->isPrimaryKey(array_keys($relation->link));

81
framework/yii/redis/ActiveRecord.php

@ -367,83 +367,14 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
return false; return false;
} }
// TODO port these changes back to AR
/** /**
* @inheritDocs * Returns a value indicating whether the specified operation is transactional in the current [[scenario]].
* This method will always return false as transactional operations are not supported by redis.
* @param integer $operation the operation to check. Possible values are [[OP_INSERT]], [[OP_UPDATE]] and [[OP_DELETE]].
* @return boolean whether the specified operation is transactional in the current [[scenario]].
*/ */
public function link($name, $model, $extraColumns = array()) public function isTransactional($operation)
{ {
$relation = $this->getRelation($name); return false;
if ($relation->via !== null) {
if ($this->getIsNewRecord() || $model->getIsNewRecord()) {
throw new InvalidCallException('Unable to link models: both models must NOT be newly created.');
}
if (is_array($relation->via)) {
/** @var $viaRelation ActiveRelation */
list($viaName, $viaRelation) = $relation->via;
/** @var $viaClass ActiveRecord */
$viaClass = $viaRelation->modelClass;
// unset $viaName so that it can be reloaded to reflect the change
// unset($this->_related[strtolower($viaName)]); // TODO this needs private access
} else {
throw new NotSupportedException('redis does not support relations via table.');
}
$columns = array();
foreach ($viaRelation->link as $a => $b) {
$columns[$a] = $this->$b;
}
foreach ($relation->link as $a => $b) {
$columns[$b] = $model->$a;
}
foreach ($extraColumns as $k => $v) {
$columns[$k] = $v;
}
$record = new $viaClass();
foreach($columns as $column => $value) {
$record->$column = $value;
}
$record->insert();
} else {
parent::link($name, $model, $extraColumns);
}
}
/**
* @inheritDocs
*/
public function unlink($name, $model, $delete = false)
{
$relation = $this->getRelation($name);
if ($relation->via !== null) {
if (is_array($relation->via)) {
/** @var $viaRelation ActiveRelation */
list($viaName, $viaRelation) = $relation->via;
/** @var $viaClass ActiveRecord */
$viaClass = $viaRelation->modelClass;
//unset($this->_related[strtolower($viaName)]); // TODO this needs private access
} else {
throw new NotSupportedException('redis does not support relations via table.');
}
$columns = array();
foreach ($viaRelation->link as $a => $b) {
$columns[$a] = $this->$b;
}
foreach ($relation->link as $a => $b) {
$columns[$b] = $model->$a;
}
if ($delete) {
$viaClass::deleteAll($columns);
} else {
$nulls = array();
foreach (array_keys($columns) as $a) {
$nulls[$a] = null;
}
$viaClass::updateAll($nulls, $columns);
}
} else {
parent::unlink($name, $model, $delete);
}
} }
} }

Loading…
Cancel
Save