Ensure statements are properly escaped when output as a string
This commit is contained in:
parent
75de89d9a1
commit
15fc4a0126
14 changed files with 157 additions and 111 deletions
|
@ -717,7 +717,7 @@ impl Transaction {
|
|||
.put(
|
||||
key,
|
||||
DefineNamespaceStatement {
|
||||
name: ns.to_owned(),
|
||||
name: ns.into(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -730,7 +730,7 @@ impl Transaction {
|
|||
.put(
|
||||
key,
|
||||
DefineDatabaseStatement {
|
||||
name: db.to_owned(),
|
||||
name: db.into(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
@ -743,7 +743,7 @@ impl Transaction {
|
|||
.put(
|
||||
key,
|
||||
DefineTableStatement {
|
||||
name: tb.to_owned(),
|
||||
name: tb.into(),
|
||||
..DefineTableStatement::default()
|
||||
},
|
||||
)
|
||||
|
|
|
@ -33,16 +33,6 @@ pub fn val_char(chr: char) -> bool {
|
|||
is_alphanumeric(chr as u8) || chr == '_'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn escape(s: &str, f: &dyn Fn(char) -> bool, c: &str) -> String {
|
||||
for x in s.chars() {
|
||||
if !f(x) {
|
||||
return format!("{}{}{}", c, s, c);
|
||||
}
|
||||
}
|
||||
s.to_owned()
|
||||
}
|
||||
|
||||
pub fn take_u32(i: &str) -> IResult<&str, u32> {
|
||||
let (i, v) = take_while(is_digit)(i)?;
|
||||
match v.parse::<u32>() {
|
||||
|
|
32
lib/src/sql/escape.rs
Normal file
32
lib/src/sql/escape.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use crate::sql::common::val_char;
|
||||
|
||||
const DOUBLE: char = '"';
|
||||
const DOUBLE_ESC: &str = r#"\""#;
|
||||
|
||||
const BACKTICK: char = '`';
|
||||
const BACKTICK_ESC: &str = r#"\`"#;
|
||||
|
||||
#[inline]
|
||||
pub fn escape_strand(s: &str) -> String {
|
||||
format!("{}{}{}", DOUBLE, s, DOUBLE)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn escape_key(s: &str) -> String {
|
||||
for x in s.chars() {
|
||||
if !val_char(x) {
|
||||
return format!("{}{}{}", DOUBLE, s.replace(DOUBLE, DOUBLE_ESC), DOUBLE);
|
||||
}
|
||||
}
|
||||
s.to_owned()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn escape_ident(s: &str) -> String {
|
||||
for x in s.chars() {
|
||||
if !val_char(x) {
|
||||
return format!("{}{}{}", BACKTICK, s.replace(BACKTICK, BACKTICK_ESC), BACKTICK);
|
||||
}
|
||||
}
|
||||
s.to_owned()
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
use crate::cnf::ID_CHARS;
|
||||
use crate::sql::common::escape;
|
||||
use crate::sql::common::val_char;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_ident;
|
||||
use crate::sql::ident::ident_raw;
|
||||
use crate::sql::number::{number, Number};
|
||||
use nanoid::nanoid;
|
||||
|
@ -50,7 +49,7 @@ impl fmt::Display for Id {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Id::Number(v) => write!(f, "{}", v),
|
||||
Id::String(v) => write!(f, "{}", escape(v, &val_char, "`")),
|
||||
Id::String(v) => write!(f, "{}", escape_ident(v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
use crate::sql::common::escape;
|
||||
use crate::sql::common::val_char;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_ident;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::escaped;
|
||||
use nom::bytes::complete::is_not;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take_while1;
|
||||
use nom::character::complete::char;
|
||||
use nom::character::complete::one_of;
|
||||
use nom::sequence::delimited;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
use std::str;
|
||||
|
||||
const BRACKET_L: char = '⟨';
|
||||
const BRACKET_R: char = '⟩';
|
||||
const BRACKET_END: &str = r#"⟩"#;
|
||||
|
||||
const BACKTICK: &str = r#"`"#;
|
||||
const BACKTICK_ESC: &str = r#"\`"#;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
pub struct Ident(pub String);
|
||||
|
||||
|
@ -41,7 +51,7 @@ impl Deref for Ident {
|
|||
|
||||
impl fmt::Display for Ident {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", escape(&self.0, &val_char, "`"))
|
||||
write!(f, "{}", escape_ident(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,12 +71,14 @@ fn ident_default(i: &str) -> IResult<&str, String> {
|
|||
}
|
||||
|
||||
fn ident_backtick(i: &str) -> IResult<&str, String> {
|
||||
let (i, v) = delimited(char('`'), is_not("`"), char('`'))(i)?;
|
||||
Ok((i, String::from(v)))
|
||||
let (i, _) = char('`')(i)?;
|
||||
let (i, v) = alt((escaped(is_not(BACKTICK_ESC), '\\', one_of(BACKTICK)), tag("")))(i)?;
|
||||
let (i, _) = char('`')(i)?;
|
||||
Ok((i, String::from(v).replace(BACKTICK_ESC, BACKTICK)))
|
||||
}
|
||||
|
||||
fn ident_brackets(i: &str) -> IResult<&str, String> {
|
||||
let (i, v) = delimited(char('⟨'), is_not("⟩"), char('⟩'))(i)?;
|
||||
let (i, v) = delimited(char(BRACKET_L), is_not(BRACKET_END), char(BRACKET_R))(i)?;
|
||||
Ok((i, String::from(v)))
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ pub(crate) mod data;
|
|||
pub(crate) mod datetime;
|
||||
pub(crate) mod duration;
|
||||
pub(crate) mod error;
|
||||
pub(crate) mod escape;
|
||||
pub(crate) mod expression;
|
||||
pub(crate) mod fetch;
|
||||
pub(crate) mod field;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::sql::common::escape;
|
||||
use crate::sql::common::take_u64;
|
||||
use crate::sql::common::val_char;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_ident;
|
||||
use crate::sql::ident::ident_raw;
|
||||
use nom::branch::alt;
|
||||
use nom::character::complete::char;
|
||||
|
@ -18,12 +17,10 @@ impl fmt::Display for Model {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Model::Count(tb, c) => {
|
||||
let t = escape(tb, &val_char, "`");
|
||||
write!(f, "|{}:{}|", t, c)
|
||||
write!(f, "|{}:{}|", escape_ident(tb), c)
|
||||
}
|
||||
Model::Range(tb, b, e) => {
|
||||
let t = escape(tb, &val_char, "`");
|
||||
write!(f, "|{}:{}..{}|", t, b, e)
|
||||
write!(f, "|{}:{}..{}|", escape_ident(tb), b, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@ use crate::dbs::Options;
|
|||
use crate::dbs::Transaction;
|
||||
use crate::err::Error;
|
||||
use crate::sql::comment::mightbespace;
|
||||
use crate::sql::common::{commas, escape, val_char};
|
||||
use crate::sql::common::{commas, val_char};
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_key;
|
||||
use crate::sql::operation::{Op, Operation};
|
||||
use crate::sql::value::{value, Value};
|
||||
use nom::branch::alt;
|
||||
|
@ -122,7 +123,7 @@ impl fmt::Display for Object {
|
|||
f,
|
||||
"{{ {} }}",
|
||||
self.iter()
|
||||
.map(|(k, v)| format!("{}: {}", escape(k, &val_char, "\""), v))
|
||||
.map(|(k, v)| format!("{}: {}", escape_key(k), v))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
|
|
|
@ -8,7 +8,8 @@ use crate::sql::base::{base, Base};
|
|||
use crate::sql::comment::shouldbespace;
|
||||
use crate::sql::duration::{duration, Duration};
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::ident::ident_raw;
|
||||
use crate::sql::escape::escape_strand;
|
||||
use crate::sql::ident::{ident, Ident};
|
||||
use crate::sql::idiom;
|
||||
use crate::sql::idiom::{Idiom, Idioms};
|
||||
use crate::sql::kind::{kind, Kind};
|
||||
|
@ -103,7 +104,7 @@ pub fn define(i: &str) -> IResult<&str, DefineStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineNamespaceStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl DefineNamespaceStatement {
|
||||
|
@ -135,7 +136,7 @@ fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = alt((tag_no_case("NS"), tag_no_case("NAMESPACE")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
DefineNamespaceStatement {
|
||||
|
@ -150,7 +151,7 @@ fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineDatabaseStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl DefineDatabaseStatement {
|
||||
|
@ -187,7 +188,7 @@ fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = alt((tag_no_case("DB"), tag_no_case("DATABASE")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
DefineDatabaseStatement {
|
||||
|
@ -202,7 +203,7 @@ fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineLoginStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub base: Base,
|
||||
pub hash: String,
|
||||
pub code: String,
|
||||
|
@ -253,7 +254,13 @@ impl DefineLoginStatement {
|
|||
|
||||
impl fmt::Display for DefineLoginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE LOGIN {} ON {} PASSHASH {}", self.name, self.base, self.hash)
|
||||
write!(
|
||||
f,
|
||||
"DEFINE LOGIN {} ON {} PASSHASH {}",
|
||||
self.name,
|
||||
self.base,
|
||||
escape_strand(&self.hash)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +269,7 @@ fn login(i: &str) -> IResult<&str, DefineLoginStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("LOGIN")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -321,7 +328,7 @@ fn login_hash(i: &str) -> IResult<&str, DefineLoginOption> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineTokenStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub base: Base,
|
||||
pub kind: Algorithm,
|
||||
pub code: String,
|
||||
|
@ -375,7 +382,10 @@ impl fmt::Display for DefineTokenStatement {
|
|||
write!(
|
||||
f,
|
||||
"DEFINE TOKEN {} ON {} TYPE {} VALUE {}",
|
||||
self.name, self.base, self.kind, self.code
|
||||
self.name,
|
||||
self.base,
|
||||
self.kind,
|
||||
escape_strand(&self.code)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +395,7 @@ fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("TOKEN")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -415,7 +425,7 @@ fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineScopeStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub code: String,
|
||||
pub session: Option<Duration>,
|
||||
pub signup: Option<Value>,
|
||||
|
@ -471,7 +481,7 @@ fn scope(i: &str) -> IResult<&str, DefineScopeStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("SCOPE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, opts) = many0(scope_opts)(i)?;
|
||||
Ok((
|
||||
i,
|
||||
|
@ -552,7 +562,7 @@ fn scope_connect(i: &str) -> IResult<&str, DefineScopeOption> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineTableStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub drop: bool,
|
||||
pub full: bool,
|
||||
pub view: Option<View>,
|
||||
|
@ -633,7 +643,7 @@ fn table(i: &str) -> IResult<&str, DefineTableStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("TABLE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, opts) = many0(table_opts)(i)?;
|
||||
Ok((
|
||||
i,
|
||||
|
@ -718,8 +728,8 @@ fn table_permissions(i: &str) -> IResult<&str, DefineTableOption> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineEventStatement {
|
||||
pub name: String,
|
||||
pub what: String,
|
||||
pub name: Ident,
|
||||
pub what: Ident,
|
||||
pub when: Value,
|
||||
pub then: Values,
|
||||
}
|
||||
|
@ -764,12 +774,12 @@ fn event(i: &str) -> IResult<&str, DefineEventStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("EVENT")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, what) = ident_raw(i)?;
|
||||
let (i, what) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("WHEN")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -796,7 +806,7 @@ fn event(i: &str) -> IResult<&str, DefineEventStatement> {
|
|||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineFieldStatement {
|
||||
pub name: Idiom,
|
||||
pub what: String,
|
||||
pub what: Ident,
|
||||
pub kind: Option<Kind>,
|
||||
pub value: Option<Value>,
|
||||
pub assert: Option<Value>,
|
||||
|
@ -857,7 +867,7 @@ fn field(i: &str) -> IResult<&str, DefineFieldStatement> {
|
|||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, what) = ident_raw(i)?;
|
||||
let (i, what) = ident(i)?;
|
||||
let (i, opts) = many0(field_opts)(i)?;
|
||||
Ok((
|
||||
i,
|
||||
|
@ -935,8 +945,8 @@ fn field_permissions(i: &str) -> IResult<&str, DefineFieldOption> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct DefineIndexStatement {
|
||||
pub name: String,
|
||||
pub what: String,
|
||||
pub name: Ident,
|
||||
pub what: Ident,
|
||||
pub cols: Idioms,
|
||||
pub uniq: bool,
|
||||
}
|
||||
|
@ -992,12 +1002,12 @@ fn index(i: &str) -> IResult<&str, DefineIndexStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("INDEX")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, what) = ident_raw(i)?;
|
||||
let (i, what) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = alt((tag_no_case("COLUMNS"), tag_no_case("FIELDS")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::dbs::Transaction;
|
|||
use crate::err::Error;
|
||||
use crate::sql::comment::shouldbespace;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::ident::ident_raw;
|
||||
use crate::sql::ident::{ident, Ident};
|
||||
use crate::sql::object::Object;
|
||||
use crate::sql::value::Value;
|
||||
use derive::Store;
|
||||
|
@ -19,8 +19,8 @@ pub enum InfoStatement {
|
|||
Kv,
|
||||
Ns,
|
||||
Db,
|
||||
Sc(String),
|
||||
Tb(String),
|
||||
Sc(Ident),
|
||||
Tb(Ident),
|
||||
}
|
||||
|
||||
impl InfoStatement {
|
||||
|
@ -45,7 +45,7 @@ impl InfoStatement {
|
|||
// Process the statement
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_ns().await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("ns".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
|
@ -63,19 +63,19 @@ impl InfoStatement {
|
|||
// Process the databases
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_db(opt.ns()).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
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? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
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? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("nl".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
|
@ -93,27 +93,27 @@ impl InfoStatement {
|
|||
// Process the tables
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_tb(opt.ns(), opt.db()).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
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? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
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_nt(opt.ns()).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
for v in run.all_dt(opt.ns(), opt.db()).await? {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("nt".to_owned(), tmp.into());
|
||||
res.insert("dt".to_owned(), tmp.into());
|
||||
// Process the logins
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_nl(opt.ns()).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
for v in run.all_dl(opt.ns(), opt.db()).await? {
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("nl".to_owned(), tmp.into());
|
||||
res.insert("dl".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
Value::from(res).ok()
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ impl InfoStatement {
|
|||
// Process the tokens
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_st(opt.ns(), opt.db(), sc).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("st".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
|
@ -147,7 +147,7 @@ impl InfoStatement {
|
|||
// Process the events
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_ev(opt.ns(), opt.db(), tb).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("ev".to_owned(), tmp.into());
|
||||
// Process the fields
|
||||
|
@ -159,13 +159,13 @@ impl InfoStatement {
|
|||
// Process the indexs
|
||||
let mut tmp = Object::default();
|
||||
for v in run.all_ix(opt.ns(), opt.db(), tb).await? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
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? {
|
||||
tmp.insert(v.name.to_owned(), v.to_string().into());
|
||||
tmp.insert(v.name.to_string(), v.to_string().into());
|
||||
}
|
||||
res.insert("ft".to_owned(), tmp.into());
|
||||
// Ok all good
|
||||
|
@ -213,14 +213,14 @@ fn db(i: &str) -> IResult<&str, InfoStatement> {
|
|||
fn sc(i: &str) -> IResult<&str, InfoStatement> {
|
||||
let (i, _) = alt((tag_no_case("SCOPE"), tag_no_case("SC")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, scope) = ident_raw(i)?;
|
||||
let (i, scope) = ident(i)?;
|
||||
Ok((i, InfoStatement::Sc(scope)))
|
||||
}
|
||||
|
||||
fn tb(i: &str) -> IResult<&str, InfoStatement> {
|
||||
let (i, _) = alt((tag_no_case("TABLE"), tag_no_case("TB")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, table) = ident_raw(i)?;
|
||||
let (i, table) = ident(i)?;
|
||||
Ok((i, InfoStatement::Tb(table)))
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ mod tests {
|
|||
let res = info(sql);
|
||||
assert!(res.is_ok());
|
||||
let out = res.unwrap().1;
|
||||
assert_eq!(out, InfoStatement::Sc(String::from("test")));
|
||||
assert_eq!(out, InfoStatement::Sc(Ident::from("test")));
|
||||
assert_eq!("INFO FOR SCOPE test", format!("{}", out));
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ mod tests {
|
|||
let res = info(sql);
|
||||
assert!(res.is_ok());
|
||||
let out = res.unwrap().1;
|
||||
assert_eq!(out, InfoStatement::Tb(String::from("test")));
|
||||
assert_eq!(out, InfoStatement::Tb(Ident::from("test")));
|
||||
assert_eq!("INFO FOR TABLE test", format!("{}", out));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::err::Error;
|
|||
use crate::sql::base::{base, Base};
|
||||
use crate::sql::comment::shouldbespace;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::ident::ident_raw;
|
||||
use crate::sql::ident::{ident, Ident};
|
||||
use crate::sql::value::Value;
|
||||
use derive::Store;
|
||||
use nom::branch::alt;
|
||||
|
@ -87,7 +87,7 @@ pub fn remove(i: &str) -> IResult<&str, RemoveStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveNamespaceStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl RemoveNamespaceStatement {
|
||||
|
@ -126,7 +126,7 @@ fn namespace(i: &str) -> IResult<&str, RemoveNamespaceStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = alt((tag_no_case("NS"), tag_no_case("NAMESPACE")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveNamespaceStatement {
|
||||
|
@ -141,7 +141,7 @@ fn namespace(i: &str) -> IResult<&str, RemoveNamespaceStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveDatabaseStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl RemoveDatabaseStatement {
|
||||
|
@ -180,7 +180,7 @@ fn database(i: &str) -> IResult<&str, RemoveDatabaseStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = alt((tag_no_case("DB"), tag_no_case("DATABASE")))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveDatabaseStatement {
|
||||
|
@ -195,7 +195,7 @@ fn database(i: &str) -> IResult<&str, RemoveDatabaseStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveLoginStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub base: Base,
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ fn login(i: &str) -> IResult<&str, RemoveLoginStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("LOGIN")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -270,7 +270,7 @@ fn login(i: &str) -> IResult<&str, RemoveLoginStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveTokenStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub base: Base,
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,7 @@ fn token(i: &str) -> IResult<&str, RemoveTokenStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("TOKEN")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
|
@ -345,7 +345,7 @@ fn token(i: &str) -> IResult<&str, RemoveTokenStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveScopeStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl RemoveScopeStatement {
|
||||
|
@ -381,7 +381,7 @@ fn scope(i: &str) -> IResult<&str, RemoveScopeStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("SCOPE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveScopeStatement {
|
||||
|
@ -396,7 +396,7 @@ fn scope(i: &str) -> IResult<&str, RemoveScopeStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveTableStatement {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
}
|
||||
|
||||
impl RemoveTableStatement {
|
||||
|
@ -435,7 +435,7 @@ fn table(i: &str) -> IResult<&str, RemoveTableStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("TABLE")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveTableStatement {
|
||||
|
@ -450,8 +450,8 @@ fn table(i: &str) -> IResult<&str, RemoveTableStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveEventStatement {
|
||||
pub name: String,
|
||||
pub what: String,
|
||||
pub name: Ident,
|
||||
pub what: Ident,
|
||||
}
|
||||
|
||||
impl RemoveEventStatement {
|
||||
|
@ -487,12 +487,12 @@ fn event(i: &str) -> IResult<&str, RemoveEventStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("EVENT")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, what) = ident_raw(i)?;
|
||||
let (i, what) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveEventStatement {
|
||||
|
@ -508,8 +508,8 @@ fn event(i: &str) -> IResult<&str, RemoveEventStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveFieldStatement {
|
||||
pub name: String,
|
||||
pub what: String,
|
||||
pub name: Ident,
|
||||
pub what: Ident,
|
||||
}
|
||||
|
||||
impl RemoveFieldStatement {
|
||||
|
@ -545,12 +545,12 @@ fn field(i: &str) -> IResult<&str, RemoveFieldStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("FIELD")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, what) = ident_raw(i)?;
|
||||
let (i, what) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveFieldStatement {
|
||||
|
@ -566,8 +566,8 @@ fn field(i: &str) -> IResult<&str, RemoveFieldStatement> {
|
|||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store)]
|
||||
pub struct RemoveIndexStatement {
|
||||
pub name: String,
|
||||
pub what: String,
|
||||
pub name: Ident,
|
||||
pub what: Ident,
|
||||
}
|
||||
|
||||
impl RemoveIndexStatement {
|
||||
|
@ -606,12 +606,12 @@ fn index(i: &str) -> IResult<&str, RemoveIndexStatement> {
|
|||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("INDEX")(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, name) = ident_raw(i)?;
|
||||
let (i, name) = ident(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, _) = tag_no_case("ON")(i)?;
|
||||
let (i, _) = opt(tuple((shouldbespace, tag_no_case("TABLE"))))(i)?;
|
||||
let (i, _) = shouldbespace(i)?;
|
||||
let (i, what) = ident_raw(i)?;
|
||||
let (i, what) = ident(i)?;
|
||||
Ok((
|
||||
i,
|
||||
RemoveIndexStatement {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_strand;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::escaped;
|
||||
use nom::bytes::complete::is_not;
|
||||
|
@ -49,7 +50,7 @@ impl Strand {
|
|||
|
||||
impl fmt::Display for Strand {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "\"{}\"", self.0)
|
||||
write!(f, "{}", escape_strand(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::sql::common::commas;
|
||||
use crate::sql::common::escape;
|
||||
use crate::sql::common::val_char;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::ident::ident_raw;
|
||||
use crate::sql::escape::escape_ident;
|
||||
use crate::sql::ident::{ident_raw, Ident};
|
||||
use nom::multi::separated_list1;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
@ -32,6 +31,12 @@ impl From<String> for Table {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Ident> for Table {
|
||||
fn from(v: Ident) -> Self {
|
||||
Table(v.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Table {
|
||||
type Target = String;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -41,7 +46,7 @@ impl Deref for Table {
|
|||
|
||||
impl fmt::Display for Table {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", escape(&self.0, &val_char, "`"))
|
||||
write!(f, "{}", escape_ident(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::sql::common::escape;
|
||||
use crate::sql::common::val_char;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_ident;
|
||||
use crate::sql::id::{id, Id};
|
||||
use crate::sql::ident::ident_raw;
|
||||
use crate::sql::number::Number;
|
||||
|
@ -45,8 +44,7 @@ impl From<(String, Number)> for Thing {
|
|||
|
||||
impl fmt::Display for Thing {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let t = escape(&self.tb, &val_char, "`");
|
||||
write!(f, "{}:{}", t, self.id)
|
||||
write!(f, "{}:{}", escape_ident(&self.tb), self.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue