Added cache initialization.

This commit is contained in:
2023-03-14 11:32:37 -04:00
parent c477a92945
commit a3d8feb37a
3 changed files with 307 additions and 102 deletions

View File

@ -1,4 +1,4 @@
use super::{DBError, FileData, SessionData, Store};
use super::{DBError, ErrorCode, FileData, SessionData, Store};
use async_std::{
fs::{read, remove_file, write},
path::{Path, PathBuf},
@ -21,7 +21,9 @@ impl DataType {
fn new(data_type: &str) -> Result<Self, DBError> {
match data_type {
"store" => Ok(DataType::DBMap(Store::new())),
_ => Err(DBError::new("invalid data type")),
_ => Err(DBError::from_code(ErrorCode::DataTypeIncorrect(
data_type.to_string(),
))),
}
}
}
@ -74,14 +76,14 @@ impl FileData<Self> for DataType {
}
let header = match str::from_utf8(&header) {
Ok(item) => item,
Err(_) => return Err(DBError::new("file corruption")),
Err(_) => return Err(DBError::from_code(ErrorCode::CorruptFile)),
};
match header {
"DBMap" => match Store::from_bytes(data) {
Ok(store) => Ok(DataType::DBMap(store)),
Err(err) => Err(err),
},
_ => Err(DBError::new("file corruption")),
_ => Err(DBError::from_code(ErrorCode::CorruptFile)),
}
}
}
@ -99,13 +101,12 @@ impl Entry {
{
let pathbuf = filename.into();
if pathbuf.as_path().exists().await {
// if Path::new(&filename).exists().await {
return Err(DBError::new("entry already exists"));
return Err(DBError::from_code(ErrorCode::EntryExists(pathbuf)));
} else {
match write(&pathbuf, data.to_bytes()).await {
Ok(_) => (),
Err(err) => {
let mut error = DBError::new("failed to write");
let mut error = DBError::from_code(ErrorCode::EntryWriteFailure(pathbuf));
error.add_source(err);
return Err(error);
}
@ -126,7 +127,7 @@ impl Entry {
let content = match read(&pathbuf).await {
Ok(text) => text,
Err(err) => {
let mut error = DBError::new("read error");
let mut error = DBError::from_code(ErrorCode::EntryReadFailure(pathbuf));
error.add_source(err);
return Err(error);
}
@ -134,7 +135,7 @@ impl Entry {
let data = match DataType::from_bytes(&mut content.iter()) {
Ok(raw) => raw,
Err(err) => {
let mut error = DBError::new("read error");
let mut error = DBError::from_code(ErrorCode::EntryReadFailure(pathbuf));
error.add_source(err);
return Err(error);
}
@ -160,7 +161,7 @@ impl Entry {
match write(&self.filename, data.to_bytes()).await {
Ok(_) => (),
Err(err) => {
let mut error = DBError::new("write error");
let mut error = DBError::from_code(ErrorCode::EntryWriteFailure(self.filename.clone()));
error.add_source(err);
return Err(error);
}
@ -173,7 +174,7 @@ impl Entry {
match remove_file(&self.filename).await {
Ok(_) => Ok(()),
Err(err) => {
let mut error = DBError::new("cannot remove");
let mut error = DBError::from_code(ErrorCode::EntryDeleteFailure(self.filename.clone()));
error.add_source(err);
Err(error)
}
@ -190,14 +191,19 @@ impl Cache {
{
let pathbuf = dir.into();
let entry = pathbuf.as_path().join(ENTRY);
let store = DataType::new("store").unwrap();
match Entry::new(entry, store).await {
match Entry::get(entry.clone()).await {
Ok(_) => Ok(Self {}),
Err(err) => {
let mut error = DBError::new("initialization failure");
error.add_source(err);
Err(error)
}
Err(_) => {
let store = DataType::new("store").unwrap();
match Entry::new(entry, store).await {
Ok(_) => Ok(Self {}),
Err(err) => {
let mut error = DBError::from_code(ErrorCode::CacheReadWrite);
error.add_source(err);
Err(error)
},
}
},
}
}
}
@ -210,10 +216,10 @@ mod datatype_sesssion {
fn invalid_cache_type() -> Result<(), DBError> {
match DataType::new("dkhgdl") {
Ok(_) => Err(DBError::new("invalid data type should raise an error")),
Err(err) => {
assert_eq!(err.to_string(), "invalid data type");
Ok(())
}
Err(err) => match err.code {
ErrorCode::DataTypeIncorrect(_) => Ok(()),
_ => Err(DBError::new("Invalid error code")),
},
}
}
@ -291,10 +297,10 @@ mod datatype_file {
let mut feed = data.iter();
match DataType::from_bytes(&mut feed) {
Ok(_) => Err(DBError::new("should have raised an error")),
Err(err) => {
assert_eq!(err.to_string(), "file corruption");
Ok(())
}
Err(err) => match err.code {
ErrorCode::CorruptFile => Ok(()),
_ => Err(DBError::new("incorrect error")),
},
}
}
@ -371,16 +377,18 @@ mod entry {
let filename = filepath.to_str().unwrap();
match Entry::new(filename.to_string(), data).await {
Ok(_) => Err(DBError::new("bad file names should raise an error")),
Err(err) => {
assert_eq!(err.to_string(), "failed to write");
assert!(err.source().is_some(), "Must include the source error.");
assert!(err
.source()
.unwrap()
.to_string()
.contains("could not write to file"));
Ok(())
}
Err(err) => match err.code {
ErrorCode::EntryWriteFailure(_) => {
assert!(err.source().is_some(), "Must include the source error.");
assert!(err
.source()
.unwrap()
.to_string()
.contains("could not write to file"));
Ok(())
}
_ => Err(DBError::new("incorrect error code")),
},
}
}
@ -398,10 +406,10 @@ mod entry {
"Should produce an error for an existing Entry",
))
}
Err(err) => {
assert_eq!(err.to_string(), "entry already exists");
Ok(())
}
Err(err) => match err.code {
ErrorCode::EntryExists(_) => Ok(()),
_ => Err(DBError::new("incorrect error code")),
},
}
}
@ -459,15 +467,17 @@ mod entry {
drop(dir);
match item.update(data).await {
Ok(_) => Err(DBError::new("file writes should return an error")),
Err(err) => {
assert_eq!(err.to_string(), "write error");
assert!(err.source().is_some(), "Must include the source error.");
assert!(err
.source()
.unwrap()
.to_string()
.contains("could not write to file"));
Ok(())
Err(err) => match err.code {
ErrorCode::EntryWriteFailure(_) => {
assert!(err.source().is_some(), "Must include the source error.");
assert!(err
.source()
.unwrap()
.to_string()
.contains("could not write to file"));
Ok(())
},
_ => Err(DBError::new("incorrect error code")),
}
}
}
@ -501,18 +511,20 @@ mod entry {
let filename = filepath.to_str().unwrap();
match Entry::get(filename).await {
Ok(_) => Err(DBError::new("should have returned an error")),
Err(err) => {
assert_eq!(err.to_string(), "read error");
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source()
.unwrap()
.to_string()
.contains("could not read file"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
Err(err) => match err.code {
ErrorCode::EntryReadFailure(_) => {
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source()
.unwrap()
.to_string()
.contains("could not read file"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
}
_ => Err(DBError::new("incorrect error code")),
}
}
}
@ -525,18 +537,17 @@ mod entry {
write(&filepath, b"jhsdfghlsdf").await.unwrap();
match Entry::get(filename).await {
Ok(_) => Err(DBError::new("should have returned an error")),
Err(err) => {
assert_eq!(err.to_string(), "read error");
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source()
.unwrap()
.to_string()
.contains("file corruption"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
Err(err) => match err.code {
ErrorCode::EntryReadFailure(_) => {
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source().unwrap().to_string().contains("corrupt file"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
},
_ => Err(DBError::new("incorrect error code")),
}
}
}
@ -566,18 +577,20 @@ mod entry {
remove_file(filename).await.unwrap();
match item.remove().await {
Ok(_) => Err(DBError::new("should have produced an error")),
Err(err) => {
assert_eq!(err.to_string(), "cannot remove");
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source()
.unwrap()
.to_string()
.contains("could not remove file"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
Err(err) => match err.code {
ErrorCode::EntryDeleteFailure(_) => {
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source()
.unwrap()
.to_string()
.contains("could not remove file"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
},
_ => Err(DBError::new("incorrect error code")),
}
}
}
@ -607,23 +620,46 @@ mod cache {
}
#[async_std::test]
async fn entry_failure() {
async fn entry_failure() -> Result<(), DBError> {
let dir = tempdir().unwrap();
let path = dir.path().join("bad").join("path");
match Cache::new(path).await {
Ok(_) => assert!(false, "Should have produced an error."),
Ok(_) => Err(DBError::new("Should have produced an error.")),
Err(err) => {
assert_eq!(err.to_string(), "initialization failure");
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source()
.unwrap()
.to_string()
.contains("failed to write"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
match err.code {
ErrorCode::CacheReadWrite => {
assert!(err.source().is_some(), "Error should have a source.");
assert!(
err.source().unwrap().to_string().contains("write failure"),
"Source Error Message: {}",
err.source().unwrap().to_string()
);
Ok(())
},
_ => Err(DBError::new("incorrect error code")),
}
}
}
}
#[async_std::test]
async fn existing_entry_point() {
let dir = tempdir().unwrap();
let data = DataType::new("store").unwrap();
Entry::new(dir.path().join(ENTRY), data.clone())
.await
.unwrap();
let cache = Cache::new(dir.path()).await.unwrap();
}
#[async_std::test]
async fn corrupt_enty_point() -> Result<(), DBError> {
let dir = tempdir().unwrap();
let file = dir.path().join(ENTRY);
write(file, b"Really bad data.").await.unwrap();
match Cache::new(dir.path()).await {
Ok(_) => Err(DBError::new("should have errored")),
Err(_) => Ok(()),
}
}
}