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};
11 description -> Nullable<Text>,
15 published -> Timestamp,
16 updated -> Nullable<Timestamp>,
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,
31 user_id -> Nullable<Int4>,
32 subscribed -> Nullable<Bool>,
37 community_fast_view (id) {
41 description -> Nullable<Text>,
45 published -> Timestamp,
46 updated -> Nullable<Timestamp>,
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,
61 user_id -> Nullable<Int4>,
62 subscribed -> Nullable<Bool>,
67 community_moderator_view (id) {
71 published -> Timestamp,
72 user_actor_id -> Text,
75 avatar -> Nullable<Text>,
76 community_actor_id -> Text,
77 community_local -> Bool,
78 community_name -> Varchar,
83 community_follower_view (id) {
87 published -> Timestamp,
88 user_actor_id -> Text,
91 avatar -> Nullable<Text>,
92 community_actor_id -> Text,
93 community_local -> Bool,
94 community_name -> Varchar,
99 community_user_ban_view (id) {
101 community_id -> Int4,
103 published -> Timestamp,
104 user_actor_id -> Text,
106 user_name -> Varchar,
107 avatar -> Nullable<Text>,
108 community_actor_id -> Text,
109 community_local -> Bool,
110 community_name -> Varchar,
115 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
117 #[table_name = "community_fast_view"]
118 pub struct CommunityView {
122 pub description: Option<String>,
123 pub category_id: i32,
126 pub published: chrono::NaiveDateTime,
127 pub updated: Option<chrono::NaiveDateTime>,
130 pub actor_id: String,
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,
142 pub user_id: Option<i32>,
143 pub subscribed: Option<bool>,
146 pub struct CommunityQueryBuilder<'a> {
147 conn: &'a PgConnection,
148 query: BoxedQuery<'a, Pg>,
150 from_user_id: Option<i32>,
152 search_term: Option<String>,
157 impl<'a> CommunityQueryBuilder<'a> {
158 pub fn create(conn: &'a PgConnection) -> Self {
159 use super::community_view::community_fast_view::dsl::*;
161 let query = community_fast_view.into_boxed();
163 CommunityQueryBuilder {
166 sort: &SortType::Hot,
175 pub fn sort(mut self, sort: &'a SortType) -> Self {
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();
185 pub fn show_nsfw(mut self, show_nsfw: bool) -> Self {
186 self.show_nsfw = show_nsfw;
190 pub fn search_term<T: MaybeOptional<String>>(mut self, search_term: T) -> Self {
191 self.search_term = search_term.get_optional();
195 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
196 self.page = page.get_optional();
200 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
201 self.limit = limit.get_optional();
205 pub fn list(self) -> Result<Vec<CommunityView>, Error> {
206 use super::community_view::community_fast_view::dsl::*;
208 let mut query = self.query;
210 if let Some(search_term) = self.search_term {
211 let searcher = fuzzy_search(&search_term);
213 .filter(name.ilike(searcher.to_owned()))
214 .or_filter(title.ilike(searcher.to_owned()))
215 .or_filter(description.ilike(searcher));
218 // The view lets you pass a null user_id, if you're not logged in
222 .order_by(hot_rank.desc())
223 .then_order_by(number_of_subscribers.desc())
224 .filter(user_id.is_null())
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) => {
230 .filter(user_id.eq(from_user_id))
231 .order_by((subscribed.asc(), number_of_subscribers.desc()))
235 .order_by(number_of_subscribers.desc())
236 .filter(user_id.is_null())
243 query = query.filter(nsfw.eq(false));
246 let (limit, offset) = limit_and_offset(self.page, self.limit);
250 .filter(removed.eq(false))
251 .filter(deleted.eq(false))
252 .load::<CommunityView>(self.conn)
259 from_community_id: i32,
260 from_user_id: Option<i32>,
261 ) -> Result<Self, Error> {
262 use super::community_view::community_fast_view::dsl::*;
264 let mut query = community_fast_view.into_boxed();
266 query = query.filter(id.eq(from_community_id));
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));
272 query = query.filter(user_id.is_null());
275 query.first::<Self>(conn)
280 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
282 #[table_name = "community_moderator_view"]
283 pub struct CommunityModeratorView {
285 pub community_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,
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))
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))
316 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
318 #[table_name = "community_follower_view"]
319 pub struct CommunityFollowerView {
321 pub community_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,
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))
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))
350 Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone,
352 #[table_name = "community_user_ban_view"]
353 pub struct CommunityUserBanView {
355 pub community_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,
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))
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))
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))