deltachat/
update_helper.rs1use anyhow::Result;
4
5use crate::chat::ChatId;
6use crate::contact::ContactId;
7use crate::context::Context;
8use crate::param::{Param, Params};
9
10impl Context {
11 pub(crate) async fn update_contacts_timestamp(
15 &self,
16 contact_id: ContactId,
17 scope: Param,
18 new_timestamp: i64,
19 ) -> Result<bool> {
20 self.sql
21 .transaction(|transaction| {
22 let mut param: Params = transaction.query_row(
23 "SELECT param FROM contacts WHERE id=?",
24 [contact_id],
25 |row| {
26 let param: String = row.get(0)?;
27 Ok(param.parse().unwrap_or_default())
28 },
29 )?;
30 let update = param.update_timestamp(scope, new_timestamp)?;
31 if update {
32 transaction.execute(
33 "UPDATE contacts SET param=? WHERE id=?",
34 (param.to_string(), contact_id),
35 )?;
36 }
37 Ok(update)
38 })
39 .await
40 }
41}
42
43impl ChatId {
44 pub(crate) async fn update_timestamp(
47 &self,
48 context: &Context,
49 scope: Param,
50 new_timestamp: i64,
51 ) -> Result<bool> {
52 context
53 .sql
54 .transaction(|transaction| {
55 let mut param: Params =
56 transaction.query_row("SELECT param FROM chats WHERE id=?", [self], |row| {
57 let param: String = row.get(0)?;
58 Ok(param.parse().unwrap_or_default())
59 })?;
60 let update = param.update_timestamp(scope, new_timestamp)?;
61 if update {
62 transaction.execute(
63 "UPDATE chats SET param=? WHERE id=?",
64 (param.to_string(), self),
65 )?;
66 }
67 Ok(update)
68 })
69 .await
70 }
71}
72
73impl Params {
74 pub(crate) fn update_timestamp(&mut self, scope: Param, new_timestamp: i64) -> Result<bool> {
77 let old_timestamp = self.get_i64(scope).unwrap_or_default();
78 if new_timestamp >= old_timestamp {
79 self.set_i64(scope, new_timestamp);
80 return Ok(true);
81 }
82 Ok(false)
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use crate::chat::Chat;
90 use crate::receive_imf::receive_imf;
91 use crate::test_utils::TestContext;
92 use crate::tools::time;
93
94 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
95 async fn test_params_update_timestamp() -> Result<()> {
96 let mut params = Params::new();
97 let ts = time();
98
99 assert!(params.update_timestamp(Param::LastSubject, ts)?);
100 assert!(params.update_timestamp(Param::LastSubject, ts)?); assert!(params.update_timestamp(Param::LastSubject, ts + 10)?);
102 assert!(!params.update_timestamp(Param::LastSubject, ts)?); assert!(!params.update_timestamp(Param::LastSubject, 0)?);
104 assert_eq!(params.get_i64(Param::LastSubject).unwrap(), ts + 10);
105
106 assert!(params.update_timestamp(Param::GroupNameTimestamp, 0)?); assert!(params.update_timestamp(Param::GroupNameTimestamp, 0)?); assert_eq!(params.get_i64(Param::GroupNameTimestamp).unwrap(), 0);
109
110 assert!(!params.update_timestamp(Param::AvatarTimestamp, -1)?);
111 assert_eq!(params.get_i64(Param::AvatarTimestamp), None);
112
113 Ok(())
114 }
115
116 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
117 async fn test_out_of_order_subject() -> Result<()> {
118 let t = TestContext::new_alice().await;
119
120 receive_imf(
121 &t,
122 b"From: Bob Authname <bob@example.org>\n\
123 To: alice@example.org\n\
124 Subject: updated subject\n\
125 Message-ID: <msg2@example.org>\n\
126 Chat-Version: 1.0\n\
127 Date: Sun, 22 Mar 2021 23:37:57 +0000\n\
128 \n\
129 second message\n",
130 false,
131 )
132 .await?;
133 receive_imf(
134 &t,
135 b"From: Bob Authname <bob@example.org>\n\
136 To: alice@example.org\n\
137 Subject: original subject\n\
138 Message-ID: <msg1@example.org>\n\
139 Chat-Version: 1.0\n\
140 Date: Sun, 22 Mar 2021 22:37:57 +0000\n\
141 \n\
142 first message\n",
143 false,
144 )
145 .await?;
146
147 let msg = t.get_last_msg().await;
148 let chat = Chat::load_from_db(&t, msg.chat_id).await?;
149 assert_eq!(
150 chat.param.get(Param::LastSubject).unwrap(),
151 "updated subject"
152 );
153
154 Ok(())
155 }
156
157 #[tokio::test(flavor = "multi_thread", worker_threads = 2)]
158 async fn test_out_of_order_group_name() -> Result<()> {
159 let t = TestContext::new_alice().await;
160
161 receive_imf(
162 &t,
163 b"From: Bob Authname <bob@example.org>\n\
164 To: alice@example.org\n\
165 Message-ID: <msg1@example.org>\n\
166 Chat-Version: 1.0\n\
167 Chat-Group-ID: abcde123456\n\
168 Chat-Group-Name: initial name\n\
169 Date: Sun, 22 Mar 2021 01:00:00 +0000\n\
170 \n\
171 first message\n",
172 false,
173 )
174 .await?;
175 let msg = t.get_last_msg().await;
176 let chat = Chat::load_from_db(&t, msg.chat_id).await?;
177 assert_eq!(chat.name, "initial name");
178
179 receive_imf(
180 &t,
181 b"From: Bob Authname <bob@example.org>\n\
182 To: alice@example.org\n\
183 Message-ID: <msg3@example.org>\n\
184 Chat-Version: 1.0\n\
185 Chat-Group-ID: abcde123456\n\
186 Chat-Group-Name: =?utf-8?q?another=0Aname update?=\n\
187 Chat-Group-Name-Changed: =?utf-8?q?a=0Aname update?=\n\
188 Date: Sun, 22 Mar 2021 03:00:00 +0000\n\
189 \n\
190 third message\n",
191 false,
192 )
193 .await?;
194 receive_imf(
195 &t,
196 b"From: Bob Authname <bob@example.org>\n\
197 To: alice@example.org\n\
198 Message-ID: <msg2@example.org>\n\
199 Chat-Version: 1.0\n\
200 Chat-Group-ID: abcde123456\n\
201 Chat-Group-Name: =?utf-8?q?a=0Aname update?=\n\
202 Chat-Group-Name-Changed: initial name\n\
203 Date: Sun, 22 Mar 2021 02:00:00 +0000\n\
204 \n\
205 second message\n",
206 false,
207 )
208 .await?;
209 let msg = t.get_last_msg().await;
210 let chat = Chat::load_from_db(&t, msg.chat_id).await?;
211 assert_eq!(chat.name, "another name update");
212
213 assert_eq!(msg.text.contains('\n'), false);
215
216 receive_imf(
218 &t,
219 b"From: Bob Authname <bob@example.org>\n\
220 To: alice@example.org\n\
221 Message-ID: <msg4@example.org>\n\
222 Chat-Version: 1.0\n\
223 Chat-Group-ID: abcde123456\n\
224 Chat-Group-Name: another name update 4\n\
225 Chat-Group-Name-Changed: another name update\n\
226 Date: Sun, 22 Mar 2021 03:00:00 +0000\n\
227 \n\
228 4th message\n",
229 false,
230 )
231 .await?;
232 let chat = Chat::load_from_db(&t, chat.id).await?;
233 assert_eq!(chat.name, "another name update");
234
235 receive_imf(
237 &t,
238 b"From: Bob Authname <bob@example.org>\n\
239 To: alice@example.org\n\
240 Message-ID: <msg5@example.org>\n\
241 Chat-Version: 1.0\n\
242 Chat-Group-ID: abcde123456\n\
243 Chat-Group-Name: another name updat\n\
244 Chat-Group-Name-Changed: another name update\n\
245 Date: Sun, 22 Mar 2021 03:00:00 +0000\n\
246 \n\
247 5th message\n",
248 false,
249 )
250 .await?;
251 let chat = Chat::load_from_db(&t, chat.id).await?;
252 assert_eq!(chat.name, "another name updat");
253
254 Ok(())
255 }
256}