mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-11-25 12:06:11 -05:00
switch from docopt to structopt
A couple reasons for this: * the docopt crate is "unlikely to see significant future evolution", and the wider docopt project is "mostly unmaintained at this point". clap/structopt is more full-featured, has more natural subcommand support, etc. * it may allow me to shrink the binary (#70). This change alone seems to be a slight regression, but it's a step toward getting rid of regex, which is pretty large. And I feel less ridiculous now that I don't have two parsing crates anyway; prettydiff was pulling in structopt. There are some behavior changes here: * misc --help output changes and such as you'd expect from switching argument-parsing libraries * I properly used PathBuf and OsString for stuff that theoretically could be non-UTF-8. I haven't tested that it actually made any difference. I'm also still storing the sample file dirname as "text" in the database to avoid causing a diff when not doing a schema change.
This commit is contained in:
@@ -52,9 +52,9 @@ const UPGRADE_NOTES: &'static str =
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Args<'a> {
|
||||
pub flag_sample_file_dir: Option<&'a str>,
|
||||
pub flag_preset_journal: &'a str,
|
||||
pub flag_no_vacuum: bool,
|
||||
pub sample_file_dir: Option<&'a std::path::Path>,
|
||||
pub preset_journal: &'a str,
|
||||
pub no_vacuum: bool,
|
||||
}
|
||||
|
||||
fn set_journal_mode(conn: &rusqlite::Connection, requested: &str) -> Result<(), Error> {
|
||||
@@ -86,7 +86,7 @@ fn upgrade(args: &Args, target_ver: i32, conn: &mut rusqlite::Connection) -> Res
|
||||
bail!("Database is at negative version {}!", old_ver);
|
||||
}
|
||||
info!("Upgrading database from version {} to version {}...", old_ver, target_ver);
|
||||
set_journal_mode(&conn, args.flag_preset_journal)?;
|
||||
set_journal_mode(&conn, args.preset_journal)?;
|
||||
for ver in old_ver .. target_ver {
|
||||
info!("...from version {} to version {}", ver, ver + 1);
|
||||
let tx = conn.transaction()?;
|
||||
@@ -118,7 +118,7 @@ pub fn run(args: &Args, conn: &mut rusqlite::Connection) -> Result<(), Error> {
|
||||
// WAL is the preferred journal mode for normal operation; it reduces the number of syncs
|
||||
// without compromising safety.
|
||||
set_journal_mode(&conn, "wal")?;
|
||||
if !args.flag_no_vacuum {
|
||||
if !args.no_vacuum {
|
||||
info!("...vacuuming database after upgrade.");
|
||||
conn.execute_batch(r#"
|
||||
pragma page_size = 16384;
|
||||
@@ -157,7 +157,7 @@ impl NixPath for UuidPath {
|
||||
mod tests {
|
||||
use crate::compare;
|
||||
use crate::testutil;
|
||||
use failure::{ResultExt, format_err};
|
||||
use failure::ResultExt;
|
||||
use super::*;
|
||||
|
||||
fn new_conn() -> Result<rusqlite::Connection, Error> {
|
||||
@@ -183,7 +183,7 @@ mod tests {
|
||||
fn upgrade_and_compare() -> Result<(), Error> {
|
||||
testutil::init();
|
||||
let tmpdir = tempdir::TempDir::new("moonfire-nvr-test")?;
|
||||
let path = tmpdir.path().to_str().ok_or_else(|| format_err!("invalid UTF-8"))?.to_owned();
|
||||
//let path = tmpdir.path().to_str().ok_or_else(|| format_err!("invalid UTF-8"))?.to_owned();
|
||||
let mut upgraded = new_conn()?;
|
||||
upgraded.execute_batch(include_str!("v0.sql"))?;
|
||||
upgraded.execute_batch(r#"
|
||||
@@ -218,9 +218,9 @@ mod tests {
|
||||
(4, None), // transitional; don't compare schemas.
|
||||
(5, Some(include_str!("../schema.sql")))] {
|
||||
upgrade(&Args {
|
||||
flag_sample_file_dir: Some(&path),
|
||||
flag_preset_journal: "delete",
|
||||
flag_no_vacuum: false,
|
||||
sample_file_dir: Some(&tmpdir.path()),
|
||||
preset_journal: "delete",
|
||||
no_vacuum: false,
|
||||
}, *ver, &mut upgraded).context(format!("upgrading to version {}", ver))?;
|
||||
if let Some(f) = fresh_sql {
|
||||
compare(&upgraded, *ver, f)?;
|
||||
|
||||
@@ -42,7 +42,7 @@ use uuid::Uuid;
|
||||
|
||||
pub fn run(args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error> {
|
||||
let sample_file_path =
|
||||
args.flag_sample_file_dir
|
||||
args.sample_file_dir
|
||||
.ok_or_else(|| format_err!("--sample-file-dir required when upgrading from \
|
||||
schema version 1 to 2."))?;
|
||||
|
||||
@@ -122,6 +122,9 @@ pub fn run(args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error>
|
||||
}
|
||||
dir::write_meta(d.as_raw_fd(), &meta)?;
|
||||
|
||||
let sample_file_path = sample_file_path.to_str()
|
||||
.ok_or_else(|| format_err!("sample file dir {} is not a valid string",
|
||||
sample_file_path.display()))?;
|
||||
tx.execute(r#"
|
||||
insert into sample_file_dir (path, uuid, last_complete_open_id)
|
||||
values (?, ?, ?)
|
||||
@@ -293,7 +296,7 @@ pub fn run(args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error>
|
||||
/// * optional: reserved sample file uuids.
|
||||
/// * optional: meta and meta-tmp from half-completed update attempts.
|
||||
/// * forbidden: anything else.
|
||||
fn verify_dir_contents(sample_file_path: &str, dir: &mut nix::dir::Dir,
|
||||
fn verify_dir_contents(sample_file_path: &std::path::Path, dir: &mut nix::dir::Dir,
|
||||
tx: &rusqlite::Transaction) -> Result<(), Error> {
|
||||
// Build a hash of the uuids found in the directory.
|
||||
let n: i64 = tx.query_row(r#"
|
||||
@@ -337,7 +340,7 @@ fn verify_dir_contents(sample_file_path: &str, dir: &mut nix::dir::Dir,
|
||||
while let Some(row) = rows.next()? {
|
||||
let uuid: crate::db::FromSqlUuid = row.get(0)?;
|
||||
if !files.remove(&uuid.0) {
|
||||
bail!("{} is missing from dir {}!", uuid.0, sample_file_path);
|
||||
bail!("{} is missing from dir {}!", uuid.0, sample_file_path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,7 +363,7 @@ fn verify_dir_contents(sample_file_path: &str, dir: &mut nix::dir::Dir,
|
||||
|
||||
if !files.is_empty() {
|
||||
bail!("{} unexpected sample file uuids in dir {}: {:?}!",
|
||||
files.len(), sample_file_path, files);
|
||||
files.len(), sample_file_path.display(), files);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user