#![allow(clippy::expect_used)]
#![allow(unsafe_code)] #![allow(clippy::unwrap_used)] #![allow(invalid_value)] #![allow(dead_code)] #![allow(clippy::excessive_nesting)] #![allow(unused_mut)] #![allow(unused_assignments)] #![allow(clippy::derivable_impls)] #![allow(clippy::should_implement_trait)] #![allow(clippy::unnecessary_map_or)] #![allow(clippy::useless_asref)] #![allow(clippy::cast_precision_loss)]
#![allow(clippy::cast_possible_truncation)]
#![allow(clippy::cast_sign_loss)]
#![allow(clippy::cast_possible_wrap)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::cognitive_complexity)]
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::must_use_candidate)]
#![allow(clippy::return_self_not_must_use)]
#![allow(clippy::map_unwrap_or)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::redundant_closure_for_method_calls)]
#![allow(clippy::match_same_arms)]
#![allow(clippy::uninlined_format_args)]
#![allow(clippy::needless_pass_by_value)]
#![allow(clippy::unused_self)]
#![allow(clippy::unused_async)]
#![allow(clippy::format_in_format_args)]
#![allow(clippy::to_string_in_format_args)]
#![allow(clippy::unreadable_literal)]
#![allow(clippy::struct_excessive_bools)]
#![allow(clippy::panic)]
#![allow(clippy::float_cmp)]
#![allow(clippy::items_after_statements)]
#![allow(clippy::wildcard_imports)]
#![allow(clippy::used_underscore_binding)]
#![allow(clippy::used_underscore_items)]
#![allow(clippy::ptr_as_ptr)]
#![allow(clippy::ptr_cast_constness)]
#![allow(clippy::format_push_string)]
#![allow(clippy::implicit_clone)]
#![allow(clippy::missing_fields_in_debug)]
#![allow(clippy::needless_raw_string_hashes)]
#![allow(clippy::default_trait_access)]
#![allow(clippy::missing_panics_doc)]
#![allow(clippy::no_effect_underscore_binding)]
#![allow(rust_2024_compatibility)]
#![allow(tail_expr_drop_order)]
#![allow(clippy::unnecessary_wraps)]
#![allow(clippy::unchecked_time_subtraction)]
#![allow(clippy::semicolon_if_nothing_returned)]
#![allow(missing_docs)]
#![allow(unknown_lints)]
#![allow(clippy::unknown_lints)]
use do_memory_core::{Error, Result};
pub mod cache;
pub mod pool;
mod relationships;
mod resilient;
mod schema;
#[cfg(test)]
mod tests;
#[cfg(feature = "hybrid_search")]
mod fts5_schema;
pub mod storage;
pub mod trait_impls;
pub mod turso_config;
pub mod prepared;
pub mod metrics;
#[cfg(feature = "compression")]
pub mod compression;
#[cfg(feature = "compression")]
pub mod transport;
mod lib_impls;
pub use lib_impls::TursoStorage;
pub use lib_impls::{StorageMode, TursoConfig};
#[async_trait::async_trait]
pub trait SelfLearningMemoryExt {
async fn with_local_storage(
path: impl AsRef<std::path::Path> + Send,
) -> Result<do_memory_core::memory::SelfLearningMemory>;
async fn with_in_memory_storage() -> Result<do_memory_core::memory::SelfLearningMemory>;
}
#[async_trait::async_trait]
impl SelfLearningMemoryExt for do_memory_core::memory::SelfLearningMemory {
async fn with_local_storage(
path: impl AsRef<std::path::Path> + Send,
) -> Result<do_memory_core::memory::SelfLearningMemory> {
let storage = TursoStorage::new_local(path).await?;
storage.initialize_schema().await?;
let cache = std::sync::Arc::new(
do_memory_storage_redb::RedbStorage::new(std::path::Path::new(":memory:"))
.await
.map_err(|e| do_memory_core::Error::Storage(e.to_string()))?,
);
Ok(do_memory_core::memory::SelfLearningMemory::with_storage(
do_memory_core::MemoryConfig::default(),
std::sync::Arc::new(storage),
cache,
))
}
async fn with_in_memory_storage() -> Result<do_memory_core::memory::SelfLearningMemory> {
let storage = TursoStorage::new_in_memory().await?;
storage.initialize_schema().await?;
let cache = std::sync::Arc::new(
do_memory_storage_redb::RedbStorage::new(std::path::Path::new(":memory:"))
.await
.map_err(|e| do_memory_core::Error::Storage(e.to_string()))?,
);
Ok(do_memory_core::memory::SelfLearningMemory::with_storage(
do_memory_core::MemoryConfig::default(),
std::sync::Arc::new(storage),
cache,
))
}
}
pub use cache::query_cache::{AdvancedCacheStats, AdvancedQueryCache, QueryKey};
pub use cache::{
AdaptiveTTLCache, CacheConfig, CacheEntry, CacheStats, CacheStatsSnapshot, CachedTursoStorage,
TTLConfig, TTLConfigError,
};
pub use pool::{
AdaptiveConnectionPool, AdaptivePoolConfig, AdaptivePoolMetrics, AdaptivePooledConnection,
};
pub use pool::{
ConnectionPool, PoolConfig, PoolMetrics, PoolMetricsSnapshot, PoolStatistics, PooledConnection,
};
#[cfg(feature = "keepalive-pool")]
pub use pool::{KeepAliveConfig, KeepAlivePool, KeepAliveStatistics};
pub use prepared::{PreparedCacheConfig, PreparedCacheStats, PreparedStatementCache};
pub use resilient::ResilientStorage;
pub use metrics::{
ExportConfig, ExportFormat, ExportStats, ExportTarget, ExportedMetric, MetricType, MetricValue,
MetricsCollector, MetricsHttpServer, PrometheusExporter, TursoMetrics,
};
pub use storage::batch::episode_batch::BatchConfig;
pub use storage::capacity::CapacityStatistics;
pub use storage::episodes::EpisodeQuery;
pub use storage::patterns::{PatternMetadata, PatternQuery};
pub use trait_impls::StorageStatistics;
#[cfg(feature = "compression")]
pub use compression::{
CompressedPayload, CompressionAlgorithm, CompressionStatistics, compress, compress_embedding,
compress_json, decompress, decompress_embedding,
};
#[cfg(feature = "compression")]
pub use transport::{
CompressedTransport, Transport, TransportCompressionConfig, TransportCompressionError,
TransportCompressionStats, TransportMetadata, TransportResponse,
};
#[cfg(test)]
mod ext_tests {
use super::*;
use do_memory_core::memory::SelfLearningMemory;
#[tokio::test]
async fn test_with_in_memory_storage() {
let memory = SelfLearningMemory::with_in_memory_storage().await.unwrap();
let (primary, cache) = memory.storage_backends();
assert!(primary.is_some());
assert!(cache.is_some());
}
#[tokio::test]
#[ignore = "flaky in full suite: libsql concurrent connection race (ADR-027); passes in isolation"]
async fn test_with_local_storage() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("test.db");
let memory = SelfLearningMemory::with_local_storage(&path).await.unwrap();
let (primary, cache) = memory.storage_backends();
assert!(primary.is_some());
assert!(cache.is_some());
}
}