1
0
mirror of https://github.com/actix/actix-website synced 2025-02-11 15:52:52 +01:00

101 lines
2.4 KiB
Rust
Raw Normal View History

2023-03-13 17:58:08 +00:00
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,
}
2020-09-12 16:21:54 +01:00
// <handler>
2023-03-13 17:58:08 +00:00
#[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<User> {
use crate::schema::users::dsl::*;
2020-09-12 16:21:54 +01:00
// Create insertion model
2023-03-13 17:58:08 +00:00
let uid = format!("{}", uuid::Uuid::new_v4());
let new_user = NewUser {
id: &uid,
name: &user_name,
2020-09-12 16:21:54 +01:00
};
// normal diesel operations
diesel::insert_into(users)
.values(&new_user)
2023-03-13 17:58:08 +00:00
.execute(conn)
2020-09-12 16:21:54 +01:00
.expect("Error inserting person");
2023-03-13 17:58:08 +00:00
let user = users
.filter(id.eq(&uid))
.first::<User>(conn)
.expect("Error loading person that was just inserted");
2020-09-12 16:21:54 +01:00
2023-03-13 17:58:08 +00:00
Ok(user)
2020-09-12 16:21:54 +01:00
}
// </handler>
// <main>
2023-03-13 17:58:08 +00:00
type DbPool = r2d2::Pool<r2d2::ConnectionManager<SqliteConnection>>;
2020-09-12 16:21:54 +01:00
#[actix_web::main]
async fn main() -> io::Result<()> {
2023-03-13 17:58:08 +00:00
// connect to SQLite DB
let manager = r2d2::ConnectionManager::<SqliteConnection>::new("app.db");
2020-09-12 16:21:54 +01:00
let pool = r2d2::Pool::builder()
.build(manager)
2023-03-13 17:58:08 +00:00
.expect("database URL should be valid path to SQLite DB file");
2020-09-12 16:21:54 +01:00
2023-03-13 17:58:08 +00:00
// start HTTP server on port 8080
2020-09-12 16:21:54 +01:00
HttpServer::new(move || {
2023-03-13 17:58:08 +00:00
App::new()
.app_data(web::Data::new(pool.clone()))
.route("/{name}", web::get().to(index))
2020-09-12 16:21:54 +01:00
})
2022-02-26 03:56:24 +00:00
.bind(("127.0.0.1", 8080))?
2020-09-12 16:21:54 +01:00
.run()
.await
}
// </main>
// <index>
2023-03-13 17:58:08 +00:00
async fn index(
pool: web::Data<DbPool>,
name: web::Path<(String,)>,
) -> actix_web::Result<impl Responder> {
let (name,) = name.into_inner();
2020-09-12 16:21:54 +01:00
let user = web::block(move || {
2023-03-13 17:58:08 +00:00
// 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)?;
2020-09-12 16:21:54 +01:00
Ok(HttpResponse::Ok().json(user))
}
// </index>