Skip to content

Commit

Permalink
Allow import and use common insert method
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanfrishkorn committed Sep 5, 2023
1 parent 821f446 commit 4764e35
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 17 deletions.
38 changes: 37 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,14 @@ fn main() -> Result<(), Box<dyn Error>> {
.arg_required_else_help(false)
.arg(Arg::new("words")),
)
.subcommand(
Command::new("import").arg_required_else_help(true).arg(
Arg::new("files")
.help("import document files")
.required(true)
.action(ArgAction::Append),
),
)
.subcommand(
Command::new("update")
.about("Update document from modified file")
Expand Down Expand Up @@ -327,7 +335,7 @@ fn main() -> Result<(), Box<dyn Error>> {
attachments: Vec::new(),
};

snip::insert_snip(&conn, &s)?;
s.insert(&conn)?;
s.index(&conn)?;
if sub_matches.get_flag("verbose") {
print!("{}", s.text);
Expand Down Expand Up @@ -784,6 +792,34 @@ fn main() -> Result<(), Box<dyn Error>> {
println!("{:?}", stems);
}

// IMPORT
if let Some(("import", sub_matches)) = matches.subcommand() {
if let Some(files) = sub_matches.get_many::<String>("files") {
let mut errors = false;
// Note: attachments are ignored and not imported
for file in files.into_iter() {
print!("importing {:?}...", file);

let mut s = snip::from_file(file)?;
if snip::get_from_uuid(&conn, &s.uuid).is_ok() {
println!("refusing duplicate insert {}", s.uuid);
errors = true;
// proceed but notify of errors after iterations
continue;
}

// check for existing id to avoid duplicates
s.insert(&conn)?;
// always index after import
s.index(&conn)?;
println!("success");
}
if errors {
eprintln!("WARNING: Some documents were not imported.");
}
}
}

// UPDATE
if let Some(("update", sub_matches)) = matches.subcommand() {
if let Some(file) = sub_matches.get_one::<String>("file") {
Expand Down
55 changes: 39 additions & 16 deletions src/snip/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,20 @@ impl Snip {
Ok(())
}

/// Inserts a new document to the database
pub fn insert(&self, conn: &Connection) -> Result<(), Box<dyn Error>> {
let mut stmt =
conn.prepare("INSERT INTO snip(uuid, timestamp, name, data) VALUES (?1, ?2, ?3, ?4)")?;
stmt.execute([
self.uuid.to_string(),
self.timestamp.to_rfc3339(),
self.name.clone(),
self.text.clone(),
])?;

Ok(())
}

/// Writes all fields to the database, overwriting existing data
pub fn update(&self, conn: &Connection) -> Result<(), Box<dyn Error>> {
let mut stmt = conn.prepare("UPDATE snip SET (data, timestamp, name) = (:data, :timestamp, :name) WHERE uuid = :uuid")?;
Expand Down Expand Up @@ -475,20 +489,6 @@ pub fn index_all_items(conn: &Connection) -> Result<(), Box<dyn Error>> {
Ok(())
}

/// Adds a new document to the database
pub fn insert_snip(conn: &Connection, s: &Snip) -> Result<(), Box<dyn Error>> {
let mut stmt =
conn.prepare("INSERT INTO snip(uuid, timestamp, name, data) VALUES (?1, ?2, ?3, ?4)")?;
stmt.execute([
s.uuid.to_string(),
s.timestamp.to_rfc3339(),
s.name.clone(),
s.text.clone(),
])?;

Ok(())
}

fn parse_text(data: &str) -> Result<String, Box<dyn Error>> {
let lines: Vec<&str> = data.split('\n').collect();

Expand Down Expand Up @@ -803,7 +803,7 @@ mod tests {
}

#[test]
fn test_insert_snip() -> Result<(), Box<dyn Error>> {
fn test_insert_new() -> Result<(), Box<dyn Error>> {
let conn = prepare_database().expect("preparing in-memory database");
let id = Uuid::new_v4();

Expand All @@ -815,7 +815,7 @@ mod tests {
analysis: SnipAnalysis { words: Vec::new() },
attachments: Vec::new(),
};
insert_snip(&conn, &s)?;
s.insert(&conn)?;

// verify
let mut stmt = conn.prepare("SELECT uuid FROM snip WHERE uuid = ?")?;
Expand Down Expand Up @@ -878,6 +878,29 @@ mod tests {
Ok(())
}

#[test]
fn test_insert() -> Result<(), Box<dyn Error>> {
let conn = prepare_database()?;
let id = Uuid::try_parse(ID_STR)?;

let s = snip::get_from_uuid(&conn, &id)?;
// first remove from database
remove_snip(&conn, id)?;

// verify removal
if snip::get_from_uuid(&conn, &id).is_ok() {
panic!("expected missing document, got document with id {}", id);
}

// insert and verify presence
s.insert(&conn)?;
if snip::get_from_uuid(&conn, &id).is_err() {
panic!("expected document, got Err searching for id {}", id);
}

Ok(())
}

#[test]
fn test_update() -> Result<(), Box<dyn Error>> {
let conn = prepare_database()?;
Expand Down

0 comments on commit 4764e35

Please sign in to comment.