relay_knowledge/adapters/
storage.rs1use std::{path::PathBuf, sync::Arc};
4
5use crate::{
6 paths::RuntimePaths,
7 storage::{
8 KnowledgeStore, KnowledgeStoreFactory, KnowledgeStoreFactoryFuture,
9 PartitionedSqliteKnowledgeStore, SqliteGraphStore, StorageError, StorageTopology,
10 StorageTopologySnapshot,
11 },
12};
13
14#[derive(Debug, Clone)]
16pub struct SqliteKnowledgeStoreFactory {
17 database_path: PathBuf,
18 paths: RuntimePaths,
19 topology: StorageTopology,
20}
21
22impl SqliteKnowledgeStoreFactory {
23 pub fn new(paths: RuntimePaths, topology: StorageTopology) -> Self {
25 Self {
26 database_path: paths.database_file(),
27 paths,
28 topology,
29 }
30 }
31}
32
33impl KnowledgeStoreFactory for SqliteKnowledgeStoreFactory {
34 fn open(&self) -> KnowledgeStoreFactoryFuture<'_, Arc<dyn KnowledgeStore>> {
35 let config = self.clone();
36 Box::pin(async move {
37 tokio::task::spawn_blocking(move || open_store(config))
38 .await
39 .map_err(StorageError::from)?
40 })
41 }
42
43 fn topology_snapshot(&self) -> KnowledgeStoreFactoryFuture<'_, StorageTopologySnapshot> {
44 let config = self.clone();
45 Box::pin(async move {
46 tokio::task::spawn_blocking(move || {
47 PartitionedSqliteKnowledgeStore::topology_snapshot_from_catalog(
48 config.database_path,
49 &config.paths,
50 )
51 })
52 .await
53 .map_err(StorageError::from)?
54 })
55 }
56}
57
58fn open_store(
59 config: SqliteKnowledgeStoreFactory,
60) -> Result<Arc<dyn KnowledgeStore>, StorageError> {
61 match config.topology {
62 StorageTopology::SingleSqlite => {
63 if PartitionedSqliteKnowledgeStore::has_active_catalog(&config.database_path)? {
64 return Err(StorageError::InvalidInput(
65 "single_sqlite cannot open a database with active partitioned_sqlite shards; set RELAY_KNOWLEDGE_STORAGE_TOPOLOGY=partitioned_sqlite or migrate the shard catalog before rollback".to_owned(),
66 ));
67 }
68 Ok(Arc::new(SqliteGraphStore::open(config.database_path)?) as Arc<dyn KnowledgeStore>)
69 }
70 StorageTopology::PartitionedSqlite => Ok(Arc::new(PartitionedSqliteKnowledgeStore::open(
71 config.database_path,
72 config.paths,
73 )?) as Arc<dyn KnowledgeStore>),
74 }
75}
76
77#[cfg(test)]
78#[path = "storage_tests.rs"]
79mod tests;