First working version of support for versions
This commit is contained in:
parent
3ac27c1021
commit
a20859597f
4 changed files with 15 additions and 25 deletions
24
src/index.rs
24
src/index.rs
|
@ -1,14 +1,13 @@
|
||||||
|
use std::collections::hash_map::Iter;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::error::BakareError;
|
use crate::error::BakareError;
|
||||||
use crate::error::BakareError::RepositoryPathNotAbsolute;
|
|
||||||
use crate::repository::{ItemId, Version};
|
use crate::repository::{ItemId, Version};
|
||||||
use crate::repository_item::RepositoryItem;
|
use crate::repository_item::RepositoryItem;
|
||||||
use std::collections::hash_map::Iter;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialOrd, PartialEq, Ord, Eq, Serialize, Deserialize)]
|
||||||
pub struct IndexItem {
|
pub struct IndexItem {
|
||||||
|
@ -48,11 +47,11 @@ impl IndexItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_version(&self, id: ItemId) -> IndexItem {
|
fn next_version(&self, id: ItemId, relative_path: String) -> IndexItem {
|
||||||
IndexItem {
|
IndexItem {
|
||||||
relative_path: self.relative_path.clone(),
|
|
||||||
original_source_path: self.original_source_path.clone(),
|
original_source_path: self.original_source_path.clone(),
|
||||||
version: self.version.next(),
|
version: self.version.next(),
|
||||||
|
relative_path,
|
||||||
id,
|
id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,20 +84,12 @@ impl Index {
|
||||||
Path::new(&self.index_path)
|
Path::new(&self.index_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn remember(&mut self, original_source_path: &Path, relative_path: &Path, id: ItemId) {
|
||||||
self.items_by_file_id.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.items_by_file_id.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remember(&mut self, original_source_path: &Path, absolute_path: &Path, relative_path: &Path, id: ItemId) {
|
|
||||||
let item = if let Some(old) = self
|
let item = if let Some(old) = self
|
||||||
.newest_items_by_source_path
|
.newest_items_by_source_path
|
||||||
.get(&original_source_path.to_string_lossy().to_string())
|
.get(&original_source_path.to_string_lossy().to_string())
|
||||||
{
|
{
|
||||||
old.next_version(id)
|
old.next_version(id, relative_path.to_string_lossy().to_string())
|
||||||
} else {
|
} else {
|
||||||
IndexItem::from(
|
IndexItem::from(
|
||||||
original_source_path.to_string_lossy().to_string(),
|
original_source_path.to_string_lossy().to_string(),
|
||||||
|
@ -108,6 +99,7 @@ impl Index {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!("remember {:?}", item);
|
||||||
self.items_by_file_id.insert(item.id.clone(), item.clone());
|
self.items_by_file_id.insert(item.id.clone(), item.clone());
|
||||||
self.newest_items_by_source_path
|
self.newest_items_by_source_path
|
||||||
.insert(original_source_path.to_string_lossy().to_string(), item.clone());
|
.insert(original_source_path.to_string_lossy().to_string(), item.clone());
|
||||||
|
@ -140,7 +132,7 @@ impl Index {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_by_id(&self, id: &ItemId) -> Result<Option<IndexItem>, BakareError> {
|
pub fn item_by_id(&self, id: &ItemId) -> Result<Option<IndexItem>, BakareError> {
|
||||||
Ok(self.items_by_file_id.get(id).map(|i| i.clone()))
|
Ok(self.items_by_file_id.get(id).cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newest_items(&self) -> IndexItemIterator {
|
pub fn newest_items(&self) -> IndexItemIterator {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
||||||
use std::{fmt, fs, io};
|
use std::{fmt, fs, io};
|
||||||
|
|
||||||
use crate::error::BakareError;
|
use crate::error::BakareError;
|
||||||
use crate::index::{Index, IndexItem, IndexItemIterator};
|
use crate::index::{Index, IndexItemIterator};
|
||||||
use crate::repository_item::RepositoryItem;
|
use crate::repository_item::RepositoryItem;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
@ -10,7 +10,6 @@ use sha2::Sha512;
|
||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::ops::Add;
|
|
||||||
|
|
||||||
/// represents a place where backup is stored an can be restored from.
|
/// represents a place where backup is stored an can be restored from.
|
||||||
/// right now only on-disk directory storage is supported
|
/// right now only on-disk directory storage is supported
|
||||||
|
@ -102,15 +101,14 @@ impl<'a> Repository<'a> {
|
||||||
if source_path.is_file() {
|
if source_path.is_file() {
|
||||||
fs::create_dir_all(destination_path.parent().unwrap())?;
|
fs::create_dir_all(destination_path.parent().unwrap())?;
|
||||||
fs::copy(source_path, destination_path)?;
|
fs::copy(source_path, destination_path)?;
|
||||||
|
let relative_path = destination_path.strip_prefix(self.path)?;
|
||||||
self.index
|
self.index.remember(source_path, relative_path, id);
|
||||||
.remember(source_path, destination_path, destination_path.strip_prefix(self.path)?, id);
|
|
||||||
self.index.save()?;
|
self.index.save()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newest_item_by_source__path(&self, path: &Path) -> Result<Option<RepositoryItem>, BakareError> {
|
pub fn newest_item_by_source_path(&self, path: &Path) -> Result<Option<RepositoryItem>, BakareError> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.index
|
.index
|
||||||
.newest_item_by_source_path(path)?
|
.newest_item_by_source_path(path)?
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub fn assert_restored_has_contents(
|
||||||
let restore_repository = Repository::open(repository_path)?;
|
let restore_repository = Repository::open(repository_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())?;
|
||||||
let item = restore_repository.newest_item_by_source__path(&source_file_full_path)?;
|
let item = restore_repository.newest_item_by_source_path(&source_file_full_path)?;
|
||||||
restore_engine.restore(&item.unwrap())?;
|
restore_engine.restore(&item.unwrap())?;
|
||||||
let restored_file_path = restore_target.path().join(source_file_full_path.strip_prefix("/")?);
|
let restored_file_path = restore_target.path().join(source_file_full_path.strip_prefix("/")?);
|
||||||
assert_target_file_contents(&restored_file_path, contents)
|
assert_target_file_contents(&restored_file_path, contents)
|
||||||
|
@ -65,7 +65,7 @@ pub fn assert_restored_from_version_has_contents(
|
||||||
pub fn item_id(repository_path: &Path, source_file_full_path: &Path) -> Result<ItemId, BakareError> {
|
pub fn item_id(repository_path: &Path, source_file_full_path: &Path) -> Result<ItemId, BakareError> {
|
||||||
let id = {
|
let id = {
|
||||||
let reading_repository = Repository::open(repository_path)?;
|
let reading_repository = Repository::open(repository_path)?;
|
||||||
let item = reading_repository.newest_item_by_source__path(&source_file_full_path)?;
|
let item = reading_repository.newest_item_by_source_path(&source_file_full_path)?;
|
||||||
assert!(item.is_some());
|
assert!(item.is_some());
|
||||||
let item = item.unwrap();
|
let item = item.unwrap();
|
||||||
item.id().clone()
|
item.id().clone()
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn restore_files_after_reopening_repository() -> Result<(), BakareError> {
|
||||||
restore_all_from_reloaded_repository(&repository_path, &restore_target)?;
|
restore_all_from_reloaded_repository(&repository_path, &restore_target)?;
|
||||||
|
|
||||||
let source_file_full_path = &source.file_path(source_file_relative_path);
|
let source_file_full_path = &source.file_path(source_file_relative_path);
|
||||||
assert_restored_has_contents(repository_path, source_file_full_path, "newest contents")
|
assert_restored_has_contents(repository_path, source_file_full_path, original_contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue