2023-01-04 21:16:48 +00:00
|
|
|
use super::super::schema;
|
2023-01-15 16:35:43 +00:00
|
|
|
use crate::{db::Database, graphql::Context};
|
2023-01-04 13:42:55 +00:00
|
|
|
use diesel::prelude::*;
|
2023-01-04 21:16:48 +00:00
|
|
|
use juniper::GraphQLEnum;
|
|
|
|
use schema::{wordrelation, words};
|
|
|
|
use tracing::info;
|
|
|
|
|
|
|
|
use super::languages::Language;
|
2023-01-03 15:11:43 +00:00
|
|
|
|
|
|
|
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq)]
|
|
|
|
#[DieselTypePath = "crate::db::schema::sql_types::Wordrelationship"]
|
|
|
|
pub enum WordRelationship {
|
|
|
|
Definition,
|
2023-01-04 13:42:55 +00:00
|
|
|
Related,
|
2023-01-03 15:11:43 +00:00
|
|
|
}
|
|
|
|
|
2023-01-08 14:58:26 +00:00
|
|
|
#[derive(
|
|
|
|
diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq, GraphQLEnum,
|
|
|
|
)]
|
2023-01-03 15:11:43 +00:00
|
|
|
#[DieselTypePath = "crate::db::schema::sql_types::Partofspeech"]
|
|
|
|
pub enum PartOfSpeech {
|
|
|
|
Adjective,
|
|
|
|
Adposition,
|
|
|
|
Adverb,
|
|
|
|
Auxilliary,
|
2023-01-04 21:16:48 +00:00
|
|
|
#[graphql(name = "COORDINATING_CONJUNCTION")]
|
2023-01-03 15:11:43 +00:00
|
|
|
CoordConj,
|
|
|
|
Determiner,
|
|
|
|
Interjection,
|
|
|
|
Noun,
|
|
|
|
Numeral,
|
|
|
|
Particle,
|
|
|
|
Pronoun,
|
2023-01-04 21:16:48 +00:00
|
|
|
#[graphql(name = "PROPER_NOUN")]
|
2023-01-03 15:11:43 +00:00
|
|
|
ProperNoun,
|
|
|
|
Punctuation,
|
2023-01-04 21:16:48 +00:00
|
|
|
#[graphql(name = "SUBORDINATING_CONJUNCTION")]
|
2023-01-03 15:11:43 +00:00
|
|
|
SubjConj,
|
|
|
|
Symbol,
|
|
|
|
Verb,
|
2023-01-04 13:42:55 +00:00
|
|
|
Other,
|
2023-01-03 15:11:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Queryable, Insertable, Debug, Clone, PartialEq, Eq)]
|
2023-01-04 18:31:52 +00:00
|
|
|
pub struct Word {
|
2023-01-03 15:11:43 +00:00
|
|
|
norm: String,
|
|
|
|
native: Option<String>,
|
|
|
|
lemma: Option<String>,
|
2023-01-08 14:58:26 +00:00
|
|
|
language: uuid::Uuid,
|
2023-01-03 15:11:43 +00:00
|
|
|
partofspeech: PartOfSpeech,
|
|
|
|
audio: Option<String>,
|
|
|
|
video: Option<String>,
|
|
|
|
image: Option<String>,
|
|
|
|
description: Option<String>,
|
|
|
|
etymology: Option<String>,
|
|
|
|
lusage: Option<String>,
|
|
|
|
morphology: Option<String>,
|
|
|
|
}
|
|
|
|
|
2023-01-04 21:16:48 +00:00
|
|
|
impl Word {
|
2023-01-08 14:58:26 +00:00
|
|
|
fn relationship(
|
|
|
|
&self,
|
2023-01-15 16:35:43 +00:00
|
|
|
db: &Database,
|
2023-01-08 14:58:26 +00:00
|
|
|
relationship: WordRelationship,
|
|
|
|
) -> Vec<Word> {
|
2023-01-04 21:16:48 +00:00
|
|
|
use schema::wordrelation::dsl;
|
2023-01-15 16:35:43 +00:00
|
|
|
match &mut db.conn() {
|
2023-01-08 14:58:26 +00:00
|
|
|
Ok(conn) => dsl::wordrelation
|
|
|
|
.filter(dsl::wordsource.eq(self.norm.clone()))
|
|
|
|
.filter(dsl::relationship.eq(relationship))
|
|
|
|
.load::<WordRelation>(conn)
|
|
|
|
.unwrap()
|
|
|
|
.into_iter()
|
|
|
|
.flat_map(|w| {
|
|
|
|
use schema::words::dsl;
|
|
|
|
dsl::words.find(w.wordtarget).first::<Word>(conn)
|
|
|
|
})
|
|
|
|
.collect::<Vec<Word>>(),
|
2023-01-04 21:16:48 +00:00
|
|
|
Err(e) => {
|
|
|
|
info!("Could not connect to database: {:?}", e);
|
|
|
|
Vec::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-15 16:35:43 +00:00
|
|
|
#[juniper::graphql_object(Context = Context)]
|
2023-01-04 21:16:48 +00:00
|
|
|
impl Word {
|
|
|
|
#[graphql(description = "Normal form of the word")]
|
|
|
|
fn norm(&self) -> String {
|
|
|
|
self.norm.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Native representation of the word")]
|
|
|
|
fn native(&self) -> Option<String> {
|
|
|
|
self.native.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Base form of the current word")]
|
2023-01-15 16:35:43 +00:00
|
|
|
fn lemma(&self, context: &Context) -> Option<Word> {
|
2023-01-04 21:16:48 +00:00
|
|
|
use schema::words::dsl;
|
|
|
|
match self.lemma.clone() {
|
2023-01-15 16:35:43 +00:00
|
|
|
Some(lemma) => match &mut context.db.conn() {
|
2023-01-08 14:58:26 +00:00
|
|
|
Ok(conn) => {
|
|
|
|
match dsl::words.find(lemma.clone()).first::<Word>(conn) {
|
|
|
|
Ok(word) => Some(word),
|
|
|
|
Err(e) => {
|
|
|
|
info!(
|
|
|
|
"Failed to retrieve lemma {} of word {}: {:?}",
|
|
|
|
lemma, self.norm, e
|
|
|
|
);
|
|
|
|
None
|
|
|
|
}
|
2023-01-04 21:16:48 +00:00
|
|
|
}
|
2023-01-08 14:58:26 +00:00
|
|
|
}
|
2023-01-04 21:16:48 +00:00
|
|
|
Err(e) => {
|
|
|
|
info!("Could not connect to the database: {:?}", e);
|
|
|
|
None
|
|
|
|
}
|
|
|
|
},
|
|
|
|
None => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Language to which the word belongs")]
|
2023-01-15 16:35:43 +00:00
|
|
|
fn language(&self, context: &Context) -> Language {
|
2023-01-04 21:16:48 +00:00
|
|
|
use schema::languages::dsl;
|
2023-01-15 16:35:43 +00:00
|
|
|
match &mut context.db.conn() {
|
2023-01-04 21:16:48 +00:00
|
|
|
Ok(conn) => {
|
2023-01-08 14:58:26 +00:00
|
|
|
match dsl::languages.find(self.language).first::<Language>(conn)
|
2023-01-04 21:16:48 +00:00
|
|
|
{
|
|
|
|
Ok(lang) => lang,
|
|
|
|
Err(e) => {
|
|
|
|
panic!("Failed to retrieve language {} of word {} from database: {:?}",
|
|
|
|
self.language, self.norm, e
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => panic!("Failed to connect to database: {:?}", e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-08 14:58:26 +00:00
|
|
|
#[graphql(
|
|
|
|
name = "partOfSpeech",
|
|
|
|
description = "Part of speech the word belongs to"
|
|
|
|
)]
|
2023-01-04 21:16:48 +00:00
|
|
|
fn part_of_speech(&self) -> PartOfSpeech {
|
|
|
|
self.partofspeech.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Link to an audio file related to the word")]
|
|
|
|
fn audio(&self) -> Option<String> {
|
|
|
|
self.audio.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Link to an video file related to the word")]
|
|
|
|
fn video(&self) -> Option<String> {
|
|
|
|
self.video.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Link to an image file related to the word")]
|
|
|
|
fn image(&self) -> Option<String> {
|
|
|
|
self.image.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Etymology of the word, can be in Markdown format")]
|
|
|
|
fn etymology(&self) -> Option<String> {
|
|
|
|
self.etymology.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[graphql(description = "Usage of the word, can be in Markdown format")]
|
|
|
|
fn usage(&self) -> Option<String> {
|
|
|
|
self.lusage.clone()
|
|
|
|
}
|
|
|
|
|
2023-01-08 14:58:26 +00:00
|
|
|
#[graphql(
|
|
|
|
description = "Morphology of the word, can be in Markdown format"
|
|
|
|
)]
|
2023-01-04 21:16:48 +00:00
|
|
|
fn morphology(&self) -> Option<String> {
|
|
|
|
self.morphology.clone()
|
|
|
|
}
|
|
|
|
|
2023-01-08 14:58:26 +00:00
|
|
|
#[graphql(
|
|
|
|
name = "related",
|
|
|
|
description = "Words related to the current word"
|
|
|
|
)]
|
2023-01-15 16:35:43 +00:00
|
|
|
fn related_words(&self, context: &Context) -> Vec<Word> {
|
|
|
|
self.relationship(&context.db, WordRelationship::Related)
|
2023-01-04 21:16:48 +00:00
|
|
|
}
|
|
|
|
|
2023-01-08 14:58:26 +00:00
|
|
|
#[graphql(
|
|
|
|
name = "definitions",
|
|
|
|
description = "Words that define the current word"
|
|
|
|
)]
|
2023-01-15 16:35:43 +00:00
|
|
|
fn definitions(&self, context: &Context) -> Vec<Word> {
|
|
|
|
self.relationship(&context.db, WordRelationship::Definition)
|
2023-01-04 21:16:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-03 15:11:43 +00:00
|
|
|
#[derive(Queryable, Insertable, Debug, Clone, PartialEq, Eq)]
|
|
|
|
#[diesel(table_name = wordrelation)]
|
2023-01-04 18:31:52 +00:00
|
|
|
pub struct WordRelation {
|
2023-01-03 15:11:43 +00:00
|
|
|
id: i32,
|
|
|
|
wordsource: String,
|
|
|
|
wordtarget: String,
|
|
|
|
relationship: WordRelationship,
|
|
|
|
}
|