You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

248 lines
6.8 KiB

<?php
/**
* Connection class file
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\db\redis;
use \yii\base\Component;
use yii\base\NotSupportedException;
use yii\base\InvalidConfigException;
use \yii\db\Exception;
/**
*
*
*
*
* @since 2.0
*/
class Connection extends Component
{
/**
* @event Event an event that is triggered after a DB connection is established
*/
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://[auth@][server][:port][/db]
* @see charset
*/
public $dsn;
/**
* @var string the username for establishing DB connection. Defaults to empty string.
*/
public $username = '';
/**
* @var string the password for establishing DB connection. Defaults to empty string.
*/
public $password = '';
/**
* @var \Jamm\Memory\RedisServer
*/
public $redis;
/**
* @var boolean whether to enable profiling for the SQL statements being executed.
* Defaults to false. This should be mainly enabled and used during development
* to find out the bottleneck of SQL executions.
* @see getStats
*/
public $enableProfiling = false;
/**
* @var string the common prefix or suffix for table names. If a table name is given
* as `{{%TableName}}`, then the percentage character `%` will be replaced with this
* property value. For example, `{{%post}}` becomes `{{tbl_post}}` if this property is
* set as `"tbl_"`. Note that this property is only effective when [[enableAutoQuoting]]
* is true.
* @see enableAutoQuoting
*/
public $keyPrefix;
/**
* @var Transaction the currently active transaction
*/
private $_transaction;
/**
* Closes the connection when this component is being serialized.
* @return array
*/
public function __sleep()
{
$this->close();
return array_keys(get_object_vars($this));
}
/**
* Returns a value indicating whether the DB connection is established.
* @return boolean whether the DB connection is established
*/
public function getIsActive()
{
return $this->redis !== null;
}
/**
* Establishes a DB connection.
* It does nothing if a DB connection has already been established.
* @throws Exception if connection fails
*/
public function open()
{
if ($this->redis === null) {
if (empty($this->dsn)) {
throw new InvalidConfigException('Connection.dsn cannot be empty.');
}
// TODO parse DSN
$host = 'localhost';
$port = 6379;
try {
\Yii::trace('Opening DB connection: ' . $this->dsn, __CLASS__);
// TODO connection to redis seems to be very easy, consider writing own connect
$this->redis = new \Jamm\Memory\RedisServer($host, $port);
$this->initConnection();
}
catch (\PDOException $e) {
\Yii::error("Failed to open DB connection ({$this->dsn}): " . $e->getMessage(), __CLASS__);
$message = YII_DEBUG ? 'Failed to open DB connection: ' . $e->getMessage() : 'Failed to open DB connection.';
throw new Exception($message, (int)$e->getCode(), $e->errorInfo);
}
}
}
/**
* Closes the currently active DB connection.
* It does nothing if the connection is already closed.
*/
public function close()
{
if ($this->redis !== null) {
\Yii::trace('Closing DB connection: ' . $this->dsn, __CLASS__);
$this->redis = null;
$this->_transaction = null;
}
}
/**
* Initializes the DB connection.
* This method is invoked right after the DB connection is established.
* The default implementation turns on `PDO::ATTR_EMULATE_PREPARES`
* if [[emulatePrepare]] is true, and sets the database [[charset]] if it is not empty.
* It then triggers an [[EVENT_AFTER_OPEN]] event.
*/
protected function initConnection()
{
$this->trigger(self::EVENT_AFTER_OPEN);
}
/**
* Creates a command for execution.
* @param string $query the SQL statement to be executed
* @param array $params the parameters to be bound to the SQL statement
* @return Command the DB command
*/
public function createCommand($query = null, $params = array())
{
$this->open();
$command = new Command(array(
'db' => $this,
'query' => $query,
));
return $command->addValues($params);
}
/**
* Returns the currently active transaction.
* @return Transaction the currently active transaction. Null if no active transaction.
*/
public function getTransaction()
{
return $this->_transaction && $this->_transaction->isActive ? $this->_transaction : null;
}
/**
* Starts a transaction.
* @return Transaction the transaction initiated
*/
public function beginTransaction()
{
$this->open();
$this->_transaction = new Transaction(array(
'db' => $this,
));
$this->_transaction->begin();
return $this->_transaction;
}
/**
* Returns the schema information for the database opened by this connection.
* @return Schema the schema information for the database opened by this connection.
* @throws NotSupportedException if there is no support for the current driver type
*/
public function getSchema()
{
$driver = $this->getDriverName();
throw new NotSupportedException("Connection does not support reading schema information for '$driver' DBMS.");
}
/**
* Returns the query builder for the current DB connection.
* @return QueryBuilder the query builder for the current DB connection.
*/
public function getQueryBuilder()
{
return $this->getSchema()->getQueryBuilder();
}
/**
* Obtains the schema information for the named table.
* @param string $name table name.
* @param boolean $refresh whether to reload the table schema even if it is found in the cache.
* @return TableSchema table schema information. Null if the named table does not exist.
*/
public function getTableSchema($name, $refresh = false)
{
return $this->getSchema()->getTableSchema($name, $refresh);
}
/**
* Returns the name of the DB driver for the current [[dsn]].
* @return string name of the DB driver
*/
public function getDriverName()
{
if (($pos = strpos($this->dsn, ':')) !== false) {
return strtolower(substr($this->dsn, 0, $pos));
} else {
return 'redis';
}
}
/**
* Returns the statistical results of SQL queries.
* The results returned include the number of SQL statements executed and
* the total time spent.
* In order to use this method, [[enableProfiling]] has to be set true.
* @return array the first element indicates the number of SQL statements executed,
* and the second element the total time spent in SQL execution.
* @see \yii\logging\Logger::getProfiling()
*/
public function getQuerySummary()
{
$logger = \Yii::getLogger();
$timings = $logger->getProfiling(array('yii\db\Command::query', 'yii\db\Command::execute'));
$count = count($timings);
$time = 0;
foreach ($timings as $timing) {
$time += $timing[1];
}
return array($count, $time);
}
}