Implement initial logic for DEFINE statements
This commit is contained in:
parent
2a0d46a2b6
commit
0f6d700f6b
5 changed files with 660 additions and 53 deletions
279
lib/src/kvs/ex.rs
Normal file
279
lib/src/kvs/ex.rs
Normal file
|
@ -0,0 +1,279 @@
|
|||
use super::Transaction;
|
||||
use crate::err::Error;
|
||||
use crate::kvs::Key;
|
||||
use crate::kvs::Val;
|
||||
use crate::sql;
|
||||
use sql::statements::DefineDatabaseStatement;
|
||||
use sql::statements::DefineEventStatement;
|
||||
use sql::statements::DefineFieldStatement;
|
||||
use sql::statements::DefineIndexStatement;
|
||||
use sql::statements::DefineLoginStatement;
|
||||
use sql::statements::DefineNamespaceStatement;
|
||||
use sql::statements::DefineScopeStatement;
|
||||
use sql::statements::DefineTableStatement;
|
||||
use sql::statements::DefineTokenStatement;
|
||||
use sql::statements::LiveStatement;
|
||||
|
||||
pub trait Convert<T> {
|
||||
fn convert(self) -> T;
|
||||
}
|
||||
|
||||
impl<T> Convert<Vec<T>> for Vec<(Key, Val)>
|
||||
where
|
||||
T: From<Val>,
|
||||
{
|
||||
fn convert(self) -> Vec<T> {
|
||||
self.into_iter().map(|(_, v)| v.into()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
// Get all namespaces
|
||||
pub async fn all_ns(&mut self) -> Result<Vec<DefineNamespaceStatement>, Error> {
|
||||
let beg = crate::key::ns::new(crate::key::PREFIX);
|
||||
let end = crate::key::ns::new(crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all namespace logins
|
||||
pub async fn all_nl(&mut self, ns: &str) -> Result<Vec<DefineLoginStatement>, Error> {
|
||||
let beg = crate::key::nl::new(ns, crate::key::PREFIX);
|
||||
let end = crate::key::nl::new(ns, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all namespace tokens
|
||||
pub async fn all_nt(&mut self, ns: &str) -> Result<Vec<DefineTokenStatement>, Error> {
|
||||
let beg = crate::key::nt::new(ns, crate::key::PREFIX);
|
||||
let end = crate::key::nt::new(ns, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all databases
|
||||
pub async fn all_db(&mut self, ns: &str) -> Result<Vec<DefineDatabaseStatement>, Error> {
|
||||
let beg = crate::key::db::new(ns, crate::key::PREFIX);
|
||||
let end = crate::key::db::new(ns, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all database logins
|
||||
pub async fn all_dl(&mut self, ns: &str, db: &str) -> Result<Vec<DefineLoginStatement>, Error> {
|
||||
let beg = crate::key::dl::new(ns, db, crate::key::PREFIX);
|
||||
let end = crate::key::dl::new(ns, db, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all database tokens
|
||||
pub async fn all_dt(&mut self, ns: &str, db: &str) -> Result<Vec<DefineTokenStatement>, Error> {
|
||||
let beg = crate::key::dt::new(ns, db, crate::key::PREFIX);
|
||||
let end = crate::key::dt::new(ns, db, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all scopes
|
||||
pub async fn all_sc(&mut self, ns: &str, db: &str) -> Result<Vec<DefineScopeStatement>, Error> {
|
||||
let beg = crate::key::sc::new(ns, db, crate::key::PREFIX);
|
||||
let end = crate::key::sc::new(ns, db, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all scope tokens
|
||||
pub async fn all_st(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
sc: &str,
|
||||
) -> Result<Vec<DefineTokenStatement>, Error> {
|
||||
let beg = crate::key::st::new(ns, db, sc, crate::key::PREFIX);
|
||||
let end = crate::key::st::new(ns, db, sc, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all tables
|
||||
pub async fn all_tb(&mut self, ns: &str, db: &str) -> Result<Vec<DefineTableStatement>, Error> {
|
||||
let beg = crate::key::tb::new(ns, db, crate::key::PREFIX);
|
||||
let end = crate::key::tb::new(ns, db, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all events
|
||||
pub async fn all_ev(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
tb: &str,
|
||||
) -> Result<Vec<DefineEventStatement>, Error> {
|
||||
let beg = crate::key::ev::new(ns, db, tb, crate::key::PREFIX);
|
||||
let end = crate::key::ev::new(ns, db, tb, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all fields
|
||||
pub async fn all_fd(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
tb: &str,
|
||||
) -> Result<Vec<DefineFieldStatement>, Error> {
|
||||
let beg = crate::key::fd::new(ns, db, tb, crate::key::PREFIX);
|
||||
let end = crate::key::fd::new(ns, db, tb, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all fields
|
||||
pub async fn all_ix(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
tb: &str,
|
||||
) -> Result<Vec<DefineIndexStatement>, Error> {
|
||||
let beg = crate::key::ix::new(ns, db, tb, crate::key::PREFIX);
|
||||
let end = crate::key::ix::new(ns, db, tb, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all views
|
||||
pub async fn all_ft(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
tb: &str,
|
||||
) -> Result<Vec<DefineTableStatement>, Error> {
|
||||
let beg = crate::key::ft::new(ns, db, tb, crate::key::PREFIX);
|
||||
let end = crate::key::ft::new(ns, db, tb, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
// Get all lives
|
||||
pub async fn all_lv(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
tb: &str,
|
||||
) -> Result<Vec<LiveStatement>, Error> {
|
||||
let beg = crate::key::lv::new(ns, db, tb, crate::key::PREFIX);
|
||||
let end = crate::key::lv::new(ns, db, tb, crate::key::SUFFIX);
|
||||
let val = self.getr(beg..end, u32::MAX).await?;
|
||||
Ok(val.convert())
|
||||
}
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
// Get a namespace
|
||||
pub async fn get_ns(&mut self, ns: &str) -> Result<DefineNamespaceStatement, Error> {
|
||||
let key = crate::key::ns::new(ns);
|
||||
let val = self.get(key).await?.ok_or(Error::NsNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a namespace login
|
||||
pub async fn get_nl(&mut self, ns: &str, nl: &str) -> Result<DefineLoginStatement, Error> {
|
||||
let key = crate::key::nl::new(ns, nl);
|
||||
let val = self.get(key).await?.ok_or(Error::NlNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a namespace token
|
||||
pub async fn get_nt(&mut self, ns: &str, nt: &str) -> Result<DefineTokenStatement, Error> {
|
||||
let key = crate::key::nt::new(ns, nt);
|
||||
let val = self.get(key).await?.ok_or(Error::NtNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a database
|
||||
pub async fn get_db(&mut self, ns: &str, db: &str) -> Result<DefineDatabaseStatement, Error> {
|
||||
let key = crate::key::db::new(ns, db);
|
||||
let val = self.get(key).await?.ok_or(Error::DbNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a database login
|
||||
pub async fn get_dl(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
dl: &str,
|
||||
) -> Result<DefineLoginStatement, Error> {
|
||||
let key = crate::key::dl::new(ns, db, dl);
|
||||
let val = self.get(key).await?.ok_or(Error::DlNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a database token
|
||||
pub async fn get_dt(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
dt: &str,
|
||||
) -> Result<DefineTokenStatement, Error> {
|
||||
let key = crate::key::dt::new(ns, db, dt);
|
||||
let val = self.get(key).await?.ok_or(Error::DtNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a scope
|
||||
pub async fn get_sc(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
sc: &str,
|
||||
) -> Result<DefineScopeStatement, Error> {
|
||||
let key = crate::key::sc::new(ns, db, sc);
|
||||
let val = self.get(key).await?.ok_or(Error::ScNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a scope token
|
||||
pub async fn get_st(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
sc: &str,
|
||||
st: &str,
|
||||
) -> Result<DefineTokenStatement, Error> {
|
||||
let key = crate::key::st::new(ns, db, sc, st);
|
||||
let val = self.get(key).await?.ok_or(Error::StNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
// Get a table
|
||||
pub async fn get_tb(
|
||||
&mut self,
|
||||
ns: &str,
|
||||
db: &str,
|
||||
tb: &str,
|
||||
) -> Result<DefineTableStatement, Error> {
|
||||
let key = crate::key::tb::new(ns, db, tb);
|
||||
let val = self.get(key).await?.ok_or(Error::TbNotFound)?;
|
||||
Ok(val.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
// Get all namespaces
|
||||
pub async fn add_ns(&mut self, ns: &str) -> Result<(), Error> {
|
||||
let key = crate::key::ns::new(ns);
|
||||
self.put(
|
||||
key,
|
||||
DefineNamespaceStatement {
|
||||
name: ns.to_owned(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
// Get all namespace logins
|
||||
pub async fn add_db(&mut self, ns: &str, db: &str) -> Result<(), Error> {
|
||||
let key = crate::key::db::new(ns, db);
|
||||
self.put(
|
||||
key,
|
||||
DefineDatabaseStatement {
|
||||
name: db.to_owned(),
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
// Get all namespace tokens
|
||||
pub async fn add_tb(&mut self, ns: &str, db: &str, tb: &str) -> Result<(), Error> {
|
||||
let key = crate::key::tb::new(ns, db, tb);
|
||||
self.put(
|
||||
key,
|
||||
DefineTableStatement {
|
||||
name: tb.to_owned(),
|
||||
..DefineTableStatement::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
mod ex;
|
||||
mod file;
|
||||
mod ixdb;
|
||||
mod kv;
|
||||
|
|
|
@ -4,6 +4,17 @@ use crate::kvs::Key;
|
|||
use crate::kvs::Val;
|
||||
use std::ops::Range;
|
||||
|
||||
trait Add<T> {
|
||||
fn add(self, v: T) -> Self;
|
||||
}
|
||||
|
||||
impl Add<u8> for Vec<u8> {
|
||||
fn add(mut self, v: u8) -> Self {
|
||||
self.push(v);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Transaction {
|
||||
// Check if closed
|
||||
pub async fn closed(&self) -> bool {
|
||||
|
@ -151,4 +162,178 @@ impl Transaction {
|
|||
Transaction::TiKV(v) => v.scan(rng, limit).await,
|
||||
}
|
||||
}
|
||||
// Retrieve a range of keys from the databases
|
||||
pub async fn getr<K>(&mut self, rng: Range<K>, limit: u32) -> Result<Vec<(Key, Val)>, Error>
|
||||
where
|
||||
K: Into<Key>,
|
||||
{
|
||||
let beg: Key = rng.start.into();
|
||||
let end: Key = rng.end.into();
|
||||
let mut nxt: Option<Key> = None;
|
||||
let mut num = limit;
|
||||
let mut out: Vec<(Key, Val)> = vec![];
|
||||
// Start processing
|
||||
while num > 0 {
|
||||
// Get records batch
|
||||
let res = match nxt {
|
||||
None => {
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
Some(ref mut beg) => {
|
||||
beg.push(0);
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
};
|
||||
// Get total results
|
||||
let n = res.len() - 1;
|
||||
// Loop over results
|
||||
for (i, (k, v)) in res.into_iter().enumerate() {
|
||||
// Ready the next
|
||||
if i == n {
|
||||
nxt = Some(k.clone());
|
||||
}
|
||||
// Delete
|
||||
out.push((k, v));
|
||||
// Count
|
||||
num -= 1;
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
// Delete a range of keys from the databases
|
||||
pub async fn delr<K>(&mut self, rng: Range<K>, limit: u32) -> Result<(), Error>
|
||||
where
|
||||
K: Into<Key>,
|
||||
{
|
||||
let beg: Key = rng.start.into();
|
||||
let end: Key = rng.end.into();
|
||||
let mut nxt: Option<Key> = None;
|
||||
let mut num = limit;
|
||||
// Start processing
|
||||
while num > 0 {
|
||||
// Get records batch
|
||||
let res = match nxt {
|
||||
None => {
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
Some(ref mut beg) => {
|
||||
beg.push(0);
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
};
|
||||
// Get total results
|
||||
let n = res.len() - 1;
|
||||
// Loop over results
|
||||
for (i, (k, _)) in res.into_iter().enumerate() {
|
||||
// Ready the next
|
||||
if i == n {
|
||||
nxt = Some(k.clone());
|
||||
}
|
||||
// Delete
|
||||
self.del(k).await?;
|
||||
// Count
|
||||
num -= 1;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
// Retrieve a prefix of keys from the databases
|
||||
pub async fn getp<K>(&mut self, key: K, limit: u32) -> Result<Vec<(Key, Val)>, Error>
|
||||
where
|
||||
K: Into<Key>,
|
||||
{
|
||||
let beg: Key = key.into();
|
||||
let end: Key = beg.clone().add(255);
|
||||
let mut nxt: Option<Key> = None;
|
||||
let mut num = limit;
|
||||
let mut out: Vec<(Key, Val)> = vec![];
|
||||
// Start processing
|
||||
while num > 0 {
|
||||
// Get records batch
|
||||
let res = match nxt {
|
||||
None => {
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
Some(ref mut beg) => {
|
||||
beg.push(0);
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
};
|
||||
// Get total results
|
||||
let n = res.len() - 1;
|
||||
// Loop over results
|
||||
for (i, (k, v)) in res.into_iter().enumerate() {
|
||||
// Ready the next
|
||||
if i == n {
|
||||
nxt = Some(k.clone());
|
||||
}
|
||||
// Delete
|
||||
out.push((k, v));
|
||||
// Count
|
||||
num -= 1;
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
// Delete a prefix of keys from the databases
|
||||
pub async fn delp<K>(&mut self, key: K, limit: u32) -> Result<(), Error>
|
||||
where
|
||||
K: Into<Key>,
|
||||
{
|
||||
let beg: Key = key.into();
|
||||
let end: Key = beg.clone().add(255);
|
||||
let mut nxt: Option<Key> = None;
|
||||
let mut num = limit;
|
||||
// Start processing
|
||||
while num > 0 {
|
||||
// Get records batch
|
||||
let res = match nxt {
|
||||
None => {
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
Some(ref mut beg) => {
|
||||
beg.push(0);
|
||||
let min = beg.clone();
|
||||
let max = end.clone();
|
||||
let num = std::cmp::min(1000, num);
|
||||
self.scan(min..max, num).await?
|
||||
}
|
||||
};
|
||||
// Get total results
|
||||
let n = res.len() - 1;
|
||||
// Loop over results
|
||||
for (i, (k, _)) in res.into_iter().enumerate() {
|
||||
// Ready the next
|
||||
if i == n {
|
||||
nxt = Some(k.clone());
|
||||
}
|
||||
// Delete
|
||||
self.del(k).await?;
|
||||
// Count
|
||||
num -= 1;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,17 +14,24 @@ use crate::sql::idiom;
|
|||
use crate::sql::idiom::{Idiom, Idioms};
|
||||
use crate::sql::kind::{kind, Kind};
|
||||
use crate::sql::permission::{permissions, Permissions};
|
||||
use crate::sql::statements::UpdateStatement;
|
||||
use crate::sql::strand::strand_raw;
|
||||
use crate::sql::value::{value, values, Value, Values};
|
||||
use crate::sql::view::{view, View};
|
||||
use argon2::password_hash::{PasswordHasher, SaltString};
|
||||
use argon2::Argon2;
|
||||
use derive::Store;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::combinator::{map, opt};
|
||||
use nom::multi::many0;
|
||||
use nom::sequence::tuple;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub enum DefineStatement {
|
||||
|
@ -105,13 +112,16 @@ impl DefineNamespaceStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Kv)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Process the statement
|
||||
let key = crate::key::ns::new(&self.name);
|
||||
txn.clone().lock().await.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,13 +159,20 @@ impl DefineDatabaseStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Ns)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::db::new(opt.ns(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,8 +204,8 @@ fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
|||
pub struct DefineLoginStatement {
|
||||
pub name: String,
|
||||
pub base: Base,
|
||||
pub pass: Option<String>,
|
||||
pub hash: Option<String>,
|
||||
pub hash: String,
|
||||
pub code: String,
|
||||
}
|
||||
|
||||
impl DefineLoginStatement {
|
||||
|
@ -196,30 +213,45 @@ impl DefineLoginStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
match self.base {
|
||||
Base::Ns => opt.check(Level::Kv)?,
|
||||
Base::Db => opt.check(Level::Ns)?,
|
||||
Base::Ns => {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Kv)?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::nl::new(opt.ns(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
Base::Db => {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Ns)?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::dl::new(opt.ns(), opt.db(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
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(())
|
||||
write!(f, "DEFINE LOGIN {} ON {} PASSHASH {}", self.name, self.base, self.hash)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,13 +271,17 @@ fn login(i: &str) -> IResult<&str, DefineLoginStatement> {
|
|||
DefineLoginStatement {
|
||||
name,
|
||||
base,
|
||||
pass: match opts {
|
||||
DefineLoginOption::Password(ref v) => Some(v.to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
code: rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(128)
|
||||
.map(char::from)
|
||||
.collect::<String>(),
|
||||
hash: match opts {
|
||||
DefineLoginOption::Passhash(ref v) => Some(v.to_owned()),
|
||||
_ => None,
|
||||
DefineLoginOption::Passhash(v) => v,
|
||||
DefineLoginOption::Password(v) => Argon2::default()
|
||||
.hash_password(v.as_ref(), SaltString::generate(&mut OsRng).as_ref())
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
},
|
||||
},
|
||||
))
|
||||
|
@ -294,17 +330,39 @@ impl DefineTokenStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
match self.base {
|
||||
Base::Ns => opt.check(Level::Kv)?,
|
||||
Base::Db => opt.check(Level::Ns)?,
|
||||
Base::Ns => {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Kv)?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::nt::new(opt.ns(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
Base::Db => {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Ns)?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::dt::new(opt.ns(), opt.db(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
// Continue
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,6 +412,7 @@ fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineScopeStatement {
|
||||
pub name: String,
|
||||
pub code: String,
|
||||
pub session: Option<Duration>,
|
||||
pub signup: Option<Value>,
|
||||
pub signin: Option<Value>,
|
||||
|
@ -365,13 +424,21 @@ impl DefineScopeStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::sc::new(opt.ns(), opt.db(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,6 +472,11 @@ fn scope(i: &str) -> IResult<&str, DefineScopeStatement> {
|
|||
i,
|
||||
DefineScopeStatement {
|
||||
name,
|
||||
code: rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(128)
|
||||
.map(char::from)
|
||||
.collect::<String>(),
|
||||
session: opts.iter().find_map(|x| match x {
|
||||
DefineScopeOption::Session(ref v) => Some(v.to_owned()),
|
||||
_ => None,
|
||||
|
@ -485,15 +557,41 @@ pub struct DefineTableStatement {
|
|||
impl DefineTableStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
txn: &Transaction,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::tb::new(opt.ns(), opt.db(), &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.set(key, self).await?;
|
||||
// Check if table is a view
|
||||
if let Some(view) = &self.view {
|
||||
// Remove the table data
|
||||
let key = crate::key::table::new(opt.ns(), opt.db(), &self.name);
|
||||
run.delp(key, u32::MAX).await?;
|
||||
// Process each foreign table
|
||||
for v in view.what.0.iter() {
|
||||
// Save the view config
|
||||
let key = crate::key::ft::new(opt.ns(), opt.db(), &v.name, &self.name);
|
||||
run.set(key, self).await?;
|
||||
// Process the view data
|
||||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::Table(v.clone())]),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
Arc::new(stm).compute(ctx, opt, txn, doc).await?;
|
||||
}
|
||||
}
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,13 +716,22 @@ impl DefineEventStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::ev::new(opt.ns(), opt.db(), &self.what, &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.add_tb(opt.ns(), opt.db(), &self.what).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -688,13 +795,22 @@ impl DefineFieldStatement {
|
|||
&self,
|
||||
_ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::fd::new(opt.ns(), opt.db(), &self.what, &self.name.to_string());
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.add_tb(opt.ns(), opt.db(), &self.what).await?;
|
||||
run.set(key, self).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -825,15 +941,33 @@ pub struct DefineIndexStatement {
|
|||
impl DefineIndexStatement {
|
||||
pub async fn compute(
|
||||
&self,
|
||||
_ctx: &Runtime,
|
||||
ctx: &Runtime,
|
||||
opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_doc: Option<&Value>,
|
||||
txn: &Transaction,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.check(Level::Db)?;
|
||||
// Continue
|
||||
todo!()
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Process the statement
|
||||
let key = crate::key::ix::new(opt.ns(), opt.db(), &self.what, &self.name);
|
||||
let mut run = run.lock().await;
|
||||
run.add_ns(opt.ns()).await?;
|
||||
run.add_db(opt.ns(), opt.db()).await?;
|
||||
run.add_tb(opt.ns(), opt.db(), &self.what).await?;
|
||||
run.set(key, self).await?;
|
||||
// Remove the index data
|
||||
let key = crate::key::index::new(opt.ns(), opt.db(), &self.what, &self.name, Value::None);
|
||||
run.delp(key, u32::MAX).await?;
|
||||
// Update the index data
|
||||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::Table(self.what.clone().into())]),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
Arc::new(stm).compute(ctx, opt, txn, doc).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,14 @@ pub struct Table {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
impl From<String> for Table {
|
||||
fn from(v: String) -> Self {
|
||||
Table {
|
||||
name: v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Table {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", escape(&self.name, &val_char, "`"))
|
||||
|
|
Loading…
Reference in a new issue