1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use sled::{self, Config, Db}; use std::convert::TryFrom; use std::str; use thiserror::Error as ThisError; #[cfg(not(feature = "alter-table"))] use crate::AlterTable; #[cfg(feature = "alter-table")] use crate::AlterTableError; use crate::{Error, Result, Schema}; #[cfg(feature = "alter-table")] mod alter_table; #[cfg(not(feature = "alter-table"))] impl AlterTable for SledStorage {} mod store; #[derive(ThisError, Debug)] enum StorageError { #[cfg(feature = "alter-table")] #[error(transparent)] AlterTable(#[from] AlterTableError), #[error(transparent)] Sled(#[from] sled::Error), #[error(transparent)] Bincode(#[from] bincode::Error), #[error(transparent)] Str(#[from] str::Utf8Error), } impl Into<Error> for StorageError { fn into(self) -> Error { use StorageError::*; match self { Sled(e) => Error::Storage(Box::new(e)), Bincode(e) => Error::Storage(e), Str(e) => Error::Storage(Box::new(e)), #[cfg(feature = "alter-table")] AlterTable(e) => e.into(), } } } #[macro_export] macro_rules! try_into { ($expr: expr) => { $expr.map_err(|e| { let e: StorageError = e.into(); let e: Error = e.into(); e })? }; ($self: expr, $expr: expr) => { match $expr { Err(e) => { let e: StorageError = e.into(); let e: Error = e.into(); return Err(($self, e)); } Ok(v) => v, } }; } #[derive(Debug)] pub struct SledStorage { tree: Db, } impl SledStorage { pub fn new(filename: &str) -> Result<Self> { let tree = try_into!(sled::open(filename)); Ok(Self { tree }) } } impl TryFrom<Config> for SledStorage { type Error = Error; fn try_from(config: Config) -> Result<Self> { let tree = try_into!(config.open()); Ok(Self { tree }) } } fn fetch_schema(tree: &Db, table_name: &str) -> Result<(String, Option<Schema>)> { let key = format!("schema/{}", table_name); let value = try_into!(tree.get(&key.as_bytes())); let schema = try_into!(value.map(|v| bincode::deserialize(&v)).transpose()); Ok((key, schema)) }