use std::collections::HashMap;
use std::pin::Pin;
use crate::error::GqlError;
use crate::proto;
use crate::types::Value;
use super::auth::AuthInfo;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SessionHandle(pub String);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TransactionHandle(pub String);
#[derive(Debug, Clone)]
pub struct SessionConfig {
pub protocol_version: u32,
pub client_info: HashMap<String, String>,
pub auth_info: Option<AuthInfo>,
}
#[derive(Debug, Clone)]
pub enum SessionProperty {
Schema(String),
Graph(String),
TimeZone(i32),
Parameter {
name: String,
value: Value,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResetTarget {
All,
Schema,
Graph,
TimeZone,
Parameters,
}
#[derive(Debug, Clone)]
pub enum ResultFrame {
Header(proto::ResultHeader),
Batch(proto::RowBatch),
Summary(proto::ResultSummary),
}
pub trait ResultStream: Send + 'static {
fn poll_next(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Result<ResultFrame, GqlError>>>;
}
#[derive(Debug, Clone)]
pub struct SchemaInfo {
pub name: String,
pub graph_count: u32,
pub graph_type_count: u32,
}
#[derive(Debug, Clone)]
pub struct GraphInfo {
pub schema: String,
pub name: String,
pub node_count: u64,
pub edge_count: u64,
pub graph_type: String,
pub storage_mode: String,
pub memory_limit_bytes: Option<u64>,
pub backward_edges: Option<bool>,
pub threads: Option<u32>,
}
#[derive(Debug, Clone)]
pub enum GraphTypeSpec {
Open,
Named(String),
}
#[derive(Debug, Clone)]
pub struct CreateGraphConfig {
pub schema: String,
pub name: String,
pub if_not_exists: bool,
pub or_replace: bool,
pub type_spec: Option<GraphTypeSpec>,
pub copy_of: Option<String>,
pub storage_mode: String,
pub memory_limit_bytes: Option<u64>,
pub backward_edges: Option<bool>,
pub threads: Option<u32>,
pub wal_enabled: Option<bool>,
pub wal_durability: Option<String>,
}
#[derive(Debug, Clone)]
pub struct GraphTypeInfo {
pub schema: String,
pub name: String,
}
#[tonic::async_trait]
pub trait GqlBackend: Send + Sync + 'static {
async fn create_session(&self, config: &SessionConfig) -> Result<SessionHandle, GqlError>;
async fn close_session(&self, session: &SessionHandle) -> Result<(), GqlError>;
async fn configure_session(
&self,
session: &SessionHandle,
property: SessionProperty,
) -> Result<(), GqlError>;
async fn reset_session(
&self,
session: &SessionHandle,
target: ResetTarget,
) -> Result<(), GqlError>;
async fn execute(
&self,
session: &SessionHandle,
statement: &str,
parameters: &HashMap<String, Value>,
transaction: Option<&TransactionHandle>,
) -> Result<Pin<Box<dyn ResultStream>>, GqlError>;
async fn begin_transaction(
&self,
session: &SessionHandle,
mode: proto::TransactionMode,
) -> Result<TransactionHandle, GqlError>;
async fn commit(
&self,
session: &SessionHandle,
transaction: &TransactionHandle,
) -> Result<(), GqlError>;
async fn rollback(
&self,
session: &SessionHandle,
transaction: &TransactionHandle,
) -> Result<(), GqlError>;
async fn list_schemas(&self) -> Result<Vec<SchemaInfo>, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn create_schema(&self, _name: &str, _if_not_exists: bool) -> Result<(), GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn drop_schema(&self, _name: &str, _if_exists: bool) -> Result<bool, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn list_graphs(&self, _schema: &str) -> Result<Vec<GraphInfo>, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn create_graph(&self, _config: CreateGraphConfig) -> Result<GraphInfo, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn drop_graph(
&self,
_schema: &str,
_name: &str,
_if_exists: bool,
) -> Result<bool, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn get_graph_info(&self, _schema: &str, _name: &str) -> Result<GraphInfo, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn list_graph_types(&self, _schema: &str) -> Result<Vec<GraphTypeInfo>, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn create_graph_type(
&self,
_schema: &str,
_name: &str,
_if_not_exists: bool,
_or_replace: bool,
) -> Result<(), GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn drop_graph_type(
&self,
_schema: &str,
_name: &str,
_if_exists: bool,
) -> Result<bool, GqlError> {
Err(GqlError::Protocol("catalog not supported".into()))
}
async fn get_graph_stats(&self, _graph: &str) -> Result<AdminStats, GqlError> {
Err(GqlError::Protocol("admin not supported".into()))
}
async fn wal_status(&self, _graph: &str) -> Result<AdminWalStatus, GqlError> {
Err(GqlError::Protocol("admin not supported".into()))
}
async fn wal_checkpoint(&self, _graph: &str) -> Result<(), GqlError> {
Err(GqlError::Protocol("admin not supported".into()))
}
async fn validate(&self, _graph: &str) -> Result<AdminValidationResult, GqlError> {
Err(GqlError::Protocol("admin not supported".into()))
}
async fn create_index(&self, _graph: &str, _index: IndexDefinition) -> Result<(), GqlError> {
Err(GqlError::Protocol("admin not supported".into()))
}
async fn drop_index(&self, _graph: &str, _index: IndexDefinition) -> Result<bool, GqlError> {
Err(GqlError::Protocol("admin not supported".into()))
}
async fn vector_search(&self, _req: VectorSearchParams) -> Result<Vec<SearchHit>, GqlError> {
Err(GqlError::Protocol("search not supported".into()))
}
async fn text_search(&self, _req: TextSearchParams) -> Result<Vec<SearchHit>, GqlError> {
Err(GqlError::Protocol("search not supported".into()))
}
async fn hybrid_search(&self, _req: HybridSearchParams) -> Result<Vec<SearchHit>, GqlError> {
Err(GqlError::Protocol("search not supported".into()))
}
}
#[derive(Debug, Clone)]
pub struct AdminStats {
pub node_count: u64,
pub edge_count: u64,
pub label_count: u64,
pub edge_type_count: u64,
pub property_key_count: u64,
pub index_count: u64,
pub memory_bytes: u64,
pub disk_bytes: Option<u64>,
}
#[derive(Debug, Clone)]
pub struct AdminWalStatus {
pub enabled: bool,
pub path: Option<String>,
pub size_bytes: u64,
pub record_count: u64,
pub last_checkpoint: Option<u64>,
pub current_epoch: u64,
}
#[derive(Debug, Clone)]
pub struct AdminValidationResult {
pub valid: bool,
pub errors: Vec<ValidationDiagnostic>,
pub warnings: Vec<ValidationDiagnostic>,
}
#[derive(Debug, Clone)]
pub struct ValidationDiagnostic {
pub code: String,
pub message: String,
pub context: Option<String>,
}
#[derive(Debug, Clone)]
pub enum IndexDefinition {
Property {
property: String,
},
Vector {
label: String,
property: String,
dimensions: Option<u32>,
metric: Option<String>,
m: Option<u32>,
ef_construction: Option<u32>,
},
Text {
label: String,
property: String,
},
}
#[derive(Debug, Clone)]
pub struct VectorSearchParams {
pub graph: String,
pub label: String,
pub property: String,
pub query_vector: Vec<f32>,
pub k: u32,
pub ef: Option<u32>,
pub filters: std::collections::HashMap<String, Value>,
}
#[derive(Debug, Clone)]
pub struct TextSearchParams {
pub graph: String,
pub label: String,
pub property: String,
pub query: String,
pub k: u32,
}
#[derive(Debug, Clone)]
pub struct HybridSearchParams {
pub graph: String,
pub label: String,
pub text_property: String,
pub vector_property: String,
pub query_text: String,
pub query_vector: Vec<f32>,
pub k: u32,
}
#[derive(Debug, Clone)]
pub struct SearchHit {
pub node_id: u64,
pub score: f64,
pub properties: std::collections::HashMap<String, Value>,
}