From 9483f2df60d6e08b33610f6e0591b787ef9f4805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Mon, 8 Apr 2019 15:19:57 +0200 Subject: [PATCH] feat: Introduce a custom Error type --- meilidb-data/Cargo.toml | 2 +- meilidb-data/src/database.rs | 85 ++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/meilidb-data/Cargo.toml b/meilidb-data/Cargo.toml index 23749631b..a142c0bd5 100644 --- a/meilidb-data/Cargo.toml +++ b/meilidb-data/Cargo.toml @@ -12,5 +12,5 @@ meilidb-core = { path = "../meilidb-core", version = "0.1.0" } ordered-float = { version = "1.0.2", features = ["serde"] } serde = { version = "1.0.88", features = ["derive"] } serde_json = { version = "1.0.39", features = ["preserve_order"] } -sled = "0.20.0" +sled = "0.21.3" toml = { version = "0.5.0", features = ["preserve_order"] } diff --git a/meilidb-data/src/database.rs b/meilidb-data/src/database.rs index 7f52dccda..f3a4d1dbd 100644 --- a/meilidb-data/src/database.rs +++ b/meilidb-data/src/database.rs @@ -1,21 +1,90 @@ -use std::path::Path; use std::sync::Arc; +use std::path::Path; + +use crate::schema::Schema; + +#[derive(Debug)] +pub enum Error { + SchemaNotFound, + SledError(sled::Error), + BincodeError(bincode::Error), +} + +impl From for Error { + fn from(error: sled::Error) -> Error { + Error::SledError(error) + } +} + +impl From for Error { + fn from(error: bincode::Error) -> Error { + Error::BincodeError(error) + } +} + +fn index_name(name: &str) -> Vec { + format!("index-{}", name).into_bytes() +} #[derive(Clone)] pub struct Database(sled::Db); impl Database { - pub fn start_default>(path: P) -> sled::Result { - sled::Db::start_default(path).map(Database) + pub fn start_default>(path: P) -> Result { + sled::Db::start_default(path).map(Database).map_err(Into::into) } - pub fn open_index(&self, name: &str) -> sled::Result { - let name = format!("index-{}", name); - let bytes = name.into_bytes(); + pub fn open_index(&self, name: &str) -> Result, Error> { + let name = index_name(name); - self.0.open_tree(bytes).map(Index) + if self.0.tree_names().into_iter().any(|tn| tn == name) { + let tree = self.0.open_tree(name)?; + let index = Index::from_raw(tree)?; + return Ok(Some(index)) + } + + Ok(None) + } + + pub fn create_index(&self, name: &str, schema: Schema) -> Result { + match self.open_index(name)? { + Some(index) => { + // TODO check if the schema is the same + Ok(index) + }, + None => { + let name = index_name(name); + let tree = self.0.open_tree(name)?; + let index = Index::new_from_raw(tree, schema)?; + Ok(index) + }, + } } } #[derive(Debug, Clone)] -pub struct Index(Arc); +pub struct Index { + schema: Schema, + inner: Arc, +} + +impl Index { + fn from_raw(inner: Arc) -> Result { + let bytes = inner.get("schema")?; + let bytes = bytes.ok_or(Error::SchemaNotFound)?; + + let schema = Schema::read_from_bin(bytes.as_ref())?; + Ok(Index { schema, inner }) + } + + fn new_from_raw(inner: Arc, schema: Schema) -> Result { + let mut schema_bytes = Vec::new(); + schema.write_to_bin(&mut schema_bytes); + inner.set("schema", schema_bytes)?; + Ok(Index { schema, inner }) + } + + pub fn schema(&self) -> &Schema { + &self.schema + } +}