From 1a3fedc78fbd4ad2724f79fdaff354374965a55a Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Mon, 13 Mar 2023 17:58:08 +0000 Subject: [PATCH] update database examples --- examples/Cargo.toml | 3 +- examples/databases/Cargo.toml | 3 ++ examples/databases/src/main.rs | 92 +++++++++++++++++++++++----------- 3 files changed, 68 insertions(+), 30 deletions(-) diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 742c070..389cba0 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -2,6 +2,7 @@ members = [ "application", "async-handlers", + "databases", "easy-form-handling", "either", "errors", @@ -23,5 +24,3 @@ members = [ "url-dispatch", "websockets", ] -# TODO: update databases -exclude = ["databases"] diff --git a/examples/databases/Cargo.toml b/examples/databases/Cargo.toml index 276e6a2..b17a4aa 100644 --- a/examples/databases/Cargo.toml +++ b/examples/databases/Cargo.toml @@ -5,3 +5,6 @@ edition = "2018" [dependencies] actix-web = "4" +diesel = { version = "2", features = ["sqlite", "r2d2"] } +serde = { version = "1", features = ["derive"] } +uuid = { version = "1", features = ["v4"] } diff --git a/examples/databases/src/main.rs b/examples/databases/src/main.rs index efffd29..55efa1e 100644 --- a/examples/databases/src/main.rs +++ b/examples/databases/src/main.rs @@ -1,43 +1,76 @@ +use std::io; + +use actix_web::{error, web, App, HttpResponse, HttpServer, Responder}; +use diesel::{prelude::*, r2d2, Insertable, Queryable, SqliteConnection}; +use serde::Serialize; + +mod schema { + diesel::table! { + users { + id -> VarChar, + name -> VarChar, + } + } +} + +#[derive(Debug, Serialize, Queryable)] +struct User { + id: String, + name: String, +} + // -fn insert_new_user(db: &SqliteConnection, user: CreateUser) -> Result { - use self::schema::users::dsl::*; +#[derive(Debug, Insertable)] +#[diesel(table_name = self::schema::users)] +struct NewUser<'a> { + id: &'a str, + name: &'a str, +} + +fn insert_new_user( + conn: &mut SqliteConnection, + user_name: String, +) -> diesel::QueryResult { + use crate::schema::users::dsl::*; // Create insertion model - let uuid = format!("{}", uuid::Uuid::new_v4()); - let new_user = models::NewUser { - id: &uuid, - name: &user.name, + let uid = format!("{}", uuid::Uuid::new_v4()); + let new_user = NewUser { + id: &uid, + name: &user_name, }; // normal diesel operations diesel::insert_into(users) .values(&new_user) - .execute(&self.0) + .execute(conn) .expect("Error inserting person"); - let mut items = users - .filter(id.eq(&uuid)) - .load::(&self.0) - .expect("Error loading person"); + let user = users + .filter(id.eq(&uid)) + .first::(conn) + .expect("Error loading person that was just inserted"); - Ok(items.pop().unwrap()) + Ok(user) } // //
-type DbPool = r2d2::Pool>; +type DbPool = r2d2::Pool>; #[actix_web::main] async fn main() -> io::Result<()> { - // Create connection pool + // connect to SQLite DB + let manager = r2d2::ConnectionManager::::new("app.db"); let pool = r2d2::Pool::builder() .build(manager) - .expect("Failed to create pool."); + .expect("database URL should be valid path to SQLite DB file"); - // Start HTTP server + // start HTTP server on port 8080 HttpServer::new(move || { - App::new().app_data(web::Data::new(pool.clone())) - .resource("/{name}", web::get().to(index)) + App::new() + .app_data(web::Data::new(pool.clone())) + .route("/{name}", web::get().to(index)) }) .bind(("127.0.0.1", 8080))? .run() @@ -46,18 +79,21 @@ async fn main() -> io::Result<()> { //
// -async fn index(pool: web::Data, name: web::Path<(String)>) -> impl Responder { - let name = name.into_inner(); +async fn index( + pool: web::Data, + name: web::Path<(String,)>, +) -> actix_web::Result { + let (name,) = name.into_inner(); let user = web::block(move || { - let conn = pool.get().expect("couldn't get db connection from pool"); - actions::insert_new_user(&conn, &user) - .await - .map_err(|e| { - eprintln!("{}", e); - HttpResponse::InternalServerError().finish() - } - })?; + // Obtaining a connection from the pool is also a potentially blocking operation. + // So, it should be called within the `web::block` closure, as well. + let mut conn = pool.get().expect("couldn't get db connection from pool"); + + insert_new_user(&mut conn, name) + }) + .await? + .map_err(error::ErrorInternalServerError)?; Ok(HttpResponse::Ok().json(user)) }