feat: serve message lists from the cache

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-10-07 22:15:34 -04:00
parent 852ead324f
commit b1e92e5b07
9 changed files with 800 additions and 5 deletions
+28 -1
View File
@@ -34,7 +34,7 @@ class MessageStore
/** Fields dropped when a message becomes a tombstone */
private const TOMBSTONE_UNSET = [
'created' => '', 'received' => '', 'sent' => '', 'size' => '',
'subject' => '', 'from' => '', 'to' => '', 'cc' => '',
'subject' => '', 'from' => '', 'to' => '', 'cc' => '', 'bcc' => '',
'urid' => '', 'inReplyTo' => '', 'references' => '',
'flags' => '', 'hasAttachments' => '', 'preview' => '', 'blobs' => '',
];
@@ -179,6 +179,33 @@ class MessageStore
return $uids;
}
/**
* UIDs of the cached messages matching a filter, in sort order (tombstones excluded).
*
* @param array $filter meta store filter (see MessageQueryBuilder::filter())
* @param array<string, int> $sort meta store sort (see MessageQueryBuilder::sort())
* @param array|null $collation collation for text sorts
* @return int[]
*/
public function query(string $serviceId, string $mailbox, int $uidValidity, array $filter = [], array $sort = ['uid' => 1], ?array $collation = null): array
{
$match = ['sid' => $serviceId, 'mailbox' => $mailbox, 'uidValidity' => $uidValidity, ...self::LIVE];
if ($filter !== []) {
$match = ['$and' => [$match, $filter]];
}
$options = ['projection' => ['uid' => 1], 'sort' => $sort];
if ($collation !== null) {
$options['collation'] = $collation;
}
$uids = [];
foreach ($this->dataStore->selectCollection(self::COLLECTION_NAME)->find($match, $options) as $document) {
$uids[] = (int) $document['uid'];
}
return $uids;
}
/**
* List the flags of every message cached for a mailbox.
*