1 use diesel::{pg::Pg, result::Error, *};
2 use lemmy_db_queries::{limit_and_offset, MaybeOptional, ToSafe, ViewToVec};
4 schema::{person, person_alias_1, private_message},
6 person::{Person, PersonAlias1, PersonSafe, PersonSafeAlias1},
7 private_message::PrivateMessage,
15 #[derive(Debug, PartialEq, Serialize, Clone)]
16 pub struct PrivateMessageView {
17 pub private_message: PrivateMessage,
18 pub creator: PersonSafe,
19 pub recipient: PersonSafeAlias1,
22 type PrivateMessageViewTuple = (PrivateMessage, PersonSafe, PersonSafeAlias1);
24 impl PrivateMessageView {
25 pub fn read(conn: &PgConnection, private_message_id: PrivateMessageId) -> Result<Self, Error> {
26 let (private_message, creator, recipient) = private_message::table
27 .find(private_message_id)
28 .inner_join(person::table.on(private_message::creator_id.eq(person::id)))
29 .inner_join(person_alias_1::table.on(private_message::recipient_id.eq(person_alias_1::id)))
30 .order_by(private_message::published.desc())
32 private_message::all_columns,
33 Person::safe_columns_tuple(),
34 PersonAlias1::safe_columns_tuple(),
36 .first::<PrivateMessageViewTuple>(conn)?;
38 Ok(PrivateMessageView {
45 /// Gets the number of unread messages
46 pub fn get_unread_messages(conn: &PgConnection, my_person_id: PersonId) -> Result<i64, Error> {
48 private_message::table
49 .filter(private_message::read.eq(false))
50 .filter(private_message::recipient_id.eq(my_person_id))
51 .filter(private_message::deleted.eq(false))
52 .select(count(private_message::id))
57 pub struct PrivateMessageQueryBuilder<'a> {
58 conn: &'a PgConnection,
59 recipient_id: PersonId,
60 unread_only: Option<bool>,
65 impl<'a> PrivateMessageQueryBuilder<'a> {
66 pub fn create(conn: &'a PgConnection, recipient_id: PersonId) -> Self {
67 PrivateMessageQueryBuilder {
76 pub fn unread_only<T: MaybeOptional<bool>>(mut self, unread_only: T) -> Self {
77 self.unread_only = unread_only.get_optional();
81 pub fn page<T: MaybeOptional<i64>>(mut self, page: T) -> Self {
82 self.page = page.get_optional();
86 pub fn limit<T: MaybeOptional<i64>>(mut self, limit: T) -> Self {
87 self.limit = limit.get_optional();
91 pub fn list(self) -> Result<Vec<PrivateMessageView>, Error> {
92 let mut query = private_message::table
93 .inner_join(person::table.on(private_message::creator_id.eq(person::id)))
94 .inner_join(person_alias_1::table.on(private_message::recipient_id.eq(person_alias_1::id)))
96 private_message::all_columns,
97 Person::safe_columns_tuple(),
98 PersonAlias1::safe_columns_tuple(),
102 // If its unread, I only want the ones to me
103 if self.unread_only.unwrap_or(false) {
105 .filter(private_message::read.eq(false))
106 .filter(private_message::recipient_id.eq(self.recipient_id));
108 // Otherwise, I want the ALL view to show both sent and received
110 query = query.filter(
111 private_message::recipient_id
112 .eq(self.recipient_id)
113 .or(private_message::creator_id.eq(self.recipient_id)),
117 let (limit, offset) = limit_and_offset(self.page, self.limit);
120 .filter(private_message::deleted.eq(false))
123 .order_by(private_message::published.desc());
126 "Private Message View Query: {:?}",
127 debug_query::<Pg, _>(&query)
130 let res = query.load::<PrivateMessageViewTuple>(self.conn)?;
132 Ok(PrivateMessageView::from_tuple_to_vec(res))
136 impl ViewToVec for PrivateMessageView {
137 type DbTuple = PrivateMessageViewTuple;
138 fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
142 private_message: a.0.to_owned(),
143 creator: a.1.to_owned(),
144 recipient: a.2.to_owned(),
146 .collect::<Vec<Self>>()