Almost no unwraps !
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Lucien Cartier-Tilet 2023-01-16 00:48:09 +01:00
parent dcaa920c51
commit d0a40b7ed8
Signed by: phundrak
GPG Key ID: BD7789E705CB8DCA
4 changed files with 97 additions and 41 deletions

View File

@ -1,6 +1,9 @@
use crate::{db::Database, graphql::Context};
use crate::{
db::{Database, DatabaseError},
graphql::Context,
};
use diesel::prelude::*;
use juniper::GraphQLEnum;
use juniper::{FieldResult, GraphQLEnum};
use tracing::info;
use uuid::Uuid;
@ -8,6 +11,8 @@ use uuid::Uuid;
use super::super::schema;
use super::users::User;
use std::convert::Into;
use schema::{langandagents, langtranslatesto, languages};
#[derive(
@ -65,14 +70,22 @@ impl Language {
&self,
db: &Database,
relationship: AgentLanguageRelation,
) -> Vec<User> {
) -> Result<Vec<User>, DatabaseError> {
use schema::langandagents::dsl;
match &mut db.conn() {
Ok(conn) => dsl::langandagents
Ok(conn) => Ok(dsl::langandagents
.filter(dsl::language.eq(self.id))
.filter(dsl::relationship.eq(relationship))
.load::<LangAndAgent>(conn)
.unwrap()
.map_err(|e| {
DatabaseError::new(
format!(
"Failed to retrieve language relationship: {:?}",
e
),
"Database reading error",
)
})?
.iter()
.map(|v| {
use schema::users::dsl;
@ -89,7 +102,7 @@ impl Language {
None
}
})
.collect::<Vec<User>>(),
.collect::<Vec<User>>()),
Err(e) => {
panic!("Could not connect to the database: {:?}", e);
}
@ -125,23 +138,32 @@ impl Language {
name = "targetLanguage",
description = "Languages in which the current language is translated"
)]
fn target_language(&self, context: &Context) -> Vec<Language> {
fn target_language(&self, context: &Context) -> FieldResult<Vec<Language>> {
use schema::langtranslatesto::dsl;
match &mut context.db.conn() {
Ok(conn) => dsl::langtranslatesto
Ok(conn) => Ok(dsl::langtranslatesto
.filter(dsl::langfrom.eq(self.id))
.load::<LangTranslatesTo>(conn)
.unwrap()
.map_err(|e| {
DatabaseError::new(
format!(
"Failed to retrieve language translations: {:?}",
e
),
"Database reading failure",
)
})?
.into_iter()
.flat_map(|l| {
use schema::languages::dsl;
dsl::languages.find(l.langto).first::<Language>(conn)
})
.collect::<Vec<Language>>(),
Err(e) => {
info!("Failed to connect to the database: {:?}", e);
Vec::new()
}
.collect::<Vec<Language>>()),
Err(e) => Err(DatabaseError::new(
format!("Failed to connect to the database: {:?}", e),
"Database connection failure",
)
.into()),
}
}
@ -187,34 +209,43 @@ impl Language {
#[graphql(
description = "User with administrative rights over the language"
)]
fn owner(&self, context: &Context) -> User {
fn owner(&self, context: &Context) -> FieldResult<User> {
use schema::users::dsl;
match &mut context.db.conn() {
Ok(conn) => dsl::users
Ok(conn) => Ok(dsl::users
.find(self.owner.clone())
.first::<User>(conn)
.unwrap_or_else(|e| {
panic!(
"Failed to retrieve owner {} of language {}: {:?}",
self.owner, self.name, e
.map_err(|e| {
DatabaseError::new(
format!(
"Failed to retrieve owner {} of language {}: {:?}",
self.owner, self.name, e
),
"Database reading error",
)
}),
Err(e) => panic!("Failed to connect to the database: {:?}", e),
})?),
Err(e) => Err(DatabaseError::new(
format!("Failed to connect to the database: {:?}", e),
"Database connection failure",
)
.into()),
}
}
#[graphql(
description = "People who participate in the elaboration of the language's dictionary"
)]
fn authors(&self, context: &Context) -> Vec<User> {
fn authors(&self, context: &Context) -> FieldResult<Vec<User>> {
self.relationship(&context.db, AgentLanguageRelation::Author)
.map_err(Into::into)
}
#[graphql(
description = "People who can and do redistribute the language's dictionary"
)]
fn publishers(&self, context: &Context) -> Vec<User> {
fn publishers(&self, context: &Context) -> FieldResult<Vec<User>> {
self.relationship(&context.db, AgentLanguageRelation::Publisher)
.map_err(Into::into)
}
}

View File

@ -1,3 +1,3 @@
pub mod users;
pub mod languages;
pub mod users;
pub mod words;

View File

@ -1,7 +1,9 @@
use super::super::schema::{userfollows, users};
use diesel::prelude::*;
use juniper::FieldResult;
use tracing::debug;
use crate::graphql::Context;
use crate::{db::DatabaseError, graphql::Context};
#[derive(Queryable, Insertable, Debug, Clone, PartialEq, Eq)]
pub struct User {
@ -22,21 +24,45 @@ impl User {
}
#[graphql(description = "Who the user follows")]
pub fn following(&self, context: &Context) -> Vec<User> {
pub fn following(&self, context: &Context) -> FieldResult<Vec<User>> {
use super::super::schema::{userfollows, users};
let conn = &mut context.db.conn().unwrap();
userfollows::dsl::userfollows
let conn = &mut context.db.conn().map_err(|e| {
DatabaseError::new(
format!("Failed to connect to database: {:?}", e),
"Database connection error",
)
})?;
Ok(userfollows::dsl::userfollows
.filter(userfollows::dsl::follower.eq(self.id.clone()))
.load::<UserFollow>(conn)
.unwrap()
.iter()
.map(|f| {
users::dsl::users
.find(f.following.clone())
.first::<User>(conn)
.unwrap()
})
.collect::<Vec<User>>()
.map_err(|e| {
DatabaseError::new(
format!(
"Failed to retrieve user follows from database: {:?}",
e
),
"Database reading error",
)
})?
.iter()
.filter_map(|f| {
match users::dsl::users
.find(f.following.clone())
.first::<User>(conn) {
Ok(val) => Some(val),
Err(e) => {
let err = DatabaseError::new(
format!("Failed to retrieve user {} from database: {:?}",
f.following.clone(),
e),
"Database reading error");
debug!("{}", err);
None
}
}
})
.collect::<Vec<User>>())
}
}

View File

@ -18,7 +18,7 @@ pub struct OtherEnvVar {
impl Default for OtherEnvVar {
fn default() -> Self {
Self {
admin_key: from_env!("ADMIN_KEY")
admin_key: from_env!("ADMIN_KEY"),
}
}
}
@ -28,7 +28,7 @@ pub struct Context {
pub db: Database,
pub appwrite: APVariables,
pub user_auth: bool,
pub other_vars: OtherEnvVar
pub other_vars: OtherEnvVar,
}
impl Context {
@ -64,7 +64,6 @@ impl Context {
res.user_auth = self.user_auth(auth_token).await;
res
}
}
impl juniper::Context for Context {}