Extract ItemVersion
This commit is contained in:
parent
5643ea3ee1
commit
2228534a9c
5 changed files with 45 additions and 13 deletions
28
src/index.rs
28
src/index.rs
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue