Skip to content

Instantly share code, notes, and snippets.

@jannes-io
Created September 2, 2019 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jannes-io/fd1b69ebbf1c0787204e7468837d3f60 to your computer and use it in GitHub Desktop.
Save jannes-io/fd1b69ebbf1c0787204e7468837d3f60 to your computer and use it in GitHub Desktop.
use actix_web::error::BlockingError;
use actix_web::{web, Error as AWError, HttpResponse, Scope};
use diesel::pg::PgConnection;
use diesel::prelude::*;
use diesel::result::{DatabaseErrorKind, Error as DieselError};
use futures::Future;
use crate::models::{NewUser, User};
use crate::ConnectionPool;
fn list_query(pool: web::Data<ConnectionPool>) -> Result<Vec<User>, DieselError> {
use crate::schema::users::dsl::*;
let conn = &pool.get().unwrap();
users.load::<User>(conn)
}
fn list(pool: web::Data<ConnectionPool>) -> impl Future<Item = HttpResponse, Error = AWError> {
web::block(move || list_query(pool)).then(|res| match res {
Ok(users) => HttpResponse::Ok().json(users),
Err(e) => {
println!("{:?}", e);
HttpResponse::InternalServerError().into()
}
})
}
fn read_query(user_id: i32, pool: web::Data<ConnectionPool>) -> Result<User, DieselError> {
use crate::schema::users::dsl::{id, users};
let conn: &PgConnection = &pool.get().unwrap();
users.filter(id.eq(user_id)).first::<User>(conn)
}
fn read(
id: web::Path<(i32)>,
pool: web::Data<ConnectionPool>,
) -> impl Future<Item = HttpResponse, Error = AWError> {
web::block(move || read_query(id.into_inner(), pool)).then(|res| match res {
Ok(user) => HttpResponse::Ok().json(user),
Err(e) => {
println!("{:?}", e);
if let BlockingError::Error(DieselError::NotFound) = e {
let err = super::ApiError {
error: String::from("NotFound"),
message: String::from("Cannot find user with given id."),
};
HttpResponse::NotFound().json(err)
} else {
HttpResponse::InternalServerError().into()
}
}
})
}
fn create_query(new_user: &NewUser, pool: web::Data<ConnectionPool>) -> Result<User, DieselError> {
use crate::schema::users;
let conn: &PgConnection = &pool.get().unwrap();
diesel::insert_into(users::table)
.values(new_user)
.get_result(conn)
}
fn create(
new_user: web::Json<NewUser>,
pool: web::Data<ConnectionPool>,
) -> impl Future<Item = HttpResponse, Error = AWError> {
web::block(move || create_query(&new_user, pool)).then(|res| match res {
Ok(user) => HttpResponse::Ok().json(user),
Err(e) => {
println!("{:?}", e);
match e {
BlockingError::Error(DieselError::DatabaseError(err, _)) => match err {
DatabaseErrorKind::UniqueViolation => {
let err = super::ApiError {
error: format!("{:?}", err),
message: String::from(
"A user with that email or username already exists.",
),
};
HttpResponse::BadRequest().json(err)
}
_ => HttpResponse::InternalServerError().into(),
},
_ => HttpResponse::InternalServerError().into(),
}
}
})
}
fn update_query(user: &User, pool: web::Data<ConnectionPool>) -> Result<User, DieselError> {
use crate::schema::users;
let conn = &pool.get().unwrap();
diesel::update(users::table).set(user).get_result(conn)
}
fn update(
user: web::Json<User>,
pool: web::Data<ConnectionPool>,
) -> impl Future<Item = HttpResponse, Error = AWError> {
web::block(move || update_query(&user, pool)).then(|res| match res {
Ok(user) => HttpResponse::Ok().json(user),
Err(e) => {
println!("{:?}", e);
if let BlockingError::Error(DieselError::NotFound) = e {
let err = super::ApiError {
error: String::from("NotFound"),
message: String::from("Cannot find user with given id."),
};
HttpResponse::NotFound().json(err)
} else {
HttpResponse::InternalServerError().into()
}
}
})
}
fn delete_query(user_id: i32, pool: web::Data<ConnectionPool>) -> Result<usize, DieselError> {
use crate::schema::users::dsl::*;
let conn = &pool.get().unwrap();
diesel::delete(users.filter(id.eq(user_id))).execute(conn)
}
fn delete(
id: web::Path<(i32)>,
pool: web::Data<ConnectionPool>,
) -> impl Future<Item = HttpResponse, Error = AWError> {
web::block(move || delete_query(id.into_inner(), pool)).then(|res| match res {
Ok(_) => HttpResponse::Ok().json(true),
Err(e) => {
println!("{:?}", e);
if let BlockingError::Error(DieselError::NotFound) = e {
let err = super::ApiError {
error: String::from("NotFound"),
message: String::from("Cannot find user with given id."),
};
HttpResponse::NotFound().json(err)
} else {
HttpResponse::InternalServerError().into()
}
}
})
}
pub fn user_scope() -> Scope {
web::scope("/users")
.route("", web::get().to_async(list))
.route("", web::post().to_async(create))
.route("/{userid}", web::get().to_async(read))
.route("/{userid}", web::put().to_async(update))
.route("/{userid}", web::delete().to_async(delete))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment