use reblessive::Stk;
use crate::sql::statements::remove::{
RemoveAnalyzerStatement, RemoveApiStatement, RemoveBucketStatement, RemoveConfigKind,
RemoveConfigStatement, RemoveModuleStatement, RemoveSequenceStatement,
};
use crate::sql::statements::{
RemoveAccessStatement, RemoveDatabaseStatement, RemoveEventStatement, RemoveFieldStatement,
RemoveFunctionStatement, RemoveIndexStatement, RemoveNamespaceStatement, RemoveParamStatement,
RemoveStatement, RemoveUserStatement,
};
use crate::sql::{ModuleName, Param};
use crate::syn::error::bail;
use crate::syn::parser::mac::{expected, expected_whitespace, unexpected};
use crate::syn::parser::{ParseResult, Parser};
use crate::syn::token::t;
impl Parser<'_> {
pub(crate) async fn parse_remove_stmt(
&mut self,
stk: &mut Stk,
) -> ParseResult<RemoveStatement> {
let next = self.next();
let res = match next.kind {
t!("NAMESPACE") => {
let expunge = if self.eat(t!("AND")) {
expected!(self, t!("EXPUNGE"));
true
} else {
false
};
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Namespace(RemoveNamespaceStatement {
name,
if_exists,
expunge,
})
}
t!("DATABASE") => {
let expunge = if self.eat(t!("AND")) {
expected!(self, t!("EXPUNGE"));
true
} else {
false
};
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Database(RemoveDatabaseStatement {
name,
if_exists,
expunge,
})
}
t!("FUNCTION") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = self.parse_custom_function_name()?;
let next = self.peek();
if self.eat(t!("(")) {
self.expect_closing_delimiter(t!(")"), next.span)?;
}
RemoveStatement::Function(RemoveFunctionStatement {
name,
if_exists,
})
}
t!("MODULE") => {
if !self.settings.surrealism_enabled {
bail!(
"Experimental capability `surrealism` is not enabled",
@self.last_span() => "Use of `REMOVE MODULE` is still experimental"
)
}
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let peek = self.peek();
let name = match peek.kind {
t!("mod") => {
self.pop_peek();
expected_whitespace!(self, t!("::"));
let name = self.parse_ident()?.into_string();
ModuleName::Module(name)
}
t!("silo") => {
self.pop_peek();
expected_whitespace!(self, t!("::"));
let organisation = self.parse_ident()?.into_string();
expected_whitespace!(self, t!("::"));
let package = self.parse_ident()?.into_string();
expected_whitespace!(self, t!("<"));
let major = self.parse_version_digits()?;
expected_whitespace!(self, t!("."));
let minor = self.parse_version_digits()?;
expected_whitespace!(self, t!("."));
let patch = self.parse_version_digits()?;
expected_whitespace!(self, t!(">"));
ModuleName::Silo(organisation, package, major, minor, patch)
}
_ => unexpected!(self, peek, "a module name"),
};
let next = self.peek();
if self.eat(t!("(")) {
self.expect_closing_delimiter(t!(")"), next.span)?;
}
RemoveStatement::Module(RemoveModuleStatement {
name,
if_exists,
})
}
t!("ACCESS") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
expected!(self, t!("ON"));
let base = self.parse_base()?;
RemoveStatement::Access(RemoveAccessStatement {
name,
base,
if_exists,
})
}
t!("PARAM") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = self.next_token_value::<Param>()?;
RemoveStatement::Param(RemoveParamStatement {
name: name.into_strand(),
if_exists,
})
}
t!("TABLE") => {
let expunge = if self.eat(t!("AND")) {
expected!(self, t!("EXPUNGE"));
true
} else {
false
};
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Table(crate::sql::statements::RemoveTableStatement {
name,
if_exists,
expunge,
})
}
t!("EVENT") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
expected!(self, t!("ON"));
self.eat(t!("TABLE"));
let table = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Event(RemoveEventStatement {
name,
what: table,
if_exists,
})
}
t!("FIELD") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
expected!(self, t!("ON"));
self.eat(t!("TABLE"));
let what = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Field(RemoveFieldStatement {
name,
what,
if_exists,
})
}
t!("INDEX") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
expected!(self, t!("ON"));
self.eat(t!("TABLE"));
let what = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Index(RemoveIndexStatement {
name,
what,
if_exists,
})
}
t!("ANALYZER") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Analyzer(RemoveAnalyzerStatement {
name,
if_exists,
})
}
t!("SEQUENCE") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Sequence(RemoveSequenceStatement {
name,
if_exists,
})
}
t!("USER") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
expected!(self, t!("ON"));
let base = self.parse_base()?;
RemoveStatement::User(RemoveUserStatement {
name,
base,
if_exists,
})
}
t!("API") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Api(RemoveApiStatement {
name,
if_exists,
})
}
t!("BUCKET") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let name = stk.run(|stk| self.parse_expr_field(stk)).await?;
RemoveStatement::Bucket(RemoveBucketStatement {
name,
if_exists,
})
}
t!("CONFIG") => {
let if_exists = if self.eat(t!("IF")) {
expected!(self, t!("EXISTS"));
true
} else {
false
};
let next = self.next();
let kind = match next.kind {
t!("GRAPHQL") => RemoveConfigKind::GraphQL,
t!("API") => RemoveConfigKind::Api,
t!("DEFAULT") => RemoveConfigKind::Default,
_ => unexpected!(self, next, "a type of config"),
};
RemoveStatement::Config(RemoveConfigStatement {
kind,
if_exists,
})
}
_ => unexpected!(self, next, "a remove statement keyword"),
};
Ok(res)
}
}