schema: make user fields non-nullable

They can always be empty. This simplifies mutation, since graphql_client
doesn't have an easy way to conditionally leave out fields (we could do
that with `@include`, but that's one bool per field in addition to the
field, a bit ugly).
This commit is contained in:
Valentin Tolmer 2021-09-01 09:59:01 +02:00 committed by nitnelave
parent 564c09d6ab
commit 0ac9e134de
8 changed files with 41 additions and 40 deletions

View File

@ -91,9 +91,9 @@ impl Component for UserDetails {
<div> <div>
<div>{"User ID: "} {&u.id}</div> <div>{"User ID: "} {&u.id}</div>
<div>{"Email: "}{&u.email}</div> <div>{"Email: "}{&u.email}</div>
<div>{"Display name: "}{&u.display_name.as_ref().unwrap_or(&String::new())}</div> <div>{"Display name: "}{&u.display_name}</div>
<div>{"First name: "}{&u.first_name.as_ref().unwrap_or(&String::new())}</div> <div>{"First name: "}{&u.first_name}</div>
<div>{"Last name: "}{&u.last_name.as_ref().unwrap_or(&String::new())}</div> <div>{"Last name: "}{&u.last_name}</div>
<div>{"Creation date: "}{&u.creation_date.with_timezone(&chrono::Local)}</div> <div>{"Creation date: "}{&u.creation_date.with_timezone(&chrono::Local)}</div>
</div> </div>
} }

View File

@ -82,9 +82,9 @@ impl Component for UserTable {
<tr> <tr>
<td>{&user.id}</td> <td>{&user.id}</td>
<td>{&user.email}</td> <td>{&user.email}</td>
<td>{&user.display_name.as_ref().unwrap_or(&String::new())}</td> <td>{&user.display_name}</td>
<td>{&user.first_name.as_ref().unwrap_or(&String::new())}</td> <td>{&user.first_name}</td>
<td>{&user.last_name.as_ref().unwrap_or(&String::new())}</td> <td>{&user.last_name}</td>
<td>{&user.creation_date.with_timezone(&chrono::Local)}</td> <td>{&user.creation_date.with_timezone(&chrono::Local)}</td>
</tr> </tr>
} }

View File

@ -45,9 +45,9 @@ type Query {
type User { type User {
id: String! id: String!
email: String! email: String!
displayName: String displayName: String!
firstName: String firstName: String!
lastName: String lastName: String!
creationDate: DateTimeUtc! creationDate: DateTimeUtc!
"The groups to which this user belongs." "The groups to which this user belongs."
groups: [Group!]! groups: [Group!]!

View File

@ -8,9 +8,9 @@ use std::collections::HashSet;
pub struct User { pub struct User {
pub user_id: String, pub user_id: String,
pub email: String, pub email: String,
pub display_name: Option<String>, pub display_name: String,
pub first_name: Option<String>, pub first_name: String,
pub last_name: Option<String>, pub last_name: String,
// pub avatar: ?, // pub avatar: ?,
pub creation_date: chrono::DateTime<chrono::Utc>, pub creation_date: chrono::DateTime<chrono::Utc>,
} }
@ -21,9 +21,9 @@ impl Default for User {
User { User {
user_id: String::new(), user_id: String::new(),
email: String::new(), email: String::new(),
display_name: None, display_name: String::new(),
first_name: None, first_name: String::new(),
last_name: None, last_name: String::new(),
creation_date: chrono::Utc.timestamp(0, 0), creation_date: chrono::Utc.timestamp(0, 0),
} }
} }

View File

@ -3,7 +3,7 @@ use crate::infra::configuration::Configuration;
use async_trait::async_trait; use async_trait::async_trait;
use futures_util::StreamExt; use futures_util::StreamExt;
use futures_util::TryStreamExt; use futures_util::TryStreamExt;
use sea_query::{Expr, Iden, Order, Query, SimpleExpr, Value}; use sea_query::{Expr, Iden, Order, Query, SimpleExpr};
use sqlx::Row; use sqlx::Row;
use std::collections::HashSet; use std::collections::HashSet;
@ -179,9 +179,9 @@ impl BackendHandler for SqlBackendHandler {
let values = vec![ let values = vec![
request.user_id.clone().into(), request.user_id.clone().into(),
request.email.into(), request.email.into(),
request.display_name.map(Into::into).unwrap_or(Value::Null), request.display_name.unwrap_or_default().into(),
request.first_name.map(Into::into).unwrap_or(Value::Null), request.first_name.unwrap_or_default().into(),
request.last_name.map(Into::into).unwrap_or(Value::Null), request.last_name.unwrap_or_default().into(),
chrono::Utc::now().naive_utc().into(), chrono::Utc::now().naive_utc().into(),
]; ];
let query = Query::insert() let query = Query::insert()

View File

@ -49,9 +49,13 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
.primary_key(), .primary_key(),
) )
.col(ColumnDef::new(Users::Email).string_len(255).not_null()) .col(ColumnDef::new(Users::Email).string_len(255).not_null())
.col(ColumnDef::new(Users::DisplayName).string_len(255)) .col(
.col(ColumnDef::new(Users::FirstName).string_len(255)) ColumnDef::new(Users::DisplayName)
.col(ColumnDef::new(Users::LastName).string_len(255)) .string_len(255)
.not_null(),
)
.col(ColumnDef::new(Users::FirstName).string_len(255).not_null())
.col(ColumnDef::new(Users::LastName).string_len(255).not_null())
.col(ColumnDef::new(Users::Avatar).binary()) .col(ColumnDef::new(Users::Avatar).binary())
.col(ColumnDef::new(Users::CreationDate).date_time().not_null()) .col(ColumnDef::new(Users::CreationDate).date_time().not_null())
.col(ColumnDef::new(Users::PasswordHash).binary()) .col(ColumnDef::new(Users::PasswordHash).binary())

View File

@ -141,16 +141,16 @@ impl<Handler: BackendHandler + Sync> User<Handler> {
&self.user.email &self.user.email
} }
fn display_name(&self) -> Option<&String> { fn display_name(&self) -> &str {
self.user.display_name.as_ref() &self.user.display_name
} }
fn first_name(&self) -> Option<&String> { fn first_name(&self) -> &str {
self.user.first_name.as_ref() &self.user.first_name
} }
fn last_name(&self) -> Option<&String> { fn last_name(&self) -> &str {
self.user.last_name.as_ref() &self.user.last_name
} }
fn creation_date(&self) -> chrono::DateTime<chrono::Utc> { fn creation_date(&self) -> chrono::DateTime<chrono::Utc> {

View File

@ -69,12 +69,9 @@ fn get_attribute(user: &User, attribute: &str) -> Result<Vec<String>> {
]), ]),
"uid" => Ok(vec![user.user_id.clone()]), "uid" => Ok(vec![user.user_id.clone()]),
"mail" => Ok(vec![user.email.clone()]), "mail" => Ok(vec![user.email.clone()]),
"givenName" => Ok(vec![user.first_name.clone().unwrap_or_default()]), "givenName" => Ok(vec![user.first_name.clone()]),
"sn" => Ok(vec![user.last_name.clone().unwrap_or_default()]), "sn" => Ok(vec![user.last_name.clone()]),
"cn" => Ok(vec![user "cn" => Ok(vec![user.display_name.clone()]),
.display_name
.clone()
.unwrap_or_else(|| user.user_id.clone())]),
_ => bail!("Unsupported attribute: {}", attribute), _ => bail!("Unsupported attribute: {}", attribute),
} }
} }
@ -479,17 +476,17 @@ mod tests {
User { User {
user_id: "bob_1".to_string(), user_id: "bob_1".to_string(),
email: "bob@bobmail.bob".to_string(), email: "bob@bobmail.bob".to_string(),
display_name: Some("Bôb Böbberson".to_string()), display_name: "Bôb Böbberson".to_string(),
first_name: Some("Bôb".to_string()), first_name: "Bôb".to_string(),
last_name: Some("Böbberson".to_string()), last_name: "Böbberson".to_string(),
..Default::default() ..Default::default()
}, },
User { User {
user_id: "jim".to_string(), user_id: "jim".to_string(),
email: "jim@cricket.jim".to_string(), email: "jim@cricket.jim".to_string(),
display_name: Some("Jimminy Cricket".to_string()), display_name: "Jimminy Cricket".to_string(),
first_name: Some("Jim".to_string()), first_name: "Jim".to_string(),
last_name: Some("Cricket".to_string()), last_name: "Cricket".to_string(),
..Default::default() ..Default::default()
}, },
]) ])