tauri_plugin_velesdb/
state.rs1use std::path::PathBuf;
7use std::sync::Arc;
8
9use parking_lot::RwLock;
10use velesdb_core::Database;
11
12use crate::error::{Error, Result};
13
14pub struct VelesDbState {
19 db: Arc<RwLock<Option<Arc<Database>>>>,
21 path: PathBuf,
23}
24
25impl VelesDbState {
26 #[must_use]
36 pub fn new(path: PathBuf) -> Self {
37 Self {
38 db: Arc::new(RwLock::new(None)),
39 path,
40 }
41 }
42
43 pub fn open(&self) -> Result<()> {
49 let mut db_guard = self.db.write();
50 if db_guard.is_none() {
51 let db = Arc::new(Database::open(&self.path)?);
52 *db_guard = Some(db);
53 tracing::info!("VelesDB opened at {:?}", self.path);
54 }
55 Ok(())
56 }
57
58 pub fn get_db(&self) -> Result<Arc<RwLock<Option<Arc<Database>>>>> {
64 {
66 let db_guard = self.db.read();
67 if db_guard.is_none() {
68 drop(db_guard);
69 self.open()?;
70 }
71 }
72 Ok(Arc::clone(&self.db))
73 }
74
75 pub fn with_db<F, T>(&self, f: F) -> Result<T>
81 where
82 F: FnOnce(Arc<Database>) -> Result<T>,
83 {
84 self.open()?;
85 let db_guard = self.db.read();
86 let db = db_guard
87 .as_ref()
88 .ok_or_else(|| Error::InvalidConfig("Database not initialized".to_string()))?;
89 f(Arc::clone(db))
90 }
91
92 #[must_use]
94 pub fn path(&self) -> &PathBuf {
95 &self.path
96 }
97}
98
99impl Default for VelesDbState {
100 fn default() -> Self {
101 Self::new(PathBuf::from("./velesdb_data"))
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use tempfile::tempdir;
109
110 #[test]
111 fn test_state_new() {
112 let path = PathBuf::from("/tmp/test_db");
114
115 let state = VelesDbState::new(path.clone());
117
118 assert_eq!(state.path(), &path);
120 }
121
122 #[test]
123 fn test_state_default() {
124 let state = VelesDbState::default();
126
127 assert_eq!(state.path(), &PathBuf::from("./velesdb_data"));
129 }
130
131 #[test]
132 fn test_state_open_and_access() {
133 let dir = tempdir().expect("Failed to create temp dir");
135 let state = VelesDbState::new(dir.path().to_path_buf());
136
137 let result = state.open();
139
140 assert!(result.is_ok());
142 }
143
144 #[test]
145 fn test_state_with_db() {
146 let dir = tempdir().expect("Failed to create temp dir");
148 let state = VelesDbState::new(dir.path().to_path_buf());
149
150 let result = state.with_db(|db| {
152 let collections = db.list_collections();
154 Ok(collections.len())
155 });
156 assert!(result.is_ok());
160 assert_eq!(result.unwrap(), 0); }
162
163 #[test]
164 fn test_state_multiple_opens_idempotent() {
165 let dir = tempdir().expect("Failed to create temp dir");
167 let state = VelesDbState::new(dir.path().to_path_buf());
168
169 let result1 = state.open();
171 let result2 = state.open();
172 let result3 = state.open();
173
174 assert!(result1.is_ok());
176 assert!(result2.is_ok());
177 assert!(result3.is_ok());
178 }
179}