From 607b9e55a9975773efbd27f14faca91ea7a07874 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Tue, 14 Nov 2023 21:53:21 -0300 Subject: [PATCH] fix: Chat::sync_contacts(): Fetch contact addresses in a single query In order to protect from races with contacts removal and (just in case) dangling contact ids in `chats_contacts` table. --- src/chat.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 9709fb7d8..fa76e0b7f 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1935,11 +1935,18 @@ impl Chat { /// Sends a `SyncAction` synchronising chat contacts to other devices. pub(crate) async fn sync_contacts(&self, context: &Context) -> Result<()> { - let mut addrs = Vec::new(); - for contact_id in get_chat_contacts(context, self.id).await? { - let contact = Contact::get_by_id(context, contact_id).await?; - addrs.push(contact.get_addr().to_string()); - } + let addrs = context + .sql + .query_map( + "SELECT c.addr \ + FROM contacts c INNER JOIN chats_contacts cc \ + ON c.id=cc.contact_id \ + WHERE cc.chat_id=?", + (self.id,), + |row| row.get::<_, String>(0), + |addrs| addrs.collect::, _>>().map_err(Into::into), + ) + .await?; self.sync(context, SyncAction::SetContacts(addrs)).await }