1pub mod flat;
2pub mod sled;
3pub mod sqlite;
4
5use crate::chunker::Chunk;
6use crate::metadata;
7use anyhow::Result;
8use std::path::Path;
9
10pub enum Store {
11 Flat(flat::FlatStore),
12 Sled(sled::SledStore),
13 Sqlite(sqlite::SqliteStore),
14}
15
16impl Store {
17 pub fn new(root: &Path, backend: &str) -> Result<Self> {
18 match backend {
19 "flat" => Ok(Store::Flat(flat::FlatStore::new(root))),
20 "sled" => Ok(Store::Sled(sled::SledStore::new(root)?)),
21 "sqlite" => Ok(Store::Sqlite(sqlite::SqliteStore::new(root)?)),
22 _ => anyhow::bail!("Unknown storage backend: {}", backend),
23 }
24 }
25
26 pub fn open(root: &Path) -> Result<Self> {
27 let config_path = root.join("config.json");
28 let backend = if config_path.exists() {
29 let data = std::fs::read(&config_path)?;
30 let config: std::collections::BTreeMap<String, String> = metadata::deserialize(&data)?;
31 config
32 .get("storage_backend")
33 .map(|s| s.as_str())
34 .unwrap_or("flat")
35 .to_string()
36 } else {
37 "flat".to_string()
38 };
39 Self::new(root, &backend)
40 }
41
42 pub fn put_chunk(&self, chunk: &Chunk) -> Result<()> {
43 match self {
44 Store::Flat(s) => s.put_chunk(chunk),
45 Store::Sled(s) => s.put_chunk(chunk),
46 Store::Sqlite(s) => s.put_chunk(chunk),
47 }
48 }
49
50 pub fn get_chunk(&self, hash_hex: &str) -> Result<Vec<u8>> {
51 match self {
52 Store::Flat(s) => s.get_chunk(hash_hex),
53 Store::Sled(s) => s.get_chunk(hash_hex),
54 Store::Sqlite(s) => s.get_chunk(hash_hex),
55 }
56 }
57
58 pub fn has_chunk(&self, hash_hex: &str) -> bool {
59 match self {
60 Store::Flat(s) => s.has_chunk(hash_hex),
61 Store::Sled(s) => s.has_chunk(hash_hex),
62 Store::Sqlite(s) => s.has_chunk(hash_hex),
63 }
64 }
65
66 pub fn iter_chunks(&self) -> Result<Vec<(String, String)>> {
67 match self {
68 Store::Flat(s) => s.iter_chunks(),
69 Store::Sled(s) => s.iter_chunks(),
70 Store::Sqlite(s) => s.iter_chunks(),
71 }
72 }
73
74 pub fn delete_chunk(&self, hash_hex: &str, full_path: Option<&str>) -> Result<()> {
75 match self {
76 Store::Flat(s) => s.delete_chunk(hash_hex, full_path),
77 Store::Sled(s) => s.delete_chunk(hash_hex, full_path),
78 Store::Sqlite(s) => s.delete_chunk(hash_hex, full_path),
79 }
80 }
81}