use crate::types::{IndexingMode, JsonbCapabilities, SearchStrategy};
pub trait SearchStrategyCapability: Send + Sync {
fn supports_precomputed_index(&self) -> bool;
fn supports_jsonb_evaluation(&self) -> bool;
fn recommended_strategy(&self) -> SearchStrategy;
fn jsonb_capabilities(&self) -> JsonbCapabilities;
fn indexing_mode(&self) -> IndexingMode;
}
pub struct SqliteSearchStrategy {
strategy: SearchStrategy,
indexing_mode: IndexingMode,
}
impl SqliteSearchStrategy {
pub fn new() -> Self {
Self {
strategy: SearchStrategy::PrecomputedIndex,
indexing_mode: IndexingMode::Inline,
}
}
pub fn with_strategy(strategy: SearchStrategy) -> Self {
Self {
strategy,
indexing_mode: IndexingMode::Inline,
}
}
pub fn hybrid(indexed_params: Vec<String>) -> Self {
Self {
strategy: SearchStrategy::Hybrid { indexed_params },
indexing_mode: IndexingMode::Inline,
}
}
pub fn with_indexing_mode(mut self, mode: IndexingMode) -> Self {
self.indexing_mode = mode;
self
}
pub fn has_precomputed_index(&self, _resource_type: &str, param_name: &str) -> bool {
match &self.strategy {
SearchStrategy::PrecomputedIndex => true,
SearchStrategy::QueryTimeEvaluation => false,
SearchStrategy::Hybrid { indexed_params } => {
indexed_params.contains(¶m_name.to_string())
}
}
}
pub fn strategy(&self) -> &SearchStrategy {
&self.strategy
}
}
impl Default for SqliteSearchStrategy {
fn default() -> Self {
Self::new()
}
}
impl SearchStrategyCapability for SqliteSearchStrategy {
fn supports_precomputed_index(&self) -> bool {
true
}
fn supports_jsonb_evaluation(&self) -> bool {
false
}
fn recommended_strategy(&self) -> SearchStrategy {
SearchStrategy::PrecomputedIndex
}
fn jsonb_capabilities(&self) -> JsonbCapabilities {
JsonbCapabilities {
path_extraction: false, array_iteration: false, containment_operator: false, gin_index: false, }
}
fn indexing_mode(&self) -> IndexingMode {
self.indexing_mode.clone()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_strategy() {
let strategy = SqliteSearchStrategy::new();
assert!(strategy.supports_precomputed_index());
assert!(!strategy.supports_jsonb_evaluation()); assert!(matches!(
strategy.recommended_strategy(),
SearchStrategy::PrecomputedIndex
));
}
#[test]
fn test_hybrid_strategy() {
let strategy =
SqliteSearchStrategy::hybrid(vec!["identifier".to_string(), "name".to_string()]);
assert!(strategy.has_precomputed_index("Patient", "identifier"));
assert!(strategy.has_precomputed_index("Patient", "name"));
assert!(!strategy.has_precomputed_index("Patient", "birthdate"));
}
#[test]
fn test_jsonb_capabilities() {
let strategy = SqliteSearchStrategy::new();
let caps = strategy.jsonb_capabilities();
assert!(!caps.path_extraction);
assert!(!caps.array_iteration);
assert!(!caps.containment_operator);
assert!(!caps.gin_index);
}
#[test]
fn test_precomputed_index_strategy() {
let strategy = SqliteSearchStrategy::with_strategy(SearchStrategy::PrecomputedIndex);
assert!(strategy.has_precomputed_index("Patient", "identifier"));
assert!(strategy.has_precomputed_index("Patient", "anything"));
}
#[test]
fn test_query_time_strategy() {
let strategy = SqliteSearchStrategy::with_strategy(SearchStrategy::QueryTimeEvaluation);
assert!(!strategy.has_precomputed_index("Patient", "identifier"));
assert!(!strategy.has_precomputed_index("Patient", "anything"));
}
}