diff --git a/server/service/src/main.rs b/server/service/src/main.rs index 39ea3e5..22a5b2a 100644 --- a/server/service/src/main.rs +++ b/server/service/src/main.rs @@ -15,7 +15,7 @@ use actix_files::NamedFile; use actix_web::{middleware, web, App, HttpResponse, HttpServer}; use failure::Error; use r2d2_sqlite::SqliteConnectionManager; -use rusqlite::{params, named_params, NO_PARAMS}; +use rusqlite::{params, named_params, types::ToSqlOutput, Result}; use std::env; use std::ops::Deref; use std::cmp; @@ -25,42 +25,62 @@ use serde_json::Value; const DEFAULT_SIZE: usize = 25; -enum SortDir { - Asc, - Desc, -} - -enum Sort { - Key(String), - Dir(SortDir), -} - - - #[derive(Copy, Clone, Debug, Deserialize)] -enum SortKey { +enum Key { Name, Size, - Seeds, - Leeches, - Scraped, + Seeders, + Leechers, + Date, } -impl fmt::Display for SortKey { +impl Default for Key { + fn default() -> Self { + Self::Name + } +} + +impl fmt::Display for Key { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) + let s = match &self { + Self::Name => "name", + Self::Size => "size_bytes", + Self::Seeders => "seeders", + Self::Leechers => "leechers", + Self::Date => "scraped_date", + }; + write!(f, "{}", s) } } #[derive(Copy, Clone, Debug, Deserialize)] -enum SortDir { +enum Direction { Asc, Desc, } -impl fmt::Display for SortDir { +impl Default for Direction { + fn default() -> Self { + Self::Desc + } +} + +impl fmt::Display for Direction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) + let s = match &self { + Self::Asc => "asc", + Self::Desc => "desc", + }; + write!(f, "{}", s) + } +} +#[derive(Copy, Clone, Debug, Default, Deserialize)] +struct Sort(Key, Direction); + +impl fmt::Display for Sort { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let s = format!("{} {}", self.0, self.1); + write!(f, "{}", s) } } @@ -109,8 +129,8 @@ struct SearchQuery { q: String, page: Option, size: Option, - sort_key: Option, - sort_dir: Option, + sort_key: Option, + sort_dir: Option, type_: Option, } @@ -136,8 +156,7 @@ async fn search( struct NewQuery { page: Option, size: Option, - sort_key: Option, - sort_dir: Option, + sort: Option, type_: Option, } @@ -170,22 +189,23 @@ fn search_query( } let page = query.page.unwrap_or(1); - let sort_key = query.sort_key.unwrap_or(SortKey::Name); - let sort_dir = query.sort_dir.unwrap_or(SortDir::Desc); + let key = query.sort_key.unwrap_or_default(); + let direction = query.sort_dir.unwrap_or_default(); + let sort = Sort(key, direction); let size = cmp::min(100, query.size.unwrap_or(DEFAULT_SIZE)); let type_ = query.type_.as_ref().map_or("torrent", String::deref); let offset = size * (page - 1); dbg!( - "query = {}, type = {}, page = {}, size = {}, sort_key = {:?}, sort_dir = {:?}", - q, type_, page, size, sort_key, sort_dir + "query = {}, type = {}, page = {}, size = {}, sort = {:?}", + q, type_, page, size, sort ); let res = if type_ == "file" { let results = torrent_file_search(conn, q, size, offset)?; serde_json::to_value(&results).unwrap() } else { - let results = torrent_search(conn, q, sort_key, sort_dir, size, offset)?; + let results = torrent_search(conn, q, sort, size, offset)?; serde_json::to_value(&results).unwrap() }; @@ -199,14 +219,13 @@ fn new_query( let page = query.page.unwrap_or(1); let size = cmp::min(100, query.size.unwrap_or(DEFAULT_SIZE)); - let sort_key = query.sort_key.as_ref().unwrap_or(&SortKey::Name); - let sort_dir = query.sort_dir.as_ref().unwrap_or(&SortDir::Desc); + let sort = query.sort.unwrap_or_default(); let type_ = query.type_.as_ref().map_or("torrent", String::deref); let offset = size * (page - 1); dbg!( - "new, type = {}, page = {}, size = {}, sort_key = {:?}, sort_dir = {:?}", - type_, page, size, sort_key, sort_dir + "new, type = {}, page = {}, size = {}, sort = {:?}", + type_, page, size, sort ); let res = if type_ == "file" { @@ -235,20 +254,19 @@ struct Torrent { fn torrent_search( conn: r2d2::PooledConnection, query: &str, - sort_key: SortKey, - sort_dir: SortDir, + sort: Sort, size: usize, offset: usize, ) -> Result, Error> { - let stmt_str = format!("select * from torrents where name like '%' || :query || '%' order by :sort_key {} limit :offset, :size", sort_dir.to_string().to_lowercase()); + let stmt_str = format!("select * from torrents where name like '%' || :query || '%' order by {} limit :offset, :size", sort); let mut stmt = conn.prepare(&stmt_str)?; - let torrent_iter = stmt.query_map_named( - named_params!{ - ":query": query.replace(" ", "%"), - ":sort_key": sort_key.to_string().to_lowercase(), - ":offset": offset.to_string(), - ":size": size.to_string(), - }, + + let torrent_iter = stmt.query_map(params![ + query.replace(" ", "%"), + offset.to_string(), + size.to_string(), + ], + |row| { let size: isize = row.get(2)?; println!("got size {:?}", size); diff --git a/server/ui/src/components/search.tsx b/server/ui/src/components/search.tsx index a7406b9..60e804b 100644 --- a/server/ui/src/components/search.tsx +++ b/server/ui/src/components/search.tsx @@ -19,7 +19,7 @@ function buildSearchURL(sort_key, {state: { searchParams }) { if (sort_key === searchParams.sort_key) { - const sort_dir = searchParams.sort_dir === "Asc" ? "Desc" : "Asc"; + const sort_dir = searchParams.sort_dir === "asc" ? "desc" : "asc"; searchParams.sort_dir = sort_dir; console.log("no change in sort key from", sort_key, "so switch direction instead.") } else {