1 use super::user_view::user_fast::BoxedQuery;
2 use crate::{fuzzy_search, limit_and_offset, MaybeOptional, SortType};
3 use diesel::{dsl::*, pg::Pg, result::Error, *};
4 use serde::{Deserialize, Serialize};
11 preferred_username -> Nullable<Varchar>,
12 avatar -> Nullable<Text>,
13 banner -> Nullable<Text>,
14 email -> Nullable<Text>,
15 matrix_user_id -> Nullable<Text>,
16 bio -> Nullable<Text>,
21 send_notifications_to_email -> Bool,
22 published -> Timestamp,
23 number_of_posts -> BigInt,
25 number_of_comments -> BigInt,
26 comment_score -> BigInt,
35 preferred_username -> Nullable<Varchar>,
36 avatar -> Nullable<Text>,
37 banner -> Nullable<Text>,
38 email -> Nullable<Text>,
39 matrix_user_id -> Nullable<Text>,
40 bio -> Nullable<Text>,
45 send_notifications_to_email -> Bool,
46 published -> Timestamp,
47 number_of_posts -> BigInt,
49 number_of_comments -> BigInt,
50 comment_score -> BigInt,
55 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
57 #[table_name = "user_fast"]
62 pub preferred_username: Option<String>,
63 pub avatar: Option<String>,
64 pub banner: Option<String>,
65 pub email: Option<String>, // TODO this shouldn't be in this view
66 pub matrix_user_id: Option<String>,
67 pub bio: Option<String>,
71 pub show_avatars: bool, // TODO this is a setting, probably doesn't need to be here
72 pub send_notifications_to_email: bool, // TODO also never used
73 pub published: chrono::NaiveDateTime,
74 pub number_of_posts: i64,
76 pub number_of_comments: i64,
77 pub comment_score: i64,
80 pub struct UserQueryBuilder<'a> {
81 conn: &'a PgConnection,
82 query: BoxedQuery<'a, Pg>,
88 impl<'a> UserQueryBuilder<'a> {
89 pub fn create(conn: &'a PgConnection) -> Self {
90 use super::user_view::user_fast::dsl::*;
92 let query = user_fast.into_boxed();
103 pub fn sort(mut self, sort: &'a SortType) -> Self {
108 pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
109 use super::user_view::user_fast::dsl::*;
110 if let Some(search_term) = search_term.get_optional() {
111 self.query = self.query.filter(name.ilike(fuzzy_search(&search_term)));
116 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
117 self.page = page.get_optional();
121 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
122 self.limit = limit.get_optional();
126 pub fn list(self) -> Result<Vec<UserView>, Error> {
127 use super::user_view::user_fast::dsl::*;
129 let mut query = self.query;
131 query = match self.sort {
132 SortType::Hot => query
133 .order_by(comment_score.desc())
134 .then_order_by(published.desc()),
135 SortType::Active => query
136 .order_by(comment_score.desc())
137 .then_order_by(published.desc()),
138 SortType::New => query.order_by(published.desc()),
139 SortType::TopAll => query.order_by(comment_score.desc()),
140 SortType::TopYear => query
141 .filter(published.gt(now - 1.years()))
142 .order_by(comment_score.desc()),
143 SortType::TopMonth => query
144 .filter(published.gt(now - 1.months()))
145 .order_by(comment_score.desc()),
146 SortType::TopWeek => query
147 .filter(published.gt(now - 1.weeks()))
148 .order_by(comment_score.desc()),
149 SortType::TopDay => query
150 .filter(published.gt(now - 1.days()))
151 .order_by(comment_score.desc()),
154 let (limit, offset) = limit_and_offset(self.page, self.limit);
155 query = query.limit(limit).offset(offset);
157 query.load::<UserView>(self.conn)
162 pub fn read(conn: &PgConnection, from_user_id: i32) -> Result<Self, Error> {
163 use super::user_view::user_fast::dsl::*;
164 user_fast.find(from_user_id).first::<Self>(conn)
167 pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> {
168 use super::user_view::user_fast::dsl::*;
169 use diesel::sql_types::{Nullable, Text};
171 // The select is necessary here to not get back emails
179 "".into_sql::<Nullable<Text>>(),
186 send_notifications_to_email,
193 .filter(admin.eq(true))
198 pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
199 use super::user_view::user_fast::dsl::*;
200 use diesel::sql_types::{Nullable, Text};
209 "".into_sql::<Nullable<Text>>(),
216 send_notifications_to_email,
223 .filter(banned.eq(true))