surrealdb_core/sql/
param.rs1use crate::{
2 ctx::Context,
3 dbs::Options,
4 doc::CursorDoc,
5 err::Error,
6 iam::Action,
7 sql::{ident::Ident, value::Value, Permission},
8};
9use reblessive::tree::Stk;
10use revision::revisioned;
11use serde::{Deserialize, Serialize};
12use std::{fmt, ops::Deref, str};
13
14pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Param";
15
16#[revisioned(revision = 1)]
17#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
18#[serde(rename = "$surrealdb::private::sql::Param")]
19#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
20#[non_exhaustive]
21pub struct Param(pub Ident);
22
23impl From<Ident> for Param {
24 fn from(v: Ident) -> Self {
25 Self(v)
26 }
27}
28
29impl From<String> for Param {
30 fn from(v: String) -> Self {
31 Self(v.into())
32 }
33}
34
35impl From<&str> for Param {
36 fn from(v: &str) -> Self {
37 Self(v.into())
38 }
39}
40
41impl Deref for Param {
42 type Target = Ident;
43 fn deref(&self) -> &Self::Target {
44 &self.0
45 }
46}
47
48impl Param {
49 pub(crate) async fn compute(
51 &self,
52 stk: &mut Stk,
53 ctx: &Context,
54 opt: &Options,
55 doc: Option<&CursorDoc>,
56 ) -> Result<Value, Error> {
57 match self.as_str() {
59 "this" | "self" => match doc {
61 Some(v) => v.doc.as_ref().compute(stk, ctx, opt, doc).await,
63 None => Ok(Value::None),
65 },
66 v => match ctx.value(v) {
68 Some(v) => v.compute(stk, ctx, opt, doc).await,
70 None => {
72 opt.valid_for_db()?;
74 let (ns, db) = opt.ns_db()?;
76 let val = ctx.tx().get_db_param(ns, db, v).await;
77 match val {
79 Ok(val) => {
81 if opt.check_perms(Action::View)? {
83 match &val.permissions {
84 Permission::Full => (),
85 Permission::None => {
86 return Err(Error::ParamPermissions {
87 name: v.to_owned(),
88 })
89 }
90 Permission::Specific(e) => {
91 let opt = &opt.new_with_perms(false);
93 if !e.compute(stk, ctx, opt, doc).await?.is_truthy() {
95 return Err(Error::ParamPermissions {
96 name: v.to_owned(),
97 });
98 }
99 }
100 }
101 }
102 val.value.compute(stk, ctx, opt, doc).await
104 }
105 Err(Error::PaNotFound {
107 ..
108 }) => Ok(Value::None),
109 Err(e) => Err(e),
111 }
112 }
113 },
114 }
115 }
116}
117
118impl fmt::Display for Param {
119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
120 write!(f, "${}", &self.0 .0)
121 }
122}