use revision::revisioned;
use surrealdb_strand::Strand;
use surrealdb_types::{SqlFormat, ToSql};
use crate::catalog::Permission;
use crate::catalog::auth::AuthLimit;
use crate::expr::statements::info::InfoStructure;
use crate::expr::{Block, Kind};
use crate::kvs::impl_kv_value_revisioned;
use crate::sql::statements::define::DefineKind;
use crate::sql::{self, DefineFunctionStatement};
use crate::val::Value;
#[revisioned(revision = 3)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct FunctionDefinition {
pub(crate) name: Strand,
pub(crate) args: Vec<(String, Kind)>,
pub(crate) block: Block,
pub(crate) comment: Option<String>,
pub(crate) permissions: Permission,
pub(crate) returns: Option<Kind>,
#[revision(start = 2, default_fn = "default_auth_limit")]
pub(crate) auth_limit: AuthLimit,
#[revision(start = 3)]
pub(crate) graphql_alias: Option<String>,
#[revision(start = 3)]
pub(crate) graphql_deprecated: Option<String>,
}
impl FunctionDefinition {
fn default_auth_limit(_revision: u16) -> Result<AuthLimit, revision::Error> {
Ok(AuthLimit::new_no_limit())
}
}
impl_kv_value_revisioned!(FunctionDefinition);
impl FunctionDefinition {
fn to_sql_definition(&self) -> DefineFunctionStatement {
DefineFunctionStatement {
kind: DefineKind::Default,
name: self.name.clone(),
args: self.args.clone().into_iter().map(|(n, k)| (n, sql::Kind::from(k))).collect(),
block: self.block.clone().into(),
permissions: self.permissions.clone().into(),
returns: self.returns.clone().map(|k| k.into()),
comment: self
.comment
.clone()
.map(|x| sql::Expr::Literal(sql::Literal::String(x.into())))
.unwrap_or(sql::Expr::Literal(sql::Literal::None)),
graphql_alias: self.graphql_alias.clone(),
graphql_deprecated: self.graphql_deprecated.clone(),
}
}
}
impl InfoStructure for FunctionDefinition {
fn structure(self) -> Value {
Value::from(map! {
"name" => self.name.into(),
"args" => self.args
.into_iter()
.map(|(n, k)| vec![n.into(), k.to_sql().into()].into())
.collect::<Vec<Value>>()
.into(),
"block" => self.block.to_sql().into(),
"permissions" => self.permissions.structure(),
"comment", if let Some(v) = self.comment => v.to_sql().into(),
"returns", if let Some(v) = self.returns => v.to_sql().into(),
"graphql_alias", if let Some(v) = self.graphql_alias => v.into(),
"graphql_deprecated", if let Some(v) = self.graphql_deprecated => v.into(),
})
}
}
impl ToSql for &FunctionDefinition {
fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
self.to_sql_definition().fmt_sql(f, fmt)
}
}