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}
27
28impl Default for DefineTableStatement {
29	fn default() -> Self {
30		Self {
31			kind: DefineKind::Default,
32			id: None,
33			name: Expr::Literal(Literal::None),
34			drop: false,
35			full: false,
36			view: None,
37			permissions: Permissions::none(),
38			changefeed: None,
39			comment: Expr::Literal(Literal::None),
40			table_type: TableType::default(),
41			graphql_alias: None,
42			graphql_deprecated: None,
43		}
44	}
45}
46
47impl ToSql for DefineTableStatement {
48	fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
49		f.push_str("DEFINE TABLE");
50		match self.kind {
51			DefineKind::Default => {}
52			DefineKind::Overwrite => f.push_str(" OVERWRITE"),
53			DefineKind::IfNotExists => f.push_str(" IF NOT EXISTS"),
54		}
55		write_sql!(f, sql_fmt, " {}", CoverStmts(&self.name));
56		f.push_str(" TYPE");
57		match &self.table_type {
58			TableType::Normal => f.push_str(" NORMAL"),
59			TableType::Relation(rel) => {
60				f.push_str(" RELATION");
61				if !rel.from.is_empty() {
62					f.push_str(" IN ");
63					for (idx, k) in rel.from.iter().enumerate() {
64						if idx != 0 {
65							f.push_str(" | ");
66						}
67						write_sql!(f, sql_fmt, "{}", EscapeKwFreeIdent(k.as_str()));
68					}
69				}
70				if !rel.to.is_empty() {
71					f.push_str(" OUT ");
72					for (idx, k) in rel.to.iter().enumerate() {
73						if idx != 0 {
74							f.push_str(" | ");
75						}
76						write_sql!(f, sql_fmt, "{}", EscapeKwFreeIdent(k.as_str()));
77					}
78				}
79				if rel.enforced {
80					f.push_str(" ENFORCED");
81				}
82			}
83			TableType::Any => f.push_str(" ANY"),
84		}
85		if self.drop {
86			f.push_str(" DROP");
87		}
88		f.push_str(if self.full {
89			" SCHEMAFULL"
90		} else {
91			" SCHEMALESS"
92		});
93		if !matches!(self.comment, Expr::Literal(Literal::None)) {
94			write_sql!(f, sql_fmt, " COMMENT {}", CoverStmts(&self.comment));
95		}
96		if let Some(ref alias) = self.graphql_alias {
97			write_sql!(f, sql_fmt, " GRAPHQL_ALIAS {}", common::fmt::QuoteStr(alias));
98		}
99		if let Some(ref reason) = self.graphql_deprecated {
100			write_sql!(f, sql_fmt, " GRAPHQL_DEPRECATED {}", common::fmt::QuoteStr(reason));
101		}
102		if let Some(ref v) = self.view {
103			write_sql!(f, sql_fmt, " {}", v);
104		}
105		if let Some(ref v) = self.changefeed {
106			write_sql!(f, sql_fmt, " {}", v);
107		}
108		if sql_fmt.is_pretty() {
109			f.push('\n');
110			let inner_fmt = sql_fmt.increment();
111			inner_fmt.write_indent(f);
112		} else {
113			f.push(' ');
114		}
115		write_sql!(f, sql_fmt, "{}", self.permissions);
116	}
117}