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