]> Untitled Git - lemmy.git/commitdiff
Use a dedicated structure in order to search posts
authorLyra <teromene@teromene.fr>
Sat, 7 Dec 2019 12:03:03 +0000 (13:03 +0100)
committerLyra <teromene@teromene.fr>
Sat, 7 Dec 2019 12:03:03 +0000 (13:03 +0100)
server/src/api/post.rs
server/src/api/site.rs
server/src/api/user.rs
server/src/db/post_view.rs
server/src/feeds.rs
server/src/websocket/server.rs

index 5df42990ae8567b2f358ecacaabc5f61df537311..e507aba338d1ac2c59d7a0ed34dd86d7fa39c819 100644 (file)
@@ -238,21 +238,13 @@ impl Perform<GetPostsResponse> for Oper<GetPosts> {
     let type_ = ListingType::from_str(&data.type_)?;
     let sort = SortType::from_str(&data.sort)?;
 
-    let posts = match PostView::list(
-      &conn,
-      type_,
-      &sort,
-      data.community_id,
-      None,
-      None,
-      None,
-      user_id,
-      show_nsfw,
-      false,
-      false,
-      data.page,
-      data.limit,
-    ) {
+    let posts = match PostViewQuery::create(&conn, type_, &sort, show_nsfw, false, false)
+      .for_community_id_optional(data.community_id)
+      .my_user_id_optional(user_id)
+      .page_optional(data.page)
+      .limit_optional(data.limit)
+      .list()
+    {
       Ok(posts) => posts,
       Err(_e) => return Err(APIError::err(&self.op, "couldnt_get_posts"))?,
     };
index 618295fca372cda377437a3e00f497b84682182e..8ed5fc257d8223672e4565ce8564c4d6637985bb 100644 (file)
@@ -319,21 +319,12 @@ impl Perform<SearchResponse> for Oper<Search> {
 
     match type_ {
       SearchType::Posts => {
-        posts = PostView::list(
-          &conn,
-          ListingType::All,
-          &sort,
-          data.community_id,
-          None,
-          Some(data.q.to_owned()),
-          None,
-          None,
-          true,
-          false,
-          false,
-          data.page,
-          data.limit,
-        )?;
+        posts = PostViewQuery::create(&conn, ListingType::All, &sort, true, false, false)
+          .for_community_id_optional(data.community_id)
+          .search_term(data.q.to_owned())
+          .page_optional(data.page)
+          .limit_optional(data.limit)
+          .list()?;
       }
       SearchType::Comments => {
         comments = CommentView::list(
@@ -363,21 +354,13 @@ impl Perform<SearchResponse> for Oper<Search> {
         users = UserView::list(&conn, &sort, Some(data.q.to_owned()), data.page, data.limit)?;
       }
       SearchType::All => {
-        posts = PostView::list(
-          &conn,
-          ListingType::All,
-          &sort,
-          data.community_id,
-          None,
-          Some(data.q.to_owned()),
-          None,
-          None,
-          true,
-          false,
-          false,
-          data.page,
-          data.limit,
-        )?;
+        posts = PostViewQuery::create(&conn, ListingType::All, &sort, true, false, false)
+          .for_community_id_optional(data.community_id)
+          .search_term(data.q.to_owned())
+          .page_optional(data.page)
+          .limit_optional(data.limit)
+          .list()?;
+
         comments = CommentView::list(
           &conn,
           &sort,
@@ -401,21 +384,12 @@ impl Perform<SearchResponse> for Oper<Search> {
         users = UserView::list(&conn, &sort, Some(data.q.to_owned()), data.page, data.limit)?;
       }
       SearchType::Url => {
-        posts = PostView::list(
-          &conn,
-          ListingType::All,
-          &sort,
-          data.community_id,
-          None,
-          None,
-          Some(data.q.to_owned()),
-          None,
-          true,
-          false,
-          false,
-          data.page,
-          data.limit,
-        )?;
+        posts = PostViewQuery::create(&conn, ListingType::All, &sort, true, false, false)
+          .for_community_id_optional(data.community_id)
+          .url_search(data.q.to_owned())
+          .page_optional(data.page)
+          .limit_optional(data.limit)
+          .list()?;
       }
     };
 
index e15563b0c8ce670befbc0cd956ba3dfbfbcc0780..da0772546766e450827b5e54ead9aa8972e81439 100644 (file)
@@ -366,40 +366,26 @@ impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
 
     let user_view = UserView::read(&conn, user_details_id)?;
 
+    let mut posts_query = PostViewQuery::create(
+      &conn,
+      ListingType::All,
+      &sort,
+      show_nsfw,
+      data.saved_only,
+      false,
+    )
+    .for_community_id_optional(data.community_id)
+    .my_user_id_optional(user_id)
+    .page_optional(data.page)
+    .limit_optional(data.limit);
+
     // If its saved only, you don't care what creator it was
-    let posts = if data.saved_only {
-      PostView::list(
-        &conn,
-        ListingType::All,
-        &sort,
-        data.community_id,
-        None,
-        None,
-        None,
-        Some(user_details_id),
-        show_nsfw,
-        data.saved_only,
-        false,
-        data.page,
-        data.limit,
-      )?
-    } else {
-      PostView::list(
-        &conn,
-        ListingType::All,
-        &sort,
-        data.community_id,
-        Some(user_details_id),
-        None,
-        None,
-        user_id,
-        show_nsfw,
-        data.saved_only,
-        false,
-        data.page,
-        data.limit,
-      )?
-    };
+    if !data.saved_only {
+      posts_query = posts_query.for_creator_id(user_details_id);
+    }
+
+    let posts = posts_query.list()?;
+
     let comments = if data.saved_only {
       CommentView::list(
         &conn,
@@ -777,21 +763,10 @@ impl Perform<LoginResponse> for Oper<DeleteAccount> {
     }
 
     // Posts
-    let posts = PostView::list(
-      &conn,
-      ListingType::All,
-      &SortType::New,
-      None,
-      Some(user_id),
-      None,
-      None,
-      None,
-      true,
-      false,
-      false,
-      None,
-      Some(std::i64::MAX),
-    )?;
+    let posts = PostViewQuery::create(&conn, ListingType::All, &SortType::New, true, false, false)
+      .for_creator_id(user_id)
+      .limit(std::i64::MAX)
+      .list()?;
 
     for post in &posts {
       let post_form = PostForm {
index 51dea027fd13eacf7b7fd7112ec48f3cc89e65f7..23454b6e64ad84a3a3f526ee46160edd728c89d0 100644 (file)
@@ -1,4 +1,6 @@
+use super::post_view::post_view::BoxedQuery;
 use super::*;
+use diesel::pg::Pg;
 
 // The faked schema since diesel doesn't do views
 table! {
@@ -73,74 +75,34 @@ pub struct PostView {
   pub saved: Option<bool>,
 }
 
-impl PostView {
-  pub fn list(
-    conn: &PgConnection,
-    type_: ListingType,
-    sort: &SortType,
-    for_community_id: Option<i32>,
-    for_creator_id: Option<i32>,
-    search_term: Option<String>,
-    url_search: Option<String>,
-    my_user_id: Option<i32>,
+pub struct PostViewQuery<'a> {
+  conn: &'a PgConnection,
+  query: BoxedQuery<'a, Pg>,
+  my_user_id: Option<i32>,
+  page: Option<i64>,
+  limit: Option<i64>,
+}
+
+impl<'a> PostViewQuery<'a> {
+  pub fn create(
+    conn: &'a PgConnection,
+    r#type: ListingType,
+    sort: &'a SortType,
     show_nsfw: bool,
     saved_only: bool,
     unread_only: bool,
-    page: Option<i64>,
-    limit: Option<i64>,
-  ) -> Result<Vec<Self>, Error> {
+  ) -> Self {
     use super::post_view::post_view::dsl::*;
 
-    let (limit, offset) = limit_and_offset(page, limit);
-
     let mut query = post_view.into_boxed();
 
-    if let Some(for_creator_id) = for_creator_id {
-      query = query.filter(creator_id.eq(for_creator_id));
-    };
-
-    if let Some(search_term) = search_term {
-      query = query.filter(name.ilike(fuzzy_search(&search_term)));
-    };
-
-    if let Some(url_search) = url_search {
-      query = query.filter(url.eq(url_search));
-    };
-
-    if let Some(for_community_id) = for_community_id {
-      query = query.filter(community_id.eq(for_community_id));
-      query = query.then_order_by(stickied.desc());
-    };
-
-    // TODO these are wrong, bc they'll only show saved for your logged in user, not theirs
-    if saved_only {
-      query = query.filter(saved.eq(true));
-    };
-
-    if unread_only {
-      query = query.filter(read.eq(false));
-    };
-
-    match type_ {
+    match r#type {
       ListingType::Subscribed => {
         query = query.filter(subscribed.eq(true));
       }
       _ => {}
     };
 
-    // The view lets you pass a null user_id, if you're not logged in
-    if let Some(my_user_id) = my_user_id {
-      query = query.filter(user_id.eq(my_user_id));
-    } else {
-      query = query.filter(user_id.is_null());
-    }
-
-    if !show_nsfw {
-      query = query
-        .filter(nsfw.eq(false))
-        .filter(community_nsfw.eq(false));
-    };
-
     query = match sort {
       SortType::Hot => query
         .then_order_by(hot_rank.desc())
@@ -161,7 +123,125 @@ impl PostView {
         .then_order_by(score.desc()),
     };
 
-    query = query
+    if !show_nsfw {
+      query = query
+        .filter(nsfw.eq(false))
+        .filter(community_nsfw.eq(false));
+    };
+
+    // TODO these are wrong, bc they'll only show saved for your logged in user, not theirs
+    if saved_only {
+      query = query.filter(saved.eq(true));
+    };
+
+    if unread_only {
+      query = query.filter(read.eq(false));
+    };
+
+    PostViewQuery {
+      conn,
+      query,
+      my_user_id: None,
+      page: None,
+      limit: None,
+    }
+  }
+
+  pub fn for_community_id(mut self, for_community_id: i32) -> Self {
+    use super::post_view::post_view::dsl::*;
+    self.query = self.query.filter(community_id.eq(for_community_id));
+    self.query = self.query.then_order_by(stickied.desc());
+    self
+  }
+
+  pub fn for_community_id_optional(self, for_community_id: Option<i32>) -> Self {
+    match for_community_id {
+      Some(for_community_id) => self.for_community_id(for_community_id),
+      None => self,
+    }
+  }
+
+  pub fn for_creator_id(mut self, for_creator_id: i32) -> Self {
+    use super::post_view::post_view::dsl::*;
+    self.query = self.query.filter(creator_id.eq(for_creator_id));
+    self
+  }
+
+  pub fn for_creator_id_optional(self, for_creator_id: Option<i32>) -> Self {
+    match for_creator_id {
+      Some(for_creator_id) => self.for_creator_id(for_creator_id),
+      None => self,
+    }
+  }
+
+  pub fn search_term(mut self, search_term: String) -> Self {
+    use super::post_view::post_view::dsl::*;
+    self.query = self.query.filter(name.ilike(fuzzy_search(&search_term)));
+    self
+  }
+
+  pub fn search_term_optional(self, search_term: Option<String>) -> Self {
+    match search_term {
+      Some(search_term) => self.search_term(search_term),
+      None => self,
+    }
+  }
+
+  pub fn url_search(mut self, url_search: String) -> Self {
+    use super::post_view::post_view::dsl::*;
+    self.query = self.query.filter(url.eq(url_search));
+    self
+  }
+
+  pub fn url_search_optional(self, url_search: Option<String>) -> Self {
+    match url_search {
+      Some(url_search) => self.url_search(url_search),
+      None => self,
+    }
+  }
+
+  pub fn my_user_id(mut self, my_user_id: i32) -> Self {
+    self.my_user_id = Some(my_user_id);
+    self
+  }
+
+  pub fn my_user_id_optional(mut self, my_user_id: Option<i32>) -> Self {
+    self.my_user_id = my_user_id;
+    self
+  }
+
+  pub fn page(mut self, page: i64) -> Self {
+    self.page = Some(page);
+    self
+  }
+
+  pub fn page_optional(mut self, page: Option<i64>) -> Self {
+    self.page = page;
+    self
+  }
+
+  pub fn limit(mut self, limit: i64) -> Self {
+    self.limit = Some(limit);
+    self
+  }
+
+  pub fn limit_optional(mut self, limit: Option<i64>) -> Self {
+    self.limit = limit;
+    self
+  }
+
+  pub fn list(mut self) -> Result<Vec<PostView>, Error> {
+    use super::post_view::post_view::dsl::*;
+    // The view lets you pass a null user_id, if you're not logged in
+    self.query = if let Some(my_user_id) = self.my_user_id {
+      self.query.filter(user_id.eq(my_user_id))
+    } else {
+      self.query.filter(user_id.is_null())
+    };
+
+    let (limit, offset) = limit_and_offset(self.page, self.limit);
+    let query = self
+      .query
       .limit(limit)
       .offset(offset)
       .filter(removed.eq(false))
@@ -169,9 +249,11 @@ impl PostView {
       .filter(community_removed.eq(false))
       .filter(community_deleted.eq(false));
 
-    query.load::<Self>(conn)
+    query.load::<PostView>(self.conn)
   }
+}
 
+impl PostView {
   pub fn read(
     conn: &PgConnection,
     from_post_id: i32,
@@ -344,38 +426,31 @@ mod tests {
       nsfw: false,
     };
 
-    let read_post_listings_with_user = PostView::list(
+    let read_post_listings_with_user = PostViewQuery::create(
       &conn,
       ListingType::Community,
       &SortType::New,
-      Some(inserted_community.id),
-      None,
-      None,
-      None,
-      Some(inserted_user.id),
       false,
       false,
       false,
-      None,
-      None,
     )
+    .for_community_id(inserted_community.id)
+    .my_user_id(inserted_user.id)
+    .list()
     .unwrap();
-    let read_post_listings_no_user = PostView::list(
+
+    let read_post_listings_no_user = PostViewQuery::create(
       &conn,
       ListingType::Community,
       &SortType::New,
-      Some(inserted_community.id),
-      None,
-      None,
-      None,
-      None,
       false,
       false,
       false,
-      None,
-      None,
     )
+    .for_community_id(inserted_community.id)
+    .list()
     .unwrap();
+
     let read_post_listing_no_user = PostView::read(&conn, inserted_post.id, None).unwrap();
     let read_post_listing_with_user =
       PostView::read(&conn, inserted_post.id, Some(inserted_user.id)).unwrap();
index 8a1db28bc599b6e0e5febdfa9041a4b6f34c90bc..732e85cf54d73f7440913ebc39daaecc952f6116 100644 (file)
@@ -4,7 +4,7 @@ extern crate rss;
 use super::*;
 use crate::db::community::Community;
 use crate::db::community_view::SiteView;
-use crate::db::post_view::PostView;
+use crate::db::post_view::PostViewQuery;
 use crate::db::user::User_;
 use crate::db::{establish_connection, ListingType, SortType};
 use crate::Settings;
@@ -124,21 +124,10 @@ fn get_feed_internal(
     }
   }
 
-  let posts = PostView::list(
-    &conn,
-    ListingType::All,
-    sort_type,
-    community_id,
-    creator_id,
-    None,
-    None,
-    None,
-    true,
-    false,
-    false,
-    None,
-    None,
-  )?;
+  let posts = PostViewQuery::create(&conn, ListingType::All, sort_type, true, false, false)
+    .for_community_id_optional(community_id)
+    .for_creator_id_optional(creator_id)
+    .list()?;
 
   let mut items: Vec<Item> = Vec::new();
 
index 5bcca297624a1f6b3707cb2be45a1a70c6de7e2c..89172e560e0957c90c7a41e27c0fb63e1897b187 100644 (file)
@@ -134,21 +134,19 @@ impl ChatServer {
     use crate::db::post_view::*;
     use crate::db::*;
     let conn = establish_connection();
-    let posts = PostView::list(
+
+    let posts = PostViewQuery::create(
       &conn,
       ListingType::Community,
       &SortType::New,
-      Some(*community_id),
-      None,
-      None,
-      None,
-      None,
       false,
       false,
       false,
-      None,
-      Some(9999),
-    )?;
+    )
+    .for_community_id(*community_id)
+    .limit(9999)
+    .list()?;
+
     for post in posts {
       self.send_room_message(&post.id, message, skip_id);
     }