2021-03-29 15:43:37 +00:00
|
|
|
use crate::dbs::Executor;
|
2022-01-13 17:36:41 +00:00
|
|
|
use crate::dbs::Level;
|
|
|
|
use crate::dbs::Options;
|
2021-03-31 12:10:13 +00:00
|
|
|
use crate::dbs::Runtime;
|
2021-03-29 15:43:37 +00:00
|
|
|
use crate::err::Error;
|
2020-06-29 15:36:01 +00:00
|
|
|
use crate::sql::algorithm::{algorithm, Algorithm};
|
|
|
|
use crate::sql::base::{base, Base};
|
|
|
|
use crate::sql::comment::shouldbespace;
|
|
|
|
use crate::sql::common::take_u64;
|
2021-03-29 15:43:37 +00:00
|
|
|
use crate::sql::duration::{duration, Duration};
|
2022-01-16 20:31:50 +00:00
|
|
|
use crate::sql::error::IResult;
|
2020-06-29 15:36:01 +00:00
|
|
|
use crate::sql::ident::ident_raw;
|
2022-01-13 17:36:41 +00:00
|
|
|
use crate::sql::idiom;
|
|
|
|
use crate::sql::idiom::{Idiom, Idioms};
|
2021-03-29 15:43:37 +00:00
|
|
|
use crate::sql::kind::{kind, Kind};
|
|
|
|
use crate::sql::permission::{permissions, Permissions};
|
2020-06-29 15:36:01 +00:00
|
|
|
use crate::sql::strand::strand_raw;
|
2022-01-13 17:36:41 +00:00
|
|
|
use crate::sql::value::{value, values, Value, Values};
|
2020-06-29 15:36:01 +00:00
|
|
|
use crate::sql::view::{view, View};
|
|
|
|
use nom::branch::alt;
|
|
|
|
use nom::bytes::complete::tag_no_case;
|
|
|
|
use nom::combinator::{map, opt};
|
2022-01-16 20:31:50 +00:00
|
|
|
use nom::multi::many0;
|
2022-01-13 17:36:41 +00:00
|
|
|
use nom::sequence::tuple;
|
2020-06-29 15:36:01 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use std::fmt;
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub enum DefineStatement {
|
|
|
|
Namespace(DefineNamespaceStatement),
|
|
|
|
Database(DefineDatabaseStatement),
|
|
|
|
Login(DefineLoginStatement),
|
|
|
|
Token(DefineTokenStatement),
|
|
|
|
Scope(DefineScopeStatement),
|
|
|
|
Table(DefineTableStatement),
|
|
|
|
Event(DefineEventStatement),
|
|
|
|
Field(DefineFieldStatement),
|
|
|
|
Index(DefineIndexStatement),
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineStatement {
|
|
|
|
pub async fn compute(
|
|
|
|
&self,
|
|
|
|
ctx: &Runtime,
|
|
|
|
opt: &Options<'_>,
|
|
|
|
exe: &mut Executor,
|
|
|
|
doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
match self {
|
|
|
|
DefineStatement::Namespace(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Database(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Login(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Token(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Scope(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Table(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Event(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Field(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
DefineStatement::Index(ref v) => v.compute(ctx, opt, exe, doc).await,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
impl fmt::Display for DefineStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
DefineStatement::Namespace(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Database(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Login(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Token(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Scope(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Table(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Event(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Field(v) => write!(f, "{}", v),
|
|
|
|
DefineStatement::Index(v) => write!(f, "{}", v),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn define(i: &str) -> IResult<&str, DefineStatement> {
|
|
|
|
alt((
|
|
|
|
map(namespace, |v| DefineStatement::Namespace(v)),
|
|
|
|
map(database, |v| DefineStatement::Database(v)),
|
|
|
|
map(login, |v| DefineStatement::Login(v)),
|
|
|
|
map(token, |v| DefineStatement::Token(v)),
|
|
|
|
map(scope, |v| DefineStatement::Scope(v)),
|
|
|
|
map(table, |v| DefineStatement::Table(v)),
|
|
|
|
map(event, |v| DefineStatement::Event(v)),
|
|
|
|
map(field, |v| DefineStatement::Field(v)),
|
|
|
|
map(index, |v| DefineStatement::Index(v)),
|
|
|
|
))(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineNamespaceStatement {
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineNamespaceStatement {
|
|
|
|
pub async fn compute(
|
2022-01-13 17:36:41 +00:00
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
2022-01-14 08:12:56 +00:00
|
|
|
opt: &Options<'_>,
|
2022-01-13 17:36:41 +00:00
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Kv)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl fmt::Display for DefineNamespaceStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE NAMESPACE {}", self.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = alt((tag_no_case("NS"), tag_no_case("NAMESPACE")))(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineNamespaceStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
2020-06-29 15:36:01 +00:00
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineDatabaseStatement {
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineDatabaseStatement {
|
|
|
|
pub async fn compute(
|
2022-01-13 17:36:41 +00:00
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
2022-01-14 08:12:56 +00:00
|
|
|
opt: &Options<'_>,
|
2022-01-13 17:36:41 +00:00
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Ns)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl fmt::Display for DefineDatabaseStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE DATABASE {}", self.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = alt((tag_no_case("DB"), tag_no_case("DATABASE")))(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineDatabaseStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
2020-06-29 15:36:01 +00:00
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineLoginStatement {
|
|
|
|
pub name: String,
|
|
|
|
pub base: Base,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
pub pass: Option<String>,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
pub hash: Option<String>,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineLoginStatement {
|
|
|
|
pub async fn compute(
|
2022-01-13 17:36:41 +00:00
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
2022-01-14 08:12:56 +00:00
|
|
|
opt: &Options<'_>,
|
2022-01-13 17:36:41 +00:00
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
match self.base {
|
|
|
|
Base::Ns => exe.check(opt, Level::Kv)?,
|
|
|
|
Base::Db => exe.check(opt, Level::Ns)?,
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl fmt::Display for DefineLoginStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE LOGIN {} ON {}", self.name, self.base)?;
|
|
|
|
if let Some(ref v) = self.pass {
|
|
|
|
write!(f, " PASSWORD {}", v)?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.hash {
|
|
|
|
write!(f, " PASSHASH {}", v)?
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
fn login(i: &str) -> IResult<&str, DefineLoginStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("LOGIN")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("ON")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, base) = base(i)?;
|
|
|
|
let (i, opts) = login_opts(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineLoginStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
2020-06-29 15:36:01 +00:00
|
|
|
base,
|
|
|
|
pass: match opts {
|
|
|
|
DefineLoginOption::Password(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
hash: match opts {
|
|
|
|
DefineLoginOption::Passhash(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub enum DefineLoginOption {
|
|
|
|
Password(String),
|
|
|
|
Passhash(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
fn login_opts(i: &str) -> IResult<&str, DefineLoginOption> {
|
|
|
|
alt((login_pass, login_hash))(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn login_pass(i: &str) -> IResult<&str, DefineLoginOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("PASSWORD")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = strand_raw(i)?;
|
2021-05-24 08:18:58 +00:00
|
|
|
Ok((i, DefineLoginOption::Password(v)))
|
2020-06-29 15:36:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn login_hash(i: &str) -> IResult<&str, DefineLoginOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("PASSHASH")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = strand_raw(i)?;
|
2021-05-24 08:18:58 +00:00
|
|
|
Ok((i, DefineLoginOption::Passhash(v)))
|
2020-06-29 15:36:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineTokenStatement {
|
|
|
|
pub name: String,
|
|
|
|
pub base: Base,
|
|
|
|
pub kind: Algorithm,
|
|
|
|
pub code: String,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineTokenStatement {
|
|
|
|
pub async fn compute(
|
2022-01-13 17:36:41 +00:00
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
2022-01-14 08:12:56 +00:00
|
|
|
opt: &Options<'_>,
|
2022-01-13 17:36:41 +00:00
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
match self.base {
|
|
|
|
Base::Ns => exe.check(opt, Level::Kv)?,
|
|
|
|
Base::Db => exe.check(opt, Level::Ns)?,
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl fmt::Display for DefineTokenStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"DEFINE TOKEN {} ON {} TYPE {} VALUE {}",
|
|
|
|
self.name, self.base, self.kind, self.code
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("TOKEN")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("ON")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, base) = base(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("TYPE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, kind) = algorithm(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("VALUE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, code) = strand_raw(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineTokenStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
2020-06-29 15:36:01 +00:00
|
|
|
base,
|
|
|
|
kind,
|
2021-05-24 08:18:58 +00:00
|
|
|
code,
|
2020-06-29 15:36:01 +00:00
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineScopeStatement {
|
|
|
|
pub name: String,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
pub session: Option<Duration>,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2022-01-13 17:36:41 +00:00
|
|
|
pub signup: Option<Value>,
|
2020-06-29 15:36:01 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2022-01-13 17:36:41 +00:00
|
|
|
pub signin: Option<Value>,
|
2020-06-29 15:36:01 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2022-01-13 17:36:41 +00:00
|
|
|
pub connect: Option<Value>,
|
2020-06-29 15:36:01 +00:00
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineScopeStatement {
|
|
|
|
pub async fn compute(
|
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
|
|
|
opt: &Options<'_>,
|
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Db)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
impl fmt::Display for DefineScopeStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE SCOPE {}", self.name)?;
|
|
|
|
if let Some(ref v) = self.session {
|
|
|
|
write!(f, " {}", v)?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.signup {
|
|
|
|
write!(f, " {}", v)?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.signin {
|
|
|
|
write!(f, " {}", v)?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.connect {
|
|
|
|
write!(f, " {}", v)?
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn scope(i: &str) -> IResult<&str, DefineScopeStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("SCOPE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
let (i, opts) = many0(scope_opts)(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineScopeStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
2020-06-29 15:36:01 +00:00
|
|
|
session: opts.iter().find_map(|x| match x {
|
|
|
|
DefineScopeOption::Session(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
signup: opts.iter().find_map(|x| match x {
|
|
|
|
DefineScopeOption::Signup(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
signin: opts.iter().find_map(|x| match x {
|
|
|
|
DefineScopeOption::Signin(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
connect: opts.iter().find_map(|x| match x {
|
|
|
|
DefineScopeOption::Connect(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub enum DefineScopeOption {
|
|
|
|
Session(Duration),
|
2022-01-13 17:36:41 +00:00
|
|
|
Signup(Value),
|
|
|
|
Signin(Value),
|
|
|
|
Connect(Value),
|
2020-06-29 15:36:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn scope_opts(i: &str) -> IResult<&str, DefineScopeOption> {
|
|
|
|
alt((scope_session, scope_signup, scope_signin, scope_connect))(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn scope_session(i: &str) -> IResult<&str, DefineScopeOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("SESSION")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = duration(i)?;
|
|
|
|
Ok((i, DefineScopeOption::Session(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn scope_signup(i: &str) -> IResult<&str, DefineScopeOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("SIGNUP")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, v) = value(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
Ok((i, DefineScopeOption::Signup(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn scope_signin(i: &str) -> IResult<&str, DefineScopeOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("SIGNIN")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, v) = value(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
Ok((i, DefineScopeOption::Signin(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn scope_connect(i: &str) -> IResult<&str, DefineScopeOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("CONNECT")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, v) = value(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
Ok((i, DefineScopeOption::Connect(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineTableStatement {
|
|
|
|
pub name: String,
|
|
|
|
pub drop: bool,
|
|
|
|
pub full: bool,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
pub view: Option<View>,
|
|
|
|
pub permissions: Permissions,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineTableStatement {
|
|
|
|
pub async fn compute(
|
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
|
|
|
opt: &Options<'_>,
|
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Db)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
impl fmt::Display for DefineTableStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE TABLE {}", self.name)?;
|
|
|
|
if self.drop == true {
|
|
|
|
write!(f, " DROP")?
|
|
|
|
}
|
|
|
|
if self.full == true {
|
|
|
|
write!(f, " SCHEMAFULL")?
|
|
|
|
}
|
|
|
|
if self.full == false {
|
|
|
|
write!(f, " SCHEMALESS")?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.view {
|
|
|
|
write!(f, " {}", v)?
|
|
|
|
}
|
|
|
|
write!(f, "{}", self.permissions)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table(i: &str) -> IResult<&str, DefineTableStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("TABLE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
let (i, opts) = many0(table_opts)(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineTableStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
2020-06-29 15:36:01 +00:00
|
|
|
drop: opts
|
|
|
|
.iter()
|
|
|
|
.find_map(|x| match x {
|
|
|
|
DefineTableOption::Drop => Some(true),
|
|
|
|
_ => None,
|
|
|
|
})
|
|
|
|
.unwrap_or(Default::default()),
|
|
|
|
full: opts
|
|
|
|
.iter()
|
|
|
|
.find_map(|x| match x {
|
|
|
|
DefineTableOption::Schemafull => Some(true),
|
|
|
|
DefineTableOption::Schemaless => Some(false),
|
|
|
|
_ => None,
|
|
|
|
})
|
|
|
|
.unwrap_or(Default::default()),
|
|
|
|
view: opts.iter().find_map(|x| match x {
|
|
|
|
DefineTableOption::View(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
permissions: opts
|
|
|
|
.iter()
|
|
|
|
.find_map(|x| match x {
|
|
|
|
DefineTableOption::Permissions(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
})
|
|
|
|
.unwrap_or(Default::default()),
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub enum DefineTableOption {
|
|
|
|
Drop,
|
|
|
|
View(View),
|
|
|
|
Schemaless,
|
|
|
|
Schemafull,
|
|
|
|
Permissions(Permissions),
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table_opts(i: &str) -> IResult<&str, DefineTableOption> {
|
|
|
|
alt((table_drop, table_view, table_schemaless, table_schemafull, table_permissions))(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table_drop(i: &str) -> IResult<&str, DefineTableOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("DROP")(i)?;
|
|
|
|
Ok((i, DefineTableOption::Drop))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table_view(i: &str) -> IResult<&str, DefineTableOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = view(i)?;
|
|
|
|
Ok((i, DefineTableOption::View(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table_schemaless(i: &str) -> IResult<&str, DefineTableOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("SCHEMALESS")(i)?;
|
|
|
|
Ok((i, DefineTableOption::Schemaless))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table_schemafull(i: &str) -> IResult<&str, DefineTableOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("SCHEMAFULL")(i)?;
|
|
|
|
Ok((i, DefineTableOption::Schemafull))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn table_permissions(i: &str) -> IResult<&str, DefineTableOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = permissions(i)?;
|
|
|
|
Ok((i, DefineTableOption::Permissions(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineEventStatement {
|
|
|
|
pub name: String,
|
|
|
|
pub what: String,
|
2022-01-13 17:36:41 +00:00
|
|
|
pub when: Value,
|
|
|
|
pub then: Values,
|
2020-06-29 15:36:01 +00:00
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineEventStatement {
|
|
|
|
pub async fn compute(
|
2022-01-13 17:36:41 +00:00
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
2022-01-14 08:12:56 +00:00
|
|
|
opt: &Options<'_>,
|
2022-01-13 17:36:41 +00:00
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Db)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl fmt::Display for DefineEventStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"DEFINE EVENT {} ON {} WHEN {} THEN {}",
|
|
|
|
self.name, self.what, self.when, self.then
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
fn event(i: &str) -> IResult<&str, DefineEventStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("EVENT")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("ON")(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, what) = ident_raw(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("WHEN")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, when) = value(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("THEN")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, then) = values(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineEventStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
|
|
|
what,
|
2020-06-29 15:36:01 +00:00
|
|
|
when,
|
|
|
|
then,
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineFieldStatement {
|
|
|
|
pub name: Idiom,
|
|
|
|
pub what: String,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
pub kind: Option<Kind>,
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2022-01-13 17:36:41 +00:00
|
|
|
pub value: Option<Value>,
|
2020-06-29 15:36:01 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
2022-01-13 17:36:41 +00:00
|
|
|
pub assert: Option<Value>,
|
2020-06-29 15:36:01 +00:00
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
pub priority: Option<u64>,
|
|
|
|
pub permissions: Permissions,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineFieldStatement {
|
|
|
|
pub async fn compute(
|
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
|
|
|
opt: &Options<'_>,
|
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Db)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
impl fmt::Display for DefineFieldStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE FIELD {} ON {}", self.name, self.what)?;
|
|
|
|
if let Some(ref v) = self.kind {
|
|
|
|
write!(f, " TYPE {}", v)?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.value {
|
|
|
|
write!(f, " VALUE {}", v)?
|
|
|
|
}
|
|
|
|
if let Some(ref v) = self.assert {
|
|
|
|
write!(f, " ASSERT {}", v)?
|
|
|
|
}
|
|
|
|
write!(f, "{}", self.permissions)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field(i: &str) -> IResult<&str, DefineFieldStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("FIELD")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, name) = idiom::local(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("ON")(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, what) = ident_raw(i)?;
|
|
|
|
let (i, opts) = many0(field_opts)(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineFieldStatement {
|
|
|
|
name,
|
2021-05-24 08:18:58 +00:00
|
|
|
what,
|
2020-06-29 15:36:01 +00:00
|
|
|
kind: opts.iter().find_map(|x| match x {
|
|
|
|
DefineFieldOption::Kind(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
value: opts.iter().find_map(|x| match x {
|
|
|
|
DefineFieldOption::Value(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
assert: opts.iter().find_map(|x| match x {
|
|
|
|
DefineFieldOption::Assert(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
priority: opts.iter().find_map(|x| match x {
|
|
|
|
DefineFieldOption::Priority(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
}),
|
|
|
|
permissions: opts
|
|
|
|
.iter()
|
|
|
|
.find_map(|x| match x {
|
|
|
|
DefineFieldOption::Permissions(ref v) => Some(v.to_owned()),
|
|
|
|
_ => None,
|
|
|
|
})
|
|
|
|
.unwrap_or(Default::default()),
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub enum DefineFieldOption {
|
|
|
|
Kind(Kind),
|
2022-01-13 17:36:41 +00:00
|
|
|
Value(Value),
|
|
|
|
Assert(Value),
|
2020-06-29 15:36:01 +00:00
|
|
|
Priority(u64),
|
|
|
|
Permissions(Permissions),
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field_opts(i: &str) -> IResult<&str, DefineFieldOption> {
|
|
|
|
alt((field_kind, field_value, field_assert, field_priority, field_permissions))(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field_kind(i: &str) -> IResult<&str, DefineFieldOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("TYPE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = kind(i)?;
|
|
|
|
Ok((i, DefineFieldOption::Kind(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field_value(i: &str) -> IResult<&str, DefineFieldOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("VALUE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, v) = value(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
Ok((i, DefineFieldOption::Value(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field_assert(i: &str) -> IResult<&str, DefineFieldOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("ASSERT")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, v) = value(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
Ok((i, DefineFieldOption::Assert(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field_priority(i: &str) -> IResult<&str, DefineFieldOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("PRIORITY")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = take_u64(i)?;
|
|
|
|
Ok((i, DefineFieldOption::Priority(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn field_permissions(i: &str) -> IResult<&str, DefineFieldOption> {
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, v) = permissions(i)?;
|
|
|
|
Ok((i, DefineFieldOption::Permissions(v)))
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
// --------------------------------------------------
|
|
|
|
|
2021-03-29 15:43:37 +00:00
|
|
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
2020-06-29 15:36:01 +00:00
|
|
|
pub struct DefineIndexStatement {
|
|
|
|
pub name: String,
|
|
|
|
pub what: String,
|
|
|
|
pub cols: Idioms,
|
|
|
|
pub uniq: bool,
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl DefineIndexStatement {
|
|
|
|
pub async fn compute(
|
2022-01-13 17:36:41 +00:00
|
|
|
&self,
|
|
|
|
_ctx: &Runtime,
|
2022-01-14 08:12:56 +00:00
|
|
|
opt: &Options<'_>,
|
2022-01-13 17:36:41 +00:00
|
|
|
exe: &mut Executor,
|
|
|
|
_doc: Option<&Value>,
|
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Allowed to run?
|
|
|
|
exe.check(opt, Level::Db)?;
|
|
|
|
// Continue
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-14 08:12:56 +00:00
|
|
|
impl fmt::Display for DefineIndexStatement {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "DEFINE INDEX {} ON {} COLUMNS {}", self.name, self.what, self.cols)?;
|
|
|
|
if self.uniq == true {
|
|
|
|
write!(f, " UNIQUE")?
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
fn index(i: &str) -> IResult<&str, DefineIndexStatement> {
|
|
|
|
let (i, _) = tag_no_case("DEFINE")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("INDEX")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, name) = ident_raw(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("ON")(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
2020-06-29 15:36:01 +00:00
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, what) = ident_raw(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
let (i, _) = tag_no_case("COLUMNS")(i)?;
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
2022-01-13 17:36:41 +00:00
|
|
|
let (i, cols) = idiom::locals(i)?;
|
2021-03-29 15:43:37 +00:00
|
|
|
let (i, uniq) = opt(|i| {
|
2020-06-29 15:36:01 +00:00
|
|
|
shouldbespace(i)?;
|
|
|
|
tag_no_case("UNIQUE")(i)?;
|
|
|
|
Ok((i, true))
|
|
|
|
})(i)?;
|
|
|
|
Ok((
|
|
|
|
i,
|
|
|
|
DefineIndexStatement {
|
2021-05-24 08:18:58 +00:00
|
|
|
name,
|
|
|
|
what,
|
2020-06-29 15:36:01 +00:00
|
|
|
cols,
|
|
|
|
uniq: uniq.is_some(),
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|