]> Untitled Git - lemmy.git/blob - server/lemmy_db/src/community_view.rs
Translated using Weblate (Italian)
[lemmy.git] / server / lemmy_db / src / community_view.rs
1 use super::community_view::community_fast_view::BoxedQuery;
2 use crate::{fuzzy_search, limit_and_offset, MaybeOptional, SortType};
3 use diesel::{pg::Pg, result::Error, *};
4 use serde::{Deserialize, Serialize};
5
6 table! {
7   community_view (id) {
8     id -> Int4,
9     name -> Varchar,
10     title -> Varchar,
11     description -> Nullable<Text>,
12     category_id -> Int4,
13     creator_id -> Int4,
14     removed -> Bool,
15     published -> Timestamp,
16     updated -> Nullable<Timestamp>,
17     deleted -> Bool,
18     nsfw -> Bool,
19     actor_id -> Text,
20     local -> Bool,
21     last_refreshed_at -> Timestamp,
22     creator_actor_id -> Text,
23     creator_local -> Bool,
24     creator_name -> Varchar,
25     creator_avatar -> Nullable<Text>,
26     category_name -> Varchar,
27     number_of_subscribers -> BigInt,
28     number_of_posts -> BigInt,
29     number_of_comments -> BigInt,
30     hot_rank -> Int4,
31     user_id -> Nullable<Int4>,
32     subscribed -> Nullable<Bool>,
33   }
34 }
35
36 table! {
37   community_fast_view (id) {
38     id -> Int4,
39     name -> Varchar,
40     title -> Varchar,
41     description -> Nullable<Text>,
42     category_id -> Int4,
43     creator_id -> Int4,
44     removed -> Bool,
45     published -> Timestamp,
46     updated -> Nullable<Timestamp>,
47     deleted -> Bool,
48     nsfw -> Bool,
49     actor_id -> Text,
50     local -> Bool,
51     last_refreshed_at -> Timestamp,
52     creator_actor_id -> Text,
53     creator_local -> Bool,
54     creator_name -> Varchar,
55     creator_avatar -> Nullable<Text>,
56     category_name -> Varchar,
57     number_of_subscribers -> BigInt,
58     number_of_posts -> BigInt,
59     number_of_comments -> BigInt,
60     hot_rank -> Int4,
61     user_id -> Nullable<Int4>,
62     subscribed -> Nullable<Bool>,
63   }
64 }
65
66 table! {
67   community_moderator_view (id) {
68     id -> Int4,
69     community_id -> Int4,
70     user_id -> Int4,
71     published -> Timestamp,
72     user_actor_id -> Text,
73     user_local -> Bool,
74     user_name -> Varchar,
75     avatar -> Nullable<Text>,
76     community_actor_id -> Text,
77     community_local -> Bool,
78     community_name -> Varchar,
79   }
80 }
81
82 table! {
83   community_follower_view (id) {
84     id -> Int4,
85     community_id -> Int4,
86     user_id -> Int4,
87     published -> Timestamp,
88     user_actor_id -> Text,
89     user_local -> Bool,
90     user_name -> Varchar,
91     avatar -> Nullable<Text>,
92     community_actor_id -> Text,
93     community_local -> Bool,
94     community_name -> Varchar,
95   }
96 }
97
98 table! {
99   community_user_ban_view (id) {
100     id -> Int4,
101     community_id -> Int4,
102     user_id -> Int4,
103     published -> Timestamp,
104     user_actor_id -> Text,
105     user_local -> Bool,
106     user_name -> Varchar,
107     avatar -> Nullable<Text>,
108     community_actor_id -> Text,
109     community_local -> Bool,
110     community_name -> Varchar,
111   }
112 }
113
114 #[derive(
115   Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
116 )]
117 #[table_name = "community_fast_view"]
118 pub struct CommunityView {
119   pub id: i32,
120   pub name: String,
121   pub title: String,
122   pub description: Option<String>,
123   pub category_id: i32,
124   pub creator_id: i32,
125   pub removed: bool,
126   pub published: chrono::NaiveDateTime,
127   pub updated: Option<chrono::NaiveDateTime>,
128   pub deleted: bool,
129   pub nsfw: bool,
130   pub actor_id: String,
131   pub local: bool,
132   pub last_refreshed_at: chrono::NaiveDateTime,
133   pub creator_actor_id: String,
134   pub creator_local: bool,
135   pub creator_name: String,
136   pub creator_avatar: Option<String>,
137   pub category_name: String,
138   pub number_of_subscribers: i64,
139   pub number_of_posts: i64,
140   pub number_of_comments: i64,
141   pub hot_rank: i32,
142   pub user_id: Option<i32>,
143   pub subscribed: Option<bool>,
144 }
145
146 pub struct CommunityQueryBuilder<'a> {
147   conn: &'a PgConnection,
148   query: BoxedQuery<'a, Pg>,
149   sort: &'a SortType,
150   from_user_id: Option<i32>,
151   show_nsfw: bool,
152   search_term: Option<String>,
153   page: Option<i64>,
154   limit: Option<i64>,
155 }
156
157 impl<'a> CommunityQueryBuilder<'a> {
158   pub fn create(conn: &'a PgConnection) -> Self {
159     use super::community_view::community_fast_view::dsl::*;
160
161     let query = community_fast_view.into_boxed();
162
163     CommunityQueryBuilder {
164       conn,
165       query,
166       sort: &SortType::Hot,
167       from_user_id: None,
168       show_nsfw: true,
169       search_term: None,
170       page: None,
171       limit: None,
172     }
173   }
174
175   pub fn sort(mut self, sort: &'a SortType) -> Self {
176     self.sort = sort;
177     self
178   }
179
180   pub fn for_user<T: MaybeOptional<i32>>(mut self, from_user_id: T) -> Self {
181     self.from_user_id = from_user_id.get_optional();
182     self
183   }
184
185   pub fn show_nsfw(mut self, show_nsfw: bool) -> Self {
186     self.show_nsfw = show_nsfw;
187     self
188   }
189
190   pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
191     self.search_term = search_term.get_optional();
192     self
193   }
194
195   pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
196     self.page = page.get_optional();
197     self
198   }
199
200   pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
201     self.limit = limit.get_optional();
202     self
203   }
204
205   pub fn list(self) -> Result<Vec<CommunityView>, Error> {
206     use super::community_view::community_fast_view::dsl::*;
207
208     let mut query = self.query;
209
210     if let Some(search_term) = self.search_term {
211       let searcher = fuzzy_search(&search_term);
212       query = query
213         .filter(name.ilike(searcher.to_owned()))
214         .or_filter(title.ilike(searcher.to_owned()))
215         .or_filter(description.ilike(searcher));
216     };
217
218     // The view lets you pass a null user_id, if you're not logged in
219     match self.sort {
220       SortType::Hot => {
221         query = query
222           .order_by(hot_rank.desc())
223           .then_order_by(number_of_subscribers.desc())
224           .filter(user_id.is_null())
225       }
226       SortType::New => query = query.order_by(published.desc()).filter(user_id.is_null()),
227       SortType::TopAll => match self.from_user_id {
228         Some(from_user_id) => {
229           query = query
230             .filter(user_id.eq(from_user_id))
231             .order_by((subscribed.asc(), number_of_subscribers.desc()))
232         }
233         None => {
234           query = query
235             .order_by(number_of_subscribers.desc())
236             .filter(user_id.is_null())
237         }
238       },
239       _ => (),
240     };
241
242     if !self.show_nsfw {
243       query = query.filter(nsfw.eq(false));
244     };
245
246     let (limit, offset) = limit_and_offset(self.page, self.limit);
247     query
248       .limit(limit)
249       .offset(offset)
250       .filter(removed.eq(false))
251       .filter(deleted.eq(false))
252       .load::<CommunityView>(self.conn)
253   }
254 }
255
256 impl CommunityView {
257   pub fn read(
258     conn: &PgConnection,
259     from_community_id: i32,
260     from_user_id: Option<i32>,
261   ) -> Result<Self, Error> {
262     use super::community_view::community_fast_view::dsl::*;
263
264     let mut query = community_fast_view.into_boxed();
265
266     query = query.filter(id.eq(from_community_id));
267
268     // The view lets you pass a null user_id, if you're not logged in
269     if let Some(from_user_id) = from_user_id {
270       query = query.filter(user_id.eq(from_user_id));
271     } else {
272       query = query.filter(user_id.is_null());
273     };
274
275     query.first::<Self>(conn)
276   }
277 }
278
279 #[derive(
280   Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
281 )]
282 #[table_name = "community_moderator_view"]
283 pub struct CommunityModeratorView {
284   pub id: i32,
285   pub community_id: i32,
286   pub user_id: i32,
287   pub published: chrono::NaiveDateTime,
288   pub user_actor_id: String,
289   pub user_local: bool,
290   pub user_name: String,
291   pub avatar: Option<String>,
292   pub community_actor_id: String,
293   pub community_local: bool,
294   pub community_name: String,
295 }
296
297 impl CommunityModeratorView {
298   pub fn for_community(conn: &PgConnection, for_community_id: i32) -> Result<Vec<Self>, Error> {
299     use super::community_view::community_moderator_view::dsl::*;
300     community_moderator_view
301       .filter(community_id.eq(for_community_id))
302       .order_by(published)
303       .load::<Self>(conn)
304   }
305
306   pub fn for_user(conn: &PgConnection, for_user_id: i32) -> Result<Vec<Self>, Error> {
307     use super::community_view::community_moderator_view::dsl::*;
308     community_moderator_view
309       .filter(user_id.eq(for_user_id))
310       .order_by(published)
311       .load::<Self>(conn)
312   }
313 }
314
315 #[derive(
316   Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
317 )]
318 #[table_name = "community_follower_view"]
319 pub struct CommunityFollowerView {
320   pub id: i32,
321   pub community_id: i32,
322   pub user_id: i32,
323   pub published: chrono::NaiveDateTime,
324   pub user_actor_id: String,
325   pub user_local: bool,
326   pub user_name: String,
327   pub avatar: Option<String>,
328   pub community_actor_id: String,
329   pub community_local: bool,
330   pub community_name: String,
331 }
332
333 impl CommunityFollowerView {
334   pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
335     use super::community_view::community_follower_view::dsl::*;
336     community_follower_view
337       .filter(community_id.eq(from_community_id))
338       .load::<Self>(conn)
339   }
340
341   pub fn for_user(conn: &PgConnection, from_user_id: i32) -> Result<Vec<Self>, Error> {
342     use super::community_view::community_follower_view::dsl::*;
343     community_follower_view
344       .filter(user_id.eq(from_user_id))
345       .load::<Self>(conn)
346   }
347 }
348
349 #[derive(
350   Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
351 )]
352 #[table_name = "community_user_ban_view"]
353 pub struct CommunityUserBanView {
354   pub id: i32,
355   pub community_id: i32,
356   pub user_id: i32,
357   pub published: chrono::NaiveDateTime,
358   pub user_actor_id: String,
359   pub user_local: bool,
360   pub user_name: String,
361   pub avatar: Option<String>,
362   pub community_actor_id: String,
363   pub community_local: bool,
364   pub community_name: String,
365 }
366
367 impl CommunityUserBanView {
368   pub fn for_community(conn: &PgConnection, from_community_id: i32) -> Result<Vec<Self>, Error> {
369     use super::community_view::community_user_ban_view::dsl::*;
370     community_user_ban_view
371       .filter(community_id.eq(from_community_id))
372       .load::<Self>(conn)
373   }
374
375   pub fn for_user(conn: &PgConnection, from_user_id: i32) -> Result<Vec<Self>, Error> {
376     use super::community_view::community_user_ban_view::dsl::*;
377     community_user_ban_view
378       .filter(user_id.eq(from_user_id))
379       .load::<Self>(conn)
380   }
381
382   pub fn get(
383     conn: &PgConnection,
384     from_user_id: i32,
385     from_community_id: i32,
386   ) -> Result<Self, Error> {
387     use super::community_view::community_user_ban_view::dsl::*;
388     community_user_ban_view
389       .filter(user_id.eq(from_user_id))
390       .filter(community_id.eq(from_community_id))
391       .first::<Self>(conn)
392   }
393 }