From 0344b168276f80189e2254c75a762aff5b517b6b Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Sun, 22 May 2016 06:32:57 -0400 Subject: [PATCH] Fix priority icon(s) position --- program/lib/Roundcube/rcube_db_mysql.php | 108 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 96 insertions(+), 12 deletions(-) diff --git a/program/lib/Roundcube/rcube_db_mysql.php b/program/lib/Roundcube/rcube_db_mysql.php index c32cc25..ee2194f 100644 --- a/program/lib/Roundcube/rcube_db_mysql.php +++ b/program/lib/Roundcube/rcube_db_mysql.php @@ -30,13 +30,30 @@ public $db_provider = 'mysql'; /** - * Driver initialization/configuration + * Object constructor + * + * @param string $db_dsnw DSN for read/write operations + * @param string $db_dsnr Optional DSN for read only operations + * @param bool $pconn Enables persistent connections */ - protected function init() + public function __construct($db_dsnw, $db_dsnr = '', $pconn = false) { + parent::__construct($db_dsnw, $db_dsnr, $pconn); + // SQL identifiers quoting $this->options['identifier_start'] = '`'; $this->options['identifier_end'] = '`'; + } + + /** + * Driver-specific configuration of database connection + * + * @param array $dsn DSN for DB connections + * @param PDO $dbh Connection handler + */ + protected function conn_configure($dsn, $dbh) + { + $dbh->query("SET NAMES 'utf8'"); } /** @@ -101,14 +118,14 @@ */ protected function dsn_options($dsn) { - $result = array(); + $result = parent::dsn_options($dsn); if (!empty($dsn['key'])) { - $result[PDO::MYSQL_ATTR_KEY] = $dsn['key']; + $result[PDO::MYSQL_ATTR_SSL_KEY] = $dsn['key']; } if (!empty($dsn['cipher'])) { - $result[PDO::MYSQL_ATTR_CIPHER] = $dsn['cipher']; + $result[PDO::MYSQL_ATTR_SSL_CIPHER] = $dsn['cipher']; } if (!empty($dsn['cert'])) { @@ -126,7 +143,34 @@ // Always return matching (not affected only) rows count $result[PDO::MYSQL_ATTR_FOUND_ROWS] = true; + // Enable AUTOCOMMIT mode (#1488902) + $result[PDO::ATTR_AUTOCOMMIT] = true; + return $result; + } + + /** + * Returns list of tables in a database + * + * @return array List of all tables of the current database + */ + public function list_tables() + { + // get tables if not cached + if ($this->tables === null) { + // first fetch current database name + $d = $this->query("SELECT database()"); + $d = $this->fetch_array($d); + + // get list of tables in current database + $q = $this->query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES" + . " WHERE TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE'" + . " ORDER BY TABLE_NAME", $d ? $d[0] : ''); + + $this->tables = $q ? $q->fetchAll(PDO::FETCH_COLUMN, 0) : array(); + } + + return $this->tables; } /** @@ -141,15 +185,55 @@ { if (!isset($this->variables)) { $this->variables = array(); - - $result = $this->query('SHOW VARIABLES'); - - while ($sql_arr = $this->fetch_array($result)) { - $this->variables[$row[0]] = $row[1]; - } } - return isset($this->variables[$varname]) ? $this->variables[$varname] : $default; + if (array_key_exists($varname, $this->variables)) { + return $this->variables[$varname]; + } + + // configured value has higher prio + $conf_value = rcube::get_instance()->config->get('db_' . $varname); + if ($conf_value !== null) { + return $this->variables[$varname] = $conf_value; + } + + $result = $this->query('SHOW VARIABLES LIKE ?', $varname); + + while ($row = $this->fetch_array($result)) { + $this->variables[$row[0]] = $row[1]; + } + + // not found, use default + if (!isset($this->variables[$varname])) { + $this->variables[$varname] = $default; + } + + return $this->variables[$varname]; + } + + /** + * Handle DB errors, re-issue the query on deadlock errors from InnoDB row-level locking + * + * @param string Query that triggered the error + * @return mixed Result to be stored and returned + */ + protected function handle_error($query) + { + $error = $this->dbh->errorInfo(); + + // retry after "Deadlock found when trying to get lock" errors + $retries = 2; + while ($error[1] == 1213 && $retries >= 0) { + usleep(50000); // wait 50 ms + $result = $this->dbh->query($query); + if ($result !== false) { + return $result; + } + $error = $this->dbh->errorInfo(); + $retries--; + } + + return parent::handle_error($query); } } -- Gitblit v1.9.1