]> Untitled Git - lemmy.git/blob - server/lemmy_db/src/private_message_view.rs
68f7df42c3679b17bcf350820b1b87c8d71a60d2
[lemmy.git] / server / lemmy_db / src / private_message_view.rs
1 use crate::{limit_and_offset, MaybeOptional};
2 use diesel::{pg::Pg, result::Error, *};
3 use serde::Serialize;
4
5 // The faked schema since diesel doesn't do views
6 table! {
7   private_message_view (id) {
8     id -> Int4,
9     creator_id -> Int4,
10     recipient_id -> Int4,
11     content -> Text,
12     deleted -> Bool,
13     read -> Bool,
14     published -> Timestamp,
15     updated -> Nullable<Timestamp>,
16     ap_id -> Text,
17     local -> Bool,
18     creator_name -> Varchar,
19     creator_preferred_username -> Nullable<Varchar>,
20     creator_avatar -> Nullable<Text>,
21     creator_actor_id -> Text,
22     creator_local -> Bool,
23     recipient_name -> Varchar,
24     recipient_preferred_username -> Nullable<Varchar>,
25     recipient_avatar -> Nullable<Text>,
26     recipient_actor_id -> Text,
27     recipient_local -> Bool,
28   }
29 }
30
31 #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, QueryableByName, Clone)]
32 #[table_name = "private_message_view"]
33 pub struct PrivateMessageView {
34   pub id: i32,
35   pub creator_id: i32,
36   pub recipient_id: i32,
37   pub content: String,
38   pub deleted: bool,
39   pub read: bool,
40   pub published: chrono::NaiveDateTime,
41   pub updated: Option<chrono::NaiveDateTime>,
42   pub ap_id: String,
43   pub local: bool,
44   pub creator_name: String,
45   pub creator_preferred_username: Option<String>,
46   pub creator_avatar: Option<String>,
47   pub creator_actor_id: String,
48   pub creator_local: bool,
49   pub recipient_name: String,
50   pub recipient_preferred_username: Option<String>,
51   pub recipient_avatar: Option<String>,
52   pub recipient_actor_id: String,
53   pub recipient_local: bool,
54 }
55
56 pub struct PrivateMessageQueryBuilder<'a> {
57   conn: &'a PgConnection,
58   query: super::private_message_view::private_message_view::BoxedQuery<'a, Pg>,
59   for_recipient_id: i32,
60   unread_only: bool,
61   page: Option<i64>,
62   limit: Option<i64>,
63 }
64
65 impl<'a> PrivateMessageQueryBuilder<'a> {
66   pub fn create(conn: &'a PgConnection, for_recipient_id: i32) -> Self {
67     use super::private_message_view::private_message_view::dsl::*;
68
69     let query = private_message_view.into_boxed();
70
71     PrivateMessageQueryBuilder {
72       conn,
73       query,
74       for_recipient_id,
75       unread_only: false,
76       page: None,
77       limit: None,
78     }
79   }
80
81   pub fn unread_only(mut self, unread_only: bool) -> Self {
82     self.unread_only = unread_only;
83     self
84   }
85
86   pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
87     self.page = page.get_optional();
88     self
89   }
90
91   pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
92     self.limit = limit.get_optional();
93     self
94   }
95
96   pub fn list(self) -> Result<Vec<PrivateMessageView>, Error> {
97     use super::private_message_view::private_message_view::dsl::*;
98
99     let mut query = self.query.filter(deleted.eq(false));
100
101     // If its unread, I only want the ones to me
102     if self.unread_only {
103       query = query
104         .filter(read.eq(false))
105         .filter(recipient_id.eq(self.for_recipient_id));
106     }
107     // Otherwise, I want the ALL view to show both sent and received
108     else {
109       query = query.filter(
110         recipient_id
111           .eq(self.for_recipient_id)
112           .or(creator_id.eq(self.for_recipient_id)),
113       )
114     }
115
116     let (limit, offset) = limit_and_offset(self.page, self.limit);
117
118     query
119       .limit(limit)
120       .offset(offset)
121       .order_by(published.desc())
122       .load::<PrivateMessageView>(self.conn)
123   }
124 }
125
126 impl PrivateMessageView {
127   pub fn read(conn: &PgConnection, from_private_message_id: i32) -> Result<Self, Error> {
128     use super::private_message_view::private_message_view::dsl::*;
129
130     let mut query = private_message_view.into_boxed();
131
132     query = query
133       .filter(id.eq(from_private_message_id))
134       .order_by(published.desc());
135
136     query.first::<Self>(conn)
137   }
138 }