Skip to content

Commit

Permalink
2squash: Optimize SQL statement and limit it to one message
Browse files Browse the repository at this point in the history
  • Loading branch information
iequidoo committed Nov 28, 2024
1 parent 53feb85 commit 4e257c5
Showing 1 changed file with 42 additions and 21 deletions.
63 changes: 42 additions & 21 deletions src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::mimeparser::SystemMessage;
use crate::param::{Param, Params};
use crate::peerstate::Peerstate;
use crate::receive_imf::ReceivedMsg;
use crate::rusqlite::OptionalExtension;
use crate::securejoin::BobState;
use crate::smtp::send_msg_to_smtp;
use crate::sql;
Expand Down Expand Up @@ -3316,37 +3317,57 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<()>
}
} else {
let conn_fn = |conn: &mut rusqlite::Connection| {
// This is to trigger emitting `MsgsNoticed` on other devices when reactions are noticed
// locally. We filter out `InNoticed` messages because they are normally a result of
// `mark_old_messages_as_noticed()` which happens on all devices anyway. Also we limit
// this to one message because the effect is the same anyway.
//
// Even if `message::markseen_msgs()` fails then, in the worst case other devices won't
// emit `MsgsNoticed` and app notifications won't be removed. The bigger problem is that
// another device may have more reactions received and not yet seen notifications are
// removed from it, but the same problem already exists for "usual" messages, so let's
// not solve it for now.
let mut stmt = conn.prepare(
"SELECT id, state FROM msgs
WHERE (state=? OR state=? OR state=?)
AND hidden=1
AND chat_id=?
ORDER BY id DESC LIMIT 1",
)?;
let id_to_markseen = stmt
.query_row(
(
MessageState::InFresh,
MessageState::InNoticed,
MessageState::InSeen,
chat_id,
),
|row| {
let id: MsgId = row.get(0)?;
let state: MessageState = row.get(1)?;
Ok((id, state))
},
)
.optional()?
.filter(|&(_, state)| state == MessageState::InFresh)
.map(|(id, _)| id);

let nr_msgs_noticed = conn.execute(
"UPDATE msgs
SET state=?
WHERE state=?
AND hidden=0
AND chat_id=?",
(MessageState::InNoticed, MessageState::InFresh, chat_id),
)?;
let mut stmt = conn.prepare(
"SELECT id FROM msgs
WHERE state>=? AND state<?
AND hidden=1
AND chat_id=?
ORDER BY id DESC LIMIT 100",
)?;
let hidden_msgs = stmt
.query_map(
(MessageState::InFresh, MessageState::InSeen, chat_id),
|row| {
let id: MsgId = row.get(0)?;
Ok(id)
},
)?
.collect::<std::result::Result<Vec<_>, _>>()?;
Ok((nr_msgs_noticed, hidden_msgs))
Ok((nr_msgs_noticed, id_to_markseen))
};
let (nr_msgs_noticed, hidden_msgs) = context.sql.call_write(conn_fn).await?;
if nr_msgs_noticed == 0 && hidden_msgs.is_empty() {
let (nr_msgs_noticed, id_to_markseen) = context.sql.call_write(conn_fn).await?;
if nr_msgs_noticed == 0 {
return Ok(());
}
message::markseen_msgs(context, hidden_msgs).await?;
if let Some(id) = id_to_markseen {
message::markseen_msgs(context, vec![id]).await?;
}
}

context.emit_event(EventType::MsgsNoticed(chat_id));
Expand Down

0 comments on commit 4e257c5

Please sign in to comment.