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