about summary refs log tree commit diff
path: root/src/database
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2021-10-27 06:27:13 +0300
committerVika <vika@fireburn.ru>2021-10-27 06:27:13 +0300
commite559259686f984fdcce5669f0ab8c6dc27d76077 (patch)
tree610543a0d741af11ccf9ebcbcaf5055973ddff72 /src/database
parent5545edcca7d8d67ef156c924351fd9cb912c160b (diff)
Deprecated Redis backend and added a database migration tool (untested, beware)
Diffstat (limited to 'src/database')
-rw-r--r--src/database/file/mod.rs2
-rw-r--r--src/database/mod.rs42
-rw-r--r--src/database/redis/mod.rs26
3 files changed, 50 insertions, 20 deletions
diff --git a/src/database/file/mod.rs b/src/database/file/mod.rs
index f58317e..1e0102a 100644
--- a/src/database/file/mod.rs
+++ b/src/database/file/mod.rs
@@ -402,7 +402,7 @@ impl Storage for FileStorage {
                             }
                         }
                         let posts = stream::iter(posts_iter)
-                            .map(|url| async move {
+                            .map(|url: String| async move {
                                 self.get_post(&url).await
                             })
                             .buffered(std::cmp::min(3, limit))
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 7c67e42..4e74c8f 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -3,32 +3,46 @@ use crate::indieauth::User;
 use async_trait::async_trait;
 use serde::{Deserialize, Serialize};
 
-#[cfg(redis)]
-mod redis;
-#[cfg(redis)]
-pub use crate::database::redis::RedisStorage;
-#[cfg(all(redis, test))]
-pub use redis::tests::{get_redis_instance, RedisInstance};
+//#[cfg(feature="redis")]
+//mod redis;
+//#[cfg(feature="redis")]
+//pub use crate::database::redis::RedisStorage;
+//#[cfg(all(redis, test))]
+//pub use redis::tests::{get_redis_instance, RedisInstance};
 
 mod file;
 pub use crate::database::file::FileStorage;
 
+/// Data structure representing a Micropub channel in the ?q=channels output.
 #[derive(Serialize, Deserialize, PartialEq, Debug)]
 pub struct MicropubChannel {
+    /// The channel's UID. It is usually also a publically accessible permalink URL.
     pub uid: String,
+    /// The channel's user-friendly name used to recognize it in lists.
     pub name: String,
 }
 
+/// Enum representing different errors that might occur during the database query.
 #[derive(Debug, Clone, Copy)]
 pub enum ErrorKind {
+    /// Backend error (e.g. database connection error)
     Backend,
+    /// Error due to insufficient contextual permissions for the query
     PermissionDenied,
+    /// Error due to the database being unable to parse JSON returned from the backing storage.
+    /// Usually indicative of someone fiddling with the database manually instead of using proper tools.
     JsonParsing,
+    ///  - ErrorKind::NotFound - equivalent to a 404 error. Note, some requests return an Option,
+    ///    in which case None is also equivalent to a 404.
     NotFound,
+    /// The user's query or request to the database was malformed. Used whenever the database processes
+    /// the user's query directly, such as when editing posts inside of the database (e.g. Redis backend)
     BadRequest,
+    ///  - ErrorKind::Other - when something so weird happens that it becomes undescribable.
     Other,
 }
 
+/// Error signalled from the database.
 #[derive(Debug)]
 pub struct StorageError {
     msg: String,
@@ -115,6 +129,7 @@ impl StorageError {
     pub fn kind(&self) -> ErrorKind {
         self.kind
     }
+    /// Get the message as a string slice.
     pub fn msg(&self) -> &str {
         &self.msg
     }
@@ -238,8 +253,8 @@ pub trait Storage: Clone + Send + Sync {
 
 #[cfg(test)]
 mod tests {
-    #[cfg(redis)]
-    use super::redis::tests::get_redis_instance;
+    //#[cfg(feature="redis")]
+    //use super::redis::tests::get_redis_instance;
     use super::{MicropubChannel, Storage};
     use serde_json::json;
     use paste::paste;
@@ -404,10 +419,11 @@ mod tests {
             "Vika's Hideout"
         );
     }
-    macro_rules! redis_test {
+    
+    /*macro_rules! redis_test {
         ($func_name:expr) => {
             paste! {
-                #[cfg(redis)]
+                #[cfg(feature="redis")]
                 #[async_std::test]
                 async fn [<redis_ $func_name>] () {
                     test_logger::ensure_env_logger_initialized();
@@ -419,7 +435,7 @@ mod tests {
                 }
             }
         }
-    }
+    }*/
 
     macro_rules! file_test {
         ($func_name:expr) => {
@@ -435,10 +451,10 @@ mod tests {
         }
     }
 
-    redis_test!(test_backend_basic_operations);
+    /*redis_test!(test_backend_basic_operations);
     redis_test!(test_backend_get_channel_list);
     redis_test!(test_backend_settings);
-    redis_test!(test_backend_update);
+    redis_test!(test_backend_update);*/
     file_test!(test_backend_basic_operations);
     file_test!(test_backend_get_channel_list);
     file_test!(test_backend_settings);
diff --git a/src/database/redis/mod.rs b/src/database/redis/mod.rs
index f1724b7..eeaa3f2 100644
--- a/src/database/redis/mod.rs
+++ b/src/database/redis/mod.rs
@@ -2,6 +2,7 @@ use async_trait::async_trait;
 use futures::stream;
 use futures_util::FutureExt;
 use futures_util::StreamExt;
+use futures_util::TryStream;
 use futures_util::TryStreamExt;
 use lazy_static::lazy_static;
 use log::error;
@@ -225,9 +226,13 @@ impl Storage for RedisStorage {
                     }
                 }
             }
+            async fn fetch_post_for_feed(url: String) -> Option<serde_json::Value> {
+                return Some(serde_json::json!({}));
+            }
             let posts = stream::iter(posts_iter)
-                .map(|url| async move {
-                    match self.redis.get().await {
+                .map(|url: String| async move {
+                    return Ok(fetch_post_for_feed(url).await);
+                    /*match self.redis.get().await {
                         Ok(mut conn) => {
                             match conn.hget::<&str, &str, Option<String>>("posts", &url).await {
                                 Ok(post) => match post {
@@ -241,18 +246,21 @@ impl Storage for RedisStorage {
                             }
                         }
                         Err(err) => Err(StorageError::with_source(ErrorKind::Backend, "Error getting a connection from the pool", Box::new(err)))
-                    }
+                    }*/
                 })
                 // TODO: determine the optimal value for this buffer
                 // It will probably depend on how often can you encounter a private post on the page
                 // It shouldn't be too large, or we'll start fetching too many posts from the database
                 // It MUST NOT be larger than the typical page size
                 // It MUST NOT be a significant amount of the connection pool size
-                .buffered(std::cmp::min(3, limit))
+                //.buffered(std::cmp::min(3, limit))
                 // Hack to unwrap the Option and sieve out broken links
                 // Broken links return None, and Stream::filter_map skips all Nones.
-                .try_filter_map(|post: Option<serde_json::Value>| async move { Ok(post) })
-                .try_filter_map(|post| async move { Ok(filter_post(post, user)) })
+                // I wonder if one can use try_flatten() here somehow akin to iters
+                .try_filter_map(|post| async move { Ok(post) })
+                .try_filter_map(|post| async move {
+                    Ok(filter_post(post, user))
+                })
                 .take(limit);
             match posts.try_collect::<Vec<serde_json::Value>>().await {
                 Ok(posts) => feed["children"] = json!(posts),
@@ -312,6 +320,12 @@ impl RedisStorage {
             Err(e) => Err(e.into()),
         }
     }
+
+    pub async fn conn(&self) -> Result<mobc::Connection<mobc_redis::RedisConnectionManager>> {
+        self.redis.get().await.map_err(|e| StorageError::with_source(
+            ErrorKind::Backend, "Error getting a connection from the pool", Box::new(e)
+        ))
+    }
 }
 
 #[cfg(test)]