rebuild-db: utility to fix DB issues

This commit is contained in:
FliegendeWurst 2021-03-31 12:00:38 +02:00 committed by Arne Keller
parent c9dde850b7
commit 9282813429
3 changed files with 46 additions and 3 deletions

29
src/bin/rebuild-db.rs Normal file
View File

@ -0,0 +1,29 @@
use std::env;
use inboxid::*;
use itertools::Itertools;
use mailparse::MailHeaderMap;
use rusqlite::params;
fn main() -> Result<()> {
let db = get_db()?;
let mut delete_mail = db.prepare("DELETE FROM mail WHERE mailbox = ?")?;
let mut save_mail = db.prepare("INSERT INTO mail VALUES (?,?,?)")?;
let mailboxes = env::args().skip(1).collect_vec();
for mailbox in mailboxes {
let maildir = get_maildir(&mailbox)?;
delete_mail.execute(params![&mailbox])?;
let mut mails = Vec::new();
for x in maildir.list_cur() {
mails.push(x?);
}
let mut mails = maildir.get_mails(&mut mails)?;
mails.sort_by_key(|x| x.date);
for mail in mails {
let headers = mail.get_headers();
let message_id = headers.get_all_values("Message-ID").join(" ");
save_mail.execute(params![&mailbox, mail.id.to_i64(), message_id])?;
}
}
Ok(())
}

View File

@ -82,14 +82,15 @@ fn sync(
let local_uid1 = (full_uid >> 32) as u32;
let local_uid2 = ((full_uid << 32) >> 32) as u32;
let local_id = gen_id(local_uid1, local_uid2);
let new_uid = MaildirID::new(uid1, uid2);
let new_id = new_uid.to_string();
// hardlink mail
let maildir1 = &maildirs[&**inbox];
println!("hardlinking: {}/{} -> {}/{}", inbox, local_id, mailbox, new_id);
let name = maildir1.find_filename(&local_id).unwrap();
let maildir2 = &maildirs[mailbox];
let new_id = gen_id(uid1, uid2);
println!("hardlinking: {}/{} -> {}/{}", inbox, local_id, mailbox, new_id);
maildir2.store_cur_from_path(&new_id, name)?;
save_mail.execute(params![mailbox, store_i64(*full_uid), message_id])?;
save_mail.execute(params![mailbox, new_uid.to_i64(), message_id])?;
} else {
to_fetch.push(uid2);
}

View File

@ -78,6 +78,19 @@ impl ToString for MaildirID {
}
}
impl MaildirID {
pub fn new(x: u32, y: u32) -> Self {
Self {
uid_validity: x,
uid: y
}
}
pub fn to_i64(&self) -> i64 {
store_i64(((self.uid_validity as u64) << 32) | self.uid as u64)
}
}
pub struct EasyMail<'a> {
pub mail: ParsedMail<'a>,
pub id: MaildirID,