mirror of
https://github.com/chatmail/core.git
synced 2026-05-20 23:36:30 +03:00
Delete expired messages using multiple SQL requests
With existing approach of constructing the SQL query dynamically I get errors like this: ephemeral.rs:575: update failed: too many SQL variables: Error code 1: SQL error or missing database In my case it is trying to delete 143658 messages. This is the result of importing a Desktop backup and enabling device auto-deletion on the phone. Current SQLite limit is 32766 variables as stated in <https://www.sqlite.org/limits.html>.
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
background process spawned by `dc_configure()` or `dc_imex()`
|
background process spawned by `dc_configure()` or `dc_imex()`
|
||||||
or `dc_jsonrpc_instance_t` is unreferenced
|
or `dc_jsonrpc_instance_t` is unreferenced
|
||||||
during handling the JSON-RPC request. #4153
|
during handling the JSON-RPC request. #4153
|
||||||
|
- Delete expired messages using multiple SQL requests. #4158
|
||||||
|
|
||||||
|
|
||||||
## 1.111.0
|
## 1.111.0
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ use std::num::ParseIntError;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use anyhow::{ensure, Context as _, Result};
|
use anyhow::{ensure, Result};
|
||||||
use async_channel::Receiver;
|
use async_channel::Receiver;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::time::timeout;
|
use tokio::time::timeout;
|
||||||
@@ -433,37 +433,40 @@ pub(crate) async fn delete_expired_messages(context: &Context, now: i64) -> Resu
|
|||||||
let rows = select_expired_messages(context, now).await?;
|
let rows = select_expired_messages(context, now).await?;
|
||||||
|
|
||||||
if !rows.is_empty() {
|
if !rows.is_empty() {
|
||||||
context
|
info!(context, "Attempting to delete {} messages.", rows.len());
|
||||||
|
|
||||||
|
let (msgs_changed, webxdc_deleted) = context
|
||||||
.sql
|
.sql
|
||||||
.execute(
|
.transaction(|transaction| {
|
||||||
|
let mut msgs_changed = Vec::with_capacity(rows.len());
|
||||||
|
let mut webxdc_deleted = Vec::new();
|
||||||
|
|
||||||
// If you change which information is removed here, also change MsgId::trash() and
|
// If you change which information is removed here, also change MsgId::trash() and
|
||||||
// which information receive_imf::add_parts() still adds to the db if the chat_id is TRASH
|
// which information receive_imf::add_parts() still adds to the db if the chat_id is TRASH
|
||||||
&format!(
|
for (msg_id, chat_id, viewtype) in rows {
|
||||||
r#"
|
transaction.execute(
|
||||||
UPDATE msgs
|
"UPDATE msgs
|
||||||
SET
|
SET chat_id=?, txt='', subject='', txt_raw='',
|
||||||
chat_id=?, txt='', subject='', txt_raw='',
|
mime_headers='', from_id=0, to_id=0, param=''
|
||||||
mime_headers='', from_id=0, to_id=0, param=''
|
WHERE id=?",
|
||||||
WHERE id IN ({})
|
params![DC_CHAT_ID_TRASH, msg_id],
|
||||||
"#,
|
)?;
|
||||||
sql::repeat_vars(rows.len())
|
|
||||||
),
|
|
||||||
rusqlite::params_from_iter(
|
|
||||||
std::iter::once(&DC_CHAT_ID_TRASH as &dyn crate::ToSql).chain(
|
|
||||||
rows.iter()
|
|
||||||
.map(|(msg_id, _chat_id, _viewtype)| msg_id as &dyn crate::ToSql),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.context("update failed")?;
|
|
||||||
|
|
||||||
for (msg_id, chat_id, viewtype) in rows {
|
msgs_changed.push((chat_id, msg_id));
|
||||||
|
if viewtype == Viewtype::Webxdc {
|
||||||
|
webxdc_deleted.push(msg_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok((msgs_changed, webxdc_deleted))
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
for (chat_id, msg_id) in msgs_changed {
|
||||||
context.emit_msgs_changed(chat_id, msg_id);
|
context.emit_msgs_changed(chat_id, msg_id);
|
||||||
|
}
|
||||||
|
|
||||||
if viewtype == Viewtype::Webxdc {
|
for msg_id in webxdc_deleted {
|
||||||
context.emit_event(EventType::WebxdcInstanceDeleted { msg_id });
|
context.emit_event(EventType::WebxdcInstanceDeleted { msg_id });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user