Adding rusqlite async. Fixes #2

pull/3/head
Heretic 1 year ago
parent d020c436a0
commit b501e0503d

190
Cargo.lock generated

@ -44,9 +44,9 @@ dependencies = [
[[package]]
name = "actix-http"
version = "3.2.2"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724"
checksum = "0070905b2c4a98d184c4e81025253cb192aa8a73827553f38e9410801ceb35bb"
dependencies = [
"actix-codec",
"actix-rt",
@ -75,6 +75,8 @@ dependencies = [
"rand",
"sha1",
"smallvec",
"tokio",
"tokio-util",
"tracing",
"zstd",
]
@ -104,9 +106,9 @@ dependencies = [
[[package]]
name = "actix-rt"
version = "2.7.0"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000"
checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e"
dependencies = [
"futures-core",
"tokio",
@ -114,9 +116,9 @@ dependencies = [
[[package]]
name = "actix-server"
version = "2.1.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824"
checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327"
dependencies = [
"actix-rt",
"actix-service",
@ -153,9 +155,9 @@ dependencies = [
[[package]]
name = "actix-web"
version = "4.2.1"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9"
checksum = "464e0fddc668ede5f26ec1f9557a8d44eda948732f40c6b0ad79126930eb775f"
dependencies = [
"actix-codec",
"actix-http",
@ -265,9 +267,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base64"
version = "0.13.1"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
[[package]]
name = "bitflags"
@ -297,9 +299,9 @@ dependencies = [
[[package]]
name = "brotli-decompressor"
version = "2.3.2"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@ -320,17 +322,11 @@ dependencies = [
"bytes",
]
[[package]]
name = "cargo-husky"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
[[package]]
name = "cc"
version = "1.0.78"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
@ -376,6 +372,25 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -491,27 +506,27 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.25"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
[[package]]
name = "futures-sink"
version = "0.3.25"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
[[package]]
name = "futures-task"
version = "0.3.25"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
[[package]]
name = "futures-util"
version = "0.3.25"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
dependencies = [
"futures-core",
"futures-task",
@ -643,9 +658,9 @@ dependencies = [
[[package]]
name = "io-lifetimes"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
dependencies = [
"libc",
"windows-sys",
@ -864,9 +879,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.49"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
dependencies = [
"unicode-ident",
]
@ -880,27 +895,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r2d2"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
dependencies = [
"log",
"parking_lot",
"scheduled-thread-pool",
]
[[package]]
name = "r2d2_sqlite"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f5d0337e99cd5cacd91ffc326c6cc9d8078def459df560c4f9bf9ba4a51034"
dependencies = [
"r2d2",
"rusqlite",
]
[[package]]
name = "rand"
version = "0.8.5"
@ -982,9 +976,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.36.6"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
dependencies = [
"bitflags",
"errno",
@ -1000,15 +994,6 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "scheduled-thread-pool"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf"
dependencies = [
"parking_lot",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -1119,9 +1104,9 @@ dependencies = [
[[package]]
name = "termcolor"
version = "1.1.3"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
@ -1170,22 +1155,46 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.24.1"
version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae"
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-rusqlite"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31dfc8c4778d61428ef6b5d0eba26a5953314f307f10fb278f9839d0a1baae5"
dependencies = [
"crossbeam-channel",
"rusqlite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.4"
@ -1207,14 +1216,13 @@ dependencies = [
"actix-files",
"actix-web",
"anyhow",
"cargo-husky",
"env_logger",
"r2d2",
"r2d2_sqlite",
"rusqlite",
"serde",
"serde_derive",
"serde_json",
"tokio",
"tokio-rusqlite",
]
[[package]]
@ -1255,9 +1263,9 @@ dependencies = [
[[package]]
name = "unicode-bidi"
version = "0.3.8"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
[[package]]
name = "unicode-ident"
@ -1351,60 +1359,60 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "zstd"
version = "0.11.2+zstd.1.5.2"
version = "0.12.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
checksum = "e9262a83dc741c0b0ffec209881b45dbc232c21b02a2b9cb1adb93266e41303d"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "5.0.2+zstd.1.5.2"
version = "6.0.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
checksum = "a6cf39f730b440bab43da8fb5faf5f254574462f73f260f85f7987f32154ff17"
dependencies = [
"libc",
"zstd-sys",

@ -5,7 +5,7 @@ authors = ["Heretic <tylerjobsearch06@gmx.com>"]
edition = "2018"
[dependencies]
actix-web = "4.2.1"
actix-web = "4.3.0"
actix-files = "0.6.2"
env_logger = "0.10.0"
@ -15,8 +15,8 @@ serde_derive = "1.0.152"
anyhow = "1.0.68"
r2d2 = "0.8.10"
r2d2_sqlite = "0.21.0"
tokio-rusqlite = "0.3.0"
tokio = { version = "1.25.0", features = ["full"] }
[dependencies.rusqlite]
version = "0.28.0"

@ -4,17 +4,15 @@ extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
extern crate r2d2;
extern crate r2d2_sqlite;
extern crate rusqlite;
use actix_files as fs;
use actix_files::NamedFile;
use actix_web::{middleware, web, web::Data, App, HttpResponse, HttpServer};
use anyhow::{anyhow, Error};
use r2d2_sqlite::SqliteConnectionManager;
use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use anyhow::{anyhow, Result};
use rusqlite::params;
use std::{cmp, env, io, ops::Deref};
use std::{cmp, env, io, ops::Deref, path::Path};
use tokio_rusqlite::Connection;
const DEFAULT_SIZE: usize = 25;
@ -24,12 +22,8 @@ async fn main() -> io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=debug");
env_logger::init();
let manager = SqliteConnectionManager::file(torrents_db_file());
let pool = r2d2::Pool::builder().max_size(15).build(manager).unwrap();
HttpServer::new(move || {
App::new()
.app_data(Data::new(pool.clone()))
.wrap(middleware::Logger::default())
.service(fs::Files::new("/static", front_end_dir()))
.route("/", web::get().to(index))
@ -65,30 +59,22 @@ struct SearchQuery {
type_: Option<String>,
}
async fn search(
db: web::Data<r2d2::Pool<SqliteConnectionManager>>,
query: web::Query<SearchQuery>,
) -> Result<HttpResponse, actix_web::Error> {
let res = web::block(move || {
let conn = db.get().unwrap();
// TODO can't get errors to propagate correctly
search_query(query, conn).unwrap()
})
.await
.map(|body| {
HttpResponse::Ok()
.append_header(("Access-Control-Allow-Origin", "*"))
.json(body)
})
.map_err(actix_web::error::ErrorBadRequest)?;
async fn search(query: web::Query<SearchQuery>) -> Result<HttpResponse, actix_web::Error> {
let conn = Connection::open(Path::new(&torrents_db_file()))
.await
.map_err(actix_web::error::ErrorBadRequest)?;
let res = search_query(query, conn)
.await
.map(|body| {
HttpResponse::Ok()
.append_header(("Access-Control-Allow-Origin", "*"))
.json(body)
})
.map_err(actix_web::error::ErrorBadRequest)?;
Ok(res)
}
fn search_query(
query: web::Query<SearchQuery>,
conn: r2d2::PooledConnection<SqliteConnectionManager>,
) -> Result<Vec<Torrent>, Error> {
async fn search_query(query: web::Query<SearchQuery>, conn: Connection) -> Result<Vec<Torrent>> {
let q = query.q.trim();
if q.is_empty() || q.len() < 3 || q == "2020" {
return Err(anyhow!("{{\"error\": \"{}\"}}", "Empty query".to_string()));
@ -99,12 +85,9 @@ fn search_query(
let type_ = query.type_.as_ref().map_or("torrent", String::deref);
let offset = size * (page - 1);
println!(
"query = {}, type = {}, page = {}, size = {}",
q, type_, page, size
);
println!("query = {q}, type = {type_}, page = {page}, size = {size}");
torrent_search(conn, q, size, offset)
torrent_search(conn, q, size, offset).await
}
#[derive(Debug, Serialize, Deserialize)]
@ -119,53 +102,56 @@ struct Torrent {
scraped_date: u32,
}
fn torrent_search(
conn: r2d2::PooledConnection<SqliteConnectionManager>,
async fn torrent_search(
conn: Connection,
query: &str,
size: usize,
offset: usize,
) -> Result<Vec<Torrent>, Error> {
let stmt_str =
"select * from torrent where name like '%' || ?1 || '%' order by seeders desc limit ?2, ?3";
let mut stmt = conn.prepare(stmt_str)?;
let torrent_iter = stmt.query_map(
params![
query.replace(' ', "%"),
offset.to_string(),
size.to_string(),
],
|row| {
Ok(Torrent {
infohash: row.get(0)?,
name: row.get(1)?,
size_bytes: row.get(2)?,
created_unix: row.get(3)?,
seeders: row.get(4)?,
leechers: row.get(5)?,
completed: row.get(6)?,
scraped_date: row.get(7)?,
})
},
)?;
let mut torrents = Vec::new();
for torrent in torrent_iter {
torrents.push(torrent?);
}
Ok(torrents)
) -> Result<Vec<Torrent>> {
let q = query.to_owned();
let res = conn
.call(move |conn| {
let stmt_str =
"select * from torrent where name like '%' || ?1 || '%' order by seeders desc limit ?2, ?3";
let mut stmt = conn.prepare(stmt_str)?;
let torrents = stmt
.query_map(
params![q.replace(' ', "%"), offset.to_string(), size.to_string(),],
|row| {
Ok(Torrent {
infohash: row.get(0)?,
name: row.get(1)?,
size_bytes: row.get(2)?,
created_unix: row.get(3)?,
seeders: row.get(4)?,
leechers: row.get(5)?,
completed: row.get(6)?,
scraped_date: row.get(7)?,
})
},
)?
.collect::<Result<Vec<Torrent>, rusqlite::Error>>()?;
Ok::<_, rusqlite::Error>(torrents)
})
.await?;
Ok(res)
}
#[cfg(test)]
mod tests {
use r2d2_sqlite::SqliteConnectionManager;
#[test]
fn test() {
let manager = SqliteConnectionManager::file(super::torrents_db_file());
let pool = r2d2::Pool::builder().max_size(15).build(manager).unwrap();
let conn = pool.get().unwrap();
let results = super::torrent_search(conn, "sherlock", 10, 0);
assert!(results.unwrap().len() > 2);
// println!("Query took {:?} seconds.", end - start);
use crate::{torrent_search, torrents_db_file};
use std::path::Path;
use tokio_rusqlite::Connection;
#[tokio::test]
async fn test() {
let conn = Connection::open(Path::new(&torrents_db_file()))
.await
.unwrap();
let results = torrent_search(conn, "sherlock", 10, 0).await.unwrap();
assert!(results.len() > 2);
}
}

Loading…
Cancel
Save