Implement RefStore for SimpleCas.
This commit is contained in:
@@ -39,6 +39,6 @@ pub use crate::{
|
||||
object_type::{ObjectType},
|
||||
object_metadata::{ObjectMetadata},
|
||||
pipeline::{Pipeline, DefaultPipeline, Reader, Writer, ReadWrapper, WriteWrapper},
|
||||
cas::{Cas},
|
||||
cas::{Cas, RefStore},
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use digest::DynDigest;
|
||||
use toml::Value;
|
||||
use cas_core::{
|
||||
Cas, DefaultPipeline, Error, ObjectId, ObjectMetadata, ObjectType,
|
||||
Pipeline, Reader, ReadWrapper, Result, Writer,
|
||||
Pipeline, Reader, ReadWrapper, RefStore, Result, Writer,
|
||||
};
|
||||
|
||||
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 {
|
||||
root_dirs: Vec<PathBuf>,
|
||||
@@ -560,4 +611,26 @@ mod tests {
|
||||
.collect::<Result<Vec<_>>>().unwrap();
|
||||
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