Skip to content

Commit

Permalink
refactor(service/postgresql): Add PostgresqlConfig to implement Confi…
Browse files Browse the repository at this point in the history
…gDeserializer (#3495)

* add PostgresqlConfig, Implement ConfigDeserializer

* avoid print connection_string, add PostgresqlConfig mod at services/mod.rs

* add cfg feature
  • Loading branch information
sd44 authored Nov 7, 2023
1 parent 1ac054d commit bdd4228
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 28 deletions.
2 changes: 2 additions & 0 deletions core/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
85 changes: 57 additions & 28 deletions core/src/services/postgresql/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,64 @@ 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;

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()
}
}

Expand Down Expand Up @@ -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
}
Expand All @@ -94,15 +128,15 @@ 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
}

/// 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
}
Expand All @@ -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
}
Expand All @@ -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
}
Expand All @@ -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(
Expand All @@ -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(),
Expand Down
1 change: 1 addition & 0 deletions core/src/services/postgresql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@

mod backend;
pub use backend::PostgresqlBuilder as Postgresql;
pub use backend::PostgresqlConfig;

0 comments on commit bdd4228

Please sign in to comment.