diff --git a/scryfall_deser/scripts/search_with_rofi.sh b/scryfall_deser/scripts/search_with_rofi.sh index bb2a7a3..f775cf6 100755 --- a/scryfall_deser/scripts/search_with_rofi.sh +++ b/scryfall_deser/scripts/search_with_rofi.sh @@ -2,7 +2,7 @@ CARDS=$(/home/arthurr/code/mini_projects/scryfall_deser/target/debug/scryfall_deser $@) -SELECTION=$(rofi -dmenu << EOF +SELECTION=$(rofi -dmenu -i << EOF $CARDS EOF ) diff --git a/scryfall_deser/src/db.rs b/scryfall_deser/src/db.rs index a08df34..db0cc54 100644 --- a/scryfall_deser/src/db.rs +++ b/scryfall_deser/src/db.rs @@ -152,6 +152,45 @@ pub fn get_card_by_name(name: &str, name_type: GetNameType) -> Option { } } +pub fn find_matching_cards_seperate_words(search_strings: &Vec) -> Vec { + assert!(!search_strings.is_empty()); + let sqlite_file = get_local_data_sqlite_file(); + let conn = rusqlite::Connection::open(sqlite_file).unwrap(); + let mut percentaged_string = Vec::new(); + // I know that .clone fixes my problem - I'm not sure why I need to though + for mut search_string in search_strings.clone() { + search_string.push('%'); + search_string.insert(0, '%'); + percentaged_string.push(search_string); + } + let mut sql: String = "SELECT name, lowercase_name, type_line, oracle_text, power_toughness, loyalty, mana_cost, scryfall_uri + FROM cards WHERE".into(); + for i in 0..search_strings.len() { + sql.push_str(&format!(" lowercase_name LIKE (?{}) AND", i + 1)); + } + sql.pop(); + sql.pop(); + sql.pop(); + sql.pop(); + dbg!(&sql); + let mut stmt = conn.prepare(&sql).unwrap(); + stmt.query_map(rusqlite::params_from_iter(percentaged_string), |row| { + Ok(DbCard { + name: row.get(0).unwrap(), + lowercase_name: row.get(1).unwrap(), + type_line: row.get(2).unwrap(), + oracle_text: row.get(3).unwrap(), + power_toughness: row.get(4).unwrap(), + loyalty: row.get(5).unwrap(), + mana_cost: row.get(6).unwrap(), + scryfall_uri: row.get(7).unwrap(), + }) + }) + .unwrap() + .filter_map(|res| res.ok()) + .collect() +} + pub fn find_matching_cards(name: &str) -> Vec { let sqlite_file = get_local_data_sqlite_file(); let conn = rusqlite::Connection::open(sqlite_file).unwrap(); diff --git a/scryfall_deser/src/lib.rs b/scryfall_deser/src/lib.rs index 80bc452..9f5c9da 100644 --- a/scryfall_deser/src/lib.rs +++ b/scryfall_deser/src/lib.rs @@ -6,8 +6,8 @@ pub use crate::deser::ScryfallCard; mod db; pub use db::{ - find_matching_cards, get_all_card_names, get_all_lowercase_card_names, get_card_by_name, - init_db, update_db_with_file, GetNameType, + find_matching_cards, find_matching_cards_seperate_words, get_all_card_names, + get_all_lowercase_card_names, get_card_by_name, init_db, update_db_with_file, GetNameType, }; mod utils; diff --git a/scryfall_deser/src/main.rs b/scryfall_deser/src/main.rs index 4e021c9..5b5d8b5 100644 --- a/scryfall_deser/src/main.rs +++ b/scryfall_deser/src/main.rs @@ -1,5 +1,6 @@ use clap::Parser; use scryfall_deser::find_matching_cards; +use scryfall_deser::find_matching_cards_seperate_words; use scryfall_deser::get_card_by_name; use scryfall_deser::get_local_cache_folder; use scryfall_deser::init_db; @@ -74,15 +75,18 @@ fn main() -> MtgCardExit { return res; } + // TODO consider scryfall-like search where I think they do something like: + // SELECT... WHERE name LIKE "" AND name LIKE ""... + /* let mut search_string = String::new(); for card in args.search_text { search_string.push_str(&card.to_lowercase()); search_string.push_str(" "); } search_string.pop(); - let matching_cards = find_matching_cards(&search_string); - //dbg!(&matching_cards); + */ + let matching_cards = find_matching_cards_seperate_words(&args.search_text); if matching_cards.is_empty() { // Do some distance checking stuff @@ -103,17 +107,4 @@ fn main() -> MtgCardExit { return MtgCardExit::Success; } unreachable!("Don't know how you got here - there's a real bug with this"); - - /* For testing - all seemed to work alright - let card = get_card_by_name("Black Lotus", GetNameType::Name); - dbg!(card); - let cards = get_all_card_names(); - for card in cards { - let card = get_card_by_name(&card); - dbg!(&card); - if card.is_none() { - panic!("None card for {:?}", card); - } - } - */ }