sql: cleanup usage of ToSql

Moved custom ToSql trait including Send + Sync from lib.rs to sql.rs.
Replaced most params! and paramsv! macro usage with tuples.

Replaced paramsv! and params_iterv! with params_slice!,
because there is no need to construct a vector.
This commit is contained in:
link2xt
2023-04-12 22:12:46 +00:00
parent f1eeb1df8c
commit 619b849ce7
30 changed files with 349 additions and 420 deletions

View File

@@ -308,7 +308,7 @@ async fn dkim_works_timestamp(context: &Context, from_domain: &str) -> Result<i6
.sql
.query_get_value(
"SELECT dkim_works FROM sending_domains WHERE domain=?",
paramsv![from_domain],
(from_domain,),
)
.await?
.unwrap_or(0);
@@ -325,7 +325,7 @@ async fn set_dkim_works_timestamp(
.execute(
"INSERT INTO sending_domains (domain, dkim_works) VALUES (?,?)
ON CONFLICT(domain) DO UPDATE SET dkim_works=excluded.dkim_works",
paramsv![from_domain, timestamp],
(from_domain, timestamp),
)
.await?;
Ok(())

View File

@@ -273,22 +273,22 @@ impl ChatId {
let row_id =
context.sql.insert(
"INSERT INTO chats (type, name, grpid, blocked, created_timestamp, protected, param) VALUES(?, ?, ?, ?, ?, ?, ?);",
paramsv![
(
chattype,
grpname,
&grpname,
grpid,
create_blocked,
create_smeared_timestamp(context),
create_protected,
param.unwrap_or_default(),
],
),
).await?;
let chat_id = ChatId::new(u32::try_from(row_id)?);
info!(
context,
"Created group/mailinglist '{}' grpid={} as {}, blocked={}.",
grpname,
&grpname,
grpid,
chat_id,
create_blocked,
@@ -304,7 +304,7 @@ impl ChatId {
"UPDATE contacts
SET selfavatar_sent=?
WHERE id IN(SELECT contact_id FROM chats_contacts WHERE chat_id=?);",
paramsv![timestamp, self],
(timestamp, self),
)
.await?;
Ok(())
@@ -321,7 +321,7 @@ impl ChatId {
.sql
.execute(
"UPDATE chats SET blocked=?1 WHERE id=?2 AND blocked != ?1",
paramsv![new_blocked, self],
(new_blocked, self),
)
.await?;
Ok(count > 0)
@@ -435,10 +435,7 @@ impl ChatId {
context
.sql
.execute(
"UPDATE chats SET protected=? WHERE id=?;",
paramsv![protect, self],
)
.execute("UPDATE chats SET protected=? WHERE id=?;", (protect, self))
.await?;
context.emit_event(EventType::ChatModified(self));
@@ -524,12 +521,12 @@ impl ChatId {
if visibility == ChatVisibility::Archived {
transaction.execute(
"UPDATE msgs SET state=? WHERE chat_id=? AND state=?;",
paramsv![MessageState::InNoticed, self, MessageState::InFresh],
(MessageState::InNoticed, self, MessageState::InFresh),
)?;
}
transaction.execute(
"UPDATE chats SET archived=? WHERE id=?;",
paramsv![visibility, self],
(visibility, self),
)?;
Ok(())
})
@@ -558,7 +555,7 @@ impl ChatId {
.execute(
"UPDATE chats SET archived=0 WHERE id=? AND archived=1 \
AND NOT(muted_until=-1 OR muted_until>?)",
paramsv![self, time()],
(self, time()),
)
.await?;
return Ok(());
@@ -576,7 +573,7 @@ impl ChatId {
WHERE state=?
AND hidden=0
AND chat_id=?",
paramsv![MessageState::InFresh, self],
(MessageState::InFresh, self),
)
.await?;
if unread_cnt == 1 {
@@ -587,7 +584,7 @@ impl ChatId {
}
context
.sql
.execute("UPDATE chats SET archived=0 WHERE id=?", paramsv![self])
.execute("UPDATE chats SET archived=0 WHERE id=?", (self,))
.await?;
Ok(())
}
@@ -616,26 +613,23 @@ impl ChatId {
.sql
.execute(
"DELETE FROM msgs_mdns WHERE msg_id IN (SELECT id FROM msgs WHERE chat_id=?);",
paramsv![self],
(self,),
)
.await?;
context
.sql
.execute("DELETE FROM msgs WHERE chat_id=?;", paramsv![self])
.execute("DELETE FROM msgs WHERE chat_id=?;", (self,))
.await?;
context
.sql
.execute(
"DELETE FROM chats_contacts WHERE chat_id=?;",
paramsv![self],
)
.execute("DELETE FROM chats_contacts WHERE chat_id=?;", (self,))
.await?;
context
.sql
.execute("DELETE FROM chats WHERE id=?;", paramsv![self])
.execute("DELETE FROM chats WHERE id=?;", (self,))
.await?;
context.emit_msgs_changed_without_ids();
@@ -691,7 +685,7 @@ impl ChatId {
.sql
.query_get_value(
"SELECT id FROM msgs WHERE chat_id=? AND state=?;",
paramsv![self, MessageState::OutDraft],
(self, MessageState::OutDraft),
)
.await?;
Ok(msg_id)
@@ -773,14 +767,14 @@ impl ChatId {
"UPDATE msgs
SET timestamp=?,type=?,txt=?, param=?,mime_in_reply_to=?
WHERE id=?;",
paramsv![
(
time(),
msg.viewtype,
msg.text.as_deref().unwrap_or(""),
msg.param.to_string(),
msg.in_reply_to.as_deref().unwrap_or_default(),
msg.id
],
msg.id,
),
)
.await?;
return Ok(true);
@@ -804,7 +798,7 @@ impl ChatId {
hidden,
mime_in_reply_to)
VALUES (?,?,?, ?,?,?,?,?,?);",
paramsv![
(
self,
ContactId::SELF,
time(),
@@ -814,7 +808,7 @@ impl ChatId {
msg.param.to_string(),
1,
msg.in_reply_to.as_deref().unwrap_or_default(),
],
),
)
.await?;
msg.id = MsgId::new(row_id.try_into()?);
@@ -827,7 +821,7 @@ impl ChatId {
.sql
.count(
"SELECT COUNT(*) FROM msgs WHERE hidden=0 AND chat_id=?",
paramsv![self],
(self,),
)
.await?;
Ok(count)
@@ -870,7 +864,7 @@ impl ChatId {
WHERE state=?
AND hidden=0
AND chat_id=?;",
paramsv![MessageState::InFresh, self],
(MessageState::InFresh, self),
)
.await?
};
@@ -880,7 +874,7 @@ impl ChatId {
pub(crate) async fn get_param(self, context: &Context) -> Result<Params> {
let res: Option<String> = context
.sql
.query_get_value("SELECT param FROM chats WHERE id=?", paramsv![self])
.query_get_value("SELECT param FROM chats WHERE id=?", (self,))
.await?;
Ok(res
.map(|s| s.parse().unwrap_or_default())
@@ -925,13 +919,13 @@ impl ChatId {
let row = sql
.query_row_optional(
&query,
paramsv![
(
self,
MessageState::OutPreparing,
MessageState::OutDraft,
MessageState::OutPending,
MessageState::OutFailed
],
MessageState::OutFailed,
),
f,
)
.await?;
@@ -1053,10 +1047,7 @@ impl ChatId {
pub async fn get_gossiped_timestamp(self, context: &Context) -> Result<i64> {
let timestamp: Option<i64> = context
.sql
.query_get_value(
"SELECT gossiped_timestamp FROM chats WHERE id=?;",
paramsv![self],
)
.query_get_value("SELECT gossiped_timestamp FROM chats WHERE id=?;", (self,))
.await?;
Ok(timestamp.unwrap_or_default())
}
@@ -1079,7 +1070,7 @@ impl ChatId {
.sql
.execute(
"UPDATE chats SET gossiped_timestamp=? WHERE id=?;",
paramsv![timestamp, self],
(timestamp, self),
)
.await?;
@@ -1175,7 +1166,7 @@ impl Chat {
c.blocked, c.locations_send_until, c.muted_until, c.protected
FROM chats c
WHERE c.id=?;",
paramsv![chat_id],
(chat_id,),
|row| {
let c = Chat {
id: chat_id,
@@ -1289,7 +1280,7 @@ impl Chat {
.sql
.execute(
"UPDATE chats SET param=? WHERE id=?",
paramsv![self.param.to_string(), self.id],
(self.param.to_string(), self.id),
)
.await?;
Ok(())
@@ -1471,7 +1462,7 @@ impl Chat {
.sql
.query_get_value(
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
paramsv![self.id],
(self.id,),
)
.await?
{
@@ -1552,13 +1543,13 @@ impl Chat {
"INSERT INTO locations \
(timestamp,from_id,chat_id, latitude,longitude,independent)\
VALUES (?,?,?, ?,?,1);",
paramsv![
(
timestamp,
ContactId::SELF,
self.id,
msg.param.get_float(Param::SetLatitude).unwrap_or_default(),
msg.param.get_float(Param::SetLongitude).unwrap_or_default(),
],
),
)
.await
{
@@ -1604,7 +1595,7 @@ impl Chat {
mime_headers=?, mime_compressed=1, location_id=?, ephemeral_timer=?,
ephemeral_timestamp=?
WHERE id=?;",
paramsv![
params_slice![
new_rfc724_mid,
self.id,
ContactId::SELF,
@@ -1653,7 +1644,7 @@ impl Chat {
ephemeral_timer,
ephemeral_timestamp)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1,?,?,?);",
paramsv![
params_slice![
new_rfc724_mid,
self.id,
ContactId::SELF,
@@ -1864,7 +1855,7 @@ async fn update_special_chat_name(
.sql
.execute(
"UPDATE chats SET name=? WHERE id=? AND name!=?",
paramsv![name, chat_id, name],
(&name, chat_id, &name),
)
.await?;
}
@@ -1927,7 +1918,7 @@ impl ChatIdBlocked {
WHERE c.type=100 -- 100 = Chattype::Single
AND c.id>9 -- 9 = DC_CHAT_ID_LAST_SPECIAL
AND j.contact_id=?;",
paramsv![contact_id],
(contact_id,),
|row| {
let id: ChatId = row.get(0)?;
let blocked: Blocked = row.get(1)?;
@@ -1978,13 +1969,13 @@ impl ChatIdBlocked {
"INSERT INTO chats
(type, name, param, blocked, created_timestamp)
VALUES(?, ?, ?, ?, ?)",
params![
(
Chattype::Single,
chat_name,
params.to_string(),
create_blocked as u8,
create_smeared_timestamp(context)
],
create_smeared_timestamp(context),
),
)?;
let chat_id = ChatId::new(
transaction
@@ -1997,7 +1988,7 @@ impl ChatIdBlocked {
"INSERT INTO chats_contacts
(chat_id, contact_id)
VALUES((SELECT last_insert_rowid()), ?)",
params![contact_id],
(contact_id,),
)?;
Ok(chat_id)
@@ -2157,7 +2148,7 @@ pub async fn is_contact_in_chat(
.sql
.exists(
"SELECT COUNT(*) FROM chats_contacts WHERE chat_id=? AND contact_id=?;",
paramsv![chat_id, contact_id],
(chat_id, contact_id),
)
.await?;
Ok(exists)
@@ -2378,12 +2369,12 @@ async fn create_send_msg_job(context: &Context, msg_id: MsgId) -> Result<Option<
.insert(
"INSERT INTO smtp (rfc724_mid, recipients, mime, msg_id)
VALUES (?1, ?2, ?3, ?4)",
paramsv![
(
&rendered_msg.rfc724_mid,
recipients,
&rendered_msg.message,
msg_id
],
msg_id,
),
)
.await?;
Ok(Some(row_id))
@@ -2549,7 +2540,7 @@ pub async fn get_chat_msgs_ex(
OR m.from_id == ?
OR m.to_id == ?
);",
paramsv![chat_id, ContactId::INFO, ContactId::INFO],
(chat_id, ContactId::INFO, ContactId::INFO),
process_row,
process_rows,
)
@@ -2562,7 +2553,7 @@ pub async fn get_chat_msgs_ex(
FROM msgs m
WHERE m.chat_id=?
AND m.hidden=0;",
paramsv![chat_id],
(chat_id,),
process_row,
process_rows,
)
@@ -2580,7 +2571,7 @@ pub(crate) async fn marknoticed_chat_if_older_than(
.sql
.query_get_value(
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=?",
paramsv![chat_id],
(chat_id,),
)
.await?
{
@@ -2630,7 +2621,7 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<()>
.sql
.exists(
"SELECT COUNT(*) FROM msgs WHERE state=? AND hidden=0 AND chat_id=?;",
paramsv![MessageState::InFresh, chat_id],
(MessageState::InFresh, chat_id),
)
.await?;
if !exists {
@@ -2645,7 +2636,7 @@ pub async fn marknoticed_chat(context: &Context, chat_id: ChatId) -> Result<()>
WHERE state=?
AND hidden=0
AND chat_id=?;",
paramsv![MessageState::InNoticed, MessageState::InFresh, chat_id],
(MessageState::InNoticed, MessageState::InFresh, chat_id),
)
.await?;
}
@@ -2694,12 +2685,12 @@ pub(crate) async fn mark_old_messages_as_noticed(
AND hidden=0
AND chat_id=?
AND timestamp<=?;",
paramsv![
(
MessageState::InNoticed,
MessageState::InFresh,
msg.chat_id,
msg.sort_timestamp
],
msg.sort_timestamp,
),
)?;
if changed_rows > 0 {
changed_chats.push(msg.chat_id);
@@ -2747,7 +2738,7 @@ pub async fn get_chat_media(
AND (type=? OR type=? OR type=?)
AND hidden=0
ORDER BY timestamp, id;",
paramsv![
(
chat_id.is_none(),
chat_id.unwrap_or_else(|| ChatId::new(0)),
DC_CHAT_ID_TRASH,
@@ -2762,7 +2753,7 @@ pub async fn get_chat_media(
} else {
msg_type
},
],
),
|row| row.get::<_, MsgId>(0),
|ids| Ok(ids.flatten().collect()),
)
@@ -2840,7 +2831,7 @@ pub async fn get_chat_contacts(context: &Context, chat_id: ChatId) -> Result<Vec
ON c.id=cc.contact_id
WHERE cc.chat_id=?
ORDER BY c.id=1, c.last_seen DESC, c.id DESC;",
paramsv![chat_id],
(chat_id,),
|row| row.get::<_, ContactId>(0),
|ids| ids.collect::<Result<Vec<_>, _>>().map_err(Into::into),
)
@@ -2866,12 +2857,12 @@ pub async fn create_group_chat(
"INSERT INTO chats
(type, name, grpid, param, created_timestamp)
VALUES(?, ?, ?, \'U=1\', ?);",
paramsv![
(
Chattype::Group,
chat_name,
grpid,
create_smeared_timestamp(context),
],
),
)
.await?;
@@ -2904,7 +2895,7 @@ async fn find_unused_broadcast_list_name(context: &Context) -> Result<String> {
.sql
.exists(
"SELECT COUNT(*) FROM chats WHERE type=? AND name=?;",
paramsv![Chattype::Broadcast, better_name],
(Chattype::Broadcast, &better_name),
)
.await?
{
@@ -2924,12 +2915,12 @@ pub async fn create_broadcast_list(context: &Context) -> Result<ChatId> {
"INSERT INTO chats
(type, name, grpid, param, created_timestamp)
VALUES(?, ?, ?, \'U=1\', ?);",
paramsv![
(
Chattype::Broadcast,
chat_name,
grpid,
create_smeared_timestamp(context),
],
),
)
.await?;
let chat_id = ChatId::new(u32::try_from(row_id)?);
@@ -2950,7 +2941,7 @@ pub(crate) async fn add_to_chat_contacts_table(
for contact_id in contact_ids {
transaction.execute(
"INSERT OR IGNORE INTO chats_contacts (chat_id, contact_id) VALUES(?, ?)",
paramsv![chat_id, contact_id],
(chat_id, contact_id),
)?;
}
Ok(())
@@ -2970,7 +2961,7 @@ pub(crate) async fn remove_from_chat_contacts_table(
.sql
.execute(
"DELETE FROM chats_contacts WHERE chat_id=? AND contact_id=?",
paramsv![chat_id, contact_id],
(chat_id, contact_id),
)
.await?;
Ok(())
@@ -3088,7 +3079,7 @@ pub(crate) async fn shall_attach_selfavatar(context: &Context, chat_id: ChatId)
FROM chats_contacts cc
LEFT JOIN contacts c ON c.id=cc.contact_id
WHERE cc.chat_id=? AND cc.contact_id!=?;",
paramsv![chat_id, ContactId::SELF],
(chat_id, ContactId::SELF),
|row| Ok(row.get::<_, i64>(0)),
|rows| {
let mut needs_attach = false;
@@ -3161,7 +3152,7 @@ pub async fn set_muted(context: &Context, chat_id: ChatId, duration: MuteDuratio
.sql
.execute(
"UPDATE chats SET muted_until=? WHERE id=?;",
paramsv![duration, chat_id],
(duration, chat_id),
)
.await
.context(format!("Failed to set mute duration for {chat_id}"))?;
@@ -3248,10 +3239,7 @@ async fn set_group_explicitly_left(context: &Context, grpid: &str) -> Result<()>
if !is_group_explicitly_left(context, grpid).await? {
context
.sql
.execute(
"INSERT INTO leftgrps (grpid) VALUES(?);",
paramsv![grpid.to_string()],
)
.execute("INSERT INTO leftgrps (grpid) VALUES(?);", (grpid,))
.await?;
}
@@ -3261,10 +3249,7 @@ async fn set_group_explicitly_left(context: &Context, grpid: &str) -> Result<()>
pub(crate) async fn is_group_explicitly_left(context: &Context, grpid: &str) -> Result<bool> {
let exists = context
.sql
.exists(
"SELECT COUNT(*) FROM leftgrps WHERE grpid=?;",
paramsv![grpid],
)
.exists("SELECT COUNT(*) FROM leftgrps WHERE grpid=?;", (grpid,))
.await?;
Ok(exists)
}
@@ -3296,7 +3281,7 @@ pub async fn set_chat_name(context: &Context, chat_id: ChatId, new_name: &str) -
.sql
.execute(
"UPDATE chats SET name=? WHERE id=?;",
paramsv![new_name.to_string(), chat_id],
(new_name.to_string(), chat_id),
)
.await?;
if chat.is_promoted()
@@ -3549,7 +3534,7 @@ pub(crate) async fn get_chat_id_by_grpid(
.sql
.query_row_optional(
"SELECT id, blocked, protected FROM chats WHERE grpid=?;",
paramsv![grpid],
(grpid,),
|row| {
let chat_id = row.get::<_, ChatId>(0)?;
@@ -3603,7 +3588,7 @@ pub async fn add_device_msg_with_importance(
.sql
.query_get_value(
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=?",
paramsv![chat_id],
(chat_id,),
)
.await?
{
@@ -3628,7 +3613,7 @@ pub async fn add_device_msg_with_importance(
param,
rfc724_mid)
VALUES (?,?,?,?,?,?,?,?,?,?,?);",
paramsv![
(
chat_id,
ContactId::DEVICE,
ContactId::SELF,
@@ -3640,7 +3625,7 @@ pub async fn add_device_msg_with_importance(
msg.text.as_ref().cloned().unwrap_or_default(),
msg.param.to_string(),
rfc724_mid,
],
),
)
.await?;
@@ -3653,10 +3638,7 @@ pub async fn add_device_msg_with_importance(
if let Some(label) = label {
context
.sql
.execute(
"INSERT INTO devmsglabels (label) VALUES (?);",
paramsv![label.to_string()],
)
.execute("INSERT INTO devmsglabels (label) VALUES (?);", (label,))
.await?;
}
@@ -3683,7 +3665,7 @@ pub async fn was_device_msg_ever_added(context: &Context, label: &str) -> Result
.sql
.exists(
"SELECT COUNT(label) FROM devmsglabels WHERE label=?",
paramsv![label],
(label,),
)
.await?;
@@ -3700,10 +3682,7 @@ pub async fn was_device_msg_ever_added(context: &Context, label: &str) -> Result
pub(crate) async fn delete_and_reset_all_device_msgs(context: &Context) -> Result<()> {
context
.sql
.execute(
"DELETE FROM msgs WHERE from_id=?;",
paramsv![ContactId::DEVICE],
)
.execute("DELETE FROM msgs WHERE from_id=?;", (ContactId::DEVICE,))
.await?;
context.sql.execute("DELETE FROM devmsglabels;", ()).await?;
@@ -3746,7 +3725,7 @@ pub(crate) async fn add_info_msg_with_cmd(
context.sql.insert(
"INSERT INTO msgs (chat_id,from_id,to_id,timestamp,timestamp_sent,timestamp_rcvd,type,state,txt,rfc724_mid,ephemeral_timer, param,mime_in_reply_to)
VALUES (?,?,?, ?,?,?,?,?, ?,?,?, ?,?);",
paramsv![
(
chat_id,
from_id.unwrap_or(ContactId::INFO),
ContactId::INFO,
@@ -3760,7 +3739,7 @@ pub(crate) async fn add_info_msg_with_cmd(
ephemeral_timer,
param.to_string(),
parent.map(|msg|msg.rfc724_mid.clone()).unwrap_or_default()
]
)
).await?;
let msg_id = MsgId::new(row_id.try_into()?);
@@ -3800,7 +3779,7 @@ pub(crate) async fn update_msg_text_and_timestamp(
.sql
.execute(
"UPDATE msgs SET txt=?, timestamp=? WHERE id=?;",
paramsv![text, timestamp, msg_id],
(text, timestamp, msg_id),
)
.await?;
context.emit_msgs_changed(chat_id, msg_id);

View File

@@ -137,7 +137,7 @@ impl Chatlist {
AND c.id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?2)
GROUP BY c.id
ORDER BY c.archived=?3 DESC, IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
paramsv![MessageState::OutDraft, query_contact_id, ChatVisibility::Pinned],
(MessageState::OutDraft, query_contact_id, ChatVisibility::Pinned),
process_row,
process_rows,
).await?
@@ -164,7 +164,7 @@ impl Chatlist {
AND c.archived=1
GROUP BY c.id
ORDER BY IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
paramsv![MessageState::OutDraft],
(MessageState::OutDraft,),
process_row,
process_rows,
)
@@ -198,7 +198,7 @@ impl Chatlist {
AND c.name LIKE ?3
GROUP BY c.id
ORDER BY IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
paramsv![MessageState::OutDraft, skip_id, str_like_cmd],
(MessageState::OutDraft, skip_id, str_like_cmd),
process_row,
process_rows,
)
@@ -228,7 +228,7 @@ impl Chatlist {
AND NOT c.archived=?4
GROUP BY c.id
ORDER BY c.id=?5 DESC, c.archived=?6 DESC, IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;",
paramsv![MessageState::OutDraft, skip_id, flag_for_forwarding, ChatVisibility::Archived, sort_id_up, ChatVisibility::Pinned],
(MessageState::OutDraft, skip_id, flag_for_forwarding, ChatVisibility::Archived, sort_id_up, ChatVisibility::Pinned),
process_row,
process_rows,
).await?;
@@ -356,7 +356,7 @@ pub async fn get_archived_cnt(context: &Context) -> Result<usize> {
.sql
.count(
"SELECT COUNT(*) FROM chats WHERE blocked!=? AND archived=?;",
paramsv![Blocked::Yes, ChatVisibility::Archived],
(Blocked::Yes, ChatVisibility::Archived),
)
.await?;
Ok(count)

View File

@@ -347,7 +347,7 @@ impl Contact {
c.authname, c.param, c.status
FROM contacts c
WHERE c.id=?;",
paramsv![contact_id],
(contact_id,),
|row| {
let name: String = row.get(0)?;
let addr: String = row.get(1)?;
@@ -460,7 +460,7 @@ impl Contact {
.sql
.execute(
"UPDATE msgs SET state=? WHERE from_id=? AND state=?;",
paramsv![MessageState::InNoticed, id, MessageState::InFresh],
(MessageState::InNoticed, id, MessageState::InFresh),
)
.await?;
Ok(())
@@ -493,7 +493,7 @@ impl Contact {
"SELECT id FROM contacts \
WHERE addr=?1 COLLATE NOCASE \
AND id>?2 AND origin>=?3 AND blocked=0;",
paramsv![addr_normalized, ContactId::LAST_SPECIAL, min_origin as u32,],
(&addr_normalized, ContactId::LAST_SPECIAL, min_origin as u32),
)
.await?;
Ok(id)
@@ -608,7 +608,7 @@ impl Contact {
transaction
.execute(
"UPDATE contacts SET name=?, addr=?, origin=?, authname=? WHERE id=?;",
paramsv![
(
new_name,
if update_addr {
addr.to_string()
@@ -626,7 +626,7 @@ impl Contact {
row_authname
},
row_id
],
),
)?;
if update_name || update_authname {
@@ -634,7 +634,7 @@ impl Contact {
// This is one of the few duplicated data, however, getting the chat list is easier this way.
let chat_id: Option<ChatId> = transaction.query_row(
"SELECT id FROM chats WHERE type=? AND id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?)",
params![Chattype::Single, isize::try_from(row_id)?],
(Chattype::Single, isize::try_from(row_id)?),
|row| {
let chat_id: ChatId = row.get(0)?;
Ok(chat_id)
@@ -648,7 +648,7 @@ impl Contact {
"SELECT addr, name, authname
FROM contacts
WHERE id=?",
params![contact_id],
(contact_id,),
|row| {
let addr: String = row.get(0)?;
let name: String = row.get(1)?;
@@ -666,7 +666,7 @@ impl Contact {
let count = transaction.execute(
"UPDATE chats SET name=?1 WHERE id=?2 AND name!=?1",
params![chat_name, chat_id])?;
(chat_name, chat_id))?;
if count > 0 {
// Chat name updated
@@ -684,7 +684,7 @@ impl Contact {
.execute(
"INSERT INTO contacts (name, addr, origin, authname)
VALUES (?, ?, ?, ?);",
params![
(
if update_name {
name.to_string()
} else {
@@ -697,7 +697,7 @@ impl Contact {
} else {
"".to_string()
}
],
),
)?;
sth_modified = Modifier::Created;
@@ -798,12 +798,12 @@ impl Contact {
ORDER BY c.last_seen DESC, c.id DESC;",
sql::repeat_vars(self_addrs.len())
),
rusqlite::params_from_iter(params_iter(&self_addrs).chain(params_iterv![
rusqlite::params_from_iter(params_iter(&self_addrs).chain(params_slice![
ContactId::LAST_SPECIAL,
Origin::IncomingReplyTo,
s3str_like_cmd,
s3str_like_cmd,
if flag_verified_only { 0i32 } else { 1i32 },
if flag_verified_only { 0i32 } else { 1i32 }
])),
|row| row.get::<_, ContactId>(0),
|ids| {
@@ -850,7 +850,7 @@ impl Contact {
ORDER BY last_seen DESC, id DESC;",
sql::repeat_vars(self_addrs.len())
),
rusqlite::params_from_iter(params_iter(&self_addrs).chain(params_iterv![
rusqlite::params_from_iter(params_iter(&self_addrs).chain(params_slice![
ContactId::LAST_SPECIAL,
Origin::IncomingReplyTo
])),
@@ -883,7 +883,7 @@ impl Contact {
.transaction(move |transaction| {
let mut stmt = transaction
.prepare("SELECT name, grpid FROM chats WHERE type=? AND blocked=?")?;
let rows = stmt.query_map(params![Chattype::Mailinglist, Blocked::Yes], |row| {
let rows = stmt.query_map((Chattype::Mailinglist, Blocked::Yes), |row| {
let name: String = row.get(0)?;
let grpid: String = row.get(1)?;
Ok((name, grpid))
@@ -905,7 +905,7 @@ impl Contact {
// Always do an update in case the blocking is reset or name is changed.
transaction.execute(
"UPDATE contacts SET name=?, origin=?, blocked=1 WHERE addr=?",
params![&name, Origin::MailinglistAddress, &grpid],
(&name, Origin::MailinglistAddress, &grpid),
)?;
}
Ok(())
@@ -920,7 +920,7 @@ impl Contact {
.sql
.count(
"SELECT COUNT(*) FROM contacts WHERE id>? AND blocked!=0",
paramsv![ContactId::LAST_SPECIAL],
(ContactId::LAST_SPECIAL,),
)
.await?;
Ok(count)
@@ -936,7 +936,7 @@ impl Contact {
.sql
.query_map(
"SELECT id FROM contacts WHERE id>? AND blocked!=0 ORDER BY last_seen DESC, id DESC;",
paramsv![ContactId::LAST_SPECIAL],
(ContactId::LAST_SPECIAL,),
|row| row.get::<_, ContactId>(0),
|ids| {
ids.collect::<std::result::Result<Vec<_>, _>>()
@@ -1030,12 +1030,12 @@ impl Contact {
let deleted_contacts = transaction.execute(
"DELETE FROM contacts WHERE id=?
AND (SELECT COUNT(*) FROM chats_contacts WHERE contact_id=?)=0;",
paramsv![contact_id, contact_id],
(contact_id, contact_id),
)?;
if deleted_contacts == 0 {
transaction.execute(
"UPDATE contacts SET origin=? WHERE id=?;",
paramsv![Origin::Hidden, contact_id],
(Origin::Hidden, contact_id),
)?;
}
Ok(())
@@ -1063,7 +1063,7 @@ impl Contact {
.sql
.execute(
"UPDATE contacts SET param=? WHERE id=?",
paramsv![self.param.to_string(), self.id],
(self.param.to_string(), self.id),
)
.await?;
Ok(())
@@ -1075,7 +1075,7 @@ impl Contact {
.sql
.execute(
"UPDATE contacts SET status=? WHERE id=?",
paramsv![self.status, self.id],
(&self.status, self.id),
)
.await?;
Ok(())
@@ -1233,7 +1233,7 @@ impl Contact {
.sql
.count(
"SELECT COUNT(*) FROM contacts WHERE id>?;",
paramsv![ContactId::LAST_SPECIAL],
(ContactId::LAST_SPECIAL,),
)
.await?;
Ok(count)
@@ -1247,10 +1247,7 @@ impl Contact {
let exists = context
.sql
.exists(
"SELECT COUNT(*) FROM contacts WHERE id=?;",
paramsv![contact_id],
)
.exists("SELECT COUNT(*) FROM contacts WHERE id=?;", (contact_id,))
.await?;
Ok(exists)
}
@@ -1265,7 +1262,7 @@ impl Contact {
.sql
.execute(
"UPDATE contacts SET origin=? WHERE id=? AND origin<?;",
paramsv![origin, contact_id, origin],
(origin, contact_id, origin),
)
.await?;
Ok(())
@@ -1329,7 +1326,7 @@ async fn set_block_contact(
.sql
.execute(
"UPDATE contacts SET blocked=? WHERE id=?;",
paramsv![i32::from(new_blocking), contact_id],
(i32::from(new_blocking), contact_id),
)
.await?;
@@ -1348,7 +1345,7 @@ WHERE type=? AND id IN (
SELECT chat_id FROM chats_contacts WHERE contact_id=?
);
"#,
paramsv![new_blocking, Chattype::Single, contact_id],
(new_blocking, Chattype::Single, contact_id),
)
.await
.is_ok()
@@ -1465,7 +1462,7 @@ pub(crate) async fn update_last_seen(
.sql
.execute(
"UPDATE contacts SET last_seen = ?1 WHERE last_seen < ?1 AND id = ?2",
paramsv![timestamp, contact_id],
(timestamp, contact_id),
)
.await?
> 0
@@ -1580,7 +1577,7 @@ impl RecentlySeenLoop {
.query_map(
"SELECT id, last_seen FROM contacts
WHERE last_seen > ?",
paramsv![time() - SEEN_RECENTLY_SECONDS],
(time() - SEEN_RECENTLY_SECONDS,),
|row| {
let contact_id: ContactId = row.get("id")?;
let last_seen: i64 = row.get("last_seen")?;

View File

@@ -799,7 +799,7 @@ impl Context {
" AND NOT(c.muted_until=-1 OR c.muted_until>?)",
" ORDER BY m.timestamp DESC,m.id DESC;"
),
paramsv![MessageState::InFresh, time()],
(MessageState::InFresh, time()),
|row| row.get::<_, MsgId>(0),
|rows| {
let mut list = Vec::new();
@@ -824,24 +824,10 @@ impl Context {
}
let str_like_in_text = format!("%{real_query}%");
let do_query = |query, params| {
self.sql.query_map(
query,
params,
|row| row.get::<_, MsgId>("id"),
|rows| {
let mut ret = Vec::new();
for id in rows {
ret.push(id?);
}
Ok(ret)
},
)
};
let list = if let Some(chat_id) = chat_id {
do_query(
"SELECT m.id AS id
self.sql
.query_map(
"SELECT m.id AS id
FROM msgs m
LEFT JOIN contacts ct
ON m.from_id=ct.id
@@ -850,9 +836,17 @@ impl Context {
AND ct.blocked=0
AND txt LIKE ?
ORDER BY m.timestamp,m.id;",
paramsv![chat_id, str_like_in_text],
)
.await?
(chat_id, str_like_in_text),
|row| row.get::<_, MsgId>("id"),
|rows| {
let mut ret = Vec::new();
for id in rows {
ret.push(id?);
}
Ok(ret)
},
)
.await?
} else {
// For performance reasons results are sorted only by `id`, that is in the order of
// message reception.
@@ -864,8 +858,9 @@ impl Context {
// of unwanted results that are discarded moments later, we added `LIMIT 1000`.
// According to some tests, this limit speeds up eg. 2 character searches by factor 10.
// The limit is documented and UI may add a hint when getting 1000 results.
do_query(
"SELECT m.id AS id
self.sql
.query_map(
"SELECT m.id AS id
FROM msgs m
LEFT JOIN contacts ct
ON m.from_id=ct.id
@@ -877,9 +872,17 @@ impl Context {
AND ct.blocked=0
AND m.txt LIKE ?
ORDER BY m.id DESC LIMIT 1000",
paramsv![str_like_in_text],
)
.await?
(str_like_in_text,),
|row| row.get::<_, MsgId>("id"),
|rows| {
let mut ret = Vec::new();
for id in rows {
ret.push(id?);
}
Ok(ret)
},
)
.await?
};
Ok(list)
@@ -1089,7 +1092,7 @@ mod tests {
t.sql
.execute(
"UPDATE chats SET muted_until=? WHERE id=?;",
paramsv![time() - 3600, bob.id],
(time() - 3600, bob.id),
)
.await
.unwrap();
@@ -1106,10 +1109,7 @@ mod tests {
// to test get_fresh_msgs() with invalid mute_until (everything < -1),
// that results in "muted forever" by definition.
t.sql
.execute(
"UPDATE chats SET muted_until=-2 WHERE id=?;",
paramsv![bob.id],
)
.execute("UPDATE chats SET muted_until=-2 WHERE id=?;", (bob.id,))
.await
.unwrap();
let bob = Chat::load_from_db(&t, bob.id).await.unwrap();

View File

@@ -101,7 +101,7 @@ impl MsgId {
.sql
.execute(
"UPDATE msgs SET download_state=? WHERE id=?;",
paramsv![download_state, self],
(download_state, self),
)
.await?;
context.emit_event(EventType::MsgsChanged {
@@ -134,7 +134,7 @@ impl Job {
.sql
.query_row_optional(
"SELECT uid, folder FROM imap WHERE rfc724_mid=? AND target=folder",
paramsv![msg.rfc724_mid],
(&msg.rfc724_mid,),
|row| {
let server_uid: u32 = row.get(0)?;
let server_folder: String = row.get(1)?;

View File

@@ -174,10 +174,7 @@ impl ChatId {
pub async fn get_ephemeral_timer(self, context: &Context) -> Result<Timer> {
let timer = context
.sql
.query_get_value(
"SELECT ephemeral_timer FROM chats WHERE id=?;",
paramsv![self],
)
.query_get_value("SELECT ephemeral_timer FROM chats WHERE id=?;", (self,))
.await?;
Ok(timer.unwrap_or_default())
}
@@ -199,7 +196,7 @@ impl ChatId {
"UPDATE chats
SET ephemeral_timer=?
WHERE id=?;",
paramsv![timer, self],
(timer, self),
)
.await?;
@@ -291,10 +288,7 @@ impl MsgId {
pub(crate) async fn ephemeral_timer(self, context: &Context) -> Result<Timer> {
let res = match context
.sql
.query_get_value(
"SELECT ephemeral_timer FROM msgs WHERE id=?",
paramsv![self],
)
.query_get_value("SELECT ephemeral_timer FROM msgs WHERE id=?", (self,))
.await?
{
None | Some(0) => Timer::Disabled,
@@ -314,7 +308,7 @@ impl MsgId {
"UPDATE msgs SET ephemeral_timestamp = ? \
WHERE (ephemeral_timestamp == 0 OR ephemeral_timestamp > ?) \
AND id = ?",
paramsv![ephemeral_timestamp, ephemeral_timestamp, self],
(ephemeral_timestamp, ephemeral_timestamp, self),
)
.await?;
context.scheduler.interrupt_ephemeral_task().await;
@@ -338,8 +332,8 @@ pub(crate) async fn start_ephemeral_timers_msgids(
sql::repeat_vars(msg_ids.len())
),
rusqlite::params_from_iter(
std::iter::once(&now as &dyn crate::ToSql)
.chain(std::iter::once(&now as &dyn crate::ToSql))
std::iter::once(&now as &dyn crate::sql::ToSql)
.chain(std::iter::once(&now as &dyn crate::sql::ToSql))
.chain(params_iter(msg_ids)),
),
)
@@ -369,7 +363,7 @@ WHERE
AND ephemeral_timestamp <= ?
AND chat_id != ?
"#,
paramsv![now, DC_CHAT_ID_TRASH],
(now, DC_CHAT_ID_TRASH),
|row| {
let id: MsgId = row.get("id")?;
let chat_id: ChatId = row.get("chat_id")?;
@@ -402,12 +396,12 @@ WHERE
AND chat_id != ?
AND chat_id != ?
"#,
paramsv![
(
threshold_timestamp,
DC_CHAT_ID_LAST_SPECIAL,
self_chat_id,
device_chat_id
],
device_chat_id,
),
|row| {
let id: MsgId = row.get("id")?;
let chat_id: ChatId = row.get("chat_id")?;
@@ -449,7 +443,7 @@ pub(crate) async fn delete_expired_messages(context: &Context, now: i64) -> Resu
SET chat_id=?, txt='', subject='', txt_raw='',
mime_headers='', from_id=0, to_id=0, param=''
WHERE id=?",
params![DC_CHAT_ID_TRASH, msg_id],
(DC_CHAT_ID_TRASH, msg_id),
)?;
msgs_changed.push((chat_id, msg_id));
@@ -494,7 +488,7 @@ async fn next_delete_device_after_timestamp(context: &Context) -> Result<Option<
AND chat_id != ?
AND chat_id != ?;
"#,
paramsv![DC_CHAT_ID_TRASH, self_chat_id, device_chat_id],
(DC_CHAT_ID_TRASH, self_chat_id, device_chat_id),
)
.await?;
@@ -518,7 +512,7 @@ async fn next_expiration_timestamp(context: &Context) -> Option<i64> {
WHERE ephemeral_timestamp != 0
AND chat_id != ?;
"#,
paramsv![DC_CHAT_ID_TRASH], // Trash contains already deleted messages, skip them
(DC_CHAT_ID_TRASH,), // Trash contains already deleted messages, skip them
)
.await
{
@@ -605,12 +599,12 @@ pub(crate) async fn delete_expired_imap_messages(context: &Context) -> Result<()
(download_state != 0 AND timestamp < ?) OR
(ephemeral_timestamp != 0 AND ephemeral_timestamp <= ?))
)",
paramsv![
target,
(
&target,
threshold_timestamp,
threshold_timestamp_extended,
now,
],
),
)
.await?;
@@ -635,12 +629,12 @@ pub(crate) async fn start_ephemeral_timers(context: &Context) -> Result<()> {
WHERE ephemeral_timer > 0 \
AND ephemeral_timestamp = 0 \
AND state NOT IN (?, ?, ?)",
paramsv![
(
time(),
MessageState::InFresh,
MessageState::InNoticed,
MessageState::OutDraft
],
MessageState::OutDraft,
),
)
.await?;
@@ -1106,7 +1100,7 @@ mod tests {
assert!(msg.text.is_none_or_empty(), "{:?}", msg.text);
let rawtxt: Option<String> = t
.sql
.query_get_value("SELECT txt_raw FROM msgs WHERE id=?;", paramsv![msg_id])
.query_get_value("SELECT txt_raw FROM msgs WHERE id=?;", (msg_id,))
.await
.unwrap();
assert!(rawtxt.is_none_or_empty(), "{rawtxt:?}");
@@ -1131,13 +1125,13 @@ mod tests {
t.sql
.execute(
"INSERT INTO msgs (id, rfc724_mid, timestamp, ephemeral_timestamp) VALUES (?,?,?,?);",
paramsv![id, message_id, timestamp, ephemeral_timestamp],
(id, &message_id, timestamp, ephemeral_timestamp),
)
.await?;
t.sql
.execute(
"INSERT INTO imap (rfc724_mid, folder, uid, target) VALUES (?,'INBOX',?, 'INBOX');",
paramsv![message_id, id],
(&message_id, id),
)
.await?;
}
@@ -1148,7 +1142,7 @@ mod tests {
.sql
.count(
"SELECT COUNT(*) FROM imap WHERE target='' AND rfc724_mid=?",
paramsv![id.to_string()],
(id.to_string(),),
)
.await?,
1
@@ -1159,10 +1153,7 @@ mod tests {
async fn remove_uid(context: &Context, id: u32) -> Result<()> {
context
.sql
.execute(
"DELETE FROM imap WHERE rfc724_mid=?",
paramsv![id.to_string()],
)
.execute("DELETE FROM imap WHERE rfc724_mid=?", (id.to_string(),))
.await?;
Ok(())
}

View File

@@ -550,7 +550,7 @@ impl Imap {
context
.sql
.transaction(move |transaction| {
transaction.execute("DELETE FROM imap WHERE folder=?", params![folder])?;
transaction.execute("DELETE FROM imap WHERE folder=?", (folder,))?;
for (uid, (rfc724_mid, target)) in &msgs {
// This may detect previously undetected moved
// messages, so we update server_folder too.
@@ -560,7 +560,7 @@ impl Imap {
ON CONFLICT(folder, uid, uidvalidity)
DO UPDATE SET rfc724_mid=excluded.rfc724_mid,
target=excluded.target",
params![rfc724_mid, folder, uid, uid_validity, target],
(rfc724_mid, folder, uid, uid_validity, target),
)?;
}
Ok(())
@@ -676,7 +676,7 @@ impl Imap {
.sql
.execute(
"DELETE FROM imap WHERE folder=? AND uidvalidity!=?",
paramsv![folder, new_uid_validity],
(&folder, new_uid_validity),
)
.await?;
@@ -759,7 +759,7 @@ impl Imap {
ON CONFLICT(folder, uid, uidvalidity)
DO UPDATE SET rfc724_mid=excluded.rfc724_mid,
target=excluded.target",
paramsv![message_id, folder, uid, uid_validity, &target],
(&message_id, &folder, uid, uid_validity, &target),
)
.await?;
@@ -1050,7 +1050,7 @@ impl Session {
WHERE folder = ?
AND target != folder
ORDER BY target, uid",
paramsv![folder],
(folder,),
|row| {
let rowid: i64 = row.get(0)?;
let uid: u32 = row.get(1)?;
@@ -2168,7 +2168,7 @@ async fn mark_seen_by_uid(
AND uid=?3
LIMIT 1
)",
paramsv![&folder, uid_validity, uid],
(&folder, uid_validity, uid),
|row| {
let msg_id: MsgId = row.get(0)?;
let chat_id: ChatId = row.get(1)?;
@@ -2184,12 +2184,12 @@ async fn mark_seen_by_uid(
"UPDATE msgs SET state=?1
WHERE (state=?2 OR state=?3)
AND id=?4",
paramsv![
(
MessageState::InSeen,
MessageState::InFresh,
MessageState::InNoticed,
msg_id
],
msg_id,
),
)
.await
.with_context(|| format!("failed to update msg {msg_id} state"))?
@@ -2219,7 +2219,7 @@ pub(crate) async fn markseen_on_imap_table(context: &Context, message_id: &str)
.execute(
"INSERT OR IGNORE INTO imap_markseen (id)
SELECT id FROM imap WHERE rfc724_mid=?",
paramsv![message_id],
(message_id,),
)
.await?;
context
@@ -2239,7 +2239,7 @@ pub(crate) async fn set_uid_next(context: &Context, folder: &str, uid_next: u32)
.execute(
"INSERT INTO imap_sync (folder, uid_next) VALUES (?,?)
ON CONFLICT(folder) DO UPDATE SET uid_next=excluded.uid_next",
paramsv![folder, uid_next],
(folder, uid_next),
)
.await?;
Ok(())
@@ -2253,10 +2253,7 @@ pub(crate) async fn set_uid_next(context: &Context, folder: &str, uid_next: u32)
async fn get_uid_next(context: &Context, folder: &str) -> Result<u32> {
Ok(context
.sql
.query_get_value(
"SELECT uid_next FROM imap_sync WHERE folder=?;",
paramsv![folder],
)
.query_get_value("SELECT uid_next FROM imap_sync WHERE folder=?;", (folder,))
.await?
.unwrap_or(0))
}
@@ -2271,7 +2268,7 @@ pub(crate) async fn set_uidvalidity(
.execute(
"INSERT INTO imap_sync (folder, uidvalidity) VALUES (?,?)
ON CONFLICT(folder) DO UPDATE SET uidvalidity=excluded.uidvalidity",
paramsv![folder, uidvalidity],
(folder, uidvalidity),
)
.await?;
Ok(())
@@ -2282,7 +2279,7 @@ async fn get_uidvalidity(context: &Context, folder: &str) -> Result<u32> {
.sql
.query_get_value(
"SELECT uidvalidity FROM imap_sync WHERE folder=?;",
paramsv![folder],
(folder,),
)
.await?
.unwrap_or(0))
@@ -2294,7 +2291,7 @@ pub(crate) async fn set_modseq(context: &Context, folder: &str, modseq: u64) ->
.execute(
"INSERT INTO imap_sync (folder, modseq) VALUES (?,?)
ON CONFLICT(folder) DO UPDATE SET modseq=excluded.modseq",
paramsv![folder, modseq],
(folder, modseq),
)
.await?;
Ok(())
@@ -2303,10 +2300,7 @@ pub(crate) async fn set_modseq(context: &Context, folder: &str, modseq: u64) ->
async fn get_modseq(context: &Context, folder: &str) -> Result<u64> {
Ok(context
.sql
.query_get_value(
"SELECT modseq FROM imap_sync WHERE folder=?;",
paramsv![folder],
)
.query_get_value("SELECT modseq FROM imap_sync WHERE folder=?;", (folder,))
.await?
.unwrap_or(0))
}

View File

@@ -763,14 +763,11 @@ async fn export_database(context: &Context, dest: &Path, passphrase: String) ->
context
.sql
.call_write(|conn| {
conn.execute("VACUUM;", params![])
conn.execute("VACUUM;", ())
.map_err(|err| warn!(context, "Vacuum failed, exporting anyway {err}"))
.ok();
conn.execute(
"ATTACH DATABASE ? AS backup KEY ?",
paramsv![dest, passphrase],
)
.context("failed to attach backup database")?;
conn.execute("ATTACH DATABASE ? AS backup KEY ?", (dest, passphrase))
.context("failed to attach backup database")?;
let res = conn
.query_row("SELECT sqlcipher_export('backup')", [], |_row| Ok(()))
.context("failed to export to attached backup database");

View File

@@ -99,7 +99,7 @@ impl Job {
if self.job_id != 0 {
context
.sql
.execute("DELETE FROM jobs WHERE id=?;", paramsv![self.job_id as i32])
.execute("DELETE FROM jobs WHERE id=?;", (self.job_id as i32,))
.await?;
}
@@ -117,22 +117,22 @@ impl Job {
.sql
.execute(
"UPDATE jobs SET desired_timestamp=?, tries=? WHERE id=?;",
paramsv![
(
self.desired_timestamp,
i64::from(self.tries),
self.job_id as i32,
],
),
)
.await?;
} else {
context.sql.execute(
"INSERT INTO jobs (added_timestamp, action, foreign_id, desired_timestamp) VALUES (?,?,?,?);",
paramsv![
(
self.added_timestamp,
self.action,
self.foreign_id,
self.desired_timestamp
]
)
).await?;
}
@@ -277,7 +277,7 @@ WHERE desired_timestamp<=?
ORDER BY action DESC, added_timestamp
LIMIT 1;
"#;
params = paramsv![t];
params = vec![t];
} else {
// processing after call to dc_maybe_network():
// process _all_ pending jobs that failed before
@@ -289,13 +289,13 @@ WHERE tries>0
ORDER BY desired_timestamp, action DESC
LIMIT 1;
"#;
params = paramsv![];
params = vec![];
};
loop {
let job_res = context
.sql
.query_row_optional(query, params.clone(), |row| {
.query_row_optional(query, rusqlite::params_from_iter(params.clone()), |row| {
let job = Job {
job_id: row.get("id")?,
action: row.get("action")?,
@@ -318,12 +318,14 @@ LIMIT 1;
// TODO: improve by only doing a single query
let id = context
.sql
.query_row(query, params.clone(), |row| row.get::<_, i32>(0))
.query_row(query, rusqlite::params_from_iter(params.clone()), |row| {
row.get::<_, i32>(0)
})
.await
.context("failed to retrieve invalid job ID from the database")?;
context
.sql
.execute("DELETE FROM jobs WHERE id=?;", paramsv![id])
.execute("DELETE FROM jobs WHERE id=?;", (id,))
.await
.with_context(|| format!("failed to delete invalid job {id}"))?;
}
@@ -344,7 +346,7 @@ mod tests {
"INSERT INTO jobs
(added_timestamp, action, foreign_id, desired_timestamp)
VALUES (?, ?, ?, ?);",
paramsv![
(
now,
if valid {
Action::DownloadMsg as i32
@@ -352,8 +354,8 @@ mod tests {
-1
},
foreign_id,
now
],
now,
),
)
.await
.unwrap();

View File

@@ -100,7 +100,7 @@ impl DcKey for SignedPublicKey {
WHERE addr=?
AND is_default=1;
"#,
paramsv![addr],
(addr,),
|row| {
let bytes: Vec<u8> = row.get(0)?;
Ok(bytes)
@@ -240,7 +240,7 @@ pub(crate) async fn load_keypair(
WHERE addr=?1
AND is_default=1;
"#,
paramsv![addr],
(addr,),
|row| {
let pub_bytes: Vec<u8> = row.get(0)?;
let sec_bytes: Vec<u8> = row.get(1)?;
@@ -297,7 +297,7 @@ pub async fn store_self_keypair(
transaction
.execute(
"DELETE FROM keypairs WHERE public_key=? OR private_key=?;",
paramsv![public_key, secret_key],
(&public_key, &secret_key),
)
.context("failed to remove old use of key")?;
if default == KeyPairUse::Default {
@@ -317,7 +317,7 @@ pub async fn store_self_keypair(
.execute(
"INSERT INTO keypairs (addr, is_default, public_key, private_key, created)
VALUES (?,?,?,?,?);",
paramsv![addr, is_default, public_key, secret_key, t],
(addr, is_default, &public_key, &secret_key, t),
)
.context("failed to insert keypair")?;

View File

@@ -35,11 +35,6 @@ extern crate rusqlite;
#[macro_use]
extern crate strum_macros;
#[allow(missing_docs)]
pub trait ToSql: rusqlite::ToSql + Send + Sync {}
impl<T: rusqlite::ToSql + Send + Sync> ToSql for T {}
#[macro_use]
pub mod log;

View File

@@ -271,11 +271,11 @@ pub async fn send_locations_to_chat(
SET locations_send_begin=?, \
locations_send_until=? \
WHERE id=?",
paramsv![
(
if 0 != seconds { now } else { 0 },
if 0 != seconds { now + seconds } else { 0 },
chat_id,
],
),
)
.await?;
if 0 != seconds && !is_sending_locations_before {
@@ -310,7 +310,7 @@ pub async fn is_sending_locations_to_chat(
.sql
.exists(
"SELECT COUNT(id) FROM chats WHERE id=? AND locations_send_until>?;",
paramsv![chat_id, time()],
(chat_id, time()),
)
.await?
}
@@ -319,7 +319,7 @@ pub async fn is_sending_locations_to_chat(
.sql
.exists(
"SELECT COUNT(id) FROM chats WHERE locations_send_until>?;",
paramsv![time()],
(time(),),
)
.await?
}
@@ -338,7 +338,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
.sql
.query_map(
"SELECT id FROM chats WHERE locations_send_until>?;",
paramsv![time()],
(time(),),
|row| row.get::<_, i32>(0),
|chats| {
chats
@@ -352,14 +352,14 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64
if let Err(err) = context.sql.execute(
"INSERT INTO locations \
(latitude, longitude, accuracy, timestamp, chat_id, from_id) VALUES (?,?,?,?,?,?);",
paramsv![
(
latitude,
longitude,
accuracy,
time(),
chat_id,
ContactId::SELF,
]
)
).await {
warn!(context, "failed to store location {:#}", err);
} else {
@@ -404,14 +404,14 @@ pub async fn get_range(
AND (? OR l.from_id=?) \
AND (l.independent=1 OR (l.timestamp>=? AND l.timestamp<=?)) \
ORDER BY l.timestamp DESC, l.id DESC, msg_id DESC;",
paramsv![
(
disable_chat_id,
chat_id,
disable_contact_id,
contact_id as i32,
timestamp_from,
timestamp_to,
],
),
|row| {
let msg_id = row.get(6)?;
let txt: String = row.get(9)?;
@@ -471,7 +471,7 @@ pub async fn get_kml(context: &Context, chat_id: ChatId) -> Result<(String, u32)
let (locations_send_begin, locations_send_until, locations_last_sent) = context.sql.query_row(
"SELECT locations_send_begin, locations_send_until, locations_last_sent FROM chats WHERE id=?;",
paramsv![chat_id], |row| {
(chat_id,), |row| {
let send_begin: i64 = row.get(0)?;
let send_until: i64 = row.get(1)?;
let last_sent: i64 = row.get(2)?;
@@ -500,12 +500,12 @@ pub async fn get_kml(context: &Context, chat_id: ChatId) -> Result<(String, u32)
AND independent=0 \
GROUP BY timestamp \
ORDER BY timestamp;",
paramsv![
(
ContactId::SELF,
locations_send_begin,
locations_last_sent,
ContactId::SELF
],
),
|row| {
let location_id: i32 = row.get(0)?;
let latitude: f64 = row.get(1)?;
@@ -575,7 +575,7 @@ pub async fn set_kml_sent_timestamp(
.sql
.execute(
"UPDATE chats SET locations_last_sent=? WHERE id=?;",
paramsv![timestamp, chat_id],
(timestamp, chat_id),
)
.await?;
Ok(())
@@ -587,7 +587,7 @@ pub async fn set_msg_location_id(context: &Context, msg_id: MsgId, location_id:
.sql
.execute(
"UPDATE msgs SET location_id=? WHERE id=?;",
paramsv![location_id, msg_id],
(location_id, msg_id),
)
.await?;
@@ -629,10 +629,10 @@ pub(crate) async fn save(
.prepare_cached("SELECT id FROM locations WHERE timestamp=? AND from_id=?")?;
let mut stmt_insert = conn.prepare_cached(stmt_insert)?;
let exists = stmt_test.exists(paramsv![timestamp, contact_id])?;
let exists = stmt_test.exists((timestamp, contact_id))?;
if independent || !exists {
stmt_insert.execute(paramsv![
stmt_insert.execute((
timestamp,
contact_id,
chat_id,
@@ -640,7 +640,7 @@ pub(crate) async fn save(
longitude,
accuracy,
independent,
])?;
))?;
if timestamp > newest_timestamp {
// okay to drop, as we use cached prepared statements
@@ -729,7 +729,7 @@ async fn maybe_send_locations(context: &Context) -> Result<Option<u64>> {
AND timestamp>=? \
AND timestamp>? \
AND independent=0",
paramsv![ContactId::SELF, locations_send_begin, locations_last_sent,],
(ContactId::SELF, locations_send_begin, locations_last_sent),
)
.await?;
@@ -781,7 +781,7 @@ async fn maybe_send_locations(context: &Context) -> Result<Option<u64>> {
"UPDATE chats \
SET locations_send_begin=0, locations_send_until=0 \
WHERE id=?",
paramsv![chat_id],
(chat_id,),
)
.await
.context("failed to disable location streaming")?;

View File

@@ -77,7 +77,7 @@ impl MsgId {
pub async fn get_state(self, context: &Context) -> Result<MessageState> {
let result = context
.sql
.query_get_value("SELECT state FROM msgs WHERE id=?", paramsv![self])
.query_get_value("SELECT state FROM msgs WHERE id=?", (self,))
.await?
.unwrap_or_default();
Ok(result)
@@ -106,7 +106,7 @@ SET
param=''
WHERE id=?;
"#,
paramsv![chat_id, self],
(chat_id, self),
)
.await?;
@@ -119,22 +119,19 @@ WHERE id=?;
// sure they are not left while the message is deleted.
context
.sql
.execute("DELETE FROM smtp WHERE msg_id=?", paramsv![self])
.execute("DELETE FROM smtp WHERE msg_id=?", (self,))
.await?;
context
.sql
.execute("DELETE FROM msgs_mdns WHERE msg_id=?;", paramsv![self])
.execute("DELETE FROM msgs_mdns WHERE msg_id=?;", (self,))
.await?;
context
.sql
.execute(
"DELETE FROM msgs_status_updates WHERE msg_id=?;",
paramsv![self],
)
.execute("DELETE FROM msgs_status_updates WHERE msg_id=?;", (self,))
.await?;
context
.sql
.execute("DELETE FROM msgs WHERE id=?;", paramsv![self])
.execute("DELETE FROM msgs WHERE id=?;", (self,))
.await?;
Ok(())
}
@@ -143,7 +140,7 @@ WHERE id=?;
update_msg_state(context, self, MessageState::OutDelivered).await?;
let chat_id: ChatId = context
.sql
.query_get_value("SELECT chat_id FROM msgs WHERE id=?", paramsv![self])
.query_get_value("SELECT chat_id FROM msgs WHERE id=?", (self,))
.await?
.unwrap_or_default();
context.emit_event(EventType::MsgDelivered {
@@ -328,7 +325,7 @@ impl Message {
" FROM msgs m LEFT JOIN chats c ON c.id=m.chat_id",
" WHERE m.id=?;"
),
paramsv![id],
(id,),
|row| {
let text = match row.get_ref("txt")? {
rusqlite::types::ValueRef::Text(buf) => {
@@ -949,7 +946,7 @@ impl Message {
.sql
.execute(
"UPDATE msgs SET param=? WHERE id=?;",
paramsv![self.param.to_string(), self.id],
(self.param.to_string(), self.id),
)
.await?;
Ok(())
@@ -960,7 +957,7 @@ impl Message {
.sql
.execute(
"UPDATE msgs SET subject=? WHERE id=?;",
paramsv![self.subject, self.id],
(&self.subject, self.id),
)
.await?;
Ok(())
@@ -1094,7 +1091,7 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> Result<String> {
let msg = Message::load_from_db(context, msg_id).await?;
let rawtxt: Option<String> = context
.sql
.query_get_value("SELECT txt_raw FROM msgs WHERE id=?;", paramsv![msg_id])
.query_get_value("SELECT txt_raw FROM msgs WHERE id=?;", (msg_id,))
.await?;
let mut ret = String::new();
@@ -1144,7 +1141,7 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> Result<String> {
.sql
.query_map(
"SELECT contact_id, timestamp_sent FROM msgs_mdns WHERE msg_id=?;",
paramsv![msg_id],
(msg_id,),
|row| {
let contact_id: ContactId = row.get(0)?;
let ts: i64 = row.get(1)?;
@@ -1225,7 +1222,7 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> Result<String> {
.sql
.query_map(
"SELECT folder, uid FROM imap WHERE rfc724_mid=?",
paramsv![msg.rfc724_mid],
(msg.rfc724_mid,),
|row| {
let folder: String = row.get("folder")?;
let uid: u32 = row.get("uid")?;
@@ -1245,7 +1242,7 @@ pub async fn get_msg_info(context: &Context, msg_id: MsgId) -> Result<String> {
}
let hop_info: Option<String> = context
.sql
.query_get_value("SELECT hop_info FROM msgs WHERE id=?;", paramsv![msg_id])
.query_get_value("SELECT hop_info FROM msgs WHERE id=?;", (msg_id,))
.await?;
ret += "\n\n";
@@ -1353,7 +1350,7 @@ pub async fn get_mime_headers(context: &Context, msg_id: MsgId) -> Result<Vec<u8
.sql
.query_row(
"SELECT mime_headers, mime_compressed FROM msgs WHERE id=?",
paramsv![msg_id],
(msg_id,),
|row| {
let headers = sql::row_get_vec(row, 0)?;
let compressed: bool = row.get(1)?;
@@ -1378,7 +1375,7 @@ pub async fn get_mime_headers(context: &Context, msg_id: MsgId) -> Result<Vec<u8
"\
UPDATE msgs SET mime_headers=?, mime_compressed=1 \
WHERE id=? AND mime_headers!='' AND mime_compressed=0",
params![compressed, msg_id],
(compressed, msg_id),
) {
Ok(rows_updated) => ensure!(rows_updated <= 1),
Err(e) => {
@@ -1421,7 +1418,7 @@ pub async fn delete_msgs(context: &Context, msg_ids: &[MsgId]) -> Result<()> {
.sql
.execute(
"UPDATE imap SET target=? WHERE rfc724_mid=?",
paramsv![target, msg.rfc724_mid],
(target, msg.rfc724_mid),
)
.await?;
@@ -1459,7 +1456,7 @@ async fn delete_poi_location(context: &Context, location_id: u32) -> Result<()>
.sql
.execute(
"DELETE FROM locations WHERE independent = 1 AND id=?;",
paramsv![location_id as i32],
(location_id as i32,),
)
.await?;
Ok(())
@@ -1558,7 +1555,7 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
.sql
.execute(
"INSERT INTO smtp_mdns (msg_id, from_id, rfc724_mid) VALUES(?, ?, ?)",
paramsv![id, curr_from_id, curr_rfc724_mid],
(id, curr_from_id, curr_rfc724_mid),
)
.await
.context("failed to insert into smtp_mdns")?;
@@ -1586,10 +1583,7 @@ pub(crate) async fn update_msg_state(
) -> Result<()> {
context
.sql
.execute(
"UPDATE msgs SET state=? WHERE id=?;",
paramsv![state, msg_id],
)
.execute("UPDATE msgs SET state=? WHERE id=?;", (state, msg_id))
.await?;
Ok(())
}
@@ -1609,7 +1603,7 @@ pub(crate) async fn exists(context: &Context, msg_id: MsgId) -> Result<bool> {
let chat_id: Option<ChatId> = context
.sql
.query_get_value("SELECT chat_id FROM msgs WHERE id=?;", paramsv![msg_id])
.query_get_value("SELECT chat_id FROM msgs WHERE id=?;", (msg_id,))
.await?;
if let Some(chat_id) = chat_id {
@@ -1635,7 +1629,7 @@ pub(crate) async fn set_msg_failed(context: &Context, msg_id: MsgId, error: &str
.sql
.execute(
"UPDATE msgs SET state=?, error=? WHERE id=?;",
paramsv![msg.state, error, msg_id],
(msg.state, error, msg_id),
)
.await
{
@@ -1680,7 +1674,7 @@ pub async fn handle_mdn(
" WHERE rfc724_mid=? AND from_id=1",
" ORDER BY m.id;"
),
paramsv![rfc724_mid],
(&rfc724_mid,),
|row| {
Ok((
row.get::<_, MsgId>("msg_id")?,
@@ -1706,7 +1700,7 @@ pub async fn handle_mdn(
.sql
.exists(
"SELECT COUNT(*) FROM msgs_mdns WHERE msg_id=? AND contact_id=?;",
paramsv![msg_id, from_id],
(msg_id, from_id),
)
.await?
{
@@ -1714,7 +1708,7 @@ pub async fn handle_mdn(
.sql
.execute(
"INSERT INTO msgs_mdns (msg_id, contact_id, timestamp_sent) VALUES (?, ?, ?);",
paramsv![msg_id, from_id, timestamp_sent],
(msg_id, from_id, timestamp_sent),
)
.await?;
}
@@ -1754,7 +1748,7 @@ pub(crate) async fn handle_ndn(
" FROM msgs m LEFT JOIN chats c ON m.chat_id=c.id",
" WHERE rfc724_mid=? AND from_id=1",
),
paramsv![failed.rfc724_mid],
(&failed.rfc724_mid,),
|row| {
Ok((
row.get::<_, MsgId>("msg_id")?,
@@ -1894,7 +1888,7 @@ pub async fn estimate_deletion_cnt(
AND timestamp < ?
AND chat_id != ?
AND EXISTS (SELECT * FROM imap WHERE rfc724_mid=m.rfc724_mid);",
paramsv![DC_MSG_ID_LAST_SPECIAL, threshold_timestamp, self_chat_id],
(DC_MSG_ID_LAST_SPECIAL, threshold_timestamp, self_chat_id),
)
.await?
} else {
@@ -1907,12 +1901,12 @@ pub async fn estimate_deletion_cnt(
AND timestamp < ?
AND chat_id != ?
AND chat_id != ? AND hidden = 0;",
paramsv![
(
DC_MSG_ID_LAST_SPECIAL,
threshold_timestamp,
self_chat_id,
DC_CHAT_ID_TRASH
],
DC_CHAT_ID_TRASH,
),
)
.await?
};
@@ -1933,7 +1927,7 @@ pub(crate) async fn rfc724_mid_exists(
.sql
.query_row_optional(
"SELECT id FROM msgs WHERE rfc724_mid=?",
paramsv![rfc724_mid],
(rfc724_mid,),
|row| {
let msg_id: MsgId = row.get(0)?;

View File

@@ -166,7 +166,7 @@ impl<'a> MimeFactory<'a> {
FROM chats_contacts cc \
LEFT JOIN contacts c ON cc.contact_id=c.id \
WHERE cc.chat_id=? AND cc.contact_id>9;",
paramsv![msg.chat_id],
(msg.chat_id,),
|row| {
let authname: String = row.get(0)?;
let addr: String = row.get(1)?;
@@ -195,7 +195,7 @@ impl<'a> MimeFactory<'a> {
.sql
.query_row(
"SELECT mime_in_reply_to, mime_references FROM msgs WHERE id=?",
paramsv![msg.id],
(msg.id,),
|row| {
let in_reply_to: String = row.get(0)?;
let references: String = row.get(1)?;

View File

@@ -1668,10 +1668,7 @@ impl MimeMessage {
{
context
.sql
.query_get_value(
"SELECT timestamp FROM msgs WHERE rfc724_mid=?",
paramsv![field],
)
.query_get_value("SELECT timestamp FROM msgs WHERE rfc724_mid=?", (field,))
.await?
} else {
None
@@ -2352,7 +2349,7 @@ mod tests {
.sql
.execute(
"INSERT INTO msgs (rfc724_mid, timestamp) VALUES(?,?)",
paramsv!["Gr.beZgAF2Nn0-.oyaJOpeuT70@example.org", timestamp],
("Gr.beZgAF2Nn0-.oyaJOpeuT70@example.org", timestamp),
)
.await
.expect("Failed to write to the database");

View File

@@ -75,7 +75,7 @@ async fn lookup_host_with_cache(
VALUES (?, ?, ?)
ON CONFLICT (hostname, address)
DO UPDATE SET timestamp=excluded.timestamp",
paramsv![hostname, ip_string, now],
(hostname, ip_string, now),
)
.await?;
}
@@ -89,7 +89,7 @@ async fn lookup_host_with_cache(
WHERE hostname = ?
AND ? < timestamp + 30 * 24 * 3600
ORDER BY timestamp DESC",
paramsv![hostname, now],
(hostname, now),
|row| {
let address: String = row.get(0)?;
Ok(address)
@@ -157,7 +157,7 @@ pub(crate) async fn connect_tcp(
"UPDATE dns_cache
SET timestamp = ?
WHERE address = ?",
paramsv![time(), resolved_addr.ip().to_string()],
(time(), resolved_addr.ip().to_string()),
)
.await?;
break;

View File

@@ -144,7 +144,7 @@ impl Peerstate {
verified_key, verified_key_fingerprint, verifier \
FROM acpeerstates \
WHERE addr=? COLLATE NOCASE LIMIT 1;";
Self::from_stmt(context, query, paramsv![addr]).await
Self::from_stmt(context, query, (addr,)).await
}
/// Loads peerstate corresponding to the given fingerprint from the database.
@@ -160,7 +160,7 @@ impl Peerstate {
OR gossip_key_fingerprint=? \
ORDER BY public_key_fingerprint=? DESC LIMIT 1;";
let fp = fingerprint.hex();
Self::from_stmt(context, query, paramsv![fp, fp, fp]).await
Self::from_stmt(context, query, (&fp, &fp, &fp)).await
}
/// Loads peerstate by address or verified fingerprint.
@@ -180,7 +180,7 @@ impl Peerstate {
OR addr=? COLLATE NOCASE \
ORDER BY verified_key_fingerprint=? DESC, last_seen DESC LIMIT 1;";
let fp = fingerprint.hex();
Self::from_stmt(context, query, paramsv![fp, addr, fp]).await
Self::from_stmt(context, query, (&fp, &addr, &fp)).await
}
async fn from_stmt(
@@ -471,7 +471,7 @@ impl Peerstate {
verified_key = excluded.verified_key,
verified_key_fingerprint = excluded.verified_key_fingerprint,
verifier = excluded.verifier",
paramsv![
(
self.last_seen,
self.last_seen_autocrypt,
self.prefer_encrypt as i64,
@@ -482,9 +482,9 @@ impl Peerstate {
self.gossip_key_fingerprint.as_ref().map(|fp| fp.hex()),
self.verified_key.as_ref().map(|k| k.to_bytes()),
self.verified_key_fingerprint.as_ref().map(|fp| fp.hex()),
self.addr,
&self.addr,
self.verifier.as_deref().unwrap_or(""),
],
),
)
.await?;
Ok(())
@@ -524,7 +524,7 @@ impl Peerstate {
.sql
.query_get_value(
"SELECT id FROM contacts WHERE addr=? COLLATE NOCASE;",
paramsv![self.addr],
(&self.addr,),
)
.await?
.with_context(|| format!("contact with peerstate.addr {:?} not found", &self.addr))?;
@@ -554,7 +554,7 @@ impl Peerstate {
.sql
.query_get_value(
"SELECT created_timestamp FROM chats WHERE id=?;",
paramsv![chat_id],
(chat_id,),
)
.await?
.unwrap_or(0)
@@ -851,7 +851,7 @@ mod tests {
// can be loaded without errors.
ctx.ctx
.sql
.execute("INSERT INTO acpeerstates (addr) VALUES(?)", paramsv![addr])
.execute("INSERT INTO acpeerstates (addr) VALUES(?)", (addr,))
.await
.expect("Failed to write to the database");

View File

@@ -156,7 +156,7 @@ async fn set_msg_id_reaction(
"DELETE FROM reactions
WHERE msg_id = ?1
AND contact_id = ?2",
paramsv![msg_id, contact_id],
(msg_id, contact_id),
)
.await?;
} else {
@@ -167,7 +167,7 @@ async fn set_msg_id_reaction(
VALUES (?1, ?2, ?3)
ON CONFLICT(msg_id, contact_id)
DO UPDATE SET reaction=excluded.reaction",
paramsv![msg_id, contact_id, reaction.as_str()],
(msg_id, contact_id, reaction.as_str()),
)
.await?;
}
@@ -247,7 +247,7 @@ async fn get_self_reaction(context: &Context, msg_id: MsgId) -> Result<Reaction>
"SELECT reaction
FROM reactions
WHERE msg_id=? AND contact_id=?",
paramsv![msg_id, ContactId::SELF],
(msg_id, ContactId::SELF),
)
.await?;
Ok(reaction_str
@@ -262,7 +262,7 @@ pub async fn get_msg_reactions(context: &Context, msg_id: MsgId) -> Result<React
.sql
.query_map(
"SELECT contact_id, reaction FROM reactions WHERE msg_id=?",
paramsv![msg_id],
(msg_id,),
|row| {
let contact_id: ContactId = row.get(0)?;
let reaction: String = row.get(1)?;

View File

@@ -118,7 +118,7 @@ pub(crate) async fn receive_imf_inner(
.sql
.execute(
"INSERT INTO msgs(rfc724_mid, chat_id) VALUES (?,?)",
paramsv![rfc724_mid, DC_CHAT_ID_TRASH],
(rfc724_mid, DC_CHAT_ID_TRASH),
)
.await?;
msg_ids = vec![MsgId::new(u32::try_from(row_id)?)];
@@ -346,7 +346,7 @@ pub(crate) async fn receive_imf_inner(
.sql
.execute(
"UPDATE imap SET target=? WHERE rfc724_mid=?",
paramsv![target, rfc724_mid],
(target, rfc724_mid),
)
.await?;
} else if !mime_parser.mdn_reports.is_empty() && mime_parser.has_chat_version() {
@@ -1365,7 +1365,7 @@ async fn calc_sort_timestamp(
.sql
.query_get_value(
"SELECT MAX(timestamp) FROM msgs WHERE chat_id=? AND state>?",
paramsv![chat_id, MessageState::InFresh],
(chat_id, MessageState::InFresh),
)
.await?;
@@ -1684,7 +1684,7 @@ async fn apply_group_changes(
.sql
.execute(
"UPDATE chats SET name=? WHERE id=?;",
paramsv![strip_rtlo_characters(grpname), chat_id],
(strip_rtlo_characters(grpname), chat_id),
)
.await?;
send_event_chat_modified = true;
@@ -1754,10 +1754,7 @@ async fn apply_group_changes(
// start from scratch.
context
.sql
.execute(
"DELETE FROM chats_contacts WHERE chat_id=?;",
paramsv![chat_id],
)
.execute("DELETE FROM chats_contacts WHERE chat_id=?;", (chat_id,))
.await?;
members_to_add.push(ContactId::SELF);

View File

@@ -374,7 +374,7 @@ async fn test_no_message_id_header() {
.sql
.exists(
"SELECT COUNT(*) FROM msgs WHERE chat_id=?;",
paramsv![DC_CHAT_ID_TRASH],
(DC_CHAT_ID_TRASH,),
)
.await
.unwrap());

View File

@@ -135,21 +135,21 @@ impl BobState {
// rows that we will delete. So start with a dummy UPDATE.
transaction.execute(
r#"UPDATE bobstate SET next_step=?;"#,
params![SecureJoinStep::Terminated],
(SecureJoinStep::Terminated,),
)?;
let mut stmt = transaction.prepare("SELECT id FROM bobstate;")?;
let mut aborted = Vec::new();
for id in stmt.query_map(params![], |row| row.get::<_, i64>(0))? {
for id in stmt.query_map((), |row| row.get::<_, i64>(0))? {
let id = id?;
let state = BobState::from_db_id(transaction, id)?;
aborted.push(state);
}
// Finally delete everything and insert new row.
transaction.execute("DELETE FROM bobstate;", params![])?;
transaction.execute("DELETE FROM bobstate;", ())?;
transaction.execute(
"INSERT INTO bobstate (invite, next_step, chat_id) VALUES (?, ?, ?);",
params![invite, next, chat_id],
(invite, next, chat_id),
)?;
let id = transaction.last_insert_rowid();
Ok((id, aborted))
@@ -180,7 +180,7 @@ impl BobState {
fn from_db_id(connection: &Connection, id: i64) -> rusqlite::Result<Self> {
connection.query_row(
"SELECT invite, next_step, chat_id FROM bobstate WHERE id=?;",
params![id],
(id,),
|row| {
let s = BobState {
id,
@@ -217,12 +217,12 @@ impl BobState {
SecureJoinStep::AuthRequired | SecureJoinStep::ContactConfirm => {
sql.execute(
"UPDATE bobstate SET next_step=? WHERE id=?;",
paramsv![next, self.id],
(next, self.id),
)
.await?;
}
SecureJoinStep::Terminated | SecureJoinStep::Completed => {
sql.execute("DELETE FROM bobstate WHERE id=?;", paramsv!(self.id))
sql.execute("DELETE FROM bobstate WHERE id=?;", (self.id,))
.await?;
}
}

View File

@@ -520,10 +520,7 @@ pub(crate) async fn send_msg_to_smtp(
// database.
context
.sql
.execute(
"UPDATE smtp SET retries=retries+1 WHERE id=?",
paramsv![rowid],
)
.execute("UPDATE smtp SET retries=retries+1 WHERE id=?", (rowid,))
.await
.context("failed to update retries count")?;
@@ -531,7 +528,7 @@ pub(crate) async fn send_msg_to_smtp(
.sql
.query_row(
"SELECT mime, recipients, msg_id, retries FROM smtp WHERE id=?",
paramsv![rowid],
(rowid,),
|row| {
let mime: String = row.get(0)?;
let recipients: String = row.get(1)?;
@@ -545,7 +542,7 @@ pub(crate) async fn send_msg_to_smtp(
message::set_msg_failed(context, msg_id, "Number of retries exceeded the limit.").await;
context
.sql
.execute("DELETE FROM smtp WHERE id=?", paramsv![rowid])
.execute("DELETE FROM smtp WHERE id=?", (rowid,))
.await
.context("failed to remove message with exceeded retry limit from smtp table")?;
bail!("Number of retries exceeded the limit");
@@ -588,7 +585,7 @@ pub(crate) async fn send_msg_to_smtp(
SendResult::Success | SendResult::Failure(_) => {
context
.sql
.execute("DELETE FROM smtp WHERE id=?", paramsv![rowid])
.execute("DELETE FROM smtp WHERE id=?", (rowid,))
.await?;
}
};
@@ -637,7 +634,7 @@ pub(crate) async fn send_smtp_messages(context: &Context, connection: &mut Smtp)
.sql
.query_map(
"SELECT id FROM smtp ORDER BY id ASC",
paramsv![],
(),
|row| {
let rowid: i64 = row.get(0)?;
Ok(rowid)
@@ -691,7 +688,7 @@ async fn send_mdn_msg_id(
"SELECT msg_id, rfc724_mid
FROM smtp_mdns
WHERE from_id=? AND msg_id!=?",
paramsv![contact_id, msg_id],
(contact_id, msg_id),
|row| {
let msg_id: MsgId = row.get(0)?;
let rfc724_mid: String = row.get(1)?;
@@ -718,7 +715,7 @@ async fn send_mdn_msg_id(
info!(context, "Successfully sent MDN for {}", msg_id);
context
.sql
.execute("DELETE FROM smtp_mdns WHERE msg_id = ?", paramsv![msg_id])
.execute("DELETE FROM smtp_mdns WHERE msg_id = ?", (msg_id,))
.await?;
if !additional_msg_ids.is_empty() {
let q = format!(
@@ -779,7 +776,7 @@ async fn send_mdn(context: &Context, smtp: &mut Smtp) -> Result<bool> {
.sql
.execute(
"UPDATE smtp_mdns SET retries=retries+1 WHERE msg_id=?",
paramsv![msg_id],
(msg_id,),
)
.await
.context("failed to update MDN retries count")?;
@@ -789,7 +786,7 @@ async fn send_mdn(context: &Context, smtp: &mut Smtp) -> Result<bool> {
// database, do not try to send this MDN again.
context
.sql
.execute("DELETE FROM smtp_mdns WHERE msg_id = ?", paramsv![msg_id])
.execute("DELETE FROM smtp_mdns WHERE msg_id = ?", (msg_id,))
.await?;
Err(err)
} else {

View File

@@ -23,27 +23,28 @@ use crate::peerstate::{deduplicate_peerstates, Peerstate};
use crate::stock_str;
use crate::tools::{delete_file, time};
#[allow(missing_docs)]
/// Extension to [`rusqlite::ToSql`] trait
/// which also includes [`Send`] and [`Sync`].
pub trait ToSql: rusqlite::ToSql + Send + Sync {}
impl<T: rusqlite::ToSql + Send + Sync> ToSql for T {}
/// Constructs a slice of trait object references `&dyn ToSql`.
///
/// One of the uses is passing more than 16 parameters
/// to a query, because [`rusqlite::Params`] is only implemented
/// for tuples of up to 16 elements.
#[macro_export]
macro_rules! paramsv {
() => {
rusqlite::params_from_iter(Vec::<&dyn $crate::ToSql>::new())
};
($($param:expr),+ $(,)?) => {
rusqlite::params_from_iter(vec![$(&$param as &dyn $crate::ToSql),+])
macro_rules! params_slice {
($($param:expr),+) => {
[$(&$param as &dyn $crate::sql::ToSql),+]
};
}
#[allow(missing_docs)]
#[macro_export]
macro_rules! params_iterv {
($($param:expr),+ $(,)?) => {
vec![$(&$param as &dyn $crate::ToSql),+]
};
}
pub(crate) fn params_iter(iter: &[impl crate::ToSql]) -> impl Iterator<Item = &dyn crate::ToSql> {
iter.iter().map(|item| item as &dyn crate::ToSql)
pub(crate) fn params_iter(
iter: &[impl crate::sql::ToSql],
) -> impl Iterator<Item = &dyn crate::sql::ToSql> {
iter.iter().map(|item| item as &dyn crate::sql::ToSql)
}
mod migrations;
@@ -139,11 +140,8 @@ impl Sql {
let res = self
.call_write(move |conn| {
// Check that backup passphrase is correct before resetting our database.
conn.execute(
"ATTACH DATABASE ? AS backup KEY ?",
paramsv![path_str, passphrase],
)
.context("failed to attach backup database")?;
conn.execute("ATTACH DATABASE ? AS backup KEY ?", (path_str, passphrase))
.context("failed to attach backup database")?;
if let Err(err) = conn
.query_row("SELECT count(*) FROM sqlite_master", [], |_row| Ok(()))
.context("backup passphrase is not correct")
@@ -556,27 +554,21 @@ impl Sql {
let mut lock = self.config_cache.write().await;
if let Some(value) = value {
let exists = self
.exists(
"SELECT COUNT(*) FROM config WHERE keyname=?;",
paramsv![key],
)
.exists("SELECT COUNT(*) FROM config WHERE keyname=?;", (key,))
.await?;
if exists {
self.execute(
"UPDATE config SET value=? WHERE keyname=?;",
paramsv![value, key],
)
.await?;
self.execute("UPDATE config SET value=? WHERE keyname=?;", (value, key))
.await?;
} else {
self.execute(
"INSERT INTO config (keyname, value) VALUES (?, ?);",
paramsv![key, value],
(key, value),
)
.await?;
}
} else {
self.execute("DELETE FROM config WHERE keyname=?;", paramsv![key])
self.execute("DELETE FROM config WHERE keyname=?;", (key,))
.await?;
}
lock.insert(key.to_string(), value.map(|s| s.to_string()));
@@ -597,7 +589,7 @@ impl Sql {
let mut lock = self.config_cache.write().await;
let value = self
.query_get_value("SELECT value FROM config WHERE keyname=?;", paramsv![key])
.query_get_value("SELECT value FROM config WHERE keyname=?;", (key,))
.await
.context(format!("failed to fetch raw config: {key}"))?;
lock.insert(key.to_string(), value.clone());
@@ -980,7 +972,7 @@ async fn prune_tombstones(sql: &Sql) -> Result<()> {
AND NOT EXISTS (
SELECT * FROM imap WHERE msgs.rfc724_mid=rfc724_mid AND target!=''
)",
paramsv![DC_CHAT_ID_TRASH],
(DC_CHAT_ID_TRASH,),
)
.await?;
Ok(())
@@ -1163,12 +1155,12 @@ mod tests {
sql.open(&t, "".to_string()).await?;
sql.execute(
"INSERT INTO config (keyname, value) VALUES (?, ?);",
paramsv!("foo", "bar"),
("foo", "bar"),
)
.await?;
let value: Option<String> = sql
.query_get_value("SELECT value FROM config WHERE keyname=?;", paramsv!("foo"))
.query_get_value("SELECT value FROM config WHERE keyname=?;", ("foo",))
.await?;
assert_eq!(value.unwrap(), "bar");

View File

@@ -30,7 +30,7 @@ pub async fn run(context: &Context, sql: &Sql) -> Result<(bool, bool, bool, bool
// set raw config inside the transaction
transaction.execute(
"INSERT INTO config (keyname, value) VALUES (?, ?);",
paramsv![VERSION_CFG, format!("{dbversion_before_update}")],
(VERSION_CFG, format!("{dbversion_before_update}")),
)?;
Ok(())
})
@@ -746,7 +746,7 @@ impl Sql {
fn set_db_version_trans(transaction: &mut rusqlite::Transaction, version: i32) -> Result<()> {
transaction.execute(
"UPDATE config SET value=? WHERE keyname=?;",
params![format!("{version}"), VERSION_CFG],
(format!("{version}"), VERSION_CFG),
)?;
Ok(())
}

View File

@@ -65,10 +65,7 @@ impl Context {
let item = SyncItem { timestamp, data };
let item = serde_json::to_string(&item)?;
self.sql
.execute(
"INSERT INTO multi_device_sync (item) VALUES(?);",
paramsv![item],
)
.execute("INSERT INTO multi_device_sync (item) VALUES(?);", (item,))
.await?;
Ok(())

View File

@@ -425,7 +425,7 @@ impl TestContext {
};
self.ctx
.sql
.execute("DELETE FROM smtp WHERE id=?;", paramsv![rowid])
.execute("DELETE FROM smtp WHERE id=?;", (rowid,))
.await
.expect("failed to remove job");
update_msg_state(&self.ctx, msg_id, MessageState::OutDelivered)

View File

@@ -35,7 +35,7 @@ pub async fn save(
.sql
.execute(
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);",
paramsv![namespace, foreign_id, token, time()],
(namespace, foreign_id, token, time()),
)
.await?,
None => {
@@ -43,7 +43,7 @@ pub async fn save(
.sql
.execute(
"INSERT INTO tokens (namespc, token, timestamp) VALUES (?, ?, ?);",
paramsv![namespace, token, time()],
(namespace, token, time()),
)
.await?
}
@@ -71,7 +71,7 @@ pub async fn lookup(
.sql
.query_get_value(
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=? ORDER BY timestamp DESC LIMIT 1;",
paramsv![namespace, chat_id],
(namespace, chat_id),
)
.await?
}
@@ -81,7 +81,7 @@ pub async fn lookup(
.sql
.query_get_value(
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=0 ORDER BY timestamp DESC LIMIT 1;",
paramsv![namespace],
(namespace,),
)
.await?
}
@@ -108,7 +108,7 @@ pub async fn exists(context: &Context, namespace: Namespace, token: &str) -> boo
.sql
.exists(
"SELECT COUNT(*) FROM tokens WHERE namespc=? AND token=?;",
paramsv![namespace, token],
(namespace, token),
)
.await
.unwrap_or_default()
@@ -119,7 +119,7 @@ pub async fn delete(context: &Context, namespace: Namespace, token: &str) -> Res
.sql
.execute(
"DELETE FROM tokens WHERE namespc=? AND token=?;",
paramsv![namespace, token],
(namespace, token),
)
.await?;
Ok(())

View File

@@ -31,7 +31,7 @@ impl Context {
if update {
transaction.execute(
"UPDATE contacts SET param=? WHERE id=?",
params![param.to_string(), contact_id],
(param.to_string(), contact_id),
)?;
}
Ok(update)
@@ -61,7 +61,7 @@ impl ChatId {
if update {
transaction.execute(
"UPDATE chats SET param=? WHERE id=?",
params![param.to_string(), self],
(param.to_string(), self),
)?;
}
Ok(update)

View File

@@ -263,7 +263,7 @@ impl Context {
FROM msgs
WHERE chat_id=?1 AND hidden=0
ORDER BY timestamp DESC, id DESC LIMIT 1"#,
paramsv![instance.chat_id],
(instance.chat_id,),
|row| {
let last_msg_id: MsgId = row.get(0)?;
let last_from_id: ContactId = row.get(1)?;
@@ -387,7 +387,7 @@ impl Context {
.sql
.insert(
"INSERT INTO msgs_status_updates (msg_id, update_item) VALUES(?, ?);",
paramsv![instance_id, serde_json::to_string(&status_update_item)?],
(instance_id, serde_json::to_string(&status_update_item)?),
)
.await?;
let status_update_serial = StatusUpdateSerial(u32::try_from(rowid)?);
@@ -435,7 +435,7 @@ impl Context {
"INSERT INTO smtp_status_updates (msg_id, first_serial, last_serial, descr) VALUES(?, ?, ?, ?)
ON CONFLICT(msg_id)
DO UPDATE SET last_serial=excluded.last_serial, descr=excluded.descr",
paramsv![instance.id, status_update_serial, status_update_serial, descr],
(instance.id, status_update_serial, status_update_serial, descr),
).await?;
self.scheduler
.interrupt_smtp(InterruptInfo::new(false))
@@ -579,7 +579,7 @@ impl Context {
.sql
.query_map(
"SELECT update_item, id FROM msgs_status_updates WHERE msg_id=? AND id>? ORDER BY id",
paramsv![instance_msg_id, last_known_serial],
(instance_msg_id, last_known_serial),
|row| {
let update_item_str = row.get::<_, String>(0)?;
let serial = row.get::<_, StatusUpdateSerial>(1)?;
@@ -631,11 +631,11 @@ impl Context {
.sql
.query_map(
"SELECT update_item FROM msgs_status_updates WHERE msg_id=? AND id>=? AND id<=? ORDER BY id",
paramsv![
(
instance_msg_id,
range.map(|r|r.0).unwrap_or(StatusUpdateSerial(0)),
range.map(|r|r.1).unwrap_or(StatusUpdateSerial(u32::MAX)),
],
),
|row| row.get::<_, String>(0),
|rows| {
let mut json = String::default();