@@ -3,41 +3,79 @@ use std::{
3
3
path:: { Path , PathBuf } ,
4
4
} ;
5
5
6
- use anyhow:: Context ;
6
+ use anyhow:: { bail , Context } ;
7
7
use serde:: { Deserialize , Serialize } ;
8
8
use spin_factor_key_value:: runtime_config:: spin:: MakeKeyValueStore ;
9
9
use spin_key_value_sqlite:: { DatabaseLocation , KeyValueSqlite } ;
10
10
11
11
/// A key-value store that uses SQLite as the backend.
12
12
pub struct SpinKeyValueStore {
13
13
/// The base path or directory for the SQLite database file.
14
- base_path : PathBuf ,
14
+ base_path : Option < PathBuf > ,
15
15
}
16
16
17
17
impl SpinKeyValueStore {
18
18
/// Create a new SpinKeyValueStore with the given base path.
19
- pub fn new ( base_path : PathBuf ) -> Self {
19
+ ///
20
+ /// If the database directory is None, the database will always be in-memory.
21
+ /// If it's `Some`, the database will be stored at the combined `base_path` and
22
+ /// the `path` specified in the runtime configuration.
23
+ pub fn new ( base_path : Option < PathBuf > ) -> Self {
20
24
Self { base_path }
21
25
}
22
26
}
23
27
24
- /// Runtime configuration for the SQLite key-value store.
28
+ impl MakeKeyValueStore for SpinKeyValueStore {
29
+ const RUNTIME_CONFIG_TYPE : & ' static str = "spin" ;
30
+
31
+ type RuntimeConfig = SpinKeyValueRuntimeConfig ;
32
+
33
+ type StoreManager = KeyValueSqlite ;
34
+
35
+ fn make_store (
36
+ & self ,
37
+ runtime_config : Self :: RuntimeConfig ,
38
+ ) -> anyhow:: Result < Self :: StoreManager > {
39
+ let location = match ( & self . base_path , & runtime_config. path ) {
40
+ // If both the base path and the path are specified, resolve the path against the base path
41
+ ( Some ( base_path) , Some ( path) ) => {
42
+ let path = resolve_relative_path ( path, base_path) ;
43
+ DatabaseLocation :: Path ( path)
44
+ }
45
+ // If the base path is `None` but path is an absolute path, use the absolute path
46
+ ( None , Some ( path) ) if path. is_absolute ( ) => DatabaseLocation :: Path ( path. clone ( ) ) ,
47
+ // If the base path is `None` but path is a relative path, error out
48
+ ( None , Some ( path) ) => {
49
+ bail ! (
50
+ "key-value store path '{}' is relative, but no base path is set" ,
51
+ path. display( )
52
+ )
53
+ }
54
+ // Otherwise, use an in-memory database
55
+ ( None | Some ( _) , None ) => DatabaseLocation :: InMemory ,
56
+ } ;
57
+ if let DatabaseLocation :: Path ( path) = & location {
58
+ // Create the store's parent directory if necessary
59
+ if let Some ( parent) = path. parent ( ) . filter ( |p| !p. exists ( ) ) {
60
+ fs:: create_dir_all ( parent)
61
+ . context ( "Failed to create key value store's parent directory" ) ?;
62
+ }
63
+ }
64
+ Ok ( KeyValueSqlite :: new ( location) )
65
+ }
66
+ }
67
+
68
+ /// The serialized runtime configuration for the SQLite key-value store.
25
69
#[ derive( Deserialize , Serialize ) ]
26
70
pub struct SpinKeyValueRuntimeConfig {
27
71
/// The path to the SQLite database file.
28
72
path : Option < PathBuf > ,
29
73
}
30
74
31
75
impl SpinKeyValueRuntimeConfig {
32
- /// The default filename for the SQLite database.
33
- const DEFAULT_SPIN_STORE_FILENAME : & ' static str = "sqlite_key_value.db" ;
34
-
35
- /// Create a new runtime configuration with the given directory.
36
- ///
37
- /// If the database directory is None, the database is in-memory.
38
- /// If the database directory is Some, the database is stored in a file in the given directory.
39
- pub fn default ( default_database_dir : Option < PathBuf > ) -> Self {
40
- let path = default_database_dir. map ( |dir| dir. join ( Self :: DEFAULT_SPIN_STORE_FILENAME ) ) ;
76
+ /// Create a new SpinKeyValueRuntimeConfig with the given parent directory
77
+ /// where the key-value store will live.
78
+ pub fn new ( path : Option < PathBuf > ) -> Self {
41
79
Self { path }
42
80
}
43
81
}
@@ -51,28 +89,3 @@ fn resolve_relative_path(path: &Path, base_dir: &Path) -> PathBuf {
51
89
}
52
90
base_dir. join ( path)
53
91
}
54
-
55
- impl MakeKeyValueStore for SpinKeyValueStore {
56
- const RUNTIME_CONFIG_TYPE : & ' static str = "spin" ;
57
-
58
- type RuntimeConfig = SpinKeyValueRuntimeConfig ;
59
-
60
- type StoreManager = KeyValueSqlite ;
61
-
62
- fn make_store (
63
- & self ,
64
- runtime_config : Self :: RuntimeConfig ,
65
- ) -> anyhow:: Result < Self :: StoreManager > {
66
- let location = match runtime_config. path {
67
- Some ( path) => {
68
- let path = resolve_relative_path ( & path, & self . base_path ) ;
69
- // Create the store's parent directory if necessary
70
- fs:: create_dir_all ( path. parent ( ) . unwrap ( ) )
71
- . context ( "Failed to create key value store" ) ?;
72
- DatabaseLocation :: Path ( path)
73
- }
74
- None => DatabaseLocation :: InMemory ,
75
- } ;
76
- Ok ( KeyValueSqlite :: new ( location) )
77
- }
78
- }
0 commit comments