chat: filter parent messages by state instead of UID

Since introduction of server message deletion, message may not have
server UID even when it is not a draft or pending message. To handle
such messages correctly, we explicitly check message state.
This commit is contained in:
Alexander Krotov
2020-04-11 22:07:43 +03:00
committed by holger krekel
parent 493a213d41
commit e9967c32e6

View File

@@ -378,34 +378,45 @@ impl ChatId {
Ok(self.get_param(context)?.exists(Param::Devicetalk)) Ok(self.get_param(context)?.exists(Param::Devicetalk))
} }
fn parent_query(fields: &str) -> String { fn parent_query<T, F>(self, context: &Context, fields: &str, f: F) -> sql::Result<Option<T>>
// Check for server_uid guarantees that we don't where
// select a draft or undelivered message. F: FnOnce(&rusqlite::Row) -> rusqlite::Result<T>,
format!( {
let sql = &context.sql;
let query = format!(
"SELECT {} \ "SELECT {} \
FROM msgs WHERE chat_id=?1 AND server_uid!=0 \ FROM msgs WHERE chat_id=? AND state NOT IN (?, ?, ?, ?) \
ORDER BY timestamp DESC, id DESC \ ORDER BY timestamp DESC, id DESC \
LIMIT 1;", LIMIT 1;",
fields fields
);
sql.query_row_optional(
query,
params![
self,
MessageState::OutPreparing,
MessageState::OutDraft,
MessageState::OutPending,
MessageState::OutFailed
],
f,
) )
} }
fn get_parent_mime_headers(self, context: &Context) -> Option<(String, String, String)> { fn get_parent_mime_headers(self, context: &Context) -> Option<(String, String, String)> {
let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)); let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?, row.get(2)?));
let params = params![self]; self.parent_query(
let sql = &context.sql; context,
"rfc724_mid, mime_in_reply_to, mime_references",
let query = Self::parent_query("rfc724_mid, mime_in_reply_to, mime_references"); collect,
)
sql.query_row(&query, params, collect).ok() .ok()
.flatten()
} }
fn parent_is_encrypted(self, context: &Context) -> Result<bool, Error> { fn parent_is_encrypted(self, context: &Context) -> Result<bool, Error> {
let sql = &context.sql; let collect = |row: &rusqlite::Row| Ok(row.get(0)?);
let params = params![self]; let packed: Option<String> = self.parent_query(context, "param", collect)?;
let query = Self::parent_query("param");
let packed: Option<String> = sql.query_get_value_result(&query, params)?;
if let Some(ref packed) = packed { if let Some(ref packed) = packed {
let param = packed.parse::<Params>()?; let param = packed.parse::<Params>()?;