WIP: improve search #1
|
@ -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<usize>,
|
||||
size: Option<usize>,
|
||||
sort_key: Option<SortKey>,
|
||||
sort_dir: Option<SortDir>,
|
||||
sort_key: Option<Key>,
|
||||
sort_dir: Option<Direction>,
|
||||
type_: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -136,8 +156,7 @@ async fn search(
|
|||
struct NewQuery {
|
||||
page: Option<usize>,
|
||||
size: Option<usize>,
|
||||
sort_key: Option<SortKey>,
|
||||
sort_dir: Option<SortDir>,
|
||||
sort: Option<Sort>,
|
||||
type_: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -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<SqliteConnectionManager>,
|
||||
query: &str,
|
||||
sort_key: SortKey,
|
||||
sort_dir: SortDir,
|
||||
sort: Sort,
|
||||
size: usize,
|
||||
offset: usize,
|
||||
) -> 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 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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue