using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using Microsoft.Data.Sqlite; using System.Reflection; using System.Windows.Forms; using System.Configuration; using System.Diagnostics; namespace DataOrganizer { public class DB { public static string DatabasePath { get; private set; } public static string ConnectionString { get; private set; } public static string TempScriptLocal = "Y:\\Database Template.sql"; public DB() { DatabasePath = $"{new FileInfo(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath).Directory.FullName}\\Organizer Data\\Main.sqlite"; ConnectionString = $"Data Source={DatabasePath}"; if (!File.Exists(DatabasePath)) { Directory.CreateDirectory(new FileInfo(DatabasePath).Directory.FullName); CreateDatabase(); } } public void DeleteDatabase() { if (File.Exists(DatabasePath)) File.Delete(DatabasePath); } private void CreateDatabase() { //TODO: this is tmp var query = File.ReadAllText(TempScriptLocal); using (var connection = new SqliteConnection(ConnectionString)) { using(var command = new SqliteCommand(query, connection)) { connection.Open(); command.ExecuteNonQuery(); } } } public List GetProfiles() { var query = "SELECT * FROM profile"; var profiles = new List(); using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { connection.Open(); var reader = command.ExecuteReader(); while (reader.Read()) { profiles.Add(new Profile { Name = reader["profile_name"].ToString(), DefaultNewContentFolder = reader["default_new_content_folder_name"].ToString(), MachineName = reader["machine_name"].ToString(), Id = Convert.ToInt32(reader["profile_id"]), FolderGroups = new List() }); } reader.Close(); command.CommandText = "SELECT root_id, name, path, pattern_id FROM folder_root WHERE profile_id = @ID ORDER BY name"; foreach(var profile in profiles) { command.Parameters.Clear(); command.Parameters.AddWithValue("ID", profile.Id); reader = command.ExecuteReader(); while(reader.Read()) { var type = OrganizationType.Custom; var patternId = Convert.ToInt32(reader["pattern_id"]); switch (patternId) { case 1: type = OrganizationType.SingleLevel; break; case 2: type = OrganizationType.Flat; break; default: type = OrganizationType.Custom; break; } profile.FolderGroups.Add(new FolderGroup { Name = reader["name"].ToString(), Id = Convert.ToInt32(reader["root_id"]), Path = reader["path"].ToString(), PatternId = Convert.ToInt32(reader["pattern_id"]), Type = type }); } reader.Close(); } } } return profiles; } public bool UpdateProfile(Profile profile) { var query = @"UPDATE main.profile SET machine_name = @MachineName, default_new_content_folder_name = @DefaultPath, profile_name = @Name WHERE profile_id = @ID"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("MachineName", profile.MachineName); command.Parameters.AddWithValue("DefaultPath", profile.DefaultNewContentFolder); command.Parameters.AddWithValue("Name", profile.Name); command.Parameters.AddWithValue("ID", profile.Id); connection.Open(); command.ExecuteNonQuery(); } } return true; } public int InsertNewProfile(Profile profile) { var query = @"INSERT INTO main.profile (machine_name, default_new_content_folder_name, profile_name) VALUES (@MachineName, @DefaultPath, @Name)"; var id = -1; using (var connection = new SqliteConnection(ConnectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { using (var command = new SqliteCommand(query, connection, transaction)) { command.Parameters.AddWithValue("MachineName", profile.MachineName); command.Parameters.AddWithValue("DefaultPath", profile.DefaultNewContentFolder); command.Parameters.AddWithValue("Name", profile.Name); command.ExecuteNonQuery(); command.CommandText = "SELECT MAX(profile_id) FROM main.profile"; id = Convert.ToInt32(command.ExecuteScalar()); command.CommandText = "INSERT INTO main.folder_root (name, path, profile_id, pattern_id) VALUES (@Name, @Path, @ProfileID, @Pattern)"; if (profile.FolderGroups != null) { foreach(var group in profile.FolderGroups) { command.Parameters.Clear(); command.Parameters.AddWithValue("Name", group.Name); command.Parameters.AddWithValue("Path", group.Path); command.Parameters.AddWithValue("ProfileID", id); command.Parameters.AddWithValue("Pattern", group.PatternId); command.ExecuteNonQuery(); } } } transaction.Commit(); } } return id; } public int InsertNewFolderGroup(Profile profile, string name, string path, int pattern_id) { var query = @"INSERT INTO main.folder_root (name, path, profile_id, pattern_id) VALUES (@Name, @Path, @ProfileID, @Pattern)"; var id = -1; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("Name", name); command.Parameters.AddWithValue("Path", path); command.Parameters.AddWithValue("ProfileID", profile.Id); command.Parameters.AddWithValue("Pattern", pattern_id); connection.Open(); command.ExecuteNonQuery(); command.CommandText = @"SELECT MAX(root_id) FROM main.folder_root"; id = Convert.ToInt32(command.ExecuteScalar()); } } return id; } public bool UpdateFolderGroup(FolderGroup group) { var query = @"UPDATE main.folder_root SET name = @Name, path = @Path, pattern_id = @Pattern WHERE root_id = @ID"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("Name", group.Name); command.Parameters.AddWithValue("Path", group.Path); command.Parameters.AddWithValue("Pattern", group.PatternId); command.Parameters.AddWithValue("ID", group.Id); connection.Open(); command.ExecuteNonQuery(); } } return true; } public bool DeleteFolderGroup(FolderGroup folderGroup) { var query = string.Format("DELETE FROM main.file WHERE folder_root_id = {0}", folderGroup.Id); using(var connection = new SqliteConnection(ConnectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { using(var command = new SqliteCommand(query, connection, transaction)) { command.ExecuteNonQuery(); command.CommandText = string.Format("DELETE FROM main.folder_root WHERE root_id = {0}", folderGroup.Id); command.ExecuteNonQuery(); } transaction.Commit(); } } return true; } public bool DeleteProfile(Profile profile) { var query = string.Format("DELETE FROM main.file WHERE profile_id = {0}", profile.Id); using (var connection = new SqliteConnection(ConnectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { using (var command = new SqliteCommand(query, connection, transaction)) { command.ExecuteNonQuery(); command.CommandText = string.Format("DELETE FROM main.folder_root WHERE profile_id = {0}", profile.Id); command.ExecuteNonQuery(); command.CommandText = string.Format("DELETE FROM main.profile WHERE profile_id = {0}", profile.Id); command.ExecuteNonQuery(); } transaction.Commit(); } } return true; } public List GetNamingConventions() { var conventions = new List(); var query = @"SELECT name, example_text, pattern_id, regex FROM main.naming_pattern"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { connection.Open(); var reader = command.ExecuteReader(); while (reader.Read()) { conventions.Add(new Namingconvention { Regex = reader["regex"].ToString(), Name = reader["name"].ToString(), ExampleText = reader["example_text"].ToString(), Id = Convert.ToInt32(reader["pattern_id"]) }); } } } return conventions; } public Namingconvention GetNamingConventionByName(string name) { var query = @"SELECT name, example_text, pattern_id, regex FROM main.naming_pattern WHERE name = @Name"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("Name", name); connection.Open(); var reader = command.ExecuteReader(); reader.Read(); return new Namingconvention { Regex = reader["regex"].ToString(), Name = reader["name"].ToString(), ExampleText = reader["example_text"].ToString(), Id = Convert.ToInt32(reader["pattern_id"]) }; } } } public string GetNamingPatternById(int id) { if (id == 0) return string.Empty; var query = @"SELECT regex FROM main.naming_pattern WHERE pattern_id = @ID"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("ID", id); connection.Open(); var reader = command.ExecuteReader(); reader.Read(); return reader["regex"].ToString(); } } } public void DeleteNamingConvention(int id) { var query = @"UPDATE main.file SET pattern_override_id = 0 WHERE pattern_override_id = @ID";//@"DELETE FROM main.naming_pattern WHERE pattern_id = @Id"; using (var connection = new SqliteConnection(ConnectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { using (var command = new SqliteCommand(query, connection, transaction)) { command.Parameters.AddWithValue("ID", id); command.ExecuteNonQuery(); query = @"UPDATE main.folder_root SET pattern_id = 0 WHERE pattern_id = @ID"; command.ExecuteNonQuery(); query = @"DELETE FROM main.naming_pattern WHERE pattern_id = @ID"; command.ExecuteNonQuery(); } transaction.Commit(); } } } public string GetRootPathById(int id) { var query = @"SELECT path FROM folder_root WHERE root_id = @ID"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("ID", id); connection.Open(); var reader = command.ExecuteReader(); reader.Read(); return reader["path"].ToString(); } } } public bool UpdateNamingPatterById(int id, string newPattern) { var query = @"UPDATE main.naming_pattern SET regex = @pattern WHERE pattern_id = @ID"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("pattern", newPattern); command.Parameters.AddWithValue("ID", id); connection.Open(); command.ExecuteNonQuery(); } } return true; } public List GetFilesForProfileByFolderGroup(int profileId, int folderGroupId) { var files = new List(); var query = @"SELECT * FROM main.file INNER JOIN main.folder_root ON main.file.folder_root_id = main.folder_root.root_id WHERE main.file.profile_id = @ProfileId AND folder_root_id = @GroupId ORDER BY main.file.full_path ASC"; using (var connection = new SqliteConnection(ConnectionString)) { using (var command = new SqliteCommand(query, connection)) { command.Parameters.AddWithValue("ProfileId", profileId); command.Parameters.AddWithValue("GroupId", folderGroupId); connection.Open(); var reader = command.ExecuteReader(); while(reader.Read()) { files.Add(new FileSnapshot { Id = Convert.ToInt32(reader["file_id"]), PathNoRoot = reader["full_path"].ToString(), Name = reader["name"].ToString(), ProfileId = profileId, RootFolderId = folderGroupId, Size = Convert.ToInt64(reader["size"]), CreationDate = Convert.ToDateTime(reader["date_created"]), ModifiedDate = Convert.ToDateTime(reader["date_modified"]), PatternId = Convert.ToInt32(reader["pattern_override_id"]), RootPath = reader["path"].ToString(), }); } } } return files; } public void InsertNewFileRecord(List files, int profileId, int folderGroupId, string root) { var query = @"INSERT INTO main.file (full_path, name, size, date_created, date_modified, folder_root_id, profile_id, pattern_override_id) VALUES (@FullPath, @Name, @Size, @DateCreated, @DateModified, @FolderId, @ProfileId, @PatternId)"; var rootLength = root.Length; using (var connection = new SqliteConnection(ConnectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { using (var command = new SqliteCommand(query, connection, transaction)) { foreach (var file in files) { command.Parameters.AddWithValue("FullPath", file.PathNoRoot.Remove(0, rootLength + 1)); //Remove the root and the trailing slash that the root folder would have. command.Parameters.AddWithValue("Name", file.Name); command.Parameters.AddWithValue("Size", file.Size); command.Parameters.AddWithValue("DateCreated", file.CreationDate); command.Parameters.AddWithValue("DateModified", file.ModifiedDate); command.Parameters.AddWithValue("FolderId", folderGroupId); command.Parameters.AddWithValue("ProfileId", profileId); command.Parameters.AddWithValue("PatternId", file.PatternId); command.ExecuteNonQuery(); command.Parameters.Clear(); } } transaction.Commit(); } } } public struct Profile { public string Name; public string DefaultNewContentFolder; public string MachineName; public int Id; public List FolderGroups; } public struct FolderGroup { public int Id; public string Name; public string Path; public OrganizationType Type; public int PatternId; } public struct Namingconvention { public int Id; public string Name; public string ExampleText; public string Regex; } public struct FileSnapshot { public int Id; public string PathNoRoot; public string Name; public int ProfileId; public int PatternId; public int RootFolderId; public DateTime CreationDate; public DateTime ModifiedDate; public long Size; public string RootPath; } public enum OrganizationType { Flat = 0, SingleLevel = 1, Custom = 2 } } }