#[cfg(feature = "postgres")]
pub mod postgres;
pub mod query;
pub mod record;
#[cfg(feature = "ledger")]
use std::sync::Arc;
use async_trait::async_trait;
pub use query::*;
pub use record::*;
use uuid::Uuid;
use crate::{
Object,
edge::query::EdgeQuery,
error::Error,
query::{GeoPoint, QueryFilter},
};
#[async_trait]
pub trait UniqueAdapter {
async fn insert_unique_hashes(
&self,
type_name: &str,
object_id: Uuid,
hashes: Vec<(String, &str)>,
) -> Result<(), Error>;
async fn delete_unique(&self, hash: &str) -> Result<(), Error>;
async fn delete_unique_hashes(&self, hashes: Vec<String>) -> Result<(), Error>;
async fn get_hashes_for_object(&self, object_id: Uuid) -> Result<Vec<String>, Error>;
async fn delete_unique_for_object(&self, object_id: Uuid) -> Result<(), Error>;
async fn delete_unique_for_objects(
&self,
type_name: &str,
owner: Uuid,
ids: Vec<Uuid>,
) -> Result<(), Error>;
async fn delete_unique_for_owned(
&self,
type_name: &str,
owner: Uuid,
) -> Result<(), Error>;
}
#[async_trait]
pub trait GeoAdapter {
async fn upsert_geo_points(
&self,
_type_name: &str,
_object_id: Uuid,
points: Vec<GeoPoint>,
) -> Result<(), Error> {
if points.is_empty() {
return Ok(());
}
Err(Error::Unsupported(
"geo indexes are not supported by this adapter".to_string(),
))
}
async fn get_geo_hashes(&self, _object_id: Uuid) -> Result<Vec<(String, String)>, Error> {
Ok(Vec::new())
}
async fn delete_geo_fields(
&self,
_object_id: Uuid,
_fields: Vec<String>,
) -> Result<(), Error> {
Ok(())
}
async fn delete_geo_for_object(&self, _object_id: Uuid) -> Result<(), Error> {
Ok(())
}
}
#[async_trait]
pub trait EdgeTraversal {
async fn fetch_object_from_edge_traversal_internal(
&self,
edge_type_name: &str,
type_name: &str,
owner: Uuid,
filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<Vec<ObjectRecord>, Error>;
async fn fetch_object_from_edge_reverse_traversal_internal(
&self,
edge_type_name: &str,
type_name: &str,
owner: Uuid,
filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<Vec<ObjectRecord>, Error>;
async fn query_edges_with_targets_batch(
&self,
edge_type: &'static str,
obj_type: &'static str,
from_ids: &[Uuid],
obj_filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<Vec<(EdgeRecord, ObjectRecord)>, Error>;
async fn query_reverse_edges_with_sources_batch(
&self,
edge_type: &'static str,
obj_type: &'static str,
to_ids: &[Uuid],
obj_filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<Vec<(EdgeRecord, ObjectRecord)>, Error>;
async fn query_edges_batch(
&self,
edge_type: &'static str,
from_ids: &[Uuid],
plan: EdgeQuery,
) -> Result<Vec<EdgeRecord>, Error>;
async fn query_reverse_edges_batch(
&self,
edge_type: &'static str,
to_ids: &[Uuid],
plan: EdgeQuery,
) -> Result<Vec<EdgeRecord>, Error>;
async fn query_edges_both_directions_with_objects(
&self,
edge_type: &'static str,
obj_type: &'static str,
pivot: Uuid,
obj_filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<
(
Vec<(EdgeRecord, ObjectRecord)>,
Vec<(EdgeRecord, ObjectRecord)>,
),
Error,
>;
async fn query_edges_both_directions(
&self,
edge_type: &'static str,
pivot: Uuid,
plan: EdgeQuery,
) -> Result<(Vec<EdgeRecord>, Vec<EdgeRecord>), Error>;
async fn count_edges_batch(
&self,
edge_type: &'static str,
from_ids: &[Uuid],
plan: EdgeQuery,
) -> Result<Vec<(Uuid, u64)>, Error>;
async fn count_reverse_edges_batch(
&self,
edge_type: &'static str,
to_ids: &[Uuid],
plan: EdgeQuery,
) -> Result<Vec<(Uuid, u64)>, Error>;
}
#[async_trait]
pub trait Adapter: UniqueAdapter + GeoAdapter + EdgeTraversal + Send + Sync + 'static {
async fn insert_object(&self, record: ObjectRecord) -> Result<(), Error>;
async fn fetch_object(
&self,
type_name: &'static str,
id: Uuid,
) -> Result<Option<ObjectRecord>, Error>;
async fn fetch_bulk_objects(
&self,
type_name: &'static str,
ids: Vec<Uuid>,
) -> Result<Vec<ObjectRecord>, Error>;
async fn update_object(&self, record: ObjectRecord) -> Result<(), Error>;
async fn transfer_object(
&self,
type_name: &'static str,
id: Uuid,
from_owner: Uuid,
to_owner: Uuid,
) -> Result<ObjectRecord, Error>;
async fn delete_object(
&self,
type_name: &'static str,
id: Uuid,
owner: Uuid,
) -> Result<Option<ObjectRecord>, Error>;
async fn delete_bulk_objects(
&self,
type_name: &'static str,
ids: Vec<Uuid>,
owner: Uuid,
) -> Result<u64, Error>;
async fn delete_owned_objects(
&self,
type_name: &'static str,
owner: Uuid,
) -> Result<u64, Error>;
async fn find_object(
&self,
type_name: &'static str,
owner: Uuid,
filters: &[QueryFilter],
) -> Result<Option<ObjectRecord>, Error>;
async fn query_objects(
&self,
type_name: &'static str,
plan: Query,
) -> Result<Vec<ObjectRecord>, Error>;
async fn query_objects_with_distance(
&self,
_type_name: &'static str,
_plan: Query,
) -> Result<Vec<(ObjectRecord, f64)>, Error> {
Err(Error::Unsupported(
"query_objects_with_distance requires postgres".to_string(),
))
}
async fn count_objects(
&self,
type_name: &'static str,
plan: Option<Query>,
) -> Result<u64, Error>;
async fn fetch_owned_objects(
&self,
type_name: &'static str,
owner: Uuid,
) -> Result<Vec<ObjectRecord>, Error>;
async fn fetch_owned_objects_batch(
&self,
type_name: &'static str,
owner_ids: &[Uuid],
) -> Result<Vec<ObjectRecord>, Error>;
async fn fetch_owned_object(
&self,
type_name: &'static str,
owner: Uuid,
) -> Result<Option<ObjectRecord>, Error>;
async fn fetch_union_object(
&self,
a_type_name: &'static str,
b_type_name: &'static str,
id: Uuid,
) -> Result<Option<ObjectRecord>, Error>;
async fn fetch_union_objects(
&self,
a_type_name: &'static str,
b_type_name: &'static str,
id: Vec<Uuid>,
) -> Result<Vec<ObjectRecord>, Error>;
async fn fetch_owned_union_object(
&self,
a_type_name: &'static str,
b_type_name: &'static str,
owner: Uuid,
) -> Result<Option<ObjectRecord>, Error>;
async fn fetch_owned_union_objects(
&self,
a_type_name: &'static str,
b_type_name: &'static str,
owner: Uuid,
) -> Result<Vec<ObjectRecord>, Error>;
async fn insert_edge(&self, record: EdgeRecord) -> Result<(), Error>;
async fn update_edge(
&self,
record: EdgeRecord,
old_to: Uuid,
to: Option<Uuid>,
) -> Result<(), Error>;
async fn delete_edge(&self, type_name: &'static str, from: Uuid, to: Uuid)
-> Result<(), Error>;
async fn delete_object_edge(&self, type_name: &'static str, from: Uuid) -> Result<(), Error>;
async fn fetch_edge(
&self,
type_name: &'static str,
from: Uuid,
to: Uuid,
) -> Result<Option<EdgeRecord>, Error>;
async fn query_edges(
&self,
type_name: &'static str,
owner: Uuid,
plan: EdgeQuery,
) -> Result<Vec<EdgeRecord>, Error>;
async fn query_reverse_edges(
&self,
type_name: &'static str,
owner_reverse: Uuid,
plan: EdgeQuery,
) -> Result<Vec<EdgeRecord>, Error>;
async fn query_edges_with_targets(
&self,
edge_type: &'static str,
obj_type: &'static str,
owner: Uuid,
obj_filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<Vec<(EdgeRecord, ObjectRecord)>, Error>;
async fn query_reverse_edges_with_sources(
&self,
edge_type: &'static str,
obj_type: &'static str,
owner: Uuid,
obj_filters: &[QueryFilter],
plan: EdgeQuery,
) -> Result<Vec<(EdgeRecord, ObjectRecord)>, Error>;
async fn count_edges(
&self,
type_name: &'static str,
owner: Uuid,
plan: Option<EdgeQuery>,
) -> Result<u64, Error>;
async fn count_reverse_edges(
&self,
type_name: &'static str,
to: Uuid,
plan: Option<EdgeQuery>,
) -> Result<u64, Error>;
async fn sequence_value(&self, sq: String) -> u64;
async fn sequence_next_value(&self, sq: String) -> u64;
#[cfg(feature = "ledger")]
fn ledger_adapter(&self) -> Option<Arc<dyn ledger::LedgerAdapter>> {
None }
}
impl dyn Adapter {
pub fn preload_object<'a, T: Object>(&'a self, id: Uuid) -> QueryContext<'a, T> {
QueryContext::new(self, id)
}
pub fn preload_objects<'a, P: Object>(&'a self, query: Query) -> MultiPreloadContext<'a, P> {
MultiPreloadContext::new(self, query)
}
}