From 3220f5c005afa780192cf83a6399b9417cebf2d6 Mon Sep 17 00:00:00 2001 From: Lucien Cartier-Tilet Date: Tue, 17 Jan 2023 00:40:36 +0100 Subject: [PATCH] Add user, language, word lookup Also add some error management --- src/db/mod.rs | 99 +++++++++++++++++++++++++++++++++----------- src/graphql/query.rs | 70 ++++++++++++++++++++++++++++--- 2 files changed, 139 insertions(+), 30 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 2c01450..0448a16 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -127,14 +127,44 @@ impl Database { pub fn all_users(&self) -> Result, DatabaseError> { use self::schema::users::dsl::users; - users - .load::(&mut self.conn()?) - .map_err(|e| { - info!("Failed to retrieve languages from database: {:?}", e); - }) + users.load::(&mut self.conn()?).map_err(|e| { + DatabaseError::new( + format!("Failed to retrieve languages: {:?}", e), + "Failed to retrieve languages", + ) + }) + } + + pub fn find_language( + &self, + query: &str, + ) -> Result, DatabaseError> { + use self::schema::languages::dsl; + dsl::languages + .filter(dsl::name.ilike(format!("%{}%", query))) + .load::(&mut self.conn()?) .map_err(|e| { DatabaseError::new( - format!("Failed to retrieve languages: {:?}", e), + format!( + "Failed to retrieve languages with query {}: {:?}", + query, e + ), + "Failed to retrieve languages", + ) + }) + } + + pub fn find_user(&self, query: &str) -> Result, DatabaseError> { + use self::schema::users::dsl; + dsl::users + .filter(dsl::username.ilike(format!("%{}%", query))) + .load::(&mut self.conn()?) + .map_err(|e| { + DatabaseError::new( + format!( + "Failed to retrieve users with query {}: {:?}", + query, e + ), "Failed to retrieve languages", ) }) @@ -224,25 +254,46 @@ impl Database { } } - pub fn words(&self, language: uuid::Uuid, word: &str) -> Vec { + pub fn words( + &self, + language: uuid::Uuid, + word: &str, + ) -> Result, DatabaseError> { use self::schema::words::dsl; - if let Ok(conn) = &mut self.conn() { - match dsl::words - .filter(dsl::language.eq(language)) - .filter(dsl::norm.eq(word)) - .load::(conn) - { - Ok(val) => val, - Err(e) => { - info!( - "Error retrieving {} from language {}: {:?}", + dsl::words + .filter(dsl::language.eq(language)) + .filter(dsl::norm.eq(word)) + .load::(&mut self.conn()?) + .map_err(|e| { + DatabaseError::new( + format!( + "Failed to retrieve word {} from language {}: {:?}", word, language, e - ); - Vec::new() - } - } - } else { - Vec::new() - } + ), + "Failed to retrieve languages", + ) + }) + } + + pub fn find_word( + &self, + language: uuid::Uuid, + query: &str, + ) -> Result, DatabaseError> { + use self::schema::words::dsl; + dsl::words + .filter(dsl::language.eq(language)) + .filter(dsl::norm.ilike(format!("%{}%", query))) + .load::(&mut self.conn()?) + .map_err(|e| { + DatabaseError::new( + format!( + "Failed to retrieve words from language {} with query {}: {:?}", + language, + query, e + ), + "Failed to retrieve languages", + ) + }) } } diff --git a/src/graphql/query.rs b/src/graphql/query.rs index 3ef31fc..1b69a54 100644 --- a/src/graphql/query.rs +++ b/src/graphql/query.rs @@ -1,4 +1,5 @@ use juniper::FieldResult; +use uuid::Uuid; use super::Context; use crate::db::{ @@ -23,6 +24,26 @@ impl Query { context.db.all_languages().map_err(Into::into) } + #[graphql( + name = "findLanguage", + description = "Find languages by username containing query", + arguments(query(description = "String to find in language name")) + )] + fn find_language( + context: &Context, + query: String, + ) -> FieldResult> { + context.db.find_language(query.as_str()).map_err(Into::into) + } + + #[graphql( + name = "allUsers", + description = "Fetch all users from database", + arguments(admin_key( + name = "adminKey", + description = "Administrator key. Without it, the query cannot be executed" + )) + )] fn all_users( context: &Context, admin_key: String, @@ -35,6 +56,15 @@ impl Query { } } + #[graphql( + name = "findUser", + description = "Find users by username containing query", + arguments(query(description = "String to find in usernames")) + )] + fn find_user(context: &Context, query: String) -> FieldResult> { + context.db.find_user(query.as_str()).map_err(Into::into) + } + #[graphql( description = "Retrieve a specific language from its name and its owner's id", arguments( @@ -66,6 +96,34 @@ impl Query { context.db.word_id(id.as_str()) } + #[graphql( + name = "findWord", + description = "Retrieve a word from a specific language", + arguments( + language( + description = "UUID of the language to look the word for in" + ), + query(description = "String to find in the word") + ) + )] + fn find_word( + context: &Context, + language: String, + query: String, + ) -> FieldResult> { + match Uuid::from_str(&language) { + Ok(uuid) => context + .db + .find_word(uuid, query.as_str()) + .map_err(Into::into), + Err(e) => Err(DatabaseError::new( + format!("Failed to convert {} to a UUID: {:?}", language, e), + "Conversion Error", + ) + .into()), + } + } + #[graphql( description = "Retrieve all words with a set normal form from a set language", arguments( @@ -81,13 +139,13 @@ impl Query { language: String, word: String, ) -> FieldResult> { - match uuid::Uuid::from_str(&language) { - Ok(uuid) => Ok(context.db.words(uuid, word.as_str())), + match Uuid::from_str(&language) { + Ok(uuid) => context + .db + .words(uuid, word.as_str()) + .map_err(Into::into), Err(e) => Err(DatabaseError::new( - format!( - "Failed to convert {} to a proper UUID: {:?}", - language, e - ), + format!("Failed to convert {} to a UUID: {:?}", language, e), "Conversion Error", ) .into()),