Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Open DB inside CLI (#452)#463

Merged
fluffyemily merged 4 commits into
fluffyemily/clifrom
fluffyemily/open-db
May 30, 2017
Merged

Open DB inside CLI (#452)#463
fluffyemily merged 4 commits into
fluffyemily/clifrom
fluffyemily/open-db

Conversation

@fluffyemily
Copy link
Copy Markdown
Contributor

@fluffyemily fluffyemily commented May 10, 2017

  • Pass in db as command line arg
  • Open from inside repl using .open [db_name]
  • Default to in memory DB if no db arg provided.

#452

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
static COMMANDS: &'static [CommandDef] = &[
CommandDef{name: "open", args: Some("<database>"),
accepts: CmdArgs::Text,
help: "Open a database with the provided name. Creates a new database of that name if it doesn't already exist."},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a path, a URI, or a name?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add close?

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
];

/// Looks up a command name by what may be an abbreviated prefix.
/// Returns the `CommandDef` structure if one is found.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a hacky way of doing what getopts calls abbreviation to uniqueness. It'll only work so long as none of your commands share a prefix — close and create, for example, will clash for .c.

Think about whether you need to do this.

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
/// Looks up a command name by what may be an abbreviated prefix.
/// Returns the `CommandDef` structure if one is found.
pub fn lookup_command(name: &str) -> Option<&'static CommandDef> {
for cmd in COMMANDS.iter() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use .find instead of iterating manually. This becomes a one-liner.

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
}

/// Calls the given closure for each command whose name begins with `prefix`.
pub fn search_command<F>(prefix: &str, mut f: F)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete dis.

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
}
},
InputError(err) => {
if let Some(err) = err {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When will we not have an error in the input error? In that case, can we have a different enum?

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
fn handle_command(&mut self, cmd: String, args: Option<String>) {
println!("{:?} {:?}", cmd, args);
match lookup_command(&cmd).map(|c| c.name) {
Some("open") => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look up map_or and unwrap_or and friends.

match self {
&Command::Query(_) |
&Command::Transact(_) => false,
_ => true
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enumerate every command rather than using _ — that way this'll fail to compile if you add a new command and forget to extend this match!

Command::Help(args)
});

let open_parser = string(OPEN_COMMAND).and(space()).and(many1::<Vec<_>, _>(alpha_num()).and(eof())).map(|x| {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be skip_many(space())?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a file path you'll need more than alpha_num:

mentat=> .open /tmp/foo.db
Invalid command ".open /tmp/foo.db"
mentat=> .open foo.db
Invalid command ".open foo.db"

.and(choice::<[&mut Parser<Input = _, Output = Command>; 3], _>
([&mut try(help_parser),
&mut try(open_parser),
&mut try(close_parser),]))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you put .skip(eof()) on the end here, you can remove it from the parsers above.

match self.reader {
Some(ref mut r) => {
r.set_prompt(prompt);
r.read_line().ok().and_then(|line| line)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need that and_then?

Comment thread tools/cli/src/mentat_cli/store.rs Outdated
}

fn db_output_name(db_name: &String) -> String {
if db_name.is_empty() { "in memory db".to_string() } else { db_name.clone() }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in-memory

// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

use combine::{eof, many, many1, sep_by, skip_many, token, Parser};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

many is unused.


let close_parser = string(CLOSE_COMMAND).and(skip_many(space())).and(eof()).map( |_| Command::Close );

token('.')
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow leading whitespace?

mentat=>  .help
Invalid command " .help"

}
} else {
for arg in args {
let msg = COMMAND_HELP.get(arg.as_str());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should allow the command arg to start with a . — I immediately typed .help .open and got all of the commands, 'cos it wanted .help open.

Comment thread tools/cli/src/mentat_cli/repl.rs Outdated
Command::Open(db) => {
self.store.open(Some(db));
},
Command::Close => self.store.close(),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mentat=> .open foo
Database "foo" opened
mentat=> .close
Database "foo" closed
mentat=> .close
Database "in memory db" closed
mentat=> .close
Database "in memory db" closed

I think we should consider having quit == close, and open = close+open, just like sqlite3.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so to close the existing db and open a new in-memory DB would be

mentat=> .open

to close existing db and exit would be

mentat=> .quit

?

@fluffyemily fluffyemily requested a review from ncalexan May 16, 2017 15:56
Copy link
Copy Markdown
Member

@ncalexan ncalexan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggested some parsing changes and some changes to the types, specifically around using Result. Feel free to counter; I haven't read your interactions with @rnewman, which would probably cover this.

For the next review round, let's fold this down to 1-2 commits. The iteration of the change sequence is not helping review.

Comment thread Cargo.toml

[workspace]
members = []
members = ["tools/cli"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I had to go read https://github.com/nox/rust-rfcs/blob/master/text/1525-cargo-workspace.md to understand this. Should we be using workspaces more generally? If I understand correctly, we could make most of the existing crates share a workspace, avoiding to rebuild shared dependencies.

// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

use combine::{any, eof, many, many1, sep_by, skip_many, token, Parser};
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We settled on the

use very::{
    long,
    vertical,
    list,
    style,
};


pub fn command(s: &str) -> Command {
let help_parser = string(HELP_COMMAND)
.and(skip_many(space()))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.with and .skip let you drop leading and trailing input, respectively. So this is equivalent to

string("help").with(skip_many(space())).with(many::<Vec<_>, _> ...

Then you won't need to index in the way you are.

let help_parser = string(HELP_COMMAND)
.and(skip_many(space()))
.and(many::<Vec<_>, _>(try(any())))
.map(|x| {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, you're parsing whitespace separated strings here; why not use combine to do this? I'll push a patch to show what I mean.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Help(Vec<String>),
Open(String),
Close,
Err(String),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've encoded errors into your Command type, which seems unnatural to me. Why not use Result<Command, AppropriateErrorType> as appropriate?

}

impl Command {
pub fn is_complete(&self) -> bool {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment explaining what "complete" means would help.

}
}

#[test]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great tests!

}
}

fn help_command(&self, args: Vec<String>) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github wouldn't let me comment on the tools/cli/src/mentat_cli/store.rs file, so here it is:

I expect we will want to grow this into something (like Conn) in core, so rather than expect() and swallowing the underlying error, can we return Result<Store, AppropriateErrorType> and handle errors like this at a higher level?

If you really want Store to be CLI specific and to handle errors inline, I think you need to surface the underlying error in some way.

Emily Toop and others added 3 commits May 19, 2017 13:19
Rearrange workspace to allow import of mentat crate in cli crate

Create store object inside repl when started for connecting to mentat

Use provided DB name to open connection in store

Accept DB name as command line arg.

Open on CLI start

Implement '.open' command to open desired DB from inside CLI
* Closes existing open db and opens new in memory db
Move over to using Result rather than enums with err
* Parse query and transact commands

* Implement is_complete for transactions and queries

* Improve query parser. Am still not happy with it though.

There must be some way that I can retain the eof() after the `then` that means I don't have to move the skip on spaces and eof

Make in process command storing clearer.

Add comments around in process commands.
Add alternative commands for transact/t and query/q

* Address review comments r=nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Send queries and transactions to mentat and output the results (#466)

* Send queries and transactions to mentat and output the results

move outputting query and transaction results out of store and into repl

* Add query and transact commands to help

* Execute queries and transacts passed in at startup

* Address review comments =nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Execute command line args in order

* Addressing rebase issues
@fluffyemily fluffyemily merged commit 46fc161 into fluffyemily/cli May 30, 2017
@fluffyemily fluffyemily deleted the fluffyemily/open-db branch May 30, 2017 10:06
fluffyemily pushed a commit that referenced this pull request Nov 21, 2017
* Open named database OR default to in memory database if no name provided

Rearrange workspace to allow import of mentat crate in cli crate

Create store object inside repl when started for connecting to mentat

Use provided DB name to open connection in store

Accept DB name as command line arg.

Open on CLI start

Implement '.open' command to open desired DB from inside CLI

* Implement Close command to close current DB.
* Closes existing open db and opens new in memory db

* Review comment: Use `combine` to parse arguments.

Move over to using Result rather than enums with err

* Accept and parse EDN Query and Transact commands (#453) (#465)

* Parse query and transact commands

* Implement is_complete for transactions and queries

* Improve query parser. Am still not happy with it though.

There must be some way that I can retain the eof() after the `then` that means I don't have to move the skip on spaces and eof

Make in process command storing clearer.

Add comments around in process commands.
Add alternative commands for transact/t and query/q

* Address review comments r=nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Send queries and transactions to mentat and output the results (#466)

* Send queries and transactions to mentat and output the results

move outputting query and transaction results out of store and into repl

* Add query and transact commands to help

* Execute queries and transacts passed in at startup

* Address review comments =nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Execute command line args in order

* Addressing rebase issues
fluffyemily pushed a commit that referenced this pull request Nov 21, 2017
* Open named database OR default to in memory database if no name provided

Rearrange workspace to allow import of mentat crate in cli crate

Create store object inside repl when started for connecting to mentat

Use provided DB name to open connection in store

Accept DB name as command line arg.

Open on CLI start

Implement '.open' command to open desired DB from inside CLI

* Implement Close command to close current DB.
* Closes existing open db and opens new in memory db

* Review comment: Use `combine` to parse arguments.

Move over to using Result rather than enums with err

* Accept and parse EDN Query and Transact commands (#453) (#465)

* Parse query and transact commands

* Implement is_complete for transactions and queries

* Improve query parser. Am still not happy with it though.

There must be some way that I can retain the eof() after the `then` that means I don't have to move the skip on spaces and eof

Make in process command storing clearer.

Add comments around in process commands.
Add alternative commands for transact/t and query/q

* Address review comments r=nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Send queries and transactions to mentat and output the results (#466)

* Send queries and transactions to mentat and output the results

move outputting query and transaction results out of store and into repl

* Add query and transact commands to help

* Execute queries and transacts passed in at startup

* Address review comments =nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Execute command line args in order

* Addressing rebase issues
fluffyemily pushed a commit that referenced this pull request Nov 21, 2017
* Create mentat command line.
* Create tools directory containing new crate for mentat_cli.
* Add simple cli with mentat prompt.

* Remove rustc-serialize dependency

* Open DB inside CLI (#452) (#463)

* Open named database OR default to in memory database if no name provided

Rearrange workspace to allow import of mentat crate in cli crate

Create store object inside repl when started for connecting to mentat

Use provided DB name to open connection in store

Accept DB name as command line arg.

Open on CLI start

Implement '.open' command to open desired DB from inside CLI

* Implement Close command to close current DB.
* Closes existing open db and opens new in memory db

* Review comment: Use `combine` to parse arguments.

Move over to using Result rather than enums with err

* Accept and parse EDN Query and Transact commands (#453) (#465)

* Parse query and transact commands

* Implement is_complete for transactions and queries

* Improve query parser. Am still not happy with it though.

There must be some way that I can retain the eof() after the `then` that means I don't have to move the skip on spaces and eof

Make in process command storing clearer.

Add comments around in process commands.
Add alternative commands for transact/t and query/q

* Address review comments r=nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Send queries and transactions to mentat and output the results (#466)

* Send queries and transactions to mentat and output the results

move outputting query and transaction results out of store and into repl

* Add query and transact commands to help

* Execute queries and transacts passed in at startup

* Address review comments =nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Execute command line args in order

* Addressing rebase issues

* Exit CLI (#457) (#484) r-rnewman

* Implement exit command for cli tool

* Address review comments r=rnewman

* Include exit commands in help

* Show schema of current DB (#487)

* Fixing rebase issues

* addressing nit

* Match updated dependencies on CLI crate and remove unused import
RDR8 pushed a commit to RDR8/mentat that referenced this pull request Mar 12, 2018
* Create mentat command line.
* Create tools directory containing new crate for mentat_cli.
* Add simple cli with mentat prompt.

* Remove rustc-serialize dependency

* Open DB inside CLI (mozilla#452) (mozilla#463)

* Open named database OR default to in memory database if no name provided

Rearrange workspace to allow import of mentat crate in cli crate

Create store object inside repl when started for connecting to mentat

Use provided DB name to open connection in store

Accept DB name as command line arg.

Open on CLI start

Implement '.open' command to open desired DB from inside CLI

* Implement Close command to close current DB.
* Closes existing open db and opens new in memory db

* Review comment: Use `combine` to parse arguments.

Move over to using Result rather than enums with err

* Accept and parse EDN Query and Transact commands (mozilla#453) (mozilla#465)

* Parse query and transact commands

* Implement is_complete for transactions and queries

* Improve query parser. Am still not happy with it though.

There must be some way that I can retain the eof() after the `then` that means I don't have to move the skip on spaces and eof

Make in process command storing clearer.

Add comments around in process commands.
Add alternative commands for transact/t and query/q

* Address review comments r=nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Send queries and transactions to mentat and output the results (mozilla#466)

* Send queries and transactions to mentat and output the results

move outputting query and transaction results out of store and into repl

* Add query and transact commands to help

* Execute queries and transacts passed in at startup

* Address review comments =nalexander.

* Bump rust version number.
* Use `bail` when throwing errors.
* Improve edn parser.
* Remove references to unused `more` flag.
* Improve naming of query and transact commands.

* Execute command line args in order

* Addressing rebase issues

* Exit CLI (mozilla#457) (mozilla#484) r-rnewman

* Implement exit command for cli tool

* Address review comments r=rnewman

* Include exit commands in help

* Show schema of current DB (mozilla#487)

* Fixing rebase issues

* addressing nit

* Match updated dependencies on CLI crate and remove unused import
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants