Add info structure (#3876)
Co-authored-by: Micha de Vries <micha@devrie.sh>
This commit is contained in:
parent
77f1318152
commit
e62bedf9bb
33 changed files with 804 additions and 26 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::Value;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -49,3 +51,8 @@ impl fmt::Display for Algorithm {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl InfoStructure for Algorithm {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::sql::Ident;
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Ident, Value};
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -30,3 +31,8 @@ impl fmt::Display for Base {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl InfoStructure for Base {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::sql::fmt::{is_pretty, pretty_indent, Fmt, Pretty};
|
use crate::sql::fmt::{is_pretty, pretty_indent, Fmt, Pretty};
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::statements::{
|
use crate::sql::statements::{
|
||||||
BreakStatement, ContinueStatement, CreateStatement, DefineStatement, DeleteStatement,
|
BreakStatement, ContinueStatement, CreateStatement, DefineStatement, DeleteStatement,
|
||||||
ForeachStatement, IfelseStatement, InsertStatement, OutputStatement, RelateStatement,
|
ForeachStatement, IfelseStatement, InsertStatement, OutputStatement, RelateStatement,
|
||||||
|
@ -166,6 +167,11 @@ impl Display for Block {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Block {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
|
||||||
#[revisioned(revision = 1)]
|
#[revisioned(revision = 1)]
|
||||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::sql::duration::Duration;
|
use crate::sql::duration::Duration;
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::Value;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
@ -31,3 +33,8 @@ impl Default for ChangeFeed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl InfoStructure for ChangeFeed {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::value::Value;
|
use crate::sql::value::Value;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -22,3 +23,8 @@ impl fmt::Display for Cond {
|
||||||
write!(f, "WHERE {}", self.0)
|
write!(f, "WHERE {}", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl InfoStructure for Cond {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.0.structure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::sql::fmt::Fmt;
|
use crate::sql::fmt::Fmt;
|
||||||
use crate::sql::idiom::Idiom;
|
use crate::sql::idiom::Idiom;
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::Value;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
@ -32,6 +34,11 @@ impl fmt::Display for Fetchs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Fetchs {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
Value::Array(self.0.into_iter().map(|f| f.0.structure()).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
|
||||||
#[revisioned(revision = 1)]
|
#[revisioned(revision = 1)]
|
||||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::ctx::Context;
|
||||||
use crate::dbs::{Options, Transaction};
|
use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::{fmt::Fmt, Idiom, Part, Value};
|
use crate::sql::{fmt::Fmt, Idiom, Part, Value};
|
||||||
use crate::syn;
|
use crate::syn;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
|
@ -65,6 +66,11 @@ impl Display for Fields {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Fields {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Fields {
|
impl Fields {
|
||||||
/// Process this type returning a computed simple Value
|
/// Process this type returning a computed simple Value
|
||||||
pub(crate) async fn compute(
|
pub(crate) async fn compute(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::sql::{escape::escape_ident, strand::no_nul_bytes};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{escape::escape_ident, strand::no_nul_bytes, Value};
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
@ -58,3 +59,9 @@ impl Display for Ident {
|
||||||
Display::fmt(&escape_ident(&self.0), f)
|
Display::fmt(&escape_ident(&self.0), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Ident {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.0.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::ctx::Context;
|
||||||
use crate::dbs::{Options, Transaction};
|
use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::{
|
use crate::sql::{
|
||||||
fmt::{fmt_separated_by, Fmt},
|
fmt::{fmt_separated_by, Fmt},
|
||||||
part::Next,
|
part::Next,
|
||||||
|
@ -199,3 +200,15 @@ impl Display for Idiom {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Idioms {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Idiom {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ use crate::fnc::util::math::vector::{
|
||||||
};
|
};
|
||||||
use crate::sql::ident::Ident;
|
use crate::sql::ident::Ident;
|
||||||
use crate::sql::scoring::Scoring;
|
use crate::sql::scoring::Scoring;
|
||||||
use crate::sql::Number;
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Number, Value};
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -204,3 +205,9 @@ impl Display for Index {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Index {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::sql::{fmt::Fmt, Table};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{fmt::Fmt, Table, Value};
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
@ -130,3 +131,9 @@ impl Display for Kind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Kind {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::sql::fmt::is_pretty;
|
use crate::sql::fmt::is_pretty;
|
||||||
use crate::sql::fmt::pretty_indent;
|
use crate::sql::fmt::pretty_indent;
|
||||||
use crate::sql::fmt::pretty_sequence_item;
|
use crate::sql::fmt::pretty_sequence_item;
|
||||||
use crate::sql::Value;
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Object, Value};
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
@ -166,3 +167,32 @@ impl Display for Permission {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Permission {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
match self {
|
||||||
|
Permission::None => Value::Bool(false),
|
||||||
|
Permission::Full => Value::Bool(true),
|
||||||
|
Permission::Specific(v) => Value::Strand(v.to_string().into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Permissions {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
select,
|
||||||
|
create,
|
||||||
|
update,
|
||||||
|
delete,
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("select".to_string(), select.structure());
|
||||||
|
acc.insert("create".to_string(), create.structure());
|
||||||
|
acc.insert("update".to_string(), update.structure());
|
||||||
|
acc.insert("delete".to_string(), delete.structure());
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{filter::Filter, tokenizer::Tokenizer, Base, Ident, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{filter::Filter, tokenizer::Tokenizer, Base, Ident, Object, Strand, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -89,3 +90,43 @@ impl Display for DefineAnalyzerStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineAnalyzerStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
function,
|
||||||
|
tokenizers,
|
||||||
|
filters,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
if let Some(function) = function {
|
||||||
|
acc.insert("function".to_string(), function.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(tokenizers) = tokenizers {
|
||||||
|
acc.insert(
|
||||||
|
"tokenizers".to_string(),
|
||||||
|
Value::Array(tokenizers.into_iter().map(|t| t.to_string().into()).collect()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(filters) = filters {
|
||||||
|
acc.insert(
|
||||||
|
"filters".to_string(),
|
||||||
|
Value::Array(filters.into_iter().map(|f| f.to_string().into()).collect()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{changefeed::ChangeFeed, Base, Ident, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{changefeed::ChangeFeed, Base, Ident, Object, Strand, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -87,3 +88,22 @@ impl Display for DefineDatabaseStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineDatabaseStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{Base, Ident, Strand, Value, Values};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Base, Ident, Object, Strand, Value, Values};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -80,3 +81,34 @@ impl Display for DefineEventStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineEventStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
what,
|
||||||
|
when,
|
||||||
|
then,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("what".to_string(), what.structure());
|
||||||
|
|
||||||
|
acc.insert("when".to_string(), when.structure());
|
||||||
|
|
||||||
|
acc.insert(
|
||||||
|
"then".to_string(),
|
||||||
|
Value::Array(then.0.iter().map(|v| v.to_string().into()).collect()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,11 +3,12 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::statements::DefineTableStatement;
|
use crate::sql::statements::DefineTableStatement;
|
||||||
use crate::sql::Part;
|
|
||||||
use crate::sql::{
|
use crate::sql::{
|
||||||
fmt::is_pretty, fmt::pretty_indent, Base, Ident, Idiom, Kind, Permissions, Strand, Value,
|
fmt::is_pretty, fmt::pretty_indent, Base, Ident, Idiom, Kind, Permissions, Strand, Value,
|
||||||
};
|
};
|
||||||
|
use crate::sql::{Object, Part};
|
||||||
use crate::sql::{Relation, TableType};
|
use crate::sql::{Relation, TableType};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
|
@ -204,3 +205,54 @@ impl Display for DefineFieldStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineFieldStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
what,
|
||||||
|
flex,
|
||||||
|
kind,
|
||||||
|
readonly,
|
||||||
|
value,
|
||||||
|
assert,
|
||||||
|
default,
|
||||||
|
permissions,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("what".to_string(), what.structure());
|
||||||
|
|
||||||
|
acc.insert("flex".to_string(), flex.into());
|
||||||
|
|
||||||
|
if let Some(kind) = kind {
|
||||||
|
acc.insert("kind".to_string(), kind.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.insert("readonly".to_string(), readonly.into());
|
||||||
|
|
||||||
|
if let Some(value) = value {
|
||||||
|
acc.insert("value".to_string(), value.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(assert) = assert {
|
||||||
|
acc.insert("assert".to_string(), assert.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(default) = default {
|
||||||
|
acc.insert("default".to_string(), default.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.insert("permissions".to_string(), permissions.structure());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::{
|
use crate::sql::{
|
||||||
fmt::{is_pretty, pretty_indent},
|
fmt::{is_pretty, pretty_indent},
|
||||||
Base, Block, Ident, Kind, Permission, Strand, Value,
|
Base, Block, Ident, Kind, Object, Permission, Strand, Value,
|
||||||
};
|
};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
|
@ -93,3 +94,39 @@ impl fmt::Display for DefineFunctionStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineFunctionStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
block,
|
||||||
|
comment,
|
||||||
|
permissions,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert(
|
||||||
|
"args".to_string(),
|
||||||
|
Value::Array(
|
||||||
|
args.into_iter()
|
||||||
|
.map(|(n, k)| Value::Array(vec![n.structure(), k.structure()].into()))
|
||||||
|
.collect::<Vec<Value>>()
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
acc.insert("block".to_string(), block.structure());
|
||||||
|
|
||||||
|
acc.insert("permissions".to_string(), permissions.structure());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,10 @@ use crate::dbs::{Force, Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{statements::UpdateStatement, Base, Ident, Idioms, Index, Strand, Value, Values};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{
|
||||||
|
statements::UpdateStatement, Base, Ident, Idioms, Index, Object, Strand, Value, Values,
|
||||||
|
};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -98,3 +101,31 @@ impl Display for DefineIndexStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineIndexStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
what,
|
||||||
|
cols,
|
||||||
|
index,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("what".to_string(), what.structure());
|
||||||
|
|
||||||
|
acc.insert("cols".to_string(), cols.structure());
|
||||||
|
|
||||||
|
acc.insert("index".to_string(), index.structure());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::{
|
use crate::sql::{
|
||||||
fmt::{is_pretty, pretty_indent},
|
fmt::{is_pretty, pretty_indent},
|
||||||
Base, Ident, Permission, Strand, Value,
|
Base, Ident, Object, Permission, Strand, Value,
|
||||||
};
|
};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
|
@ -89,3 +90,28 @@ impl DefineModelStatement {
|
||||||
Ok(Value::None)
|
Ok(Value::None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineModelStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
version,
|
||||||
|
comment,
|
||||||
|
permissions,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("version".to_string(), version.into());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.insert("permissions".to_string(), permissions.structure());
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{Base, Ident, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Base, Ident, Object, Strand, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -80,3 +81,22 @@ impl Display for DefineNamespaceStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineNamespaceStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::fmt::{is_pretty, pretty_indent};
|
use crate::sql::fmt::{is_pretty, pretty_indent};
|
||||||
use crate::sql::{Base, Ident, Permission, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Base, Ident, Object, Permission, Strand, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -84,3 +85,28 @@ impl Display for DefineParamStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineParamStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
comment,
|
||||||
|
permissions,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("value".to_string(), value.structure());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.insert("permissions".to_string(), permissions.structure());
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{Base, Duration, Ident, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Base, Duration, Ident, Object, Strand, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use rand::distributions::Alphanumeric;
|
use rand::distributions::Alphanumeric;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
@ -93,3 +94,32 @@ impl Display for DefineScopeStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineScopeStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
signup,
|
||||||
|
signin,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
if let Some(signup) = signup {
|
||||||
|
acc.insert("signup".to_string(), signup.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(signin) = signin {
|
||||||
|
acc.insert("signin".to_string(), signin.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,10 +7,11 @@ use crate::sql::{
|
||||||
changefeed::ChangeFeed,
|
changefeed::ChangeFeed,
|
||||||
fmt::{is_pretty, pretty_indent},
|
fmt::{is_pretty, pretty_indent},
|
||||||
statements::UpdateStatement,
|
statements::UpdateStatement,
|
||||||
Base, Ident, Permissions, Strand, Value, Values, View,
|
Base, Ident, Object, Permissions, Strand, Value, Values, View,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::{Idiom, Kind, Part, Table, TableType};
|
use crate::sql::{Idiom, Kind, Part, Table, TableType};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
|
@ -211,3 +212,43 @@ impl Display for DefineTableStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineTableStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
drop,
|
||||||
|
full,
|
||||||
|
view,
|
||||||
|
permissions,
|
||||||
|
changefeed,
|
||||||
|
comment,
|
||||||
|
kind,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("drop".to_string(), drop.into());
|
||||||
|
acc.insert("full".to_string(), full.into());
|
||||||
|
|
||||||
|
if let Some(view) = view {
|
||||||
|
acc.insert("view".to_string(), view.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.insert("permissions".to_string(), permissions.structure());
|
||||||
|
|
||||||
|
if let Some(changefeed) = changefeed {
|
||||||
|
acc.insert("changefeed".to_string(), changefeed.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
acc.insert("kind".to_string(), kind.structure());
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{escape::quote_str, Algorithm, Base, Ident, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{escape::quote_str, Algorithm, Base, Ident, Object, Strand, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -143,3 +144,31 @@ impl Display for DefineTokenStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineTokenStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
base,
|
||||||
|
kind,
|
||||||
|
code,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("base".to_string(), base.structure());
|
||||||
|
|
||||||
|
acc.insert("kind".to_string(), kind.structure());
|
||||||
|
|
||||||
|
acc.insert("code".to_string(), code.into());
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::iam::{Action, ResourceKind};
|
use crate::iam::{Action, ResourceKind};
|
||||||
use crate::sql::{escape::quote_str, fmt::Fmt, Base, Ident, Strand, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{escape::quote_str, fmt::Fmt, Base, Ident, Object, Strand, Value};
|
||||||
use argon2::{
|
use argon2::{
|
||||||
password_hash::{PasswordHasher, SaltString},
|
password_hash::{PasswordHasher, SaltString},
|
||||||
Argon2,
|
Argon2,
|
||||||
|
@ -199,3 +200,34 @@ impl Display for DefineUserStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for DefineUserStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
name,
|
||||||
|
base,
|
||||||
|
code,
|
||||||
|
roles,
|
||||||
|
comment,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("name".to_string(), name.structure());
|
||||||
|
|
||||||
|
acc.insert("base".to_string(), base.structure());
|
||||||
|
|
||||||
|
acc.insert("code".to_string(), code.into());
|
||||||
|
|
||||||
|
acc.insert(
|
||||||
|
"roles".to_string(),
|
||||||
|
Value::Array(roles.into_iter().map(|r| r.structure()).collect()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(comment) = comment {
|
||||||
|
acc.insert("comment".to_string(), comment.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,11 @@ pub enum InfoStatement {
|
||||||
Sc(Ident),
|
Sc(Ident),
|
||||||
Tb(Ident),
|
Tb(Ident),
|
||||||
User(Ident, Option<Base>),
|
User(Ident, Option<Base>),
|
||||||
|
RootStructure,
|
||||||
|
NsStructure,
|
||||||
|
DbStructure,
|
||||||
|
ScStructure(Ident),
|
||||||
|
TbStructure(Ident),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InfoStatement {
|
impl InfoStatement {
|
||||||
|
@ -215,6 +220,130 @@ impl InfoStatement {
|
||||||
// Ok all good
|
// Ok all good
|
||||||
Value::from(res.to_string()).ok()
|
Value::from(res.to_string()).ok()
|
||||||
}
|
}
|
||||||
|
InfoStatement::RootStructure => {
|
||||||
|
// Allowed to run?
|
||||||
|
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Root)?;
|
||||||
|
// Claim transaction
|
||||||
|
let mut run = txn.lock().await;
|
||||||
|
// Create the result set
|
||||||
|
let mut res = Object::default();
|
||||||
|
// Process the namespaces
|
||||||
|
res.insert("namespaces".to_owned(), process_arr(run.all_ns().await?));
|
||||||
|
// Process the users
|
||||||
|
res.insert("users".to_owned(), process_arr(run.all_root_users().await?));
|
||||||
|
// Ok all good
|
||||||
|
Value::from(res).ok()
|
||||||
|
}
|
||||||
|
InfoStatement::NsStructure => {
|
||||||
|
// Allowed to run?
|
||||||
|
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Ns)?;
|
||||||
|
// Claim transaction
|
||||||
|
let mut run = txn.lock().await;
|
||||||
|
// Create the result set
|
||||||
|
let mut res = Object::default();
|
||||||
|
// Process the databases
|
||||||
|
res.insert("databases".to_owned(), process_arr(run.all_db(opt.ns()).await?));
|
||||||
|
// Process the users
|
||||||
|
res.insert("users".to_owned(), process_arr(run.all_ns_users(opt.ns()).await?));
|
||||||
|
// Process the tokens
|
||||||
|
res.insert("tokens".to_owned(), process_arr(run.all_ns_tokens(opt.ns()).await?));
|
||||||
|
// Ok all good
|
||||||
|
Value::from(res).ok()
|
||||||
|
}
|
||||||
|
InfoStatement::DbStructure => {
|
||||||
|
// Allowed to run?
|
||||||
|
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||||
|
// Claim transaction
|
||||||
|
let mut run = txn.lock().await;
|
||||||
|
// Create the result set
|
||||||
|
let mut res = Object::default();
|
||||||
|
// Process the users
|
||||||
|
res.insert(
|
||||||
|
"users".to_owned(),
|
||||||
|
process_arr(run.all_db_users(opt.ns(), opt.db()).await?),
|
||||||
|
);
|
||||||
|
// Process the tokens
|
||||||
|
res.insert(
|
||||||
|
"tokens".to_owned(),
|
||||||
|
process_arr(run.all_db_tokens(opt.ns(), opt.db()).await?),
|
||||||
|
);
|
||||||
|
// Process the functions
|
||||||
|
res.insert(
|
||||||
|
"functions".to_owned(),
|
||||||
|
process_arr(run.all_db_functions(opt.ns(), opt.db()).await?),
|
||||||
|
);
|
||||||
|
// Process the models
|
||||||
|
res.insert(
|
||||||
|
"models".to_owned(),
|
||||||
|
process_arr(run.all_db_models(opt.ns(), opt.db()).await?),
|
||||||
|
);
|
||||||
|
// Process the params
|
||||||
|
res.insert(
|
||||||
|
"params".to_owned(),
|
||||||
|
process_arr(run.all_db_params(opt.ns(), opt.db()).await?),
|
||||||
|
);
|
||||||
|
// Process the scopes
|
||||||
|
res.insert("scopes".to_owned(), process_arr(run.all_sc(opt.ns(), opt.db()).await?));
|
||||||
|
// Process the tables
|
||||||
|
res.insert("tables".to_owned(), process_arr(run.all_tb(opt.ns(), opt.db()).await?));
|
||||||
|
// Process the analyzers
|
||||||
|
res.insert(
|
||||||
|
"analyzers".to_owned(),
|
||||||
|
process_arr(run.all_db_analyzers(opt.ns(), opt.db()).await?),
|
||||||
|
);
|
||||||
|
// Ok all good
|
||||||
|
Value::from(res).ok()
|
||||||
|
}
|
||||||
|
InfoStatement::ScStructure(sc) => {
|
||||||
|
// Allowed to run?
|
||||||
|
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||||
|
// Claim transaction
|
||||||
|
let mut run = txn.lock().await;
|
||||||
|
// Create the result set
|
||||||
|
let mut res = Object::default();
|
||||||
|
// Process the tokens
|
||||||
|
res.insert(
|
||||||
|
"tokens".to_owned(),
|
||||||
|
process_arr(run.all_sc_tokens(opt.ns(), opt.db(), sc).await?),
|
||||||
|
);
|
||||||
|
// Ok all good
|
||||||
|
Value::from(res).ok()
|
||||||
|
}
|
||||||
|
InfoStatement::TbStructure(tb) => {
|
||||||
|
// Allowed to run?
|
||||||
|
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||||
|
// Claim transaction
|
||||||
|
let mut run = txn.lock().await;
|
||||||
|
// Create the result set
|
||||||
|
let mut res = Object::default();
|
||||||
|
// Process the events
|
||||||
|
res.insert(
|
||||||
|
"events".to_owned(),
|
||||||
|
process_arr(run.all_tb_events(opt.ns(), opt.db(), tb).await?),
|
||||||
|
);
|
||||||
|
// Process the fields
|
||||||
|
res.insert(
|
||||||
|
"fields".to_owned(),
|
||||||
|
process_arr(run.all_tb_fields(opt.ns(), opt.db(), tb).await?),
|
||||||
|
);
|
||||||
|
// Process the tables
|
||||||
|
res.insert(
|
||||||
|
"tables".to_owned(),
|
||||||
|
process_arr(run.all_tb_views(opt.ns(), opt.db(), tb).await?),
|
||||||
|
);
|
||||||
|
// Process the indexes
|
||||||
|
res.insert(
|
||||||
|
"indexes".to_owned(),
|
||||||
|
process_arr(run.all_tb_indexes(opt.ns(), opt.db(), tb).await?),
|
||||||
|
);
|
||||||
|
// Process the live queries
|
||||||
|
res.insert(
|
||||||
|
"lives".to_owned(),
|
||||||
|
process_arr(run.all_tb_lives(opt.ns(), opt.db(), tb).await?),
|
||||||
|
);
|
||||||
|
// Ok all good
|
||||||
|
Value::from(res).ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,10 +352,15 @@ impl fmt::Display for InfoStatement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Root => f.write_str("INFO FOR ROOT"),
|
Self::Root => f.write_str("INFO FOR ROOT"),
|
||||||
|
Self::RootStructure => f.write_str("INFO FOR ROOT STRUCTURE"),
|
||||||
Self::Ns => f.write_str("INFO FOR NAMESPACE"),
|
Self::Ns => f.write_str("INFO FOR NAMESPACE"),
|
||||||
|
Self::NsStructure => f.write_str("INFO FOR NAMESPACE STRUCTURE"),
|
||||||
Self::Db => f.write_str("INFO FOR DATABASE"),
|
Self::Db => f.write_str("INFO FOR DATABASE"),
|
||||||
|
Self::DbStructure => f.write_str("INFO FOR DATABASE STRUCTURE"),
|
||||||
Self::Sc(ref s) => write!(f, "INFO FOR SCOPE {s}"),
|
Self::Sc(ref s) => write!(f, "INFO FOR SCOPE {s}"),
|
||||||
|
Self::ScStructure(ref s) => write!(f, "INFO FOR SCOPE {s} STRUCTURE"),
|
||||||
Self::Tb(ref t) => write!(f, "INFO FOR TABLE {t}"),
|
Self::Tb(ref t) => write!(f, "INFO FOR TABLE {t}"),
|
||||||
|
Self::TbStructure(ref t) => write!(f, "INFO FOR TABLE {t} STRUCTURE"),
|
||||||
Self::User(ref u, ref b) => match b {
|
Self::User(ref u, ref b) => match b {
|
||||||
Some(ref b) => write!(f, "INFO FOR USER {u} ON {b}"),
|
Some(ref b) => write!(f, "INFO FOR USER {u} ON {b}"),
|
||||||
None => write!(f, "INFO FOR USER {u}"),
|
None => write!(f, "INFO FOR USER {u}"),
|
||||||
|
@ -234,3 +368,30 @@ impl fmt::Display for InfoStatement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub(crate) trait InfoStructure {
|
||||||
|
fn structure(self) -> Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InfoStatement {
|
||||||
|
pub(crate) fn structurize(self) -> Result<Self, ()> {
|
||||||
|
let out = match self {
|
||||||
|
InfoStatement::Root => InfoStatement::RootStructure,
|
||||||
|
InfoStatement::Ns => InfoStatement::NsStructure,
|
||||||
|
InfoStatement::Db => InfoStatement::DbStructure,
|
||||||
|
InfoStatement::Sc(s) => InfoStatement::ScStructure(s),
|
||||||
|
InfoStatement::Tb(t) => InfoStatement::TbStructure(t),
|
||||||
|
_ => return Err(()),
|
||||||
|
};
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_arr<T>(a: Arc<[T]>) -> Value
|
||||||
|
where
|
||||||
|
T: InfoStructure + Clone,
|
||||||
|
{
|
||||||
|
Value::Array(a.iter().cloned().map(InfoStructure::structure).collect())
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ use crate::err::{Error, LiveQueryCause};
|
||||||
use crate::fflags::FFLAGS;
|
use crate::fflags::FFLAGS;
|
||||||
use crate::iam::Auth;
|
use crate::iam::Auth;
|
||||||
use crate::kvs::lq_structs::{LqEntry, TrackedResult};
|
use crate::kvs::lq_structs::{LqEntry, TrackedResult};
|
||||||
use crate::sql::{Cond, Fetchs, Fields, Table, Uuid, Value};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{Cond, Fetchs, Fields, Object, Table, Uuid, Value};
|
||||||
use derive::Store;
|
use derive::Store;
|
||||||
use futures::lock::MutexGuard;
|
use futures::lock::MutexGuard;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
|
@ -191,3 +192,30 @@ impl fmt::Display for LiveStatement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for LiveStatement {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
let Self {
|
||||||
|
expr,
|
||||||
|
what,
|
||||||
|
cond,
|
||||||
|
fetch,
|
||||||
|
..
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
acc.insert("expr".to_string(), expr.structure());
|
||||||
|
|
||||||
|
acc.insert("what".to_string(), what.structure());
|
||||||
|
|
||||||
|
if let Some(cond) = cond {
|
||||||
|
acc.insert("cond".to_string(), cond.structure());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fetch) = fetch {
|
||||||
|
acc.insert("fetch".to_string(), fetch.structure());
|
||||||
|
}
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::Array;
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use super::{Kind, Table};
|
use super::{Kind, Object, Table, Value};
|
||||||
|
|
||||||
/// The type of records stored by a table
|
/// The type of records stored by a table
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, Hash, Clone, Eq, PartialEq, PartialOrd)]
|
#[derive(Debug, Default, Serialize, Deserialize, Hash, Clone, Eq, PartialEq, PartialOrd)]
|
||||||
|
@ -26,10 +28,10 @@ impl Display for TableType {
|
||||||
TableType::Relation(rel) => {
|
TableType::Relation(rel) => {
|
||||||
f.write_str(" RELATION")?;
|
f.write_str(" RELATION")?;
|
||||||
if let Some(Kind::Record(kind)) = &rel.from {
|
if let Some(Kind::Record(kind)) = &rel.from {
|
||||||
write!(f, " IN {}", get_tables_from_kind(kind))?;
|
write!(f, " IN {}", get_tables_from_kind(kind).join(" | "))?;
|
||||||
}
|
}
|
||||||
if let Some(Kind::Record(kind)) = &rel.to {
|
if let Some(Kind::Record(kind)) = &rel.to {
|
||||||
write!(f, " OUT {}", get_tables_from_kind(kind))?;
|
write!(f, " OUT {}", get_tables_from_kind(kind).join(" | "))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TableType::Any => {
|
TableType::Any => {
|
||||||
|
@ -40,8 +42,42 @@ impl Display for TableType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tables_from_kind(tables: &[Table]) -> String {
|
impl InfoStructure for TableType {
|
||||||
tables.iter().map(|t| t.0.as_str()).collect::<Vec<_>>().join(" | ")
|
fn structure(self) -> Value {
|
||||||
|
let mut acc = Object::default();
|
||||||
|
|
||||||
|
match &self {
|
||||||
|
TableType::Any => {
|
||||||
|
acc.insert("kind".to_string(), "ANY".into());
|
||||||
|
}
|
||||||
|
TableType::Normal => {
|
||||||
|
acc.insert("kind".to_string(), "NORMAL".into());
|
||||||
|
}
|
||||||
|
TableType::Relation(rel) => {
|
||||||
|
acc.insert("kind".to_string(), "RELATION".into());
|
||||||
|
|
||||||
|
if let Some(Kind::Record(tables)) = &rel.from {
|
||||||
|
acc.insert(
|
||||||
|
"in".to_string(),
|
||||||
|
Value::Array(Array::from(get_tables_from_kind(tables))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Kind::Record(tables)) = &rel.to {
|
||||||
|
acc.insert(
|
||||||
|
"out".to_string(),
|
||||||
|
Value::Array(Array::from(get_tables_from_kind(tables))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Value::Object(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_tables_from_kind(tables: &[Table]) -> Vec<&str> {
|
||||||
|
tables.iter().map(|t| t.0.as_str()).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, Hash, Clone, Eq, PartialEq, PartialOrd)]
|
#[derive(Debug, Default, Serialize, Deserialize, Hash, Clone, Eq, PartialEq, PartialOrd)]
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::dbs::{Options, Transaction};
|
||||||
use crate::doc::CursorDoc;
|
use crate::doc::CursorDoc;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::fnc::util::string::fuzzy::Fuzzy;
|
use crate::fnc::util::string::fuzzy::Fuzzy;
|
||||||
|
use crate::sql::statements::info::InfoStructure;
|
||||||
use crate::sql::{
|
use crate::sql::{
|
||||||
array::Uniq,
|
array::Uniq,
|
||||||
fmt::{Fmt, Pretty},
|
fmt::{Fmt, Pretty},
|
||||||
|
@ -2594,6 +2595,12 @@ impl fmt::Display for Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InfoStructure for Value {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
/// Check if we require a writeable transaction
|
/// Check if we require a writeable transaction
|
||||||
pub(crate) fn writeable(&self) -> bool {
|
pub(crate) fn writeable(&self) -> bool {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::sql::{cond::Cond, field::Fields, group::Groups, table::Tables};
|
use crate::sql::statements::info::InfoStructure;
|
||||||
|
use crate::sql::{cond::Cond, field::Fields, group::Groups, table::Tables, Value};
|
||||||
use revision::revisioned;
|
use revision::revisioned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -26,3 +27,8 @@ impl fmt::Display for View {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl InfoStructure for View {
|
||||||
|
fn structure(self) -> Value {
|
||||||
|
self.to_string().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -185,6 +185,7 @@ pub(crate) static KEYWORDS: phf::Map<UniCase<&'static str>, TokenKind> = phf_map
|
||||||
UniCase::ascii("SNOWBALL") => TokenKind::Keyword(Keyword::Snowball),
|
UniCase::ascii("SNOWBALL") => TokenKind::Keyword(Keyword::Snowball),
|
||||||
UniCase::ascii("SPLIT") => TokenKind::Keyword(Keyword::Split),
|
UniCase::ascii("SPLIT") => TokenKind::Keyword(Keyword::Split),
|
||||||
UniCase::ascii("START") => TokenKind::Keyword(Keyword::Start),
|
UniCase::ascii("START") => TokenKind::Keyword(Keyword::Start),
|
||||||
|
UniCase::ascii("STRUCTURE") => TokenKind::Keyword(Keyword::Structure),
|
||||||
UniCase::ascii("TABLE") => TokenKind::Keyword(Keyword::Table),
|
UniCase::ascii("TABLE") => TokenKind::Keyword(Keyword::Table),
|
||||||
UniCase::ascii("TB") => TokenKind::Keyword(Keyword::Table),
|
UniCase::ascii("TB") => TokenKind::Keyword(Keyword::Table),
|
||||||
UniCase::ascii("TERMS_CACHE") => TokenKind::Keyword(Keyword::TermsCache),
|
UniCase::ascii("TERMS_CACHE") => TokenKind::Keyword(Keyword::TermsCache),
|
||||||
|
|
|
@ -425,7 +425,7 @@ impl Parser<'_> {
|
||||||
/// Expects `INFO` to already be consumed.
|
/// Expects `INFO` to already be consumed.
|
||||||
pub(crate) fn parse_info_stmt(&mut self) -> ParseResult<InfoStatement> {
|
pub(crate) fn parse_info_stmt(&mut self) -> ParseResult<InfoStatement> {
|
||||||
expected!(self, t!("FOR"));
|
expected!(self, t!("FOR"));
|
||||||
let stmt = match self.next().kind {
|
let mut stmt = match self.next().kind {
|
||||||
t!("ROOT") => InfoStatement::Root,
|
t!("ROOT") => InfoStatement::Root,
|
||||||
t!("NAMESPACE") => InfoStatement::Ns,
|
t!("NAMESPACE") => InfoStatement::Ns,
|
||||||
t!("DATABASE") => InfoStatement::Db,
|
t!("DATABASE") => InfoStatement::Db,
|
||||||
|
@ -444,6 +444,18 @@ impl Parser<'_> {
|
||||||
}
|
}
|
||||||
x => unexpected!(self, x, "an info target"),
|
x => unexpected!(self, x, "an info target"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if self.peek_kind() == t!("STRUCTURE") {
|
||||||
|
stmt = match stmt.structurize() {
|
||||||
|
Ok(s) => {
|
||||||
|
self.pop_peek();
|
||||||
|
s
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
unexpected!(self, t!("STRUCTURE"), "not STRUCTURE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
Ok(stmt)
|
Ok(stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,7 @@ keyword! {
|
||||||
Snowball => "SNOWBALL",
|
Snowball => "SNOWBALL",
|
||||||
Split => "SPLIT",
|
Split => "SPLIT",
|
||||||
Start => "START",
|
Start => "START",
|
||||||
|
Structure => "STRUCTURE",
|
||||||
Table => "TABLE",
|
Table => "TABLE",
|
||||||
TermsCache => "TERMS_CACHE",
|
TermsCache => "TERMS_CACHE",
|
||||||
TermsOrder => "TERMS_ORDER",
|
TermsOrder => "TERMS_ORDER",
|
||||||
|
|
Loading…
Reference in a new issue