parent
2949ea7f4d
commit
7fabf54593
13 changed files with 353 additions and 33 deletions
|
@ -202,6 +202,10 @@ pub enum Error {
|
|||
#[error("The scope token does not exist")]
|
||||
StNotFound,
|
||||
|
||||
/// The requested param does not exist
|
||||
#[error("The param does not exist")]
|
||||
PaNotFound,
|
||||
|
||||
/// The requested table does not exist
|
||||
#[error("The table does not exist")]
|
||||
TbNotFound,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
/// DL /*{ns}*{db}!dl{us}
|
||||
/// DT /*{ns}*{db}!dt{tk}
|
||||
/// SC /*{ns}*{db}!sc{sc}
|
||||
/// PA /*{ns}*{db}!pa{pa}
|
||||
/// TB /*{ns}*{db}!tb{tb}
|
||||
/// LQ /*{ns}*{db}!lq{lq}
|
||||
///
|
||||
|
@ -46,6 +47,7 @@ pub mod namespace;
|
|||
pub mod nl;
|
||||
pub mod ns;
|
||||
pub mod nt;
|
||||
pub mod pa;
|
||||
pub mod sc;
|
||||
pub mod scope;
|
||||
pub mod st;
|
||||
|
|
64
lib/src/key/pa.rs
Normal file
64
lib/src/key/pa.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
use derive::Key;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
|
||||
pub struct Pa {
|
||||
__: u8,
|
||||
_a: u8,
|
||||
pub ns: String,
|
||||
_b: u8,
|
||||
pub db: String,
|
||||
_c: u8,
|
||||
_d: u8,
|
||||
_e: u8,
|
||||
pub pa: String,
|
||||
}
|
||||
|
||||
pub fn new(ns: &str, db: &str, pa: &str) -> Pa {
|
||||
Pa::new(ns.to_string(), db.to_string(), pa.to_string())
|
||||
}
|
||||
|
||||
pub fn prefix(ns: &str, db: &str) -> Vec<u8> {
|
||||
let mut k = super::database::new(ns, db).encode().unwrap();
|
||||
k.extend_from_slice(&[0x21, 0x70, 0x61, 0x00]);
|
||||
k
|
||||
}
|
||||
|
||||
pub fn suffix(ns: &str, db: &str) -> Vec<u8> {
|
||||
let mut k = super::database::new(ns, db).encode().unwrap();
|
||||
k.extend_from_slice(&[0x21, 0x70, 0x61, 0xff]);
|
||||
k
|
||||
}
|
||||
|
||||
impl Pa {
|
||||
pub fn new(ns: String, db: String, pa: String) -> Pa {
|
||||
Pa {
|
||||
__: 0x2f, // /
|
||||
_a: 0x2a, // *
|
||||
ns,
|
||||
_b: 0x2a, // *
|
||||
db,
|
||||
_c: 0x21, // !
|
||||
_d: 0x70, // p
|
||||
_e: 0x61, // a
|
||||
pa,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn key() {
|
||||
use super::*;
|
||||
#[rustfmt::skip]
|
||||
let val = Pa::new(
|
||||
"test".to_string(),
|
||||
"test".to_string(),
|
||||
"test".to_string(),
|
||||
);
|
||||
let enc = Pa::encode(&val).unwrap();
|
||||
let dec = Pa::decode(&enc).unwrap();
|
||||
assert_eq!(val, dec);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ use crate::sql::statements::DefineFieldStatement;
|
|||
use crate::sql::statements::DefineIndexStatement;
|
||||
use crate::sql::statements::DefineLoginStatement;
|
||||
use crate::sql::statements::DefineNamespaceStatement;
|
||||
use crate::sql::statements::DefineParamStatement;
|
||||
use crate::sql::statements::DefineScopeStatement;
|
||||
use crate::sql::statements::DefineTableStatement;
|
||||
use crate::sql::statements::DefineTokenStatement;
|
||||
|
@ -25,6 +26,7 @@ pub enum Entry {
|
|||
Dts(Arc<[DefineTokenStatement]>),
|
||||
Scs(Arc<[DefineScopeStatement]>),
|
||||
Sts(Arc<[DefineTokenStatement]>),
|
||||
Pas(Arc<[DefineParamStatement]>),
|
||||
Tbs(Arc<[DefineTableStatement]>),
|
||||
Evs(Arc<[DefineEventStatement]>),
|
||||
Fds(Arc<[DefineFieldStatement]>),
|
||||
|
|
|
@ -16,6 +16,7 @@ use sql::statements::DefineFieldStatement;
|
|||
use sql::statements::DefineIndexStatement;
|
||||
use sql::statements::DefineLoginStatement;
|
||||
use sql::statements::DefineNamespaceStatement;
|
||||
use sql::statements::DefineParamStatement;
|
||||
use sql::statements::DefineScopeStatement;
|
||||
use sql::statements::DefineTableStatement;
|
||||
use sql::statements::DefineTokenStatement;
|
||||
|
@ -812,6 +813,28 @@ impl Transaction {
|
|||
}
|
||||
}
|
||||
}
|
||||
/// Retrieve all scope definitions for a specific database.
|
||||
pub async fn all_pa(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
) -> Result<Arc<[DefineParamStatement]>, Error> {
|
||||
let key = crate::key::pa::prefix(ns, db);
|
||||
match self.cache.exi(&key) {
|
||||
true => match self.cache.get(&key) {
|
||||
Some(Entry::Pas(v)) => Ok(v),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => {
|
||||
let beg = crate::key::pa::prefix(ns, db);
|
||||
let end = crate::key::pa::suffix(ns, db);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
let val = val.convert().into();
|
||||
self.cache.set(key, Entry::Pas(Arc::clone(&val)));
|
||||
Ok(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Retrieve all table definitions for a specific database.
|
||||
pub async fn all_tb(
|
||||
&mut self,
|
||||
|
@ -1018,6 +1041,17 @@ impl Transaction {
|
|||
let val = self.get(key).await?.ok_or(Error::StNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
/// Retrieve a specific param definition.
|
||||
pub async fn get_pa(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
pa: &str,
|
||||
) -> Result<DefineParamStatement, Error> {
|
||||
let key = crate::key::pa::new(ns, db, pa);
|
||||
let val = self.get(key).await?.ok_or(Error::PaNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
/// Retrieve a specific table definition.
|
||||
pub async fn get_tb(
|
||||
&mut self,
|
||||
|
@ -1329,6 +1363,20 @@ impl Transaction {
|
|||
chn.send(bytes!("")).await?;
|
||||
}
|
||||
}
|
||||
// Output PARAMS
|
||||
{
|
||||
let pas = self.all_pa(ns, db).await?;
|
||||
if !pas.is_empty() {
|
||||
chn.send(bytes!("-- ------------------------------")).await?;
|
||||
chn.send(bytes!("-- PARAMS")).await?;
|
||||
chn.send(bytes!("-- ------------------------------")).await?;
|
||||
chn.send(bytes!("")).await?;
|
||||
for pa in pas.iter() {
|
||||
chn.send(bytes!(format!("{};", pa))).await?;
|
||||
}
|
||||
chn.send(bytes!("")).await?;
|
||||
}
|
||||
}
|
||||
// Output TABLES
|
||||
{
|
||||
let tbs = self.all_tb(ns, db).await?;
|
||||
|
|
|
@ -42,6 +42,7 @@ impl Param {
|
|||
match self.first() {
|
||||
// The first part will be a field
|
||||
Some(Part::Field(v)) => match v.as_str() {
|
||||
// This is a special param
|
||||
"this" | "self" => match doc {
|
||||
// The base document exists
|
||||
Some(v) => {
|
||||
|
@ -55,8 +56,9 @@ impl Param {
|
|||
// The base document does not exist
|
||||
None => Ok(Value::None),
|
||||
},
|
||||
// This is a normal param
|
||||
_ => match ctx.value(v) {
|
||||
// The base variable exists
|
||||
// The param has been set locally
|
||||
Some(v) => {
|
||||
// Get the path parts
|
||||
let pth: &[Part] = self;
|
||||
|
@ -65,8 +67,22 @@ impl Param {
|
|||
// Return the desired field
|
||||
res.get(ctx, opt, txn, pth.next()).await
|
||||
}
|
||||
// The base variable does not exist
|
||||
None => Ok(Value::None),
|
||||
// The param has not been set locally
|
||||
None => {
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Claim transaction
|
||||
let mut run = run.lock().await;
|
||||
// Get the param definition
|
||||
let val = run.get_pa(opt.ns(), opt.db(), v).await;
|
||||
// Check if the param has been set globally
|
||||
match val {
|
||||
// The param has been set globally
|
||||
Ok(v) => Ok(v.value),
|
||||
// The param has not been set globally
|
||||
Err(_) => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -23,6 +23,7 @@ use argon2::Argon2;
|
|||
use derive::Store;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::character::complete::char;
|
||||
use nom::combinator::{map, opt};
|
||||
use nom::multi::many0;
|
||||
use nom::sequence::tuple;
|
||||
|
@ -40,6 +41,7 @@ pub enum DefineStatement {
|
|||
Login(DefineLoginStatement),
|
||||
Token(DefineTokenStatement),
|
||||
Scope(DefineScopeStatement),
|
||||
Param(DefineParamStatement),
|
||||
Table(DefineTableStatement),
|
||||
Event(DefineEventStatement),
|
||||
Field(DefineFieldStatement),
|
||||
|
@ -60,6 +62,7 @@ impl DefineStatement {
|
|||
Self::Login(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Token(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Scope(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Param(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Table(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Event(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Field(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
|
@ -76,6 +79,7 @@ impl fmt::Display for DefineStatement {
|
|||
Self::Login(v) => Display::fmt(v, f),
|
||||
Self::Token(v) => Display::fmt(v, f),
|
||||
Self::Scope(v) => Display::fmt(v, f),
|
||||
Self::Param(v) => Display::fmt(v, f),
|
||||
Self::Table(v) => Display::fmt(v, f),
|
||||
Self::Event(v) => Display::fmt(v, f),
|
||||
Self::Field(v) => Display::fmt(v, f),
|
||||
|
@ -91,6 +95,7 @@ pub fn define(i: &str) -> IResult<&str, DefineStatement> {
|
|||
map(login, DefineStatement::Login),
|
||||
map(token, DefineStatement::Token),
|
||||
map(scope, DefineStatement::Scope),
|
||||
map(param, DefineStatement::Param),
|
||||
map(table, DefineStatement::Table),
|
||||
map(event, DefineStatement::Event),
|
||||
map(field, DefineStatement::Field),
|
||||
|
@ -569,6 +574,68 @@ fn scope_signin(i: &str) -> IResult<&str, DefineScopeOption> {
|
|||
// --------------------------------------------------
|
||||
// --------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
|
||||
pub struct DefineParamStatement {
|
||||
pub name: Ident,
|
||||
pub value: Value,
|
||||
}
|
||||
|
||||
impl DefineParamStatement {
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Selected DB?
|
||||
opt.needs(Level::Db)?;
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Claim transaction
|
||||
let mut run = run.lock().await;
|
||||
// Process the statement
|
||||
let key = crate::key::pa::new(opt.ns(), opt.db(), &self.name);
|
||||
run.add_ns(opt.ns(), opt.strict).await?;
|
||||
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DefineParamStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE PARAM ${} VALUE {}", self.name, self.value)
|
||||
}
|
||||
}
|
||||
|
||||
fn param(i: &str) -> IResult<&str, DefineParamStatement> {
|
||||
let (i, _) = tag_no_case("DEFINE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("PARAM")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = char('$')(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("VALUE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, value) = value(i)?;
|
||||
Ok((
|
||||
i,
|
||||
DefineParamStatement {
|
||||
name,
|
||||
value,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// --------------------------------------------------
|
||||
// --------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
|
||||
pub struct DefineTableStatement {
|
||||
pub name: Ident,
|
||||
|
|
|
@ -70,18 +70,18 @@ impl InfoStatement {
|
|||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("db".to_owned(), tmp.into());
|
||||
// Process the tokens
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_nt(opt.ns()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("nt".to_owned(), tmp.into());
|
||||
// Process the logins
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_nl(opt.ns()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("nl".to_owned(), tmp.into());
|
||||
// Process the tokens
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_nt(opt.ns()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("nt".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
Value::from(res).ok()
|
||||
}
|
||||
|
@ -96,30 +96,36 @@ impl InfoStatement {
|
|||
let mut run = run.lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the tables
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_tb(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("tb".to_owned(), tmp.into());
|
||||
// Process the scopes
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_sc(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("sc".to_owned(), tmp.into());
|
||||
// Process the tokens
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_dt(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("dt".to_owned(), tmp.into());
|
||||
// Process the logins
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_dl(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("dl".to_owned(), tmp.into());
|
||||
// Process the tokens
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_dt(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("dt".to_owned(), tmp.into());
|
||||
// Process the params
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_pa(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("pa".to_owned(), tmp.into());
|
||||
// Process the scopes
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_sc(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("sc".to_owned(), tmp.into());
|
||||
// Process the tables
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_tb(opt.ns(), opt.db()).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("tb".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
Value::from(res).ok()
|
||||
}
|
||||
|
@ -166,18 +172,18 @@ impl InfoStatement {
|
|||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("fd".to_owned(), tmp.into());
|
||||
// Process the indexes
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_ix(opt.ns(), opt.db(), tb).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("ix".to_owned(), tmp.into());
|
||||
// Process the tables
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_ft(opt.ns(), opt.db(), tb).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("ft".to_owned(), tmp.into());
|
||||
// Process the indexes
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_ix(opt.ns(), opt.db(), tb).await?.iter() {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("ix".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
Value::from(res).ok()
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ pub use self::define::DefineIndexStatement;
|
|||
pub use self::define::DefineLoginOption;
|
||||
pub use self::define::DefineLoginStatement;
|
||||
pub use self::define::DefineNamespaceStatement;
|
||||
pub use self::define::DefineParamStatement;
|
||||
pub use self::define::DefineScopeOption;
|
||||
pub use self::define::DefineScopeStatement;
|
||||
pub use self::define::DefineStatement;
|
||||
|
@ -57,6 +58,7 @@ pub use self::remove::RemoveFieldStatement;
|
|||
pub use self::remove::RemoveIndexStatement;
|
||||
pub use self::remove::RemoveLoginStatement;
|
||||
pub use self::remove::RemoveNamespaceStatement;
|
||||
pub use self::remove::RemoveParamStatement;
|
||||
pub use self::remove::RemoveScopeStatement;
|
||||
pub use self::remove::RemoveStatement;
|
||||
pub use self::remove::RemoveTableStatement;
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::sql::value::Value;
|
|||
use derive::Store;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::character::complete::char;
|
||||
use nom::combinator::{map, opt};
|
||||
use nom::sequence::tuple;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -25,6 +26,7 @@ pub enum RemoveStatement {
|
|||
Login(RemoveLoginStatement),
|
||||
Token(RemoveTokenStatement),
|
||||
Scope(RemoveScopeStatement),
|
||||
Param(RemoveParamStatement),
|
||||
Table(RemoveTableStatement),
|
||||
Event(RemoveEventStatement),
|
||||
Field(RemoveFieldStatement),
|
||||
|
@ -45,6 +47,7 @@ impl RemoveStatement {
|
|||
Self::Login(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Token(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Scope(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Param(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Table(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Event(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Field(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
|
@ -61,6 +64,7 @@ impl Display for RemoveStatement {
|
|||
Self::Login(v) => Display::fmt(v, f),
|
||||
Self::Token(v) => Display::fmt(v, f),
|
||||
Self::Scope(v) => Display::fmt(v, f),
|
||||
Self::Param(v) => Display::fmt(v, f),
|
||||
Self::Table(v) => Display::fmt(v, f),
|
||||
Self::Event(v) => Display::fmt(v, f),
|
||||
Self::Field(v) => Display::fmt(v, f),
|
||||
|
@ -76,6 +80,7 @@ pub fn remove(i: &str) -> IResult<&str, RemoveStatement> {
|
|||
map(login, RemoveStatement::Login),
|
||||
map(token, RemoveStatement::Token),
|
||||
map(scope, RemoveStatement::Scope),
|
||||
map(param, RemoveStatement::Param),
|
||||
map(table, RemoveStatement::Table),
|
||||
map(event, RemoveStatement::Event),
|
||||
map(field, RemoveStatement::Field),
|
||||
|
@ -428,6 +433,60 @@ fn scope(i: &str) -> IResult<&str, RemoveScopeStatement> {
|
|||
// --------------------------------------------------
|
||||
// --------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
|
||||
pub struct RemoveParamStatement {
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl RemoveParamStatement {
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Selected DB?
|
||||
opt.needs(Level::Db)?;
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Claim transaction
|
||||
let mut run = run.lock().await;
|
||||
// Delete the definition
|
||||
let key = crate::key::pa::new(opt.ns(), opt.db(), &self.name);
|
||||
run.del(key).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RemoveParamStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "REMOVE PARAM {}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
fn param(i: &str) -> IResult<&str, RemoveParamStatement> {
|
||||
let (i, _) = tag_no_case("REMOVE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("PARAM")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = char('$')(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveParamStatement {
|
||||
name,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
// --------------------------------------------------
|
||||
// --------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
|
||||
pub struct RemoveTableStatement {
|
||||
pub name: Ident,
|
||||
|
|
|
@ -76,6 +76,9 @@ async fn define_statement_table_drop() -> Result<(), Error> {
|
|||
"{
|
||||
dl: {},
|
||||
dt: {},
|
||||
pa: {},
|
||||
sc: {},
|
||||
pa: {},
|
||||
sc: {},
|
||||
tb: { test: 'DEFINE TABLE test DROP SCHEMALESS' },
|
||||
}",
|
||||
|
@ -104,6 +107,7 @@ async fn define_statement_table_schemaless() -> Result<(), Error> {
|
|||
"{
|
||||
dl: {},
|
||||
dt: {},
|
||||
pa: {},
|
||||
sc: {},
|
||||
tb: { test: 'DEFINE TABLE test SCHEMALESS' },
|
||||
}",
|
||||
|
@ -136,6 +140,7 @@ async fn define_statement_table_schemafull() -> Result<(), Error> {
|
|||
"{
|
||||
dl: {},
|
||||
dt: {},
|
||||
pa: {},
|
||||
sc: {},
|
||||
tb: { test: 'DEFINE TABLE test SCHEMAFULL' },
|
||||
}",
|
||||
|
@ -164,6 +169,7 @@ async fn define_statement_table_schemaful() -> Result<(), Error> {
|
|||
"{
|
||||
dl: {},
|
||||
dt: {},
|
||||
pa: {},
|
||||
sc: {},
|
||||
tb: { test: 'DEFINE TABLE test SCHEMAFULL' },
|
||||
}",
|
||||
|
|
|
@ -5,6 +5,49 @@ use surrealdb::err::Error;
|
|||
use surrealdb::kvs::Datastore;
|
||||
use surrealdb::sql::Value;
|
||||
|
||||
#[tokio::test]
|
||||
async fn define_global_param() -> Result<(), Error> {
|
||||
let sql = "
|
||||
DEFINE PARAM $test VALUE 12345;
|
||||
INFO FOR DB;
|
||||
SELECT * FROM $test;
|
||||
LET $test = 56789;
|
||||
SELECT * FROM $test;
|
||||
";
|
||||
let dbs = Datastore::new("memory").await?;
|
||||
let ses = Session::for_kv().with_ns("test").with_db("test");
|
||||
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
|
||||
assert_eq!(res.len(), 5);
|
||||
//
|
||||
let tmp = res.remove(0).result;
|
||||
assert!(tmp.is_ok());
|
||||
//
|
||||
let tmp = res.remove(0).result?;
|
||||
let val = Value::parse(
|
||||
"{
|
||||
dl: {},
|
||||
dt: {},
|
||||
pa: { test: 'DEFINE PARAM $test VALUE 12345' },
|
||||
sc: {},
|
||||
tb: {},
|
||||
}",
|
||||
);
|
||||
assert_eq!(tmp, val);
|
||||
//
|
||||
let tmp = res.remove(0).result?;
|
||||
let val = Value::parse("[12345]");
|
||||
assert_eq!(tmp, val);
|
||||
//
|
||||
let tmp = res.remove(0).result;
|
||||
assert!(tmp.is_ok());
|
||||
//
|
||||
let tmp = res.remove(0).result?;
|
||||
let val = Value::parse("[56789]");
|
||||
assert_eq!(tmp, val);
|
||||
//
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn define_protected_param() -> Result<(), Error> {
|
||||
let sql = "
|
||||
|
|
|
@ -192,6 +192,7 @@ async fn loose_mode_all_ok() -> Result<(), Error> {
|
|||
"{
|
||||
dl: {},
|
||||
dt: {},
|
||||
pa: {},
|
||||
sc: {},
|
||||
tb: { test: 'DEFINE TABLE test SCHEMALESS PERMISSIONS NONE' },
|
||||
}",
|
||||
|
|
Loading…
Reference in a new issue