2022-04-07 11:27:06 +02:00
|
|
|
pub use search::{
|
2022-06-02 10:48:02 +02:00
|
|
|
SearchQuery, SearchResult, DEFAULT_CROP_LENGTH, DEFAULT_CROP_MARKER,
|
2022-04-11 14:18:47 +02:00
|
|
|
DEFAULT_HIGHLIGHT_POST_TAG, DEFAULT_HIGHLIGHT_PRE_TAG, DEFAULT_SEARCH_LIMIT,
|
2022-04-07 11:27:06 +02:00
|
|
|
};
|
2021-09-28 22:22:59 +02:00
|
|
|
pub use updates::{apply_settings_to_builder, Checked, Facets, Settings, Unchecked};
|
2021-06-14 21:26:35 +02:00
|
|
|
|
2021-05-26 22:52:06 +02:00
|
|
|
mod dump;
|
2021-10-06 13:01:02 +02:00
|
|
|
pub mod error;
|
2021-05-31 16:03:39 +02:00
|
|
|
mod search;
|
2021-12-02 16:03:26 +01:00
|
|
|
pub mod updates;
|
2021-10-06 13:01:02 +02:00
|
|
|
|
|
|
|
#[allow(clippy::module_inception)]
|
2021-10-04 12:15:21 +02:00
|
|
|
mod index;
|
2021-04-01 16:44:42 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub use index::{Document, IndexMeta, IndexStats};
|
2021-03-04 14:20:19 +01:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
#[cfg(not(test))]
|
|
|
|
pub use index::Index;
|
2021-09-24 11:53:11 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
#[cfg(test)]
|
|
|
|
pub use test::MockIndex as Index;
|
2021-09-24 11:53:11 +02:00
|
|
|
|
2021-10-06 14:34:14 +02:00
|
|
|
/// The index::test module provides means of mocking an index instance. I can be used throughout the
|
|
|
|
/// code for unit testing, in places where an index would normally be used.
|
2021-10-04 12:15:21 +02:00
|
|
|
#[cfg(test)]
|
2021-10-04 18:27:42 +02:00
|
|
|
pub mod test {
|
2021-10-06 14:34:14 +02:00
|
|
|
use std::path::Path;
|
2021-10-04 12:15:21 +02:00
|
|
|
use std::path::PathBuf;
|
2021-12-02 16:03:26 +01:00
|
|
|
use std::sync::Arc;
|
2021-09-24 11:53:11 +02:00
|
|
|
|
2022-01-19 11:21:19 +01:00
|
|
|
use milli::update::IndexerConfig;
|
2021-12-02 16:03:26 +01:00
|
|
|
use milli::update::{DocumentAdditionResult, DocumentDeletionResult, IndexDocumentsMethod};
|
|
|
|
use nelson::Mocker;
|
2021-10-04 12:15:21 +02:00
|
|
|
use uuid::Uuid;
|
2021-09-24 11:53:11 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
use super::error::Result;
|
2021-10-06 13:01:02 +02:00
|
|
|
use super::index::Index;
|
2022-05-25 11:51:26 +02:00
|
|
|
use super::Document;
|
2021-10-06 13:01:02 +02:00
|
|
|
use super::{Checked, IndexMeta, IndexStats, SearchQuery, SearchResult, Settings};
|
2021-12-02 16:03:26 +01:00
|
|
|
use crate::update_file_store::UpdateFileStore;
|
2021-10-04 12:15:21 +02:00
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
#[derive(Clone)]
|
2021-10-04 18:27:42 +02:00
|
|
|
pub enum MockIndex {
|
2021-12-02 16:03:26 +01:00
|
|
|
Real(Index),
|
|
|
|
Mock(Arc<Mocker>),
|
2021-10-04 18:27:42 +02:00
|
|
|
}
|
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
impl MockIndex {
|
2021-12-02 16:03:26 +01:00
|
|
|
pub fn mock(mocker: Mocker) -> Self {
|
|
|
|
Self::Mock(Arc::new(mocker))
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
2021-03-04 15:09:00 +01:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn open(
|
|
|
|
path: impl AsRef<Path>,
|
|
|
|
size: usize,
|
|
|
|
uuid: Uuid,
|
2022-01-19 11:21:19 +01:00
|
|
|
update_handler: Arc<IndexerConfig>,
|
2021-10-04 12:15:21 +02:00
|
|
|
) -> Result<Self> {
|
2021-12-02 16:03:26 +01:00
|
|
|
let index = Index::open(path, size, uuid, update_handler)?;
|
|
|
|
Ok(Self::Real(index))
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
2021-03-04 15:09:00 +01:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn load_dump(
|
|
|
|
src: impl AsRef<Path>,
|
|
|
|
dst: impl AsRef<Path>,
|
|
|
|
size: usize,
|
2022-01-19 11:21:19 +01:00
|
|
|
update_handler: &IndexerConfig,
|
2021-10-04 12:15:21 +02:00
|
|
|
) -> anyhow::Result<()> {
|
2021-12-02 16:03:26 +01:00
|
|
|
Index::load_dump(src, dst, size, update_handler)
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
2021-03-15 10:17:41 +01:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn uuid(&self) -> Uuid {
|
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.uuid(),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("uuid").call(()) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
2021-06-17 14:36:32 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn stats(&self) -> Result<IndexStats> {
|
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.stats(),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("stats").call(()) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
2021-06-17 14:36:32 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn meta(&self) -> Result<IndexMeta> {
|
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.meta(),
|
|
|
|
MockIndex::Mock(_) => todo!(),
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn settings(&self) -> Result<Settings<Checked>> {
|
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.settings(),
|
|
|
|
MockIndex::Mock(_) => todo!(),
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
2021-03-15 11:01:14 +01:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn retrieve_documents<S: AsRef<str>>(
|
|
|
|
&self,
|
|
|
|
offset: usize,
|
|
|
|
limit: usize,
|
|
|
|
attributes_to_retrieve: Option<Vec<S>>,
|
2022-05-25 11:51:26 +02:00
|
|
|
) -> Result<(u64, Vec<Document>)> {
|
2021-10-04 12:15:21 +02:00
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => {
|
2021-10-06 13:01:02 +02:00
|
|
|
index.retrieve_documents(offset, limit, attributes_to_retrieve)
|
|
|
|
}
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Mock(_) => todo!(),
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
2021-04-01 16:44:42 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
pub fn retrieve_document<S: AsRef<str>>(
|
|
|
|
&self,
|
|
|
|
doc_id: String,
|
|
|
|
attributes_to_retrieve: Option<Vec<S>>,
|
2022-05-25 11:51:26 +02:00
|
|
|
) -> Result<Document> {
|
2021-10-04 12:15:21 +02:00
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.retrieve_document(doc_id, attributes_to_retrieve),
|
|
|
|
MockIndex::Mock(_) => todo!(),
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn size(&self) -> u64 {
|
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.size(),
|
|
|
|
MockIndex::Mock(_) => todo!(),
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn snapshot(&self, path: impl AsRef<Path>) -> Result<()> {
|
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.snapshot(path),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("snapshot").call(path.as_ref()) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
pub fn close(self) {
|
2021-10-04 12:15:21 +02:00
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.close(),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("close").call(()) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
pub fn perform_search(&self, query: SearchQuery) -> Result<SearchResult> {
|
2021-10-04 12:15:21 +02:00
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.perform_search(query),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("perform_search").call(query) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
2021-12-02 16:03:26 +01:00
|
|
|
|
|
|
|
pub fn dump(&self, path: impl AsRef<Path>) -> Result<()> {
|
2021-10-04 12:15:21 +02:00
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.dump(path),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("dump").call(path.as_ref()) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
pub fn update_documents(
|
|
|
|
&self,
|
|
|
|
method: IndexDocumentsMethod,
|
|
|
|
primary_key: Option<String>,
|
|
|
|
file_store: UpdateFileStore,
|
2022-01-19 11:21:19 +01:00
|
|
|
contents: impl Iterator<Item = Uuid>,
|
2021-12-02 16:03:26 +01:00
|
|
|
) -> Result<DocumentAdditionResult> {
|
|
|
|
match self {
|
|
|
|
MockIndex::Real(index) => {
|
2022-01-19 11:21:19 +01:00
|
|
|
index.update_documents(method, primary_key, file_store, contents)
|
2021-12-02 16:03:26 +01:00
|
|
|
}
|
|
|
|
MockIndex::Mock(mocker) => unsafe {
|
2022-01-19 11:21:19 +01:00
|
|
|
mocker
|
|
|
|
.get("update_documents")
|
|
|
|
.call((method, primary_key, file_store, contents))
|
2021-12-02 16:03:26 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update_settings(&self, settings: &Settings<Checked>) -> Result<()> {
|
|
|
|
match self {
|
|
|
|
MockIndex::Real(index) => index.update_settings(settings),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("update_settings").call(settings) },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update_primary_key(&self, primary_key: String) -> Result<IndexMeta> {
|
|
|
|
match self {
|
|
|
|
MockIndex::Real(index) => index.update_primary_key(primary_key),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("update_primary_key").call(primary_key) },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn delete_documents(&self, ids: &[String]) -> Result<DocumentDeletionResult> {
|
|
|
|
match self {
|
|
|
|
MockIndex::Real(index) => index.delete_documents(ids),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("delete_documents").call(ids) },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clear_documents(&self) -> Result<()> {
|
2021-10-04 12:15:21 +02:00
|
|
|
match self {
|
2021-12-02 16:03:26 +01:00
|
|
|
MockIndex::Real(index) => index.clear_documents(),
|
|
|
|
MockIndex::Mock(m) => unsafe { m.get("clear_documents").call(()) },
|
2021-10-04 12:15:21 +02:00
|
|
|
}
|
|
|
|
}
|
2021-03-15 11:01:14 +01:00
|
|
|
}
|
2021-09-27 16:48:03 +02:00
|
|
|
|
2021-10-04 12:15:21 +02:00
|
|
|
#[test]
|
|
|
|
fn test_faux_index() {
|
2021-10-04 18:27:42 +02:00
|
|
|
let faux = Mocker::default();
|
2021-10-06 13:01:02 +02:00
|
|
|
faux.when("snapshot")
|
2021-10-04 18:27:42 +02:00
|
|
|
.times(2)
|
2021-10-06 13:01:02 +02:00
|
|
|
.then(|_: &Path| -> Result<()> { Ok(()) });
|
2021-10-04 12:15:21 +02:00
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
let index = MockIndex::mock(faux);
|
2021-10-04 12:15:21 +02:00
|
|
|
|
|
|
|
let path = PathBuf::from("hello");
|
|
|
|
index.snapshot(&path).unwrap();
|
|
|
|
index.snapshot(&path).unwrap();
|
2021-09-27 16:48:03 +02:00
|
|
|
}
|
2021-10-04 18:27:42 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_faux_unexisting_method_stub() {
|
|
|
|
let faux = Mocker::default();
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
let index = MockIndex::mock(faux);
|
2021-10-04 18:27:42 +02:00
|
|
|
|
|
|
|
let path = PathBuf::from("hello");
|
|
|
|
index.snapshot(&path).unwrap();
|
|
|
|
index.snapshot(&path).unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_faux_panic() {
|
|
|
|
let faux = Mocker::default();
|
2021-10-06 13:01:02 +02:00
|
|
|
faux.when("snapshot")
|
2021-10-04 18:27:42 +02:00
|
|
|
.times(2)
|
|
|
|
.then(|_: &Path| -> Result<()> {
|
|
|
|
panic!();
|
|
|
|
});
|
|
|
|
|
2021-12-02 16:03:26 +01:00
|
|
|
let index = MockIndex::mock(faux);
|
2021-10-04 18:27:42 +02:00
|
|
|
|
|
|
|
let path = PathBuf::from("hello");
|
|
|
|
index.snapshot(&path).unwrap();
|
|
|
|
index.snapshot(&path).unwrap();
|
|
|
|
}
|
2021-03-04 12:38:55 +01:00
|
|
|
}
|