1use mxr_core::id::*;
2use mxr_core::types::*;
3
4use crate::message::record_to_envelope;
5
6impl super::Store {
7 pub async fn get_thread(&self, thread_id: &ThreadId) -> Result<Option<Thread>, sqlx::Error> {
8 let tid = thread_id.as_str();
9 let row = sqlx::query!(
10 r#"SELECT
11 thread_id as "thread_id!",
12 account_id as "account_id!",
13 MIN(subject) as "subject!: String",
14 COUNT(*) as "message_count!: i64",
15 SUM(CASE WHEN (flags & 1) = 0 THEN 1 ELSE 0 END) as "unread_count!: i64",
16 MAX(date) as "latest_date!: i64",
17 snippet as "snippet!"
18 FROM messages
19 WHERE thread_id = ?
20 GROUP BY thread_id"#,
21 tid,
22 )
23 .fetch_optional(self.reader())
24 .await?;
25
26 let row = match row {
27 Some(r) => r,
28 None => return Ok(None),
29 };
30
31 let tid2 = thread_id.as_str();
33 let participant_rows = sqlx::query!(
34 r#"SELECT DISTINCT from_name, from_email as "from_email!" FROM messages WHERE thread_id = ?"#,
35 tid2,
36 )
37 .fetch_all(self.reader())
38 .await?;
39
40 let participants: Vec<Address> = participant_rows
41 .into_iter()
42 .map(|r| Address {
43 name: r.from_name,
44 email: r.from_email,
45 })
46 .collect();
47
48 Ok(Some(Thread {
49 id: ThreadId::from_uuid(uuid::Uuid::parse_str(&row.thread_id).unwrap()),
50 account_id: AccountId::from_uuid(uuid::Uuid::parse_str(&row.account_id).unwrap()),
51 subject: row.subject,
52 participants,
53 message_count: row.message_count as u32,
54 unread_count: row.unread_count as u32,
55 latest_date: chrono::DateTime::from_timestamp(row.latest_date, 0).unwrap_or_default(),
56 snippet: row.snippet,
57 }))
58 }
59
60 pub async fn get_thread_envelopes(
61 &self,
62 thread_id: &ThreadId,
63 ) -> Result<Vec<Envelope>, sqlx::Error> {
64 let tid = thread_id.as_str();
65 let rows = sqlx::query!(
66 r#"SELECT
67 id as "id!", account_id as "account_id!", provider_id as "provider_id!",
68 thread_id as "thread_id!", message_id_header, in_reply_to,
69 reference_headers, from_name, from_email as "from_email!",
70 to_addrs as "to_addrs!", cc_addrs as "cc_addrs!", bcc_addrs as "bcc_addrs!",
71 subject as "subject!", date as "date!", flags as "flags!",
72 snippet as "snippet!", has_attachments as "has_attachments!: bool",
73 size_bytes as "size_bytes!", unsubscribe_method,
74 COALESCE((
75 SELECT GROUP_CONCAT(labels.provider_id, char(31))
76 FROM message_labels
77 JOIN labels ON labels.id = message_labels.label_id
78 WHERE message_labels.message_id = messages.id
79 ), '') as "label_provider_ids!: String"
80 FROM messages WHERE thread_id = ? ORDER BY date ASC"#,
81 tid,
82 )
83 .fetch_all(self.reader())
84 .await?;
85
86 Ok(rows
87 .into_iter()
88 .map(|r| {
89 record_to_envelope(
90 &r.id,
91 &r.account_id,
92 &r.provider_id,
93 &r.thread_id,
94 r.message_id_header.as_deref(),
95 r.in_reply_to.as_deref(),
96 r.reference_headers.as_deref(),
97 r.from_name.as_deref(),
98 &r.from_email,
99 &r.to_addrs,
100 &r.cc_addrs,
101 &r.bcc_addrs,
102 &r.subject,
103 r.date,
104 r.flags,
105 &r.snippet,
106 r.has_attachments,
107 r.size_bytes,
108 r.unsubscribe_method.as_deref(),
109 &r.label_provider_ids,
110 )
111 })
112 .collect())
113 }
114}