-
Notifications
You must be signed in to change notification settings - Fork 286
feat: store envelopes as list of threads #11529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -756,10 +756,11 @@ | |
/** | ||
* @param Account $account | ||
* @param string $threadRootId | ||
* @param string $sortOrder | ||
* | ||
* @return Message[] | ||
*/ | ||
public function findThread(Account $account, string $threadRootId): array { | ||
public function findThread(Account $account, string $threadRootId, string $sortOrder): array { | ||
$qb = $this->db->getQueryBuilder(); | ||
$qb->select('messages.*') | ||
->from($this->getTableName(), 'messages') | ||
|
@@ -768,7 +769,7 @@ | |
$qb->expr()->eq('mailboxes.account_id', $qb->createNamedParameter($account->getId(), IQueryBuilder::PARAM_INT)), | ||
$qb->expr()->eq('messages.thread_root_id', $qb->createNamedParameter($threadRootId, IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR) | ||
) | ||
->orderBy('messages.sent_at', 'desc'); | ||
->orderBy('messages.sent_at', $sortOrder); | ||
|
||
return $this->findRelatedData($this->findEntities($qb), $account->getUserId()); | ||
} | ||
|
@@ -1273,10 +1274,11 @@ | |
* @param Mailbox $mailbox | ||
* @param string $userId | ||
* @param int[] $ids | ||
* @param string $sortOrder | ||
* | ||
* @return Message[] | ||
*/ | ||
public function findByMailboxAndIds(Mailbox $mailbox, string $userId, array $ids): array { | ||
public function findByMailboxAndIds(Mailbox $mailbox, string $userId, array $ids, string $sortOrder): array { | ||
if ($ids === []) { | ||
return []; | ||
} | ||
|
@@ -1288,7 +1290,7 @@ | |
$qb->expr()->eq('mailbox_id', $qb->createNamedParameter($mailbox->getId()), IQueryBuilder::PARAM_INT), | ||
$qb->expr()->in('id', $qb->createParameter('ids')) | ||
) | ||
->orderBy('sent_at', 'desc'); | ||
->orderBy('sent_at', $sortOrder); | ||
|
||
$results = []; | ||
foreach (array_chunk($ids, 1000) as $chunk) { | ||
|
@@ -1298,6 +1300,50 @@ | |
return array_merge([], ...$results); | ||
} | ||
|
||
/** | ||
* @param Account $account | ||
* @param Mailbox $mailbox | ||
* @param string $userId | ||
* @param int[] $ids | ||
* @param string $sortOrder | ||
* @param bool $threadingEnabled | ||
* | ||
* @return Message[][] | ||
Check failure on line 1311 in lib/Db/MessageMapper.php
|
||
*/ | ||
public function findMessageListsByMailboxAndIds(Account $account, Mailbox $mailbox, string $userId, array $ids, string $sortOrder, bool $threadingEnabled = false): array { | ||
if ($ids === []) { | ||
return []; | ||
} | ||
|
||
$qb = $this->db->getQueryBuilder(); | ||
$qb->select('*') | ||
->from($this->getTableName()) | ||
->where( | ||
$qb->expr()->eq('mailbox_id', $qb->createNamedParameter($mailbox->getId()), IQueryBuilder::PARAM_INT), | ||
$qb->expr()->in('id', $qb->createParameter('ids')) | ||
) | ||
->orderBy('sent_at', $sortOrder); | ||
$results = []; | ||
foreach (array_chunk($ids, 1000) as $chunk) { | ||
$qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); | ||
if ($threadingEnabled) { | ||
$res = $qb->executeQuery(); | ||
while ($row = $res->fetch()) { | ||
$message = $this->mapRowToEntity($row); | ||
if ($message->getThreadRootId() === null) { | ||
$results[] = [$message]; | ||
} else { | ||
$results[] = $this->findThread($account, $message->getThreadRootId(), $sortOrder); | ||
Check failure on line 1336 in lib/Db/MessageMapper.php
|
||
} | ||
} | ||
$res->closeCursor(); | ||
} else { | ||
$results[] = array_map(fn (Message $msg) => [$msg], $this->findRelatedData($this->findEntities($qb), $userId)); | ||
} | ||
} | ||
return $threadingEnabled ? $results : array_merge([], ...$results); | ||
Check failure on line 1344 in lib/Db/MessageMapper.php
|
||
} | ||
|
||
/** | ||
* @param string $userId | ||
* @param int[] $ids | ||
|
@@ -1325,6 +1371,48 @@ | |
return array_merge([], ...$results); | ||
} | ||
|
||
|
||
/** | ||
* @param Account $account | ||
* @param string $userId | ||
* @param int[] $ids | ||
* @param string $sortOrder | ||
* | ||
* @return Message[][] | ||
Check failure on line 1381 in lib/Db/MessageMapper.php
|
||
*/ | ||
public function findMessageListsByIds(Account $account, string $userId, array $ids, string $sortOrder, bool $threadingEnabled = false): array { | ||
if ($ids === []) { | ||
return []; | ||
} | ||
$qb = $this->db->getQueryBuilder(); | ||
$qb->select('*') | ||
->from($this->getTableName()) | ||
->where( | ||
$qb->expr()->in('id', $qb->createParameter('ids')) | ||
) | ||
->orderBy('sent_at', $sortOrder); | ||
|
||
$results = []; | ||
foreach (array_chunk($ids, 1000) as $chunk) { | ||
$qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY); | ||
if ($threadingEnabled) { | ||
$res = $qb->executeQuery(); | ||
while ($row = $res->fetch()) { | ||
$message = $this->mapRowToEntity($row); | ||
if ($message->getThreadRootId() === null) { | ||
$results[] = [$message]; | ||
} else { | ||
$results[] = $this->findThread($account, $message->getThreadRootId(), $sortOrder); | ||
Check failure on line 1405 in lib/Db/MessageMapper.php
|
||
|
||
} | ||
} | ||
$res->closeCursor(); | ||
} else { | ||
$results[] = array_map(fn (Message $msg) => [$msg], $this->findRelatedData($this->findEntities($qb), $userId)); | ||
} | ||
} | ||
return $threadingEnabled ? $results : array_merge([], ...$results); | ||
Check failure on line 1413 in lib/Db/MessageMapper.php
|
||
} | ||
|
||
/** | ||
* @param Message[] $messages | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the n+1 can be avoided with a subquery or self join
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When called from
getDatabaseSyncChanges
I wonder if it's even necessary to fetch messages of the same thread. We already know the new IDs. Other messages are not relevant, are they?