Save last-modified date (aka 'changed') in cache and allow to use it in queries (#847)
This commit is contained in:
parent
92b2bbead7
commit
464b4961cc
4 changed files with 33 additions and 14 deletions
|
@ -6,12 +6,15 @@
|
|||
* @licence GNU AGPL
|
||||
**/
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `kolab_cache` (
|
||||
DROP TABLE IF EXISTS `kolab_cache`;
|
||||
|
||||
CREATE TABLE `kolab_cache` (
|
||||
`resource` VARCHAR(255) CHARACTER SET ascii NOT NULL,
|
||||
`type` VARCHAR(32) CHARACTER SET ascii NOT NULL,
|
||||
`msguid` BIGINT UNSIGNED NOT NULL,
|
||||
`uid` VARCHAR(128) CHARACTER SET ascii NOT NULL,
|
||||
`created` DATETIME DEFAULT NULL,
|
||||
`changed` DATETIME DEFAULT NULL,
|
||||
`data` TEXT NOT NULL,
|
||||
`xml` TEXT NOT NULL,
|
||||
`dtstart` DATETIME,
|
||||
|
|
|
@ -40,6 +40,7 @@ abstract class kolab_format
|
|||
protected $loaded = false;
|
||||
|
||||
const VERSION = '3.0';
|
||||
const KTYPE_PREFIX = 'application/x-vnd.kolab.';
|
||||
|
||||
/**
|
||||
* Factory method to instantiate a kolab_format object of the given type
|
||||
|
@ -166,6 +167,17 @@ abstract class kolab_format
|
|||
return $vec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the X-Kolab-Type header from MIME messages and return the object type in short form
|
||||
*
|
||||
* @param string X-Kolab-Type header value
|
||||
* @return string Kolab object type (contact,event,task,note,etc.)
|
||||
*/
|
||||
public static function mime2object_type($x_kolab_type)
|
||||
{
|
||||
return preg_replace('/dictionary.[a-z.]+$/', 'dictionary', substr($x_kolab_type, strlen(self::KTYPE_PREFIX)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for format errors after calling kolabformat::write*()
|
||||
*
|
||||
|
|
|
@ -215,12 +215,13 @@ class kolab_storage_cache
|
|||
|
||||
$result = $this->db->query(
|
||||
"INSERT INTO kolab_cache ".
|
||||
" (resource, type, msguid, uid, created, data, xml, dtstart, dtend, tags, words)".
|
||||
" VALUES (?, ?, ?, ?, " . $this->db->now() . ", ?, ?, ?, ?, ?, ?)",
|
||||
" (resource, type, msguid, uid, created, changed, data, xml, dtstart, dtend, tags, words)".
|
||||
" VALUES (?, ?, ?, ?, " . $this->db->now() . ", ?, ?, ?, ?, ?, ?, ?)",
|
||||
$this->resource_uri,
|
||||
$objtype,
|
||||
$msguid,
|
||||
$object['uid'],
|
||||
$sql_data['changed'],
|
||||
$sql_data['data'],
|
||||
$sql_data['xml'],
|
||||
$sql_data['dtstart'],
|
||||
|
@ -331,7 +332,7 @@ class kolab_storage_cache
|
|||
$index = $this->index;
|
||||
}
|
||||
else { // search by object type
|
||||
$search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_storage_folder::KTYPE_PREFIX . $filter['type'];
|
||||
$search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_format::KTYPE_PREFIX . $filter['type'];
|
||||
$index = $this->imap->search_once($this->folder->name, $search)->get();
|
||||
}
|
||||
|
||||
|
@ -369,7 +370,7 @@ class kolab_storage_cache
|
|||
else {
|
||||
// search IMAP by object type
|
||||
$filter = $this->_query2assoc($query);
|
||||
$ctype = kolab_storage_folder::KTYPE_PREFIX . $filter['type'];
|
||||
$ctype = kolab_format::KTYPE_PREFIX . $filter['type'];
|
||||
$index = $this->imap->search_once($this->folder->name, 'UNDELETED HEADER X-Kolab-Type ' . $ctype);
|
||||
$count = $index->count();
|
||||
}
|
||||
|
@ -464,7 +465,7 @@ class kolab_storage_cache
|
|||
|
||||
$results = array();
|
||||
foreach ((array)$this->imap->fetch_headers($this->folder->name, $index, false) as $msguid => $headers) {
|
||||
$object_type = preg_replace('/dictionary.[a-z]+$/', 'dictionary', substr($headers->others['x-kolab-type'], strlen(kolab_storage_folder::KTYPE_PREFIX)));
|
||||
$object_type = kolab_format::mime2object_type($headers->others['x-kolab-type']);
|
||||
|
||||
// check object type header and abort on mismatch
|
||||
if ($type != '*' && $object_type != $type)
|
||||
|
@ -485,7 +486,7 @@ class kolab_storage_cache
|
|||
private function _serialize($object)
|
||||
{
|
||||
$bincols = array_flip($this->binary_cols);
|
||||
$sql_data = array('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;
|
||||
|
||||
// set type specific values
|
||||
|
@ -506,6 +507,10 @@ class kolab_storage_cache
|
|||
$sql_data['dtend'] = date('Y-m-d H:i:s', is_object($object['due']) ? $object['due']->format('U') : $object['due']);
|
||||
}
|
||||
|
||||
if ($object['changed']) {
|
||||
$sql_data['changed'] = date('Y-m-d H:i:s', is_object($object['changed']) ? $object['changed']->format('U') : $object['changed']);
|
||||
}
|
||||
|
||||
if ($object['_formatobj']) {
|
||||
$sql_data['xml'] = preg_replace('!(</?[a-z0-9:-]+>)[\n\r\t\s]+!ms', '$1', (string)$object['_formatobj']->write());
|
||||
$sql_data['tags'] = ' ' . join(' ', $object['_formatobj']->get_tags()) . ' '; // pad with spaces for strict/prefix search
|
||||
|
@ -581,6 +586,7 @@ class kolab_storage_cache
|
|||
$this->db->quote($msguid),
|
||||
$this->db->quote($object['uid']),
|
||||
$this->db->now(),
|
||||
$this->db->quote($sql_data['changed']),
|
||||
$this->db->quote($sql_data['data']),
|
||||
$this->db->quote($sql_data['xml']),
|
||||
$this->db->quote($sql_data['dtstart']),
|
||||
|
@ -594,7 +600,7 @@ class kolab_storage_cache
|
|||
if ($buffer && (!$msguid || (strlen($buffer) + strlen($line) > $this->max_sql_packet))) {
|
||||
$result = $this->db->query(
|
||||
"INSERT INTO kolab_cache ".
|
||||
" (resource, type, msguid, uid, created, data, xml, dtstart, dtend, tags, words)".
|
||||
" (resource, type, msguid, uid, created, changed, data, xml, dtstart, dtend, tags, words)".
|
||||
" VALUES $buffer"
|
||||
);
|
||||
if (!$this->db->affected_rows($result)) {
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
*/
|
||||
class kolab_storage_folder
|
||||
{
|
||||
const KTYPE_PREFIX = 'application/x-vnd.kolab.';
|
||||
|
||||
/**
|
||||
* The folder name.
|
||||
* @var string
|
||||
|
@ -358,7 +356,7 @@ class kolab_storage_folder
|
|||
if ($param[0] == 'type') {
|
||||
$type = $param[2];
|
||||
}
|
||||
else if (($param[0] == 'dtstart' || $param[0] == 'dtend') && is_numeric($param[2])) {
|
||||
else if (($param[0] == 'dtstart' || $param[0] == 'dtend' || $param[0] == 'changed') && is_numeric($param[2])) {
|
||||
$query[$i][2] = date('Y-m-d H:i:s', $param[2]);
|
||||
}
|
||||
}
|
||||
|
@ -428,8 +426,8 @@ class kolab_storage_folder
|
|||
$this->imap->set_folder($folder);
|
||||
|
||||
$headers = $this->imap->get_message_headers($msguid);
|
||||
$object_type = preg_replace('/dictionary.[a-z]+$/', 'dictionary', substr($headers->others['x-kolab-type'], strlen(self::KTYPE_PREFIX)));
|
||||
$content_type = self::KTYPE_PREFIX . $object_type;
|
||||
$object_type = kolab_format::mime2object_type($headers->others['x-kolab-type']);
|
||||
$content_type = kolab_format::KTYPE_PREFIX . $object_type;
|
||||
|
||||
// check object type header and abort on mismatch
|
||||
if ($type != '*' && $object_type != $type)
|
||||
|
@ -719,7 +717,7 @@ class kolab_storage_folder
|
|||
$headers['To'] = $ident['email'];
|
||||
}
|
||||
$headers['Date'] = date('r');
|
||||
$headers['X-Kolab-Type'] = self::KTYPE_PREFIX . $type;
|
||||
$headers['X-Kolab-Type'] = kolab_format::KTYPE_PREFIX . $type;
|
||||
$headers['X-Kolab-Mime-Version'] = kolab_format::VERSION;
|
||||
$headers['Subject'] = $object['uid'];
|
||||
// $headers['Message-ID'] = $rcmail->gen_message_id();
|
||||
|
|
Loading…
Add table
Reference in a new issue