use tokio_postgres::{Client, NoTls};
use super::{SchemaId, SchemaMetadata, SchemaVersion};
use crate::{AdapterError, SymbolTable};
mod queries;
pub struct PostgreSQLDatabase {
pub(super) client: Client,
}
impl PostgreSQLDatabase {
pub async fn new(connection_string: &str) -> Result<Self, AdapterError> {
let (client, connection) = tokio_postgres::connect(connection_string, NoTls)
.await
.map_err(|e| {
AdapterError::InvalidOperation(format!("Failed to connect to PostgreSQL: {}", e))
})?;
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("PostgreSQL connection error: {}", e);
}
});
let mut db = Self { client };
db.initialize_schema_async().await?;
Ok(db)
}
async fn initialize_schema_async(&mut self) -> Result<(), AdapterError> {
for sql in queries::create_tables_postgres_sql() {
self.client.execute(&sql, &[]).await.map_err(|e| {
AdapterError::InvalidOperation(format!("Failed to create tables: {}", e))
})?;
}
Ok(())
}
pub(super) fn current_timestamp() -> i64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("SystemTime after UNIX_EPOCH")
.as_secs() as i64
}
pub async fn store_schema_async(
&mut self,
name: &str,
table: &SymbolTable,
) -> Result<SchemaId, AdapterError> {
queries::store_schema(&self.client, name, table).await
}
pub async fn load_schema_async(&self, id: SchemaId) -> Result<SymbolTable, AdapterError> {
queries::load_schema(&self.client, id).await
}
pub async fn load_schema_by_name_async(&self, name: &str) -> Result<SymbolTable, AdapterError> {
queries::load_schema_by_name(&self.client, name).await
}
pub async fn list_schemas_async(&self) -> Result<Vec<SchemaMetadata>, AdapterError> {
queries::list_schemas(&self.client).await
}
pub async fn delete_schema_async(&mut self, id: SchemaId) -> Result<(), AdapterError> {
queries::delete_schema(&self.client, id).await
}
pub async fn search_schemas_async(
&self,
pattern: &str,
) -> Result<Vec<SchemaMetadata>, AdapterError> {
queries::search_schemas(&self.client, pattern).await
}
pub async fn get_schema_history_async(
&self,
name: &str,
) -> Result<Vec<SchemaVersion>, AdapterError> {
queries::get_schema_history(&self.client, name).await
}
}