Browse Source

moved redis to extensions

tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
8ac2b7364d
  1. 2
      composer.json
  2. 0
      extensions/redis/ActiveQuery.php
  3. 0
      extensions/redis/ActiveRecord.php
  4. 0
      extensions/redis/ActiveRelation.php
  5. 184
      extensions/redis/Cache.php
  6. 87
      extensions/redis/Connection.php
  7. 32
      extensions/redis/LICENSE.md
  8. 0
      extensions/redis/LuaScriptBuilder.php
  9. 91
      extensions/redis/README.md
  10. 27
      extensions/redis/composer.json
  11. 2
      extensions/sphinx/composer.json
  12. 218
      framework/yii/caching/RedisCache.php
  13. 3
      framework/yii/classes.php
  14. 4
      tests/unit/data/config.php
  15. 3
      tests/unit/extensions/redis/ActiveRecordTest.php
  16. 34
      tests/unit/extensions/redis/RedisCacheTest.php
  17. 23
      tests/unit/extensions/redis/RedisConnectionTest.php
  18. 29
      tests/unit/extensions/redis/RedisTestCase.php

2
composer.json

@ -69,6 +69,7 @@
"yiisoft/yii2-debug": "self.version",
"yiisoft/yii2-gii": "self.version",
"yiisoft/yii2-jui": "self.version",
"yiisoft/yii2-redis": "self.version",
"yiisoft/yii2-smarty": "self.version",
"yiisoft/yii2-swiftmailer": "self.version",
"yiisoft/yii2-sphinx": "self.version",
@ -95,6 +96,7 @@
"yii\\debug\\": "extensions/debug/",
"yii\\gii\\": "extensions/gii/",
"yii\\jui\\": "extensions/jui/",
"yii\\redis\\": "extensions/redis/",
"yii\\smarty\\": "extensions/smarty/",
"yii\\swiftmailer\\": "extensions/swiftmailer/",
"yii\\sphinx\\": "extensions/sphinx/",

0
framework/yii/redis/ActiveQuery.php → extensions/redis/ActiveQuery.php

0
framework/yii/redis/ActiveRecord.php → extensions/redis/ActiveRecord.php

0
framework/yii/redis/ActiveRelation.php → extensions/redis/ActiveRelation.php

184
extensions/redis/Cache.php

@ -0,0 +1,184 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\redis;
/**
* 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.
*
* It needs to be configured with a redis [[Connection]] that is also configured as an application component.
* By default it will use the `redis` application component.
*
* See [[Cache]] manual for common cache operations that redis Cache supports.
*
* Unlike the [[Cache]], redis Cache allows the expire parameter of [[set]], [[add]], [[mset]] and [[madd]] to
* be a floating point number, so you may specify the time in milliseconds (e.g. 0.1 will be 100 milliseconds).
*
* To use redis Cache as the cache application component, configure the application as follows,
*
* ~~~
* [
* 'components' => [
* 'cache' => [
* 'class' => 'yii\redis\Cache',
* ],
* 'redis' => [
* 'class' => 'yii\redis\Connection',
* 'hostname' => 'localhost',
* 'port' => 6379,
* 'database' => 0,
* ]
* ],
* ]
* ~~~
*
* @property Connection $connection The redis connection object. This property is read-only.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class Cache extends \yii\caching\Cache
{
/**
* @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 $connectionId = 'redis';
/**
* Checks whether a specified key exists in the cache.
* This can be faster than getting the value from the cache if the data is big.
* Note that this method does not check whether the dependency associated
* with the cached data, if there is any, has changed. So a call to [[get]]
* may return false while exists returns true.
* @param mixed $key a key identifying the cached value. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @return boolean true if a value exists in cache, false if the value is not in the cache or expired.
*/
public function exists($key)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return (bool) $connection->executeCommand('EXISTS', [$this->buildKey($key)]);
}
/**
* @inheritDocs
*/
protected function getValue($key)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return $connection->executeCommand('GET', [$key]);
}
/**
* @inheritDocs
*/
protected function getValues($keys)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
$response = $connection->executeCommand('MGET', $keys);
$result = [];
$i = 0;
foreach ($keys as $key) {
$result[$key] = $response[$i++];
}
return $result;
}
/**
* @inheritDocs
*/
protected function setValue($key, $value, $expire)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
if ($expire == 0) {
return (bool) $connection->executeCommand('SET', [$key, $value]);
} else {
$expire = (int) ($expire * 1000);
return (bool) $connection->executeCommand('SET', [$key, $value, 'PX', $expire]);
}
}
/**
* @inheritDocs
*/
protected function setValues($data, $expire)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
$args = [];
foreach($data as $key => $value) {
$args[] = $key;
$args[] = $value;
}
$failedKeys = [];
if ($expire == 0) {
$connection->executeCommand('MSET', $args);
} else {
$expire = (int) ($expire * 1000);
$connection->executeCommand('MULTI');
$connection->executeCommand('MSET', $args);
$index = [];
foreach ($data as $key => $value) {
$connection->executeCommand('PEXPIRE', [$key, $expire]);
$index[] = $key;
}
$result = $connection->executeCommand('EXEC');
array_shift($result);
foreach($result as $i => $r) {
if ($r != 1) {
$failedKeys[] = $index[$i];
}
}
}
return $failedKeys;
}
/**
* @inheritDocs
*/
protected function addValue($key, $value, $expire)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
if ($expire == 0) {
return (bool) $connection->executeCommand('SET', [$key, $value, 'NX']);
} else {
$expire = (int) ($expire * 1000);
return (bool) $connection->executeCommand('SET', [$key, $value, 'PX', $expire, 'NX']);
}
}
/**
* @inheritDocs
*/
protected function deleteValue($key)
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return (bool) $connection->executeCommand('DEL', [$key]);
}
/**
* @inheritDocs
*/
protected function flushValues()
{
/** @var Connection $connection */
$connection = \Yii::$app->getComponent($this->connectionId);
return $connection->executeCommand('FLUSHDB');
}
}

87
framework/yii/redis/Connection.php → extensions/redis/Connection.php

@ -13,6 +13,15 @@ use yii\db\Exception;
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 get($key) Set the string value of a key
@ -33,20 +42,23 @@ class Connection extends Component
const EVENT_AFTER_OPEN = 'afterOpen';
/**
* @var string the Data Source Name, or DSN, contains the information required to connect to the database.
* 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
* @var string the hostname or ip address to use for connecting to the redis server. Defaults to 'localhost'.
*/
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.
* See http://redis.io/commands/auth
*/
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;
@ -230,38 +242,30 @@ class Connection extends Component
*/
public function open()
{
if ($this->_socket === null) {
if (empty($this->dsn)) {
throw new InvalidConfigException('Connection.dsn cannot be empty.');
}
$dsn = explode('/', $this->dsn);
$host = $dsn[2];
if (strpos($host, ':')===false) {
$host .= ':6379';
if ($this->_socket !== null) {
return;
}
$connection = $this->hostname . ':' . $this->port . ', database=' . $this->database;
\Yii::trace('Opening redis DB connection: ' . $connection, __CLASS__);
$this->_socket = @stream_socket_client(
'tcp://' . $this->hostname . ':' . $this->port,
$errorNumber,
$errorDescription,
$this->connectionTimeout ? $this->connectionTimeout : ini_get("default_socket_timeout")
);
if ($this->_socket) {
if ($this->dataTimeout !== null) {
stream_set_timeout($this->_socket, $timeout=(int)$this->dataTimeout, (int) (($this->dataTimeout - $timeout) * 1000000));
}
$db = isset($dsn[3]) ? $dsn[3] : 0;
\Yii::trace('Opening DB connection: ' . $this->dsn, __CLASS__);
$this->_socket = @stream_socket_client(
$host,
$errorNumber,
$errorDescription,
$this->connectionTimeout ? $this->connectionTimeout : ini_get("default_socket_timeout")
);
if ($this->_socket) {
if ($this->dataTimeout !== null) {
stream_set_timeout($this->_socket, $timeout=(int)$this->dataTimeout, (int) (($this->dataTimeout - $timeout) * 1000000));
}
if ($this->password !== null) {
$this->executeCommand('AUTH', [$this->password]);
}
$this->executeCommand('SELECT', [$db]);
$this->initConnection();
} else {
\Yii::error("Failed to open DB connection ({$this->dsn}): " . $errorNumber . ' - ' . $errorDescription, __CLASS__);
$message = YII_DEBUG ? 'Failed to open DB connection: ' . $errorNumber . ' - ' . $errorDescription : 'Failed to open DB connection.';
throw new Exception($message, $errorDescription, (int)$errorNumber);
if ($this->password !== null) {
$this->executeCommand('AUTH', [$this->password]);
}
$this->executeCommand('SELECT', [$this->database]);
$this->initConnection();
} else {
\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.';
throw new Exception($message, $errorDescription, (int)$errorNumber);
}
}
@ -272,7 +276,8 @@ class Connection extends Component
public function close()
{
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');
stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR);
$this->_socket = null;
@ -295,11 +300,7 @@ class Connection extends Component
*/
public function getDriverName()
{
if (($pos = strpos($this->dsn, ':')) !== false) {
return strtolower(substr($this->dsn, 0, $pos));
} else {
return 'redis';
}
return 'redis';
}
/**

32
extensions/redis/LICENSE.md

@ -0,0 +1,32 @@
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.

0
framework/yii/redis/LuaScriptBuilder.php → extensions/redis/LuaScriptBuilder.php

91
extensions/redis/README.md

@ -0,0 +1,91 @@
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.

27
extensions/redis/composer.json

@ -0,0 +1,27 @@
{
"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"
}

2
extensions/sphinx/composer.json

@ -1,7 +1,7 @@
{
"name": "yiisoft/yii2-sphinx",
"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",
"license": "BSD-3-Clause",
"support": {

218
framework/yii/caching/RedisCache.php

@ -1,218 +0,0 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\caching;
use yii\redis\Connection;
/**
* RedisCache implements a cache application component based on [redis](http://redis.io/) version 2.6.12 or higher.
*
* RedisCache needs to be configured with [[hostname]], [[port]] and [[database]] of the server
* to connect to. By default RedisCache assumes there is a redis server running on localhost at
* port 6379 and uses the database number 0.
*
* RedisCache 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.
*
* See [[Cache]] manual for common cache operations that RedisCache supports.
* Unlike the [[CCache]], RedisCache allows the expire parameter of
* [[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,
*
* ~~~
* [
* 'components' => [
* 'cache' => [
* 'class' => 'RedisCache',
* 'hostname' => 'localhost',
* 'port' => 6379,
* 'database' => 0,
* ],
* ],
* ]
* ~~~
*
* @property Connection $connection The redis connection object. This property is read-only.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class RedisCache extends Cache
{
/**
* @var string hostname to use for connecting to the redis server. Defaults to 'localhost'.
*/
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;
/**
* @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.
* This can be faster than getting the value from the cache if the data is big.
* Note that this method does not check whether the dependency associated
* with the cached data, if there is any, has changed. So a call to [[get]]
* may return false while exists returns true.
* @param mixed $key a key identifying the cached value. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @return boolean true if a value exists in cache, false if the value is not in the cache or expired.
*/
public function exists($key)
{
return (bool) $this->_connection->executeCommand('EXISTS', [$this->buildKey($key)]);
}
/**
* @inheritDocs
*/
protected function getValue($key)
{
return $this->_connection->executeCommand('GET', [$key]);
}
/**
* @inheritDocs
*/
protected function getValues($keys)
{
$response = $this->_connection->executeCommand('MGET', $keys);
$result = [];
$i = 0;
foreach ($keys as $key) {
$result[$key] = $response[$i++];
}
return $result;
}
/**
* @inheritDocs
*/
protected function setValue($key, $value, $expire)
{
if ($expire == 0) {
return (bool) $this->_connection->executeCommand('SET', [$key, $value]);
} else {
$expire = (int) ($expire * 1000);
return (bool) $this->_connection->executeCommand('SET', [$key, $value, 'PX', $expire]);
}
}
/**
* @inheritDocs
*/
protected function setValues($data, $expire)
{
$args = [];
foreach($data as $key => $value) {
$args[] = $key;
$args[] = $value;
}
$failedKeys = [];
if ($expire == 0) {
$this->_connection->executeCommand('MSET', $args);
} else {
$expire = (int) ($expire * 1000);
$this->_connection->executeCommand('MULTI');
$this->_connection->executeCommand('MSET', $args);
$index = [];
foreach ($data as $key => $value) {
$this->_connection->executeCommand('PEXPIRE', [$key, $expire]);
$index[] = $key;
}
$result = $this->_connection->executeCommand('EXEC');
array_shift($result);
foreach($result as $i => $r) {
if ($r != 1) {
$failedKeys[] = $index[$i];
}
}
}
return $failedKeys;
}
/**
* @inheritDocs
*/
protected function addValue($key, $value, $expire)
{
if ($expire == 0) {
return (bool) $this->_connection->executeCommand('SET', [$key, $value, 'NX']);
} else {
$expire = (int) ($expire * 1000);
return (bool) $this->_connection->executeCommand('SET', [$key, $value, 'PX', $expire, 'NX']);
}
}
/**
* @inheritDocs
*/
protected function deleteValue($key)
{
return (bool) $this->_connection->executeCommand('DEL', [$key]);
}
/**
* @inheritDocs
*/
protected function flushValues()
{
return $this->_connection->executeCommand('FLUSHDB');
}
}

3
framework/yii/classes.php

@ -61,7 +61,6 @@ return [
'yii\caching\GroupDependency' => YII_PATH . '/caching/GroupDependency.php',
'yii\caching\MemCache' => YII_PATH . '/caching/MemCache.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\XCache' => YII_PATH . '/caching/XCache.php',
'yii\caching\ZendDataCache' => YII_PATH . '/caching/ZendDataCache.php',
@ -168,8 +167,6 @@ return [
'yii\rbac\Item' => YII_PATH . '/rbac/Item.php',
'yii\rbac\Manager' => YII_PATH . '/rbac/Manager.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\test\DbFixtureManager' => YII_PATH . '/test/DbFixtureManager.php',
'yii\test\DbTestTrait' => YII_PATH . '/test/DbTestTrait.php',

4
tests/unit/data/config.php

@ -30,7 +30,9 @@ return [
'fixture' => __DIR__ . '/postgres.sql',
],
'redis' => [
'dsn' => 'redis://localhost:6379/0',
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
'password' => null,
],
],

3
tests/unit/framework/redis/ActiveRecordTest.php → tests/unit/extensions/redis/ActiveRecordTest.php

@ -1,8 +1,7 @@
<?php
namespace yiiunit\framework\redis;
namespace yiiunit\extensions\redis;
use yii\db\Query;
use yii\redis\ActiveQuery;
use yiiunit\data\ar\redis\ActiveRecord;
use yiiunit\data\ar\redis\Customer;

34
tests/unit/framework/caching/RedisCacheTest.php → tests/unit/extensions/redis/RedisCacheTest.php

@ -1,7 +1,12 @@
<?php
namespace yiiunit\framework\caching;
use yii\caching\MemCache;
use yii\caching\RedisCache;
namespace yiiunit\extensions\redis;
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
@ -13,23 +18,24 @@ class RedisCacheTest extends CacheTestCase
private $_cacheInstance = null;
/**
* @return MemCache
* @return Cache
*/
protected function getCacheInstance()
{
$config = [
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
'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);
$databases = $this->getParam('databases');
$params = isset($databases['redis']) ? $databases['redis'] : null;
if ($params === null) {
$this->markTestSkipped('No redis server connection configured.');
}
$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) {
$this->_cacheInstance = new RedisCache($config);
$this->_cacheInstance = new Cache();
}
return $this->_cacheInstance;
}

23
tests/unit/framework/redis/RedisConnectionTest.php → tests/unit/extensions/redis/RedisConnectionTest.php

@ -1,6 +1,6 @@
<?php
namespace yiiunit\framework\redis;
namespace yiiunit\extensions\redis;
use yii\redis\Connection;
@ -10,35 +10,24 @@ use yii\redis\Connection;
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
*/
public function testConnect()
{
$db = new Connection();
$db->dsn = 'redis://localhost:6379';
$db = $this->getConnection(false);
$db->open();
$this->assertTrue($db->ping());
$db->set('YIITESTKEY', 'YIITESTVALUE');
$db->close();
$db = new Connection();
$db->dsn = 'redis://localhost:6379/0';
$db = $this->getConnection(false);
$db->database = 0;
$db->open();
$this->assertEquals('YIITESTVALUE', $db->get('YIITESTKEY'));
$db->close();
$db = new Connection();
$db->dsn = 'redis://localhost:6379/1';
$db = $this->getConnection(false);
$db->database = 1;
$db->open();
$this->assertNull($db->get('YIITESTKEY'));
$db->close();

29
tests/unit/framework/redis/RedisTestCase.php → tests/unit/extensions/redis/RedisTestCase.php

@ -1,10 +1,13 @@
<?php
namespace yiiunit\framework\redis;
namespace yiiunit\extensions\redis;
use Yii;
use yii\redis\Connection;
use yiiunit\TestCase;
Yii::setAlias('@yii/redis', __DIR__ . '/../../../../extensions/redis');
/**
* RedisTestCase is the base class for all redis related test cases
*/
@ -12,22 +15,18 @@ abstract class RedisTestCase extends TestCase
{
protected function setUp()
{
$this->mockApplication();
$databases = $this->getParam('databases');
$params = isset($databases['redis']) ? $databases['redis'] : null;
if ($params === null || !isset($params['dsn'])) {
if ($params === null) {
$this->markTestSkipped('No redis server connection configured.');
}
$dsn = explode('/', $params['dsn']);
$host = $dsn[2];
if (strpos($host, ':')===false) {
$host .= ':6379';
}
if(!@stream_socket_client($host, $errorNumber, $errorDescription, 0.5)) {
$this->markTestSkipped('No redis server running at ' . $params['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]]);
parent::setUp();
}
@ -38,13 +37,11 @@ abstract class RedisTestCase extends TestCase
public function getConnection($reset = true)
{
$databases = $this->getParam('databases');
$params = isset($databases['redis']) ? $databases['redis'] : array();
$db = new Connection;
$db->dsn = $params['dsn'];
$db->password = $params['password'];
$params = isset($databases['redis']) ? $databases['redis'] : [];
$db = new Connection($params);
if ($reset) {
$db->open();
$db->flushall();
$db->flushdb();
}
return $db;
}
Loading…
Cancel
Save