mod access;
mod analyzer;
mod api;
mod bucket;
pub mod config;
mod database;
mod event;
mod field;
mod function;
mod index;
mod model;
mod module;
mod namespace;
mod param;
mod sequence;
mod table;
mod user;
pub(crate) use access::DefineAccessStatement;
pub(crate) use analyzer::DefineAnalyzerStatement;
use anyhow::Result;
pub(crate) use api::{ApiAction, DefineApiStatement};
pub(crate) use bucket::DefineBucketStatement;
pub(crate) use config::DefineConfigStatement;
pub(crate) use database::DefineDatabaseStatement;
pub(crate) use event::DefineEventStatement;
pub(crate) use field::{
DefineDefault, DefineFieldStatement, purge_dropped_reference_keys,
validate_id_field_restrictions,
};
pub(crate) use function::DefineFunctionStatement;
pub(crate) use index::DefineIndexStatement;
pub(in crate::expr::statements) use index::run_indexing;
pub(crate) use model::DefineModelStatement;
pub(crate) use module::DefineModuleStatement;
pub(crate) use namespace::DefineNamespaceStatement;
pub(crate) use param::DefineParamStatement;
use reblessive::tree::Stk;
pub(crate) use sequence::DefineSequenceStatement;
pub(crate) use table::DefineTableStatement;
pub(crate) use user::DefineUserStatement;
use crate::ctx::FrozenContext;
use crate::dbs::Options;
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::val::Value;
pub(crate) fn validate_graphql_alias(alias: &Option<String>, kind: &str) -> Result<()> {
let Some(alias) = alias.as_deref() else {
return Ok(());
};
let mut chars = alias.chars();
let first_ok = chars.next().is_some_and(|c| c.is_ascii_alphabetic() || c == '_');
let rest_ok = chars.all(|c| c.is_ascii_alphanumeric() || c == '_');
if !first_ok || !rest_ok {
return Err(Error::InvalidStatement(format!(
"GRAPHQL_ALIAS `{alias}` on {kind} is not a valid GraphQL Name; \
expected /[_A-Za-z][_0-9A-Za-z]*/"
))
.into());
}
Ok(())
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Hash)]
pub enum DefineKind {
#[default]
Default,
Overwrite,
IfNotExists,
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) enum DefineStatement {
Namespace(DefineNamespaceStatement),
Database(DefineDatabaseStatement),
Function(DefineFunctionStatement),
Analyzer(DefineAnalyzerStatement),
Param(DefineParamStatement),
Table(DefineTableStatement),
Event(DefineEventStatement),
Field(DefineFieldStatement),
Index(DefineIndexStatement),
User(DefineUserStatement),
Model(DefineModelStatement),
Access(DefineAccessStatement),
Config(DefineConfigStatement),
Api(DefineApiStatement),
Bucket(DefineBucketStatement),
Sequence(DefineSequenceStatement),
Module(DefineModuleStatement),
}
impl DefineStatement {
#[instrument(level = "trace", name = "DefineStatement::compute", skip_all)]
pub(crate) async fn compute(
&self,
stk: &mut Stk,
ctx: &FrozenContext,
opt: &Options,
doc: Option<&CursorDoc>,
) -> Result<Value> {
match self {
Self::Namespace(v) => v.compute(stk, ctx, opt, doc).await,
Self::Database(v) => v.compute(stk, ctx, opt, doc).await,
Self::Function(v) => v.compute(stk, ctx, opt, doc).await,
Self::Param(v) => v.compute(stk, ctx, opt, doc).await,
Self::Table(v) => v.compute(stk, ctx, opt, doc).await,
Self::Event(v) => v.compute(stk, ctx, opt, doc).await,
Self::Field(v) => v.compute(stk, ctx, opt, doc).await,
Self::Index(v) => v.compute(stk, ctx, opt, doc).await,
Self::Analyzer(v) => v.compute(stk, ctx, opt, doc).await,
Self::User(v) => v.compute(stk, ctx, opt, doc).await,
Self::Model(v) => v.compute(stk, ctx, opt, doc).await,
Self::Access(v) => v.compute(stk, ctx, opt, doc).await,
Self::Config(v) => v.compute(stk, ctx, opt, doc).await,
Self::Api(v) => v.compute(stk, ctx, opt, doc).await,
Self::Bucket(v) => v.compute(stk, ctx, opt, doc).await,
Self::Sequence(v) => v.compute(stk, ctx, opt, doc).await,
Self::Module(v) => v.compute(stk, ctx, opt, doc).await,
}
}
}