From b630e4e8c8503f2e832d1d180788eee275a5e856 Mon Sep 17 00:00:00 2001 From: msrd0 Date: Sun, 6 Nov 2022 20:23:13 +0100 Subject: [PATCH] Update diesel to 2.0 (#601) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/diesel/Cargo.toml | 7 ++--- examples/diesel/src/main.rs | 28 +++++++++---------- examples/diesel/src/models.rs | 5 +--- examples/diesel/src/schema.rs | 4 ++- middleware/diesel/Cargo.toml | 12 ++++---- middleware/diesel/src/lib.rs | 52 +++++++++++------------------------ middleware/diesel/src/repo.rs | 42 ++++++++++++++-------------- 7 files changed, 64 insertions(+), 86 deletions(-) diff --git a/examples/diesel/Cargo.toml b/examples/diesel/Cargo.toml index 99f9ec465..09b8644bc 100644 --- a/examples/diesel/Cargo.toml +++ b/examples/diesel/Cargo.toml @@ -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"] } diff --git a/examples/diesel/src/main.rs b/examples/diesel/src/main.rs index f49e442ae..bba1874b6 100644 --- a/examples/diesel/src/main.rs +++ b/examples/diesel/src/main.rs @@ -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; @@ -55,10 +48,10 @@ fn create_product_handler(mut state: State) -> Pin> { }; let query_result = repo - .run(move |conn| { + .run(move |mut conn| { diesel::insert_into(products::table) .values(&product) - .execute(&conn) + .execute(&mut conn) }) .await; @@ -80,7 +73,9 @@ fn get_products_handler(state: State) -> Pin> { let repo = Repo::borrow_from(&state).clone(); async move { - let result = repo.run(move |conn| products.load::(&conn)).await; + let result = repo + .run(move |mut conn| products.load::(&mut conn)) + .await; match result { Ok(users) => { let body = serde_json::to_string(&users).expect("Failed to serialize users."); @@ -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; @@ -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 = 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() @@ -170,9 +167,10 @@ mod tests { #[test] fn create_and_retrieve_product() { - let repo = Repo::with_test_transactions(DATABASE_URL); + let repo: Repo = 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 diff --git a/examples/diesel/src/models.rs b/examples/diesel/src/models.rs index efa019ccb..97c0c6494 100644 --- a/examples/diesel/src/models.rs +++ b/examples/diesel/src/models.rs @@ -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}; @@ -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, diff --git a/examples/diesel/src/schema.rs b/examples/diesel/src/schema.rs index dfa05cc6d..4b816b2db 100644 --- a/examples/diesel/src/schema.rs +++ b/examples/diesel/src/schema.rs @@ -1,4 +1,6 @@ -table! { +// @generated automatically by Diesel CLI. + +diesel::table! { products (id) { id -> Integer, title -> Text, diff --git a/middleware/diesel/Cargo.toml b/middleware/diesel/Cargo.toml index 1039d7f52..5436b8ec3 100644 --- a/middleware/diesel/Cargo.toml +++ b/middleware/diesel/Cargo.toml @@ -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"] } diff --git a/middleware/diesel/src/lib.rs b/middleware/diesel/src/lib.rs index 63d97a359..e1cb94688 100644 --- a/middleware/diesel/src/lib.rs +++ b/middleware/diesel/src/lib.rs @@ -8,6 +8,9 @@ //! 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::*; @@ -15,12 +18,10 @@ //! # 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; //! @@ -43,9 +44,9 @@ //! // `SELECT 1` //! async move { //! let result = repo -//! .run(move |conn| { -//! diesel::select(diesel::dsl::sql("1")) -//! .load::(&conn) +//! .run(move |mut conn| { +//! diesel::select(diesel::dsl::sql::("1")) +//! .load::(&mut conn) //! .map(|v| v.into_iter().next().expect("no results")) //! }) //! .await; @@ -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 where - T: Connection + 'static, + T: R2D2Connection + 'static, { repo: AssertUnwindSafe>, } impl DieselMiddleware where - T: Connection, + T: R2D2Connection, { pub fn new(repo: Repo) -> Self { DieselMiddleware { @@ -114,7 +115,7 @@ where impl Clone for DieselMiddleware where - T: Connection + 'static, + T: R2D2Connection + 'static, { fn clone(&self) -> Self { match catch_unwind(|| self.repo.clone()) { @@ -129,30 +130,9 @@ where } } -impl NewMiddleware for DieselMiddleware -where - T: Connection + 'static, -{ - type Instance = DieselMiddleware; - - fn new_middleware(&self) -> anyhow::Result { - 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 Middleware for DieselMiddleware where - T: Connection + 'static, + T: R2D2Connection + 'static, { fn call(self, mut state: State, chain: Chain) -> Pin> where diff --git a/middleware/diesel/src/repo.rs b/middleware/diesel/src/repo.rs index c2a31bb04..d768db4b0 100644 --- a/middleware/diesel/src/repo.rs +++ b/middleware/diesel/src/repo.rs @@ -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. @@ -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)] @@ -37,30 +37,30 @@ use tokio::task; /// /// type Repo = gotham_middleware_diesel::Repo; /// 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::(&conn) +/// users.load::(&mut conn) /// })) /// .unwrap(); /// ``` #[derive(StateData)] pub struct Repo where - T: Connection + 'static, + T: R2D2Connection + 'static, { connection_pool: Pool>, } impl Clone for Repo where - T: Connection + 'static, + T: R2D2Connection + 'static, { fn clone(&self) -> Repo { Repo { @@ -71,7 +71,7 @@ where impl Repo where - T: Connection + 'static, + T: R2D2Connection + 'static, { /// Creates a repo with default connection pool settings. /// The default connection pool is `r2d2::Builder::default()` @@ -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; /// let database_url = ":memory:"; @@ -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) }