use crate::compiled_query::CompiledQuery;
use crate::error::{Error, Result};
use crate::record_id::RecordId;
use crate::ttl::{BackendTtlCapability, SchemaTtlPolicy};
use std::any::Any;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BackendCapabilities {
pub supports_merge: bool,
pub supports_graph_edges: bool,
pub telemetry_label: &'static str,
}
impl BackendCapabilities {
#[must_use]
pub const fn mem() -> Self {
Self {
supports_merge: true,
supports_graph_edges: true,
telemetry_label: "mem",
}
}
}
#[async_trait::async_trait]
pub trait DatabaseBackend: Send + Sync + std::fmt::Debug + 'static {
fn engine_id(&self) -> &'static str;
fn capabilities(&self) -> BackendCapabilities;
#[doc(hidden)]
fn as_any_local(&self) -> Option<&dyn Any> {
None
}
async fn use_namespace(&self, ns: &str, db_name: &str) -> Result<()> {
let _ = (ns, db_name);
Ok(())
}
async fn execute_compiled_query(
&self,
compiled: &CompiledQuery,
) -> Result<Vec<serde_json::Value>>;
async fn ensure_schemaless_table(&self, table: &str) -> Result<()> {
let _ = table;
Ok(())
}
async fn get_record(&self, table: &str, id: &str) -> Result<Option<serde_json::Value>>;
async fn create_record(
&self,
table: &str,
content: serde_json::Value,
) -> Result<serde_json::Value>;
async fn update_record(
&self,
table: &str,
id: &str,
content: serde_json::Value,
) -> Result<serde_json::Value>;
async fn merge_record(
&self,
table: &str,
id: &str,
patch: serde_json::Value,
) -> Result<serde_json::Value> {
let _ = (table, id, patch);
Err(Error::Internal(
"merge_record is not supported by this database backend".into(),
))
}
async fn upsert_record(
&self,
table: &str,
id: &str,
content: serde_json::Value,
) -> Result<serde_json::Value>;
async fn delete_record(&self, table: &str, id: &str) -> Result<()>;
async fn relate_edge(&self, from: &RecordId, edge_table: &str, to: &RecordId) -> Result<()>;
async fn unrelate_edge(&self, from: &RecordId, edge_table: &str, to: &RecordId) -> Result<()>;
async fn get_edge_targets(&self, from: &RecordId, edge_table: &str) -> Result<Vec<RecordId>>;
async fn define_unique_index(&self, table: &str, field: &str) -> Result<()> {
let _ = (table, field);
Err(Error::Internal(format!(
"define_unique_index not supported for {}",
self.engine_id()
)))
}
fn ttl_capability(&self) -> BackendTtlCapability {
BackendTtlCapability::Unsupported
}
async fn apply_ttl_policy(&self, _table: &str, _policy: &SchemaTtlPolicy) -> Result<()> {
Ok(())
}
}