Compare commits
2 Commits
6671f81a9a
...
96c251c1ca
Author | SHA1 | Date | |
---|---|---|---|
96c251c1ca | |||
f2107568f0 |
@ -1,4 +1,4 @@
|
|||||||
use actix_web::{delete, get, HttpResponse, post, Responder, web};
|
use actix_web::{delete, get, HttpResponse, patch, post, Responder, web};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@ -11,14 +11,15 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
|||||||
.service(get_task)
|
.service(get_task)
|
||||||
.service(get_tasks)
|
.service(get_tasks)
|
||||||
.service(create_task)
|
.service(create_task)
|
||||||
.service(delete_task);
|
.service(delete_task)
|
||||||
|
.service(update_task);
|
||||||
|
|
||||||
cfg.service(scope);
|
cfg.service(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/get_tasks")]
|
#[get("/get_tasks")]
|
||||||
pub async fn get_tasks(data: web::Data<AppState>) -> impl Responder {
|
pub async fn get_tasks(data: web::Data<AppState>) -> impl Responder {
|
||||||
let tasks = match db::get_tasks(data.database_url.clone()).await {
|
let tasks = match db::get_tasks(&data.database_url).await {
|
||||||
Ok(tasks) => tasks,
|
Ok(tasks) => tasks,
|
||||||
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
||||||
};
|
};
|
||||||
@ -30,7 +31,7 @@ pub async fn get_tasks(data: web::Data<AppState>) -> impl Responder {
|
|||||||
pub async fn get_task(data: web::Data<AppState>, path: web::Path<Uuid>) -> impl Responder {
|
pub async fn get_task(data: web::Data<AppState>, path: web::Path<Uuid>) -> impl Responder {
|
||||||
let uuid = path.into_inner();
|
let uuid = path.into_inner();
|
||||||
|
|
||||||
let task = match db::get_task(data.database_url.clone(), uuid).await {
|
let task = match db::get_task(&data.database_url, uuid).await {
|
||||||
Ok(task) => task,
|
Ok(task) => task,
|
||||||
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
||||||
};
|
};
|
||||||
@ -39,25 +40,20 @@ pub async fn get_task(data: web::Data<AppState>, path: web::Path<Uuid>) -> impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct JsonTask {
|
pub struct JsonNewTask {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub due_date: NaiveDateTime,
|
pub due_date: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/create_task")]
|
#[post("/create_task")]
|
||||||
pub async fn create_task(data: web::Data<AppState>, task: web::Json<JsonTask>) -> impl Responder {
|
pub async fn create_task(
|
||||||
let uuid = Uuid::now_v7();
|
data: web::Data<AppState>,
|
||||||
|
task: web::Json<JsonNewTask>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let task = task.into_inner();
|
||||||
|
|
||||||
let new_task = match db::create_task(
|
let new_task = match db::create_task(&data.database_url, task).await {
|
||||||
data.database_url.clone(),
|
|
||||||
uuid,
|
|
||||||
&task.title,
|
|
||||||
&task.description,
|
|
||||||
task.due_date,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(task) => task,
|
Ok(task) => task,
|
||||||
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
||||||
};
|
};
|
||||||
@ -69,7 +65,7 @@ pub async fn create_task(data: web::Data<AppState>, task: web::Json<JsonTask>) -
|
|||||||
pub async fn delete_task(data: web::Data<AppState>, path: web::Path<Uuid>) -> impl Responder {
|
pub async fn delete_task(data: web::Data<AppState>, path: web::Path<Uuid>) -> impl Responder {
|
||||||
let uuid = path.into_inner();
|
let uuid = path.into_inner();
|
||||||
|
|
||||||
let result = match db::delete_task(data.database_url.clone(), uuid).await {
|
let result = match db::delete_task(&data.database_url, uuid).await {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
||||||
};
|
};
|
||||||
@ -80,3 +76,26 @@ pub async fn delete_task(data: web::Data<AppState>, path: web::Path<Uuid>) -> im
|
|||||||
HttpResponse::NotFound().body("Unable to delete. Not found.")
|
HttpResponse::NotFound().body("Unable to delete. Not found.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct JsonPatchTask {
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub complete: Option<bool>,
|
||||||
|
pub due_date: Option<NaiveDateTime>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[patch("/update_task/{uuid}")]
|
||||||
|
pub async fn update_task(
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
path: web::Path<Uuid>,
|
||||||
|
new_values: web::Json<JsonPatchTask>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let new_values = new_values.into_inner();
|
||||||
|
let uuid = path.into_inner();
|
||||||
|
|
||||||
|
match db::update_task(&data.database_url, uuid, new_values).await {
|
||||||
|
Ok(task) => HttpResponse::Ok().json(task),
|
||||||
|
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
use std::error;
|
use std::error;
|
||||||
|
|
||||||
use chrono::NaiveDateTime;
|
|
||||||
use diesel::{
|
use diesel::{
|
||||||
Connection, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, SelectableHelper,
|
Connection, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, SelectableHelper,
|
||||||
};
|
};
|
||||||
@ -13,6 +12,7 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
use models::Task;
|
use models::Task;
|
||||||
|
|
||||||
|
use crate::api::v1::{JsonNewTask, JsonPatchTask};
|
||||||
use crate::db::models::NewTask;
|
use crate::db::models::NewTask;
|
||||||
use crate::schema;
|
use crate::schema;
|
||||||
|
|
||||||
@ -20,8 +20,8 @@ pub mod models;
|
|||||||
|
|
||||||
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations");
|
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations");
|
||||||
|
|
||||||
pub fn establish_connection(database_url: &String) -> Result<PgConnection, Box<dyn error::Error>> {
|
pub fn establish_connection(database_url: &str) -> Result<PgConnection, Box<dyn error::Error>> {
|
||||||
Ok(PgConnection::establish(&database_url)?)
|
Ok(PgConnection::establish(database_url)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_migrations(
|
pub fn run_migrations(
|
||||||
@ -32,36 +32,33 @@ pub fn run_migrations(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_tasks(database_url: String) -> Result<Vec<Task>, Box<dyn error::Error>> {
|
pub async fn get_tasks(database_url: &str) -> Result<Vec<Task>, Box<dyn error::Error>> {
|
||||||
use schema::tasks::dsl::*;
|
use schema::tasks::dsl::*;
|
||||||
|
|
||||||
let conn = &mut establish_connection(&database_url)?;
|
let conn = &mut establish_connection(database_url)?;
|
||||||
|
|
||||||
Ok(tasks.select(Task::as_select()).load(conn)?)
|
Ok(tasks.select(Task::as_select()).load(conn)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_task(database_url: String, uuid: Uuid) -> Result<Task, Box<dyn error::Error>> {
|
pub async fn get_task(database_url: &str, uuid: Uuid) -> Result<Task, Box<dyn error::Error>> {
|
||||||
use schema::tasks::dsl::*;
|
use schema::tasks::dsl::*;
|
||||||
|
|
||||||
let conn = &mut establish_connection(&database_url)?;
|
let conn = &mut establish_connection(database_url)?;
|
||||||
|
|
||||||
Ok(tasks.find(uuid).select(Task::as_select()).first(conn)?)
|
Ok(tasks.find(uuid).select(Task::as_select()).first(conn)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_task(
|
pub async fn create_task(
|
||||||
database_url: String,
|
database_url: &str,
|
||||||
uuid: Uuid,
|
task: JsonNewTask,
|
||||||
title: &str,
|
|
||||||
description: &str,
|
|
||||||
due_date: NaiveDateTime,
|
|
||||||
) -> Result<Task, Box<dyn error::Error>> {
|
) -> Result<Task, Box<dyn error::Error>> {
|
||||||
let conn = &mut establish_connection(&database_url)?;
|
let conn = &mut establish_connection(database_url)?;
|
||||||
|
|
||||||
let new_task = NewTask {
|
let new_task = NewTask {
|
||||||
id: uuid,
|
id: Uuid::now_v7(),
|
||||||
title,
|
title: &task.title,
|
||||||
description,
|
description: &task.description,
|
||||||
due_date,
|
due_date: task.due_date,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(diesel::insert_into(schema::tasks::table)
|
Ok(diesel::insert_into(schema::tasks::table)
|
||||||
@ -70,10 +67,48 @@ pub async fn create_task(
|
|||||||
.get_result(conn)?)
|
.get_result(conn)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_task(database_url: String, uuid: Uuid) -> Result<usize, Box<dyn error::Error>> {
|
pub async fn delete_task(database_url: &str, uuid: Uuid) -> Result<usize, Box<dyn error::Error>> {
|
||||||
use schema::tasks::dsl::*;
|
use schema::tasks::dsl::*;
|
||||||
|
|
||||||
let conn = &mut establish_connection(&database_url)?;
|
let conn = &mut establish_connection(database_url)?;
|
||||||
|
|
||||||
Ok(diesel::delete(tasks.filter(id.eq(uuid))).execute(conn)?)
|
Ok(diesel::delete(tasks.filter(id.eq(uuid))).execute(conn)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_task(
|
||||||
|
database_url: &str,
|
||||||
|
uuid: Uuid,
|
||||||
|
new_values: JsonPatchTask,
|
||||||
|
) -> Result<Task, Box<dyn error::Error>> {
|
||||||
|
use schema::tasks::dsl::*;
|
||||||
|
|
||||||
|
let conn = &mut establish_connection(database_url)?;
|
||||||
|
|
||||||
|
let mut current_task = get_task(database_url, uuid).await?;
|
||||||
|
|
||||||
|
if let Some(new_title) = new_values.title {
|
||||||
|
current_task.title = new_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(new_description) = new_values.description {
|
||||||
|
current_task.description = new_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(new_complete) = new_values.complete {
|
||||||
|
current_task.complete = new_complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(new_due_date) = new_values.due_date {
|
||||||
|
current_task.due_date = new_due_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(diesel::update(tasks.find(uuid))
|
||||||
|
.set((
|
||||||
|
title.eq(current_task.title),
|
||||||
|
description.eq(current_task.description),
|
||||||
|
complete.eq(current_task.complete),
|
||||||
|
due_date.eq(current_task.due_date),
|
||||||
|
))
|
||||||
|
.returning(Task::as_returning())
|
||||||
|
.get_result(conn)?)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user