Commit 8ac2b736 by Carsten Brandt

moved redis to extensions

parent 4c1b823d
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
"yiisoft/yii2-debug": "self.version", "yiisoft/yii2-debug": "self.version",
"yiisoft/yii2-gii": "self.version", "yiisoft/yii2-gii": "self.version",
"yiisoft/yii2-jui": "self.version", "yiisoft/yii2-jui": "self.version",
"yiisoft/yii2-redis": "self.version",
"yiisoft/yii2-smarty": "self.version", "yiisoft/yii2-smarty": "self.version",
"yiisoft/yii2-swiftmailer": "self.version", "yiisoft/yii2-swiftmailer": "self.version",
"yiisoft/yii2-sphinx": "self.version", "yiisoft/yii2-sphinx": "self.version",
...@@ -95,6 +96,7 @@ ...@@ -95,6 +96,7 @@
"yii\\debug\\": "extensions/debug/", "yii\\debug\\": "extensions/debug/",
"yii\\gii\\": "extensions/gii/", "yii\\gii\\": "extensions/gii/",
"yii\\jui\\": "extensions/jui/", "yii\\jui\\": "extensions/jui/",
"yii\\redis\\": "extensions/redis/",
"yii\\smarty\\": "extensions/smarty/", "yii\\smarty\\": "extensions/smarty/",
"yii\\swiftmailer\\": "extensions/swiftmailer/", "yii\\swiftmailer\\": "extensions/swiftmailer/",
"yii\\sphinx\\": "extensions/sphinx/", "yii\\sphinx\\": "extensions/sphinx/",
......
...@@ -5,36 +5,35 @@ ...@@ -5,36 +5,35 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\caching; namespace yii\redis;
use yii\redis\Connection;
/** /**
* RedisCache implements a cache application component based on [redis](http://redis.io/) version 2.6.12 or higher. * Redis Cache implements a cache application component based on [redis](http://redis.io/) key-value store.
*
* Redis Cache requires redis version 2.6.12 or higher to work properly.
* *
* RedisCache needs to be configured with [[hostname]], [[port]] and [[database]] of the server * It needs to be configured with a redis [[Connection]] that is also configured as an application component.
* to connect to. By default RedisCache assumes there is a redis server running on localhost at * By default it will use the `redis` application component.
* port 6379 and uses the database number 0.
* *
* RedisCache also supports [the AUTH command](http://redis.io/commands/auth) of redis. * See [[Cache]] manual for common cache operations that redis Cache supports.
* When the server needs authentication, you can set the [[password]] property to
* authenticate with the server after connect.
* *
* See [[Cache]] manual for common cache operations that RedisCache supports. * Unlike the [[Cache]], redis Cache allows the expire parameter of [[set]], [[add]], [[mset]] and [[madd]] to
* Unlike the [[CCache]], RedisCache allows the expire parameter of * be a floating point number, so you may specify the time in milliseconds (e.g. 0.1 will be 100 milliseconds).
* [[set]] and [[add]] to be a floating point number, so you may specify the time in milliseconds.
* *
* To use RedisCache as the cache application component, configure the application as follows, * To use redis Cache as the cache application component, configure the application as follows,
* *
* ~~~ * ~~~
* [ * [
* 'components' => [ * 'components' => [
* 'cache' => [ * 'cache' => [
* 'class' => 'RedisCache', * 'class' => 'yii\redis\Cache',
* ],
* 'redis' => [
* 'class' => 'yii\redis\Connection',
* 'hostname' => 'localhost', * 'hostname' => 'localhost',
* 'port' => 6379, * 'port' => 6379,
* 'database' => 0, * 'database' => 0,
* ], * ]
* ], * ],
* ] * ]
* ~~~ * ~~~
...@@ -44,64 +43,14 @@ use yii\redis\Connection; ...@@ -44,64 +43,14 @@ use yii\redis\Connection;
* @author Carsten Brandt <mail@cebe.cc> * @author Carsten Brandt <mail@cebe.cc>
* @since 2.0 * @since 2.0
*/ */
class RedisCache extends Cache class Cache extends \yii\caching\Cache
{ {
/** /**
* @var string hostname to use for connecting to the redis server. Defaults to 'localhost'. * @var string the id of the application component to use as the redis connection.
*/ * It should be configured as a [[yii\redis\Connection]]. Defaults to `redis`.
public $hostname = 'localhost';
/**
* @var int the port to use for connecting to the redis server. Default port is 6379.
*/
public $port = 6379;
/**
* @var string the password to use to authenticate with the redis server. If not set, no AUTH command will be sent.
*/
public $password;
/**
* @var int the redis database to use. This is an integer value starting from 0. Defaults to 0.
*/
public $database = 0;
/**
* @var float timeout to use for connection to redis. If not set the timeout set in php.ini will be used: ini_get("default_socket_timeout")
*/
public $connectionTimeout = null;
/**
* @var float timeout to use for redis socket when reading and writing data. If not set the php default value will be used.
*/ */
public $dataTimeout = null; public $connectionId = 'redis';
/**
* @var Connection the redis connection
*/
private $_connection;
/**
* Initializes the cache component by establishing a connection to the redis server.
*/
public function init()
{
parent::init();
$this->getConnection();
}
/**
* Returns the redis connection object.
* Establishes a connection to the redis server if it does not already exists.
* @return Connection the redis connection object.
*/
public function getConnection()
{
if ($this->_connection === null) {
$this->_connection = new Connection([
'dsn' => 'redis://' . $this->hostname . ':' . $this->port . '/' . $this->database,
'password' => $this->password,
'connectionTimeout' => $this->connectionTimeout,
'dataTimeout' => $this->dataTimeout,
]);
}
return $this->_connection;
}
/** /**
* Checks whether a specified key exists in the cache. * Checks whether a specified key exists in the cache.
...@@ -115,7 +64,9 @@ class RedisCache extends Cache ...@@ -115,7 +64,9 @@ class RedisCache extends Cache
*/ */
public function exists($key) public function exists($key)
{ {
return (bool) $this->_connection->executeCommand('EXISTS', [$this->buildKey($key)]); /** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return (bool) $connection->executeCommand('EXISTS', [$this->buildKey($key)]);
} }
/** /**
...@@ -123,7 +74,9 @@ class RedisCache extends Cache ...@@ -123,7 +74,9 @@ class RedisCache extends Cache
*/ */
protected function getValue($key) protected function getValue($key)
{ {
return $this->_connection->executeCommand('GET', [$key]); /** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return $connection->executeCommand('GET', [$key]);
} }
/** /**
...@@ -131,7 +84,9 @@ class RedisCache extends Cache ...@@ -131,7 +84,9 @@ class RedisCache extends Cache
*/ */
protected function getValues($keys) protected function getValues($keys)
{ {
$response = $this->_connection->executeCommand('MGET', $keys); /** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
$response = $connection->executeCommand('MGET', $keys);
$result = []; $result = [];
$i = 0; $i = 0;
foreach ($keys as $key) { foreach ($keys as $key) {
...@@ -145,11 +100,13 @@ class RedisCache extends Cache ...@@ -145,11 +100,13 @@ class RedisCache extends Cache
*/ */
protected function setValue($key, $value, $expire) protected function setValue($key, $value, $expire)
{ {
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
if ($expire == 0) { if ($expire == 0) {
return (bool) $this->_connection->executeCommand('SET', [$key, $value]); return (bool) $connection->executeCommand('SET', [$key, $value]);
} else { } else {
$expire = (int) ($expire * 1000); $expire = (int) ($expire * 1000);
return (bool) $this->_connection->executeCommand('SET', [$key, $value, 'PX', $expire]); return (bool) $connection->executeCommand('SET', [$key, $value, 'PX', $expire]);
} }
} }
...@@ -158,6 +115,9 @@ class RedisCache extends Cache ...@@ -158,6 +115,9 @@ class RedisCache extends Cache
*/ */
protected function setValues($data, $expire) protected function setValues($data, $expire)
{ {
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
$args = []; $args = [];
foreach($data as $key => $value) { foreach($data as $key => $value) {
$args[] = $key; $args[] = $key;
...@@ -166,17 +126,17 @@ class RedisCache extends Cache ...@@ -166,17 +126,17 @@ class RedisCache extends Cache
$failedKeys = []; $failedKeys = [];
if ($expire == 0) { if ($expire == 0) {
$this->_connection->executeCommand('MSET', $args); $connection->executeCommand('MSET', $args);
} else { } else {
$expire = (int) ($expire * 1000); $expire = (int) ($expire * 1000);
$this->_connection->executeCommand('MULTI'); $connection->executeCommand('MULTI');
$this->_connection->executeCommand('MSET', $args); $connection->executeCommand('MSET', $args);
$index = []; $index = [];
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$this->_connection->executeCommand('PEXPIRE', [$key, $expire]); $connection->executeCommand('PEXPIRE', [$key, $expire]);
$index[] = $key; $index[] = $key;
} }
$result = $this->_connection->executeCommand('EXEC'); $result = $connection->executeCommand('EXEC');
array_shift($result); array_shift($result);
foreach($result as $i => $r) { foreach($result as $i => $r) {
if ($r != 1) { if ($r != 1) {
...@@ -192,11 +152,13 @@ class RedisCache extends Cache ...@@ -192,11 +152,13 @@ class RedisCache extends Cache
*/ */
protected function addValue($key, $value, $expire) protected function addValue($key, $value, $expire)
{ {
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
if ($expire == 0) { if ($expire == 0) {
return (bool) $this->_connection->executeCommand('SET', [$key, $value, 'NX']); return (bool) $connection->executeCommand('SET', [$key, $value, 'NX']);
} else { } else {
$expire = (int) ($expire * 1000); $expire = (int) ($expire * 1000);
return (bool) $this->_connection->executeCommand('SET', [$key, $value, 'PX', $expire, 'NX']); return (bool) $connection->executeCommand('SET', [$key, $value, 'PX', $expire, 'NX']);
} }
} }
...@@ -205,7 +167,9 @@ class RedisCache extends Cache ...@@ -205,7 +167,9 @@ class RedisCache extends Cache
*/ */
protected function deleteValue($key) protected function deleteValue($key)
{ {
return (bool) $this->_connection->executeCommand('DEL', [$key]); /** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return (bool) $connection->executeCommand('DEL', [$key]);
} }
/** /**
...@@ -213,6 +177,8 @@ class RedisCache extends Cache ...@@ -213,6 +177,8 @@ class RedisCache extends Cache
*/ */
protected function flushValues() protected function flushValues()
{ {
return $this->_connection->executeCommand('FLUSHDB'); /** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return $connection->executeCommand('FLUSHDB');
} }
} }
...@@ -13,6 +13,15 @@ use yii\db\Exception; ...@@ -13,6 +13,15 @@ use yii\db\Exception;
use yii\helpers\Inflector; use yii\helpers\Inflector;
/** /**
* The redis connection class is used to establish a connection to a [redis](http://redis.io/) server.
*
* By default it assumes there is a redis server running on localhost at port 6379 and uses the database number 0.
*
* It also supports [the AUTH command](http://redis.io/commands/auth) of redis.
* When the server needs authentication, you can set the [[password]] property to
* authenticate with the server after connect.
*
* The ecexution of [redis commands](http://redis.io/commands) is possible with via [[executeCommand()]].
* *
* @method mixed set($key, $value) Set the string value of a key * @method mixed set($key, $value) Set the string value of a key
* @method mixed get($key) Set the string value of a key * @method mixed get($key) Set the string value of a key
...@@ -33,20 +42,23 @@ class Connection extends Component ...@@ -33,20 +42,23 @@ class Connection extends Component
const EVENT_AFTER_OPEN = 'afterOpen'; const EVENT_AFTER_OPEN = 'afterOpen';
/** /**
* @var string the Data Source Name, or DSN, contains the information required to connect to the database. * @var string the hostname or ip address to use for connecting to the redis server. Defaults to 'localhost'.
* DSN format: redis://server:port[/db]
* Where db is a zero based integer which refers to the DB to use.
* If no DB is given, ID 0 is used.
*
* Example: redis://localhost:6379/2
*/ */
public $dsn; public $hostname = 'localhost';
/**
* @var int the port to use for connecting to the redis server. Default port is 6379.
*/
public $port = 6379;
/** /**
* @var string the password for establishing DB connection. Defaults to null meaning no AUTH command is send. * @var string the password for establishing DB connection. Defaults to null meaning no AUTH command is send.
* See http://redis.io/commands/auth * See http://redis.io/commands/auth
*/ */
public $password; public $password;
/** /**
* @var int the redis database to use. This is an integer value starting from 0. Defaults to 0.
*/
public $database = 0;
/**
* @var float timeout to use for connection to redis. If not set the timeout set in php.ini will be used: ini_get("default_socket_timeout") * @var float timeout to use for connection to redis. If not set the timeout set in php.ini will be used: ini_get("default_socket_timeout")
*/ */
public $connectionTimeout = null; public $connectionTimeout = null;
...@@ -230,20 +242,13 @@ class Connection extends Component ...@@ -230,20 +242,13 @@ class Connection extends Component
*/ */
public function open() public function open()
{ {
if ($this->_socket === null) { if ($this->_socket !== null) {
if (empty($this->dsn)) { return;
throw new InvalidConfigException('Connection.dsn cannot be empty.');
}
$dsn = explode('/', $this->dsn);
$host = $dsn[2];
if (strpos($host, ':')===false) {
$host .= ':6379';
} }
$db = isset($dsn[3]) ? $dsn[3] : 0; $connection = $this->hostname . ':' . $this->port . ', database=' . $this->database;
\Yii::trace('Opening redis DB connection: ' . $connection, __CLASS__);
\Yii::trace('Opening DB connection: ' . $this->dsn, __CLASS__);
$this->_socket = @stream_socket_client( $this->_socket = @stream_socket_client(
$host, 'tcp://' . $this->hostname . ':' . $this->port,
$errorNumber, $errorNumber,
$errorDescription, $errorDescription,
$this->connectionTimeout ? $this->connectionTimeout : ini_get("default_socket_timeout") $this->connectionTimeout ? $this->connectionTimeout : ini_get("default_socket_timeout")
...@@ -255,15 +260,14 @@ class Connection extends Component ...@@ -255,15 +260,14 @@ class Connection extends Component
if ($this->password !== null) { if ($this->password !== null) {
$this->executeCommand('AUTH', [$this->password]); $this->executeCommand('AUTH', [$this->password]);
} }
$this->executeCommand('SELECT', [$db]); $this->executeCommand('SELECT', [$this->database]);
$this->initConnection(); $this->initConnection();
} else { } else {
\Yii::error("Failed to open DB connection ({$this->dsn}): " . $errorNumber . ' - ' . $errorDescription, __CLASS__); \Yii::error("Failed to open DB connection ($connection): " . $errorNumber . ' - ' . $errorDescription, __CLASS__);
$message = YII_DEBUG ? 'Failed to open DB connection: ' . $errorNumber . ' - ' . $errorDescription : 'Failed to open DB connection.'; $message = YII_DEBUG ? 'Failed to open DB connection: ' . $errorNumber . ' - ' . $errorDescription : 'Failed to open DB connection.';
throw new Exception($message, $errorDescription, (int)$errorNumber); throw new Exception($message, $errorDescription, (int)$errorNumber);
} }
} }
}
/** /**
* Closes the currently active DB connection. * Closes the currently active DB connection.
...@@ -272,7 +276,8 @@ class Connection extends Component ...@@ -272,7 +276,8 @@ class Connection extends Component
public function close() public function close()
{ {
if ($this->_socket !== null) { if ($this->_socket !== null) {
\Yii::trace('Closing DB connection: ' . $this->dsn, __CLASS__); $connection = $this->hostname . ':' . $this->port . ', database=' . $this->database;
\Yii::trace('Closing DB connection: ' . $connection, __CLASS__);
$this->executeCommand('QUIT'); $this->executeCommand('QUIT');
stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR); stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR);
$this->_socket = null; $this->_socket = null;
...@@ -295,12 +300,8 @@ class Connection extends Component ...@@ -295,12 +300,8 @@ class Connection extends Component
*/ */
public function getDriverName() public function getDriverName()
{ {
if (($pos = strpos($this->dsn, ':')) !== false) {
return strtolower(substr($this->dsn, 0, $pos));
} else {
return 'redis'; return 'redis';
} }
}
/** /**
* @return LuaScriptBuilder * @return LuaScriptBuilder
......
The Yii framework is free software. It is released under the terms of
the following BSD License.
Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Yii Software LLC nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Redis Cache and ActiveRecord for Yii 2
======================================
This extension provides the [redis](http://redis.io/) key-value store support for the Yii2 framework.
It includes a `Cache` class and implents the `ActiveRecord` pattern that allows you to store active
records in redis.
To use this extension, you have to configure the Connection class in your application configuration:
```php
return [
//....
'components' => [
'redis' => [
'class' => 'yii\redis\Connection',
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
],
]
];
```
To use the `Cache` component, you also have to configure the `cache` component to be `yii\redis\Cache`:
```php
return [
//....
'components' => [
// ...
'cache' => [
'class' => 'yii\redis\Cache',
],
]
];
```
Installation
------------
The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
Either run
```
php composer.phar require yiisoft/yii2-redis "*"
```
or add
```json
"yiisoft/yii2-redis": "*"
```
to the require section of your composer.json.
Using the redis ActiveRecord
----------------------------
For general information on how to use yii's ActiveRecord please refer to the [guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/active-record.md).
For defining a redis ActiveRecord class your record class needs to extend from `yii\redis\ActiveRecord` and
implement at least the `attributes()` method to define the attributes of the record.
A primary key can be defined via [[primaryKey()]] which defaults to `id` if not specified.
The primaryKey needs to be part of the attributes so make sure you have an `id` attribute defined if you do
not specify your own primary key.
The following is an example model called `Customer`:
```php
class Customer extends \yii\redis\ActiveRecord
{
public function attributes()
{
return ['id', 'name', 'address', 'registration_date'];
}
}
```
The general usage of redis ActiveRecord is very similar to the database ActiveRecord as described in the
[guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/active-record.md).
It supports the same interface and features except the following limitations:
- As redis does not support SQL the query API is limited to the following methods:
`where()`, `limit()`, `offset()`, `orderBy()` and `indexBy()`.
(orderBy() is not yet implemented: [#1305](https://github.com/yiisoft/yii2/issues/1305))
- `via`-relations can not be defined via a table as there are not tables in redis. You can only define relations via other records.
It is also possible to define relations from redis ActiveRecords to normal ActiveRecord classes and vice versa.
\ No newline at end of file
{
"name": "yiisoft/yii2-redis",
"description": "Redis Cache and ActiveRecord for the Yii framework",
"keywords": ["yii", "redis", "active-record", "cache"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aredis",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"authors": [
{
"name": "Carsten Brandt",
"email": "mail@cebe.cc"
}
],
"require": {
"yiisoft/yii2": "*"
},
"autoload": {
"psr-0": { "yii\\redis\\": "" }
},
"target-dir": "yii/redis"
}
{ {
"name": "yiisoft/yii2-sphinx", "name": "yiisoft/yii2-sphinx",
"description": "Sphinx full text search engine extension for the Yii framework", "description": "Sphinx full text search engine extension for the Yii framework",
"keywords": ["yii", "sphinx", "search", "fulltext"], "keywords": ["yii", "sphinx", "active-record", "search", "fulltext"],
"type": "yii2-extension", "type": "yii2-extension",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"support": { "support": {
......
...@@ -61,7 +61,6 @@ return [ ...@@ -61,7 +61,6 @@ return [
'yii\caching\GroupDependency' => YII_PATH . '/caching/GroupDependency.php', 'yii\caching\GroupDependency' => YII_PATH . '/caching/GroupDependency.php',
'yii\caching\MemCache' => YII_PATH . '/caching/MemCache.php', 'yii\caching\MemCache' => YII_PATH . '/caching/MemCache.php',
'yii\caching\MemCacheServer' => YII_PATH . '/caching/MemCacheServer.php', 'yii\caching\MemCacheServer' => YII_PATH . '/caching/MemCacheServer.php',
'yii\caching\RedisCache' => YII_PATH . '/caching/RedisCache.php',
'yii\caching\WinCache' => YII_PATH . '/caching/WinCache.php', 'yii\caching\WinCache' => YII_PATH . '/caching/WinCache.php',
'yii\caching\XCache' => YII_PATH . '/caching/XCache.php', 'yii\caching\XCache' => YII_PATH . '/caching/XCache.php',
'yii\caching\ZendDataCache' => YII_PATH . '/caching/ZendDataCache.php', 'yii\caching\ZendDataCache' => YII_PATH . '/caching/ZendDataCache.php',
...@@ -168,8 +167,6 @@ return [ ...@@ -168,8 +167,6 @@ return [
'yii\rbac\Item' => YII_PATH . '/rbac/Item.php', 'yii\rbac\Item' => YII_PATH . '/rbac/Item.php',
'yii\rbac\Manager' => YII_PATH . '/rbac/Manager.php', 'yii\rbac\Manager' => YII_PATH . '/rbac/Manager.php',
'yii\rbac\PhpManager' => YII_PATH . '/rbac/PhpManager.php', 'yii\rbac\PhpManager' => YII_PATH . '/rbac/PhpManager.php',
'yii\redis\Connection' => YII_PATH . '/redis/Connection.php',
'yii\redis\Transaction' => YII_PATH . '/redis/Transaction.php',
'yii\requirements\YiiRequirementChecker' => YII_PATH . '/requirements/YiiRequirementChecker.php', 'yii\requirements\YiiRequirementChecker' => YII_PATH . '/requirements/YiiRequirementChecker.php',
'yii\test\DbFixtureManager' => YII_PATH . '/test/DbFixtureManager.php', 'yii\test\DbFixtureManager' => YII_PATH . '/test/DbFixtureManager.php',
'yii\test\DbTestTrait' => YII_PATH . '/test/DbTestTrait.php', 'yii\test\DbTestTrait' => YII_PATH . '/test/DbTestTrait.php',
......
...@@ -30,7 +30,9 @@ return [ ...@@ -30,7 +30,9 @@ return [
'fixture' => __DIR__ . '/postgres.sql', 'fixture' => __DIR__ . '/postgres.sql',
], ],
'redis' => [ 'redis' => [
'dsn' => 'redis://localhost:6379/0', 'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
'password' => null, 'password' => null,
], ],
], ],
......
<?php <?php
namespace yiiunit\framework\redis; namespace yiiunit\extensions\redis;
use yii\db\Query;
use yii\redis\ActiveQuery; use yii\redis\ActiveQuery;
use yiiunit\data\ar\redis\ActiveRecord; use yiiunit\data\ar\redis\ActiveRecord;
use yiiunit\data\ar\redis\Customer; use yiiunit\data\ar\redis\Customer;
......
<?php <?php
namespace yiiunit\framework\caching; namespace yiiunit\extensions\redis;
use yii\caching\MemCache;
use yii\caching\RedisCache; use Yii;
use yii\redis\Cache;
use yii\redis\Connection;
use yiiunit\framework\caching\CacheTestCase;
Yii::setAlias('@yii/redis', __DIR__ . '/../../../../extensions/redis');
/** /**
* Class for testing redis cache backend * Class for testing redis cache backend
...@@ -13,23 +18,24 @@ class RedisCacheTest extends CacheTestCase ...@@ -13,23 +18,24 @@ class RedisCacheTest extends CacheTestCase
private $_cacheInstance = null; private $_cacheInstance = null;
/** /**
* @return MemCache * @return Cache
*/ */
protected function getCacheInstance() protected function getCacheInstance()
{ {
$config = [ $databases = $this->getParam('databases');
'hostname' => 'localhost', $params = isset($databases['redis']) ? $databases['redis'] : null;
'port' => 6379, if ($params === null) {
'database' => 0, $this->markTestSkipped('No redis server connection configured.');
'dataTimeout' => 0.1,
];
$dsn = $config['hostname'] . ':' .$config['port'];
if (!@stream_socket_client($dsn, $errorNumber, $errorDescription, 0.5)) {
$this->markTestSkipped('No redis server running at ' . $dsn .' : ' . $errorNumber . ' - ' . $errorDescription);
} }
$connection = new Connection($params);
if(!@stream_socket_client($connection->hostname . ':' . $connection->port, $errorNumber, $errorDescription, 0.5)) {
$this->markTestSkipped('No redis server running at ' . $connection->hostname . ':' . $connection->port . ' : ' . $errorNumber . ' - ' . $errorDescription);
}
$this->mockApplication(['components' => ['redis' => $connection]]);
if ($this->_cacheInstance === null) { if ($this->_cacheInstance === null) {
$this->_cacheInstance = new RedisCache($config); $this->_cacheInstance = new Cache();
} }
return $this->_cacheInstance; return $this->_cacheInstance;
} }
......
<?php <?php
namespace yiiunit\framework\redis; namespace yiiunit\extensions\redis;
use yii\redis\Connection; use yii\redis\Connection;
...@@ -10,35 +10,24 @@ use yii\redis\Connection; ...@@ -10,35 +10,24 @@ use yii\redis\Connection;
class RedisConnectionTest extends RedisTestCase class RedisConnectionTest extends RedisTestCase
{ {
/** /**
* Empty DSN should throw exception
* @expectedException \yii\base\InvalidConfigException
*/
public function testEmptyDSN()
{
$db = new Connection();
$db->open();
}
/**
* test connection to redis and selection of db * test connection to redis and selection of db
*/ */
public function testConnect() public function testConnect()
{ {
$db = new Connection(); $db = $this->getConnection(false);
$db->dsn = 'redis://localhost:6379';
$db->open(); $db->open();
$this->assertTrue($db->ping()); $this->assertTrue($db->ping());
$db->set('YIITESTKEY', 'YIITESTVALUE'); $db->set('YIITESTKEY', 'YIITESTVALUE');
$db->close(); $db->close();
$db = new Connection(); $db = $this->getConnection(false);
$db->dsn = 'redis://localhost:6379/0'; $db->database = 0;
$db->open(); $db->open();
$this->assertEquals('YIITESTVALUE', $db->get('YIITESTKEY')); $this->assertEquals('YIITESTVALUE', $db->get('YIITESTKEY'));
$db->close(); $db->close();
$db = new Connection(); $db = $this->getConnection(false);
$db->dsn = 'redis://localhost:6379/1'; $db->database = 1;
$db->open(); $db->open();
$this->assertNull($db->get('YIITESTKEY')); $this->assertNull($db->get('YIITESTKEY'));
$db->close(); $db->close();
......
<?php <?php
namespace yiiunit\framework\redis; namespace yiiunit\extensions\redis;
use Yii;
use yii\redis\Connection; use yii\redis\Connection;
use yiiunit\TestCase; use yiiunit\TestCase;
Yii::setAlias('@yii/redis', __DIR__ . '/../../../../extensions/redis');
/** /**
* RedisTestCase is the base class for all redis related test cases * RedisTestCase is the base class for all redis related test cases
*/ */
...@@ -12,22 +15,18 @@ abstract class RedisTestCase extends TestCase ...@@ -12,22 +15,18 @@ abstract class RedisTestCase extends TestCase
{ {
protected function setUp() protected function setUp()
{ {
$this->mockApplication();
$databases = $this->getParam('databases'); $databases = $this->getParam('databases');
$params = isset($databases['redis']) ? $databases['redis'] : null; $params = isset($databases['redis']) ? $databases['redis'] : null;
if ($params === null || !isset($params['dsn'])) { if ($params === null) {
$this->markTestSkipped('No redis server connection configured.'); $this->markTestSkipped('No redis server connection configured.');
} }
$dsn = explode('/', $params['dsn']); $connection = new Connection($params);
$host = $dsn[2]; if(!@stream_socket_client($connection->hostname . ':' . $connection->port, $errorNumber, $errorDescription, 0.5)) {
if (strpos($host, ':')===false) { $this->markTestSkipped('No redis server running at ' . $connection->hostname . ':' . $connection->port . ' : ' . $errorNumber . ' - ' . $errorDescription);
$host .= ':6379';
}
if(!@stream_socket_client($host, $errorNumber, $errorDescription, 0.5)) {
$this->markTestSkipped('No redis server running at ' . $params['dsn'] . ' : ' . $errorNumber . ' - ' . $errorDescription);
} }
$this->mockApplication(['components' => ['redis' => $connection]]);
parent::setUp(); parent::setUp();
} }
...@@ -38,13 +37,11 @@ abstract class RedisTestCase extends TestCase ...@@ -38,13 +37,11 @@ abstract class RedisTestCase extends TestCase
public function getConnection($reset = true) public function getConnection($reset = true)
{ {
$databases = $this->getParam('databases'); $databases = $this->getParam('databases');
$params = isset($databases['redis']) ? $databases['redis'] : array(); $params = isset($databases['redis']) ? $databases['redis'] : [];
$db = new Connection; $db = new Connection($params);
$db->dsn = $params['dsn'];
$db->password = $params['password'];
if ($reset) { if ($reset) {
$db->open(); $db->open();
$db->flushall(); $db->flushdb();
} }
return $db; return $db;
} }
......
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