From b06366ebb75e0046ce943ea03461dde2acd94f9b Mon Sep 17 00:00:00 2001 From: K Simmons Date: Tue, 18 Oct 2022 11:43:18 -0700 Subject: [PATCH] Get rusqlite more shippable --- Cargo.lock | 1 + crates/auto_update/src/auto_update.rs | 9 ++--- crates/db/Cargo.toml | 3 +- crates/db/src/db.rs | 57 ++++++++++++++++++--------- crates/zed/src/main.rs | 2 +- crates/zed/src/paths.rs | 2 +- 6 files changed, 48 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23b2c8334d..6640037f3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1603,6 +1603,7 @@ dependencies = [ "collections", "gpui", "lazy_static", + "log", "parking_lot 0.11.2", "rusqlite", "rusqlite_migration", diff --git a/crates/auto_update/src/auto_update.rs b/crates/auto_update/src/auto_update.rs index d32835547c..da3d35a2b8 100644 --- a/crates/auto_update/src/auto_update.rs +++ b/crates/auto_update/src/auto_update.rs @@ -283,9 +283,9 @@ impl AutoUpdater { let db = self.db.clone(); cx.background().spawn(async move { if should_show { - db.write([(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY, "")])?; + db.write_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY, "")?; } else { - db.delete([(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)])?; + db.delete_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?; } Ok(()) }) @@ -293,8 +293,7 @@ impl AutoUpdater { fn should_show_update_notification(&self, cx: &AppContext) -> Task> { let db = self.db.clone(); - cx.background().spawn(async move { - Ok(db.read([(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)])?[0].is_some()) - }) + cx.background() + .spawn(async move { Ok(db.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?.is_some()) }) } } diff --git a/crates/db/Cargo.toml b/crates/db/Cargo.toml index 22b4ed1a0d..a2efe13261 100644 --- a/crates/db/Cargo.toml +++ b/crates/db/Cargo.toml @@ -14,10 +14,11 @@ test-support = [] collections = { path = "../collections" } anyhow = "1.0.57" async-trait = "0.1" +lazy_static = "1.4.0" +log = { version = "0.4.16", features = ["kv_unstable_serde"] } parking_lot = "0.11.1" rusqlite = { version = "0.28.0", features = ["bundled", "serde_json"] } rusqlite_migration = "1.0.0" -lazy_static = "1.4.0" [dev-dependencies] gpui = { path = "../gpui", features = ["test-support"] } diff --git a/crates/db/src/db.rs b/crates/db/src/db.rs index 46c8a24fcd..dcef0d659a 100644 --- a/crates/db/src/db.rs +++ b/crates/db/src/db.rs @@ -1,19 +1,22 @@ -mod items; mod kvp; mod migrations; -use anyhow::Result; -use migrations::MIGRATIONS; -use parking_lot::Mutex; -use rusqlite::Connection; use std::path::Path; use std::sync::Arc; -pub use kvp::*; +use anyhow::Result; +use log::error; +use parking_lot::Mutex; +use rusqlite::Connection; -pub struct Db { - connection: Mutex, - in_memory: bool, +use migrations::MIGRATIONS; + +pub enum Db { + Real { + connection: Mutex, + in_memory: bool, + }, + Null, } // To make a migration: @@ -23,25 +26,43 @@ pub struct Db { impl Db { /// Open or create a database at the given file path. Falls back to in memory database if the /// database at the given path is corrupted - pub fn open(path: &Path) -> Result> { - let conn = Connection::open(path)?; - - Self::initialize(conn, false).or_else(|_| Self::open_in_memory()) + pub fn open(path: &Path) -> Arc { + Connection::open(path) + .map_err(Into::into) + .and_then(|connection| Self::initialize(connection, false)) + .unwrap_or_else(|e| { + error!( + "Connecting to db failed. Falling back to in memory db. {}", + e + ); + Self::open_in_memory() + }) } /// Open a in memory database for testing and as a fallback. - pub fn open_in_memory() -> Result> { - let conn = Connection::open_in_memory()?; - - Self::initialize(conn, true) + pub fn open_in_memory() -> Arc { + Connection::open_in_memory() + .map_err(Into::into) + .and_then(|connection| Self::initialize(connection, true)) + .unwrap_or_else(|e| { + error!("Connecting to in memory db failed. Reverting to null db. {}"); + Arc::new(Self::Null) + }) } fn initialize(mut conn: Connection, in_memory: bool) -> Result> { MIGRATIONS.to_latest(&mut conn)?; - Ok(Arc::new(Self { + Ok(Arc::new(Self::Real { connection: Mutex::new(conn), in_memory, })) } + + fn persisting(&self) -> bool { + match self { + Db::Real { in_memory, .. } => *in_memory, + _ => false, + } + } } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index a921bc2680..55cb203ee7 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -55,7 +55,7 @@ fn main() { let db = app.background().spawn(async move { project::Db::open(&*zed::paths::DB) .log_err() - .unwrap_or_else(project::Db::null) + .unwrap_or_else(project::Db::open_in_memory()) }); load_embedded_fonts(&app); diff --git a/crates/zed/src/paths.rs b/crates/zed/src/paths.rs index d6d99288c7..81ecc5be8a 100644 --- a/crates/zed/src/paths.rs +++ b/crates/zed/src/paths.rs @@ -6,7 +6,7 @@ lazy_static::lazy_static! { pub static ref LOGS_DIR: PathBuf = HOME.join("Library/Logs/Zed"); pub static ref LANGUAGES_DIR: PathBuf = HOME.join("Library/Application Support/Zed/languages"); pub static ref DB_DIR: PathBuf = HOME.join("Library/Application Support/Zed/db"); - pub static ref DB: PathBuf = DB_DIR.join("zed.db"); + pub static ref DB: PathBuf = DB_DIR.join("zed.sqlite"); pub static ref SETTINGS: PathBuf = CONFIG_DIR.join("settings.json"); pub static ref KEYMAP: PathBuf = CONFIG_DIR.join("keymap.json"); pub static ref LAST_USERNAME: PathBuf = CONFIG_DIR.join("last-username.txt");