Skip to content

Commit

Permalink
Update diesel to 2.0 (#601)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
msrd0 and dependabot[bot] committed Nov 6, 2022
1 parent 84c7f08 commit b630e4e
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 86 deletions.
7 changes: 3 additions & 4 deletions examples/diesel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ publish = false
[dependencies]
gotham = { path = "../../gotham/"}
gotham_middleware_diesel = { path = "../../middleware/diesel"}
futures-util = "0.3.14"

diesel = { version = "2.0", features = ["r2d2", "sqlite"] }
diesel_migrations = { version = "2.0", features = ["sqlite"] }
futures-util = "0.3.14"
log = "0.4"
diesel = { version = "1.4.6", features = ["r2d2", "sqlite"] }
diesel_migrations = { version = "1.4", features = ["sqlite"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[dev-dependencies]
diesel_migrations = "1.4.0"
tokio = { version = "1.11.0", features = ["full"] }
28 changes: 13 additions & 15 deletions examples/diesel/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
//! An example application working with the diesel middleware.

#[macro_use]
extern crate diesel;

#[cfg(test)]
#[macro_use]
extern crate diesel_migrations;

use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
use futures_util::FutureExt;
Expand Down Expand Up @@ -55,10 +48,10 @@ fn create_product_handler(mut state: State) -> Pin<Box<HandlerFuture>> {
};

let query_result = repo
.run(move |conn| {
.run(move |mut conn| {
diesel::insert_into(products::table)
.values(&product)
.execute(&conn)
.execute(&mut conn)
})
.await;

Expand All @@ -80,7 +73,9 @@ fn get_products_handler(state: State) -> Pin<Box<HandlerFuture>> {

let repo = Repo::borrow_from(&state).clone();
async move {
let result = repo.run(move |conn| products.load::<Product>(&conn)).await;
let result = repo
.run(move |mut conn| products.load::<Product>(&mut conn))
.await;
match result {
Ok(users) => {
let body = serde_json::to_string(&users).expect("Failed to serialize users.");
Expand Down Expand Up @@ -135,6 +130,7 @@ fn main() {
#[cfg(test)]
mod tests {
use super::*;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness as _};
use gotham::hyper::StatusCode;
use gotham::test::TestServer;
use gotham_middleware_diesel::Repo;
Expand All @@ -146,13 +142,14 @@ mod tests {
// You could also choose to do this separately using something like
// `cargo-make` (https://sagiegurari.github.io/cargo-make/) to run
// migrations before the test suite.
embed_migrations!();
const MIGRATIONS: EmbeddedMigrations = embed_migrations!();

#[test]
fn get_empty_products() {
let repo = Repo::with_test_transactions(DATABASE_URL);
let repo: Repo<SqliteConnection> = Repo::with_test_transactions(DATABASE_URL);
let runtime = tokio::runtime::Runtime::new().unwrap();
let _ = runtime.block_on(repo.run(|conn| embedded_migrations::run(&conn)));
_ = runtime
.block_on(repo.run(|mut conn| conn.run_pending_migrations(MIGRATIONS).map(|_| ())));
let test_server = TestServer::new(router(repo)).unwrap();
let response = test_server
.client()
Expand All @@ -170,9 +167,10 @@ mod tests {

#[test]
fn create_and_retrieve_product() {
let repo = Repo::with_test_transactions(DATABASE_URL);
let repo: Repo<SqliteConnection> = Repo::with_test_transactions(DATABASE_URL);
let runtime = tokio::runtime::Runtime::new().unwrap();
let _ = runtime.block_on(repo.run(|conn| embedded_migrations::run(&conn)));
_ = runtime
.block_on(repo.run(|mut conn| conn.run_pending_migrations(MIGRATIONS).map(|_| ())));
let test_server = TestServer::new(router(repo)).unwrap();

// First we'll insert something into the DB with a post
Expand Down
5 changes: 1 addition & 4 deletions examples/diesel/src/models.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//! Holds the two possible structs that are `Queryable` and
//! `Insertable` in the DB

// This warning is triggered by diesel's derive macros
#![allow(clippy::extra_unused_lifetimes)]

use diesel::{Insertable, Queryable};
use serde::{Deserialize, Serialize};

Expand All @@ -21,7 +18,7 @@ pub struct Product {

/// Represents a new product to insert in the DB.
#[derive(Insertable, Deserialize)]
#[table_name = "products"]
#[diesel(table_name = products)]
pub struct NewProduct {
pub title: String,
pub price: f32,
Expand Down
4 changes: 3 additions & 1 deletion examples/diesel/src/schema.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
table! {
// @generated automatically by Diesel CLI.

diesel::table! {
products (id) {
id -> Integer,
title -> Text,
Expand Down
12 changes: 7 additions & 5 deletions middleware/diesel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ categories = ["web-programming::http-server"]
keywords = ["http", "async", "web", "gotham", "diesel"]

[dependencies]
futures-util = "0.3.14"
gotham = { path = "../../gotham", version = "0.7.1", default-features = false, features = ["derive"] }
diesel = { version = "1.4.6", features = ["r2d2"] }
r2d2 = "0.8"
tokio = { version = "1.0", features = ["full"] }

diesel = { version = "2.0", features = ["r2d2"] }
futures-util = "0.3.14"
log = "0.4"
tokio = { version = "1.0", features = ["full"] }

[dev-dependencies]
diesel = { version = "1.4.6", features = ["sqlite"] }
gotham = { path = "../../gotham", version = "0.7.1", default-features = false, features = ["testing"] }

diesel = { version = "2.0.0", features = ["sqlite"] }
52 changes: 16 additions & 36 deletions middleware/diesel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@
//! Usage example:
//!
//! ```rust
//! # use diesel::{RunQueryDsl, SqliteConnection};
//! # use diesel::sql_types::Int8;
//! # use futures_util::FutureExt;
//! # use gotham::router::Router;
//! # use gotham::router::builder::*;
//! # use gotham::pipeline::*;
//! # use gotham::state::{FromState, State};
//! # use gotham::helpers::http::response::create_response;
//! # use gotham::handler::HandlerFuture;
//! # use gotham_middleware_diesel::{self, DieselMiddleware};
//! # use diesel::{RunQueryDsl, SqliteConnection};
//! # use gotham::hyper::StatusCode;
//! # use futures_util::FutureExt;
//! # use gotham::test::TestServer;
//! # use std::pin::Pin;
//! # use gotham::mime::TEXT_PLAIN;
//! # use std::pin::Pin;
//!
//! pub type Repo = gotham_middleware_diesel::Repo<SqliteConnection>;
//!
Expand All @@ -43,9 +44,9 @@
//! // `SELECT 1`
//! async move {
//! let result = repo
//! .run(move |conn| {
//! diesel::select(diesel::dsl::sql("1"))
//! .load::<i64>(&conn)
//! .run(move |mut conn| {
//! diesel::select(diesel::dsl::sql::<Int8>("1"))
//! .load::<i64>(&mut conn)
//! .map(|v| v.into_iter().next().expect("no results"))
//! })
//! .await;
Expand Down Expand Up @@ -75,35 +76,35 @@
//! ```
#![doc(test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]

use diesel::Connection;
use diesel::r2d2::R2D2Connection;
use futures_util::future::{self, FutureExt, TryFutureExt};
use log::{error, trace};
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::pin::Pin;
use std::process;

use gotham::anyhow;
use gotham::handler::HandlerFuture;
use gotham::middleware::{Middleware, NewMiddleware};
use gotham::middleware::Middleware;
use gotham::prelude::*;
use gotham::state::{request_id, State};

mod repo;

pub use crate::repo::Repo;
pub use repo::Repo;

/// A Gotham compatible Middleware that manages a pool of Diesel connections via a `Repo` and hands
/// out connections to other Middleware and Handlers that require them via the Gotham `State`
/// mechanism.
#[derive(NewMiddleware)]
pub struct DieselMiddleware<T>
where
T: Connection + 'static,
T: R2D2Connection + 'static,
{
repo: AssertUnwindSafe<Repo<T>>,
}

impl<T> DieselMiddleware<T>
where
T: Connection,
T: R2D2Connection,
{
pub fn new(repo: Repo<T>) -> Self {
DieselMiddleware {
Expand All @@ -114,7 +115,7 @@ where

impl<T> Clone for DieselMiddleware<T>
where
T: Connection + 'static,
T: R2D2Connection + 'static,
{
fn clone(&self) -> Self {
match catch_unwind(|| self.repo.clone()) {
Expand All @@ -129,30 +130,9 @@ where
}
}

impl<T> NewMiddleware for DieselMiddleware<T>
where
T: Connection + 'static,
{
type Instance = DieselMiddleware<T>;

fn new_middleware(&self) -> anyhow::Result<Self::Instance> {
match catch_unwind(|| self.repo.clone()) {
Ok(repo) => Ok(DieselMiddleware {
repo: AssertUnwindSafe(repo),
}),
Err(_) => {
error!(
"PANIC: r2d2::Pool::clone caused a panic, unable to rescue with a HTTP error"
);
process::abort()
}
}
}
}

impl<T> Middleware for DieselMiddleware<T>
where
T: Connection + 'static,
T: R2D2Connection + 'static,
{
fn call<Chain>(self, mut state: State, chain: Chain) -> Pin<Box<HandlerFuture>>
where
Expand Down
42 changes: 21 additions & 21 deletions middleware/diesel/src/repo.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use diesel::r2d2::ConnectionManager;
use diesel::Connection;
use diesel::r2d2::{self, CustomizeConnection, Pool, PooledConnection};
use diesel::r2d2::{ConnectionManager, R2D2Connection};
use gotham::prelude::*;
use log::error;
use r2d2::{CustomizeConnection, Pool, PooledConnection};
use tokio::task;

/// A database "repository", for running database workloads.
Expand All @@ -15,18 +14,19 @@ use tokio::task;
/// # use diesel::prelude::*;
/// # use diesel::Queryable;
/// # use diesel::sqlite::SqliteConnection;
/// # use diesel::connection::SimpleConnection as _;
/// # use tokio::runtime::Runtime;
///
/// # let runtime = Runtime::new().unwrap();
///
/// # let database_url = ":memory:";
/// # mod schema {
/// # table! {
/// # users {
/// # id -> Integer,
/// # name -> VarChar,
/// # }
/// # }
/// # table! {
/// # users {
/// # id -> Integer,
/// # name -> VarChar,
/// # }
/// # }
/// # }
///
/// #[derive(Queryable, Debug)]
Expand All @@ -37,30 +37,30 @@ use tokio::task;
///
/// type Repo = gotham_middleware_diesel::Repo<SqliteConnection>;
/// let repo = Repo::new(database_url);
/// # runtime.block_on(repo.run(|conn| {
/// # conn.execute("CREATE TABLE IF NOT EXISTS users (
/// # id INTEGER PRIMARY KEY AUTOINCREMENT,
/// # name VARCHAR NOT NULL
/// # )")
/// # runtime.block_on(repo.run(|mut conn| {
/// # conn.batch_execute("CREATE TABLE IF NOT EXISTS users (
/// # id INTEGER PRIMARY KEY AUTOINCREMENT,
/// # name VARCHAR NOT NULL
/// # )")
/// # })).unwrap();
/// let result = runtime
/// .block_on(repo.run(|conn| {
/// .block_on(repo.run(|mut conn| {
/// use schema::users::dsl::*;
/// users.load::<User>(&conn)
/// users.load::<User>(&mut conn)
/// }))
/// .unwrap();
/// ```
#[derive(StateData)]
pub struct Repo<T>
where
T: Connection + 'static,
T: R2D2Connection + 'static,
{
connection_pool: Pool<ConnectionManager<T>>,
}

impl<T> Clone for Repo<T>
where
T: Connection + 'static,
T: R2D2Connection + 'static,
{
fn clone(&self) -> Repo<T> {
Repo {
Expand All @@ -71,7 +71,7 @@ where

impl<T> Repo<T>
where
T: Connection + 'static,
T: R2D2Connection + 'static,
{
/// Creates a repo with default connection pool settings.
/// The default connection pool is `r2d2::Builder::default()`
Expand All @@ -94,7 +94,7 @@ where
/// ```rust
/// # use diesel::sqlite::SqliteConnection;
/// use core::time::Duration;
/// use r2d2::Pool;
/// use diesel::r2d2::Pool;
///
/// type Repo = gotham_middleware_diesel::Repo<SqliteConnection>;
/// let database_url = ":memory:";
Expand Down Expand Up @@ -128,7 +128,7 @@ where
/// ```
pub fn with_test_transactions(database_url: &str) -> Self {
let customizer = TestConnectionCustomizer {};
let builder = Pool::builder().connection_customizer(Box::new(customizer));
let builder = Pool::builder().connection_customizer(Box::new(customizer) as _);
Self::from_pool_builder(database_url, builder)
}

Expand Down

0 comments on commit b630e4e

Please sign in to comment.