| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Db\Adapter\Pdo; |
|
|
| use Exception; |
| use PDO; |
| use PDOException; |
| use Piwik\Config; |
| use Piwik\Db; |
| use Piwik\Db\AdapterInterface; |
| use Piwik\Db\Schema; |
| use Piwik\Piwik; |
| use Zend_Config; |
| use Zend_Db_Adapter_Pdo_Mysql; |
|
|
| class Mysql extends Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface |
| { |
| use Db\TransactionalDatabaseDynamicTrait; |
|
|
| |
| |
| |
| public function __construct($config) |
| { |
| |
| if (defined('PDO::MYSQL_ATTR_LOCAL_INFILE')) { |
| $config['driver_options'][PDO::MYSQL_ATTR_LOCAL_INFILE] = true; |
| } |
| if ($config['enable_ssl']) { |
| if (!empty($config['ssl_key'])) { |
| $config['driver_options'][PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key']; |
| } |
| if (!empty($config['ssl_cert'])) { |
| $config['driver_options'][PDO::MYSQL_ATTR_SSL_CERT] = $config['ssl_cert']; |
| } |
| if (!empty($config['ssl_ca'])) { |
| $config['driver_options'][PDO::MYSQL_ATTR_SSL_CA] = $config['ssl_ca']; |
| } |
| if (!empty($config['ssl_ca_path'])) { |
| $config['driver_options'][PDO::MYSQL_ATTR_SSL_CAPATH] = $config['ssl_ca_path']; |
| } |
| if (!empty($config['ssl_cipher'])) { |
| $config['driver_options'][PDO::MYSQL_ATTR_SSL_CIPHER] = $config['ssl_cipher']; |
| } |
| if ( |
| !empty($config['ssl_no_verify']) |
| && defined('PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT') |
| ) { |
| $config['driver_options'][PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = false; |
| } |
| } |
| parent::__construct($config); |
| } |
|
|
| |
| |
| |
| |
| |
| public function getConnection() |
| { |
| if ($this->_connection) { |
| return $this->_connection; |
| } |
|
|
| $this->_connect(); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| $this->_connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); |
|
|
| return $this->_connection; |
| } |
|
|
| protected function _connect() // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore |
| { |
| if ($this->_connection) { |
| return; |
| } |
|
|
| $sql = 'SET sql_mode = "' . Db::SQL_MODE . '"'; |
|
|
| try { |
| parent::_connect(); |
| $this->_connection->exec($sql); |
| } catch (Exception $e) { |
| if ($this->isErrNo($e, \Piwik\Updater\Migration\Db::ERROR_CODE_MYSQL_SERVER_HAS_GONE_AWAY)) { |
| |
| |
| $this->_connection = null; |
| usleep(400 * 1000); |
| parent::_connect(); |
| $this->_connection->exec($sql); |
| } else { |
| throw $e; |
| } |
| } |
| } |
|
|
| |
| |
| |
| public function resetConfig() |
| { |
| $this->_config = array(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public static function getDefaultPort() |
| { |
| return 3306; |
| } |
|
|
| |
| |
| |
| |
| |
| public function checkServerVersion() |
| { |
| $requiredVersion = Schema::getInstance()->getMinimumSupportedVersion(); |
| $serverVersion = $this->getServerVersion(); |
|
|
| if (version_compare($serverVersion, $requiredVersion) === -1) { |
| throw new Exception(Piwik::translate('General_ExceptionDatabaseVersion', array('MySQL', $serverVersion, $requiredVersion))); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| public function getServerVersion() |
| { |
| |
| |
| $versionInfo = $this->fetchAll('SELECT @@VERSION'); |
|
|
| if (count($versionInfo)) { |
| return $versionInfo[0]['@@VERSION']; |
| } |
|
|
| return parent::getServerVersion(); |
| } |
|
|
| |
| |
| |
| |
| |
| public function checkClientVersion() |
| { |
| $serverVersion = $this->getServerVersion(); |
| $clientVersion = $this->getClientVersion(); |
|
|
| |
| if ( |
| version_compare($serverVersion, '5.0.3') >= 0 |
| && version_compare($clientVersion, '5.0.3') < 0 |
| ) { |
| throw new Exception(Piwik::translate('General_ExceptionIncompatibleClientServerVersions', array('MySQL', $clientVersion, $serverVersion))); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| public static function isEnabled() |
| { |
| return extension_loaded('PDO') && extension_loaded('pdo_mysql') && in_array('mysql', PDO::getAvailableDrivers()); |
| } |
|
|
| |
| |
| |
| |
| |
| public function hasBlobDataType() |
| { |
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| public function hasBulkLoader() |
| { |
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function isErrNo($e, $errno) |
| { |
| return self::isPdoErrorNumber($e, $errno); |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| public static function isPdoErrorNumber($e, $errno) |
| { |
| if (preg_match('/(?:\[|\s)([0-9]{4})(?:\]|\s)/', $e->getMessage(), $match)) { |
| return $match[1] == $errno; |
| } |
|
|
| return false; |
| } |
|
|
| |
| |
| |
| |
| |
| public function isConnectionUTF8() |
| { |
| $charsetInfo = $this->fetchAll('SHOW VARIABLES LIKE ?', array('character_set_connection')); |
|
|
| if (empty($charsetInfo)) { |
| return false; |
| } |
|
|
| $charset = $charsetInfo[0]['Value']; |
| return strpos($charset, 'utf8') === 0; |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| public function rowCount($queryResult) |
| { |
| return $queryResult->rowCount(); |
| } |
|
|
| |
| |
| |
| |
| |
| public function getClientVersion() |
| { |
| $this->_connect(); |
| try { |
| $version = $this->_connection->getAttribute(PDO::ATTR_CLIENT_VERSION); |
| $matches = null; |
| if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) { |
| return $matches[1]; |
| } |
| } catch (PDOException $e) { |
| |
| } |
| return null; |
| } |
|
|
| |
| |
| |
| |
| |
| protected function _dsn() // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore |
| { |
| if (!empty($this->_config['unix_socket'])) { |
| unset($this->_config['host']); |
| unset($this->_config['port']); |
| } |
|
|
| return parent::_dsn(); |
| } |
| } |
|
|