gluesql_file_storage/
store.rs1use {
2 crate::{FileRow, FileStorage, ResultExt},
3 async_trait::async_trait,
4 futures::stream::iter,
5 gluesql_core::{
6 data::{Key, Schema},
7 error::Result,
8 store::{DataRow, RowIter, Store},
9 },
10 std::{ffi::OsStr, fs},
11};
12
13#[async_trait(?Send)]
14impl Store for FileStorage {
15 async fn fetch_all_schemas(&self) -> Result<Vec<Schema>> {
16 let mut schemas = fs::read_dir(&self.path)
17 .map_storage_err()?
18 .map(|dir_entry| {
19 let dir_entry = dir_entry.map_storage_err()?;
20 let file_type = dir_entry.file_type().map_storage_err()?;
21 let path = dir_entry.path();
22 let extension = path.extension().and_then(OsStr::to_str);
23 if file_type.is_dir() || extension != Some("sql") {
24 return Ok(None);
25 }
26
27 self.fetch_schema(path).map(Some)
28 })
29 .filter_map(Result::transpose)
30 .collect::<Result<Vec<Schema>>>()?;
31
32 schemas.sort_by(|a, b| a.table_name.cmp(&b.table_name));
33
34 Ok(schemas)
35 }
36
37 async fn fetch_schema(&self, table_name: &str) -> Result<Option<Schema>> {
38 let path = self.path(table_name).with_extension("sql");
39 if !path.exists() {
40 return Ok(None);
41 }
42
43 self.fetch_schema(path).map(Some)
44 }
45
46 async fn fetch_data(&self, table_name: &str, key: &Key) -> Result<Option<DataRow>> {
47 let path = self.data_path(table_name, key)?;
48 if !path.exists() {
49 return Ok(None);
50 }
51
52 fs::read_to_string(path)
53 .map_storage_err()
54 .and_then(|data| {
55 ron::from_str(&data)
56 .map_storage_err()
57 .map(|FileRow { row, .. }| row)
58 })
59 .map(Some)
60 }
61
62 async fn scan_data(&self, table_name: &str) -> Result<RowIter> {
63 let path = self.path(table_name);
64 let mut entries = fs::read_dir(path)
65 .map_storage_err()?
66 .map(|dir_entry| {
67 let dir_entry = dir_entry.map_storage_err()?;
68 let file_type = dir_entry.file_type().map_storage_err()?;
69 let path = dir_entry.path();
70 let extension = path.extension().and_then(OsStr::to_str);
71 if file_type.is_dir() || extension != Some("ron") {
72 return Ok(None);
73 }
74
75 Ok(Some(path))
76 })
77 .filter_map(Result::transpose)
78 .collect::<Result<Vec<_>>>()?;
79
80 entries.sort();
81
82 let rows = entries.into_iter().map(|path| {
83 let data = fs::read_to_string(path).map_storage_err()?;
84
85 ron::from_str(&data)
86 .map_storage_err()
87 .map(|FileRow { key, row }| (key, row))
88 });
89
90 Ok(Box::pin(iter(rows)))
91 }
92}