mirror of
https://github.com/chatmail/core.git
synced 2026-05-06 16:36:59 +03:00
Return results from add_parts() via structure
Replaced mutable out parameters with explicit return of structure. Also moved all decisions about emitted events out of add_parts(). Chat ID is removed from created_db_entries as it is the same for all parts.
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
- improve speed by caching config values #3131 #3145
|
- improve speed by caching config values #3131 #3145
|
||||||
- optimize `markseen_msgs` #3141
|
- optimize `markseen_msgs` #3141
|
||||||
- automatically accept chats with outgoing messages #3143
|
- automatically accept chats with outgoing messages #3143
|
||||||
|
- return result from `add_parts()` via structure #3154
|
||||||
|
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|||||||
@@ -41,12 +41,6 @@ use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on
|
|||||||
use crate::sql;
|
use crate::sql;
|
||||||
use crate::stock_str;
|
use crate::stock_str;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
enum CreateEvent {
|
|
||||||
MsgsChanged,
|
|
||||||
IncomingMsg,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is the struct that is returned after receiving one email (aka MIME message).
|
/// This is the struct that is returned after receiving one email (aka MIME message).
|
||||||
///
|
///
|
||||||
/// One email with multiple attachments can end up as multiple chat messages, but they
|
/// One email with multiple attachments can end up as multiple chat messages, but they
|
||||||
@@ -59,6 +53,18 @@ pub struct ReceivedMsg {
|
|||||||
// Feel free to add more fields here
|
// Feel free to add more fields here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information about added message parts.
|
||||||
|
struct AddedParts {
|
||||||
|
/// Common info about received messages.
|
||||||
|
pub received_msg: ReceivedMsg,
|
||||||
|
|
||||||
|
/// IDs of inserted rows in messages table.
|
||||||
|
pub created_db_entries: Vec<MsgId>,
|
||||||
|
|
||||||
|
/// Whether IMAP messages should be immediately deleted.
|
||||||
|
pub needs_delete_job: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Emulates reception of a message from the network.
|
/// Emulates reception of a message from the network.
|
||||||
///
|
///
|
||||||
/// This method returns errors on a failure to parse the mail or extract Message-ID. It's only used
|
/// This method returns errors on a failure to parse the mail or extract Message-ID. It's only used
|
||||||
@@ -160,11 +166,6 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// the function returns the number of created messages in the database
|
// the function returns the number of created messages in the database
|
||||||
let mut needs_delete_job = false;
|
|
||||||
|
|
||||||
let mut created_db_entries = Vec::new();
|
|
||||||
let mut create_event_to_send = Some(CreateEvent::MsgsChanged);
|
|
||||||
|
|
||||||
let prevent_rename =
|
let prevent_rename =
|
||||||
mime_parser.is_mailinglist_message() || mime_parser.get_header(HeaderDef::Sender).is_some();
|
mime_parser.is_mailinglist_message() || mime_parser.get_header(HeaderDef::Sender).is_some();
|
||||||
|
|
||||||
@@ -207,7 +208,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add parts
|
// Add parts
|
||||||
let received_msg = add_parts(
|
let added_parts = add_parts(
|
||||||
context,
|
context,
|
||||||
&mut mime_parser,
|
&mut mime_parser,
|
||||||
imf_raw,
|
imf_raw,
|
||||||
@@ -220,9 +221,6 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
from_id,
|
from_id,
|
||||||
seen || replace_partial_download,
|
seen || replace_partial_download,
|
||||||
is_partial_download,
|
is_partial_download,
|
||||||
&mut needs_delete_job,
|
|
||||||
&mut created_db_entries,
|
|
||||||
&mut create_event_to_send,
|
|
||||||
fetching_existing_messages,
|
fetching_existing_messages,
|
||||||
prevent_rename,
|
prevent_rename,
|
||||||
)
|
)
|
||||||
@@ -236,7 +234,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
// Update gossiped timestamp for the chat if someone else or our other device sent
|
// Update gossiped timestamp for the chat if someone else or our other device sent
|
||||||
// Autocrypt-Gossip for all recipients in the chat to avoid sending Autocrypt-Gossip ourselves
|
// Autocrypt-Gossip for all recipients in the chat to avoid sending Autocrypt-Gossip ourselves
|
||||||
// and waste traffic.
|
// and waste traffic.
|
||||||
let chat_id = received_msg.chat_id;
|
let chat_id = added_parts.received_msg.chat_id;
|
||||||
if !chat_id.is_special()
|
if !chat_id.is_special()
|
||||||
&& mime_parser
|
&& mime_parser
|
||||||
.recipients
|
.recipients
|
||||||
@@ -254,7 +252,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let insert_msg_id = if let Some((_chat_id, msg_id)) = created_db_entries.last() {
|
let insert_msg_id = if let Some(msg_id) = added_parts.created_db_entries.last() {
|
||||||
*msg_id
|
*msg_id
|
||||||
} else {
|
} else {
|
||||||
MsgId::new_unset()
|
MsgId::new_unset()
|
||||||
@@ -335,8 +333,10 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
// Get user-configured server deletion
|
// Get user-configured server deletion
|
||||||
let delete_server_after = context.get_config_delete_server_after().await?;
|
let delete_server_after = context.get_config_delete_server_after().await?;
|
||||||
|
|
||||||
if !created_db_entries.is_empty() {
|
if !added_parts.created_db_entries.is_empty() {
|
||||||
if needs_delete_job || (delete_server_after == Some(0) && is_partial_download.is_none()) {
|
if added_parts.needs_delete_job
|
||||||
|
|| (delete_server_after == Some(0) && is_partial_download.is_none())
|
||||||
|
{
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.execute(
|
.execute(
|
||||||
@@ -364,11 +364,12 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
msg_id: MsgId::new(0),
|
msg_id: MsgId::new(0),
|
||||||
chat_id,
|
chat_id,
|
||||||
});
|
});
|
||||||
} else if let Some(create_event_to_send) = create_event_to_send {
|
} else if !chat_id.is_trash() {
|
||||||
for (chat_id, msg_id) in created_db_entries {
|
for msg_id in added_parts.created_db_entries {
|
||||||
let event = match create_event_to_send {
|
let event = if incoming && added_parts.received_msg.state == MessageState::InFresh {
|
||||||
CreateEvent::MsgsChanged => EventType::MsgsChanged { msg_id, chat_id },
|
EventType::IncomingMsg { msg_id, chat_id }
|
||||||
CreateEvent::IncomingMsg => EventType::IncomingMsg { msg_id, chat_id },
|
} else {
|
||||||
|
EventType::MsgsChanged { msg_id, chat_id }
|
||||||
};
|
};
|
||||||
context.emit_event(event);
|
context.emit_event(event);
|
||||||
}
|
}
|
||||||
@@ -378,7 +379,7 @@ pub(crate) async fn dc_receive_imf_inner(
|
|||||||
.handle_reports(context, from_id, sent_timestamp, &mime_parser.parts)
|
.handle_reports(context, from_id, sent_timestamp, &mime_parser.parts)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
Ok(Some(received_msg))
|
Ok(Some(added_parts.received_msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts "From" field to contact id.
|
/// Converts "From" field to contact id.
|
||||||
@@ -441,12 +442,9 @@ async fn add_parts(
|
|||||||
from_id: ContactId,
|
from_id: ContactId,
|
||||||
seen: bool,
|
seen: bool,
|
||||||
is_partial_download: Option<u32>,
|
is_partial_download: Option<u32>,
|
||||||
needs_delete_job: &mut bool,
|
|
||||||
created_db_entries: &mut Vec<(ChatId, MsgId)>,
|
|
||||||
create_event_to_send: &mut Option<CreateEvent>,
|
|
||||||
fetching_existing_messages: bool,
|
fetching_existing_messages: bool,
|
||||||
prevent_rename: bool,
|
prevent_rename: bool,
|
||||||
) -> Result<ReceivedMsg> {
|
) -> Result<AddedParts> {
|
||||||
let mut chat_id = None;
|
let mut chat_id = None;
|
||||||
let mut chat_id_blocked = Blocked::Not;
|
let mut chat_id_blocked = Blocked::Not;
|
||||||
|
|
||||||
@@ -494,6 +492,7 @@ async fn add_parts(
|
|||||||
let to_id: ContactId;
|
let to_id: ContactId;
|
||||||
|
|
||||||
let state: MessageState;
|
let state: MessageState;
|
||||||
|
let mut needs_delete_job = false;
|
||||||
if incoming {
|
if incoming {
|
||||||
to_id = DC_CONTACT_ID_SELF;
|
to_id = DC_CONTACT_ID_SELF;
|
||||||
|
|
||||||
@@ -506,7 +505,7 @@ async fn add_parts(
|
|||||||
match handle_securejoin_handshake(context, mime_parser, from_id).await {
|
match handle_securejoin_handshake(context, mime_parser, from_id).await {
|
||||||
Ok(securejoin::HandshakeMessage::Done) => {
|
Ok(securejoin::HandshakeMessage::Done) => {
|
||||||
chat_id = Some(DC_CHAT_ID_TRASH);
|
chat_id = Some(DC_CHAT_ID_TRASH);
|
||||||
*needs_delete_job = true;
|
needs_delete_job = true;
|
||||||
securejoin_seen = true;
|
securejoin_seen = true;
|
||||||
}
|
}
|
||||||
Ok(securejoin::HandshakeMessage::Ignore) => {
|
Ok(securejoin::HandshakeMessage::Ignore) => {
|
||||||
@@ -1086,7 +1085,7 @@ async fn add_parts(
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ids = Vec::with_capacity(parts.len());
|
let mut created_db_entries = Vec::with_capacity(parts.len());
|
||||||
|
|
||||||
let conn = context.sql.get_conn().await?;
|
let conn = context.sql.get_conn().await?;
|
||||||
|
|
||||||
@@ -1187,13 +1186,12 @@ INSERT INTO msgs
|
|||||||
let row_id = conn.last_insert_rowid();
|
let row_id = conn.last_insert_rowid();
|
||||||
|
|
||||||
drop(stmt);
|
drop(stmt);
|
||||||
ids.push(MsgId::new(u32::try_from(row_id)?));
|
created_db_entries.push(MsgId::new(u32::try_from(row_id)?));
|
||||||
}
|
}
|
||||||
drop(conn);
|
drop(conn);
|
||||||
|
|
||||||
chat_id.unarchive(context).await?;
|
chat_id.unarchive(context).await?;
|
||||||
|
|
||||||
created_db_entries.extend(ids.iter().map(|id| (chat_id, *id)));
|
|
||||||
mime_parser.parts = parts;
|
mime_parser.parts = parts;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
@@ -1206,15 +1204,6 @@ INSERT INTO msgs
|
|||||||
chat::marknoticed_chat_if_older_than(context, chat_id, sort_timestamp).await?;
|
chat::marknoticed_chat_if_older_than(context, chat_id, sort_timestamp).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check event to send
|
|
||||||
*create_event_to_send = if chat_id.is_trash() {
|
|
||||||
None
|
|
||||||
} else if incoming && state == MessageState::InFresh {
|
|
||||||
Some(CreateEvent::IncomingMsg)
|
|
||||||
} else {
|
|
||||||
Some(CreateEvent::MsgsChanged)
|
|
||||||
};
|
|
||||||
|
|
||||||
if !is_mdn {
|
if !is_mdn {
|
||||||
let mut chat = Chat::load_from_db(context, chat_id).await?;
|
let mut chat = Chat::load_from_db(context, chat_id).await?;
|
||||||
|
|
||||||
@@ -1234,10 +1223,16 @@ INSERT INTO msgs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ReceivedMsg {
|
let received_msg = ReceivedMsg {
|
||||||
chat_id,
|
chat_id,
|
||||||
state,
|
state,
|
||||||
sort_timestamp,
|
sort_timestamp,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(AddedParts {
|
||||||
|
received_msg,
|
||||||
|
created_db_entries,
|
||||||
|
needs_delete_job,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user