]> Untitled Git - lemmy.git/blob - crates/db_views/src/custom_emoji_view.rs
Fixing hot_ranks and scores to append a published sort. (#3618)
[lemmy.git] / crates / db_views / src / custom_emoji_view.rs
1 use crate::structs::CustomEmojiView;
2 use diesel::{result::Error, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl};
3 use diesel_async::RunQueryDsl;
4 use lemmy_db_schema::{
5   newtypes::{CustomEmojiId, LocalSiteId},
6   schema::{custom_emoji, custom_emoji_keyword},
7   source::{custom_emoji::CustomEmoji, custom_emoji_keyword::CustomEmojiKeyword},
8   utils::{get_conn, DbPool},
9 };
10 use std::collections::HashMap;
11
12 type CustomEmojiTuple = (CustomEmoji, Option<CustomEmojiKeyword>);
13
14 impl CustomEmojiView {
15   pub async fn get(pool: &mut DbPool<'_>, emoji_id: CustomEmojiId) -> Result<Self, Error> {
16     let conn = &mut get_conn(pool).await?;
17     let emojis = custom_emoji::table
18       .find(emoji_id)
19       .left_join(
20         custom_emoji_keyword::table.on(custom_emoji_keyword::custom_emoji_id.eq(custom_emoji::id)),
21       )
22       .select((
23         custom_emoji::all_columns,
24         custom_emoji_keyword::all_columns.nullable(), // (or all the columns if you want)
25       ))
26       .load::<CustomEmojiTuple>(conn)
27       .await?;
28     if let Some(emoji) = CustomEmojiView::from_tuple_to_vec(emojis)
29       .into_iter()
30       .next()
31     {
32       Ok(emoji)
33     } else {
34       Err(diesel::result::Error::NotFound)
35     }
36   }
37
38   pub async fn get_all(
39     pool: &mut DbPool<'_>,
40     for_local_site_id: LocalSiteId,
41   ) -> Result<Vec<Self>, Error> {
42     let conn = &mut get_conn(pool).await?;
43     let emojis = custom_emoji::table
44       .filter(custom_emoji::local_site_id.eq(for_local_site_id))
45       .left_join(
46         custom_emoji_keyword::table.on(custom_emoji_keyword::custom_emoji_id.eq(custom_emoji::id)),
47       )
48       .order(custom_emoji::category)
49       .then_order_by(custom_emoji::id)
50       .select((
51         custom_emoji::all_columns,
52         custom_emoji_keyword::all_columns.nullable(), // (or all the columns if you want)
53       ))
54       .load::<CustomEmojiTuple>(conn)
55       .await?;
56
57     Ok(CustomEmojiView::from_tuple_to_vec(emojis))
58   }
59
60   fn from_tuple_to_vec(items: Vec<CustomEmojiTuple>) -> Vec<Self> {
61     let mut result = Vec::new();
62     let mut hash: HashMap<CustomEmojiId, Vec<CustomEmojiKeyword>> = HashMap::new();
63     for item in &items {
64       let emoji_id: CustomEmojiId = item.0.id;
65       if let std::collections::hash_map::Entry::Vacant(e) = hash.entry(emoji_id) {
66         e.insert(Vec::new());
67         result.push(CustomEmojiView {
68           custom_emoji: item.0.clone(),
69           keywords: Vec::new(),
70         })
71       }
72       if let Some(item_keyword) = &item.1 {
73         if let Some(keywords) = hash.get_mut(&emoji_id) {
74           keywords.push(item_keyword.clone())
75         }
76       }
77     }
78     for emoji in &mut result {
79       if let Some(keywords) = hash.get_mut(&emoji.custom_emoji.id) {
80         emoji.keywords = keywords.clone();
81       }
82     }
83     result
84   }
85 }