De-duplicate binary content when saving in database (#1749)

This commit is contained in:
Aleksander Machniak 2013-06-17 15:44:17 +02:00
parent 8707292fd6
commit bc4d15ab55

View file

@ -37,7 +37,11 @@ class kolab_storage_cache
private $ready = false; private $ready = false;
private $max_sql_packet; private $max_sql_packet;
private $max_sync_lock_time = 600; private $max_sync_lock_time = 600;
private $binary_cols = array('photo','pgppublickey','pkcs7publickey'); private $binary_items = array(
'photo' => '|<photo><uri>[^;]+;base64,([^<]+)</uri></photo>|i',
'pgppublickey' => '|<key><uri>date:application/pgp-keys;base64,([^<]+)</uri></photo>|i',
'pkcs7publickey' => '|<key><uri>date:application/pkcs7-mime;base64,([^<]+)</uri></photo>|i',
);
/** /**
@ -524,7 +528,6 @@ class kolab_storage_cache
*/ */
private function _serialize($object) private function _serialize($object)
{ {
$bincols = array_flip($this->binary_cols);
$sql_data = array('changed' => null, 'dtstart' => null, 'dtend' => null, 'xml' => '', 'tags' => '', 'words' => ''); $sql_data = array('changed' => null, 'dtstart' => null, 'dtend' => null, 'xml' => '', 'tags' => '', 'words' => '');
$objtype = $object['_type'] ? $object['_type'] : $this->folder->type; $objtype = $object['_type'] ? $object['_type'] : $this->folder->type;
@ -566,12 +569,13 @@ class kolab_storage_cache
// extract object data // extract object data
$data = array(); $data = array();
foreach ($object as $key => $val) { foreach ($object as $key => $val) {
// skip empty properties
if ($val === "" || $val === null) { if ($val === "" || $val === null) {
// skip empty properties
continue; continue;
} }
if (isset($bincols[$key])) { // mark binary data to be extracted from xml on unserialize()
$data[$key] = base64_encode($val); if (isset($this->binary_items[$key])) {
$data[$key] = true;
} }
else if ($key[0] != '_') { else if ($key[0] != '_') {
$data[$key] = $val; $data[$key] = $val;
@ -597,9 +601,10 @@ class kolab_storage_cache
$object = unserialize($sql_arr['data']); $object = unserialize($sql_arr['data']);
// decode binary properties // decode binary properties
foreach ($this->binary_cols as $key) { foreach ($this->binary_items as $key => $regexp) {
if (!empty($object[$key])) if (!empty($object[$key]) && preg_match($regexp, $sql_arr['xml'], $m)) {
$object[$key] = base64_decode($object[$key]); $object[$key] = base64_decode($m[1]);
}
} }
// add meta data // add meta data
@ -708,17 +713,15 @@ class kolab_storage_cache
if (!$sql_arr) { if (!$sql_arr) {
$this->db->query( $this->db->query(
"INSERT INTO kolab_cache (resource, type, msguid, created, uid, data, xml)". "INSERT INTO kolab_cache (resource, type, msguid, created, uid, data, xml)".
" VALUES (?, ?, 1, ?, '', '', '')", " VALUES (?, ?, 1, " . $this->db->now() . ", '', '', '')",
$this->resource_uri, $this->resource_uri,
'lock', 'lock'
date('Y-m-d H:i:s')
); );
} }
else { else {
$this->db->query( $this->db->query(
"UPDATE kolab_cache SET msguid=1, created=? ". "UPDATE kolab_cache SET msguid = 1, created = " . $this->db->now() .
"WHERE resource=? AND type=?", " WHERE resource = ? AND type = ?",
date('Y-m-d H:i:s'),
$this->resource_uri, $this->resource_uri,
'lock' 'lock'
); );
@ -734,8 +737,7 @@ class kolab_storage_cache
return; return;
$this->db->query( $this->db->query(
"UPDATE kolab_cache SET msguid=0 ". "UPDATE kolab_cache SET msguid = 0 WHERE resource = ? AND type = ?",
"WHERE resource=? AND type=?",
$this->resource_uri, $this->resource_uri,
'lock' 'lock'
); );