Skip to main content

surrealdb_sql/statements/define/
table.rs

1use common::fmt::EscapeKwFreeIdent;
2use surrealdb_types::{SqlFormat, ToSql, write_sql};
3
4use super::DefineKind;
5use crate::changefeed::ChangeFeed;
6use crate::{CoverStmts, Expr, Literal, Permissions, TableType, View};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
9#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
10pub struct DefineTableStatement {
11	pub kind: DefineKind,
12	pub id: Option<u32>,
13	pub name: Expr,
14	pub drop: bool,
15	pub full: bool,
16	pub view: Option<View>,
17	pub permissions: Permissions,
18	pub changefeed: Option<ChangeFeed>,
19	pub comment: Expr,
20	pub table_type: TableType,
21	/// Optional GraphQL alias declared via `GRAPHQL_ALIAS "..."`.
22	pub graphql_alias: Option<String>,
23	/// Optional GraphQL deprecation reason declared via
24	/// `GRAPHQL_DEPRECATED "..."`.
25	pub graphql_deprecated: Option<String>,
26	/// Inline adjacency cache cap declared via `INLINE EDGES <n>`.
27	pub inline_edges_cap: Option<u32>,
28	/// Inline reference cache cap declared via `INLINE REFERENCES <n>`.
29	pub inline_refs_cap: Option<u32>,
30}
31
32impl Default for DefineTableStatement {
33	fn default() -> Self {
34		Self {
35			kind: DefineKind::Default,
36			id: None,
37			name: Expr::Literal(Literal::None),
38			drop: false,
39			full: false,
40			view: None,
41			permissions: Permissions::none(),
42			changefeed: None,
43			comment: Expr::Literal(Literal::None),
44			table_type: TableType::default(),
45			graphql_alias: None,
46			graphql_deprecated: None,
47			inline_edges_cap: None,
48			inline_refs_cap: None,
49		}
50	}
51}
52
53impl ToSql for DefineTableStatement {
54	fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
55		f.push_str("DEFINE TABLE");
56		match self.kind {
57			DefineKind::Default => {}
58			DefineKind::Overwrite => f.push_str(" OVERWRITE"),
59			DefineKind::IfNotExists => f.push_str(" IF NOT EXISTS"),
60		}
61		write_sql!(f, sql_fmt, " {}", CoverStmts(&self.name));
62		f.push_str(" TYPE");
63		match &self.table_type {
64			TableType::Normal => f.push_str(" NORMAL"),
65			TableType::Relation(rel) => {
66				f.push_str(" RELATION");
67				if !rel.from.is_empty() {
68					f.push_str(" IN ");
69					for (idx, k) in rel.from.iter().enumerate() {
70						if idx != 0 {
71							f.push_str(" | ");
72						}
73						write_sql!(f, sql_fmt, "{}", EscapeKwFreeIdent(k.as_str()));
74					}
75				}
76				if !rel.to.is_empty() {
77					f.push_str(" OUT ");
78					for (idx, k) in rel.to.iter().enumerate() {
79						if idx != 0 {
80							f.push_str(" | ");
81						}
82						write_sql!(f, sql_fmt, "{}", EscapeKwFreeIdent(k.as_str()));
83					}
84				}
85				if rel.enforced {
86					f.push_str(" ENFORCED");
87				}
88				if rel.lightweight {
89					f.push_str(" LIGHTWEIGHT");
90				}
91			}
92			TableType::Any => f.push_str(" ANY"),
93		}
94		if self.drop {
95			f.push_str(" DROP");
96		}
97		f.push_str(if self.full {
98			" SCHEMAFULL"
99		} else {
100			" SCHEMALESS"
101		});
102		if !matches!(self.comment, Expr::Literal(Literal::None)) {
103			write_sql!(f, sql_fmt, " COMMENT {}", CoverStmts(&self.comment));
104		}
105		if let Some(ref alias) = self.graphql_alias {
106			write_sql!(f, sql_fmt, " GRAPHQL_ALIAS {}", common::fmt::QuoteStr(alias));
107		}
108		if let Some(ref reason) = self.graphql_deprecated {
109			write_sql!(f, sql_fmt, " GRAPHQL_DEPRECATED {}", common::fmt::QuoteStr(reason));
110		}
111		if let Some(cap) = self.inline_edges_cap {
112			write_sql!(f, sql_fmt, " INLINE EDGES {}", cap);
113		}
114		if let Some(cap) = self.inline_refs_cap {
115			write_sql!(f, sql_fmt, " INLINE REFERENCES {}", cap);
116		}
117		if let Some(ref v) = self.view {
118			write_sql!(f, sql_fmt, " {}", v);
119		}
120		if let Some(ref v) = self.changefeed {
121			write_sql!(f, sql_fmt, " {}", v);
122		}
123		if sql_fmt.is_pretty() {
124			f.push('\n');
125			let inner_fmt = sql_fmt.increment();
126			inner_fmt.write_indent(f);
127		} else {
128			f.push(' ');
129		}
130		write_sql!(f, sql_fmt, "{}", self.permissions);
131	}
132}