From 91a29480dfb3badda873e90823df6e87023f956a Mon Sep 17 00:00:00 2001 From: grimhilt Date: Fri, 4 Aug 2023 19:17:04 +0200 Subject: [PATCH] fix blob creation and get changes --- src/store/object/blob.rs | 103 +++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 14 deletions(-) diff --git a/src/store/object/blob.rs b/src/store/object/blob.rs index 26132ce..6c1b6bf 100644 --- a/src/store/object/blob.rs +++ b/src/store/object/blob.rs @@ -1,4 +1,7 @@ -use std::io; +use std::io::{self, Read}; +use std::fs::File; +use std::io::Write; +use std::fs::OpenOptions; use std::path::PathBuf; use std::time::SystemTime; use std::fs; @@ -9,15 +12,17 @@ use crate::store::head; use crate::store::object::{update_dates, add_node, create_obj, rm_node}; pub struct Blob { - path: PathBuf, + r_path: PathBuf, + a_path: PathBuf, hash: String, obj_p: PathBuf, + data: Vec, } impl Blob { - pub fn new(path: PathBuf) -> Blob { + pub fn new(r_path: PathBuf) -> Blob { let mut hasher = Sha1::new(); - hasher.input_str(path.to_str().unwrap()); + hasher.input_str(r_path.to_str().unwrap()); let hash = hasher.result_str(); let (dir, res) = hash.split_at(2); @@ -26,15 +31,20 @@ impl Blob { obj_p.push(dir); obj_p.push(res); + let root = path::repo_root(); + let a_path = root.join(r_path.clone()); + Blob { - path, + r_path, + a_path, hash, obj_p, + data: vec![], } } fn get_line_filename(&mut self) -> (String, String) { - let file_name = self.path.file_name().unwrap().to_str().unwrap().to_owned(); + let file_name = self.r_path.file_name().unwrap().to_str().unwrap().to_owned(); let mut line = String::from("blob"); line.push_str(" "); line.push_str(&self.hash); @@ -44,7 +54,7 @@ impl Blob { } fn get_file_hash(&self) -> String { - let bytes = std::fs::read(self.path.clone()).unwrap(); + let bytes = std::fs::read(self.a_path.clone()).unwrap(); let hash = md5::compute(&bytes); format!("{:x}", hash) } @@ -53,14 +63,14 @@ impl Blob { let (line, file_name) = self.get_line_filename(); // add blob reference to parent - if self.path.iter().count() == 1 { + if self.r_path.iter().count() == 1 { head::add_line(line)?; } else { - add_node(self.path.parent().unwrap(), &line)?; + add_node(self.r_path.parent().unwrap(), &line)?; } // create blob object - let metadata = fs::metadata(self.path.clone())?; + let metadata = fs::metadata(self.a_path.clone())?; let mut content = file_name.clone(); content.push_str(" "); @@ -68,6 +78,7 @@ impl Blob { content.push_str(" "); content.push_str(&metadata.len().to_string()); content.push_str(" "); + let secs = metadata .modified() .unwrap() @@ -77,11 +88,22 @@ impl Blob { content.push_str(&secs.to_string()); content.push_str(" "); content.push_str(&self.get_file_hash()); - create_obj(self.hash.clone(), &content)?; + content.push_str(" "); + + // create ref of object + let binding = self.obj_p.clone(); + let child = binding.file_name(); + self.obj_p.pop(); + self.obj_p.push(child.unwrap().to_str().unwrap()); + let mut file = OpenOptions::new() + .create_new(true) + .write(true) + .open(self.obj_p.clone())?; + writeln!(file, "{}", &content)?; // update date for all parent if up_parent { - update_dates(self.path.clone(), ts_remote)?; + update_dates(self.r_path.clone(), ts_remote)?; } Ok(()) } @@ -90,10 +112,10 @@ impl Blob { let (line, _) = self.get_line_filename(); // remove blob reference to parent - if self.path.iter().count() == 1 { + if self.r_path.iter().count() == 1 { head::rm_line(&line)?; } else { - rm_node(self.path.parent().unwrap(), &line)?; + rm_node(self.r_path.parent().unwrap(), &line)?; } // remove blob object @@ -101,4 +123,57 @@ impl Blob { Ok(()) } + + pub fn read_data(&mut self) { + if self.data.len() == 0 { + if let Ok(mut file) = File::open(self.obj_p.clone()) { + let mut buffer = String::new(); + let _ = file.read_to_string(&mut buffer); + let data = buffer.rsplit(' ').collect::>(); + for e in data { + self.data.push(String::from(e)); + } + self.data.reverse(); + } + } + } + + fn has_same_size(&mut self) -> bool { + let metadata = match fs::metadata(self.a_path.clone()) { + Ok(m) => m, + Err(_) => return true, + }; + + self.read_data(); + if self.data.len() < 3 { return true; } + metadata.len().to_string() == self.data[2] + } + + fn is_newer(&mut self) -> bool { + let metadata = match fs::metadata(self.a_path.clone()) { + Ok(m) => m, + Err(_) => return true, + }; + + self.read_data(); + let secs = metadata + .modified() + .unwrap() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(); + if self.data.len() < 4 { return true; } + secs > self.data[3].parse::().unwrap() + } + + fn has_same_hash(&mut self) -> bool { + self.read_data(); + if self.data.len() < 5 { return false; } + self.data[4] == self.get_file_hash() + } + + pub fn has_change(&mut self) -> bool { + !self.has_same_size() || (self.is_newer() && !self.has_same_hash()) + } } +