mod ssl_mode;
use std::collections::HashMap;
use std::future::Future;
use std::pin::Pin;
use std::time::Duration;
use futures::future::BoxFuture;
use tokio_postgres::{Client, NoTls};
use tokio_postgres::config::SslMode;
use native_tls::{Certificate, TlsConnector};
use postgres_native_tls::MakeTlsConnector;
use std::fs;
use tracing_subscriber::fmt::time;
use url::Url;
use rsdbc_core::connection::{Batch, Connection, ConnectionFactory, ConnectionFactoryMetadata, ConnectionFactoryOptions, ConnectionFactoryProvider, ConnectionMetadata, IsolationLevel, Statement, ValidationDepth};
use rsdbc_core::error::RsdbcErrors;
use rsdbc_core::{OptionValue, Result, TransactionDefinition};
pub struct PostgresqlConnectionConfiguration {
pub application_name: String,
pub auto_detect_extensions: bool, pub compatibility_mode: bool,
pub connection_timeout: Duration,
pub database: String,
pub fetch_size: u64,
pub force_binary: bool,
pub host: String,
pub options: HashMap<String, String>,
pub password: String,
pub port: u32, pub prepared_statement_cache_queries: i32,
pub schema: String,
pub socket: String,
pub ssl_cert: Option<Url>,
pub ssl_key: Option<Url>,
pub ssl_mode: ssl_mode::SslMode, pub ssl_password: String,
pub ssl_root_cert: Option<Url>,
pub statement_timeout: Duration,
pub tcp_keep_alive: bool,
pub tcp_no_delay: bool, pub username: String,
}
impl PostgresqlConnectionConfiguration {
fn new() -> Self {
Self {
application_name: "rsdbc-postgresql".to_string(), auto_detect_extensions: false,
compatibility_mode: false,
connection_timeout: Default::default(),
database: "".to_string(),
fetch_size: 0,
force_binary: false,
host: "".to_string(),
options: Default::default(),
password: "".to_string(),
port: 5432,
prepared_statement_cache_queries: 0,
schema: "".to_string(),
socket: "".to_string(),
ssl_cert: None,
ssl_key: None,
ssl_mode: ssl_mode::SslMode::Disable,
ssl_password: "".to_string(),
ssl_root_cert: None,
statement_timeout: Default::default(),
tcp_keep_alive: false,
tcp_no_delay: false,
username: "".to_string()
}
}
pub fn application_name(&mut self, name: String) -> &mut Self {
self.application_name = name;
self
}
pub fn auto_detect_extensions(&mut self, auto_detect: bool) -> &mut Self {
self.auto_detect_extensions = auto_detect;
self
}
pub fn compatibility_mode(&mut self, compatibility_mode: bool) -> &mut Self {
self.compatibility_mode = compatibility_mode;
self
}
pub fn connect_timeout(&mut self, timeout: Duration) -> &mut Self {
self.connection_timeout = timeout;
self
}
pub fn database(&mut self, database: String) -> &mut Self {
self.database = database;
self
}
pub fn enable_ssl(&mut self) -> &mut Self {
self.ssl_mode = ssl_mode::SslMode::Require; self
}
pub fn fetch_size(&mut self, fetch_size: u64) -> &mut Self {
self.fetch_size = fetch_size;
self
}
pub fn force_binary(&mut self, force_binary: bool) -> &mut Self {
self.force_binary = force_binary;
self
}
pub fn host(&mut self, host: String) -> &mut Self {
self.host = host;
self
}
pub fn options(&mut self, options: HashMap<String, String>) -> &mut Self {
self.options = options;
self
}
pub fn password(&mut self, password: String) -> &mut Self {
self.password = password;
self
}
pub fn port(&mut self, port: u32) -> &mut Self {
self.port = port;
self
}
pub fn prepared_statement_cache_queries(&mut self, prepared_statement_cache_queries: i32) -> &mut Self {
self.prepared_statement_cache_queries = prepared_statement_cache_queries;
self
}
pub fn schema(&mut self, schema: String) -> &mut Self {
self.schema = schema;
self
}
pub fn socket(&mut self, socket: String) -> &mut Self {
self.socket = socket;
self.ssl_mode = ssl_mode::SslMode::Disable;
self
}
pub fn ssl_url(&mut self, ssl_cert: Url) -> &mut Self {
self.ssl_key = Some(ssl_cert);
self
}
pub fn sslkey_url(&mut self, sslkey: Url) -> &mut Self {
self.ssl_key = Some(sslkey);
self
}
pub fn ssl_mode(&mut self, ssl_mode: ssl_mode::SslMode) -> &mut Self {
self.ssl_mode = ssl_mode;
self
}
pub fn ssl_password(&mut self, ssl_password: String) -> &mut Self {
self.ssl_password = ssl_password;
self
}
pub fn ssl_root_cert_url(&mut self, ssl_root_cert: Url) -> &mut Self {
self.ssl_root_cert = Some(ssl_root_cert);
self
}
pub fn tcp_keep_alive(&mut self, enabled: bool) -> &mut Self {
self.tcp_keep_alive = enabled;
self
}
pub fn tcp_no_delay(&mut self, enabled: bool) -> &mut Self {
self.tcp_no_delay = enabled;
self
}
pub fn username(&mut self, username: String) -> &mut Self {
self.username = username;
self
}
}
pub struct PostgresqlConnectionFactory {
pub configuration: PostgresqlConnectionConfiguration
}
pub struct PostgresqlConnection {
client: Client,
}
impl Connection for PostgresqlConnection {
fn begin_transaction(&mut self) -> Result<()> {
todo!()
}
fn close(&mut self) -> Result<()> {
todo!()
}
fn commit_transaction(&mut self) {
todo!()
}
fn create_batch(&mut self) -> Result<Box<dyn Batch>> {
todo!()
}
fn create_savepoint(&mut self, name: &str) {
todo!()
}
fn create_statement(&mut self, sql: &str) -> Result<Box<dyn Statement<'_> + '_>> {
todo!()
}
fn is_auto_commit(&mut self) -> bool {
todo!()
}
fn metadata(&mut self) -> Result<Box<dyn ConnectionMetadata>> {
todo!()
}
fn transaction_isolation_level(&mut self) -> IsolationLevel {
todo!()
}
fn release_savepoint(&mut self, name: &str) {
todo!()
}
fn rollback_transaction(&mut self) {
todo!()
}
fn rollback_transaction_to_savepoint(&mut self, name: String) {
todo!()
}
fn auto_commit(&mut self, commit: bool) {
todo!()
}
fn set_transaction_isolation_level(&mut self, isolation_level: IsolationLevel) {
todo!()
}
fn validate(&mut self, depth: ValidationDepth) -> bool {
if self.client.is_closed() {
return false;
}
let query = self.client.simple_query("SELECT 1");
return true;
}
}
impl ConnectionFactory for PostgresqlConnectionFactory {
fn connect(&self) -> Pin<Box<dyn Future<Output = Result<Box<(dyn Connection + 'static)>>> + Send>> {
todo!()
}
fn get_metadata(&self) -> Box<dyn ConnectionFactoryMetadata> {
todo!()
}
}
impl ConnectionFactoryProvider for PostgresqlConnectionFactory {
type C = PostgresqlConnectionFactory;
fn create(connection_factory_options: ConnectionFactoryOptions) -> Result<Self::C> {
let configuration = PostgresqlConnectionConfiguration::new();
Ok(PostgresqlConnectionFactory {
configuration
})
}
}
fn to_rsdbc_err(e: postgres::error::Error) -> rsdbc_core::error::RsdbcErrors {
rsdbc_core::error::RsdbcErrors::General(format!("{:?}", e))
}
pub struct PostgresTransactionDefinition {
pub options: HashMap<String, OptionValue>,
}
impl PostgresTransactionDefinition {
fn deferrable(&mut self) -> &mut Self {
self.options.insert("deferrable".to_string(), OptionValue::Bool(true));
self
}
fn non_deferrable(&mut self) -> &mut Self {
self.options.insert("deferrable".to_string(), OptionValue::Bool(false));
self
}
fn isolation_level(&mut self, isolation_level: IsolationLevel) -> &mut Self {
self.options.insert("isolationLevel".to_string(), OptionValue::String(isolation_level.as_sql().to_string()));
self
}
fn read_only(&mut self) -> &mut Self {
self.options.insert("readOnly".to_string(), OptionValue::Bool(true));
self
}
fn read_write(&mut self) -> &mut Self {
self.options.insert("readOnly".to_string(), OptionValue::Bool(false));
self
}
}
impl TransactionDefinition for PostgresTransactionDefinition {
fn get_attribute(&self, attribute: &str) -> OptionValue {
todo!()
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}