Added untagging subcommand
parent
41a47b42a5
commit
a7c0480a58
|
@ -12,6 +12,7 @@ pub struct CliArgs {
|
|||
#[derive(Debug, Subcommand, PartialEq, Eq)]
|
||||
pub enum Commands {
|
||||
Init,
|
||||
Untag(UntagArgs),
|
||||
Tag(TagArgs),
|
||||
Tags(TagsArgs),
|
||||
Files(FilesArgs),
|
||||
|
@ -40,6 +41,13 @@ pub struct TagArgs {
|
|||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args, PartialEq, Eq)]
|
||||
pub struct UntagArgs {
|
||||
pub file: PathBuf,
|
||||
|
||||
pub tags: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args, PartialEq, Eq)]
|
||||
pub struct FilesArgs {
|
||||
pub query: Option<String>,
|
||||
|
|
|
@ -14,6 +14,7 @@ fn main() -> anyhow::Result<()> {
|
|||
match args.commands {
|
||||
cli::Commands::Init => init_db().map_err(|_| anyhow!("Database already exists!")),
|
||||
cli::Commands::Tag(args) => tags::handle_tag(args),
|
||||
cli::Commands::Untag(args) => tags::handle_untag(args),
|
||||
cli::Commands::Tags(args) => tags::handle_tags(args),
|
||||
cli::Commands::Files(args) => tags::handle_files(args),
|
||||
}
|
||||
|
|
53
src/tags.rs
53
src/tags.rs
|
@ -6,10 +6,10 @@ use std::{
|
|||
|
||||
use anyhow::{Result, anyhow};
|
||||
|
||||
use rusqlite::{Connection, params_from_iter};
|
||||
use rusqlite::{Connection, params, params_from_iter};
|
||||
|
||||
use crate::{
|
||||
cli::{self, FilesArgs, TagArgs, TagsArgs},
|
||||
cli::{self, FilesArgs, TagArgs, TagsArgs, UntagArgs},
|
||||
try_database,
|
||||
};
|
||||
|
||||
|
@ -69,6 +69,14 @@ pub fn handle_tag(args: TagArgs) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_untag(args: UntagArgs) -> Result<()> {
|
||||
let mut conn = try_database()?;
|
||||
|
||||
untag_file(&mut conn, args.file, args.tags)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_tags(args: TagsArgs) -> Result<()> {
|
||||
let mut conn = try_database()?;
|
||||
|
||||
|
@ -224,3 +232,44 @@ fn tag_file(conn: &mut Connection, file: PathBuf, tags: Vec<String>) -> Result<(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn untag_file(conn: &mut Connection, file: PathBuf, tags: Option<Vec<String>>) -> Result<()> {
|
||||
let file = file
|
||||
.to_str()
|
||||
.ok_or(anyhow!("Unable to find path {:?}", file))?
|
||||
.to_string();
|
||||
|
||||
let tx = conn.transaction()?;
|
||||
{
|
||||
let _file_id: i32 = tx
|
||||
.query_row(r#"SELECT id FROM file WHERE path = ?"#, [&file], |row| {
|
||||
row.get(0)
|
||||
})
|
||||
.map_err(|_| anyhow!("No {} file registered!", file))?;
|
||||
|
||||
let mut sql = r#"
|
||||
DELETE FROM file_tag
|
||||
WHERE ROWID IN (
|
||||
SELECT file_tag.ROWID FROM file_tag
|
||||
INNER JOIN file ON file_tag.file_id = file.id
|
||||
INNER JOIN tag ON file_tag.tag_id = tag.id"#
|
||||
.to_string();
|
||||
|
||||
match tags {
|
||||
Some(tags) => {
|
||||
let tags = tags.join(",");
|
||||
sql.push_str(" WHERE file.path = ?1 AND tag.name IN (?2))");
|
||||
let mut stmt = tx.prepare(&sql)?;
|
||||
stmt.execute(params![file, tags])?;
|
||||
}
|
||||
None => {
|
||||
sql.push_str(" WHERE file.path = ?1)");
|
||||
let mut stmt = tx.prepare(&sql)?;
|
||||
stmt.execute(params![file])?;
|
||||
}
|
||||
};
|
||||
}
|
||||
tx.commit()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue