about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2022-02-21 20:51:00 +0300
committerVika <vika@fireburn.ru>2022-02-21 20:51:00 +0300
commitf726a42f6190ee3f0438a83823b89fa038eb8301 (patch)
tree69600d1948ea23068c22117d4f92751c358bb6c1
parentd6064461e9ef4da518eea684e6dea7b8fcddc470 (diff)
database: code cleanup
-rw-r--r--src/database/file/mod.rs28
-rw-r--r--src/database/mod.rs49
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);
-    */
+
 }