melib/sqlite3: reset db on version mismatch

jmap-eventsource
Manos Pitsidianakis 2020-10-18 17:41:06 +03:00
parent 54cb4ea623
commit b9f4d718c7
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 57 additions and 42 deletions

View File

@ -321,7 +321,7 @@ impl MailBackend for ImapType {
None None
}; };
let mut state = FetchState { let mut state = FetchState {
stage: if self.uid_store.keep_offline_cache { stage: if self.uid_store.keep_offline_cache && cache_handle.is_some() {
FetchStage::InitialCache FetchStage::InitialCache
} else { } else {
FetchStage::InitialFresh FetchStage::InitialFresh

View File

@ -50,50 +50,65 @@ pub fn open_or_create_db(
description: &DatabaseDescription, description: &DatabaseDescription,
identifier: Option<&str>, identifier: Option<&str>,
) -> Result<Connection> { ) -> Result<Connection> {
let db_path = if let Some(id) = identifier { let mut second_try: bool = false;
db_path(&format!("{}_{}", id, description.name)) loop {
} else { let db_path = if let Some(id) = identifier {
db_path(description.name) db_path(&format!("{}_{}", id, description.name))
}?; } else {
let mut set_mode = false; db_path(description.name)
if !db_path.exists() { }?;
log( let mut set_mode = false;
format!( if !db_path.exists() {
"Creating {} database in {}", log(
description.name, format!(
db_path.display() "Creating {} database in {}",
), description.name,
crate::INFO, db_path.display()
); ),
set_mode = true; crate::INFO,
} );
let conn = Connection::open(&db_path).map_err(|e| MeliError::new(e.to_string()))?; set_mode = true;
if set_mode { }
use std::os::unix::fs::PermissionsExt; let conn = Connection::open(&db_path).map_err(|e| MeliError::new(e.to_string()))?;
let file = std::fs::File::open(&db_path)?; if set_mode {
let metadata = file.metadata()?; use std::os::unix::fs::PermissionsExt;
let mut permissions = metadata.permissions(); let file = std::fs::File::open(&db_path)?;
let metadata = file.metadata()?;
let mut permissions = metadata.permissions();
permissions.set_mode(0o600); // Read/write for owner only. permissions.set_mode(0o600); // Read/write for owner only.
file.set_permissions(permissions)?; file.set_permissions(permissions)?;
} }
let version: i32 = conn.pragma_query_value(None, "user_version", |row| row.get(0))?; let version: i32 = conn.pragma_query_value(None, "user_version", |row| row.get(0))?;
if version != 0_i32 && version as u32 != description.version { if version != 0_i32 && version as u32 != description.version {
return Err(MeliError::new(format!( log(
"Database version mismatch, is {} but expected {}", format!(
version, description.version "Database version mismatch, is {} but expected {}",
))); version, description.version
} ),
crate::INFO,
);
if second_try {
return Err(MeliError::new(format!(
"Database version mismatch, is {} but expected {}. Could not recreate database.",
version, description.version
)));
}
reset_db(description, identifier)?;
second_try = true;
continue;
}
if version == 0 { if version == 0 {
conn.pragma_update(None, "user_version", &description.version)?; conn.pragma_update(None, "user_version", &description.version)?;
} }
if let Some(s) = description.init_script { if let Some(s) = description.init_script {
conn.execute_batch(s) conn.execute_batch(s)
.map_err(|e| MeliError::new(e.to_string()))?; .map_err(|e| MeliError::new(e.to_string()))?;
} }
Ok(conn) return Ok(conn);
}
} }
/// Return database to a clean slate. /// Return database to a clean slate.