dmdb/model/XmlData.cs

119 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace dezentrale.model
{
public class XmlData : XmlLog
{
[XmlAttribute] public DateTime LastChanged { get; set; } = DateTime.Now;
[XmlAttribute] public string ProgramVersion { get; set; } = "";
/** \brief Move or make a backup copy of the specified file to the same folder. Will overwrite old backups if @ref permanentWithTimestamp is false
* \param name="fileWithPath" Source file to copy. File must exist.
* \param name="backupName" Optional name for a backup. E.g. "PreImport" or "NewProgVersion"
* \param param name="permanentWithTimestamp" Stores the backup including a timestamp (@ref DateTime.Now) and fails if the target file already exists.
* \return the resulting name on success.
* \note this method throws Exceptions when failing.
*/
public static string CreateBackup(string fileWithPath, bool fileMove = true, string backupName = null, bool permanentWithTimestamp = false)
{
if (!File.Exists(fileWithPath)) throw new FileNotFoundException(fileWithPath);
string backupFile = fileWithPath;
if (backupName != null) backupFile += "." + backupName;
if (permanentWithTimestamp) backupFile += "." + DateTime.Now.ToString("yyMMdd_HHmmss");
backupFile += ".bak";
if (File.Exists(backupFile))
{
if (permanentWithTimestamp)
throw new IOException($"File {backupFile} already exists");
File.Delete(backupFile);
}
if (fileMove) File.Move(fileWithPath, backupFile);
else File.Copy(fileWithPath, backupFile);
return backupName;
}
public static XmlData LoadFromFile(string fileName, Type type = null)
{
FileStream fs = null;
try
{
XmlSerializer ser = new XmlSerializer(type ?? typeof(XmlData));
fs = new FileStream(fileName, FileMode.Open);
XmlLog.SuppressAllLogging = true;
XmlData ds = (XmlData)ser.Deserialize(fs);
XmlLog.SuppressAllLogging = false;
fs.Close();
if (ds.ProgramVersion != Program.VersionString)
{
Console.WriteLine($"Object of type {ds.GetType()} was stored in Version {ds.ProgramVersion:X8}, Re-Storing with {Program.VersionNumber:X8}");
//backup file
try
{
CreateBackup(fileName, true, $"v{ds.ProgramVersion:X8}", true);
if (!SaveToFile(fileName, ds)) throw new Exception("Saving returned false");
} catch(Exception e2)
{
Console.WriteLine($"Error {e2.GetType()}: {e2.Message}");
}
}
return ds;
}
catch (Exception e)
{
XmlLog.SuppressAllLogging = false;
fs?.Close();
throw e.InnerException ?? e;
}
}
public static bool SaveToFile(string fileName, XmlData ds, Type[] extraTypes = null)
{
try
{
if (ds == null) throw new NullReferenceException("XmlData.SaveToFile(fileName, ds): ds == null");
if (File.Exists(fileName))
{
CreateBackup(fileName);
//string backupName = $"{fileName}.bak";
//if (File.Exists(backupName)) File.Delete(backupName);
//File.Move(fileName, backupName);
}
Console.WriteLine($"XmlData.SaveToFile({ds.GetType()})");
ds.ProgramVersion = Program.VersionString;
ds.LastChanged = DateTime.Now;
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer ser;
if (extraTypes != null)
ser = new XmlSerializer(ds.GetType(), extraTypes);
else
ser = new XmlSerializer(ds.GetType());
FileStream fs;
fs = new FileStream(fileName, FileMode.Create);
ser.Serialize(fs, ds, ns);
fs.Close();
}
catch (Exception e)
{
throw e.InnerException ?? e;
}
return true;
}
}
}