ui/sqlite3: add env body in sqlite3 fts table
Add the envelope body in the full text search table inside the sqlite3 db. Now search returns results matching the e-mail content as well.sql
parent
3b5dc33d3e
commit
70fb34a2e4
|
@ -19,11 +19,13 @@
|
||||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
use melib::backends::{FolderHash, MailBackend};
|
use melib::backends::{FolderHash, MailBackend};
|
||||||
use melib::email::{EnvelopeHash, Flag, UnixTimestamp};
|
|
||||||
use melib::mailbox::*;
|
use melib::mailbox::*;
|
||||||
use melib::thread::{ThreadHash, ThreadNode};
|
use melib::thread::{ThreadHash, ThreadNode};
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
*/
|
||||||
|
use melib::email::{Flag, UnixTimestamp};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Query {
|
pub enum Query {
|
||||||
|
@ -47,17 +49,16 @@ pub enum Query {
|
||||||
Flag(Flag),
|
Flag(Flag),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
enum CacheType {
|
enum CacheType {
|
||||||
Sqlite3,
|
Sqlite3,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
collection: Collection,
|
collection: Collection,
|
||||||
kind: CacheType,
|
kind: CacheType,
|
||||||
backend: Box<dyn MailBackend>,
|
backend: Box<dyn MailBackend>,
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
|
|
||||||
impl Cache {
|
impl Cache {
|
||||||
pub fn build_index(&mut self) {
|
pub fn build_index(&mut self) {
|
||||||
|
|
|
@ -38,9 +38,6 @@ impl fmt::Display for StatusPanel {
|
||||||
|
|
||||||
impl Component for StatusPanel {
|
impl Component for StatusPanel {
|
||||||
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
|
||||||
if !self.dirty {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let (width, height) = self.content.size();
|
let (width, height) = self.content.size();
|
||||||
{
|
{
|
||||||
let (_, y) = write_string_to_grid(
|
let (_, y) = write_string_to_grid(
|
||||||
|
@ -143,7 +140,6 @@ impl Component for StatusPanel {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
self.dirty = false;
|
|
||||||
context.dirty_areas.push_back(area);
|
context.dirty_areas.push_back(area);
|
||||||
}
|
}
|
||||||
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use fnv::FnvHashMap;
|
|
||||||
use melib::{
|
use melib::{
|
||||||
email::{Envelope, EnvelopeHash},
|
email::EnvelopeHash,
|
||||||
|
log,
|
||||||
thread::{SortField, SortOrder},
|
thread::{SortField, SortOrder},
|
||||||
MeliError, Result, StackVec,
|
MeliError, Result, StackVec, ERROR,
|
||||||
};
|
};
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection};
|
||||||
use std::borrow::Cow;
|
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()))?,
|
||||||
)
|
)
|
||||||
.map_err(|e| MeliError::new(e.to_string()))?;
|
.map_err(|e| MeliError::new(e.to_string()))?;
|
||||||
/*
|
let work_context = context.work_controller().get_context();
|
||||||
for acc in context.accounts.iter() {
|
let mutexes = context
|
||||||
debug!("inserting {} envelopes", acc.collection.envelopes.len());
|
.accounts
|
||||||
for e in acc.collection.envelopes.values() {
|
.iter()
|
||||||
conn.execute(
|
.map(|acc| (acc.collection.envelopes.clone(), acc.backend.clone()))
|
||||||
"INSERT OR REPLACE INTO envelopes (hash, date, _from, _to, cc, bcc, subject, message_id, in_reply_to, _references, flags, has_attachments, body_text, timestamp)
|
.collect::<Vec<(Arc<RwLock<_>>, Arc<_>)>>();
|
||||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)",
|
let env_hashes = mutexes
|
||||||
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()],
|
.iter()
|
||||||
)
|
.map(|m| m.0.read().unwrap().keys().cloned().collect::<Vec<_>>())
|
||||||
.map_err(|e| MeliError::new(e.to_string()))?;
|
.collect::<Vec<Vec<_>>>();
|
||||||
|
|
||||||
|
/* 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue