Commit 34b66244 by Carsten Brandt

implemented redis AR ActiveQuery and find()

parent 7efe3b14
...@@ -70,15 +70,20 @@ class ActiveQuery extends \yii\base\Component ...@@ -70,15 +70,20 @@ class ActiveQuery extends \yii\base\Component
*/ */
public $limit; public $limit;
/** /**
* @var integer zero-based offset from where the records are to be returned. If not set or * @var integer zero-based offset from where the records are to be returned.
* less than 0, it means starting from the beginning. * If not set, it means starting from the beginning.
* If less than zero it means starting n elements from the end.
*/ */
public $offset; public $offset;
/** /**
* @var string|array how to sort the query results. This refers to the ORDER BY clause in a SQL statement. * @var array array of primary keys of the records to find.
* It can be either a string (e.g. `'id ASC, name DESC'`) or an array (e.g. `array('id ASC', 'name DESC')`).
*/ */
public $orderBy; public $primaryKeys;
public function primaryKeys($primaryKeys) {
$this->primaryKeys = $primaryKeys;
return $this;
}
/** /**
* Executes query and returns all results as an array. * Executes query and returns all results as an array.
...@@ -86,9 +91,20 @@ class ActiveQuery extends \yii\base\Component ...@@ -86,9 +91,20 @@ class ActiveQuery extends \yii\base\Component
*/ */
public function all() public function all()
{ {
// TODO implement $modelClass = $this->modelClass;
$command = $this->createCommand(); /** @var Connection $db */
$rows = $command->queryAll(); $db = $modelClass::getDb();
if (($primaryKeys = $this->primaryKeys) === null) {
$start = $this->offset === null ? 0 : $this->offset;
$end = $this->limit === null ? -1 : $start + $this->limit;
$primaryKeys = $db->executeCommand('LRANGE', array($modelClass::tableName(), $start, $end));
}
$rows = array();
foreach($primaryKeys as $pk) {
$key = $modelClass::tableName() . ':a:' . (is_array($pk) ? implode('-', $pk) : $pk); // TODO escape PK glue
// get attributes
$rows[] = $db->executeCommand('HGETALL', array($key));
}
if ($rows !== array()) { if ($rows !== array()) {
$models = $this->createModels($rows); $models = $this->createModels($rows);
if (!empty($this->with)) { if (!empty($this->with)) {
...@@ -108,9 +124,18 @@ class ActiveQuery extends \yii\base\Component ...@@ -108,9 +124,18 @@ class ActiveQuery extends \yii\base\Component
*/ */
public function one() public function one()
{ {
// TODO implement $modelClass = $this->modelClass;
$command = $this->createCommand(); /** @var Connection $db */
$row = $command->queryRow(); $db = $modelClass::getDb();
if (($primaryKeys = $this->primaryKeys) === null) {
$start = $this->offset === null ? 0 : $this->offset;
$primaryKeys = $db->executeCommand('LRANGE', array($modelClass::tableName(), $start, $start + 1));
}
$pk = reset($primaryKeys);
$key = $modelClass::tableName() . ':a:' . (is_array($pk) ? implode('-', $pk) : $pk); // TODO escape PK glue
// get attributes
$row = $db->executeCommand('HGETALL', array($key));
// TODO check for empty list if key does not exist
if ($row !== false && !$this->asArray) { if ($row !== false && !$this->asArray) {
/** @var $class ActiveRecord */ /** @var $class ActiveRecord */
$class = $this->modelClass; $class = $this->modelClass;
...@@ -132,63 +157,12 @@ class ActiveQuery extends \yii\base\Component ...@@ -132,63 +157,12 @@ class ActiveQuery extends \yii\base\Component
* Make sure you properly quote column names. * Make sure you properly quote column names.
* @return integer number of records * @return integer number of records
*/ */
public function count($q = '*') public function count()
{
// TODO implement
$this->select = array("COUNT($q)");
return $this->createCommand()->queryScalar();
}
/**
* Returns the sum of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names.
* @return integer the sum of the specified column values
*/
public function sum($q)
{
// TODO implement
$this->select = array("SUM($q)");
return $this->createCommand()->queryScalar();
}
/**
* Returns the average of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names.
* @return integer the average of the specified column values.
*/
public function average($q)
{
// TODO implement
$this->select = array("AVG($q)");
return $this->createCommand()->queryScalar();
}
/**
* Returns the minimum of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names.
* @return integer the minimum of the specified column values.
*/
public function min($q)
{
// TODO implement
$this->select = array("MIN($q)");
return $this->createCommand()->queryScalar();
}
/**
* Returns the maximum of the specified column values.
* @param string $q the column name or expression.
* Make sure you properly quote column names.
* @return integer the maximum of the specified column values.
*/
public function max($q)
{ {
// TODO implement $modelClass = $this->modelClass;
$this->select = array("MAX($q)"); /** @var Connection $db */
return $this->createCommand()->queryScalar(); $db = $modelClass::getDb();
return $db->executeCommand('LLEN', array($modelClass::tableName()));
} }
/** /**
...@@ -197,10 +171,10 @@ class ActiveQuery extends \yii\base\Component ...@@ -197,10 +171,10 @@ class ActiveQuery extends \yii\base\Component
* @return string|boolean the value of the first column in the first row of the query result. * @return string|boolean the value of the first column in the first row of the query result.
* False is returned if the query result is empty. * False is returned if the query result is empty.
*/ */
public function scalar() public function scalar($column)
{ {
// TODO implement $record = $this->one();
return $this->createCommand()->queryScalar(); return $record->$column;
} }
/** /**
...@@ -209,9 +183,7 @@ class ActiveQuery extends \yii\base\Component ...@@ -209,9 +183,7 @@ class ActiveQuery extends \yii\base\Component
*/ */
public function exists() public function exists()
{ {
// TODO implement return $this->one() !== null;
$this->select = array(new Expression('1'));
return $this->scalar() !== false;
} }
...@@ -228,48 +200,6 @@ class ActiveQuery extends \yii\base\Component ...@@ -228,48 +200,6 @@ class ActiveQuery extends \yii\base\Component
} }
/** /**
* Sets the ORDER BY part of the query.
* TODO: refactor, it is duplicated from yii/db/Query
* @param string|array $columns the columns (and the directions) to be ordered by.
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return Query the query object itself
* @see addOrder()
*/
public function orderBy($columns)
{
$this->orderBy = $columns;
return $this;
}
/**
* Adds additional ORDER BY columns to the query.
* TODO: refactor, it is duplicated from yii/db/Query
* @param string|array $columns the columns (and the directions) to be ordered by.
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return Query the query object itself
* @see order()
*/
public function addOrderBy($columns)
{
if (empty($this->orderBy)) {
$this->orderBy = $columns;
} else {
if (!is_array($this->orderBy)) {
$this->orderBy = preg_split('/\s*,\s*/', trim($this->orderBy), -1, PREG_SPLIT_NO_EMPTY);
}
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
$this->orderBy = array_merge($this->orderBy, $columns);
}
return $this;
}
/**
* Sets the LIMIT part of the query. * Sets the LIMIT part of the query.
* TODO: refactor, it is duplicated from yii/db/Query * TODO: refactor, it is duplicated from yii/db/Query
* @param integer $limit the limit * @param integer $limit the limit
......
...@@ -60,16 +60,15 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord ...@@ -60,16 +60,15 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
* returned (null will be returned if there is no matching). * returned (null will be returned if there is no matching).
* @see createQuery() * @see createQuery()
*/ */
public static function find($q = null) public static function find($q = null) // TODO optimize API
{ {
// TODO
$query = static::createQuery(); $query = static::createQuery();
if (is_array($q)) { if (is_array($q)) {
return $query->where($q)->one(); return $query->primaryKeys($q)->one();
} elseif ($q !== null) { } elseif ($q !== null) {
// query by primary key // query by primary key
$primaryKey = static::primaryKey(); $primaryKey = static::primaryKey();
return $query->where(array($primaryKey[0] => $q))->one(); return $query->primaryKeys(array($primaryKey[0] => $q))->one();
} }
return $query; return $query;
} }
...@@ -178,7 +177,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord ...@@ -178,7 +177,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
} }
} }
// save pk in a findall pool // save pk in a findall pool
$db->executeCommand('SADD', array(static::tableName(), $pk)); $db->executeCommand('RPUSH', array(static::tableName(), $pk));
$key = static::tableName() . ':a:' . implode('-', $pk); // TODO escape PK glue $key = static::tableName() . ':a:' . implode('-', $pk); // TODO escape PK glue
// save attributes // save attributes
...@@ -214,7 +213,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord ...@@ -214,7 +213,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
{ {
$db = static::getDb(); $db = static::getDb();
if ($condition==='') { if ($condition==='') {
$condition = $db->executeCommand('SMEMBERS', array(static::tableName())); $condition = $db->executeCommand('LRANGE', array(static::tableName(), 0, -1));
} }
if (empty($attributes)) { if (empty($attributes)) {
return 0; return 0;
...@@ -255,7 +254,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord ...@@ -255,7 +254,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
{ {
$db = static::getDb(); $db = static::getDb();
if ($condition==='') { if ($condition==='') {
$condition = $db->executeCommand('SMEMBERS', array(static::tableName())); $condition = $db->executeCommand('LRANGE', array(static::tableName(), 0, -1));
} }
$n=0; $n=0;
foreach($condition as $pk) { foreach($condition as $pk) {
...@@ -287,23 +286,20 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord ...@@ -287,23 +286,20 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
{ {
$db = static::getDb(); $db = static::getDb();
if ($condition==='') { if ($condition==='') {
$condition = $db->executeCommand('SMEMBERS', array(static::tableName())); $condition = $db->executeCommand('LRANGE', array(static::tableName(), 0, -1));
} }
if (empty($condition)) { if (empty($condition)) {
return 0; return 0;
} }
$smembers = array();
$attributeKeys = array(); $attributeKeys = array();
foreach($condition as $pk) { foreach($condition as $pk) {
if (is_array($pk)) { if (is_array($pk)) {
$pk = implode('-', $pk); $pk = implode('-', $pk);
} }
$smembers[] = $pk; // TODO escape PK glue $db->executeCommand('LREM', array(static::tableName(), 0, $pk)); // TODO escape PK glue
$attributeKeys[] = static::tableName() . ':' . $pk . ':a'; // TODO escape PK glue $attributeKeys[] = static::tableName() . ':' . $pk . ':a'; // TODO escape PK glue
} }
array_unshift($smembers, static::tableName()); return $db->executeCommand('DEL', $attributeKeys);
$db->executeCommand('DEL', $attributeKeys);
return $db->executeCommand('SREM', $smembers);
} }
/** /**
......
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