Fix "duplicate entry" errors on inserts to imap cache tables (#1489146)

pull/79/head
Aleksander Machniak 11 years ago
parent 4fee776e51
commit be4b5c2fe5

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Fix "duplicate entry" errors on inserts to imap cache tables (#1489146)
- Fix so bounces addresses in Sender headers are skipped on Reply-All (#1489011)
- Fix bug where serialized strings were truncated in PDO::quote() (#1489142)
- Improved handling of Reply-To/Bcc addresses of identity in compose form (#1489016)

@ -415,13 +415,16 @@ class rcube_db
if ($result === false) {
$error = $this->dbh->errorInfo();
$this->db_error = true;
$this->db_error_msg = sprintf('[%s] %s', $error[1], $error[2]);
rcube::raise_error(array('code' => 500, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => $this->db_error_msg . " (SQL Query: $query)"
), true, false);
if (empty($this->options['ignore_key_errors']) || $error[0] != '23000') {
$this->db_error = true;
$this->db_error_msg = sprintf('[%s] %s', $error[1], $error[2]);
rcube::raise_error(array('code' => 500, 'type' => 'db',
'line' => __LINE__, 'file' => __FILE__,
'message' => $this->db_error_msg . " (SQL Query: $query)"
), true, false);
}
}
$this->last_result = $result;
@ -881,6 +884,17 @@ class rcube_db
return $table;
}
/**
* Set class option value
*
* @param string $name Option name
* @param mixed $value Option value
*/
public function set_option($name, $value)
{
$this->options[$name] = $value;
}
/**
* MDB2 DSN string parser
*

@ -437,12 +437,28 @@ class rcube_imap_cache
}
}
$this->db->set_option('ignore_key_errors', true);
// insert new record
$this->db->query(
$res = $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_messages')
." (user_id, mailbox, uid, flags, changed, data)"
." VALUES (?, ?, ?, ?, ".$this->db->now().", ?)",
$this->userid, $mailbox, (int) $message->uid, $flags, $msg);
// race-condition, insert failed so try update (#1489146)
// thanks to ignore_key_errors "duplicate row" errors will be ignored
if ($force && !$res && !$this->db->is_error($res)) {
$this->db->query(
"UPDATE ".$this->db->table_name('cache_messages')
." SET flags = ?, data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?"
." AND uid = ?",
$flags, $msg, $this->userid, $mailbox, (int) $message->uid);
}
$this->db->set_option('ignore_key_errors', false);
}
@ -714,20 +730,38 @@ class rcube_imap_cache
$data = implode('@', $data);
if ($exists) {
$sql_result = $this->db->query(
$res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_index')
." SET data = ?, valid = 1, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
if ($this->db->affected_rows($res)) {
return;
}
}
else {
$sql_result = $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_index')
." (user_id, mailbox, data, valid, changed)"
." VALUES (?, ?, ?, 1, ".$this->db->now().")",
$this->userid, $mailbox, $data);
$this->db->set_option('ignore_key_errors', true);
$res = $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_index')
." (user_id, mailbox, data, valid, changed)"
." VALUES (?, ?, ?, 1, ".$this->db->now().")",
$this->userid, $mailbox, $data);
// race-condition, insert failed so try update (#1489146)
// thanks to ignore_key_errors "duplicate row" errors will be ignored
if (!$exists && !$res && !$this->db->is_error($res)) {
$res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_index')
." SET data = ?, valid = 1, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
}
$this->db->set_option('ignore_key_errors', false);
}
@ -745,20 +779,38 @@ class rcube_imap_cache
$data = implode('@', $data);
if ($exists) {
$sql_result = $this->db->query(
$res = $this->db->query(
"UPDATE ".$this->db->table_name('cache_thread')
." SET data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
if ($this->db->affected_rows($res)) {
return;
}
}
else {
$sql_result = $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_thread')
." (user_id, mailbox, data, changed)"
." VALUES (?, ?, ?, ".$this->db->now().")",
$this->userid, $mailbox, $data);
$this->db->set_option('ignore_key_errors', true);
$res = $this->db->query(
"INSERT INTO ".$this->db->table_name('cache_thread')
." (user_id, mailbox, data, changed)"
." VALUES (?, ?, ?, ".$this->db->now().")",
$this->userid, $mailbox, $data);
// race-condition, insert failed so try update (#1489146)
// thanks to ignore_key_errors "duplicate row" errors will be ignored
if (!$exists && !$res && !$this->db->is_error($res)) {
$this->db->query(
"UPDATE ".$this->db->table_name('cache_thread')
." SET data = ?, changed = ".$this->db->now()
." WHERE user_id = ?"
." AND mailbox = ?",
$data, $this->userid, $mailbox);
}
$this->db->set_option('ignore_key_errors', false);
}

Loading…
Cancel
Save