WIP: improve search #1

Closed
rob wants to merge 26 commits from improve-search into master
2 changed files with 64 additions and 46 deletions
Showing only changes of commit 276b66ed12 - Show all commits

View File

@ -15,7 +15,7 @@ use actix_files::NamedFile;
use actix_web::{middleware, web, App, HttpResponse, HttpServer}; use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use failure::Error; use failure::Error;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use rusqlite::{params, named_params, NO_PARAMS}; use rusqlite::{params, named_params, types::ToSqlOutput, Result};
use std::env; use std::env;
use std::ops::Deref; use std::ops::Deref;
use std::cmp; use std::cmp;
@ -25,42 +25,62 @@ use serde_json::Value;
const DEFAULT_SIZE: usize = 25; const DEFAULT_SIZE: usize = 25;
enum SortDir {
Asc,
Desc,
}
enum Sort {
Key(String),
Dir(SortDir),
}
#[derive(Copy, Clone, Debug, Deserialize)] #[derive(Copy, Clone, Debug, Deserialize)]
enum SortKey { enum Key {
Name, Name,
Size, Size,
Seeds, Seeders,
Leeches, Leechers,
Scraped, 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 { 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)] #[derive(Copy, Clone, Debug, Deserialize)]
enum SortDir { enum Direction {
Asc, Asc,
Desc, 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 { 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, q: String,
page: Option<usize>, page: Option<usize>,
size: Option<usize>, size: Option<usize>,
sort_key: Option<SortKey>, sort_key: Option<Key>,
sort_dir: Option<SortDir>, sort_dir: Option<Direction>,
type_: Option<String>, type_: Option<String>,
} }
@ -136,8 +156,7 @@ async fn search(
struct NewQuery { struct NewQuery {
page: Option<usize>, page: Option<usize>,
size: Option<usize>, size: Option<usize>,
sort_key: Option<SortKey>, sort: Option<Sort>,
sort_dir: Option<SortDir>,
type_: Option<String>, type_: Option<String>,
} }
@ -170,22 +189,23 @@ fn search_query(
} }
let page = query.page.unwrap_or(1); let page = query.page.unwrap_or(1);
let sort_key = query.sort_key.unwrap_or(SortKey::Name); let key = query.sort_key.unwrap_or_default();
let sort_dir = query.sort_dir.unwrap_or(SortDir::Desc); 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 size = cmp::min(100, query.size.unwrap_or(DEFAULT_SIZE));
let type_ = query.type_.as_ref().map_or("torrent", String::deref); let type_ = query.type_.as_ref().map_or("torrent", String::deref);
let offset = size * (page - 1); let offset = size * (page - 1);
dbg!( dbg!(
"query = {}, type = {}, page = {}, size = {}, sort_key = {:?}, sort_dir = {:?}", "query = {}, type = {}, page = {}, size = {}, sort = {:?}",
q, type_, page, size, sort_key, sort_dir q, type_, page, size, sort
); );
let res = if type_ == "file" { let res = if type_ == "file" {
let results = torrent_file_search(conn, q, size, offset)?; let results = torrent_file_search(conn, q, size, offset)?;
serde_json::to_value(&results).unwrap() serde_json::to_value(&results).unwrap()
} else { } 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() serde_json::to_value(&results).unwrap()
}; };
@ -199,14 +219,13 @@ fn new_query(
let page = query.page.unwrap_or(1); let page = query.page.unwrap_or(1);
let size = cmp::min(100, query.size.unwrap_or(DEFAULT_SIZE)); 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 = query.sort.unwrap_or_default();
let sort_dir = query.sort_dir.as_ref().unwrap_or(&SortDir::Desc);
let type_ = query.type_.as_ref().map_or("torrent", String::deref); let type_ = query.type_.as_ref().map_or("torrent", String::deref);
let offset = size * (page - 1); let offset = size * (page - 1);
dbg!( dbg!(
"new, type = {}, page = {}, size = {}, sort_key = {:?}, sort_dir = {:?}", "new, type = {}, page = {}, size = {}, sort = {:?}",
type_, page, size, sort_key, sort_dir type_, page, size, sort
); );
let res = if type_ == "file" { let res = if type_ == "file" {
@ -235,20 +254,19 @@ struct Torrent {
fn torrent_search( fn torrent_search(
conn: r2d2::PooledConnection<SqliteConnectionManager>, conn: r2d2::PooledConnection<SqliteConnectionManager>,
query: &str, query: &str,
sort_key: SortKey, sort: Sort,
sort_dir: SortDir,
size: usize, size: usize,
offset: usize, offset: usize,
) -> Result<Vec<Torrent>, Error> { ) -> Result<Vec<Torrent>, 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 mut stmt = conn.prepare(&stmt_str)?;
let torrent_iter = stmt.query_map_named(
named_params!{ let torrent_iter = stmt.query_map(params![
":query": query.replace(" ", "%"), query.replace(" ", "%"),
":sort_key": sort_key.to_string().to_lowercase(), offset.to_string(),
":offset": offset.to_string(), size.to_string(),
":size": size.to_string(), ],
},
|row| { |row| {
let size: isize = row.get(2)?; let size: isize = row.get(2)?;
println!("got size {:?}", size); println!("got size {:?}", size);

View File

@ -19,7 +19,7 @@ function buildSearchURL(sort_key, {state: { searchParams }) {
if (sort_key === searchParams.sort_key) { 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; searchParams.sort_dir = sort_dir;
console.log("no change in sort key from", sort_key, "so switch direction instead.") console.log("no change in sort key from", sort_key, "so switch direction instead.")
} else { } else {