Skip to main content

surrealdb_sql/statements/define/
field.rs

1use surrealdb_types::{SqlFormat, ToSql, write_sql};
2
3use super::DefineKind;
4use crate::reference::Reference;
5use crate::{CoverStmts, Expr, Kind, Literal, Permissions};
6
7#[derive(Clone, Debug, Default, PartialEq, Eq)]
8#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
9pub enum DefineDefault {
10	#[default]
11	None,
12	Always(Expr),
13	Set(Expr),
14}
15
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct DefineFieldStatement {
18	pub kind: DefineKind,
19	pub name: Expr,
20	pub what: Expr,
21	pub field_kind: Option<Kind>,
22	pub flexible: bool,
23	pub readonly: bool,
24	/// Inline the field's value into the edge's adjacency (the `INLINE` clause).
25	pub inline: bool,
26	pub value: Option<Expr>,
27	pub assert: Option<Expr>,
28	pub computed: Option<Expr>,
29	pub default: DefineDefault,
30	pub permissions: Permissions,
31	pub comment: Expr,
32	pub reference: Option<Reference>,
33	/// Optional GraphQL alias declared via `GRAPHQL_ALIAS "..."`.
34	pub graphql_alias: Option<String>,
35	/// Optional GraphQL deprecation reason declared via
36	/// `GRAPHQL_DEPRECATED "..."`.
37	pub graphql_deprecated: Option<String>,
38}
39
40impl Default for DefineFieldStatement {
41	fn default() -> Self {
42		Self {
43			kind: DefineKind::Default,
44			name: Expr::Literal(Literal::None),
45			what: Expr::Literal(Literal::None),
46			field_kind: None,
47			flexible: false,
48			readonly: false,
49			inline: false,
50			value: None,
51			assert: None,
52			computed: None,
53			default: DefineDefault::None,
54			permissions: Permissions::default(),
55			comment: Expr::Literal(Literal::None),
56			reference: None,
57			graphql_alias: None,
58			graphql_deprecated: None,
59		}
60	}
61}
62
63impl ToSql for DefineFieldStatement {
64	fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
65		f.push_str("DEFINE FIELD");
66		match self.kind {
67			DefineKind::Default => {}
68			DefineKind::Overwrite => f.push_str(" OVERWRITE"),
69			DefineKind::IfNotExists => f.push_str(" IF NOT EXISTS"),
70		}
71		write_sql!(f, sql_fmt, " {} ON {}", CoverStmts(&self.name), CoverStmts(&self.what));
72		if let Some(ref v) = self.field_kind {
73			write_sql!(f, sql_fmt, " TYPE {}", v);
74			if self.flexible {
75				f.push_str(" FLEXIBLE");
76			}
77		}
78		match self.default {
79			DefineDefault::None => {}
80			DefineDefault::Always(ref expr) => {
81				write_sql!(f, sql_fmt, " DEFAULT ALWAYS {}", CoverStmts(expr));
82			}
83			DefineDefault::Set(ref expr) => {
84				write_sql!(f, sql_fmt, " DEFAULT {}", CoverStmts(expr));
85			}
86		}
87		if self.readonly {
88			f.push_str(" READONLY");
89		}
90		if self.inline {
91			f.push_str(" INLINE");
92		}
93		if let Some(ref v) = self.value {
94			write_sql!(f, sql_fmt, " VALUE {}", CoverStmts(v))
95		}
96		if let Some(ref v) = self.assert {
97			write_sql!(f, sql_fmt, " ASSERT {}", CoverStmts(v))
98		}
99		if let Some(ref v) = self.computed {
100			write_sql!(f, sql_fmt, " COMPUTED {}", CoverStmts(v))
101		}
102		if let Some(ref v) = self.reference {
103			write_sql!(f, sql_fmt, " REFERENCE {v}");
104		}
105		if !matches!(self.comment, Expr::Literal(Literal::None)) {
106			write_sql!(f, sql_fmt, " COMMENT {}", CoverStmts(&self.comment));
107		}
108		if let Some(ref alias) = self.graphql_alias {
109			write_sql!(f, sql_fmt, " GRAPHQL_ALIAS {}", common::fmt::QuoteStr(alias));
110		}
111		if let Some(ref reason) = self.graphql_deprecated {
112			write_sql!(f, sql_fmt, " GRAPHQL_DEPRECATED {}", common::fmt::QuoteStr(reason));
113		}
114		if sql_fmt.is_pretty() {
115			f.push('\n');
116			sql_fmt.write_indent(f);
117		} else {
118			f.push(' ');
119		}
120		self.permissions.fmt_sql(f, sql_fmt);
121	}
122}