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:
parent
8ddbd18f5f
commit
0b84a0802d
3 changed files with 9 additions and 123 deletions
41
src/store.rs
41
src/store.rs
|
@ -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> {
|
||||
let mut ip = self.begin_transaction()?;
|
||||
let report = ip.transact(transaction)?;
|
||||
|
@ -127,28 +111,9 @@ impl Store {
|
|||
})
|
||||
}
|
||||
|
||||
/// Variant of `open_empty` that allows a key (for encryption/decryption) to
|
||||
/// be supplied. Fails unless linked against sqlcipher (or something else
|
||||
/// that supports the Sqlite 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).
|
||||
/// Change the key for a database that was opened using `open_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<()> {
|
||||
::change_encryption_key(&self.sqlite, new_encryption_key)?;
|
||||
Ok(())
|
||||
|
|
|
@ -51,9 +51,7 @@ pub static COMMAND_HELP: &'static str = &"help";
|
|||
pub static COMMAND_IMPORT_LONG: &'static str = &"import";
|
||||
pub static COMMAND_IMPORT_SHORT: &'static str = &"i";
|
||||
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_EMPTY_ENCRYPTED: &'static str = &"empty_encrypted";
|
||||
pub static COMMAND_QUERY_LONG: &'static str = &"query";
|
||||
pub static COMMAND_QUERY_SHORT: &'static str = &"q";
|
||||
pub static COMMAND_QUERY_EXPLAIN_LONG: &'static str = &"explain_query";
|
||||
|
@ -73,9 +71,7 @@ pub enum Command {
|
|||
Help(Vec<String>),
|
||||
Import(String),
|
||||
Open(String),
|
||||
OpenEmpty(String),
|
||||
OpenEncrypted(String, String),
|
||||
OpenEmptyEncrypted(String, String),
|
||||
Query(String),
|
||||
QueryExplain(String),
|
||||
QueryPrepared(String),
|
||||
|
@ -105,9 +101,7 @@ impl Command {
|
|||
&Command::Help(_) |
|
||||
&Command::Import(_) |
|
||||
&Command::Open(_) |
|
||||
&Command::OpenEmpty(_) |
|
||||
&Command::OpenEncrypted(_, _) |
|
||||
&Command::OpenEmptyEncrypted(_, _) |
|
||||
&Command::Timer(_) |
|
||||
&Command::Schema |
|
||||
&Command::Sync(_)
|
||||
|
@ -128,9 +122,7 @@ impl Command {
|
|||
&Command::Exit |
|
||||
&Command::Help(_) |
|
||||
&Command::Open(_) |
|
||||
&Command::OpenEmpty(_) |
|
||||
&Command::OpenEncrypted(_, _) |
|
||||
&Command::OpenEmptyEncrypted(_, _) |
|
||||
&Command::QueryExplain(_) |
|
||||
&Command::Timer(_) |
|
||||
&Command::Schema |
|
||||
|
@ -159,15 +151,9 @@ impl Command {
|
|||
&Command::Open(ref args) => {
|
||||
format!(".{} {}", COMMAND_OPEN, args)
|
||||
},
|
||||
&Command::OpenEmpty(ref args) => {
|
||||
format!(".{} {}", COMMAND_OPEN_EMPTY, args)
|
||||
},
|
||||
&Command::OpenEncrypted(ref db, ref key) => {
|
||||
format!(".{} {} {}", COMMAND_OPEN_ENCRYPTED, db, key)
|
||||
},
|
||||
&Command::OpenEmptyEncrypted(ref db, ref key) => {
|
||||
format!(".{} {} {}", COMMAND_OPEN_EMPTY_ENCRYPTED, db, key)
|
||||
},
|
||||
&Command::Query(ref 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|
|
||||
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|
|
||||
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)))
|
||||
.with(edn_arg_parser())
|
||||
.map(|x| {
|
||||
|
@ -340,15 +320,13 @@ pub fn command(s: &str) -> Result<Command, Error> {
|
|||
|
||||
spaces()
|
||||
.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(import_parser),
|
||||
&mut try(timer_parser),
|
||||
&mut try(cache_parser),
|
||||
&mut try(open_encrypted_parser),
|
||||
&mut try(open_empty_encrypted_parser),
|
||||
&mut try(open_parser),
|
||||
&mut try(open_empty_parser),
|
||||
&mut try(close_parser),
|
||||
&mut try(explain_query_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]
|
||||
fn test_open_encrypted_parser_missing_key() {
|
||||
let input = ".open_encrypted path/to/db.db";
|
||||
|
@ -479,13 +444,6 @@ mod tests {
|
|||
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]
|
||||
fn test_sync_parser_path_arg() {
|
||||
let input = ".sync https://example.com/api/ 316ea470-ce35-4adf-9c61-e0de6e289c59";
|
||||
|
|
|
@ -63,7 +63,6 @@ use command_parser::{
|
|||
COMMAND_HELP,
|
||||
COMMAND_IMPORT_LONG,
|
||||
COMMAND_OPEN,
|
||||
COMMAND_OPEN_EMPTY,
|
||||
COMMAND_QUERY_LONG,
|
||||
COMMAND_QUERY_SHORT,
|
||||
COMMAND_QUERY_EXPLAIN_LONG,
|
||||
|
@ -81,7 +80,6 @@ use command_parser::{
|
|||
// omit them from help message (since they wouldn't work).
|
||||
#[cfg(feature = "sqlcipher")]
|
||||
use command_parser::{
|
||||
COMMAND_OPEN_EMPTY_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_OPEN, "Open a database at path."),
|
||||
(COMMAND_OPEN_EMPTY, "Open an empty database at path."),
|
||||
|
||||
#[cfg(feature = "sqlcipher")]
|
||||
(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."),
|
||||
|
||||
|
@ -306,24 +301,12 @@ impl Repl {
|
|||
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) => {
|
||||
match self.open_with_key(db, &encryption_key) {
|
||||
Ok(_) => println!("Database {:?} opened with key {:?}", self.db_name(), encryption_key),
|
||||
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) => {
|
||||
self.store
|
||||
.q_once(query.as_str(), None)
|
||||
|
@ -414,30 +397,20 @@ impl Repl {
|
|||
|
||||
fn open_common(
|
||||
&mut self,
|
||||
empty: bool,
|
||||
path: String,
|
||||
encryption_key: Option<&str>
|
||||
) -> ::mentat::errors::Result<()> {
|
||||
if self.path.is_empty() || path != self.path {
|
||||
let next = match encryption_key {
|
||||
#[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")]
|
||||
Some(k) => {
|
||||
if empty {
|
||||
Store::open_empty_with_key(path.as_str(), k)?
|
||||
} else {
|
||||
Store::open_with_key(path.as_str(), k)?
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
if empty {
|
||||
Store::open_empty(path.as_str())?
|
||||
} else {
|
||||
Store::open(path.as_str())?
|
||||
}
|
||||
}
|
||||
};
|
||||
self.path = path;
|
||||
self.store = next;
|
||||
|
@ -447,22 +420,12 @@ impl Repl {
|
|||
}
|
||||
|
||||
fn open<T>(&mut self, path: T) -> ::mentat::errors::Result<()> where T: Into<String> {
|
||||
self.open_common(false, 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)
|
||||
self.open_common(path.into(), None)
|
||||
}
|
||||
|
||||
fn open_with_key<T, U>(&mut self, path: T, encryption_key: U)
|
||||
-> ::mentat::errors::Result<()> where T: Into<String>, U: AsRef<str> {
|
||||
self.open_common(false, 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()))
|
||||
self.open_common(path.into(), Some(encryption_key.as_ref()))
|
||||
}
|
||||
|
||||
// Close the current store by opening a new in-memory store in its place.
|
||||
|
|
Loading…
Reference in a new issue