show attributes of current database
This commit is contained in:
parent
a9c05ba9b7
commit
9932a98c6f
3 changed files with 72 additions and 4 deletions
|
@ -38,6 +38,7 @@ pub static CLOSE_COMMAND: &'static str = &"close";
|
||||||
pub static LONG_QUERY_COMMAND: &'static str = &"query";
|
pub static LONG_QUERY_COMMAND: &'static str = &"query";
|
||||||
pub static SHORT_QUERY_COMMAND: &'static str = &"q";
|
pub static SHORT_QUERY_COMMAND: &'static str = &"q";
|
||||||
pub static SCHEMA_COMMAND: &'static str = &"schema";
|
pub static SCHEMA_COMMAND: &'static str = &"schema";
|
||||||
|
pub static ATTRIBUTES_COMMAND: &'static str = &"attributes";
|
||||||
pub static LONG_TRANSACT_COMMAND: &'static str = &"transact";
|
pub static LONG_TRANSACT_COMMAND: &'static str = &"transact";
|
||||||
pub static SHORT_TRANSACT_COMMAND: &'static str = &"t";
|
pub static SHORT_TRANSACT_COMMAND: &'static str = &"t";
|
||||||
pub static LONG_EXIT_COMMAND: &'static str = &"exit";
|
pub static LONG_EXIT_COMMAND: &'static str = &"exit";
|
||||||
|
@ -51,6 +52,7 @@ pub enum Command {
|
||||||
Open(String),
|
Open(String),
|
||||||
Query(String),
|
Query(String),
|
||||||
Schema,
|
Schema,
|
||||||
|
Attributes,
|
||||||
Transact(String),
|
Transact(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +71,8 @@ impl Command {
|
||||||
&Command::Open(_) |
|
&Command::Open(_) |
|
||||||
&Command::Close |
|
&Command::Close |
|
||||||
&Command::Exit |
|
&Command::Exit |
|
||||||
&Command::Schema => true
|
&Command::Schema |
|
||||||
|
&Command::Attributes => true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +99,9 @@ impl Command {
|
||||||
&Command::Schema => {
|
&Command::Schema => {
|
||||||
format!(".{}", SCHEMA_COMMAND)
|
format!(".{}", SCHEMA_COMMAND)
|
||||||
},
|
},
|
||||||
|
&Command::Attributes => {
|
||||||
|
format!(".{}", ATTRIBUTES_COMMAND)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +151,15 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
|
||||||
Ok(Command::Schema)
|
Ok(Command::Schema)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let attributes_parser = string(ATTRIBUTES_COMMAND)
|
||||||
|
.with(no_arg_parser())
|
||||||
|
.map(|args| {
|
||||||
|
if !args.is_empty() {
|
||||||
|
bail!(cli::ErrorKind::CommandParse(format!("Unrecognized argument {:?}", args[0])) );
|
||||||
|
}
|
||||||
|
Ok(Command::Attributes)
|
||||||
|
});
|
||||||
|
|
||||||
let exit_parser = try(string(LONG_EXIT_COMMAND)).or(try(string(SHORT_EXIT_COMMAND)))
|
let exit_parser = try(string(LONG_EXIT_COMMAND)).or(try(string(SHORT_EXIT_COMMAND)))
|
||||||
.with(no_arg_parser())
|
.with(no_arg_parser())
|
||||||
.map(|args| {
|
.map(|args| {
|
||||||
|
@ -176,13 +191,14 @@ pub fn command(s: &str) -> Result<Command, cli::Error> {
|
||||||
|
|
||||||
spaces()
|
spaces()
|
||||||
.skip(token('.'))
|
.skip(token('.'))
|
||||||
.with(choice::<[&mut Parser<Input = _, Output = Result<Command, cli::Error>>; 7], _>
|
.with(choice::<[&mut Parser<Input = _, Output = Result<Command, cli::Error>>; 8], _>
|
||||||
([&mut try(help_parser),
|
([&mut try(help_parser),
|
||||||
&mut try(open_parser),
|
&mut try(open_parser),
|
||||||
&mut try(close_parser),
|
&mut try(close_parser),
|
||||||
&mut try(exit_parser),
|
&mut try(exit_parser),
|
||||||
&mut try(query_parser),
|
&mut try(query_parser),
|
||||||
&mut try(schema_parser),
|
&mut try(schema_parser),
|
||||||
|
&mut try(attributes_parser),
|
||||||
&mut try(transact_parser)]))
|
&mut try(transact_parser)]))
|
||||||
.parse(s)
|
.parse(s)
|
||||||
.unwrap_or((Err(cli::ErrorKind::CommandParse(format!("Invalid command {:?}", s)).into()), "")).0
|
.unwrap_or((Err(cli::ErrorKind::CommandParse(format!("Invalid command {:?}", s)).into()), "")).0
|
||||||
|
@ -390,6 +406,33 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_attributes_parser_with_args() {
|
||||||
|
let input = ".attributes arg1";
|
||||||
|
let err = command(&input).expect_err("Expected an error");
|
||||||
|
assert_eq!(err.to_string(), format!("Invalid command {:?}", input));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_attributes_parser_no_args() {
|
||||||
|
let input = ".attributes";
|
||||||
|
let cmd = command(&input).expect("Expected attributes command");
|
||||||
|
match cmd {
|
||||||
|
Command::Attributes => assert!(true),
|
||||||
|
_ => assert!(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_attributes_parser_no_args_trailing_whitespace() {
|
||||||
|
let input = ".attributes ";
|
||||||
|
let cmd = command(&input).expect("Expected attributes command");
|
||||||
|
match cmd {
|
||||||
|
Command::Attributes => assert!(true),
|
||||||
|
_ => assert!(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_query_parser_complete_edn() {
|
fn test_query_parser_complete_edn() {
|
||||||
let input = ".q [:find ?x :where [?x foo/bar ?y]]";
|
let input = ".q [:find ?x :where [?x foo/bar ?y]]";
|
||||||
|
|
|
@ -27,6 +27,7 @@ use command_parser::{
|
||||||
SHORT_TRANSACT_COMMAND,
|
SHORT_TRANSACT_COMMAND,
|
||||||
LONG_EXIT_COMMAND,
|
LONG_EXIT_COMMAND,
|
||||||
SHORT_EXIT_COMMAND,
|
SHORT_EXIT_COMMAND,
|
||||||
|
ATTRIBUTES_COMMAND,
|
||||||
};
|
};
|
||||||
use input::InputReader;
|
use input::InputReader;
|
||||||
use input::InputResult::{
|
use input::InputResult::{
|
||||||
|
@ -43,6 +44,7 @@ use store::{
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref COMMAND_HELP: HashMap<&'static str, &'static str> = {
|
static ref COMMAND_HELP: HashMap<&'static str, &'static str> = {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
|
map.insert(ATTRIBUTES_COMMAND, "Output the attributes for the schema in the current open database.");
|
||||||
map.insert(LONG_EXIT_COMMAND, "Close the current database and exit the REPL.");
|
map.insert(LONG_EXIT_COMMAND, "Close the current database and exit the REPL.");
|
||||||
map.insert(SHORT_EXIT_COMMAND, "Shortcut for `.exit`. Close the current database and exit the REPL.");
|
map.insert(SHORT_EXIT_COMMAND, "Shortcut for `.exit`. Close the current database and exit the REPL.");
|
||||||
map.insert(HELP_COMMAND, "Show help for commands.");
|
map.insert(HELP_COMMAND, "Show help for commands.");
|
||||||
|
@ -120,8 +122,14 @@ impl Repl {
|
||||||
Ok(s) => println!("{}", s),
|
Ok(s) => println!("{}", s),
|
||||||
Err(e) => println!("{}", e)
|
Err(e) => println!("{}", e)
|
||||||
};
|
};
|
||||||
|
},
|
||||||
}
|
Command::Attributes => {
|
||||||
|
let edn = self.store.fetch_attributes();
|
||||||
|
match edn.to_pretty(120) {
|
||||||
|
Ok(s) => println!("{}", s),
|
||||||
|
Err(e) => println!("{}", e)
|
||||||
|
};
|
||||||
|
},
|
||||||
Command::Transact(transaction) => self.execute_transact(transaction),
|
Command::Transact(transaction) => self.execute_transact(transaction),
|
||||||
Command::Exit => {
|
Command::Exit => {
|
||||||
self.close();
|
self.close();
|
||||||
|
|
|
@ -62,7 +62,24 @@ impl Store {
|
||||||
Ok(self.conn.transact(&mut self.handle, &transaction)?)
|
Ok(self.conn.transact(&mut self.handle, &transaction)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the schema is the entire schema of the store including structure used to describe the store.
|
||||||
pub fn fetch_schema(&self) -> edn::Value {
|
pub fn fetch_schema(&self) -> edn::Value {
|
||||||
self.conn.current_schema().to_edn_value()
|
self.conn.current_schema().to_edn_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the attributes are the specific attributes added to the schema for this particular store.
|
||||||
|
pub fn fetch_attributes(&self) -> edn::Value {
|
||||||
|
let schema = self.conn.current_schema();
|
||||||
|
|
||||||
|
edn::Value::Vector((&schema.schema_map).iter()
|
||||||
|
.filter_map(|(entid, attribute)| {
|
||||||
|
if let Some(ident) = schema.get_ident(*entid) {
|
||||||
|
if !ident.namespace.starts_with("db") {
|
||||||
|
return Some(attribute.to_edn_value(Some(ident.clone())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue