use std::sync::Arc;
use crate::ctx::CancelHandle;
use crate::dbs::Session;
use crate::expr::LogicalPlan;
use crate::kvs::Transaction;
use crate::sql::Ast;
use crate::types::PublicVariables;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum Dialect {
#[default]
SurrealQl,
Gql,
}
pub enum QuerySource<'src> {
Text {
text: &'src str,
dialect: Dialect,
},
Ast(Ast),
Plan(LogicalPlan),
}
impl<'src> QuerySource<'src> {
pub fn text(text: &'src str) -> Self {
QuerySource::Text {
text,
dialect: Dialect::SurrealQl,
}
}
pub fn gql(text: &'src str) -> Self {
QuerySource::Text {
text,
dialect: Dialect::Gql,
}
}
pub fn in_dialect(text: &'src str, dialect: Dialect) -> Self {
QuerySource::Text {
text,
dialect,
}
}
}
impl From<Ast> for QuerySource<'_> {
fn from(ast: Ast) -> Self {
QuerySource::Ast(ast)
}
}
impl From<LogicalPlan> for QuerySource<'_> {
fn from(plan: LogicalPlan) -> Self {
QuerySource::Plan(plan)
}
}
impl<'src> From<&'src str> for QuerySource<'src> {
fn from(text: &'src str) -> Self {
QuerySource::text(text)
}
}
pub struct QueryRequest<'a> {
pub source: QuerySource<'a>,
pub session: &'a Session,
pub variables: Option<PublicVariables>,
pub transaction: Option<Arc<Transaction>>,
pub cancel: Option<CancelHandle>,
}
impl<'a> QueryRequest<'a> {
pub fn new(source: impl Into<QuerySource<'a>>, session: &'a Session) -> Self {
QueryRequest {
source: source.into(),
session,
variables: None,
transaction: None,
cancel: None,
}
}
pub fn with_variables(mut self, variables: Option<PublicVariables>) -> Self {
self.variables = variables;
self
}
pub fn with_transaction(mut self, transaction: Arc<Transaction>) -> Self {
self.transaction = Some(transaction);
self
}
pub fn with_optional_transaction(mut self, transaction: Option<Arc<Transaction>>) -> Self {
self.transaction = transaction;
self
}
pub fn with_cancel(mut self, cancel: CancelHandle) -> Self {
self.cancel = Some(cancel);
self
}
pub fn with_optional_cancel(mut self, cancel: Option<CancelHandle>) -> Self {
self.cancel = cancel;
self
}
}
#[cfg(test)]
mod tests {
use super::{Dialect, QuerySource};
#[test]
fn bare_text_is_surrealql() {
let QuerySource::Text {
dialect,
..
} = QuerySource::from("SELECT * FROM person")
else {
panic!("text is a `Text` source");
};
assert_eq!(dialect, Dialect::SurrealQl);
assert_eq!(Dialect::default(), Dialect::SurrealQl);
}
}