diff --git a/ui/src/cache.rs b/ui/src/cache.rs
index 0f2f6878d..cd0a13013 100644
--- a/ui/src/cache.rs
+++ b/ui/src/cache.rs
@@ -19,11 +19,13 @@
* along with meli. If not, see .
*/
+/*
use melib::backends::{FolderHash, MailBackend};
-use melib::email::{EnvelopeHash, Flag, UnixTimestamp};
use melib::mailbox::*;
use melib::thread::{ThreadHash, ThreadNode};
use std::sync::RwLock;
+*/
+use melib::email::{Flag, UnixTimestamp};
#[derive(Debug)]
pub enum Query {
@@ -47,17 +49,16 @@ pub enum Query {
Flag(Flag),
}
+/*
enum CacheType {
Sqlite3,
}
-/*
pub struct Cache {
collection: Collection,
kind: CacheType,
backend: Box,
}
-/*
impl Cache {
pub fn build_index(&mut self) {
diff --git a/ui/src/components/mail/status.rs b/ui/src/components/mail/status.rs
index 7489839e9..8c7a97e7e 100644
--- a/ui/src/components/mail/status.rs
+++ b/ui/src/components/mail/status.rs
@@ -38,9 +38,6 @@ impl fmt::Display for StatusPanel {
impl Component for StatusPanel {
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
- if !self.dirty {
- return;
- }
let (width, height) = self.content.size();
{
let (_, y) = write_string_to_grid(
@@ -143,7 +140,6 @@ impl Component for StatusPanel {
),
),
);
- self.dirty = false;
context.dirty_areas.push_back(area);
}
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
diff --git a/ui/src/sqlite3.rs b/ui/src/sqlite3.rs
index 3324d5e09..bc25cd87e 100644
--- a/ui/src/sqlite3.rs
+++ b/ui/src/sqlite3.rs
@@ -19,11 +19,11 @@
* along with meli. If not, see .
*/
-use fnv::FnvHashMap;
use melib::{
- email::{Envelope, EnvelopeHash},
+ email::EnvelopeHash,
+ log,
thread::{SortField, SortOrder},
- MeliError, Result, StackVec,
+ MeliError, Result, StackVec, ERROR,
};
use rusqlite::{params, Connection};
use std::borrow::Cow;
@@ -171,19 +171,93 @@ pub fn insert(context: &mut crate::state::Context) -> Result<()> {
.map_err(|e| MeliError::new(e.to_string()))?,
)
.map_err(|e| MeliError::new(e.to_string()))?;
- /*
- for acc in context.accounts.iter() {
- debug!("inserting {} envelopes", acc.collection.envelopes.len());
- for e in acc.collection.envelopes.values() {
- conn.execute(
- "INSERT OR REPLACE INTO envelopes (hash, date, _from, _to, cc, bcc, subject, message_id, in_reply_to, _references, flags, has_attachments, body_text, timestamp)
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)",
- params![e.hash().to_be_bytes().to_vec(), e.date_as_str(), e.field_from_to_string(), e.field_to_to_string(), e.field_cc_to_string(), e.field_bcc_to_string(), e.subject().into_owned().trim_end_matches('\u{0}'), e.message_id_display().to_string(), e.in_reply_to_display().map(|f| f.to_string()).unwrap_or(String::new()), e.field_references_to_string(), i64::from(e.flags().bits()), if e.has_attachments() { 1 } else { 0 }, String::from("sdfsa"), e.date().to_be_bytes().to_vec()],
- )
- .map_err(|e| MeliError::new(e.to_string()))?;
+ let work_context = context.work_controller().get_context();
+ let mutexes = context
+ .accounts
+ .iter()
+ .map(|acc| (acc.collection.envelopes.clone(), acc.backend.clone()))
+ .collect::>, Arc<_>)>>();
+ let env_hashes = mutexes
+ .iter()
+ .map(|m| m.0.read().unwrap().keys().cloned().collect::>())
+ .collect::>>();
+
+ /* Sleep, index and repeat in order not to block the main process */
+ let handle = std::thread::Builder::new().name(String::from("rebuilding index")).spawn(move || {
+ let thread_id = std::thread::current().id();
+
+ let sleep_dur = std::time::Duration::from_millis(20);
+ for ((acc_mutex, backend_mutex), env_hashes) in mutexes.into_iter().zip(env_hashes.into_iter()) {
+ let mut ctr = 0;
+ debug!("{}", format!("Rebuilding index. {}/{}", ctr, env_hashes.len()));
+ work_context
+ .set_status
+ .send((thread_id, format!("Rebuilding index. {}/{}", ctr, env_hashes.len())))
+ .unwrap();
+ for chunk in env_hashes.chunks(200) {
+ ctr += chunk.len();
+ let envelopes_lck = acc_mutex.read().unwrap();
+ let backend_lck = backend_mutex.read().unwrap();
+ for env_hash in chunk {
+ if let Some(e) = envelopes_lck.get(&env_hash) {
+ let op = backend_lck.operation(e.hash());
+ let body = match e.body(op) {
+ Ok(body) => body.text(),
+ Err(err) => {
+ debug!("{}",
+ format!(
+ "Failed to open envelope {}: {}",
+ e.message_id_display(),
+ err.to_string()
+ ));
+ log(
+ format!(
+ "Failed to open envelope {}: {}",
+ e.message_id_display(),
+ err.to_string()
+ ),
+ ERROR,
+ );
+ return;
+ }
+ };
+ if let Err(err) = conn.execute(
+ "INSERT OR REPLACE INTO envelopes (hash, date, _from, _to, cc, bcc, subject, message_id, in_reply_to, _references, flags, has_attachments, body_text, timestamp)
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)",
+ params![e.hash().to_be_bytes().to_vec(), e.date_as_str(), e.field_from_to_string(), e.field_to_to_string(), e.field_cc_to_string(), e.field_bcc_to_string(), e.subject().into_owned().trim_end_matches('\u{0}'), e.message_id_display().to_string(), e.in_reply_to_display().map(|f| f.to_string()).unwrap_or(String::new()), e.field_references_to_string(), i64::from(e.flags().bits()), if e.has_attachments() { 1 } else { 0 }, body, e.date().to_be_bytes().to_vec()],
+ )
+ .map_err(|e| MeliError::new(e.to_string())) {
+ debug!("{}",
+ format!(
+ "Failed to insert envelope {}: {}",
+ e.message_id_display(),
+ err.to_string()
+ ));
+ log(
+ format!(
+ "Failed to insert envelope {}: {}",
+ e.message_id_display(),
+ err.to_string()
+ ),
+ ERROR,
+ );
+ }
+ }
+ }
+ drop(envelopes_lck);
+ work_context
+ .set_status
+ .send((thread_id, format!("Rebuilding index. {}/{}", ctr, env_hashes.len())))
+ .unwrap();
+ std::thread::sleep(sleep_dur);
}
}
- */
+ work_context.finished.send(thread_id).unwrap();
+ })?;
+ context.work_controller().static_threads.lock()?.insert(
+ handle.thread().id(),
+ String::from("Rebuilding sqlite3 index").into(),
+ );
Ok(())
}