Pre: Remove open_empty.

This was a work-around for Tolstoy, which couldn't gracefully handle
syncing a store with a bootstrap transaction.  Tolstoy now handles
that single transaction, so this is no longer necessary.
This commit is contained in:
Nick Alexander 2018-06-06 15:47:32 -07:00 committed by Grisha Kruglov
parent 8ddbd18f5f
commit 0b84a0802d
3 changed files with 9 additions and 123 deletions

View file

@ -89,22 +89,6 @@ impl Store {
}) })
} }
/// Returns a totally blank store with no bootstrap schema. Use `open` instead.
pub fn open_empty(path: &str) -> Result<Store> {
if !path.is_empty() {
if Path::new(path).exists() {
bail!(MentatError::PathAlreadyExists(path.to_string()));
}
}
let mut connection = ::new_connection(path)?;
let conn = Conn::empty(&mut connection)?;
Ok(Store {
conn: conn,
sqlite: connection,
})
}
pub fn transact(&mut self, transaction: &str) -> Result<TxReport> { pub fn transact(&mut self, transaction: &str) -> Result<TxReport> {
let mut ip = self.begin_transaction()?; let mut ip = self.begin_transaction()?;
let report = ip.transact(transaction)?; let report = ip.transact(transaction)?;
@ -127,28 +111,9 @@ impl Store {
}) })
} }
/// Variant of `open_empty` that allows a key (for encryption/decryption) to /// Change the key for a database that was opened using `open_with_key` (using `PRAGMA
/// be supplied. Fails unless linked against sqlcipher (or something else /// rekey`). Fails unless linked against sqlcipher (or something else that supports the Sqlite
/// that supports the Sqlite Encryption Extension). /// Encryption Extension).
pub fn open_empty_with_key(path: &str, encryption_key: &str) -> Result<Store> {
if !path.is_empty() {
if Path::new(path).exists() {
bail!(MentatError::PathAlreadyExists(path.to_string()));
}
}
let mut connection = ::new_connection_with_key(path, encryption_key)?;
let conn = Conn::empty(&mut connection)?;
Ok(Store {
conn: conn,
sqlite: connection,
})
}
/// Change the key for a database that was opened using `open_with_key` or
/// `open_empty_with_key` (using `PRAGMA rekey`). Fails unless linked
/// against sqlcipher (or something else that supports the Sqlite Encryption
/// Extension).
pub fn change_encryption_key(&mut self, new_encryption_key: &str) -> Result<()> { pub fn change_encryption_key(&mut self, new_encryption_key: &str) -> Result<()> {
::change_encryption_key(&self.sqlite, new_encryption_key)?; ::change_encryption_key(&self.sqlite, new_encryption_key)?;
Ok(()) Ok(())

View file

@ -51,9 +51,7 @@ pub static COMMAND_HELP: &'static str = &"help";
pub static COMMAND_IMPORT_LONG: &'static str = &"import"; pub static COMMAND_IMPORT_LONG: &'static str = &"import";
pub static COMMAND_IMPORT_SHORT: &'static str = &"i"; pub static COMMAND_IMPORT_SHORT: &'static str = &"i";
pub static COMMAND_OPEN: &'static str = &"open"; pub static COMMAND_OPEN: &'static str = &"open";
pub static COMMAND_OPEN_EMPTY: &'static str = &"empty";
pub static COMMAND_OPEN_ENCRYPTED: &'static str = &"open_encrypted"; pub static COMMAND_OPEN_ENCRYPTED: &'static str = &"open_encrypted";
pub static COMMAND_OPEN_EMPTY_ENCRYPTED: &'static str = &"empty_encrypted";
pub static COMMAND_QUERY_LONG: &'static str = &"query"; pub static COMMAND_QUERY_LONG: &'static str = &"query";
pub static COMMAND_QUERY_SHORT: &'static str = &"q"; pub static COMMAND_QUERY_SHORT: &'static str = &"q";
pub static COMMAND_QUERY_EXPLAIN_LONG: &'static str = &"explain_query"; pub static COMMAND_QUERY_EXPLAIN_LONG: &'static str = &"explain_query";
@ -73,9 +71,7 @@ pub enum Command {
Help(Vec<String>), Help(Vec<String>),
Import(String), Import(String),
Open(String), Open(String),
OpenEmpty(String),
OpenEncrypted(String, String), OpenEncrypted(String, String),
OpenEmptyEncrypted(String, String),
Query(String), Query(String),
QueryExplain(String), QueryExplain(String),
QueryPrepared(String), QueryPrepared(String),
@ -105,9 +101,7 @@ impl Command {
&Command::Help(_) | &Command::Help(_) |
&Command::Import(_) | &Command::Import(_) |
&Command::Open(_) | &Command::Open(_) |
&Command::OpenEmpty(_) |
&Command::OpenEncrypted(_, _) | &Command::OpenEncrypted(_, _) |
&Command::OpenEmptyEncrypted(_, _) |
&Command::Timer(_) | &Command::Timer(_) |
&Command::Schema | &Command::Schema |
&Command::Sync(_) &Command::Sync(_)
@ -128,9 +122,7 @@ impl Command {
&Command::Exit | &Command::Exit |
&Command::Help(_) | &Command::Help(_) |
&Command::Open(_) | &Command::Open(_) |
&Command::OpenEmpty(_) |
&Command::OpenEncrypted(_, _) | &Command::OpenEncrypted(_, _) |
&Command::OpenEmptyEncrypted(_, _) |
&Command::QueryExplain(_) | &Command::QueryExplain(_) |
&Command::Timer(_) | &Command::Timer(_) |
&Command::Schema | &Command::Schema |
@ -159,15 +151,9 @@ impl Command {
&Command::Open(ref args) => { &Command::Open(ref args) => {
format!(".{} {}", COMMAND_OPEN, args) format!(".{} {}", COMMAND_OPEN, args)
}, },
&Command::OpenEmpty(ref args) => {
format!(".{} {}", COMMAND_OPEN_EMPTY, args)
},
&Command::OpenEncrypted(ref db, ref key) => { &Command::OpenEncrypted(ref db, ref key) => {
format!(".{} {} {}", COMMAND_OPEN_ENCRYPTED, db, key) format!(".{} {} {}", COMMAND_OPEN_ENCRYPTED, db, key)
}, },
&Command::OpenEmptyEncrypted(ref db, ref key) => {
format!(".{} {} {}", COMMAND_OPEN_EMPTY_ENCRYPTED, db, key)
},
&Command::Query(ref args) => { &Command::Query(ref args) => {
format!(".{} {}", COMMAND_QUERY_LONG, args) format!(".{} {}", COMMAND_QUERY_LONG, args)
}, },
@ -282,15 +268,9 @@ pub fn command(s: &str) -> Result<Command, Error> {
let open_parser = opener(COMMAND_OPEN, 1).map(|args_res| let open_parser = opener(COMMAND_OPEN, 1).map(|args_res|
args_res.map(|args| Command::Open(args[0].clone()))); args_res.map(|args| Command::Open(args[0].clone())));
let open_empty_parser = opener(COMMAND_OPEN_EMPTY, 1).map(|args_res|
args_res.map(|args| Command::OpenEmpty(args[0].clone())));
let open_encrypted_parser = opener(COMMAND_OPEN_ENCRYPTED, 2).map(|args_res| let open_encrypted_parser = opener(COMMAND_OPEN_ENCRYPTED, 2).map(|args_res|
args_res.map(|args| Command::OpenEncrypted(args[0].clone(), args[1].clone()))); args_res.map(|args| Command::OpenEncrypted(args[0].clone(), args[1].clone())));
let open_empty_encrypted_parser = opener(COMMAND_OPEN_EMPTY_ENCRYPTED, 2).map(|args_res|
args_res.map(|args| Command::OpenEmptyEncrypted(args[0].clone(), args[1].clone())));
let query_parser = try(string(COMMAND_QUERY_LONG)).or(try(string(COMMAND_QUERY_SHORT))) let query_parser = try(string(COMMAND_QUERY_LONG)).or(try(string(COMMAND_QUERY_SHORT)))
.with(edn_arg_parser()) .with(edn_arg_parser())
.map(|x| { .map(|x| {
@ -340,15 +320,13 @@ pub fn command(s: &str) -> Result<Command, Error> {
spaces() spaces()
.skip(token('.')) .skip(token('.'))
.with(choice::<[&mut Parser<Input = _, Output = Result<Command, Error>>; 16], _> .with(choice::<[&mut Parser<Input = _, Output = Result<Command, Error>>; 14], _>
([&mut try(help_parser), ([&mut try(help_parser),
&mut try(import_parser), &mut try(import_parser),
&mut try(timer_parser), &mut try(timer_parser),
&mut try(cache_parser), &mut try(cache_parser),
&mut try(open_encrypted_parser), &mut try(open_encrypted_parser),
&mut try(open_empty_encrypted_parser),
&mut try(open_parser), &mut try(open_parser),
&mut try(open_empty_parser),
&mut try(close_parser), &mut try(close_parser),
&mut try(explain_query_parser), &mut try(explain_query_parser),
&mut try(exit_parser), &mut try(exit_parser),
@ -459,19 +437,6 @@ mod tests {
} }
} }
#[test]
fn test_empty_encrypted_parser() {
let input = ".empty_encrypted /path/to/my.db hunter2";
let cmd = command(&input).expect("Expected empty_encrypted command");
match cmd {
Command::OpenEmptyEncrypted(path, key) => {
assert_eq!(path, "/path/to/my.db".to_string());
assert_eq!(key, "hunter2".to_string());
},
_ => assert!(false)
}
}
#[test] #[test]
fn test_open_encrypted_parser_missing_key() { fn test_open_encrypted_parser_missing_key() {
let input = ".open_encrypted path/to/db.db"; let input = ".open_encrypted path/to/db.db";
@ -479,13 +444,6 @@ mod tests {
assert_eq!(err.to_string(), "Missing required argument"); assert_eq!(err.to_string(), "Missing required argument");
} }
#[test]
fn test_empty_encrypted_parser_missing_key() {
let input = ".empty_encrypted path/to/db.db";
let err = command(&input).expect_err("Expected an error");
assert_eq!(err.to_string(), "Missing required argument");
}
#[test] #[test]
fn test_sync_parser_path_arg() { fn test_sync_parser_path_arg() {
let input = ".sync https://example.com/api/ 316ea470-ce35-4adf-9c61-e0de6e289c59"; let input = ".sync https://example.com/api/ 316ea470-ce35-4adf-9c61-e0de6e289c59";

View file

@ -63,7 +63,6 @@ use command_parser::{
COMMAND_HELP, COMMAND_HELP,
COMMAND_IMPORT_LONG, COMMAND_IMPORT_LONG,
COMMAND_OPEN, COMMAND_OPEN,
COMMAND_OPEN_EMPTY,
COMMAND_QUERY_LONG, COMMAND_QUERY_LONG,
COMMAND_QUERY_SHORT, COMMAND_QUERY_SHORT,
COMMAND_QUERY_EXPLAIN_LONG, COMMAND_QUERY_EXPLAIN_LONG,
@ -81,7 +80,6 @@ use command_parser::{
// omit them from help message (since they wouldn't work). // omit them from help message (since they wouldn't work).
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
use command_parser::{ use command_parser::{
COMMAND_OPEN_EMPTY_ENCRYPTED,
COMMAND_OPEN_ENCRYPTED, COMMAND_OPEN_ENCRYPTED,
}; };
@ -107,12 +105,9 @@ lazy_static! {
(COMMAND_EXIT_SHORT, "Shortcut for `.exit`. Close the current database and exit the REPL."), (COMMAND_EXIT_SHORT, "Shortcut for `.exit`. Close the current database and exit the REPL."),
(COMMAND_OPEN, "Open a database at path."), (COMMAND_OPEN, "Open a database at path."),
(COMMAND_OPEN_EMPTY, "Open an empty database at path."),
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
(COMMAND_OPEN_ENCRYPTED, "Open an encrypted database at path using the provided key."), (COMMAND_OPEN_ENCRYPTED, "Open an encrypted database at path using the provided key."),
#[cfg(feature = "sqlcipher")]
(COMMAND_OPEN_EMPTY_ENCRYPTED, "Open an empty encrypted database at path using the provided key."),
(COMMAND_SCHEMA, "Output the schema for the current open database."), (COMMAND_SCHEMA, "Output the schema for the current open database."),
@ -306,24 +301,12 @@ impl Repl {
Err(e) => eprintln!("{}", e.to_string()), Err(e) => eprintln!("{}", e.to_string()),
}; };
}, },
Command::OpenEmpty(db) => {
match self.open_empty(db) {
Ok(_) => println!("Empty database {:?} opened", self.db_name()),
Err(e) => eprintln!("{}", e.to_string()),
};
},
Command::OpenEncrypted(db, encryption_key) => { Command::OpenEncrypted(db, encryption_key) => {
match self.open_with_key(db, &encryption_key) { match self.open_with_key(db, &encryption_key) {
Ok(_) => println!("Database {:?} opened with key {:?}", self.db_name(), encryption_key), Ok(_) => println!("Database {:?} opened with key {:?}", self.db_name(), encryption_key),
Err(e) => eprintln!("{}", e.to_string()), Err(e) => eprintln!("{}", e.to_string()),
} }
}, },
Command::OpenEmptyEncrypted(db, encryption_key) => {
match self.open_empty_with_key(db, &encryption_key) {
Ok(_) => println!("Empty database {:?} opened with key {:?}", self.db_name(), encryption_key),
Err(e) => eprintln!("{}", e.to_string()),
}
},
Command::Query(query) => { Command::Query(query) => {
self.store self.store
.q_once(query.as_str(), None) .q_once(query.as_str(), None)
@ -414,30 +397,20 @@ impl Repl {
fn open_common( fn open_common(
&mut self, &mut self,
empty: bool,
path: String, path: String,
encryption_key: Option<&str> encryption_key: Option<&str>
) -> ::mentat::errors::Result<()> { ) -> ::mentat::errors::Result<()> {
if self.path.is_empty() || path != self.path { if self.path.is_empty() || path != self.path {
let next = match encryption_key { let next = match encryption_key {
#[cfg(not(feature = "sqlcipher"))] #[cfg(not(feature = "sqlcipher"))]
Some(_) => return Err(::mentat::MentatError::RusqliteError(".open_encrypted and .empty_encrypted require the sqlcipher Mentat feature".into())), Some(_) => return Err(::mentat::MentatError::RusqliteError(".open_encrypted requires the sqlcipher Mentat feature".into())),
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
Some(k) => { Some(k) => {
if empty {
Store::open_empty_with_key(path.as_str(), k)?
} else {
Store::open_with_key(path.as_str(), k)? Store::open_with_key(path.as_str(), k)?
}
}, },
_ => { _ => {
if empty {
Store::open_empty(path.as_str())?
} else {
Store::open(path.as_str())? Store::open(path.as_str())?
} }
}
}; };
self.path = path; self.path = path;
self.store = next; self.store = next;
@ -447,22 +420,12 @@ impl Repl {
} }
fn open<T>(&mut self, path: T) -> ::mentat::errors::Result<()> where T: Into<String> { fn open<T>(&mut self, path: T) -> ::mentat::errors::Result<()> where T: Into<String> {
self.open_common(false, path.into(), None) self.open_common(path.into(), None)
}
fn open_empty<T>(&mut self, path: T)
-> ::mentat::errors::Result<()> where T: Into<String> {
self.open_common(true, path.into(), None)
} }
fn open_with_key<T, U>(&mut self, path: T, encryption_key: U) fn open_with_key<T, U>(&mut self, path: T, encryption_key: U)
-> ::mentat::errors::Result<()> where T: Into<String>, U: AsRef<str> { -> ::mentat::errors::Result<()> where T: Into<String>, U: AsRef<str> {
self.open_common(false, path.into(), Some(encryption_key.as_ref())) self.open_common(path.into(), Some(encryption_key.as_ref()))
}
fn open_empty_with_key<T, U>(&mut self, path: T, encryption_key: U)
-> ::mentat::errors::Result<()> where T: Into<String>, U: AsRef<str> {
self.open_common(true, path.into(), Some(encryption_key.as_ref()))
} }
// Close the current store by opening a new in-memory store in its place. // Close the current store by opening a new in-memory store in its place.