From fcd629259800513c67390b765c7be26d5bf3130e Mon Sep 17 00:00:00 2001 From: Wynd Date: Sat, 3 May 2025 17:33:17 +0300 Subject: [PATCH] Fixed an insertion bug and made it so the files subcommand can filter per file --- src/cli.rs | 2 +- src/main.rs | 4 +-- src/tags.rs | 73 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 6eeb9f9..8ddf06b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use clap::{Args, Parser, Subcommand}; +use clap::{Args, Parser, Subcommand, ValueEnum}; #[derive(Debug, Parser, PartialEq, Eq)] #[command(version, about, author, long_about = None, args_override_self = true)] diff --git a/src/main.rs b/src/main.rs index 18695f9..471383a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,8 +49,8 @@ fn init_db(conn: &Connection) { conn.execute( r#"CREATE TABLE IF NOT EXISTS file_tag( - tag_id INT REFERENCES tag(id), - file_id INT REFERENCES file(id) + file_id INT REFERENCES file(id), + tag_id INT REFERENCES tag(id) );"#, (), ) diff --git a/src/tags.rs b/src/tags.rs index 3ab62fe..397f521 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -12,6 +12,42 @@ use crate::{ try_database, }; +pub fn handle_files(args: FilesArgs) { + try_database(); + + let conn = Connection::open(DB_PATH).unwrap(); + let mut sql = r#"SELECT path, group_concat(name) as tags FROM file_tag + JOIN file ON file.id = file_tag.file_id + JOIN tag ON tag.id = file_tag.tag_id"# + .to_string(); + + if let Some(query) = args.query { + let path = PathBuf::from_str(&query).unwrap_or_default(); + match path.exists() { + true => { + sql.push_str(&format!(" WHERE path IN ('{}')", query)); + } + false => todo!(), + }; + } + + sql.push_str(" GROUP BY path"); + + let mut stmt = conn.prepare(&sql).unwrap(); + let result = stmt + .query_map([], |row| -> Result<(String, String), rusqlite::Error> { + Ok((row.get(0).unwrap(), row.get(1).unwrap())) + }) + .unwrap() + .flatten(); + + let mut w = io::stdout(); + for (file, tags) in result { + writeln!(&mut w, "{}: {}", file, tags).unwrap(); + } + w.flush().unwrap(); +} + pub fn handle_tag(args: TagArgs) { try_database(); @@ -84,12 +120,22 @@ fn tag_file(conn: &mut Connection, file: PathBuf, tags: Vec) { let tx = conn.transaction().unwrap(); { - let mut stmt = tx - .prepare(r#"INSERT INTO file(path) VALUES (?) RETURNING id"#) - .unwrap(); - let file_id = stmt - .query_row([file], |row| -> Result { row.get(0) }) - .unwrap(); + let file_id: Option = tx + .query_row(r#"SELECT id FROM file WHERE path = ?"#, [&file], |row| { + row.get(0) + }) + .ok(); + + let file_id = match file_id { + Some(id) => id, + None => { + let mut stmt = tx + .prepare(r#"INSERT INTO file(path) VALUES (?) RETURNING id"#) + .unwrap(); + stmt.query_row([file], |row| -> Result { row.get(0) }) + .unwrap() + } + }; let mut sql = "SELECT id FROM tag WHERE name IN ".to_string(); sql.push('('); @@ -116,7 +162,7 @@ fn tag_file(conn: &mut Connection, file: PathBuf, tags: Vec) { } let mut stmt = tx - .prepare(r#"INSERT INTO file_tag(tag_id, file_id) VALUES (?, ?)"#) + .prepare(r#"INSERT INTO file_tag(file_id, tag_id) VALUES (?, ?)"#) .unwrap(); for tag_id in tags_ids { @@ -125,16 +171,3 @@ fn tag_file(conn: &mut Connection, file: PathBuf, tags: Vec) { } tx.commit().unwrap(); } - -pub fn handle_files(args: FilesArgs) { - if let Some(query) = args.query { - // match PathBuf::from_str(&query) { - // Ok(path) => { - // dbg!(path); - // } - // Err(_) => { - // dbg!("a query"); - // } - // } - } -}