Extract cache from yii\db\Command to yii\db\CacheableQueryTrait and use it in yii\db\Query

This commit is contained in:
胡倍玮
2018-02-10 18:30:58 +08:00
committed by Dmitry Naumenko
parent 59e591ba3a
commit a036fac490
4 changed files with 88 additions and 45 deletions

View File

@ -319,7 +319,11 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$params = $this->params; $params = $this->params;
} }
return $db->createCommand($sql, $params); $command = $db->createCommand($sql, $params);
if ($this->hasCache()) {
$command->cache($this->queryCacheDuration, $this->queryCacheDependency);
}
return $command;
} }
/** /**
@ -337,11 +341,14 @@ class ActiveQuery extends Query implements ActiveQueryInterface
return parent::queryScalar($selectExpression, $db); return parent::queryScalar($selectExpression, $db);
} }
return (new Query())->select([$selectExpression]) $command = (new Query())->select([$selectExpression])
->from(['c' => "({$this->sql})"]) ->from(['c' => "({$this->sql})"])
->params($this->params) ->params($this->params)
->createCommand($db) ->createCommand($db);
->queryScalar(); if ($this->hasCache()) {
$command->cache($this->queryCacheDuration, $this->queryCacheDependency);
}
return $command->queryScalar();
} }
/** /**

View File

@ -0,0 +1,63 @@
<?php
namespace yii\db;
/**
* Trait CacheableQueryTrait provides methods to cache query execution result.
*
* The class that uses this trait must have the $db property:
* @property Connection $db
*
* @author hubeiwei <hubeiwei@hotmail.com>
* @author Dmytro Naumenko <d.naumenko.a@gmail.com>
* @since 2.0.14
*/
trait CacheableQueryTrait
{
/**
* @var int the default number of seconds that query results can remain valid in cache.
* Use 0 to indicate that the cached data will never expire. And use a negative number to indicate
* query cache should not be used.
* @see cache()
*/
public $queryCacheDuration;
/**
* @var \yii\caching\Dependency the dependency to be associated with the cached query result for this command
* @see cache()
*/
public $queryCacheDependency;
/**
* Enables query cache for this command or query.
* @param int $duration the number of seconds that query result of this command or query can remain valid in the cache.
* If this is not set, the value of [[Connection::queryCacheDuration]] will be used instead.
* Use 0 to indicate that the cached data will never expire.
* @param \yii\caching\Dependency $dependency the cache dependency associated with the cached result.
* @return $this the command or query object itself
*/
public function cache($duration = null, $dependency = null)
{
$this->queryCacheDuration = $duration !== null ? $duration : $this->db->queryCacheDuration;
$this->queryCacheDependency = $dependency;
return $this;
}
/**
* Disables query cache for this command or query.
* @return $this the command or query object itself
*/
public function noCache()
{
$this->queryCacheDuration = -1;
return $this;
}
/**
* Checks, whether caching is enabled
* @return bool
*/
public function hasCache()
{
return $this->queryCacheDuration !== null || $this->queryCacheDependency !== null;
}
}

View File

@ -56,6 +56,8 @@ use yii\base\NotSupportedException;
*/ */
class Command extends Component class Command extends Component
{ {
use CacheableQueryTrait;
/** /**
* @var Connection the DB connection that this command is associated with * @var Connection the DB connection that this command is associated with
*/ */
@ -75,18 +77,6 @@ class Command extends Component
* and is used to generate [[rawSql]]. Do not modify it directly. * and is used to generate [[rawSql]]. Do not modify it directly.
*/ */
public $params = []; public $params = [];
/**
* @var int the default number of seconds that query results can remain valid in cache.
* Use 0 to indicate that the cached data will never expire. And use a negative number to indicate
* query cache should not be used.
* @see cache()
*/
public $queryCacheDuration;
/**
* @var \yii\caching\Dependency the dependency to be associated with the cached query result for this command
* @see cache()
*/
public $queryCacheDependency;
/** /**
* @var array pending parameters to be bound to the current PDO statement. * @var array pending parameters to be bound to the current PDO statement.
@ -112,31 +102,6 @@ class Command extends Component
private $_retryHandler; private $_retryHandler;
/**
* Enables query cache for this command.
* @param int $duration the number of seconds that query result of this command can remain valid in the cache.
* If this is not set, the value of [[Connection::queryCacheDuration]] will be used instead.
* Use 0 to indicate that the cached data will never expire.
* @param \yii\caching\Dependency $dependency the cache dependency associated with the cached query result.
* @return $this the command object itself
*/
public function cache($duration = null, $dependency = null)
{
$this->queryCacheDuration = $duration === null ? $this->db->queryCacheDuration : $duration;
$this->queryCacheDependency = $dependency;
return $this;
}
/**
* Disables query cache for this command.
* @return $this the command object itself
*/
public function noCache()
{
$this->queryCacheDuration = -1;
return $this;
}
/** /**
* Returns the SQL statement for this command. * Returns the SQL statement for this command.
* @return string the SQL statement to be executed * @return string the SQL statement to be executed

View File

@ -50,6 +50,7 @@ use yii\base\InvalidParamException;
class Query extends Component implements QueryInterface class Query extends Component implements QueryInterface
{ {
use QueryTrait; use QueryTrait;
use CacheableQueryTrait;
/** /**
* @var array the columns being selected. For example, `['id', 'name']`. * @var array the columns being selected. For example, `['id', 'name']`.
@ -129,7 +130,11 @@ class Query extends Component implements QueryInterface
} }
list($sql, $params) = $db->getQueryBuilder()->build($this); list($sql, $params) = $db->getQueryBuilder()->build($this);
return $db->createCommand($sql, $params); $command = $db->createCommand($sql, $params);
if ($this->hasCache()) {
$command->cache($this->queryCacheDuration, $this->queryCacheDependency);
}
return $command;
} }
/** /**
@ -449,11 +454,14 @@ class Query extends Component implements QueryInterface
return $command->queryScalar(); return $command->queryScalar();
} }
return (new self()) $command = (new self())
->select([$selectExpression]) ->select([$selectExpression])
->from(['c' => $this]) ->from(['c' => $this])
->createCommand($db) ->createCommand($db);
->queryScalar(); if ($this->hasCache()) {
$command->cache($this->queryCacheDuration, $this->queryCacheDependency);
}
return $command->queryScalar();
} }
/** /**