Use INSERT ... ON DUPLICATE KEY UPDATE in kolab cache

Bifrost#T61987
This commit is contained in:
Aleksander Machniak 2018-12-28 14:13:25 +00:00
parent 47f7793ac0
commit e848de3129

View file

@ -938,36 +938,38 @@ class kolab_storage_cache
static $buffer = ''; static $buffer = '';
$line = ''; $line = '';
$cols = array('folder_id', 'msguid', 'uid', 'created', 'changed', 'data', 'tags', 'words');
if ($this->extra_cols) {
$cols = array_merge($cols, $this->extra_cols);
}
if ($object) { if ($object) {
$sql_data = $this->_serialize($object); $sql_data = $this->_serialize($object);
// Skip multifolder insert for Oracle, we can't put long data inline // Skip multi-folder insert for all databases but MySQL
if ($this->db->db_provider == 'oracle') { // In Oracle we can't put long data inline, others we don't support yet
$extra_cols = ''; if (strpos($this->db->db_provider, 'mysql') !== 0) {
if ($this->extra_cols) { $extra_args = array();
$extra_cols = array_map(function($n) { return "`{$n}`"; }, $this->extra_cols);
$extra_cols = ', ' . join(', ', $extra_cols);
$extra_args = str_repeat(', ?', count($this->extra_cols));
}
$params = array($this->folder_id, $msguid, $object['uid'], $sql_data['changed'], $params = array($this->folder_id, $msguid, $object['uid'], $sql_data['changed'],
$sql_data['data'], $sql_data['tags'], $sql_data['words']); $sql_data['data'], $sql_data['tags'], $sql_data['words']);
foreach ($this->extra_cols as $col) { foreach ($this->extra_cols as $col) {
$params[] = $sql_data[$col]; $params[] = $sql_data[$col];
$extra_args[] = '?';
} }
$cols = implode(', ', array_map(function($n) { return "`{$n}`"; }, $cols));
$extra_args = count($extra_args) ? ', ' . implode(', ', $extra_args) : '';
$result = $this->db->query( $result = $this->db->query(
"INSERT INTO `{$this->cache_table}` " "INSERT INTO `{$this->cache_table}` ($cols)"
. " (`folder_id`, `msguid`, `uid`, `created`, `changed`, `data`, `tags`, `words`$extra_cols)" . " VALUES (?, ?, ?, " . $this->db->now() . ", ?, ?, ?, ?$extra_args)",
. " VALUES (?, ?, ?, " . $this->db->now() . ", ?, ?, ?, ? $extra_args)",
$params $params
); );
if (!$this->db->affected_rows($result)) { if (!$this->db->affected_rows($result)) {
rcube::raise_error(array( rcube::raise_error(array(
'code' => 900, 'type' => 'php', 'code' => 900, 'message' => "Failed to write to kolab cache"
'message' => "Failed to write to kolab cache"
), true); ), true);
} }
@ -991,22 +993,17 @@ class kolab_storage_cache
} }
if ($buffer && (!$msguid || (strlen($buffer) + strlen($line) > $this->max_sql_packet()))) { if ($buffer && (!$msguid || (strlen($buffer) + strlen($line) > $this->max_sql_packet()))) {
$extra_cols = ''; $columns = implode(', ', array_map(function($n) { return "`{$n}`"; }, $cols));
if ($this->extra_cols) { $update = implode(', ', array_map(function($i) { return "`{$i}` = VALUES(`{$i}`)"; }, array_slice($cols, 2)));
$extra_cols = array_map(function($n) { return "`{$n}`"; }, $this->extra_cols);
$extra_cols = ', ' . join(', ', $extra_cols);
}
$result = $this->db->query( $result = $this->db->query(
"INSERT INTO `{$this->cache_table}` ". "INSERT INTO `{$this->cache_table}` ($columns) VALUES $buffer"
" (`folder_id`, `msguid`, `uid`, `created`, `changed`, `data`, `tags`, `words`$extra_cols)". . " ON DUPLICATE KEY UPDATE $update"
" VALUES $buffer"
); );
if (!$this->db->affected_rows($result)) { if (!$this->db->affected_rows($result)) {
rcube::raise_error(array( rcube::raise_error(array(
'code' => 900, 'type' => 'php', 'code' => 900, 'message' => "Failed to write to kolab cache"
'message' => "Failed to write to kolab cache"
), true); ), true);
} }