From 42a577fbf1d4ba97daa22ebde2a5da8485e9a36a Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Fri, 15 May 2020 17:41:50 +0200
Subject: [PATCH] Improve schema

---
 Cargo.lock                                    | 249 ++++++++++++++++++
 Cargo.toml                                    |   1 +
 .../down.sql                                  |   1 +
 .../2020-05-14-213742_create_database/up.sql  |  18 +-
 schema.graphql                                | 131 +++++++++
 src/models.rs                                 |  22 +-
 src/schema.rs                                 |  18 +-
 7 files changed, 411 insertions(+), 29 deletions(-)
 create mode 100644 schema.graphql

diff --git a/Cargo.lock b/Cargo.lock
index dbb383c..11b5f46 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+[[package]]
+name = "addr2line"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456d75cbb82da1ad150c8a9d97285ffcd21c9931dcb11e995903e7d75141b38b"
+dependencies = [
+ "gimli",
+]
+
 [[package]]
 name = "aho-corasick"
 version = "0.7.10"
@@ -15,6 +24,12 @@ version = "1.0.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
 
+[[package]]
+name = "ascii"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e"
+
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -32,6 +47,32 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
 
+[[package]]
+name = "backtrace"
+version = "0.3.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130"
+dependencies = [
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "bae"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "637d592da18c2fec0ad380a3e1cdcb4fe195fa1cb6dc02e92faa720227cab91e"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+]
+
 [[package]]
 name = "base64"
 version = "0.9.3"
@@ -86,6 +127,30 @@ dependencies = [
  "time",
 ]
 
+[[package]]
+name = "colored"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
+dependencies = [
+ "atty",
+ "lazy_static",
+ "winapi",
+]
+
+[[package]]
+name = "combine"
+version = "3.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
+dependencies = [
+ "ascii",
+ "byteorder",
+ "either",
+ "memchr",
+ "unreachable",
+]
+
 [[package]]
 name = "cookie"
 version = "0.11.2"
@@ -161,6 +226,12 @@ version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
 
+[[package]]
+name = "either"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
+
 [[package]]
 name = "env_logger"
 version = "0.7.1"
@@ -174,6 +245,28 @@ dependencies = [
  "termcolor",
 ]
 
+[[package]]
+name = "failure"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
+dependencies = [
+ "backtrace",
+ "failure_derive",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
+dependencies = [
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+ "synstructure",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -275,12 +368,37 @@ dependencies = [
  "slab",
 ]
 
+[[package]]
+name = "gimli"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
+
 [[package]]
 name = "glob"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
+[[package]]
+name = "graphql-parser"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5613c31f18676f164112732202124f373bb2103ff017b3b85ca954ea6a66ada"
+dependencies = [
+ "combine",
+ "failure",
+]
+
+[[package]]
+name = "heck"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+dependencies = [
+ "unicode-segmentation",
+]
+
 [[package]]
 name = "hermit-abi"
 version = "0.1.12"
@@ -378,6 +496,54 @@ dependencies = [
  "uuid",
 ]
 
+[[package]]
+name = "juniper-eager-loading"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4552bb2ddf449154e9cc69923ba907253db8d85647fc7c73f423f43c96c973d"
+dependencies = [
+ "juniper-eager-loading-code-gen",
+ "juniper-from-schema",
+]
+
+[[package]]
+name = "juniper-eager-loading-code-gen"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51fa21518f17f29fc8da741571dbeb8a51bbde4eaccb99ac57bab60eb3506051"
+dependencies = [
+ "bae",
+ "heck",
+ "proc-macro-error",
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+]
+
+[[package]]
+name = "juniper-from-schema"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc6f3fb3b8c143a963725b5d82d206d4822b98e4c2b739ecaf5e04d8cbe8f0c"
+dependencies = [
+ "juniper",
+ "juniper-from-schema-code-gen",
+]
+
+[[package]]
+name = "juniper-from-schema-code-gen"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca83b4fd2f19063d5744e7b39ff541996efa21d8b48e35a52ee0237c4bb57e9b"
+dependencies = [
+ "colored",
+ "graphql-parser",
+ "heck",
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+]
+
 [[package]]
 name = "juniper_codegen"
 version = "0.14.2"
@@ -455,6 +621,7 @@ dependencies = [
  "env_logger",
  "futures",
  "juniper",
+ "juniper-eager-loading",
  "juniper_rocket",
  "rocket",
  "serde",
@@ -507,6 +674,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "object"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
+
 [[package]]
 name = "once_cell"
 version = "1.4.0"
@@ -582,6 +755,32 @@ dependencies = [
  "vcpkg",
 ]
 
+[[package]]
+name = "proc-macro-error"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+ "version_check 0.9.1",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
+dependencies = [
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+ "syn-mid",
+ "version_check 0.9.1",
+]
+
 [[package]]
 name = "proc-macro-hack"
 version = "0.5.15"
@@ -719,6 +918,12 @@ dependencies = [
  "unicode-xid 0.1.0",
 ]
 
+[[package]]
+name = "rustc-demangle"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
+
 [[package]]
 name = "ryu"
 version = "1.0.4"
@@ -799,6 +1004,29 @@ dependencies = [
  "unicode-xid 0.2.0",
 ]
 
+[[package]]
+name = "syn-mid"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
+dependencies = [
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
+dependencies = [
+ "proc-macro2 1.0.12",
+ "quote 1.0.5",
+ "syn 1.0.21",
+ "unicode-xid 0.2.0",
+]
+
 [[package]]
 name = "termcolor"
 version = "1.1.0"
@@ -875,6 +1103,12 @@ dependencies = [
  "smallvec",
 ]
 
+[[package]]
+name = "unicode-segmentation"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
+
 [[package]]
 name = "unicode-xid"
 version = "0.1.0"
@@ -887,6 +1121,15 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
 
+[[package]]
+name = "unreachable"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
+dependencies = [
+ "void",
+]
+
 [[package]]
 name = "untrusted"
 version = "0.6.2"
@@ -939,6 +1182,12 @@ version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
 
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
 [[package]]
 name = "winapi"
 version = "0.3.8"
diff --git a/Cargo.toml b/Cargo.toml
index b796629..225db9d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,3 +20,4 @@ serde = "1.0.110"
 serde_derive = "1.0.110"
 serde_json = "1.0.53"
 anyhow = "1.0.30"
+juniper-eager-loading = "0.5.1"
\ No newline at end of file
diff --git a/migrations/2020-05-14-213742_create_database/down.sql b/migrations/2020-05-14-213742_create_database/down.sql
index d0cdad3..c06d890 100644
--- a/migrations/2020-05-14-213742_create_database/down.sql
+++ b/migrations/2020-05-14-213742_create_database/down.sql
@@ -1,3 +1,4 @@
+alter table titles drop constraint title_parent_id_fkey;
 drop table title_subtitles;
 drop table title_ratings;
 drop table title_names;
diff --git a/migrations/2020-05-14-213742_create_database/up.sql b/migrations/2020-05-14-213742_create_database/up.sql
index 076a9df..78e0081 100644
--- a/migrations/2020-05-14-213742_create_database/up.sql
+++ b/migrations/2020-05-14-213742_create_database/up.sql
@@ -44,7 +44,7 @@ create table if not exists title_casts
 			primary key,
 	category text,
 	characters text [] not null,
-	job text,
+	credit text,
 	created_at timestamp with time zone not null,
 	updated_at timestamp with time zone not null,
 	title_id uuid not null
@@ -130,9 +130,9 @@ create table if not exists title_images
 	id uuid not null
 		constraint title_images_pkey
 			primary key,
-	kind text,
-	mime text,
-	src text,
+	kind text not null,
+	mime text not null,
+	src text not null,
 	created_at timestamp with time zone not null,
 	updated_at timestamp with time zone not null,
 	title_id uuid not null
@@ -147,10 +147,10 @@ create table if not exists title_media
 	id uuid not null
 		constraint title_media_pkey
 			primary key,
-	mime text,
+	mime text not null,
 	codecs text [] not null,
 	languages text [] not null,
-	src text,
+	src text not null,
 	created_at timestamp with time zone not null,
 	updated_at timestamp with time zone not null,
 	title_id uuid not null
@@ -184,7 +184,7 @@ create table if not exists title_ratings
 		constraint title_ratings_pkey
 			primary key,
 	region text,
-	certification text,
+	certification text not null,
 	created_at timestamp with time zone not null,
 	updated_at timestamp with time zone not null,
 	title_id uuid not null
@@ -199,11 +199,11 @@ create table if not exists title_subtitles
 	id uuid not null
 		constraint title_subtitles_pkey
 			primary key,
-	format text,
+	format text not null,
 	language text,
 	region text,
 	specifier text,
-	src text,
+	src text not null,
 	created_at timestamp with time zone not null,
 	updated_at timestamp with time zone not null,
 	title_id uuid not null
diff --git a/schema.graphql b/schema.graphql
new file mode 100644
index 0000000..1b2084a
--- /dev/null
+++ b/schema.graphql
@@ -0,0 +1,131 @@
+schema {
+    query: Query
+}
+
+type Query {
+    apiVersion: String!
+
+    genres(id: ID = null, limit: Int = null, offset: Int = null): [Genre!]!
+    people(id: ID = null, limit: Int = null, offset: Int = null): [Person!]!
+    titles(id: ID = null, limit: Int = null, offset: Int = null): [Title!]!
+}
+
+type Genre {
+    id: ID!
+    tmdbId: Int
+    name: String!
+
+    titles(limit: Int = null, offset: Int = null): [Title!]!
+}
+
+type Person {
+    id: ID!
+    imdbId: ID
+    name: String!
+
+    starring(limit: Int = null, offset: Int = null): [Title!]!
+}
+
+type Cast {
+    id: ID!
+    category: String
+    characters: [String!]!
+    credit: String
+
+    title: Title
+    person: Person
+}
+
+type Description {
+    id: ID!
+    region: String
+    languages: [String!]!
+    kind: LocalizedKind!
+    overview: String!
+    tagline: String
+}
+
+type ShowEpisode {
+    id: ID!
+    seasonNumber: String
+    episodeNumber: String
+    airDate: Date
+
+    show: Title
+    episode: Title
+}
+
+type Image {
+    id: ID!
+    kind: ImageKind!
+    mime: String!
+    src: String!
+}
+
+type Media {
+    id: ID!
+    mime: String
+    codecs: [String!]!
+    languages: [String!]!
+    src: String!
+}
+
+type Name {
+    id: ID!
+    region: String
+    languages: [String!]!
+    kind: LocalizedKind!
+    name: String!
+}
+
+type Rating {
+    id: ID!
+    region: String
+    certification: String!
+}
+
+type Subtitle {
+    id: ID!
+    format: String!
+    language: String
+    region: String
+    specifier: String
+    src: String!
+}
+
+type Title {
+    id: ID!
+    imdbId: String
+    tmdbId: Int
+    tvdbId: Int
+    originalLanguage: String
+    runtime: Int
+    yearStart: Int
+    yearEnd: Int
+
+    cast(limit: Int = null, offset: Int = null): [Cast!]!
+    descriptions(region: String = null, language: String = null, limit: Int = null, offset: Int = null): [Description!]!
+    genres: [Genre!]!
+    image: [Image!]!
+    media: [Media!]!
+    names(region: String = null, language: String = null, limit: Int = null, offset: Int = null): [Name!]!
+    ratings(region: String = null, limit: Int = null, offset: Int = null): [Rating!]!
+    subtitles: [Subtitle!]!
+    episodes(seasonNumber: Int = null, episodeNumber: Int = null, limit: Int = null, offset: Int = null): [ShowEpisode!]!
+    show: ShowEpisode
+}
+
+scalar Date
+
+enum ImageKind {
+    still
+    backdrop
+    poster
+    logo
+}
+
+enum LocalizedKind {
+    primary
+    original
+    localized
+}
\ No newline at end of file
diff --git a/src/models.rs b/src/models.rs
index 94835c3..4bab9da 100644
--- a/src/models.rs
+++ b/src/models.rs
@@ -176,7 +176,7 @@ pub struct TitleCast {
     pub id: uuid::Uuid,
     pub category: Option<String>,
     pub characters: Vec<String>,
-    pub job: Option<String>,
+    pub credit: Option<String>,
     pub created_at: chrono::DateTime<chrono::Utc>,
     pub updated_at: chrono::DateTime<chrono::Utc>,
     pub title_id: uuid::Uuid,
@@ -194,8 +194,8 @@ impl TitleCast {
     pub fn characters(&self) -> Vec<String> {
         self.characters.clone()
     }
-    pub fn job(&self) -> Option<String> {
-        self.job.clone()
+    pub fn credit(&self) -> Option<String> {
+        self.credit.clone()
     }
 
     pub fn title(&self, context: &Context) -> FieldResult<Title> {
@@ -279,9 +279,9 @@ pub struct TitleGenre {
 #[table_name = "title_images"]
 pub struct TitleImage {
     pub id: uuid::Uuid,
-    pub kind: Option<String>,
-    pub mime: Option<String>,
-    pub src: Option<String>,
+    pub kind: String,
+    pub mime: String,
+    pub src: String,
     pub created_at: chrono::DateTime<chrono::Utc>,
     pub updated_at: chrono::DateTime<chrono::Utc>,
     pub title_id: uuid::Uuid,
@@ -292,10 +292,10 @@ pub struct TitleImage {
 #[table_name = "title_media"]
 pub struct TitleMedium {
     pub id: uuid::Uuid,
-    pub mime: Option<String>,
+    pub mime: String,
     pub codecs: Vec<String>,
     pub languages: Vec<String>,
-    pub src: Option<String>,
+    pub src: String,
     pub created_at: chrono::DateTime<chrono::Utc>,
     pub updated_at: chrono::DateTime<chrono::Utc>,
     pub title_id: uuid::Uuid,
@@ -321,7 +321,7 @@ pub struct TitleName {
 pub struct TitleRating {
     pub id: uuid::Uuid,
     pub region: Option<String>,
-    pub certification: Option<String>,
+    pub certification: String,
     pub created_at: chrono::DateTime<chrono::Utc>,
     pub updated_at: chrono::DateTime<chrono::Utc>,
     pub title_id: uuid::Uuid,
@@ -332,11 +332,11 @@ pub struct TitleRating {
 #[table_name = "title_subtitles"]
 pub struct TitleSubtitle {
     pub id: uuid::Uuid,
-    pub format: Option<String>,
+    pub format: String,
     pub language: Option<String>,
     pub region: Option<String>,
     pub specifier: Option<String>,
-    pub src: Option<String>,
+    pub src: String,
     pub created_at: chrono::DateTime<chrono::Utc>,
     pub updated_at: chrono::DateTime<chrono::Utc>,
     pub title_id: uuid::Uuid,
diff --git a/src/schema.rs b/src/schema.rs
index bfeff64..dd10781 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -23,7 +23,7 @@ table! {
         id -> Uuid,
         category -> Nullable<Text>,
         characters -> Array<Text>,
-        job -> Nullable<Text>,
+        credit -> Nullable<Text>,
         created_at -> Timestamptz,
         updated_at -> Timestamptz,
         title_id -> Uuid,
@@ -70,9 +70,9 @@ table! {
 table! {
     title_images (id) {
         id -> Uuid,
-        kind -> Nullable<Text>,
-        mime -> Nullable<Text>,
-        src -> Nullable<Text>,
+        kind -> Text,
+        mime -> Text,
+        src -> Text,
         created_at -> Timestamptz,
         updated_at -> Timestamptz,
         title_id -> Uuid,
@@ -82,10 +82,10 @@ table! {
 table! {
     title_media (id) {
         id -> Uuid,
-        mime -> Nullable<Text>,
+        mime -> Text,
         codecs -> Array<Text>,
         languages -> Array<Text>,
-        src -> Nullable<Text>,
+        src -> Text,
         created_at -> Timestamptz,
         updated_at -> Timestamptz,
         title_id -> Uuid,
@@ -109,7 +109,7 @@ table! {
     title_ratings (id) {
         id -> Uuid,
         region -> Nullable<Text>,
-        certification -> Nullable<Text>,
+        certification -> Text,
         created_at -> Timestamptz,
         updated_at -> Timestamptz,
         title_id -> Uuid,
@@ -119,11 +119,11 @@ table! {
 table! {
     title_subtitles (id) {
         id -> Uuid,
-        format -> Nullable<Text>,
+        format -> Text,
         language -> Nullable<Text>,
         region -> Nullable<Text>,
         specifier -> Nullable<Text>,
-        src -> Nullable<Text>,
+        src -> Text,
         created_at -> Timestamptz,
         updated_at -> Timestamptz,
         title_id -> Uuid,
-- 
GitLab