mellib/imap: don't flood user with sqlite3 errors if db is corrupted
Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/299/head
parent
bb4d200036
commit
9b9c38f769
|
@ -169,11 +169,24 @@ pub mod sqlite3_m {
|
|||
|
||||
impl Sqlite3Cache {
|
||||
pub fn get(uid_store: Arc<UIDStore>) -> Result<Box<dyn ImapCache>> {
|
||||
let connection =
|
||||
match sqlite3::open_or_create_db(&DB_DESCRIPTION, Some(&uid_store.account_name)) {
|
||||
Ok(c) => Ok(c),
|
||||
Err(err) => {
|
||||
// try resetting database on error, but only one time.
|
||||
if Self::reset_db(&uid_store).is_ok() {
|
||||
sqlite3::open_or_create_db(
|
||||
&DB_DESCRIPTION,
|
||||
Some(&uid_store.account_name),
|
||||
)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}?;
|
||||
|
||||
Ok(Box::new(Self {
|
||||
connection: sqlite3::open_or_create_db(
|
||||
&DB_DESCRIPTION,
|
||||
Some(&uid_store.account_name),
|
||||
)?,
|
||||
connection,
|
||||
loaded_mailboxes: BTreeSet::default(),
|
||||
uid_store,
|
||||
}))
|
||||
|
@ -712,7 +725,7 @@ pub(super) async fn fetch_cached_envs(state: &mut FetchState) -> Result<Option<V
|
|||
cache_handle: _,
|
||||
} = state;
|
||||
let mailbox_hash = *mailbox_hash;
|
||||
if !uid_store.keep_offline_cache {
|
||||
if !*uid_store.keep_offline_cache.lock().unwrap() {
|
||||
return Ok(None);
|
||||
}
|
||||
{
|
||||
|
|
|
@ -628,7 +628,7 @@ impl ImapConnection {
|
|||
#[cfg(debug_assertions)]
|
||||
id,
|
||||
server_conf: server_conf.clone(),
|
||||
sync_policy: if uid_store.keep_offline_cache {
|
||||
sync_policy: if *uid_store.keep_offline_cache.lock().unwrap() {
|
||||
SyncPolicy::Basic
|
||||
} else {
|
||||
SyncPolicy::None
|
||||
|
@ -984,7 +984,7 @@ impl ImapConnection {
|
|||
format!("Could not parse select response for mailbox {}", imap_path)
|
||||
})?;
|
||||
{
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
#[cfg(not(feature = "sqlite3"))]
|
||||
let mut cache_handle = super::cache::DefaultCache::get(self.uid_store.clone())?;
|
||||
#[cfg(feature = "sqlite3")]
|
||||
|
|
|
@ -148,7 +148,7 @@ macro_rules! get_conf_val {
|
|||
pub struct UIDStore {
|
||||
account_hash: AccountHash,
|
||||
account_name: Arc<str>,
|
||||
keep_offline_cache: bool,
|
||||
keep_offline_cache: Arc<Mutex<bool>>,
|
||||
capabilities: Arc<Mutex<Capabilities>>,
|
||||
hash_index: Arc<Mutex<HashMap<EnvelopeHash, (UID, MailboxHash)>>>,
|
||||
uid_index: Arc<Mutex<HashMap<(MailboxHash, UID), EnvelopeHash>>>,
|
||||
|
@ -179,7 +179,7 @@ impl UIDStore {
|
|||
Self {
|
||||
account_hash,
|
||||
account_name,
|
||||
keep_offline_cache: false,
|
||||
keep_offline_cache: Arc::new(Mutex::new(false)),
|
||||
capabilities: Default::default(),
|
||||
uidvalidity: Default::default(),
|
||||
envelopes: Default::default(),
|
||||
|
@ -301,7 +301,7 @@ impl MailBackend for ImapType {
|
|||
) -> Result<Pin<Box<dyn Stream<Item = Result<Vec<Envelope>>> + Send + 'static>>> {
|
||||
let cache_handle = {
|
||||
#[cfg(feature = "sqlite3")]
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
match cache::Sqlite3Cache::get(self.uid_store.clone()).chain_err_summary(|| {
|
||||
format!(
|
||||
"Could not initialize cache for IMAP account {}. Resetting database.",
|
||||
|
@ -317,9 +317,11 @@ impl MailBackend for ImapType {
|
|||
{
|
||||
Ok(v) => Some(v),
|
||||
Err(err) => {
|
||||
(self.uid_store.event_consumer)(
|
||||
self.uid_store.account_hash,
|
||||
err.into(),
|
||||
*self.uid_store.keep_offline_cache.lock().unwrap() = false;
|
||||
log::trace!(
|
||||
"{}: sqlite3 cache error: {}",
|
||||
self.uid_store.account_name,
|
||||
err
|
||||
);
|
||||
None
|
||||
}
|
||||
|
@ -333,7 +335,7 @@ impl MailBackend for ImapType {
|
|||
None
|
||||
};
|
||||
let mut state = FetchState {
|
||||
stage: if self.uid_store.keep_offline_cache && cache_handle.is_some() {
|
||||
stage: if *self.uid_store.keep_offline_cache.lock().unwrap() && cache_handle.is_some() {
|
||||
FetchStage::InitialCache
|
||||
} else {
|
||||
FetchStage::InitialFresh
|
||||
|
@ -1294,7 +1296,7 @@ impl ImapType {
|
|||
let account_hash = AccountHash::from_bytes(s.name.as_bytes());
|
||||
let account_name = s.name.to_string().into();
|
||||
let uid_store: Arc<UIDStore> = Arc::new(UIDStore {
|
||||
keep_offline_cache,
|
||||
keep_offline_cache: Arc::new(Mutex::new(keep_offline_cache)),
|
||||
..UIDStore::new(
|
||||
account_hash,
|
||||
account_name,
|
||||
|
|
|
@ -147,7 +147,7 @@ impl ImapConnection {
|
|||
},
|
||||
));
|
||||
}
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
cache_handle.update(mailbox_hash, &events)?;
|
||||
}
|
||||
for (_, event) in events {
|
||||
|
@ -190,7 +190,7 @@ impl ImapConnection {
|
|||
kind: Remove(deleted_hash),
|
||||
},
|
||||
)];
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
cache_handle.update(mailbox_hash, &event)?;
|
||||
}
|
||||
self.add_refresh_event(std::mem::replace(
|
||||
|
@ -282,7 +282,7 @@ impl ImapConnection {
|
|||
mailbox.path(),
|
||||
);
|
||||
}
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
if let Err(err) = cache_handle
|
||||
.insert_envelopes(mailbox_hash, &v)
|
||||
.chain_err_summary(|| {
|
||||
|
@ -384,7 +384,7 @@ impl ImapConnection {
|
|||
}
|
||||
mailbox.exists.lock().unwrap().insert_new(env.hash());
|
||||
}
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
if let Err(err) = cache_handle
|
||||
.insert_envelopes(mailbox_hash, &v)
|
||||
.chain_err_summary(|| {
|
||||
|
@ -525,7 +525,7 @@ impl ImapConnection {
|
|||
kind: NewFlags(env_hash, flags),
|
||||
},
|
||||
)];
|
||||
if self.uid_store.keep_offline_cache {
|
||||
if *self.uid_store.keep_offline_cache.lock().unwrap() {
|
||||
cache_handle.update(mailbox_hash, &event)?;
|
||||
}
|
||||
self.add_refresh_event(std::mem::replace(
|
||||
|
|
|
@ -90,7 +90,7 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> {
|
|||
|
||||
if let Some(v) = uidvalidities.get(&mailbox_hash) {
|
||||
if *v != select_response.uidvalidity {
|
||||
if uid_store.keep_offline_cache {
|
||||
if *uid_store.keep_offline_cache.lock().unwrap() {
|
||||
#[cfg(not(feature = "sqlite3"))]
|
||||
let mut cache_handle = super::cache::DefaultCache::get(uid_store.clone())?;
|
||||
#[cfg(feature = "sqlite3")]
|
||||
|
@ -232,7 +232,7 @@ pub async fn examine_updates(
|
|||
|
||||
if let Some(v) = uidvalidities.get(&mailbox_hash) {
|
||||
if *v != select_response.uidvalidity {
|
||||
if uid_store.keep_offline_cache {
|
||||
if *uid_store.keep_offline_cache.lock().unwrap() {
|
||||
cache_handle.clear(mailbox_hash, &select_response)?;
|
||||
}
|
||||
conn.add_refresh_event(RefreshEvent {
|
||||
|
@ -383,7 +383,9 @@ pub async fn examine_updates(
|
|||
}
|
||||
}
|
||||
}
|
||||
if uid_store.keep_offline_cache && cache_handle.mailbox_state(mailbox_hash)?.is_some() {
|
||||
if *uid_store.keep_offline_cache.lock().unwrap()
|
||||
&& cache_handle.mailbox_state(mailbox_hash)?.is_some()
|
||||
{
|
||||
cache_handle
|
||||
.insert_envelopes(mailbox_hash, &v)
|
||||
.chain_err_summary(|| {
|
||||
|
|
Loading…
Reference in New Issue