1use crate::utility::config::Config;
2use std::error::Error;
3use std::path::Path;
4use surrealdb::Surreal;
5use surrealdb::engine::local::SurrealKv;
6
7pub mod queries;
8
9pub type DB = Surreal<surrealdb::engine::local::Db>;
10
11pub async fn init() -> Result<DB, Box<dyn Error>> {
12 let config = Config::get();
13 let path = &config.surreal_data_path;
14
15 let parent_dir = Path::new(path).parent().unwrap_or(Path::new("."));
16 let parent_exists = parent_dir.exists();
17 let parent_writable = parent_exists
18 && std::fs::metadata(parent_dir)
19 .map(|m| !m.permissions().readonly())
20 .unwrap_or(false);
21
22 let db = Surreal::new::<SurrealKv>(path).await.map_err(|e| {
23 let mut hint = String::new();
24 if !parent_exists {
25 hint.push_str("Parent directory does not exist. ");
26 } else if !parent_writable {
27 hint.push_str("Parent directory is not writable. ");
28 } else {
29 hint.push_str(
30 "Check if the path is valid, writable, and not locked by another process. ",
31 );
32 }
33 hint.push_str("If the file exists, it may be corrupted.");
34
35 format!(
36 "Failed to open embedded database at '{}'\nHint: {}\n\nError: {}",
37 path, hint, e
38 )
39 })?;
40
41 db.use_ns(&config.surreal_ns)
42 .use_db(&config.surreal_db)
43 .await
44 .map_err(|e| format!("Failed to select namespace/database\nError: {}", e))?;
45
46 Ok(db)
47}