diff --git a/src/download.rs b/src/download.rs index 3a7113ef0..a05a35e53 100644 --- a/src/download.rs +++ b/src/download.rs @@ -11,7 +11,7 @@ use crate::imap::{Imap, ImapActionResult}; use crate::job::{self, Action, Job, Status}; use crate::message::{Message, MsgId, Viewtype}; use crate::mimeparser::{MimeMessage, Part}; -use crate::param::{Param, Params}; +use crate::param::Params; use crate::tools::time; use crate::{job_try, stock_str, EventType}; use std::cmp::max; @@ -69,76 +69,6 @@ impl Context { Ok(Some(max(MIN_DOWNLOAD_LIMIT, download_limit as u32))) } } - - // Merges the two messages to `placeholder_msg_id`; - // `full_msg_id` is no longer used afterwards. - pub(crate) async fn merge_messages( - &self, - full_msg_id: MsgId, - placeholder_msg_id: MsgId, - ) -> Result<()> { - let placeholder = Message::load_from_db(self, placeholder_msg_id).await?; - self.sql - .transaction(move |transaction| { - // Move all the data from full message to placeholder. - // `id` stays the same, so foreign key constraints are not violated. - // For example, `reactions.msg_id` foreign key keeps pointing - // to the same message. - transaction.execute( - "UPDATE msgs - SET - rfc724_mid=full.rfc724_mid, - chat_id=full.chat_id, - from_id=full.from_id, - to_id=full.to_id, - timestamp=full.timestamp, - type=full.type, - state=full.state, - msgrmsg=full.msgrmsg, - bytes=full.bytes, - txt=full.txt, - txt_raw=full.txt_raw, - param=full.param, - starred=full.starred, - timestamp_sent=full.timestamp_sent, - timestamp_rcvd=full.timestamp_rcvd, - hidden=full.hidden, - mime_headers=full.mime_headers, - mime_in_reply_to=full.mime_in_reply_to, - mime_references=full.mime_references, - move_state=full.move_state, - location_id=full.location_id, - error=full.error, - ephemeral_timer=full.ephemeral_timer, - ephemeral_timestamp=full.ephemeral_timestamp, - mime_modified=full.mime_modified, - subject=full.subject, - download_state=full.download_state, - hop_info=full.hop_info - FROM msgs AS full - WHERE msgs.id=?1 AND full.id=?2", - paramsv![placeholder_msg_id, full_msg_id], - )?; - transaction.execute("DELETE FROM msgs WHERE id=?;", paramsv![full_msg_id])?; - Ok(()) - }) - .await?; - let mut full = Message::load_from_db(self, placeholder_msg_id).await?; - - for key in [ - Param::WebxdcSummary, - Param::WebxdcSummaryTimestamp, - Param::WebxdcDocument, - Param::WebxdcDocumentTimestamp, - ] { - if let Some(value) = placeholder.param.get(key) { - full.param.set(key, value); - } - } - full.update_param(self).await?; - - Ok(()) - } } impl MsgId { diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 7e71d0081..ddf33ab35 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -405,7 +405,7 @@ async fn add_parts( from_id: ContactId, seen: bool, is_partial_download: Option, - replace_msg_id: Option, + mut replace_msg_id: Option, fetching_existing_messages: bool, prevent_rename: bool, ) -> Result { @@ -1068,11 +1068,30 @@ async fn add_parts( .await?; } + let mut param = part.param.clone(); + if is_system_message != SystemMessage::Unknown { + param.set_int(Param::Cmd, is_system_message as i32); + } + if let Some(replace_msg_id) = replace_msg_id { + let placeholder = Message::load_from_db(context, replace_msg_id).await?; + for key in [ + Param::WebxdcSummary, + Param::WebxdcSummaryTimestamp, + Param::WebxdcDocument, + Param::WebxdcDocumentTimestamp, + ] { + if let Some(value) = placeholder.param.get(key) { + param.set(key, value); + } + } + } + let mut txt_raw = "".to_string(); let mut stmt = conn.prepare_cached( r#" INSERT INTO msgs ( + id, rfc724_mid, chat_id, from_id, to_id, timestamp, timestamp_sent, timestamp_rcvd, type, state, msgrmsg, @@ -1082,13 +1101,22 @@ INSERT INTO msgs ephemeral_timestamp, download_state, hop_info ) VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ); + ) +ON CONFLICT (id) DO UPDATE +SET rfc724_mid=excluded.rfc724_mid, chat_id=excluded.chat_id, + from_id=excluded.from_id, to_id=excluded.to_id, timestamp=excluded.timestamp, timestamp_sent=excluded.timestamp_sent, + timestamp_rcvd=excluded.timestamp_rcvd, type=excluded.type, state=excluded.state, msgrmsg=excluded.msgrmsg, + txt=excluded.txt, subject=excluded.subject, txt_raw=excluded.txt_raw, param=excluded.param, + bytes=excluded.bytes, mime_headers=excluded.mime_headers, mime_in_reply_to=excluded.mime_in_reply_to, + mime_references=excluded.mime_references, mime_modified=excluded.mime_modified, error=excluded.error, ephemeral_timer=excluded.ephemeral_timer, + ephemeral_timestamp=excluded.ephemeral_timestamp, download_state=excluded.download_state, hop_info=excluded.hop_info "#, )?; @@ -1110,11 +1138,6 @@ INSERT INTO msgs txt_raw = format!("{}\n\n{}", subject, msg_raw); } - let mut param = part.param.clone(); - if is_system_message != SystemMessage::Unknown { - param.set_int(Param::Cmd, is_system_message as i32); - } - let ephemeral_timestamp = if in_fresh { 0 } else { @@ -1131,6 +1154,7 @@ INSERT INTO msgs let trash = chat_id.is_trash() || (is_location_kml && msg.is_empty()); stmt.execute(paramsv![ + replace_msg_id, rfc724_mid, if trash { DC_CHAT_ID_TRASH } else { chat_id }, if trash { ContactId::UNDEFINED } else { from_id }, @@ -1169,6 +1193,10 @@ INSERT INTO msgs }, mime_parser.hop_info ])?; + + // We only replace placeholder with a first part, + // afterwards insert additional parts. + replace_msg_id = None; let row_id = conn.last_insert_rowid(); drop(stmt); @@ -1177,14 +1205,8 @@ INSERT INTO msgs drop(conn); if let Some(replace_msg_id) = replace_msg_id { - if let Some(created_msg_id) = created_db_entries.pop() { - context - .merge_messages(created_msg_id, replace_msg_id) - .await?; - created_db_entries.push(replace_msg_id); - } else { - replace_msg_id.delete_from_db(context).await?; - } + // "Replace" placeholder with a message that has no parts. + replace_msg_id.delete_from_db(context).await?; } chat_id.unarchive_if_not_muted(context).await?;