This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new bdd4228d3 refactor(service/postgresql): Add PostgresqlConfig to 
implement ConfigDeserializer (#3495)
bdd4228d3 is described below

commit bdd4228d3e50ecf80eed1381c22fcbfc797695d0
Author: 蛋疼的蛋蛋 <[email protected]>
AuthorDate: Tue Nov 7 10:43:53 2023 +0800

    refactor(service/postgresql): Add PostgresqlConfig to implement 
ConfigDeserializer (#3495)
    
    * add PostgresqlConfig, Implement ConfigDeserializer
    
    * avoid print connection_string, add PostgresqlConfig mod at services/mod.rs
    
    * add cfg feature
---
 core/src/services/mod.rs                |  2 +
 core/src/services/postgresql/backend.rs | 85 ++++++++++++++++++++++-----------
 core/src/services/postgresql/mod.rs     |  1 +
 3 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/core/src/services/mod.rs b/core/src/services/mod.rs
index cb84289a3..4a3dbbf5b 100644
--- a/core/src/services/mod.rs
+++ b/core/src/services/mod.rs
@@ -215,6 +215,8 @@ pub use self::foundationdb::Foundationdb;
 mod postgresql;
 #[cfg(feature = "services-postgresql")]
 pub use self::postgresql::Postgresql;
+#[cfg(feature = "services-postgresql")]
+pub use self::postgresql::PostgresqlConfig;
 
 #[cfg(feature = "services-atomicserver")]
 mod atomicserver;
diff --git a/core/src/services/postgresql/backend.rs 
b/core/src/services/postgresql/backend.rs
index ac7b82a5a..7e3aafd01 100644
--- a/core/src/services/postgresql/backend.rs
+++ b/core/src/services/postgresql/backend.rs
@@ -24,6 +24,7 @@ use std::sync::Arc;
 use async_trait::async_trait;
 use bb8::Pool;
 use bb8_postgres::PostgresConnectionManager;
+use serde::Deserialize;
 use tokio::sync::OnceCell;
 use tokio_postgres::Config;
 
@@ -31,23 +32,56 @@ use crate::raw::adapters::kv;
 use crate::raw::*;
 use crate::*;
 
-/// [Postgresql](https://www.postgresql.org/) services support.
-#[doc = include_str!("docs.md")]
-#[derive(Default)]
-pub struct PostgresqlBuilder {
+/// Config for PostGresQL services support.
+#[derive(Default, Deserialize)]
+#[serde(default)]
+#[non_exhaustive]
+pub struct PostgresqlConfig {
+    /// root of this backend.
+    ///
+    /// All operations will happen under this root.
+    ///
+    /// default to `/` if not set.
+    pub root: Option<String>,
+    /// the connection string of postgres server
     connection_string: Option<String>,
-
+    /// the table of postgresql
     table: Option<String>,
+    /// the key field of postgresql
     key_field: Option<String>,
+    /// the value field of postgresql
     value_field: Option<String>,
-    root: Option<String>,
+}
+
+impl Debug for PostgresqlConfig {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        let mut d = f.debug_struct("PostgresqlConfig");
+
+        if self.connection_string.is_some() {
+            d.field("connection_string", &"<redacted>");
+        }
+
+        d.field("root", &self.root)
+            .field("table", &self.table)
+            .field("key_field", &self.key_field)
+            .field("value_field", &self.value_field)
+            .finish()
+    }
+}
+
+/// [Postgresql](https://www.postgresql.org/) services support.
+#[doc = include_str!("docs.md")]
+#[derive(Default)]
+pub struct PostgresqlBuilder {
+    config: PostgresqlConfig,
 }
 
 impl Debug for PostgresqlBuilder {
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
-        let mut ds = f.debug_struct("Builder");
-        ds.field("table", &self.table);
-        ds.finish()
+        let mut d = f.debug_struct("PostgresqlBuilder");
+
+        d.field("config", &self.config);
+        d.finish()
     }
 }
 
@@ -84,7 +118,7 @@ impl PostgresqlBuilder {
     /// For more information, please visit 
<https://docs.rs/postgres/latest/postgres/config/struct.Config.html>
     pub fn connection_string(&mut self, v: &str) -> &mut Self {
         if !v.is_empty() {
-            self.connection_string = Some(v.to_string());
+            self.config.connection_string = Some(v.to_string());
         }
         self
     }
@@ -94,7 +128,7 @@ impl PostgresqlBuilder {
     /// default: "/"
     pub fn root(&mut self, root: &str) -> &mut Self {
         if !root.is_empty() {
-            self.root = Some(root.to_owned());
+            self.config.root = Some(root.to_owned());
         }
         self
     }
@@ -102,7 +136,7 @@ impl PostgresqlBuilder {
     /// Set the table name of the postgresql service to read/write.
     pub fn table(&mut self, table: &str) -> &mut Self {
         if !table.is_empty() {
-            self.table = Some(table.to_string());
+            self.config.table = Some(table.to_string());
         }
         self
     }
@@ -112,7 +146,7 @@ impl PostgresqlBuilder {
     /// Default to `key` if not specified.
     pub fn key_field(&mut self, key_field: &str) -> &mut Self {
         if !key_field.is_empty() {
-            self.key_field = Some(key_field.to_string());
+            self.config.key_field = Some(key_field.to_string());
         }
         self
     }
@@ -122,7 +156,7 @@ impl PostgresqlBuilder {
     /// Default to `value` if not specified.
     pub fn value_field(&mut self, value_field: &str) -> &mut Self {
         if !value_field.is_empty() {
-            self.value_field = Some(value_field.to_string());
+            self.config.value_field = Some(value_field.to_string());
         }
         self
     }
@@ -133,20 +167,14 @@ impl Builder for PostgresqlBuilder {
     type Accessor = PostgresqlBackend;
 
     fn from_map(map: HashMap<String, String>) -> Self {
-        let mut builder = PostgresqlBuilder::default();
-
-        map.get("connection_string")
-            .map(|v| builder.connection_string(v));
-        map.get("table").map(|v| builder.table(v));
-        map.get("key_field").map(|v| builder.key_field(v));
-        map.get("value_field").map(|v| builder.value_field(v));
-        map.get("root").map(|v| builder.root(v));
+        let config = 
PostgresqlConfig::deserialize(ConfigDeserializer::new(map))
+            .expect("config deserialize must succeed");
 
-        builder
+        PostgresqlBuilder { config }
     }
 
     fn build(&mut self) -> Result<Self::Accessor> {
-        let conn = match self.connection_string.clone() {
+        let conn = match self.config.connection_string.clone() {
             Some(v) => v,
             None => {
                 return Err(
@@ -162,23 +190,24 @@ impl Builder for PostgresqlBuilder {
                 .set_source(err)
         })?;
 
-        let table = match self.table.clone() {
+        let table = match self.config.table.clone() {
             Some(v) => v,
             None => {
                 return Err(Error::new(ErrorKind::ConfigInvalid, "table is 
empty")
                     .with_context("service", Scheme::Postgresql))
             }
         };
-        let key_field = match self.key_field.clone() {
+        let key_field = match self.config.key_field.clone() {
             Some(v) => v,
             None => "key".to_string(),
         };
-        let value_field = match self.value_field.clone() {
+        let value_field = match self.config.value_field.clone() {
             Some(v) => v,
             None => "value".to_string(),
         };
         let root = normalize_root(
-            self.root
+            self.config
+                .root
                 .clone()
                 .unwrap_or_else(|| "/".to_string())
                 .as_str(),
diff --git a/core/src/services/postgresql/mod.rs 
b/core/src/services/postgresql/mod.rs
index 427152a7e..ca185a4ec 100644
--- a/core/src/services/postgresql/mod.rs
+++ b/core/src/services/postgresql/mod.rs
@@ -17,3 +17,4 @@
 
 mod backend;
 pub use backend::PostgresqlBuilder as Postgresql;
+pub use backend::PostgresqlConfig;

Reply via email to