Plenty of GraphQL query implementation

Implement query for languages, words, initial implementation for user
query
This commit is contained in:
2023-01-04 22:16:48 +01:00
parent c0b0a53061
commit ecd8f58542
6 changed files with 454 additions and 43 deletions

View File

@@ -1,18 +1,28 @@
use super::super::schema::{langandagents, languages};
use crate::db::Database;
use diesel::prelude::*;
use juniper::GraphQLEnum;
use tracing::info;
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum)]
use super::super::schema;
use super::users::User;
use schema::{langandagents, languages};
#[derive(
diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum,
)]
#[DieselTypePath = "crate::db::schema::sql_types::Release"]
pub enum Release {
Public,
#[graphql(name="NON_COMMERCIAL")]
#[graphql(name = "NON_COMMERCIAL")]
NonCommercial,
Research,
Private,
}
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum)]
#[derive(
diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum,
)]
#[DieselTypePath = "crate::db::schema::sql_types::Dictgenre"]
pub enum DictGenre {
General,
@@ -24,7 +34,9 @@ pub enum DictGenre {
Terminology,
}
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum)]
#[derive(
diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum,
)]
#[DieselTypePath = "crate::db::schema::sql_types::Agentlanguagerelation"]
pub enum AgentLanguageRelation {
Publisher,
@@ -46,21 +58,163 @@ pub struct Language {
owner: String,
}
#[juniper::graphql_object]
impl Language {
#[graphql(name = "release")]
fn relationship(
&self,
context: &Database,
relationship: AgentLanguageRelation,
) -> Vec<User> {
use schema::langandagents::dsl;
match &mut context.conn() {
Ok(conn) => dsl::langandagents
.filter(dsl::language.eq(self.name.clone()))
.filter(dsl::relationship.eq(relationship))
.load::<LangAndAgent>(conn)
.unwrap()
.iter()
.map(|v| {
use schema::users::dsl;
dsl::users.find(v.agent.clone()).first::<User>(conn)
})
.filter_map(|author| match author {
Ok(val) => Some(val),
Err(e) => {
info!(
"Failed ot retrieve author from database: {:?}",
e
);
None
}
})
.collect::<Vec<User>>(),
Err(e) => {
panic!("Could not connect to the database: {:?}", e);
}
}
}
}
#[juniper::graphql_object(Context = Database)]
impl Language {
#[graphql(
description = "Name in the main target language (often English) of the described language"
)]
fn name(&self) -> String {
self.name.clone()
}
#[graphql(description = "Native name of the language")]
fn native() -> Option<String> {
self.native.clone()
}
#[graphql(description = "How the dictionary is currently released")]
fn release(&self) -> Release {
self.release.clone()
}
#[graphql(name = "created")]
#[graphql(
name = "targetLanguage",
description = "Languages in which the current language is translated"
)]
fn target_language(&self, context: &Database) -> Vec<Language> {
use schema::languages::dsl;
match &mut context.conn() {
Ok(conn) => self
.targetlanguage
.clone()
.into_iter()
.flatten()
.map(|l| dsl::languages.find(l).first::<Language>(conn))
.filter_map(|l| match l {
Ok(language) => Some(language),
Err(e) => {
info!(
"Failed to retrieve language from database: {:?}",
e
);
None
}
})
.collect::<Vec<Language>>(),
Err(e) => {
info!("Failed to connect to the database: {:?}", e);
Vec::new()
}
}
}
#[graphql(description = "What kind of dictionary this is")]
fn genre(&self) -> Vec<DictGenre> {
self.genre.clone().into_iter().flatten().collect()
}
#[graphql(
name = "abstract",
description = "Short description of the language"
)]
fn abstract_(&self) -> Option<String> {
self.abstract_.clone()
}
#[graphql(
description = "Time at which the language's dictionary was created"
)]
fn created(&self) -> String {
self.created.to_string()
}
#[graphql(name = "name")]
fn name(&self) -> String {
self.name.clone()
#[graphql(
description = "Longer description of the language, its content can be formatted as Markdown"
)]
fn description(&self) -> Option<String> {
self.description.clone()
}
#[graphql(
description = "Copyrights held by various people over the language's dictionary and its content"
)]
fn rights(&self) -> Option<String> {
self.rights.clone()
}
#[graphql(description = "License under which the dictionary is released")]
fn license(&self) -> Option<String> {
self.license.clone()
}
#[graphql(
description = "User with administrative rights over the language"
)]
fn owner(&self, context: &Database) -> User {
use schema::users::dsl;
match &mut context.conn() {
Ok(conn) => 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
)
}),
Err(e) => panic!("Failed to connect to the database: {:?}", e),
}
}
#[graphql(
description = "People who participate in the elaboration of the language's dictionary"
)]
fn authors(&self, context: &Database) -> Vec<User> {
self.relationship(context, AgentLanguageRelation::Author)
}
#[graphql(
description = "People who can and do redistribute the language's dictionary"
)]
fn publishers(&self, context: &Database) -> Vec<User> {
self.relationship(context, AgentLanguageRelation::Publisher)
}
}
@@ -70,4 +224,5 @@ pub struct LangAndAgent {
id: i32,
agent: String,
language: String,
relationship: AgentLanguageRelation,
}