Refactor code structure for improved readability and maintainability
This commit is contained in:
311
DaireApplication/DataBase/DataPathManager.cs
Normal file
311
DaireApplication/DataBase/DataPathManager.cs
Normal file
@@ -0,0 +1,311 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DaireApplication.DataBase
|
||||
{
|
||||
public static class DataPathManager
|
||||
{
|
||||
private static readonly string AppName = "DaireApplication";
|
||||
private static string _dataDirectory;
|
||||
|
||||
// Expected CSV headers for each file
|
||||
private static readonly string UsersCsvHeader = "ID,UserName,Password,CanEdit,IsAdmin,IsActive";
|
||||
private static readonly string RecipeCsvHeader = "ID,Name,TankTemp,FountainTemp,Mixer,Fountain,MoldHeater,Vibration,VibHeater,Pedal,PedalOnTime,PedalOffTime,HeatingGoal,CoolingGoal,PouringGoal";
|
||||
private static readonly string MachineCsvHeader = "ID,TankMaxHeat,PumbMaxHeat,PumbDelay,MixerDelay,HeatingDelay,CoolingDelay,PouringDelay,PumbMinHeat,AbsMaxTemp,AbsMinTemp,PreHeatingTemp,SetTemp1,SetTemp2,SetTemp3,SetTemp4";
|
||||
private static readonly string MappingCsvHeader = "Id,Name,Address,IsRead,BitNumbers";
|
||||
private static readonly string ConfigrationCsvHeader = "Id,Max,Min,H_out,FC_out,SC_out,kp,ki,kd,kl,Name,I_Nuet,I_Mot1,I_Mot2,FC_Threshold,HeatConRange";
|
||||
private static readonly string ErrorSettingsCsvHeader = "Id,gridFreq,phaseNumber,extPower,phaseVoltage";
|
||||
private static readonly string ScreenCsvHeader = "Id,Brightness,DimSec,OffSec,Port,BoundRate,Parity,StopBits,SendingTime,WarningLimit,ErrorLimit";
|
||||
|
||||
static DataPathManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Determine the data directory based on the OS
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
// Windows: Use LocalApplicationData
|
||||
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
_dataDirectory = Path.Combine(appDataPath, AppName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Linux/macOS: Use ~/.local/share/DaireApplication
|
||||
string home = Environment.GetEnvironmentVariable("HOME") ?? "/tmp";
|
||||
_dataDirectory = Path.Combine(home, ".local", "share", AppName);
|
||||
}
|
||||
|
||||
// Ensure the directory exists
|
||||
Directory.CreateDirectory(_dataDirectory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to CreateDirectory: {ex.Message}");
|
||||
Console.WriteLine($"_dataDirectory: {_dataDirectory}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the full path for a data file, ensuring the directory exists.
|
||||
/// </summary>
|
||||
public static string GetDataFilePath(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure the directory exists before returning the file path
|
||||
Directory.CreateDirectory(_dataDirectory);
|
||||
return Path.Combine(_dataDirectory, fileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to GetDataFilePath: {ex.Message}");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migrates legacy data files from the application's base directory to the new data directory.
|
||||
/// </summary>
|
||||
public static void MigrateLegacyData()
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] csvFiles = { "Users.csv", "Recipe.csv", "Machine.csv", "Mapping.csv",
|
||||
"Configration.csv", "ErrorSettings.csv", "Screen.csv" };
|
||||
|
||||
foreach (string file in csvFiles)
|
||||
{
|
||||
string legacyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, file);
|
||||
string newPath = GetDataFilePath(file);
|
||||
|
||||
// If the file exists in the old location but not in the new location, move it
|
||||
if (File.Exists(legacyPath) && !File.Exists(newPath))
|
||||
{
|
||||
// Ensure the target directory exists
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(newPath) ?? _dataDirectory);
|
||||
File.Move(legacyPath, newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to MigrateLegacyData: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migrates CSV files by adding missing columns with default values instead of deleting them.
|
||||
/// </summary>
|
||||
public static void MigrateCsvFiles()
|
||||
{
|
||||
MigrateCsvFile("Users.csv", UsersCsvHeader, GetUsersDefaultValues);
|
||||
MigrateCsvFile("Recipe.csv", RecipeCsvHeader, GetRecipeDefaultValues);
|
||||
MigrateCsvFile("Machine.csv", MachineCsvHeader, GetMachineDefaultValues);
|
||||
MigrateCsvFile("Mapping.csv", MappingCsvHeader, GetMappingDefaultValues);
|
||||
MigrateCsvFile("Configration.csv", ConfigrationCsvHeader, GetConfigrationDefaultValues);
|
||||
MigrateCsvFile("ErrorSettings.csv", ErrorSettingsCsvHeader, GetErrorSettingsDefaultValues);
|
||||
MigrateCsvFile("Screen.csv", ScreenCsvHeader, GetScreenDefaultValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migrates a CSV file by adding missing columns with default values.
|
||||
/// </summary>
|
||||
private static void MigrateCsvFile(string fileName, string expectedHeader, Func<string, string> getDefaultValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
string filePath = GetDataFilePath(fileName);
|
||||
if (!File.Exists(filePath))
|
||||
return;
|
||||
|
||||
string[] lines = File.ReadAllLines(filePath);
|
||||
if (lines.Length == 0)
|
||||
return;
|
||||
|
||||
string actualHeader = lines[0];
|
||||
if (string.Equals(actualHeader.Trim(), expectedHeader.Trim(), StringComparison.OrdinalIgnoreCase))
|
||||
return; // No migration needed
|
||||
|
||||
string[] expectedColumns = expectedHeader.Split(',');
|
||||
string[] actualColumns = actualHeader.Split(',');
|
||||
|
||||
// Find missing columns
|
||||
var missingColumns = new List<(int index, string columnName)>();
|
||||
for (int i = 0; i < expectedColumns.Length; i++)
|
||||
{
|
||||
if (i >= actualColumns.Length || !string.Equals(actualColumns[i].Trim(), expectedColumns[i].Trim(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
missingColumns.Add((i, expectedColumns[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (missingColumns.Count == 0)
|
||||
return;
|
||||
|
||||
// Migrate the file
|
||||
var migratedLines = new List<string>();
|
||||
|
||||
// Add new header
|
||||
migratedLines.Add(expectedHeader);
|
||||
|
||||
// Migrate data rows
|
||||
for (int i = 1; i < lines.Length; i++)
|
||||
{
|
||||
string[] dataColumns = lines[i].Split(',');
|
||||
var newDataColumns = new List<string>(dataColumns);
|
||||
|
||||
// Add missing columns with default values
|
||||
foreach (var missing in missingColumns)
|
||||
{
|
||||
if (missing.index >= newDataColumns.Count)
|
||||
{
|
||||
newDataColumns.Add(getDefaultValue(missing.columnName));
|
||||
}
|
||||
else
|
||||
{
|
||||
newDataColumns.Insert(missing.index, getDefaultValue(missing.columnName));
|
||||
}
|
||||
}
|
||||
|
||||
migratedLines.Add(string.Join(",", newDataColumns));
|
||||
}
|
||||
|
||||
// Write the migrated file
|
||||
File.WriteAllLines(filePath, migratedLines);
|
||||
Console.WriteLine($"Migrated {fileName} - added {missingColumns.Count} missing columns");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Failed to migrate {fileName}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// Default value providers for each file type
|
||||
private static string GetUsersDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"IsActive" => "0",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetRecipeDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"TankTemp" => "0",
|
||||
"FountainTemp" => "0",
|
||||
"Mixer" => "0",
|
||||
"Fountain" => "0",
|
||||
"MoldHeater" => "0",
|
||||
"Vibration" => "0",
|
||||
"VibHeater" => "0",
|
||||
"Pedal" => "0",
|
||||
"PedalOnTime" => "0",
|
||||
"PedalOffTime" => "0",
|
||||
"HeatingGoal" => "46",
|
||||
"CoolingGoal" => "27",
|
||||
"PouringGoal" => "30",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetMachineDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"TankMaxHeat" => "50",
|
||||
"PumbMaxHeat" => "50",
|
||||
"PumbDelay" => "60",
|
||||
"MixerDelay" => "60",
|
||||
"HeatingDelay" => "60",
|
||||
"CoolingDelay" => "60",
|
||||
"PouringDelay" => "60",
|
||||
"PumbMinHeat" => "-10",
|
||||
"AbsMaxTemp" => "65",
|
||||
"AbsMinTemp" => "-14",
|
||||
"PreHeatingTemp" => "5",
|
||||
"SetTemp1" => "0",
|
||||
"SetTemp2" => "-10",
|
||||
"SetTemp3" => "5",
|
||||
"SetTemp4" => "0",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetMappingDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"BitNumbers" => "",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetConfigrationDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"Max" => "0",
|
||||
"Min" => "0",
|
||||
"H_out" => "",
|
||||
"FC_out" => "",
|
||||
"SC_out" => "",
|
||||
"kp" => "0",
|
||||
"ki" => "0",
|
||||
"kd" => "0",
|
||||
"kl" => "0",
|
||||
"Name" => "",
|
||||
"I_Nuet" => "0",
|
||||
"I_Mot1" => "0",
|
||||
"I_Mot2" => "0",
|
||||
"FC_Threshold" => "3",
|
||||
"HeatConRange" => "50",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetErrorSettingsDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"gridFreq" => "50",
|
||||
"phaseNumber" => "3",
|
||||
"extPower" => "1",
|
||||
"phaseVoltage" => "220",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetScreenDefaultValues(string columnName)
|
||||
{
|
||||
return columnName switch
|
||||
{
|
||||
"Brightness" => "100",
|
||||
"DimSec" => "3300",
|
||||
"OffSec" => "3600",
|
||||
"Port" => "",
|
||||
"BoundRate" => "19200",
|
||||
"Parity" => "1",
|
||||
"StopBits" => "0",
|
||||
"SendingTime" => "50",
|
||||
"WarningLimit" => "0.5",
|
||||
"ErrorLimit" => "2",
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
|
||||
// Legacy delete methods (kept for backward compatibility but now call migration)
|
||||
public static void DeleteUsersCsv() => MigrateCsvFile("Users.csv", UsersCsvHeader, GetUsersDefaultValues);
|
||||
public static void DeleteRecipeCsv() => MigrateCsvFile("Recipe.csv", RecipeCsvHeader, GetRecipeDefaultValues);
|
||||
public static void DeleteMachineCsv() => MigrateCsvFile("Machine.csv", MachineCsvHeader, GetMachineDefaultValues);
|
||||
public static void DeleteMappingCsv() => MigrateCsvFile("Mapping.csv", MappingCsvHeader, GetMappingDefaultValues);
|
||||
public static void DeleteConfigrationCsv() => MigrateCsvFile("Configration.csv", ConfigrationCsvHeader, GetConfigrationDefaultValues);
|
||||
public static void DeleteErrorSettingsCsv() => MigrateCsvFile("ErrorSettings.csv", ErrorSettingsCsvHeader, GetErrorSettingsDefaultValues);
|
||||
public static void DeleteScreenCsv() => MigrateCsvFile("Screen.csv", ScreenCsvHeader, GetScreenDefaultValues);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user