diff --git a/src/database.rs b/src/database.rs new file mode 100644 index 0000000..b45df65 --- /dev/null +++ b/src/database.rs @@ -0,0 +1,68 @@ +use rusqlite::{Connection, params}; +use crate::coco_commit::CocoCommit; + +pub struct Database { + pub connection: Connection +} + +impl Database { + pub fn new(filename: &str) -> Database { + let connection = Connection::open(filename).unwrap(); + Database { + connection + } + } + + pub fn create_commit_table(&self) { + self.connection.execute( + "CREATE TABLE IF NOT EXISTS git_commit ( + commit_id TEXT PRIMARY KEY, + branch TEXT, + author TEXT, + committer TEXT, + date INT, + message TEXT, + parent_hashes TEXT, + tree_hash TEXT, + changes TEXT, + added INT, + deleted INT, + files TEXT + )", + params![], + ).unwrap(); + } + + pub fn create_file_change(&self) { + self.connection.execute( + "CREATE TABLE IF NOT EXISTS file_changed ( + id INTEGER PRIMARY KEY, + commit_id TEXT, + added INTEGER, + deleted INTEGER, + file TEXT, + mode TEXT + )", + params![], + ).unwrap(); + } + + pub fn insert_commit_with_changes(&self, commit: &CocoCommit) { + let changes = serde_json::to_string_pretty(&commit.changes).unwrap(); + let parent_hashes = commit.parent_hashes.join(" "); + + self.connection.execute( + "INSERT INTO git_commit (commit_id, branch, author, date, message, parent_hashes, tree_hash, changes) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)", + params![commit.commit_id, commit.branch, commit.author, commit.date, commit.message, parent_hashes, commit.tree_hash, changes], + ).unwrap(); + } + + pub fn insert_commit(&self, commit: &CocoCommit) { + let parent_hashes = commit.parent_hashes.join(" "); + + self.connection.execute( + "INSERT INTO git_commit (commit_id, branch, author, date, message, parent_hashes, tree_hash, added, deleted, files) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)", + params![commit.commit_id, commit.branch, commit.author, commit.date, commit.message, parent_hashes, commit.tree_hash, commit.added,commit.deleted, commit.files.join(",")], + ).unwrap(); + } +} \ No newline at end of file diff --git a/src/git_log_parser.rs b/src/git_log_parser.rs index 3ceac5e..d5341ce 100644 --- a/src/git_log_parser.rs +++ b/src/git_log_parser.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; use regex::{Captures, Regex}; -use rusqlite::{Connection, params}; use crate::coco_commit::{CocoCommit, FileChange}; use crate::cli_option::ConvertOptions; +use crate::database::Database; lazy_static! { static ref COMMIT_INFO: Regex = Regex::new( @@ -48,43 +48,16 @@ impl GitMessageParser { let split = str.split("\n"); let mut parser = GitMessageParser::default(); - let conn = Connection::open("coco_git.db").unwrap(); - conn.execute( - "CREATE TABLE IF NOT EXISTS git_commit ( - commit_id TEXT PRIMARY KEY, - branch TEXT, - author TEXT, - committer TEXT, - date INT, - message TEXT, - parent_hashes TEXT, - tree_hash TEXT, - changes TEXT, - added INT, - deleted INT, - files TEXT - )", - params![], - ).unwrap(); - - conn.execute( - "CREATE TABLE IF NOT EXISTS file_changed ( - id INTEGER PRIMARY KEY, - commit_id TEXT, - added INTEGER, - deleted INTEGER, - file TEXT, - mode TEXT - )", - params![], - ).unwrap(); + let db = Database::new("coco_git.db"); + db.create_commit_table(); + db.create_file_change(); for line in split { - parser.parse_log_by_line(line, &conn, &options) + parser.parse_log_by_line(line, &db, &options) } } - pub fn parse_log_by_line(&mut self, text: &str, conn: &Connection, options: &ConvertOptions) { + pub fn parse_log_by_line(&mut self, text: &str, db: &Database, options: &ConvertOptions) { // COMMIT_ID -> CHANGES -> CHANGE_MODEL -> Push to Commits if let Some(captures) = COMMIT_INFO.captures(text) { self.current_commit = GitMessageParser::create_commit(&captures) @@ -95,11 +68,11 @@ impl GitMessageParser { } else if let Some(caps) = CHANGEMODEL.captures(text) { self.update_change_mode(caps) } else if self.current_commit.commit_id != "" { - self.push_to_commits(conn, options); + self.push_to_commits(db, options); } } - fn push_to_commits(&mut self, conn: &Connection, options: &ConvertOptions) { + fn push_to_commits(&mut self, db: &Database, options: &ConvertOptions) { self.current_file_change = vec![]; for (_filename, change) in &self.current_file_change_map { self.current_file_change.push(change.clone()); @@ -118,19 +91,11 @@ impl GitMessageParser { self.current_file_change_map.clear(); let commit = &self.current_commit; - let parent_hashes = commit.parent_hashes.join(" "); - let changes = serde_json::to_string_pretty(&commit.changes).unwrap(); if options.with_changes { - conn.execute( - "INSERT INTO git_commit (commit_id, branch, author, date, message, parent_hashes, tree_hash, changes) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)", - params![commit.commit_id, commit.branch, commit.author, commit.date, commit.message, parent_hashes, commit.tree_hash, changes], - ).unwrap(); + db.insert_commit_with_changes(commit); } else { - conn.execute( - "INSERT INTO git_commit (commit_id, branch, author, date, message, parent_hashes, tree_hash, added, deleted, files) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)", - params![commit.commit_id, commit.branch, commit.author, commit.date, commit.message, parent_hashes, commit.tree_hash, commit.added,commit.deleted, commit.files.join(",")], - ).unwrap(); + db.insert_commit(commit); } } diff --git a/src/main.rs b/src/main.rs index b184146..89a3771 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ pub mod git_command; pub mod git_log_parser; pub mod coco_commit; pub mod cli_option; +pub mod database; pub fn analysis(local_path: &Path, options: ConvertOptions) { let messages = get_commit_message(Some(format!("{}", local_path.display())));