Fixed an insertion bug and made it so the files subcommand can filter per file

master
Wynd 2025-05-03 17:33:17 +03:00
parent 45eb3fcbbd
commit fcd6292598
3 changed files with 56 additions and 23 deletions

View File

@ -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)]

View File

@ -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)
);"#,
(),
)

View File

@ -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<String>) {
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<i32, rusqlite::Error> { row.get(0) })
.unwrap();
let file_id: Option<i32> = 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<i32, rusqlite::Error> { 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<String>) {
}
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<String>) {
}
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");
// }
// }
}
}