Skip to content

Commit 17dd457

Browse files
committed
refactor(sql): do not expose rusqlite Error type in query_map methods
We use query_and_then() instead of query_map() function now. The difference is that row processing function returns anyhow::Result, so simple fallible processing like JSON parsing can be done inside of it when calling query_map_vec() and query_map_collect() without having to resort to query_map() and iterating over all rows again afterwards.
1 parent 7f05914 commit 17dd457

File tree

11 files changed

+98
-62
lines changed

11 files changed

+98
-62
lines changed

src/chat.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,7 +2029,10 @@ impl Chat {
20292029
ON c.id=cc.contact_id \
20302030
WHERE cc.chat_id=? AND cc.add_timestamp >= cc.remove_timestamp",
20312031
(self.id,),
2032-
|row| row.get::<_, String>(0),
2032+
|row| {
2033+
let addr: String = row.get(0)?;
2034+
Ok(addr)
2035+
},
20332036
)
20342037
.await?;
20352038
self.sync(context, SyncAction::SetContacts(addrs)).await?;
@@ -3038,7 +3041,7 @@ pub async fn get_chat_msgs_ex(
30383041
))
30393042
}
30403043
};
3041-
let process_rows = |rows: rusqlite::MappedRows<_>| {
3044+
let process_rows = |rows: rusqlite::AndThenRows<_>| {
30423045
// It is faster to sort here rather than
30433046
// let sqlite execute an ORDER BY clause.
30443047
let mut sorted_rows = Vec::new();
@@ -3120,7 +3123,10 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<()>
31203123
LEFT JOIN chats c ON m.chat_id=c.id
31213124
WHERE m.state=10 AND m.hidden=0 AND m.chat_id>9 AND c.archived=1",
31223125
(),
3123-
|row| row.get::<_, ChatId>(0),
3126+
|row| {
3127+
let chat_id: ChatId = row.get(0)?;
3128+
Ok(chat_id)
3129+
},
31243130
)
31253131
.await?;
31263132
if chat_ids_in_archive.is_empty() {
@@ -3298,7 +3304,10 @@ pub async fn get_chat_media(
32983304
DC_CHAT_ID_TRASH,
32993305
Viewtype::Webxdc,
33003306
),
3301-
|row| row.get::<_, MsgId>(0),
3307+
|row| {
3308+
let msg_id: MsgId = row.get(0)?;
3309+
Ok(msg_id)
3310+
},
33023311
)
33033312
.await?
33043313
} else {
@@ -3328,7 +3337,10 @@ pub async fn get_chat_media(
33283337
msg_type
33293338
},
33303339
),
3331-
|row| row.get::<_, MsgId>(0),
3340+
|row| {
3341+
let msg_id: MsgId = row.get(0)?;
3342+
Ok(msg_id)
3343+
},
33323344
)
33333345
.await?
33343346
};
@@ -3349,7 +3361,10 @@ pub async fn get_chat_contacts(context: &Context, chat_id: ChatId) -> Result<Vec
33493361
WHERE cc.chat_id=? AND cc.add_timestamp >= cc.remove_timestamp
33503362
ORDER BY c.id=1, c.last_seen DESC, c.id DESC;",
33513363
(chat_id,),
3352-
|row| row.get::<_, ContactId>(0),
3364+
|row| {
3365+
let contact_id: ContactId = row.get(0)?;
3366+
Ok(contact_id)
3367+
},
33533368
)
33543369
.await
33553370
}
@@ -3371,7 +3386,10 @@ pub async fn get_past_chat_contacts(context: &Context, chat_id: ChatId) -> Resul
33713386
AND ? < cc.remove_timestamp
33723387
ORDER BY c.id=1, cc.remove_timestamp DESC, c.id DESC",
33733388
(chat_id, now.saturating_sub(60 * 24 * 3600)),
3374-
|row| row.get::<_, ContactId>(0),
3389+
|row| {
3390+
let contact_id: ContactId = row.get(0)?;
3391+
Ok(contact_id)
3392+
},
33753393
)
33763394
.await
33773395
}
@@ -3734,11 +3752,13 @@ pub(crate) async fn shall_attach_selfavatar(context: &Context, chat_id: ChatId)
37343752
LEFT JOIN contacts c ON c.id=cc.contact_id
37353753
WHERE cc.chat_id=? AND cc.contact_id!=? AND cc.add_timestamp >= cc.remove_timestamp",
37363754
(chat_id, ContactId::SELF),
3737-
|row| Ok(row.get::<_, i64>(0)),
3755+
|row| {
3756+
let selfavatar_sent: i64 = row.get(0)?;
3757+
Ok(selfavatar_sent)
3758+
},
37383759
|rows| {
37393760
let mut needs_attach = false;
37403761
for row in rows {
3741-
let row = row?;
37423762
let selfavatar_sent = row?;
37433763
if selfavatar_sent < timestamp_some_days_ago {
37443764
needs_attach = true;

src/chatlist.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,6 @@ impl Chatlist {
107107
Ok((chat_id, msg_id))
108108
};
109109

110-
let process_rows = |rows: rusqlite::MappedRows<_>| {
111-
rows.collect::<std::result::Result<Vec<_>, _>>()
112-
.map_err(Into::into)
113-
};
114-
115110
let skip_id = if flag_for_forwarding {
116111
ChatId::lookup_by_contact(context, ContactId::DEVICE)
117112
.await?
@@ -132,7 +127,7 @@ impl Chatlist {
132127
// groups. Otherwise it would be hard to follow conversations.
133128
let ids = if let Some(query_contact_id) = query_contact_id {
134129
// show chats shared with a given contact
135-
context.sql.query_map(
130+
context.sql.query_map_vec(
136131
"SELECT c.id, m.id
137132
FROM chats c
138133
LEFT JOIN msgs m
@@ -150,7 +145,6 @@ impl Chatlist {
150145
ORDER BY c.archived=?3 DESC, IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
151146
(MessageState::OutDraft, query_contact_id, ChatVisibility::Pinned),
152147
process_row,
153-
process_rows,
154148
).await?
155149
} else if flag_archived_only {
156150
// show archived chats
@@ -159,7 +153,7 @@ impl Chatlist {
159153
// and adapting the number requires larger refactorings and seems not to be worth the effort)
160154
context
161155
.sql
162-
.query_map(
156+
.query_map_vec(
163157
"SELECT c.id, m.id
164158
FROM chats c
165159
LEFT JOIN msgs m
@@ -177,7 +171,6 @@ impl Chatlist {
177171
ORDER BY IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
178172
(MessageState::OutDraft,),
179173
process_row,
180-
process_rows,
181174
)
182175
.await?
183176
} else if let Some(query) = query {
@@ -195,7 +188,7 @@ impl Chatlist {
195188
let str_like_cmd = format!("%{query}%");
196189
context
197190
.sql
198-
.query_map(
191+
.query_map_vec(
199192
"SELECT c.id, m.id
200193
FROM chats c
201194
LEFT JOIN msgs m
@@ -214,7 +207,6 @@ impl Chatlist {
214207
ORDER BY IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
215208
(MessageState::OutDraft, skip_id, str_like_cmd, only_unread, MessageState::InFresh),
216209
process_row,
217-
process_rows,
218210
)
219211
.await?
220212
} else {
@@ -229,7 +221,7 @@ impl Chatlist {
229221
let msg_id: Option<MsgId> = row.get(3)?;
230222
Ok((chat_id, typ, param, msg_id))
231223
};
232-
let process_rows = |rows: rusqlite::MappedRows<_>| {
224+
let process_rows = |rows: rusqlite::AndThenRows<_>| {
233225
rows.filter_map(|row: std::result::Result<(_, _, Params, _), _>| match row {
234226
Ok((chat_id, typ, param, msg_id)) => {
235227
if typ == Chattype::Mailinglist
@@ -272,7 +264,7 @@ impl Chatlist {
272264
).await?
273265
} else {
274266
// show normal chatlist
275-
context.sql.query_map(
267+
context.sql.query_map_vec(
276268
"SELECT c.id, m.id
277269
FROM chats c
278270
LEFT JOIN msgs m
@@ -290,7 +282,6 @@ impl Chatlist {
290282
ORDER BY c.id=0 DESC, c.archived=? DESC, IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
291283
(MessageState::OutDraft, skip_id, ChatVisibility::Archived, ChatVisibility::Pinned),
292284
process_row,
293-
process_rows,
294285
).await?
295286
};
296287
if !flag_no_specials && get_archived_cnt(context).await? > 0 {

src/configure.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,16 +192,11 @@ impl Context {
192192
pub async fn list_transports(&self) -> Result<Vec<EnteredLoginParam>> {
193193
let transports = self
194194
.sql
195-
.query_map(
196-
"SELECT entered_param FROM transports",
197-
(),
198-
|row| row.get::<_, String>(0),
199-
|rows| {
200-
rows.flatten()
201-
.map(|s| Ok(serde_json::from_str(&s)?))
202-
.collect::<Result<Vec<EnteredLoginParam>>>()
203-
},
204-
)
195+
.query_map_vec("SELECT entered_param FROM transports", (), |row| {
196+
let entered_param: String = row.get(0)?;
197+
let transport: EnteredLoginParam = serde_json::from_str(&entered_param)?;
198+
Ok(transport)
199+
})
205200
.await?;
206201

207202
Ok(transports)

src/contact.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,10 @@ impl Contact {
12851285
.query_map_vec(
12861286
"SELECT id FROM contacts WHERE id>? AND blocked!=0 ORDER BY last_seen DESC, id DESC;",
12871287
(ContactId::LAST_SPECIAL,),
1288-
|row| row.get::<_, ContactId>(0),
1288+
|row| {
1289+
let contact_id: ContactId = row.get(0)?;
1290+
Ok(contact_id)
1291+
}
12891292
)
12901293
.await?;
12911294
Ok(list)
@@ -2044,7 +2047,7 @@ impl RecentlySeenLoop {
20442047
// become unseen in the future.
20452048
let mut unseen_queue: BinaryHeap<MyHeapElem> = context
20462049
.sql
2047-
.query_map(
2050+
.query_map_collect(
20482051
"SELECT id, last_seen FROM contacts
20492052
WHERE last_seen > ?",
20502053
(now_ts - SEEN_RECENTLY_SECONDS,),
@@ -2053,10 +2056,6 @@ impl RecentlySeenLoop {
20532056
let last_seen: i64 = row.get("last_seen")?;
20542057
Ok((Reverse(last_seen + SEEN_RECENTLY_SECONDS), contact_id))
20552058
},
2056-
|rows| {
2057-
rows.collect::<std::result::Result<BinaryHeap<MyHeapElem>, _>>()
2058-
.map_err(Into::into)
2059-
},
20602059
)
20612060
.await
20622061
.unwrap_or_default();

src/context.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,10 @@ impl Context {
11001100
" ORDER BY m.timestamp DESC,m.id DESC;"
11011101
),
11021102
(MessageState::InFresh, time()),
1103-
|row| row.get::<_, MsgId>(0),
1103+
|row| {
1104+
let msg_id: MsgId = row.get(0)?;
1105+
Ok(msg_id)
1106+
},
11041107
)
11051108
.await?;
11061109
Ok(list)
@@ -1204,7 +1207,10 @@ impl Context {
12041207
AND IFNULL(txt_normalized, txt) LIKE ?
12051208
ORDER BY m.timestamp,m.id;",
12061209
(chat_id, str_like_in_text),
1207-
|row| row.get::<_, MsgId>("id"),
1210+
|row| {
1211+
let msg_id: MsgId = row.get("id")?;
1212+
Ok(msg_id)
1213+
},
12081214
)
12091215
.await?
12101216
} else {
@@ -1233,7 +1239,10 @@ impl Context {
12331239
AND IFNULL(txt_normalized, txt) LIKE ?
12341240
ORDER BY m.id DESC LIMIT 1000",
12351241
(str_like_in_text,),
1236-
|row| row.get::<_, MsgId>("id"),
1242+
|row| {
1243+
let msg_id: MsgId = row.get("id")?;
1244+
Ok(msg_id)
1245+
},
12371246
)
12381247
.await?
12391248
};

src/key.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,15 @@ pub(crate) async fn load_self_public_key(context: &Context) -> Result<SignedPubl
159159
pub(crate) async fn load_self_public_keyring(context: &Context) -> Result<Vec<SignedPublicKey>> {
160160
let keys = context
161161
.sql
162-
.query_map(
162+
.query_map_vec(
163163
r#"SELECT public_key
164164
FROM keypairs
165165
ORDER BY id=(SELECT value FROM config WHERE keyname='key_id') DESC"#,
166166
(),
167-
|row| row.get::<_, Vec<u8>>(0),
168-
|keys| keys.collect::<Result<Vec<_>, _>>().map_err(Into::into),
167+
|row| {
168+
let public_key_bytes: Vec<u8> = row.get(0)?;
169+
Ok(public_key_bytes)
170+
},
169171
)
170172
.await?
171173
.into_iter()
@@ -232,13 +234,15 @@ pub(crate) async fn load_self_secret_key(context: &Context) -> Result<SignedSecr
232234
pub(crate) async fn load_self_secret_keyring(context: &Context) -> Result<Vec<SignedSecretKey>> {
233235
let keys = context
234236
.sql
235-
.query_map(
237+
.query_map_vec(
236238
r#"SELECT private_key
237239
FROM keypairs
238240
ORDER BY id=(SELECT value FROM config WHERE keyname='key_id') DESC"#,
239241
(),
240-
|row| row.get::<_, Vec<u8>>(0),
241-
|keys| keys.collect::<Result<Vec<_>, _>>().map_err(Into::into),
242+
|row| {
243+
let bytes: Vec<u8> = row.get(0)?;
244+
Ok(bytes)
245+
},
242246
)
243247
.await?
244248
.into_iter()

src/location.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,10 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
348348
.query_map_vec(
349349
"SELECT id FROM chats WHERE locations_send_until>?;",
350350
(now,),
351-
|row| row.get::<_, i32>(0),
351+
|row| {
352+
let id: i32 = row.get(0)?;
353+
Ok(id)
354+
},
352355
)
353356
.await?;
354357

0 commit comments

Comments
 (0)