From 92828134292bff1c86e33f92ef5e6be938eb8ada Mon Sep 17 00:00:00 2001 From: FliegendeWurst <2012gdwu+github@posteo.de> Date: Wed, 31 Mar 2021 12:00:38 +0200 Subject: [PATCH] rebuild-db: utility to fix DB issues --- src/bin/rebuild-db.rs | 29 +++++++++++++++++++++++++++++ src/bin/sync.rs | 7 ++++--- src/lib.rs | 13 +++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/bin/rebuild-db.rs diff --git a/src/bin/rebuild-db.rs b/src/bin/rebuild-db.rs new file mode 100644 index 0000000..1906213 --- /dev/null +++ b/src/bin/rebuild-db.rs @@ -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(()) +} diff --git a/src/bin/sync.rs b/src/bin/sync.rs index e7f650f..e41c16e 100644 --- a/src/bin/sync.rs +++ b/src/bin/sync.rs @@ -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); } diff --git a/src/lib.rs b/src/lib.rs index 1ed270e..5c363e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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,