use std::sync::Arc;
use tokio::net::TcpStream;
use tracing::error;
use crate::config::{Config, Protocol};
use crate::database::Storage;
use crate::protocol::{MySqlProtocol, PostgresProtocol};
use crate::protocol::shared_catalog::SharedCatalog;
pub struct Connection {
config: Arc<Config>,
storage: Arc<Storage>,
shared_catalog: Option<SharedCatalog>,
}
impl Connection {
pub fn new(config: Arc<Config>, storage: Arc<Storage>) -> Self {
Self {
config,
storage,
shared_catalog: None,
}
}
pub async fn new_with_shared_catalog(
config: Arc<Config>,
storage: Arc<Storage>
) -> crate::Result<Self> {
let shared_catalog = if matches!(config.protocol, Protocol::Postgres) {
Some(crate::protocol::shared_catalog::create_shared_catalog(storage.clone()).await?)
} else {
None
};
Ok(Self {
config,
storage,
shared_catalog,
})
}
pub fn new_with_shared_catalog_ref(
config: Arc<Config>,
storage: Arc<Storage>,
shared_catalog: SharedCatalog
) -> Self {
Self {
config,
storage,
shared_catalog: Some(shared_catalog),
}
}
pub async fn handle(&self, stream: TcpStream) -> crate::Result<()> {
match self.config.protocol {
Protocol::Postgres => {
let mut protocol = if let Some(shared_catalog) = &self.shared_catalog {
PostgresProtocol::new_with_shared_catalog(
self.config.clone(),
self.storage.clone(),
shared_catalog.clone()
).await?
} else {
PostgresProtocol::new(self.config.clone(), self.storage.clone()).await?
};
protocol.handle_connection(stream).await
}
Protocol::Mysql => {
let mut protocol =
MySqlProtocol::new(self.config.clone(), self.storage.clone()).await?;
protocol.handle_connection(stream).await
}
Protocol::Sqlserver => {
error!("SQL Server protocol not yet implemented");
Err(crate::YamlBaseError::NotImplemented(
"SQL Server protocol not yet implemented".to_string(),
))
}
}
}
}