use crate::{limit_and_offset, MaybeOptional}; use diesel::{pg::Pg, result::Error, *}; use serde::{Deserialize, Serialize}; // The faked schema since diesel doesn't do views table! { private_message_view (id) { id -> Int4, creator_id -> Int4, recipient_id -> Int4, content -> Text, deleted -> Bool, read -> Bool, published -> Timestamp, updated -> Nullable, ap_id -> Text, local -> Bool, creator_name -> Varchar, creator_preferred_username -> Nullable, creator_avatar -> Nullable, creator_actor_id -> Text, creator_local -> Bool, recipient_name -> Varchar, recipient_preferred_username -> Nullable, recipient_avatar -> Nullable, recipient_actor_id -> Text, recipient_local -> Bool, } } #[derive( Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone, )] #[table_name = "private_message_view"] pub struct PrivateMessageView { pub id: i32, pub creator_id: i32, pub recipient_id: i32, pub content: String, pub deleted: bool, pub read: bool, pub published: chrono::NaiveDateTime, pub updated: Option, pub ap_id: String, pub local: bool, pub creator_name: String, pub creator_preferred_username: Option, pub creator_avatar: Option, pub creator_actor_id: String, pub creator_local: bool, pub recipient_name: String, pub recipient_preferred_username: Option, pub recipient_avatar: Option, pub recipient_actor_id: String, pub recipient_local: bool, } pub struct PrivateMessageQueryBuilder<'a> { conn: &'a PgConnection, query: super::private_message_view::private_message_view::BoxedQuery<'a, Pg>, for_recipient_id: i32, unread_only: bool, page: Option, limit: Option, } impl<'a> PrivateMessageQueryBuilder<'a> { pub fn create(conn: &'a PgConnection, for_recipient_id: i32) -> Self { use super::private_message_view::private_message_view::dsl::*; let query = private_message_view.into_boxed(); PrivateMessageQueryBuilder { conn, query, for_recipient_id, unread_only: false, page: None, limit: None, } } pub fn unread_only(mut self, unread_only: bool) -> Self { self.unread_only = unread_only; self } pub fn page>(mut self, page: T) -> Self { self.page = page.get_optional(); self } pub fn limit>(mut self, limit: T) -> Self { self.limit = limit.get_optional(); self } pub fn list(self) -> Result, Error> { use super::private_message_view::private_message_view::dsl::*; let mut query = self.query.filter(deleted.eq(false)); // If its unread, I only want the ones to me if self.unread_only { query = query .filter(read.eq(false)) .filter(recipient_id.eq(self.for_recipient_id)); } // Otherwise, I want the ALL view to show both sent and received else { query = query.filter( recipient_id .eq(self.for_recipient_id) .or(creator_id.eq(self.for_recipient_id)), ) } let (limit, offset) = limit_and_offset(self.page, self.limit); query .limit(limit) .offset(offset) .order_by(published.desc()) .load::(self.conn) } } impl PrivateMessageView { pub fn read(conn: &PgConnection, from_private_message_id: i32) -> Result { use super::private_message_view::private_message_view::dsl::*; let mut query = private_message_view.into_boxed(); query = query .filter(id.eq(from_private_message_id)) .order_by(published.desc()); query.first::(conn) } }