diff options
author | Dessalines <tyhou13@gmx.com> | 2020-07-11 19:12:56 -0400 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2020-07-11 19:12:56 -0400 |
commit | 60288b2d060ba930fe6cae22c4824d88fe7a00c9 (patch) | |
tree | 8fed01325853240c69f3688ee621be29bedfd382 /server/lemmy_db/src/user_view.rs | |
parent | 1710844a1bc6a4f46eceaa12f2fb428cb794c694 (diff) | |
parent | 1b9f2fa5f7f7831f59b24cb36a5607a769a0d92e (diff) |
Merge branch 'master' into jmarthernandez-remove-karma-from-search
Diffstat (limited to 'server/lemmy_db/src/user_view.rs')
-rw-r--r-- | server/lemmy_db/src/user_view.rs | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/server/lemmy_db/src/user_view.rs b/server/lemmy_db/src/user_view.rs new file mode 100644 index 00000000..84feba38 --- /dev/null +++ b/server/lemmy_db/src/user_view.rs @@ -0,0 +1,167 @@ +use super::user_view::user_fast::BoxedQuery; +use crate::{fuzzy_search, limit_and_offset, MaybeOptional, SortType}; +use diesel::{dsl::*, pg::Pg, result::Error, *}; +use serde::{Deserialize, Serialize}; + +table! { + user_view (id) { + id -> Int4, + actor_id -> Text, + name -> Varchar, + avatar -> Nullable<Text>, + email -> Nullable<Text>, + matrix_user_id -> Nullable<Text>, + bio -> Nullable<Text>, + local -> Bool, + admin -> Bool, + banned -> Bool, + show_avatars -> Bool, + send_notifications_to_email -> Bool, + published -> Timestamp, + number_of_posts -> BigInt, + post_score -> BigInt, + number_of_comments -> BigInt, + comment_score -> BigInt, + } +} + +table! { + user_fast (id) { + id -> Int4, + actor_id -> Text, + name -> Varchar, + avatar -> Nullable<Text>, + email -> Nullable<Text>, + matrix_user_id -> Nullable<Text>, + bio -> Nullable<Text>, + local -> Bool, + admin -> Bool, + banned -> Bool, + show_avatars -> Bool, + send_notifications_to_email -> Bool, + published -> Timestamp, + number_of_posts -> BigInt, + post_score -> BigInt, + number_of_comments -> BigInt, + comment_score -> BigInt, + } +} + +#[derive( + Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone, +)] +#[table_name = "user_fast"] +pub struct UserView { + pub id: i32, + pub actor_id: String, + pub name: String, + pub avatar: Option<String>, + pub email: Option<String>, + pub matrix_user_id: Option<String>, + pub bio: Option<String>, + pub local: bool, + pub admin: bool, + pub banned: bool, + pub show_avatars: bool, + pub send_notifications_to_email: bool, + pub published: chrono::NaiveDateTime, + pub number_of_posts: i64, + pub post_score: i64, + pub number_of_comments: i64, + pub comment_score: i64, +} + +pub struct UserQueryBuilder<'a> { + conn: &'a PgConnection, + query: BoxedQuery<'a, Pg>, + sort: &'a SortType, + page: Option<i64>, + limit: Option<i64>, +} + +impl<'a> UserQueryBuilder<'a> { + pub fn create(conn: &'a PgConnection) -> Self { + use super::user_view::user_fast::dsl::*; + + let query = user_fast.into_boxed(); + + UserQueryBuilder { + conn, + query, + sort: &SortType::Hot, + page: None, + limit: None, + } + } + + pub fn sort(mut self, sort: &'a SortType) -> Self { + self.sort = sort; + self + } + + pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self { + use super::user_view::user_fast::dsl::*; + if let Some(search_term) = search_term.get_optional() { + self.query = self.query.filter(name.ilike(fuzzy_search(&search_term))); + } + self + } + + pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self { + self.page = page.get_optional(); + self + } + + pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self { + self.limit = limit.get_optional(); + self + } + + pub fn list(self) -> Result<Vec<UserView>, Error> { + use super::user_view::user_fast::dsl::*; + + let mut query = self.query; + + query = match self.sort { + SortType::Hot => query + .order_by(comment_score.desc()) + .then_order_by(published.desc()), + SortType::New => query.order_by(published.desc()), + SortType::TopAll => query.order_by(comment_score.desc()), + SortType::TopYear => query + .filter(published.gt(now - 1.years())) + .order_by(comment_score.desc()), + SortType::TopMonth => query + .filter(published.gt(now - 1.months())) + .order_by(comment_score.desc()), + SortType::TopWeek => query + .filter(published.gt(now - 1.weeks())) + .order_by(comment_score.desc()), + SortType::TopDay => query + .filter(published.gt(now - 1.days())) + .order_by(comment_score.desc()), + }; + + let (limit, offset) = limit_and_offset(self.page, self.limit); + query = query.limit(limit).offset(offset); + + query.load::<UserView>(self.conn) + } +} + +impl UserView { + pub fn read(conn: &PgConnection, from_user_id: i32) -> Result<Self, Error> { + use super::user_view::user_fast::dsl::*; + user_fast.find(from_user_id).first::<Self>(conn) + } + + pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> { + use super::user_view::user_fast::dsl::*; + user_fast.filter(admin.eq(true)).load::<Self>(conn) + } + + pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> { + use super::user_view::user_fast::dsl::*; + user_fast.filter(banned.eq(true)).load::<Self>(conn) + } +} |