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->_socket !== 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->_socket === 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__); $this->_socket = stream_socket_client($host . ':' . $port); // TODO auth // TODO select database $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->_socket !== null) { \Yii::trace('Closing DB connection: ' . $this->dsn, __CLASS__); // TODO send CLOSE to the server stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR); $this->_socket = 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); } /** * 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 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'; } } public function __call($name, $params) { if (in_array($name, $this->redisCommands)) { array_unshift($params, $name); $cmd = '*' . count($params) . "\r\n"; foreach($params as $arg) { $cmd .= '$' . strlen( $item ) . "\r\n" . $item . "\r\n"; } fwrite( $this->_socket, $cmd ); return $this->_parseResponse(); } else { return parent::__call($name, $params); } } /** * 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() {// TODO implement $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); } }