surrealdb_core/sql/
param.rsuse crate::{
ctx::Context,
dbs::Options,
doc::CursorDoc,
err::Error,
iam::Action,
sql::{ident::Ident, value::Value, Permission},
};
use reblessive::tree::Stk;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::{fmt, ops::Deref, str};
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Param";
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Param")]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[non_exhaustive]
pub struct Param(pub Ident);
impl From<Ident> for Param {
fn from(v: Ident) -> Self {
Self(v)
}
}
impl From<String> for Param {
fn from(v: String) -> Self {
Self(v.into())
}
}
impl From<&str> for Param {
fn from(v: &str) -> Self {
Self(v.into())
}
}
impl Deref for Param {
type Target = Ident;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Param {
pub(crate) async fn compute(
&self,
stk: &mut Stk,
ctx: &Context,
opt: &Options,
doc: Option<&CursorDoc>,
) -> Result<Value, Error> {
match self.as_str() {
"this" | "self" => match doc {
Some(v) => v.doc.as_ref().compute(stk, ctx, opt, doc).await,
None => Ok(Value::None),
},
v => match ctx.value(v) {
Some(v) => v.compute(stk, ctx, opt, doc).await,
None => {
opt.valid_for_db()?;
let val = ctx.tx().get_db_param(opt.ns()?, opt.db()?, v).await;
match val {
Ok(val) => {
if opt.check_perms(Action::View)? {
match &val.permissions {
Permission::Full => (),
Permission::None => {
return Err(Error::ParamPermissions {
name: v.to_owned(),
})
}
Permission::Specific(e) => {
let opt = &opt.new_with_perms(false);
if !e.compute(stk, ctx, opt, doc).await?.is_truthy() {
return Err(Error::ParamPermissions {
name: v.to_owned(),
});
}
}
}
}
val.value.compute(stk, ctx, opt, doc).await
}
Err(Error::PaNotFound {
..
}) => Ok(Value::None),
Err(e) => Err(e),
}
}
},
}
}
}
impl fmt::Display for Param {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "${}", &self.0 .0)
}
}