use crate::{BackendFamily, Result, Value};
use async_trait::async_trait;
use std::collections::HashMap;
#[async_trait]
pub trait AgentDB: Send + Sync {
fn family(&self) -> BackendFamily;
fn capabilities(&self) -> &dyn Capabilities;
async fn put(&self, key: &str, value: Value) -> Result<()>;
async fn get(&self, key: &str) -> Result<Option<Value>>;
async fn delete(&self, key: &str) -> Result<()>;
async fn exists(&self, key: &str) -> Result<bool>;
async fn query(&self, query: &str, params: Vec<Value>) -> Result<QueryResult>;
async fn scan(&self, prefix: &str) -> Result<ScanResult>;
async fn begin(&self) -> Result<Box<dyn Transaction>>;
async fn close(&self) -> Result<()>;
}
pub trait Capabilities: Send + Sync {
fn supports_transactions(&self) -> bool;
fn supports_directories(&self) -> bool;
fn supports_graph_queries(&self) -> bool;
fn supports_sql_queries(&self) -> bool;
fn supports_indexes(&self) -> bool;
fn supports_ttl(&self) -> bool;
fn max_key_size(&self) -> Option<usize>;
fn max_value_size(&self) -> Option<usize>;
}
#[async_trait]
pub trait Transaction: Send + Sync {
async fn commit(self: Box<Self>) -> Result<()>;
async fn rollback(self: Box<Self>) -> Result<()>;
}
#[derive(Debug, Clone)]
pub struct QueryResult {
pub rows: Vec<Row>,
pub rows_affected: usize,
}
impl QueryResult {
pub fn new(rows: Vec<Row>, rows_affected: usize) -> Self {
Self {
rows,
rows_affected,
}
}
pub fn empty() -> Self {
Self {
rows: Vec::new(),
rows_affected: 0,
}
}
}
#[derive(Debug, Clone)]
pub struct Row {
pub columns: HashMap<String, Value>,
}
impl Row {
pub fn new() -> Self {
Self {
columns: HashMap::new(),
}
}
pub fn with_column(mut self, name: impl Into<String>, value: Value) -> Self {
self.columns.insert(name.into(), value);
self
}
pub fn get(&self, name: &str) -> Option<&Value> {
self.columns.get(name)
}
}
impl Default for Row {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct ScanResult {
pub keys: Vec<String>,
}
impl ScanResult {
pub fn new(keys: Vec<String>) -> Self {
Self { keys }
}
pub fn empty() -> Self {
Self { keys: Vec::new() }
}
}
#[derive(Debug, Clone)]
pub struct DefaultCapabilities {
pub transactions: bool,
pub directories: bool,
pub graph_queries: bool,
pub sql_queries: bool,
pub indexes: bool,
pub ttl: bool,
pub max_key_size: Option<usize>,
pub max_value_size: Option<usize>,
}
impl Capabilities for DefaultCapabilities {
fn supports_transactions(&self) -> bool {
self.transactions
}
fn supports_directories(&self) -> bool {
self.directories
}
fn supports_graph_queries(&self) -> bool {
self.graph_queries
}
fn supports_sql_queries(&self) -> bool {
self.sql_queries
}
fn supports_indexes(&self) -> bool {
self.indexes
}
fn supports_ttl(&self) -> bool {
self.ttl
}
fn max_key_size(&self) -> Option<usize> {
self.max_key_size
}
fn max_value_size(&self) -> Option<usize> {
self.max_value_size
}
}
impl Default for DefaultCapabilities {
fn default() -> Self {
Self {
transactions: false,
directories: false,
graph_queries: false,
sql_queries: false,
indexes: false,
ttl: false,
max_key_size: None,
max_value_size: None,
}
}
}