Introduce db connection pool. Derive Clone for State
This commit is contained in:
parent
5a859e5c33
commit
60a87d1898
5 changed files with 87 additions and 23 deletions
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -14,6 +14,8 @@ dependencies = [
|
|||
"num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pulldown-cmark 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -37,6 +39,11 @@ name = "ansi_term"
|
|||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "antidote"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.2"
|
||||
|
@ -451,6 +458,25 @@ name = "quote"
|
|||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "r2d2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2-diesel"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"diesel 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.16"
|
||||
|
@ -504,6 +530,14 @@ dependencies = [
|
|||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scheduled-thread-pool"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "0.1.0"
|
||||
|
@ -791,6 +825,7 @@ dependencies = [
|
|||
[metadata]
|
||||
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
|
||||
"checksum bart 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f9d52a5c46e2abe28ae1c2ecdaa320c01e424c29a56acb7a6222141c78bae7"
|
||||
"checksum bart_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "39fdc9035ac29aeb14993e2cdae217de7ccc9f9960eae0c5a12d541ca11c6af1"
|
||||
|
@ -843,6 +878,8 @@ dependencies = [
|
|||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||
"checksum pulldown-cmark 0.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7c04a8bb38f80717527edea39c82378c2ef13ecdbc914cbd90653a2e24afdf"
|
||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||
"checksum r2d2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c665a538b218e1620093be6643b375d3321837bfc1b30aa18757b7c6546d2ca"
|
||||
"checksum r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6b921696a6c45991296d21b52ed973b9fb56f6c47524fda1f99458c2d6c0478"
|
||||
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
|
||||
"checksum redox_syscall 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "8312fba776a49cf390b7b62f3135f9b294d8617f7a7592cfd0ac2492b658cd7b"
|
||||
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
|
||||
|
@ -850,6 +887,7 @@ dependencies = [
|
|||
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
|
||||
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
|
||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||
"checksum scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d9fbe48ead32343b76f544c85953bf260ed39219a8bbbb62cd85f6a00f9644f"
|
||||
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
|
||||
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
|
||||
"checksum serde 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f7726f29ddf9731b17ff113c461e362c381d9d69433f79de4f3dd572488823e9"
|
||||
|
|
|
@ -12,6 +12,8 @@ tokio-service = "0.1"
|
|||
serde_derive = "1.0.0"
|
||||
serde = "1.0.0"
|
||||
serde_urlencoded = "0.5.0"
|
||||
r2d2 = "0.7"
|
||||
r2d2-diesel = "0.16"
|
||||
regex = "0.2"
|
||||
lazy_static = "0.2"
|
||||
chrono = "0.4"
|
||||
|
|
34
src/db.rs
34
src/db.rs
|
@ -1,23 +1,33 @@
|
|||
use diesel::Connection;
|
||||
use diesel::sqlite::SqliteConnection;
|
||||
use diesel::prelude::*;
|
||||
use diesel::expression::sql_literal::sql;
|
||||
use diesel::types::*;
|
||||
use r2d2::{Config, CustomizeConnection, Pool};
|
||||
use r2d2_diesel::{self, ConnectionManager};
|
||||
|
||||
embed_migrations!();
|
||||
|
||||
pub fn connect_database(connection_string: &str, run_migrations: bool) -> SqliteConnection {
|
||||
let connection = SqliteConnection::establish(connection_string)
|
||||
.expect(&format!("Error connecting to database at {}", connection_string));
|
||||
#[derive(Debug)]
|
||||
struct SqliteInitializer;
|
||||
|
||||
// Integer is a dummy placeholder. Compiling fails when passing ().
|
||||
impl CustomizeConnection<SqliteConnection, r2d2_diesel::Error> for SqliteInitializer {
|
||||
fn on_acquire(&self, conn: &mut SqliteConnection) -> Result<(), r2d2_diesel::Error> {
|
||||
sql::<(Integer)>("PRAGMA foreign_keys = ON")
|
||||
.execute(&connection)
|
||||
.expect("Should be able to enable foreign_keys");
|
||||
|
||||
if run_migrations {
|
||||
embedded_migrations::run(&connection).unwrap();
|
||||
.execute(conn)
|
||||
.and(Ok(()))
|
||||
.map_err(|x| r2d2_diesel::Error::QueryError(x))
|
||||
}
|
||||
|
||||
connection
|
||||
}
|
||||
|
||||
pub fn create_pool(connection_string: String) -> Result<Pool<ConnectionManager<SqliteConnection>>, Box<::std::error::Error>> {
|
||||
let config = Config::builder()
|
||||
.connection_customizer(Box::new(SqliteInitializer {}))
|
||||
.build();
|
||||
let manager = ConnectionManager::<SqliteConnection>::new(connection_string);
|
||||
|
||||
let pool = Pool::new(config, manager)?;
|
||||
|
||||
embedded_migrations::run(&*pool.get()?)?;
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -2,13 +2,16 @@
|
|||
#[macro_use] extern crate diesel;
|
||||
#[macro_use] extern crate diesel_codegen;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
extern crate bart;
|
||||
extern crate chrono;
|
||||
extern crate clap;
|
||||
extern crate futures;
|
||||
extern crate hyper;
|
||||
extern crate pulldown_cmark;
|
||||
extern crate r2d2;
|
||||
extern crate r2d2_diesel;
|
||||
extern crate serde_urlencoded;
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
|
@ -48,14 +51,14 @@ fn core_main() -> Result<(), Box<std::error::Error>> {
|
|||
.map(|p| p.parse().expect("Guaranteed by validator"))
|
||||
.unwrap_or(8080);
|
||||
|
||||
// Connect to the database and run migrations up front:
|
||||
db::connect_database(&db_file, true);
|
||||
let db_pool = db::create_pool(db_file)?;
|
||||
let state = state::State::new(db_pool);
|
||||
|
||||
let server =
|
||||
hyper::server::Http::new()
|
||||
.bind(
|
||||
&SocketAddr::new(bind_host, bind_port),
|
||||
move || Ok(site::Site::new(state::State::new(db::connect_database(&db_file, false))))
|
||||
move || Ok(site::Site::new(state.clone()))
|
||||
)?;
|
||||
|
||||
println!("Listening on http://{}", server.local_addr().unwrap());
|
||||
|
|
23
src/state.rs
23
src/state.rs
|
@ -3,19 +3,30 @@ use std;
|
|||
use chrono;
|
||||
use diesel::sqlite::SqliteConnection;
|
||||
use diesel::prelude::*;
|
||||
use r2d2::Pool;
|
||||
use r2d2_diesel::ConnectionManager;
|
||||
|
||||
use models;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct State {
|
||||
db_connection: SqliteConnection
|
||||
connection_pool: Pool<ConnectionManager<SqliteConnection>>
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateArticle {
|
||||
base_revision: i32,
|
||||
body: String,
|
||||
}
|
||||
|
||||
pub type Error = Box<std::error::Error + Send + Sync>;
|
||||
|
||||
impl State {
|
||||
pub fn new(db_connection: SqliteConnection) -> State {
|
||||
State { db_connection }
|
||||
pub fn new(connection_pool: Pool<ConnectionManager<SqliteConnection>>) -> State {
|
||||
State { connection_pool }
|
||||
}
|
||||
|
||||
pub fn get_article_revision_by_slug(&self, slug: &str) -> Result<Option<models::ArticleRevision>, Box<std::error::Error + Send + Sync>> {
|
||||
pub fn get_article_revision_by_slug(&self, slug: &str) -> Result<Option<models::ArticleRevision>, Error> {
|
||||
Ok(Some(models::ArticleRevision {
|
||||
article_id: 0,
|
||||
revision: 0,
|
||||
|
@ -25,14 +36,14 @@ impl State {
|
|||
}))
|
||||
}
|
||||
|
||||
pub fn get_article_revision_by_id(&self, article_id: i32) -> Result<Option<models::ArticleRevision>, Box<std::error::Error + Send + Sync>> {
|
||||
pub fn get_article_revision_by_id(&self, article_id: i32) -> Result<Option<models::ArticleRevision>, Error> {
|
||||
use schema::article_revisions;
|
||||
|
||||
Ok(article_revisions::table
|
||||
.filter(article_revisions::article_id.eq(article_id))
|
||||
.order(article_revisions::revision.desc())
|
||||
.limit(1)
|
||||
.load::<models::ArticleRevision>(&self.db_connection)?
|
||||
.load::<models::ArticleRevision>(&*self.connection_pool.get()?)?
|
||||
.pop())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue