diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b3ae7ea23..28b9db455 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -142,15 +142,24 @@ fn search( handle: tauri::AppHandle, project_id: &str, query: &str, + limit: Option, + offset: Option, ) -> Result, Error> { let app_state = handle.state::(); + let query = search::SearchQuery { + project_id: project_id.to_string(), + q: query.to_string(), + limit: limit.unwrap_or(100), + offset, + }; + let deltas = app_state .deltas_searcher .lock() .unwrap() - .search(project_id, query) - .with_context(|| format!("Failed to search for {}", query))?; + .search(&query) + .with_context(|| format!("Failed to search for {:?}", query))?; Ok(deltas) } diff --git a/src-tauri/src/search/deltas.rs b/src-tauri/src/search/deltas.rs index f04629e07..54e33ae67 100644 --- a/src-tauri/src/search/deltas.rs +++ b/src-tauri/src/search/deltas.rs @@ -81,8 +81,8 @@ impl Deltas { }) } - pub fn search(&self, project_id: &str, query: &str) -> Result> { - search(&self.index, &self.reader, project_id, query) + pub fn search(&self, query: &SearchQuery) -> Result> { + search(&self.index, &self.reader, query) } pub fn reindex_project( @@ -262,11 +262,18 @@ fn index( Ok(()) } +#[derive(Debug, Default)] +pub struct SearchQuery { + pub q: String, + pub project_id: String, + pub limit: usize, + pub offset: Option, +} + pub fn search( index: &tantivy::Index, reader: &tantivy::IndexReader, - project_id: &str, - q: &str, + q: &SearchQuery, ) -> Result> { let query = &tantivy::query::QueryParser::for_index( index, @@ -278,7 +285,7 @@ pub fn search( .parse_query( format!( "version:\"{}\" AND project_id:\"{}\" AND ({})", - CURRENT_VERSION, project_id, q + CURRENT_VERSION, q.project_id, q.q, ) .as_str(), )?; @@ -288,7 +295,8 @@ pub fn search( let top_docs = searcher.search( query, - &collector::TopDocs::with_limit(10) + &collector::TopDocs::with_limit(q.limit) + .and_offset(q.offset.unwrap_or(0)) .order_by_u64_field(index.schema().get_field("timestamp_ms").unwrap()), )?; diff --git a/src-tauri/src/search/deltas_test.rs b/src-tauri/src/search/deltas_test.rs index 807f98bde..aec408d77 100644 --- a/src-tauri/src/search/deltas_test.rs +++ b/src-tauri/src/search/deltas_test.rs @@ -55,7 +55,12 @@ fn test_sorted_by_timestamp() { let write_result = searcher.index_session(&repo, &project, &session); assert!(write_result.is_ok()); - let search_result = searcher.search(&project.id, "hello world"); + let search_result = searcher.search(&super::SearchQuery { + project_id: project.id, + q: "hello world".to_string(), + limit: 10, + ..Default::default() + }); assert!(search_result.is_ok()); let search_result = search_result.unwrap(); assert_eq!(search_result.len(), 2); @@ -92,7 +97,12 @@ fn test_simple() { let write_result = searcher.index_session(&repo, &project, &session); assert!(write_result.is_ok()); - let search_result1 = searcher.search(&project.id, "hello"); + let search_result1 = searcher.search(&super::SearchQuery { + project_id: project.id.clone(), + q: "hello".to_string(), + limit: 10, + ..Default::default() + }); assert!(search_result1.is_ok()); let search_result1 = search_result1.unwrap(); assert_eq!(search_result1.len(), 1); @@ -101,7 +111,12 @@ fn test_simple() { assert_eq!(search_result1[0].file_path, "test.txt"); assert_eq!(search_result1[0].index, 0); - let search_result2 = searcher.search(&project.id, "world"); + let search_result2 = searcher.search(&super::SearchQuery { + project_id: project.id.clone(), + q: "world".to_string(), + limit: 10, + ..Default::default() + }); assert!(search_result2.is_ok()); let search_result2 = search_result2.unwrap(); assert_eq!(search_result2.len(), 1); @@ -110,7 +125,12 @@ fn test_simple() { assert_eq!(search_result2[0].file_path, "test.txt"); assert_eq!(search_result2[0].index, 1); - let search_result3 = searcher.search(&project.id, "hello world"); + let search_result3 = searcher.search(&super::SearchQuery { + project_id: project.id.clone(), + q: "hello world".to_string(), + limit: 10, + ..Default::default() + }); println!("{:?}", search_result3); assert!(search_result3.is_ok()); let search_result3 = search_result3.unwrap(); @@ -122,7 +142,12 @@ fn test_simple() { assert_eq!(search_result3[1].project_id, project.id); assert_eq!(search_result3[1].file_path, "test.txt"); - let search_by_filename_result = searcher.search(&project.id, "test.txt"); + let search_by_filename_result = searcher.search(&super::SearchQuery { + project_id: project.id.clone(), + q: "test.txt".to_string(), + limit: 10, + ..Default::default() + }); assert!(search_by_filename_result.is_ok()); let search_by_filename_result = search_by_filename_result.unwrap(); assert_eq!(search_by_filename_result.len(), 2); @@ -130,7 +155,12 @@ fn test_simple() { assert_eq!(search_by_filename_result[0].project_id, project.id); assert_eq!(search_by_filename_result[0].file_path, "test.txt"); - let not_found_result = searcher.search("404", "hello world"); + let not_found_result = searcher.search(&super::SearchQuery { + project_id: "not found".to_string(), + q: "test.txt".to_string(), + limit: 10, + ..Default::default() + }); assert!(not_found_result.is_ok()); let not_found_result = not_found_result.unwrap(); assert_eq!(not_found_result.len(), 0); diff --git a/src-tauri/src/search/mod.rs b/src-tauri/src/search/mod.rs index e4a81e6c2..060fcf845 100644 --- a/src-tauri/src/search/mod.rs +++ b/src-tauri/src/search/mod.rs @@ -1,6 +1,6 @@ mod deltas; -pub use deltas::{Deltas, SearchResult}; +pub use deltas::{Deltas, SearchResult, SearchQuery}; #[cfg(test)] mod deltas_test; diff --git a/src/lib/search.ts b/src/lib/search.ts index 5204eae24..6b106773c 100644 --- a/src/lib/search.ts +++ b/src/lib/search.ts @@ -1,12 +1,16 @@ import { invoke } from '@tauri-apps/api'; export type SearchResult = { - projectId: string; - sessionId: string; - filePath: string; - // index of the delta in the session. - index: number; + projectId: string; + sessionId: string; + filePath: string; + // index of the delta in the session. + index: number; }; -export const search = (params: { projectId: string; query: string }) => - invoke('search', params); +export const search = (params: { + projectId: string; + query: string; + limit?: number; + offset?: number; +}) => invoke('search', params);