Implement RefStore for SimpleCas.
This commit is contained in:
@@ -39,6 +39,6 @@ pub use crate::{
|
|||||||
object_type::{ObjectType},
|
object_type::{ObjectType},
|
||||||
object_metadata::{ObjectMetadata},
|
object_metadata::{ObjectMetadata},
|
||||||
pipeline::{Pipeline, DefaultPipeline, Reader, Writer, ReadWrapper, WriteWrapper},
|
pipeline::{Pipeline, DefaultPipeline, Reader, Writer, ReadWrapper, WriteWrapper},
|
||||||
cas::{Cas},
|
cas::{Cas, RefStore},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use digest::DynDigest;
|
|||||||
use toml::Value;
|
use toml::Value;
|
||||||
use cas_core::{
|
use cas_core::{
|
||||||
Cas, DefaultPipeline, Error, ObjectId, ObjectMetadata, ObjectType,
|
Cas, DefaultPipeline, Error, ObjectId, ObjectMetadata, ObjectType,
|
||||||
Pipeline, Reader, ReadWrapper, Result, Writer,
|
Pipeline, Reader, ReadWrapper, RefStore, Result, Writer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
@@ -162,6 +162,57 @@ impl Cas for SimpleCas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RefStore for SimpleCas {
|
||||||
|
fn get_ref<P: AsRef<Path>>(&self, key: P) -> Result<ObjectId> {
|
||||||
|
let path = ref_dir(&self.db_path).join(key.as_ref());
|
||||||
|
if !path.exists() {
|
||||||
|
Error::err(format!("reference {} does not exists", key.as_ref().to_string_lossy()))
|
||||||
|
}
|
||||||
|
else if !path.is_file() {
|
||||||
|
Error::err(format!("reference {} is not a file", key.as_ref().to_string_lossy()))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let file = std::fs::read(path).or_else(|err|
|
||||||
|
Error::err(format!("failed to read reference file for {}: {}", key.as_ref().to_string_lossy(), err))
|
||||||
|
)?;
|
||||||
|
Ok(
|
||||||
|
ObjectId::from_str(
|
||||||
|
std::str::from_utf8(&file).or_else(|err|
|
||||||
|
Error::err(format!("invalid reference file at {}: {}", key.as_ref().to_string_lossy(), err))
|
||||||
|
)?
|
||||||
|
)?
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_ref<P: AsRef<Path>>(&mut self, key: P, value: &ObjectId) -> Result<()> {
|
||||||
|
let path = ref_dir(&self.db_path).join(key.as_ref());
|
||||||
|
std::fs::create_dir_all(path.parent().ok_or_else(||
|
||||||
|
Error::error(format!("reference file {} has no parent dir?", key.as_ref().to_string_lossy()))
|
||||||
|
)?).or_else(|err|
|
||||||
|
Error::err(format!("failed to create reference dir for {}: {}", key.as_ref().to_string_lossy(), err))
|
||||||
|
)?;
|
||||||
|
std::fs::write(path, value.to_string()).or_else(|err|
|
||||||
|
Error::err(format!("failed to write reference {}: {}", key.as_ref().to_string_lossy(), err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_ref<P: AsRef<Path>>(&mut self, key: P) -> Result<()> {
|
||||||
|
let path = ref_dir(&self.db_path).join(key.as_ref());
|
||||||
|
if !path.exists() {
|
||||||
|
Error::err(format!("reference {} does not exists", key.as_ref().to_string_lossy()))
|
||||||
|
}
|
||||||
|
else if !path.is_file() {
|
||||||
|
Error::err(format!("reference {} is not a file", key.as_ref().to_string_lossy()))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::fs::remove_file(path).or_else(|err|
|
||||||
|
Error::err(format!("failed to remove reference file {}: {}", key.as_ref().to_string_lossy(), err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct ObjectIdIterator {
|
pub struct ObjectIdIterator {
|
||||||
root_dirs: Vec<PathBuf>,
|
root_dirs: Vec<PathBuf>,
|
||||||
@@ -560,4 +611,26 @@ mod tests {
|
|||||||
.collect::<Result<Vec<_>>>().unwrap();
|
.collect::<Result<Vec<_>>>().unwrap();
|
||||||
assert_eq!(objects, oids);
|
assert_eq!(objects, oids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reference() {
|
||||||
|
let dir = tempfile::tempdir().expect("failed to create temp test dir");
|
||||||
|
let cas_path = get_cas_path(dir.path());
|
||||||
|
let config = get_config();
|
||||||
|
|
||||||
|
let mut cas = SimpleCas::create(cas_path.clone(), config)
|
||||||
|
.expect("failed to create SimpleCas object");
|
||||||
|
|
||||||
|
let oid_0 = ObjectId::from_str("f731f6bc6a6a73bad170e56452473ef6930b7a0ab33cc54be44221a89b49d786").unwrap();
|
||||||
|
|
||||||
|
assert!(cas.get_ref("foo/bar").is_err());
|
||||||
|
assert!(cas.remove_ref("foo/bar").is_err());
|
||||||
|
|
||||||
|
cas.set_ref("foo/bar", &oid_0).unwrap();
|
||||||
|
assert_eq!(cas.get_ref("foo/bar").unwrap(), oid_0);
|
||||||
|
|
||||||
|
cas.remove_ref("foo/bar").unwrap();
|
||||||
|
|
||||||
|
assert!(cas.get_ref("foo/bar").is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user