Fix big memory consumption of DB layer (#1488856)

pull/51/head
Aleksander Machniak 12 years ago
parent 996af3bfd9
commit a3985963f0

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Fix big memory consumption of DB layer (#1488856)
- Add workaround for IE<=8 bug where Content-Disposition:inline was ignored (#1488844)
- Fix XSS vulnerability in vbscript: and data:text links handling (#1488850)
- Fix broken message/part bodies when FETCH response contains more untagged lines (#1488836)

@ -37,12 +37,11 @@ class rcube_db
protected $db_mode; // Connection mode
protected $dbh; // Connection handle
protected $db_error = false;
protected $db_error_msg = '';
protected $conn_failure = false;
protected $a_query_results = array('dummy');
protected $last_res_id = 0;
protected $db_index = 0;
protected $db_error = false;
protected $db_error_msg = '';
protected $conn_failure = false;
protected $db_index = 0;
protected $last_result;
protected $tables;
protected $variables;
@ -267,14 +266,14 @@ class rcube_db
/**
* Getter for error state
*
* @param int $res_id Optional query result identifier
* @param mixed $result Optional query result
*
* @return string Error message
*/
public function is_error($res_id = null)
public function is_error($result = null)
{
if ($res_id !== null) {
return $this->_get_result($res_id) === false ? $this->db_error_msg : null;
if ($result !== null) {
return $result === false ? $this->db_error_msg : null;
}
return $this->db_error ? $this->db_error_msg : null;
@ -343,7 +342,7 @@ class rcube_db
* @param int Number of rows for LIMIT statement
* @param mixed Values to be inserted in query
*
* @return int Query handle identifier
* @return PDOStatement|bool Query handle or False on error
*/
public function limitquery()
{
@ -363,7 +362,7 @@ class rcube_db
* @param int $numrows Number of rows for LIMIT statement
* @param array $params Values to be inserted in query
*
* @return int Query handle identifier
* @return PDOStatement|bool Query handle or False on error
*/
protected function _query($query, $offset, $numrows, $params)
{
@ -374,7 +373,7 @@ class rcube_db
// check connection before proceeding
if (!$this->is_connected()) {
return null;
return $this->last_result = false;
}
if ($numrows || $offset) {
@ -417,20 +416,21 @@ class rcube_db
'message' => $this->db_error_msg), true, false);
}
// add result, even if it's an error
return $this->_add_result($query);
$this->last_result = $query;
return $query;
}
/**
* Get number of affected rows for the last query
*
* @param number $res_id Optional query handle identifier
* @param mixed $result Optional query handle
*
* @return int Number of rows or false on failure
*/
public function affected_rows($res_id = null)
public function affected_rows($result = null)
{
if ($result = $this->_get_result($res_id)) {
if ($result || ($result === null && ($result = $this->last_result))) {
return $result->rowCount();
}
@ -464,13 +464,12 @@ class rcube_db
* Get an associative array for one row
* If no query handle is specified, the last query will be taken as reference
*
* @param int $res_id Optional query handle identifier
* @param mixed $result Optional query handle
*
* @return mixed Array with col values or false on failure
*/
public function fetch_assoc($res_id = null)
public function fetch_assoc($result = null)
{
$result = $this->_get_result($res_id);
return $this->_fetch_row($result, PDO::FETCH_ASSOC);
}
@ -478,31 +477,30 @@ class rcube_db
* Get an index array for one row
* If no query handle is specified, the last query will be taken as reference
*
* @param int $res_id Optional query handle identifier
* @param mixed $result Optional query handle
*
* @return mixed Array with col values or false on failure
*/
public function fetch_array($res_id = null)
public function fetch_array($result = null)
{
$result = $this->_get_result($res_id);
return $this->_fetch_row($result, PDO::FETCH_NUM);
}
/**
* Get col values for a result row
*
* @param PDOStatement $result Result handle
* @param int $mode Fetch mode identifier
* @param mixed $result Optional query handle
* @param int $mode Fetch mode identifier
*
* @return mixed Array with col values or false on failure
*/
protected function _fetch_row($result, $mode)
{
if (!is_object($result) || !$this->is_connected()) {
return false;
if ($result || ($result === null && ($result = $this->last_result))) {
return $result->fetch($mode);
}
return $result->fetch($mode);
return false;
}
/**
@ -538,8 +536,8 @@ class rcube_db
if ($this->tables === null) {
$q = $this->query('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_NAME');
if ($res = $this->_get_result($q)) {
$this->tables = $res->fetchAll(PDO::FETCH_COLUMN, 0);
if ($q) {
$this->tables = $q->fetchAll(PDO::FETCH_COLUMN, 0);
}
else {
$this->tables = array();
@ -561,8 +559,8 @@ class rcube_db
$q = $this->query('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ?',
array($table));
if ($res = $this->_get_result($q)) {
return $res->fetchAll(PDO::FETCH_COLUMN, 0);
if ($q) {
return $q->fetchAll(PDO::FETCH_COLUMN, 0);
}
return array();
@ -776,42 +774,6 @@ class rcube_db
return utf8_decode($input);
}
/**
* Adds a query result and returns a handle ID
*
* @param object $res Query handle
*
* @return int Handle ID
*/
protected function _add_result($res)
{
$this->last_res_id = sizeof($this->a_query_results);
$this->a_query_results[$this->last_res_id] = $res;
return $this->last_res_id;
}
/**
* Resolves a given handle ID and returns the according query handle
* If no ID is specified, the last resource handle will be returned
*
* @param int $res_id Handle ID
*
* @return mixed Resource handle or false on failure
*/
protected function _get_result($res_id = null)
{
if ($res_id == null) {
$res_id = $this->last_res_id;
}
if (!empty($this->a_query_results[$res_id])) {
return $this->a_query_results[$res_id];
}
return false;
}
/**
* Return correct name for a specific database table
*

Loading…
Cancel
Save