mirror of
https://github.com/actix/examples
synced 2025-01-22 14:05:55 +01:00
update rusqlite and r2d2_sqlite in async_db and r2d2 (#148)
* upgrade rusqlite to 0.18 * add note about async_db blocking and running in thread pool * idiomatic async_db - DRY - Iterator::collect + return type - note about why we are sleeping * remove r2d2/test.db
This commit is contained in:
parent
817a61855d
commit
78a753a06a
@ -14,7 +14,7 @@ failure = "0.1.1"
|
||||
futures = "0.3.1"
|
||||
num_cpus = "1.10.0"
|
||||
r2d2 = "0.8.2"
|
||||
r2d2_sqlite = "0.8.0"
|
||||
rusqlite = "0.16"
|
||||
r2d2_sqlite = "0.10"
|
||||
rusqlite = "0.18"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
@ -3,12 +3,13 @@ use failure::Error;
|
||||
use futures::{Future, TryFutureExt};
|
||||
use r2d2;
|
||||
use r2d2_sqlite;
|
||||
use rusqlite::NO_PARAMS;
|
||||
use rusqlite::{Statement, NO_PARAMS};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{thread::sleep, time::Duration};
|
||||
|
||||
pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>;
|
||||
pub type Connection = r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>;
|
||||
type WeatherAggResult = Result<Vec<WeatherAgg>, rusqlite::Error>;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum WeatherAgg {
|
||||
@ -28,115 +29,96 @@ pub fn execute(
|
||||
query: Queries,
|
||||
) -> impl Future<Output = Result<Vec<WeatherAgg>, AWError>> {
|
||||
let pool = pool.clone();
|
||||
web::block(move || match query {
|
||||
Queries::GetTopTenHottestYears => get_hottest_years(pool.get()?),
|
||||
Queries::GetTopTenColdestYears => get_coldest_years(pool.get()?),
|
||||
Queries::GetTopTenHottestMonths => get_hottest_months(pool.get()?),
|
||||
Queries::GetTopTenColdestMonths => get_coldest_months(pool.get()?),
|
||||
web::block(move || {
|
||||
// simulate an expensive query, see comments at top of main.rs
|
||||
sleep(Duration::from_secs(2));
|
||||
|
||||
let result = match query {
|
||||
Queries::GetTopTenHottestYears => get_hottest_years(pool.get()?),
|
||||
Queries::GetTopTenColdestYears => get_coldest_years(pool.get()?),
|
||||
Queries::GetTopTenHottestMonths => get_hottest_months(pool.get()?),
|
||||
Queries::GetTopTenColdestMonths => get_coldest_months(pool.get()?),
|
||||
};
|
||||
result.map_err(Error::from)
|
||||
})
|
||||
.map_err(AWError::from)
|
||||
}
|
||||
|
||||
fn get_hottest_years(conn: Connection) -> Result<Vec<WeatherAgg>, Error> {
|
||||
let stmt = "
|
||||
fn get_hottest_years(conn: Connection) -> WeatherAggResult {
|
||||
let stmt = conn.prepare(
|
||||
"
|
||||
SELECT cast(strftime('%Y', date) as int) as theyear,
|
||||
sum(tmax) as total
|
||||
FROM nyc_weather
|
||||
WHERE tmax <> 'TMAX'
|
||||
GROUP BY theyear
|
||||
ORDER BY total DESC LIMIT 10;";
|
||||
ORDER BY total DESC LIMIT 10",
|
||||
)?;
|
||||
|
||||
let mut prep_stmt = conn.prepare(stmt)?;
|
||||
let annuals = prep_stmt
|
||||
.query_map(NO_PARAMS, |row| WeatherAgg::AnnualAgg {
|
||||
year: row.get(0),
|
||||
total: row.get(1),
|
||||
})
|
||||
.and_then(|mapped_rows| {
|
||||
Ok(mapped_rows
|
||||
.map(|row| row.unwrap())
|
||||
.collect::<Vec<WeatherAgg>>())
|
||||
})?;
|
||||
|
||||
sleep(Duration::from_secs(2)); //see comments at top of main.rs
|
||||
|
||||
Ok(annuals)
|
||||
get_rows_as_annual_agg(stmt)
|
||||
}
|
||||
|
||||
fn get_coldest_years(conn: Connection) -> Result<Vec<WeatherAgg>, Error> {
|
||||
let stmt = "
|
||||
fn get_coldest_years(conn: Connection) -> WeatherAggResult {
|
||||
let stmt = conn.prepare(
|
||||
"
|
||||
SELECT cast(strftime('%Y', date) as int) as theyear,
|
||||
sum(tmax) as total
|
||||
FROM nyc_weather
|
||||
WHERE tmax <> 'TMAX'
|
||||
GROUP BY theyear
|
||||
ORDER BY total ASC LIMIT 10;";
|
||||
ORDER BY total ASC LIMIT 10",
|
||||
)?;
|
||||
|
||||
let mut prep_stmt = conn.prepare(stmt)?;
|
||||
let annuals = prep_stmt
|
||||
.query_map(NO_PARAMS, |row| WeatherAgg::AnnualAgg {
|
||||
year: row.get(0),
|
||||
total: row.get(1),
|
||||
})
|
||||
.and_then(|mapped_rows| {
|
||||
Ok(mapped_rows
|
||||
.map(|row| row.unwrap())
|
||||
.collect::<Vec<WeatherAgg>>())
|
||||
})?;
|
||||
|
||||
sleep(Duration::from_secs(2)); //see comments at top of main.rs
|
||||
|
||||
Ok(annuals)
|
||||
get_rows_as_annual_agg(stmt)
|
||||
}
|
||||
|
||||
fn get_hottest_months(conn: Connection) -> Result<Vec<WeatherAgg>, Error> {
|
||||
let stmt = "SELECT cast(strftime('%Y', date) as int) as theyear,
|
||||
fn get_rows_as_annual_agg(mut statement: Statement) -> WeatherAggResult {
|
||||
statement
|
||||
.query_map(NO_PARAMS, |row| {
|
||||
Ok(WeatherAgg::AnnualAgg {
|
||||
year: row.get(0)?,
|
||||
total: row.get(1)?,
|
||||
})
|
||||
})
|
||||
.and_then(Iterator::collect)
|
||||
}
|
||||
|
||||
fn get_hottest_months(conn: Connection) -> WeatherAggResult {
|
||||
let stmt = conn.prepare(
|
||||
"SELECT cast(strftime('%Y', date) as int) as theyear,
|
||||
cast(strftime('%m', date) as int) as themonth,
|
||||
sum(tmax) as total
|
||||
FROM nyc_weather
|
||||
WHERE tmax <> 'TMAX'
|
||||
GROUP BY theyear, themonth
|
||||
ORDER BY total DESC LIMIT 10;";
|
||||
ORDER BY total DESC LIMIT 10",
|
||||
)?;
|
||||
|
||||
let mut prep_stmt = conn.prepare(stmt)?;
|
||||
let annuals = prep_stmt
|
||||
.query_map(NO_PARAMS, |row| WeatherAgg::MonthAgg {
|
||||
year: row.get(0),
|
||||
month: row.get(1),
|
||||
total: row.get(2),
|
||||
})
|
||||
.and_then(|mapped_rows| {
|
||||
Ok(mapped_rows
|
||||
.map(|row| row.unwrap())
|
||||
.collect::<Vec<WeatherAgg>>())
|
||||
})?;
|
||||
|
||||
sleep(Duration::from_secs(2)); //see comments at top of main.rs
|
||||
Ok(annuals)
|
||||
get_rows_as_month_agg(stmt)
|
||||
}
|
||||
|
||||
fn get_coldest_months(conn: Connection) -> Result<Vec<WeatherAgg>, Error> {
|
||||
let stmt = "SELECT cast(strftime('%Y', date) as int) as theyear,
|
||||
fn get_coldest_months(conn: Connection) -> WeatherAggResult {
|
||||
let stmt = conn.prepare(
|
||||
"SELECT cast(strftime('%Y', date) as int) as theyear,
|
||||
cast(strftime('%m', date) as int) as themonth,
|
||||
sum(tmax) as total
|
||||
FROM nyc_weather
|
||||
WHERE tmax <> 'TMAX'
|
||||
GROUP BY theyear, themonth
|
||||
ORDER BY total ASC LIMIT 10;";
|
||||
ORDER BY total ASC LIMIT 10",
|
||||
)?;
|
||||
|
||||
let mut prep_stmt = conn.prepare(stmt)?;
|
||||
let annuals = prep_stmt
|
||||
.query_map(NO_PARAMS, |row| WeatherAgg::MonthAgg {
|
||||
year: row.get(0),
|
||||
month: row.get(1),
|
||||
total: row.get(2),
|
||||
})
|
||||
.and_then(|mapped_rows| {
|
||||
Ok(mapped_rows
|
||||
.map(|row| row.unwrap())
|
||||
.collect::<Vec<WeatherAgg>>())
|
||||
})?;
|
||||
|
||||
sleep(Duration::from_secs(2)); //see comments at top of main.rs
|
||||
Ok(annuals)
|
||||
get_rows_as_month_agg(stmt)
|
||||
}
|
||||
|
||||
fn get_rows_as_month_agg(mut statement: Statement) -> WeatherAggResult {
|
||||
statement
|
||||
.query_map(NO_PARAMS, |row| {
|
||||
Ok(WeatherAgg::MonthAgg {
|
||||
year: row.get(0)?,
|
||||
month: row.get(1)?,
|
||||
total: row.get(2)?,
|
||||
})
|
||||
})
|
||||
.and_then(Iterator::collect)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Actix-Web Asynchronous Database Example
|
||||
|
||||
This project illustrates two examples:
|
||||
This project illustrates expensive and blocking database requests that runs
|
||||
in a thread-pool using `web::block` with two examples:
|
||||
|
||||
1. An asynchronous handler that executes 4 queries in *sequential order*,
|
||||
collecting the results and returning them as a single serialized json object
|
||||
|
@ -13,5 +13,5 @@ env_logger = "0.6"
|
||||
uuid = { version = "0.8", features = ["v4"] }
|
||||
|
||||
r2d2 = "0.8"
|
||||
r2d2_sqlite = "0.8"
|
||||
rusqlite = "0.16"
|
||||
r2d2_sqlite = "0.10"
|
||||
rusqlite = "0.18"
|
||||
|
BIN
r2d2/test.db
BIN
r2d2/test.db
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user