Adding connection pool.

main
Heretic 10 months ago
parent 296b15e5a7
commit cd07888b03

73
Cargo.lock generated

@ -420,25 +420,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
"cfg-if",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -846,6 +827,15 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "nanoid"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
dependencies = [
"rand",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
@ -948,6 +938,28 @@ 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_pool"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c211b97022a76440bd16521bba1abf82398218ade33d96813c5776bf8baf9722"
dependencies = [
"nanoid",
"r2d2",
"rusqlite",
]
[[package]]
name = "rand"
version = "0.8.5"
@ -1064,6 +1076,15 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "scheduled-thread-pool"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
dependencies = [
"parking_lot",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -1265,17 +1286,6 @@ dependencies = [
"syn 2.0.27",
]
[[package]]
name = "tokio-rusqlite"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aa66395f5ff117faee90c9458232c936405f9227ad902038000b74b3bc1feac"
dependencies = [
"crossbeam-channel",
"rusqlite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.8"
@ -1298,12 +1308,13 @@ dependencies = [
"actix-web",
"anyhow",
"env_logger",
"r2d2",
"r2d2_sqlite_pool",
"rusqlite",
"serde",
"serde_derive",
"serde_json",
"tokio",
"tokio-rusqlite",
"uuid",
]

@ -15,9 +15,10 @@ serde_derive = "1.0.163"
anyhow = "1.0.71"
tokio-rusqlite = "0.4.0"
tokio = { version = "1.28.1", features = ["full"] }
uuid = { version = "1.4.1", features = ["v4", "fast-rng"] }
r2d2_sqlite_pool = "0.1.1"
r2d2 = "0.8.10"
[dependencies.rusqlite]
version = "0.29.0"
features = ["bundled"]

@ -13,22 +13,29 @@ use actix_web::{
HttpServer,
};
use anyhow::{anyhow, Result};
use r2d2::{Pool, PooledConnection};
use r2d2_sqlite_pool::SqliteConnectionManager;
use rusqlite::params;
use std::{cmp, env, io, ops::Deref, path::Path};
use std::{cmp, env, io, ops::Deref};
use tokio::sync::Mutex;
use tokio_rusqlite::Connection;
use uuid::Uuid;
const DEFAULT_SIZE: usize = 25;
type Conn = PooledConnection<SqliteConnectionManager>;
struct MyAppData {
etag: String,
pool: Pool<SqliteConnectionManager>,
}
#[actix_web::main]
async fn main() -> io::Result<()> {
let manager = SqliteConnectionManager::file(torrents_db_file());
let pool = r2d2::Pool::new(manager).unwrap();
let my_app_data = Data::new(Mutex::new(MyAppData {
etag: Uuid::new_v4().to_string(),
pool,
}));
println!("Access me at {}", endpoint());
std::env::set_var("RUST_LOG", "actix_web=debug");
@ -68,11 +75,8 @@ async fn search(
) -> Result<HttpResponse, actix_web::Error> {
let my_app_data = data.lock().await;
let etag = my_app_data.etag.clone();
let conn = Connection::open(Path::new(&torrents_db_file()))
.await
.map_err(actix_web::error::ErrorBadRequest)?;
let conn = my_app_data.pool.get().unwrap();
let res = search_query(query, conn)
.await
.map(|body| {
HttpResponse::Ok()
.append_header(("Access-Control-Allow-Origin", "*"))
@ -84,7 +88,7 @@ async fn search(
Ok(res)
}
async fn search_query(query: web::Query<SearchQuery>, conn: Connection) -> Result<Vec<Torrent>> {
fn search_query(query: web::Query<SearchQuery>, conn: Conn) -> 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()));
@ -97,7 +101,7 @@ async fn search_query(query: web::Query<SearchQuery>, conn: Connection) -> Resul
println!("query = {q}, type = {type_}, page = {page}, size = {size}");
torrent_search(conn, q, size, offset).await
torrent_search(conn, q, size, offset)
}
#[derive(Debug, Serialize, Deserialize)]
@ -112,39 +116,27 @@ struct Torrent {
scraped_date: u32,
}
async fn torrent_search(
conn: Connection,
query: &str,
size: usize,
offset: usize,
) -> Result<Vec<Torrent>> {
fn torrent_search(conn: Conn, query: &str, size: usize, offset: usize) -> Result<Vec<Torrent>> {
let q = query.to_owned();
let res = conn
.call(move |conn| {
let stmt_str = "select * from torrent where name like '%' || ?1 || '%' 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)
let stmt_str = "select * from torrent where name like '%' || ?1 || '%' 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(torrents)
}

Loading…
Cancel
Save