From cd32b5cb6466f5597de1818afca868a48830ee00 Mon Sep 17 00:00:00 2001
From: Eemeli <eemeli.o.lehtonen@utu.fi>
Date: Mon, 3 Apr 2023 15:05:23 +0300
Subject: [PATCH] db add_course

---
 crates/back/src/api/course.rs  | 19 +++++++++++++++++++
 crates/back/src/api/courses.rs | 13 +++++++++++--
 crates/back/src/db/any.rs      |  6 +++++-
 crates/back/src/db/mod.rs      |  6 +++++-
 crates/back/src/db/postgres.rs | 18 ++++++++++++++++--
 5 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/crates/back/src/api/course.rs b/crates/back/src/api/course.rs
index cf07e39..64df61d 100644
--- a/crates/back/src/api/course.rs
+++ b/crates/back/src/api/course.rs
@@ -58,6 +58,25 @@ pub struct Course {
     pub points_max: u32,
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
+pub struct NewCourse {
+    /// Uuid for this course
+    #[schema(example = "c52de49c-5dba-4820-bf64-0da20f9f339f")]
+    pub id: Uuid,
+
+    /// Name of the course
+    #[schema(example = "Project IV")]
+    pub name: String,
+
+    /// Description for the course
+    #[schema(example = "Project IV description")]
+    pub description: Option<String>,
+
+    /// Max points for the course
+    #[schema(example = 40)]
+    pub points_max: u32,
+}
+
 //
 
 #[cfg(test)]
diff --git a/crates/back/src/api/courses.rs b/crates/back/src/api/courses.rs
index b85fbf7..1ad10ec 100644
--- a/crates/back/src/api/courses.rs
+++ b/crates/back/src/api/courses.rs
@@ -1,10 +1,12 @@
 use crate::db::Database;
 use actix_web::{
     dev::HttpServiceFactory,
-    web::{self, Data},
+    web::{self, Data, Json},
     HttpResponse,
 };
 
+use super::course::NewCourse;
+
 //
 
 pub fn api() -> impl HttpServiceFactory {
@@ -31,7 +33,14 @@ async fn get(db: Data<Database>) -> HttpResponse {
     }
 }
 
-async fn post() -> HttpResponse {
+/// Add a new course
+#[utoipa::path(
+    post,
+    path = "/api/courses",
+    responses((status = CREATED, description = "Add a new course", body = Uuid)),
+)]
+async fn post(Json(course): Json<NewCourse>) -> HttpResponse {
+    course;
     HttpResponse::Ok().json("aaa")
 }
 
diff --git a/crates/back/src/db/any.rs b/crates/back/src/db/any.rs
index 7c0528f..c731813 100644
--- a/crates/back/src/db/any.rs
+++ b/crates/back/src/db/any.rs
@@ -3,7 +3,7 @@ use std::mem::transmute;
 use super::{embedded, postgres, DbCreateUser, DbError, DbResult, DbUser};
 use crate::{
     api::{
-        course::Course,
+        course::{Course, NewCourse},
         exercise::{Exercise, ExerciseDetail, ExerciseVerifyData},
         lesson::Lesson,
     },
@@ -147,6 +147,10 @@ impl AnyDatabase {
         gen_match!(self, get_courses())
     }
 
+    pub async fn add_course(&self, course: NewCourse) -> DbResult<()> {
+        gen_match!(self, add_course(course))
+    }
+
     pub async fn get_lessons(&self, course: Uuid) -> DbResult<Vec<Lesson>> {
         gen_match!(self, get_lessons(course))
     }
diff --git a/crates/back/src/db/mod.rs b/crates/back/src/db/mod.rs
index 1d9bb92..eb61bb1 100644
--- a/crates/back/src/db/mod.rs
+++ b/crates/back/src/db/mod.rs
@@ -1,7 +1,7 @@
 use self::any::AnyDatabase;
 use crate::{
     api::{
-        course::Course,
+        course::{Course, NewCourse},
         exercise::{Exercise, ExerciseDetail, ExerciseVerifyData},
         lesson::Lesson,
     },
@@ -82,6 +82,10 @@ impl Database {
         self.db().await.get_courses().await
     }
 
+    pub async fn add_course(&self, course: NewCourse) -> DbResult<()> {
+        self.db().await.add_course(course).await
+    }
+
     pub async fn get_lessons(&self, course: Uuid) -> DbResult<Vec<Lesson>> {
         self.db().await.get_lessons(course).await
     }
diff --git a/crates/back/src/db/postgres.rs b/crates/back/src/db/postgres.rs
index a00d642..57a2f63 100644
--- a/crates/back/src/db/postgres.rs
+++ b/crates/back/src/db/postgres.rs
@@ -1,6 +1,6 @@
 use super::{DbCreateUser, DbError, DbResult, DbUser};
 use crate::api::{
-    course::Course,
+    course::{Course, NewCourse},
     exercise::{Exercise, ExerciseDetail, ExerciseVerifyData},
     lesson::Lesson,
 };
@@ -53,6 +53,20 @@ impl Database {
         .collect())
     }
 
+    pub async fn add_course(&self, course: NewCourse) -> DbResult<Uuid> {
+        Ok(sqlx::query_as::<_, (Uuid,)>(
+            r#"INSERT INTO
+                 courses (name, description, points_max)
+               VALUES
+                 ($1, $2, $3)
+               RETURNING
+                 id"#,
+        )
+        .fetch_one(&self.pool)
+        .await?
+        .0)
+    }
+
     pub async fn get_lessons(&self, course: Uuid) -> DbResult<Vec<Lesson>> {
         Ok(sqlx::query_as(
             r#"SELECT
@@ -165,7 +179,7 @@ impl Database {
             r#"INSERT INTO
                  users (username, password)
                VALUES
-                 ($2, $3);
+                 ($2, $3)
                ON CONFLICT
                  DO NOTHING
                RETURNING
-- 
GitLab