Cache relation members for better performance (#3452)
This commit is contained in:
parent
e3d29617ae
commit
0730852179
4 changed files with 123 additions and 76 deletions
|
@ -391,7 +391,7 @@ class kolab_notes extends rcube_plugin
|
||||||
$this->rc->output->set_env('kolab_notes_template', array(
|
$this->rc->output->set_env('kolab_notes_template', array(
|
||||||
'_from_mail' => true,
|
'_from_mail' => true,
|
||||||
'title' => $message->get('subject'),
|
'title' => $message->get('subject'),
|
||||||
'links' => array($this->get_message_reference($this->get_message_uri($message, $folder))),
|
'links' => array($this->get_message_reference(kolab_storage_config::get_message_uri($message, $folder))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,7 +996,6 @@ class kolab_notes extends rcube_plugin
|
||||||
foreach ($relations as $relation) {
|
foreach ($relations as $relation) {
|
||||||
if (empty($links)) {
|
if (empty($links)) {
|
||||||
$config->delete($relation['uid']);
|
$config->delete($relation['uid']);
|
||||||
$this->relations = null; // clear in-memory cache
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// make relation members up-to-date
|
// make relation members up-to-date
|
||||||
|
@ -1010,7 +1009,6 @@ class kolab_notes extends rcube_plugin
|
||||||
if (count($diff1) || count($diff2)) {
|
if (count($diff1) || count($diff2)) {
|
||||||
$relation['members'] = $members;
|
$relation['members'] = $members;
|
||||||
$config->save($relation, 'relation');
|
$config->save($relation, 'relation');
|
||||||
$this->relations = null; // clear in-memory cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$links = null;
|
$links = null;
|
||||||
|
@ -1025,7 +1023,6 @@ class kolab_notes extends rcube_plugin
|
||||||
);
|
);
|
||||||
|
|
||||||
$config->save($relation, 'relation');
|
$config->save($relation, 'relation');
|
||||||
$this->relations = null; // clear in-memory cache
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1070,33 +1067,11 @@ class kolab_notes extends rcube_plugin
|
||||||
*/
|
*/
|
||||||
private function get_message_notes($message, $folder)
|
private function get_message_notes($message, $folder)
|
||||||
{
|
{
|
||||||
$result = array();
|
$config = kolab_storage_config::get_instance();
|
||||||
$uids = array();
|
$result = $config->get_message_relations($message, $folder, 'note');
|
||||||
|
|
||||||
// TODO: only query for notes if message was flagged with $KolabNotes ?
|
foreach ($result as $idx => $note) {
|
||||||
|
$result[$idx]['list'] = kolab_storage::folder_id($note['_mailbox']);
|
||||||
// get UIDs of assigned notes
|
|
||||||
foreach ($this->get_relations() as $relation) {
|
|
||||||
// get Folder/UIDs of relation members
|
|
||||||
$messages = kolab_storage_config::resolve_members($relation);
|
|
||||||
|
|
||||||
if (!empty($messages[$folder]) && in_array($message->uid, $messages[$folder])) {
|
|
||||||
// find note UID(s)
|
|
||||||
foreach ($relation['members'] as $member) {
|
|
||||||
if (strpos($member, 'urn:uuid:') === 0) {
|
|
||||||
$uids[] = substr($member, 9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get Note objects
|
|
||||||
if (!empty($uids)) {
|
|
||||||
$query = array(array('uid', '=', $uids));
|
|
||||||
foreach (kolab_storage::select($query, 'note') as $record) {
|
|
||||||
$record['list'] = kolab_storage::folder_id($record['_mailbox']);
|
|
||||||
$result[] = $record;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -1105,55 +1080,17 @@ class kolab_notes extends rcube_plugin
|
||||||
/**
|
/**
|
||||||
* Find relation objects referring to specified note
|
* Find relation objects referring to specified note
|
||||||
*/
|
*/
|
||||||
private function get_relations($uid = null)
|
private function get_relations($uid)
|
||||||
{
|
{
|
||||||
if (!isset($this->relations)) {
|
$config = kolab_storage_config::get_instance();
|
||||||
$config = kolab_storage_config::get_instance();
|
$default = true;
|
||||||
$default = true;
|
$filter = array(
|
||||||
$filter = array(
|
array('type', '=', 'relation'),
|
||||||
array('type', '=', 'relation'),
|
array('category', '=', 'generic'),
|
||||||
array('category', '=', 'generic')
|
array('member', '=', $uid),
|
||||||
);
|
|
||||||
|
|
||||||
$this->relations = $config->get_objects($filter, $default);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($uid === null) {
|
|
||||||
return $this->relations;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = array();
|
|
||||||
$search = kolab_storage_config::build_member_url($uid);
|
|
||||||
|
|
||||||
foreach ($this->relations as $relation) {
|
|
||||||
if (in_array($search, (array) $relation['members'])) {
|
|
||||||
$result[] = $relation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a URI representing the given message reference
|
|
||||||
*/
|
|
||||||
private function get_message_uri($headers, $folder)
|
|
||||||
{
|
|
||||||
$params = array(
|
|
||||||
'folder' => $headers->folder ?: $folder,
|
|
||||||
'uid' => $headers->uid,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (($messageid = $headers->get('message-id', false)) && ($date = $headers->get('date', false))) {
|
return $config->get_objects($filter, $default, 100);
|
||||||
$params['message-id'] = $messageid;
|
|
||||||
$params['date'] = $date;
|
|
||||||
|
|
||||||
if ($subject = $headers->get('subject')) {
|
|
||||||
$params['subject'] = $subject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return kolab_storage_config::build_member_url($params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -220,4 +220,29 @@ class kolab_format_configuration extends kolab_format
|
||||||
|
|
||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for kolab_storage_cache to get words to index for fulltext search
|
||||||
|
*
|
||||||
|
* @return array List of words to save in cache
|
||||||
|
*/
|
||||||
|
public function get_words()
|
||||||
|
{
|
||||||
|
$words = array();
|
||||||
|
|
||||||
|
foreach ((array)$this->data['members'] as $url) {
|
||||||
|
$member = kolab_storage_config::parse_member_url($url);
|
||||||
|
|
||||||
|
if (empty($member)) {
|
||||||
|
if (strpos($url, 'urn:uuid:') === 0) {
|
||||||
|
$words[] = substr($url, 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!empty($member['params']['message-id'])) {
|
||||||
|
$words[] = $member['params']['message-id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $words;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,12 @@ class kolab_storage_cache_configuration extends kolab_storage_cache
|
||||||
$query[$idx][0] = 'tags';
|
$query[$idx][0] = 'tags';
|
||||||
$query[$idx][2] = count($param[2]) > 1 ? $param[2] : $param[2][0];
|
$query[$idx][2] = count($param[2]) > 1 ? $param[2] : $param[2][0];
|
||||||
}
|
}
|
||||||
|
// convert member filter (we support only = operator with single value)
|
||||||
|
else if ($param[0] == 'member') {
|
||||||
|
$query[$idx][0] = 'words';
|
||||||
|
$query[$idx][1] = '~';
|
||||||
|
$query[$idx][2] = '^' . $param[2] . '$';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -623,6 +623,12 @@ class kolab_storage_config
|
||||||
array('category', '=', 'tag')
|
array('category', '=', 'tag')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// use faster method
|
||||||
|
if ($uid && $uid != '*') {
|
||||||
|
$filter[] = array('member', '=', $uid);
|
||||||
|
return $this->get_objects($filter, $default);
|
||||||
|
}
|
||||||
|
|
||||||
$this->tags = $this->get_objects($filter, $default);
|
$this->tags = $this->get_objects($filter, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,4 +647,77 @@ class kolab_storage_config
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find kolab objects assigned to specified e-mail message
|
||||||
|
*
|
||||||
|
* @param rcube_message $message E-mail message
|
||||||
|
* @param string $folder Folder name
|
||||||
|
* @param string $type Result objects type
|
||||||
|
*
|
||||||
|
* @return array List of kolab objects
|
||||||
|
*/
|
||||||
|
public function get_message_relations($message, $folder, $type)
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
$uids = array();
|
||||||
|
$default = true;
|
||||||
|
$uri = self::get_message_uri($message, $folder);
|
||||||
|
$filter = array(
|
||||||
|
array('type', '=', 'relation'),
|
||||||
|
array('category', '=', 'generic'),
|
||||||
|
// @TODO: what if Message-Id (and Date) does not exist?
|
||||||
|
array('member', '=', $message->get('message-id', false)),
|
||||||
|
);
|
||||||
|
|
||||||
|
// get UIDs of assigned notes
|
||||||
|
foreach ($this->get_objects($filter, $default) as $relation) {
|
||||||
|
// we don't need to update members if the URI is found
|
||||||
|
if (in_array($uri, $relation['members'])) {
|
||||||
|
// update members...
|
||||||
|
$messages = kolab_storage_config::resolve_members($relation);
|
||||||
|
// ...and check again
|
||||||
|
if (empty($messages[$folder]) || !in_array($message->uid, $messages[$folder])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find note UID(s)
|
||||||
|
foreach ($relation['members'] as $member) {
|
||||||
|
if (strpos($member, 'urn:uuid:') === 0) {
|
||||||
|
$uids[] = substr($member, 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get kolab objects of specified type
|
||||||
|
if (!empty($uids)) {
|
||||||
|
$query = array(array('uid', '=', array_unique($uids)));
|
||||||
|
$result = kolab_storage::select($query, $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a URI representing the given message reference
|
||||||
|
*/
|
||||||
|
public static function get_message_uri($headers, $folder)
|
||||||
|
{
|
||||||
|
$params = array(
|
||||||
|
'folder' => $headers->folder ?: $folder,
|
||||||
|
'uid' => $headers->uid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (($messageid = $headers->get('message-id', false)) && ($date = $headers->get('date', false))) {
|
||||||
|
$params['message-id'] = $messageid;
|
||||||
|
$params['date'] = $date;
|
||||||
|
|
||||||
|
if ($subject = $headers->get('subject')) {
|
||||||
|
$params['subject'] = $subject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::build_member_url($params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue