]> Untitled Git - lemmy.git/blob - server/src/db/user_view.rs
Merge branch 'dev' into federation
[lemmy.git] / server / src / db / user_view.rs
1 use super::user_view::user_mview::BoxedQuery;
2 use super::*;
3 use diesel::pg::Pg;
4
5 table! {
6   user_view (id) {
7     id -> Int4,
8     name -> Varchar,
9     avatar -> Nullable<Text>,
10     email -> Nullable<Text>,
11     matrix_user_id -> Nullable<Text>,
12     fedi_name -> Varchar,
13     admin -> Bool,
14     banned -> Bool,
15     show_avatars -> Bool,
16     send_notifications_to_email -> Bool,
17     published -> Timestamp,
18     number_of_posts -> BigInt,
19     post_score -> BigInt,
20     number_of_comments -> BigInt,
21     comment_score -> BigInt,
22   }
23 }
24
25 table! {
26   user_mview (id) {
27     id -> Int4,
28     name -> Varchar,
29     avatar -> Nullable<Text>,
30     email -> Nullable<Text>,
31     matrix_user_id -> Nullable<Text>,
32     fedi_name -> Varchar,
33     admin -> Bool,
34     banned -> Bool,
35     show_avatars -> Bool,
36     send_notifications_to_email -> Bool,
37     published -> Timestamp,
38     number_of_posts -> BigInt,
39     post_score -> BigInt,
40     number_of_comments -> BigInt,
41     comment_score -> BigInt,
42   }
43 }
44
45 #[derive(
46   Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
47 )]
48 #[table_name = "user_view"]
49 pub struct UserView {
50   pub id: i32,
51   pub name: String,
52   pub avatar: Option<String>,
53   pub email: Option<String>,
54   pub matrix_user_id: Option<String>,
55   pub fedi_name: String,
56   pub admin: bool,
57   pub banned: bool,
58   pub show_avatars: bool,
59   pub send_notifications_to_email: bool,
60   pub published: chrono::NaiveDateTime,
61   pub number_of_posts: i64,
62   pub post_score: i64,
63   pub number_of_comments: i64,
64   pub comment_score: i64,
65 }
66
67 pub struct UserQueryBuilder<'a> {
68   conn: &'a PgConnection,
69   query: BoxedQuery<'a, Pg>,
70   sort: &'a SortType,
71   page: Option<i64>,
72   limit: Option<i64>,
73 }
74
75 impl<'a> UserQueryBuilder<'a> {
76   pub fn create(conn: &'a PgConnection) -> Self {
77     use super::user_view::user_mview::dsl::*;
78
79     let query = user_mview.into_boxed();
80
81     UserQueryBuilder {
82       conn,
83       query,
84       sort: &SortType::Hot,
85       page: None,
86       limit: None,
87     }
88   }
89
90   pub fn sort(mut self, sort: &'a SortType) -> Self {
91     self.sort = sort;
92     self
93   }
94
95   pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
96     use super::user_view::user_mview::dsl::*;
97     if let Some(search_term) = search_term.get_optional() {
98       self.query = self.query.filter(name.ilike(fuzzy_search(&search_term)));
99     }
100     self
101   }
102
103   pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
104     self.page = page.get_optional();
105     self
106   }
107
108   pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
109     self.limit = limit.get_optional();
110     self
111   }
112
113   pub fn list(self) -> Result<Vec<UserView>, Error> {
114     use super::user_view::user_mview::dsl::*;
115
116     let mut query = self.query;
117
118     query = match self.sort {
119       SortType::Hot => query
120         .order_by(comment_score.desc())
121         .then_order_by(published.desc()),
122       SortType::New => query.order_by(published.desc()),
123       SortType::TopAll => query.order_by(comment_score.desc()),
124       SortType::TopYear => query
125         .filter(published.gt(now - 1.years()))
126         .order_by(comment_score.desc()),
127       SortType::TopMonth => query
128         .filter(published.gt(now - 1.months()))
129         .order_by(comment_score.desc()),
130       SortType::TopWeek => query
131         .filter(published.gt(now - 1.weeks()))
132         .order_by(comment_score.desc()),
133       SortType::TopDay => query
134         .filter(published.gt(now - 1.days()))
135         .order_by(comment_score.desc()),
136     };
137
138     let (limit, offset) = limit_and_offset(self.page, self.limit);
139     query = query.limit(limit).offset(offset);
140
141     query.load::<UserView>(self.conn)
142   }
143 }
144
145 impl UserView {
146   pub fn read(conn: &PgConnection, from_user_id: i32) -> Result<Self, Error> {
147     use super::user_view::user_view::dsl::*;
148
149     user_view.find(from_user_id).first::<Self>(conn)
150   }
151
152   pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> {
153     use super::user_view::user_mview::dsl::*;
154     user_mview.filter(admin.eq(true)).load::<Self>(conn)
155   }
156
157   pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
158     use super::user_view::user_mview::dsl::*;
159     user_mview.filter(banned.eq(true)).load::<Self>(conn)
160   }
161 }