Page MenuHomeDevCentral

D1662.diff
No OneTemporary

D1662.diff

diff --git a/Cargo.toml b/Cargo.toml
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,3 +8,7 @@
license = "BSD-2-Clause"
[dependencies]
+diesel = { version = "1.0.0", features = ["postgres", "r2d2", "chrono"] }
+log = "^0.4.4"
+r2d2 = "^0.8.2"
+rocket = "^0.3.16"
diff --git a/src/database.rs b/src/database.rs
new file mode 100644
--- /dev/null
+++ b/src/database.rs
@@ -0,0 +1,105 @@
+//! This module handles a database layer, mainly intended to be used
+//! with a web server or framework like Rocket or Iron.
+//!
+//! It leverages diesel and r2d2.
+//!
+//! Most code comes from the Rocket manual:
+//! https://rocket.rs/guide/state/#databases
+
+use diesel::Connection;
+use diesel::pg::PgConnection;
+use diesel::r2d2::ConnectionManager;
+use diesel::r2d2::Pool;
+use diesel::r2d2::PooledConnection;
+use ErrorResult;
+use r2d2::Error as PoolError;
+use rocket::http::Status;
+use rocket::Outcome;
+use rocket::request::FromRequest;
+use rocket::request::Outcome as RequestOutcome;
+use rocket::Request;
+use rocket::State;
+use std::error::Error;
+use std::ops::Deref;
+
+/* -------------------------------------------------------------
+ Custom types
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+pub type PostgreSQLPool = Pool<ConnectionManager<PgConnection>>;
+
+/* -------------------------------------------------------------
+ DatabaseConnection
+
+ :: FromRequest
+ :: Deref
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/// Represents an established working database connection from the pool
+pub struct DatabaseConnection(pub PooledConnection<ConnectionManager<PgConnection>>);
+
+impl<'a, 'r> FromRequest<'a, 'r> for DatabaseConnection {
+ type Error = ();
+
+ fn from_request(request: &'a Request<'r>) -> RequestOutcome<Self, Self::Error> {
+ let pool = request.guard::<State<PostgreSQLPool>>()?;
+ match pool.get() {
+ Ok(connection) => Outcome::Success(DatabaseConnection(connection)),
+ Err(error) => {
+ warn!(target:"request", "Can't get a connection from the pool: {}", error.description());
+
+ Outcome::Failure((Status::ServiceUnavailable, ()))
+ },
+ }
+ }
+}
+
+impl Deref for DatabaseConnection {
+ type Target = PgConnection;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+/* -------------------------------------------------------------
+ Helper methods to get a database connection
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/// Builds a r2d2 database pool, to be used in a request guard or a managed state.
+///
+/// # Examples
+///
+/// ```
+/// rocket::ignite()
+/// .manage(initialize_database_pool(String::from("postgres://::1/test"), 4)?)
+/// .mount("/", routes)
+/// .launch();
+/// ```
+pub fn initialize_database_pool(url: String, max_size: u32) -> Result<PostgreSQLPool, PoolError> {
+ let manager = ConnectionManager::<PgConnection>::new(url);
+
+ Pool::builder()
+ .max_size(max_size)
+ .build(manager)
+}
+
+/// Allows to test if it's possible to establish a connection to the database.
+///
+/// The goal is to test early any issue with the connection, and loudly warn or fail
+/// if the database can't be reached.
+///
+/// # Examples
+///
+/// ```
+/// // Initial connection to test if the database configuration works
+/// {
+/// test_database_connection(&config.database_url)?;
+/// info!(target: "runner", "Connection to database established.");
+/// }
+/// ```
+pub fn test_database_connection(database_url: &str) -> ErrorResult<()> {
+ PgConnection::establish(database_url)?;
+
+ Ok(())
+}
diff --git a/src/lib.rs b/src/lib.rs
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,14 @@
+extern crate diesel;
+#[macro_use] extern crate log;
+extern crate r2d2;
+extern crate rocket;
+
+/* -------------------------------------------------------------
+ Public modules offered by this crate
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+pub mod database;
+
/* -------------------------------------------------------------
Custom types
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 29, 22:50 (21 m, 23 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2165117
Default Alt Text
D1662.diff (4 KB)

Event Timeline