Extract ItemVersion

This commit is contained in:
Cyryl Płotnicki 2019-09-07 11:37:31 +01:00
parent 5643ea3ee1
commit 2228534a9c
5 changed files with 45 additions and 13 deletions

View file

@ -5,12 +5,16 @@ use serde::{Deserialize, Serialize};
use crate::error::BakareError; use crate::error::BakareError;
use crate::repository_item::RepositoryItem; use crate::repository_item::RepositoryItem;
use std::fs::File; use std::fs::File;
use std::ops::Deref;
#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)]
pub struct ItemVersion(Box<[u8]>);
#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)]
pub struct IndexItem { pub struct IndexItem {
relative_path: String, relative_path: String,
original_source_path: String, original_source_path: String,
version: Box<[u8]>, version: ItemVersion,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@ -20,6 +24,26 @@ pub struct Index {
repository_path: String, repository_path: String,
} }
impl AsRef<[u8]> for ItemVersion {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Deref for ItemVersion {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<&[u8]> for ItemVersion {
fn from(a: &[u8]) -> Self {
ItemVersion(Box::from(a))
}
}
impl Index { impl Index {
pub fn new(repository_path: &Path) -> Self { pub fn new(repository_path: &Path) -> Self {
Index { Index {
@ -81,7 +105,7 @@ impl From<RepositoryItem> for IndexItem {
IndexItem { IndexItem {
relative_path: i.relative_path().to_string_lossy().to_string(), relative_path: i.relative_path().to_string_lossy().to_string(),
original_source_path: i.original_source_path().to_string_lossy().to_string(), original_source_path: i.original_source_path().to_string_lossy().to_string(),
version: i.version(), version: i.version().clone(),
} }
} }
} }

View file

@ -2,7 +2,7 @@ use std::path::Path;
use std::{fs, io}; use std::{fs, io};
use crate::error::BakareError; use crate::error::BakareError;
use crate::index::{Index, IndexIterator}; use crate::index::{Index, IndexIterator, ItemVersion};
use crate::repository_item::RepositoryItem; use crate::repository_item::RepositoryItem;
use sha2::Digest; use sha2::Digest;
use sha2::Sha512; use sha2::Sha512;
@ -82,15 +82,14 @@ impl<'a> Repository<'a> {
Ok(()) Ok(())
} }
fn calculate_version(source_path: &Path) -> Result<Box<[u8]>, BakareError> { fn calculate_version(source_path: &Path) -> Result<ItemVersion, BakareError> {
let source_file = File::open(source_path)?; let source_file = File::open(source_path)?;
let mut reader = BufReader::new(source_file); let mut reader = BufReader::new(source_file);
let mut hasher = Sha512::new(); let mut hasher = Sha512::new();
io::copy(&mut reader, &mut hasher)?; io::copy(&mut reader, &mut hasher)?;
let version = hasher.result(); Ok(hasher.result().as_slice().into())
Ok(Box::from(version.as_slice()))
} }
pub fn item_by_source_path(&self, path: &Path) -> Result<Option<RepositoryItem>, BakareError> { pub fn item_by_source_path(&self, path: &Path) -> Result<Option<RepositoryItem>, BakareError> {

View file

@ -1,4 +1,5 @@
use crate::error::BakareError; use crate::error::BakareError;
use crate::index::ItemVersion;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::path::Path; use std::path::Path;
use std::{fmt, fs}; use std::{fmt, fs};
@ -8,11 +9,11 @@ pub struct RepositoryItem {
relative_path: Box<Path>, relative_path: Box<Path>,
absolute_path: Box<Path>, absolute_path: Box<Path>,
original_source_path: Box<Path>, original_source_path: Box<Path>,
version: Box<[u8]>, version: ItemVersion,
} }
impl RepositoryItem { impl RepositoryItem {
pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path, version: Box<[u8]>) -> Self { pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path, version: ItemVersion) -> Self {
RepositoryItem { RepositoryItem {
relative_path: Box::from(relative_path), relative_path: Box::from(relative_path),
absolute_path: Box::from(absolute_path), absolute_path: Box::from(absolute_path),
@ -50,8 +51,8 @@ impl RepositoryItem {
&self.original_source_path &self.original_source_path
} }
pub fn version(&self) -> Box<[u8]> { pub fn version(&self) -> &ItemVersion {
self.version.clone() &self.version
} }
} }

View file

@ -1,6 +1,7 @@
use std::path::Path; use std::path::Path;
use crate::error::BakareError; use crate::error::BakareError;
use crate::index::ItemVersion;
use crate::repository::Repository; use crate::repository::Repository;
use crate::repository_item::RepositoryItem; use crate::repository_item::RepositoryItem;
@ -29,4 +30,9 @@ impl<'a> Engine<'a> {
item.save(self.target_path)?; item.save(self.target_path)?;
Ok(()) Ok(())
} }
pub fn restore_as_of_version(&self, item: &RepositoryItem, version: &ItemVersion) -> Result<(), BakareError> {
println!("restoring {}", item);
Ok(())
}
} }

View file

@ -75,7 +75,7 @@ fn restore_older_version_of_file() -> Result<(), BakareError> {
let item = reading_repository.item_by_source_path(&file_path)?; let item = reading_repository.item_by_source_path(&file_path)?;
assert!(item.is_some()); assert!(item.is_some());
let item = item.unwrap(); let item = item.unwrap();
let _old_version = item.version(); let old_version = item.version();
{ {
let new_contents = "totally new contents"; let new_contents = "totally new contents";
@ -87,8 +87,8 @@ fn restore_older_version_of_file() -> Result<(), BakareError> {
let restore_repository = Repository::open(repository_path.as_path())?; let restore_repository = Repository::open(repository_path.as_path())?;
let restore_target = tempdir()?; let restore_target = tempdir()?;
let _restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?; let restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?;
//restore_engine.restore_as_of_version(&item, old_version)?; restore_engine.restore_as_of_version(&item, old_version)?;
assert_target_file_contents(restore_target.path(), relative_path_text, old_contents) assert_target_file_contents(restore_target.path(), relative_path_text, old_contents)
} }
@ -161,3 +161,5 @@ fn get_sorted_files_recursively(path: &Path) -> Result<Vec<Box<Path>>, BakareErr
} }
// TODO: restore latest version by default // TODO: restore latest version by default
// TODO: deduplicate data // TODO: deduplicate data
// TODO: test that index is stored separately from data
// TODO: index corruption