From 2f5ba16719d381939ace94c5f92214b468f58fd1 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Fri, 25 Sep 2020 02:14:05 +0200
Subject: [PATCH] Created initial solution for loading aggregate data

---
 Cargo.lock    | 15 +++++++++++++++
 Cargo.toml    |  2 +-
 src/main.rs   | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--
 src/models.rs |  4 +---
 src/schema.rs |  1 -
 5 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index c0296eb..3880d50 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -686,6 +686,7 @@ dependencies = [
  "futures",
  "rocket",
  "rocket_contrib",
+ "serde",
  "serde_json",
  "uuid",
 ]
@@ -1181,6 +1182,20 @@ name = "serde"
 version = "1.0.115"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.115"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
+dependencies = [
+ "proc-macro2 1.0.20",
+ "quote 1.0.7",
+ "syn 1.0.39",
+]
 
 [[package]]
 name = "serde_json"
diff --git a/Cargo.toml b/Cargo.toml
index 5eb7773..3e91561 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,7 +25,7 @@ version = "0.4.5"
 default-features = false
 features = ["json", "diesel_postgres_pool"]
 
-[dependencis.serde]
+[dependencies.serde]
 version = "1.0.115"
 features = ["derive"]
 
diff --git a/src/main.rs b/src/main.rs
index 127e81e..cf94f40 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,10 +7,13 @@ extern crate rocket;
 extern crate rocket_contrib;
 
 use diesel::prelude::*;
+use dotenv::dotenv;
+use rocket::http::RawStr;
+use rocket::request::FromParam;
 use rocket_contrib::databases::diesel;
 use rocket_contrib::json::Json;
+use uuid::Uuid;
 
-use dotenv::dotenv;
 use media_backend::models::*;
 
 #[database("mediaflix")]
@@ -24,6 +27,48 @@ fn list_genres(db: MediaflixConnection) -> QueryResult<Json<Vec<Genre>>> {
     Ok(Json(query.load::<Genre>(&db.0)?))
 }
 
+struct ParamUuid(uuid::Uuid);
+
+impl FromParam<'_> for ParamUuid {
+    type Error = uuid::parser::ParseError;
+
+    fn from_param(param: &RawStr) -> Result<Self, Self::Error> {
+        return Ok(ParamUuid(Uuid::parse_str(param.as_str())?));
+    }
+}
+
+
+#[get("/api/v1/genres/<genre>")]
+fn get_genre(db: MediaflixConnection, genre: ParamUuid) -> QueryResult<Json<Vec<((Title, Vec<TitleName>), Vec<TitleRating>)>>> {
+    use media_backend::schema::*;
+    let titles = title_genres::table
+        .filter(title_genres::genre_id.eq(genre.0))
+        .inner_join(titles::table)
+        .select(titles::all_columns)
+        .load::<Title>(&db.0)?;
+    let title_akas = TitleName::belonging_to(&titles)
+        .load::<TitleName>(&db.0)?
+        .grouped_by(&titles);
+    let title_ratings = TitleRating::belonging_to(&titles)
+        .load::<TitleRating>(&db.0)?
+        .grouped_by(&titles);
+    let data = titles.into_iter()
+        .zip(title_akas)
+        .zip(title_ratings)
+        .collect::<Vec<_>>();
+    Ok(Json(data))
+}
+
+
+#[get("/api/v1/titles/<title>")]
+fn get_title(db: MediaflixConnection, title: ParamUuid) -> QueryResult<Json<Title>> {
+    use media_backend::schema::*;
+    let query = titles::table
+        .find(title.0)
+        .into_boxed();
+    Ok(Json(query.first::<Title>(&db.0)?))
+}
+
 fn main() {
     dotenv().ok();
 
@@ -31,7 +76,11 @@ fn main() {
         .attach(MediaflixConnection::fairing())
         .mount(
             "/",
-            rocket::routes![list_genres],
+            rocket::routes![
+                list_genres,
+                get_genre,
+                get_title
+            ],
         )
         .launch();
 }
diff --git a/src/models.rs b/src/models.rs
index bec69a5..6e28154 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -148,8 +148,7 @@ pub struct TitleSubtitle {
     pub title_id: uuid::Uuid,
 }
 
-#[derive(Identifiable, Queryable, Associations, Serialize, Deserialize, PartialEq, Debug)]
-#[belongs_to(TitleEpisode, foreign_key = "parent_id")]
+#[derive(Identifiable, Queryable, Serialize, Deserialize, PartialEq, Debug)]
 #[table_name = "titles"]
 pub struct Title {
     pub id: uuid::Uuid,
@@ -162,5 +161,4 @@ pub struct Title {
     pub year_end: Option<i32>,
     pub created_at: chrono::DateTime<chrono::Utc>,
     pub updated_at: chrono::DateTime<chrono::Utc>,
-    pub parent_id: Option<uuid::Uuid>,
 }
diff --git a/src/schema.rs b/src/schema.rs
index dd10781..3a91dc2 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -142,7 +142,6 @@ table! {
         year_end -> Nullable<Int4>,
         created_at -> Timestamptz,
         updated_at -> Timestamptz,
-        parent_id -> Nullable<Uuid>,
     }
 }
 
-- 
GitLab