From 962fbcc50339be28384ec0a09c1a7a298c997b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mina=20Gali=C4=87?= Date: Thu, 23 Jul 2020 20:29:21 +0200 Subject: [PATCH] plume-model: refactor Searcher to have its own DbPool this way, we don't need to pass along a conn into the function. This should make splitting PlumeRocket up into its components a little easier. This PR is another attempt at fixing #799. --- plume-models/src/posts.rs | 4 +-- plume-models/src/search/searcher.rs | 52 +++++++++++++++++------------ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 73c0c915..c51ecade 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -78,14 +78,14 @@ impl Post { let _: Post = post.save_changes(conn)?; } - searcher.add_document(conn, &post)?; + searcher.add_document(&post)?; Ok(post) } pub fn update(&self, conn: &Connection, searcher: &Searcher) -> Result { diesel::update(self).set(self).execute(conn)?; let post = Self::get(conn, self.id)?; - searcher.update_document(conn, &post)?; + searcher.update_document(&post)?; Ok(post) } diff --git a/plume-models/src/search/searcher.rs b/plume-models/src/search/searcher.rs index 34a45b0b..1b1afc0e 100644 --- a/plume-models/src/search/searcher.rs +++ b/plume-models/src/search/searcher.rs @@ -1,6 +1,6 @@ use crate::{ - config::SearchTokenizerConfig, instance::Instance, posts::Post, schema::posts, - search::query::PlumeQuery, tags::Tag, Connection, Result, + config::SearchTokenizerConfig, db_conn::DbPool, instance::Instance, posts::Post, schema::posts, + search::query::PlumeQuery, tags::Tag, Result, }; use chrono::Datelike; use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; @@ -25,6 +25,7 @@ pub struct Searcher { index: Index, reader: IndexReader, writer: Mutex>, + dbpool: DbPool, } impl Searcher { @@ -67,7 +68,11 @@ impl Searcher { schema_builder.build() } - pub fn create(path: &dyn AsRef, tokenizers: &SearchTokenizerConfig) -> Result { + pub fn create( + path: &dyn AsRef, + dbpool: DbPool, + tokenizers: &SearchTokenizerConfig, + ) -> Result { let schema = Self::schema(); create_dir_all(path).map_err(|_| SearcherError::IndexCreationError)?; @@ -95,10 +100,15 @@ impl Searcher { .try_into() .map_err(|_| SearcherError::IndexCreationError)?, index, + dbpool, }) } - pub fn open(path: &dyn AsRef, tokenizers: &SearchTokenizerConfig) -> Result { + pub fn open( + path: &dyn AsRef, + dbpool: DbPool, + tokenizers: &SearchTokenizerConfig, + ) -> Result { let mut index = Index::open(MmapDirectory::open(path).map_err(|_| SearcherError::IndexOpeningError)?) .map_err(|_| SearcherError::IndexOpeningError)?; @@ -150,10 +160,11 @@ impl Searcher { } })?, index, + dbpool, }) } - pub fn add_document(&self, conn: &Connection, post: &Post) -> Result<()> { + pub fn add_document(&self, post: &Post) -> Result<()> { if !post.published { return Ok(()); } @@ -175,15 +186,16 @@ impl Searcher { let lang = schema.get_field("lang").unwrap(); let license = schema.get_field("license").unwrap(); + let conn = self.dbpool.get().unwrap(); let mut writer = self.writer.lock().unwrap(); let writer = writer.as_mut().unwrap(); writer.add_document(doc!( post_id => i64::from(post.id), - author => post.get_authors(conn)?.into_iter().map(|u| u.fqn).join(" "), + author => post.get_authors(&conn)?.into_iter().map(|u| u.fqn).join(" "), creation_date => i64::from(post.creation_date.num_days_from_ce()), - instance => Instance::get(conn, post.get_blog(conn)?.instance_id)?.public_domain, - tag => Tag::for_post(conn, post.id)?.into_iter().map(|t| t.tag).join(" "), - blog_name => post.get_blog(conn)?.title, + instance => Instance::get(&conn, post.get_blog(&conn)?.instance_id)?.public_domain, + tag => Tag::for_post(&conn, post.id)?.into_iter().map(|t| t.tag).join(" "), + blog_name => post.get_blog(&conn)?.title, content => post.content.get().clone(), subtitle => post.subtitle.clone(), title => post.title.clone(), @@ -203,17 +215,12 @@ impl Searcher { writer.delete_term(doc_id); } - pub fn update_document(&self, conn: &Connection, post: &Post) -> Result<()> { + pub fn update_document(&self, post: &Post) -> Result<()> { self.delete_document(post); - self.add_document(conn, post) + self.add_document(post) } - pub fn search_document( - &self, - conn: &Connection, - query: PlumeQuery, - (min, max): (i32, i32), - ) -> Vec { + pub fn search_document(&self, query: PlumeQuery, (min, max): (i32, i32)) -> Vec { let schema = self.index.schema(); let post_id = schema.get_field("post_id").unwrap(); @@ -222,24 +229,27 @@ impl Searcher { let searcher = self.reader.searcher(); let res = searcher.search(&query.into_query(), &collector).unwrap(); + let conn = self.dbpool.get().unwrap(); + res.get(min as usize..) .unwrap_or(&[]) .iter() .filter_map(|(_, doc_add)| { let doc = searcher.doc(*doc_add).ok()?; let id = doc.get_first(post_id)?; - Post::get(conn, id.i64_value() as i32).ok() + Post::get(&conn, id.i64_value() as i32).ok() //borrow checker don't want me to use filter_map or and_then here }) .collect() } - pub fn fill(&self, conn: &Connection) -> Result<()> { + pub fn fill(&self) -> Result<()> { + let conn = self.dbpool.get().unwrap(); for post in posts::table .filter(posts::published.eq(true)) - .load::(conn)? + .load::(&conn)? { - self.update_document(conn, &post)? + self.update_document(&post)? } Ok(()) }