gluesql_file_storage/
lib.rs1#![deny(clippy::str_to_string)]
2
3mod store;
4mod store_mut;
5
6use {
7 gluesql_core::{
8 data::{Key, Schema},
9 error::{Error, Result},
10 store::{
11 AlterTable, CustomFunction, CustomFunctionMut, DataRow, Index, IndexMut, Metadata,
12 Transaction,
13 },
14 },
15 hex::ToHex,
16 serde::{Deserialize, Serialize},
17 std::{
18 convert::AsRef,
19 fs,
20 path::{Path, PathBuf},
21 },
22};
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct FileStorage {
26 pub path: PathBuf,
27}
28
29#[derive(Debug, Serialize, Deserialize)]
30pub struct FileRow {
31 pub key: Key,
32 pub row: DataRow,
33}
34
35impl FileStorage {
36 pub fn new<T: AsRef<Path>>(path: T) -> Result<Self> {
37 let path = path.as_ref();
38 fs::create_dir_all(path).map_storage_err()?;
39
40 Ok(Self { path: path.into() })
41 }
42
43 pub fn path<T: AsRef<Path>>(&self, table_name: T) -> PathBuf {
44 let mut path = self.path.clone();
45 path.push(table_name);
46 path
47 }
48
49 pub fn data_path<T: AsRef<Path>>(&self, table_name: T, key: &Key) -> Result<PathBuf> {
50 let mut path = self.path(table_name);
51 let key = key.to_cmp_be_bytes()?.encode_hex::<String>();
52
53 path.push(key);
54 let path = path.with_extension("ron");
55
56 Ok(path)
57 }
58
59 fn fetch_schema(&self, path: PathBuf) -> Result<Schema> {
60 fs::read_to_string(path)
61 .map_storage_err()
62 .and_then(|data| Schema::from_ddl(&data))
63 }
64}
65
66pub trait ResultExt<T, E: ToString> {
67 fn map_storage_err(self) -> Result<T, Error>;
68}
69
70impl<T, E: ToString> ResultExt<T, E> for std::result::Result<T, E> {
71 fn map_storage_err(self) -> Result<T, Error> {
72 self.map_err(|e| e.to_string()).map_err(Error::StorageMsg)
73 }
74}
75
76impl AlterTable for FileStorage {}
77impl Index for FileStorage {}
78impl IndexMut for FileStorage {}
79impl Transaction for FileStorage {}
80impl Metadata for FileStorage {}
81impl CustomFunction for FileStorage {}
82impl CustomFunctionMut for FileStorage {}