Files
duplicati/Duplicati/Scheduler/Data/HistoryDataSetSupport.cs
T
kenb@programmer.net 9b43ae6674 Removed DynamicLoader error log message
Several improvements to Scheduler
Added Scheduler backup monitors


git-svn-id: https://duplicati.googlecode.com/svn/trunk@1003 59da171f-624f-0410-aa54-27559c288bec
2011-11-18 15:39:16 +00:00

234 lines
9.4 KiB
C#

#region Disclaimer / License
// Copyright (C) 2011, Kenneth Bergeron, IAP Worldwide Services, Inc
// NOAA :: National Marine Fisheries Service
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Duplicati.Scheduler.Data
{
/// <summary>
/// Provides some tools used with the history dataset
/// </summary>
public partial class HistoryDataSet
{
/// <summary>
/// The name of the XML file (no path)
/// </summary>
public const string DefaultName = "History.xml";
/// <summary>
/// The XML file path without the file name
/// </summary>
public static string DefaultPath()
{
return GetAppData(DefaultName);
}
/// <summary>
/// The application path and filename, making sure it exists
/// </summary>
public static string GetAppData(string aFileName)
{
string Result = Utility.User.GetApplicationDirectory(@"Duplicati");
if (!System.IO.Directory.Exists(Result)) System.IO.Directory.CreateDirectory(Result);
return System.IO.Path.Combine(Result, aFileName);
}
/// <summary>
/// Load the database from the deefault XML file
/// </summary>
/// <returns>null if OK, else the exception</returns>
public Exception Load()
{
return Load(string.Empty);
}
/// <summary>
/// Load the database from a file (if empty, use the default)
/// </summary>
/// <param name="aFullPath">File to load or default if null or empty</param>
/// <returns>null if OK, else the exception</returns>
public Exception Load(string aFullPath)
{
if (string.IsNullOrEmpty(aFullPath)) aFullPath = DefaultPath();
if (!System.IO.File.Exists(aFullPath)) return new Exception("File not found: " + aFullPath);
this.Clear();
Exception Result = null;
try
{
this.ReadXml(aFullPath);
}
catch (Exception Ex)
{
Result = Ex;
}
return Result;
}
/// <summary>
/// Saves the dataset to the default XML
/// </summary>
/// <returns>null if OK, else the exception</returns>
public Exception Save()
{
return Save(GetAppData(DefaultName));
}
/// <summary>
/// Saves the dataset to the passed file
/// </summary>
/// <param name="aFullPath">XML file to load</param>
/// <returns>null if OK, else the exception</returns>
public Exception Save(string aFullPath)
{
Exception Result = null;
try
{
this.WriteXml(aFullPath);
}
catch (Exception Ex)
{
Result = Ex;
}
return Result;
}
/// <summary>
/// Tools for the data table
/// </summary>
public partial class HistoryDataTable
{
/// <summary>
/// Get all rows for a job
/// </summary>
/// <param name="aJob">Job to load</param>
/// <returns>Rows or empty if none</returns>
public HistoryRow[] GetHistory(string aJob)
{
return this.Where(qR => qR.Name.Equals(aJob)).ToArray();
}
/// <summary>
/// Gives all rows for a job older than a time span
/// </summary>
/// <param name="aJob">Job to load</param>
/// <param name="aYoungerThan">TimeSpan older than which rows will not be loaded</param>
/// <returns></returns>
public HistoryRow[] GetHistory(string aJob, TimeSpan aYoungerThan)
{
DateTime Later = DateTime.Now - aYoungerThan;
return GetHistory(aJob).Where(qR => qR.ActionDate > Later).ToArray();
}
/// <summary>
/// Returns the last FULL backup for a job or null
/// </summary>
/// <param name="aJob">Job to load</param>
/// <returns>the last FULL backup for a job or null</returns>
public DateTime LastFull(string aJob)
{
return GetHistory(aJob).Where(qF => qF.Full && qF.Success).Select(qD => qD.ActionDate).DefaultIfEmpty(DateTime.MinValue).Max();
}
/// <summary>
/// Returns the number of runs since the last full backup
/// </summary>
/// <param name="aJob">Job to load</param>
/// <returns>The number of runs since the last full backup</returns>
public int NumberSinceLastFull(string aJob)
{
DateTime Last = LastFull(aJob);
if (Last == DateTime.MinValue) return 0;
return NumberSinceLastFull(aJob, Last);
}
/// <summary>
/// Returns the number of incremntal runs since a date
/// </summary>
/// <param name="aJob">Job to run</param>
/// <param name="aLastFull">Date</param>
/// <returns>The number of incremntal runs since a date</returns>
public int NumberSinceLastFull(string aJob, DateTime aLastFull)
{
return GetHistory(aJob).Where(qF => !qF.Full && qF.Success && qF.ActionDate > aLastFull).Count();
}
/// <summary>
/// Deletes all rows for a job
/// </summary>
/// <param name="aJob"></param>
public void DeleteJob(string aJob)
{
foreach (HistoryRow Row in GetHistory(aJob))
Row.Delete();
}
}
/// <summary>
/// Data row tools
/// </summary>
public partial class HistoryRow
{
/// <summary>
/// Update a stats row
/// </summary>
/// <param name="aOutput">Duplicati output (Result) string</param>
public void UpdateStats(string aOutput)
{
StatsRow[] Stats = this.GetStatsRows();
StatsRow sRow = null;
if (Stats == null || Stats.Length == 0)
sRow = ((StatsDataTable)this.tableHistory.ChildRelations["History_Stats"].ChildTable).AddStatsRow(this,
this.ActionDate, 0, 0, 0, 0, 0L, 0L, 0L, 0, 0, 0, this.ActionDate, this.ActionDate, string.Empty,
0, 0, 0, string.Empty, null);
else
sRow = Stats[0];
// Parse the stats out of the results
foreach (string Line in aOutput.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries))
{
int Colon = Line.IndexOf(':');
if (Colon > 0)
{
string Field = Line.Substring(0, Colon).Trim();
string Value = Line.Substring(Colon + 1).Trim();
if (sRow.Table.Columns.Contains(Field))
sRow[Field] = System.Convert.ChangeType(Value, sRow.Table.Columns[Field].DataType);
}
}
}
/// <summary>
/// Update a History row
/// </summary>
/// <param name="aAction">Action done</param>
/// <param name="aFull">Was it full</param>
/// <param name="aSuccess">OK</param>
/// <param name="aStatus">Status</param>
/// <param name="aChecksum">Checksun used</param>
/// <param name="aCheckMod">Module used</param>
public void Update(string aAction, bool aFull, bool aSuccess, string aStatus, byte[] aChecksum, string aCheckMod)
{
this.Action = aAction;
this.Full = aFull;
this.Success = aSuccess;
this.CheckMod = aCheckMod;
this.Checksum = aChecksum;
this.UpdateStats(aStatus);
}
/// <summary>
/// Delete a history row
/// </summary>
public new void Delete()
{
foreach (StatsRow sRow in from StatsRow qS in this.GetStatsRows() select qS)
sRow.Delete();
base.Delete();
}
}
}
}