diff options
author | Vika <vika@fireburn.ru> | 2022-02-21 20:51:00 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2022-02-21 20:51:00 +0300 |
commit | f726a42f6190ee3f0438a83823b89fa038eb8301 (patch) | |
tree | 69600d1948ea23068c22117d4f92751c358bb6c1 | |
parent | d6064461e9ef4da518eea684e6dea7b8fcddc470 (diff) | |
download | kittybox-f726a42f6190ee3f0438a83823b89fa038eb8301.tar.zst |
database: code cleanup
-rw-r--r-- | src/database/file/mod.rs | 28 | ||||
-rw-r--r-- | src/database/mod.rs | 49 |
2 files changed, 29 insertions, 48 deletions
diff --git a/src/database/file/mod.rs b/src/database/file/mod.rs index da8a06a..d1227d8 100644 --- a/src/database/file/mod.rs +++ b/src/database/file/mod.rs @@ -196,7 +196,7 @@ fn modify_post(post: &serde_json::Value, update: &serde_json::Value) -> Result<s Ok(post) } -#[derive(Clone)] +#[derive(Clone, Debug)] /// A backend using a folder with JSON files as a backing store. /// Uses symbolic links to represent a many-to-one mapping of URLs to a post. pub struct FileStorage { @@ -271,11 +271,12 @@ impl Storage for FileStorage { let lock = RwLock::new(file); debug!("Trying to get a lock for file {:?}", &path); let guard = lock.read()?; - + debug!("Lock for {:?} acquired", &path); let mut content = String::new(); // Typechecks because OS magic acts on references // to FDs as if they were behind a mutex (&mut &*guard).read_to_string(&mut content)?; + debug!("Read {} bytes successfully from {:?}", content.as_bytes().len(), &path); Ok(Some(serde_json::from_str(&content)?)) } Err(err) => { @@ -291,7 +292,7 @@ impl Storage for FileStorage { })).await?.unwrap() } - async fn put_post<'a>(&self, post: &'a serde_json::Value, user: &'a str) -> Result<()> { + async fn put_post(&self, post: &'_ serde_json::Value, user: &'_ str) -> Result<()> { let key = post["properties"]["uid"][0] .as_str() .expect("Tried to save a post without UID"); @@ -384,6 +385,7 @@ impl Storage for FileStorage { .map(|s| s.to_string()) .unwrap_or_else(String::default); let key = key.to_string(); + #[allow(clippy::drop_ref)] // using drop() to prevent mistakes here drop(post); tokio::time::timeout(Duration::from_secs(IO_TIMEOUT), spawn_blocking(move || { let file = OpenOptions::new() @@ -421,7 +423,7 @@ impl Storage for FileStorage { Ok(()) } - async fn update_post<'a>(&self, url: &'a str, update: serde_json::Value) -> Result<()> { + async fn update_post(&self, url: &'_ str, update: serde_json::Value) -> Result<()> { let path = url_to_path(&self.root_dir, url); #[allow(unused_variables)] let (old_json, new_json) = tokio::time::timeout( @@ -454,7 +456,7 @@ impl Storage for FileStorage { Ok(()) } - async fn get_channels<'a>(&self, user: &'a str) -> Result<Vec<super::MicropubChannel>> { + async fn get_channels(&self, user: &'_ str) -> Result<Vec<super::MicropubChannel>> { let mut path = relative_path::RelativePathBuf::new(); path.push(warp::http::Uri::try_from(user.to_string()).unwrap().authority().unwrap().to_string()); path.push("channels"); @@ -486,12 +488,12 @@ impl Storage for FileStorage { })).await?.unwrap() } - async fn read_feed_with_limit<'a>( + async fn read_feed_with_limit( &self, - url: &'a str, - after: &'a Option<String>, + url: &'_ str, + after: &'_ Option<String>, limit: usize, - user: &'a Option<String>, + user: &'_ Option<String>, ) -> Result<Option<serde_json::Value>> { if let Some(feed) = self.get_post(url).await? { if let Some(mut feed) = filter_post(feed, user) { @@ -545,7 +547,7 @@ impl Storage for FileStorage { } } - async fn delete_post<'a>(&self, url: &'a str) -> Result<()> { + async fn delete_post(&self, url: &'_ str) -> Result<()> { let path = url_to_path(&self.root_dir, url); if let Err(e) = tokio::fs::remove_file(path).await { Err(e.into()) @@ -555,7 +557,7 @@ impl Storage for FileStorage { } } - async fn get_setting<'a>(&self, setting: &'a str, user: &'a str) -> Result<String> { + async fn get_setting(&self, setting: &'_ str, user: &'_ str) -> Result<String> { log::debug!("User for getting settings: {}", user); let url = http_types::Url::parse(user).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); @@ -581,7 +583,7 @@ impl Storage for FileStorage { })).await?.unwrap() } - async fn set_setting<'a>(&self, setting: &'a str, user: &'a str, value: &'a str) -> Result<()> { + async fn set_setting(&self, setting: &'_ str, user: &'_ str, value: &'_ str) -> Result<()> { let url = http_types::Url::parse(user).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); path.push(url.origin().ascii_serialization()); @@ -618,7 +620,7 @@ impl Storage for FileStorage { settings.insert(setting.to_string(), value.to_string()); (&mut *guard).seek(SeekFrom::Start(0))?; - (&mut *guard).set_len(0)?; + (*guard).set_len(0)?; (&mut *guard).write_all(serde_json::to_string(&settings)?.as_bytes())?; Result::Ok(()) })).await?.unwrap() diff --git a/src/database/mod.rs b/src/database/mod.rs index 55ab027..6fdb9b1 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -42,25 +42,6 @@ pub struct StorageError { kind: ErrorKind, } -/*impl From<StorageError> for tide::Response { - fn from(err: StorageError) -> Self { - tide::Response::builder(match err.kind() { - ErrorKind::BadRequest => 400, - ErrorKind::NotFound => 404, - _ => 500, - }) - .body(serde_json::json!({ - "error": match err.kind() { - ErrorKind::BadRequest => "invalid_request", - ErrorKind::NotFound => "not_found", - _ => "database_error" - }, - "error_description": err - })) - .build() - } -}*/ - impl std::error::Error for StorageError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.source @@ -198,7 +179,7 @@ pub fn filter_post( /// Implementations should note that all methods listed on this trait MUST be fully atomic /// or lock the database so that write conflicts or reading half-written data should not occur. #[async_trait] -pub trait Storage: Clone + Send + Sync { +pub trait Storage: std::fmt::Debug + Clone + Send + Sync { /// Check if a post exists in the database. async fn post_exists(&self, url: &str) -> Result<bool>; @@ -208,7 +189,7 @@ pub trait Storage: Clone + Send + Sync { /// Save a post to the database as an MF2-JSON structure. /// /// Note that the `post` object MUST have `post["properties"]["uid"][0]` defined. - async fn put_post<'a>(&self, post: &'a serde_json::Value, user: &'a str) -> Result<()>; + async fn put_post(&self, post: &'_ serde_json::Value, user: &'_ str) -> Result<()>; /// Modify a post using an update object as defined in the Micropub spec. /// @@ -217,10 +198,10 @@ pub trait Storage: Clone + Send + Sync { /// /// You can assume concurrent updates will never contradict each other, since that will be dumb. /// The last update always wins. - async fn update_post<'a>(&self, url: &'a str, update: serde_json::Value) -> Result<()>; + async fn update_post(&self, url: &'_ str, update: serde_json::Value) -> Result<()>; /// Get a list of channels available for the user represented by the URL `user` to write to. - async fn get_channels<'a>(&self, user: &'a str) -> Result<Vec<MicropubChannel>>; + async fn get_channels(&self, user: &'_ str) -> Result<Vec<MicropubChannel>>; /// Fetch a feed at `url` and return a an h-feed object containing /// `limit` posts after a post by url `after`, filtering the content @@ -239,28 +220,26 @@ pub trait Storage: Clone + Send + Sync { /// from the database, preferably make this method use a connection pool /// to reduce overhead of creating a database connection per post for /// parallel fetching. - async fn read_feed_with_limit<'a>( + async fn read_feed_with_limit( &self, - url: &'a str, - after: &'a Option<String>, + url: &'_ str, + after: &'_ Option<String>, limit: usize, - user: &'a Option<String>, + user: &'_ Option<String>, ) -> Result<Option<serde_json::Value>>; /// Deletes a post from the database irreversibly. 'nuff said. Must be idempotent. - async fn delete_post<'a>(&self, url: &'a str) -> Result<()>; + async fn delete_post(&self, url: &'_ str) -> Result<()>; /// Gets a setting from the setting store and passes the result. - async fn get_setting<'a>(&self, setting: &'a str, user: &'a str) -> Result<String>; + async fn get_setting(&self, setting: &'_ str, user: &'_ str) -> Result<String>; /// Commits a setting to the setting store. - async fn set_setting<'a>(&self, setting: &'a str, user: &'a str, value: &'a str) -> Result<()>; + async fn set_setting(&self, setting: &'_ str, user: &'_ str, value: &'_ str) -> Result<()>; } #[cfg(test)] mod tests { - //#[cfg(feature="redis")] - //use super::redis::tests::get_redis_instance; use super::{MicropubChannel, Storage}; use paste::paste; use serde_json::json; @@ -425,10 +404,10 @@ mod tests { ); } - /*macro_rules! file_test { + macro_rules! file_test { ($func_name:expr) => { paste! { - #[async_std::test] + #[tokio::test] async fn [<file_ $func_name>] () { test_logger::ensure_env_logger_initialized(); let tempdir = tempdir::TempDir::new("file").expect("Failed to create tempdir"); @@ -443,5 +422,5 @@ mod tests { file_test!(test_backend_get_channel_list); file_test!(test_backend_settings); file_test!(test_backend_update); - */ + } |