use super::manager::registry::fts_err;
use super::manager::{FtsCollectionManager, resident_index};
use crate::engine::fts::LiteFtsIndex;
use crate::error::LiteError;
impl FtsCollectionManager {
pub fn set_collection_analyzer(
&mut self,
collection: &str,
analyzer_name: &str,
) -> Result<(), LiteError> {
self.collection_analyzers
.insert(collection.to_string(), analyzer_name.to_string());
for key in self.collection_keys(collection) {
if let Some(idx) = self.indices.get(&key) {
idx.set_collection_analyzer(0, 0, &key, analyzer_name)
.map_err(|e| fts_err(collection, e))?;
}
}
Ok(())
}
pub fn set_collection_fuzzy(&mut self, collection: &str, fuzzy: bool) -> Result<(), LiteError> {
self.collection_fuzzy_defaults
.insert(collection.to_string(), fuzzy);
for key in self.collection_keys(collection) {
if let Some(idx) = self.indices.get(&key) {
idx.set_collection_fuzzy(0, 0, &key, fuzzy)
.map_err(|e| fts_err(collection, e))?;
}
}
Ok(())
}
pub(crate) fn analyzer_for(&self, collection: &str) -> Option<&str> {
self.collection_analyzers
.get(collection)
.map(String::as_str)
}
pub(crate) fn fuzzy_for(&self, collection: &str) -> Option<bool> {
self.collection_fuzzy_defaults.get(collection).copied()
}
pub(crate) fn new_index_for(
&self,
collection: &str,
key: &str,
) -> Result<LiteFtsIndex, LiteError> {
let idx = resident_index(std::sync::Arc::clone(&self.governor));
if let Some(name) = self.analyzer_for(collection) {
idx.set_collection_analyzer(0, 0, key, name)
.map_err(|e| fts_err(collection, e))?;
}
if let Some(fuzzy) = self.fuzzy_for(collection) {
idx.set_collection_fuzzy(0, 0, key, fuzzy)
.map_err(|e| fts_err(collection, e))?;
}
Ok(idx)
}
}
#[cfg(test)]
mod tests {
use super::FtsCollectionManager;
use crate::engine::fts::manager::test_governor;
const DOC_KEY: &str = "col";
fn doc_index_config(mgr: &FtsCollectionManager) -> (Option<String>, bool) {
let idx = mgr
.indices
.get(DOC_KEY)
.expect("whole-document index must exist");
(
idx.get_collection_analyzer(0, 0, DOC_KEY)
.expect("meta read must succeed"),
idx.get_collection_fuzzy(0, 0, DOC_KEY)
.expect("meta read must succeed"),
)
}
#[test]
fn setting_analyzer_leaves_fuzzy_default_unchanged() {
let mut mgr = FtsCollectionManager::new(test_governor());
mgr.index_document("col", "doc1", "the quick brown fox")
.expect("index update must succeed");
mgr.set_collection_fuzzy("col", true)
.expect("config binding must succeed");
mgr.set_collection_analyzer("col", "german")
.expect("config binding must succeed");
let (analyzer, fuzzy) = doc_index_config(&mgr);
assert_eq!(analyzer.as_deref(), Some("german"));
assert!(
fuzzy,
"binding the analyzer must not clear the fuzzy default"
);
assert_eq!(mgr.fuzzy_for("col"), Some(true));
}
#[test]
fn setting_fuzzy_default_leaves_analyzer_unchanged() {
let mut mgr = FtsCollectionManager::new(test_governor());
mgr.index_document("col", "doc1", "the quick brown fox")
.expect("index update must succeed");
mgr.set_collection_analyzer("col", "german")
.expect("config binding must succeed");
mgr.set_collection_fuzzy("col", true)
.expect("config binding must succeed");
let (analyzer, fuzzy) = doc_index_config(&mgr);
assert_eq!(
analyzer.as_deref(),
Some("german"),
"binding the fuzzy default must not clear the analyzer"
);
assert!(fuzzy);
assert_eq!(mgr.analyzer_for("col"), Some("german"));
}
#[test]
fn config_bound_before_any_index_is_inherited_by_later_indexes() {
let mut mgr = FtsCollectionManager::new(test_governor());
mgr.set_collection_analyzer("col", "german")
.expect("config binding must succeed");
mgr.set_collection_fuzzy("col", true)
.expect("config binding must succeed");
assert!(mgr.indices.is_empty());
mgr.index_document("col", "doc1", "der schnelle braune fuchs")
.expect("index update must succeed");
let (analyzer, fuzzy) = doc_index_config(&mgr);
assert_eq!(analyzer.as_deref(), Some("german"));
assert!(fuzzy);
}
#[test]
fn config_bound_before_any_index_is_inherited_by_later_field_indexes() {
let mut mgr = FtsCollectionManager::new(test_governor());
mgr.set_collection_analyzer("col", "german")
.expect("config binding must succeed");
mgr.set_collection_fuzzy("col", true)
.expect("config binding must succeed");
mgr.index_field("col", "title", "doc1", "der schnelle braune fuchs")
.expect("index update must succeed");
let key = "col:title";
let idx = mgr.indices.get(key).expect("field index must exist");
assert_eq!(
idx.get_collection_analyzer(0, 0, key)
.expect("meta read must succeed")
.as_deref(),
Some("german")
);
assert!(
idx.get_collection_fuzzy(0, 0, key)
.expect("meta read must succeed")
);
}
#[test]
fn binding_nothing_leaves_the_collection_at_its_defaults() {
let mut mgr = FtsCollectionManager::new(test_governor());
mgr.index_document("col", "doc1", "the quick brown fox")
.expect("index update must succeed");
let (analyzer, fuzzy) = doc_index_config(&mgr);
assert_eq!(analyzer, None);
assert!(!fuzzy);
assert_eq!(mgr.analyzer_for("col"), None);
assert_eq!(mgr.fuzzy_for("col"), None);
}
#[test]
fn config_is_bound_to_the_exact_collection_name() {
let mut mgr = FtsCollectionManager::new(test_governor());
mgr.set_collection_analyzer("a:b", "german")
.expect("config binding must succeed");
mgr.set_collection_fuzzy("a:b", true)
.expect("config binding must succeed");
assert_eq!(mgr.analyzer_for("a:b"), Some("german"));
assert_eq!(mgr.fuzzy_for("a:b"), Some(true));
assert_eq!(mgr.analyzer_for("a"), None);
assert_eq!(mgr.fuzzy_for("a"), None);
}
}