Merge remote-tracking branch 'upstream/master' into fix-stop-after-current-file
This commit is contained in:
@@ -24,3 +24,4 @@ binfiles.wxs
|
||||
.idea/
|
||||
.vs/
|
||||
|
||||
Installer/debian/*.buildinfo
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CoCoL, Version=1.5.0.19417, Culture=neutral, PublicKeyToken=0983de3c914beeaa, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\CoCoL.1.6.1\lib\net45\CoCoL.dll</HintPath>
|
||||
<Reference Include="CoCoL, Version=1.6.2.0, Culture=neutral, PublicKeyToken=0983de3c914beeaa, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\CoCoL.1.6.2\lib\net45\CoCoL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Duplicati Team")]
|
||||
[assembly: AssemblyProduct("Duplicati.GUI.TrayIcon")]
|
||||
[assembly: AssemblyCopyright("LGPL, Copyright © Duplicati Team 2015")]
|
||||
[assembly: AssemblyCopyright("LGPL, Copyright © Duplicati Team 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CoCoL" version="1.6.1" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net45" />
|
||||
<package id="CoCoL" version="1.6.2" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -646,7 +646,7 @@ namespace Duplicati.Library.Main.Database
|
||||
|
||||
private long GetPreviousFilesetID(System.Data.IDbCommand cmd, DateTime timestamp, long filesetid)
|
||||
{
|
||||
var lastFilesetId = cmd.ExecuteScalarInt64(@"SELECT ""ID"" FROM ""Fileset"" WHERE ""Timestamp"" < ? AND ""ID"" != ? ORDER BY ""Timestamp"" DESC ", -1, NormalizeDateTimeToEpochSeconds(timestamp), filesetid);
|
||||
var lastFilesetId = cmd.ExecuteScalarInt64(@"SELECT ""ID"" FROM ""Fileset"" WHERE ""Timestamp"" < ? AND ""ID"" != ? ORDER BY ""Timestamp"" DESC ", -1, Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(timestamp), filesetid);
|
||||
return lastFilesetId;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace Duplicati.Library.Main.Database
|
||||
m_connection.Open();
|
||||
|
||||
using (var cmd = m_connection.CreateCommand())
|
||||
m_operationid = cmd.ExecuteScalarInt64(@"INSERT INTO ""Operation"" (""Description"", ""Timestamp"") VALUES (?, ?); SELECT last_insert_rowid();", -1, operation, NormalizeDateTimeToEpochSeconds(OperationTimestamp));
|
||||
m_operationid = cmd.ExecuteScalarInt64( @"INSERT INTO ""Operation"" (""Description"", ""Timestamp"") VALUES (?, ?); SELECT last_insert_rowid();", -1, operation, Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(OperationTimestamp));
|
||||
}
|
||||
|
||||
private LocalDatabase(System.Data.IDbConnection connection)
|
||||
@@ -153,23 +153,6 @@ namespace Duplicati.Library.Main.Database
|
||||
m_result = result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a DateTime instance floor'ed to seconds and in UTC
|
||||
/// </summary>
|
||||
/// <returns>The normalised date time</returns>
|
||||
/// <param name="input">The input time</param>
|
||||
public static DateTime NormalizeDateTime(DateTime input)
|
||||
{
|
||||
var ticks = input.ToUniversalTime().Ticks;
|
||||
ticks -= ticks % TimeSpan.TicksPerSecond;
|
||||
return new DateTime(ticks, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
public static long NormalizeDateTimeToEpochSeconds(DateTime input)
|
||||
{
|
||||
return (long)Math.Floor((NormalizeDateTime(input) - Library.Utility.Utility.EPOCH).TotalSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a DateTime instance by adding the specified number of seconds to the EPOCH value
|
||||
/// </summary>
|
||||
@@ -252,7 +235,7 @@ namespace Duplicati.Library.Main.Database
|
||||
|
||||
query.Append(singleTimeMatch ? @" ""Timestamp"" = ?" : @" ""Timestamp"" <= ?");
|
||||
// Make sure the resolution is the same (i.e. no milliseconds)
|
||||
args.Add(NormalizeDateTimeToEpochSeconds(time));
|
||||
args.Add(Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(time));
|
||||
hasTime = true;
|
||||
}
|
||||
|
||||
@@ -355,7 +338,7 @@ namespace Duplicati.Library.Main.Database
|
||||
{
|
||||
m_insertremotelogCommand.Transaction = transaction;
|
||||
m_insertremotelogCommand.SetParameterValue(0, m_operationid);
|
||||
m_insertremotelogCommand.SetParameterValue(1, NormalizeDateTimeToEpochSeconds(DateTime.UtcNow));
|
||||
m_insertremotelogCommand.SetParameterValue(1, Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(DateTime.UtcNow));
|
||||
m_insertremotelogCommand.SetParameterValue(2, operation);
|
||||
m_insertremotelogCommand.SetParameterValue(3, path);
|
||||
m_insertremotelogCommand.SetParameterValue(4, data);
|
||||
@@ -372,7 +355,7 @@ namespace Duplicati.Library.Main.Database
|
||||
{
|
||||
m_insertlogCommand.Transaction = transaction;
|
||||
m_insertlogCommand.SetParameterValue(0, m_operationid);
|
||||
m_insertlogCommand.SetParameterValue(1, NormalizeDateTimeToEpochSeconds(DateTime.UtcNow));
|
||||
m_insertlogCommand.SetParameterValue(1, Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(DateTime.UtcNow));
|
||||
m_insertlogCommand.SetParameterValue(2, type);
|
||||
m_insertlogCommand.SetParameterValue(3, message);
|
||||
m_insertlogCommand.SetParameterValue(4, exception == null ? null : exception.ToString());
|
||||
@@ -585,7 +568,7 @@ namespace Duplicati.Library.Main.Database
|
||||
{
|
||||
using (var cmd = m_connection.CreateCommand())
|
||||
{
|
||||
using (var rd = cmd.ExecuteReader($@"SELECT ""IsFullBackup"" FROM ""Fileset"" WHERE ""Timestamp"" = {NormalizeDateTimeToEpochSeconds(filesetTime)}"))
|
||||
using (var rd = cmd.ExecuteReader($@"SELECT ""IsFullBackup"" FROM ""Fileset"" WHERE ""Timestamp"" = {Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(filesetTime)}"))
|
||||
{
|
||||
if (!rd.Read())
|
||||
{
|
||||
@@ -1314,8 +1297,8 @@ ORDER BY
|
||||
using (var cmd = m_connection.CreateCommand())
|
||||
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
|
||||
{
|
||||
cmd.Transaction = tr.Parent;
|
||||
var id = cmd.ExecuteScalarInt64(@"INSERT INTO ""Fileset"" (""OperationID"", ""IsFullBackup"", ""Timestamp"", ""VolumeID"") VALUES (?, ?, ?, ?); SELECT last_insert_rowid();", -1, m_operationid, BackupType.PARTIAL_BACKUP, NormalizeDateTimeToEpochSeconds(timestamp), volumeid);
|
||||
cmd.Transaction = tr.Parent;
|
||||
var id = cmd.ExecuteScalarInt64(@"INSERT INTO ""Fileset"" (""OperationID"", ""Timestamp"", ""VolumeID"") VALUES (?, ?, ?); SELECT last_insert_rowid();", -1, m_operationid, Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(timestamp), volumeid);
|
||||
tr.Commit();
|
||||
return id;
|
||||
}
|
||||
@@ -1391,7 +1374,7 @@ ORDER BY
|
||||
using (var tr = m_connection.BeginTransaction())
|
||||
using (var cmd = m_connection.CreateCommand(tr))
|
||||
{
|
||||
var t = NormalizeDateTimeToEpochSeconds(threshold);
|
||||
var t = Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(threshold);
|
||||
cmd.ExecuteNonQuery(@"DELETE FROM ""LogData"" WHERE ""Timestamp"" < ?", t);
|
||||
cmd.ExecuteNonQuery(@"DELETE FROM ""RemoteOperation"" WHERE ""Timestamp"" < ?", t);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Duplicati.Library.Main.Database
|
||||
string q = string.Join(",", Enumerable.Repeat("?", sliceLen));
|
||||
|
||||
//First we remove unwanted entries
|
||||
deleted += cmd.ExecuteNonQuery(@"DELETE FROM ""Fileset"" WHERE ""Timestamp"" IN (" + q + @") ", toDelete.Skip(sliceStart).Take(sliceLen).Select(x => NormalizeDateTimeToEpochSeconds(x)).Cast<object>().ToArray());
|
||||
deleted += cmd.ExecuteNonQuery(@"DELETE FROM ""Fileset"" WHERE ""Timestamp"" IN (" + q + @") ", toDelete.Skip(sliceStart).Take(sliceLen).Select(Library.Utility.Utility.NormalizeDateTimeToEpochSeconds).Cast<object>().ToArray());
|
||||
}
|
||||
|
||||
if (deleted != toDelete.Length)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Duplicati.Library.Common;
|
||||
using Duplicati.Library.Common.IO;
|
||||
using Duplicati.Library.Common;
|
||||
using Duplicati.Library.Common.IO;
|
||||
using Duplicati.Library.Main.Volumes;
|
||||
|
||||
namespace Duplicati.Library.Main.Database
|
||||
@@ -189,7 +189,7 @@ namespace Duplicati.Library.Main.Database
|
||||
|
||||
using(var cmd = m_connection.CreateCommand())
|
||||
{
|
||||
var filesetIds = GetFilesetIDs(NormalizeDateTime(restoretime), versions).ToList();
|
||||
var filesetIds = GetFilesetIDs(Library.Utility.Utility.NormalizeDateTime(restoretime), versions).ToList();
|
||||
while(filesetIds.Count > 0)
|
||||
{
|
||||
var filesetId = filesetIds[0];
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CoCoL, Version=1.5.0.19417, Culture=neutral, PublicKeyToken=0983de3c914beeaa, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\CoCoL.1.6.1\lib\net45\CoCoL.dll</HintPath>
|
||||
<Reference Include="CoCoL, Version=1.6.2.0, Culture=neutral, PublicKeyToken=0983de3c914beeaa, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\CoCoL.1.6.2\lib\net45\CoCoL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CoCoL" version="1.6.1" targetFramework="net462" />
|
||||
<package id="CoCoL" version="1.6.2" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -31,8 +31,8 @@
|
||||
<ConsolePause>false</ConsolePause>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CoCoL, Version=1.5.0.19417, Culture=neutral, PublicKeyToken=0983de3c914beeaa, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\CoCoL.1.6.1\lib\net45\CoCoL.dll</HintPath>
|
||||
<Reference Include="CoCoL, Version=1.6.2.0, Culture=neutral, PublicKeyToken=0983de3c914beeaa, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\CoCoL.1.6.2\lib\net45\CoCoL.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CoCoL" version="1.6.1" targetFramework="net462" />
|
||||
<package id="CoCoL" version="1.6.2" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -21,8 +21,8 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Duplicati.Library.Common.IO;
|
||||
using Duplicati.Library.Common;
|
||||
using Duplicati.Library.Common.IO;
|
||||
using Duplicati.Library.Common;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
@@ -801,12 +801,12 @@ namespace Duplicati.Library.Utility
|
||||
|
||||
try
|
||||
{
|
||||
var psi = new System.Diagnostics.ProcessStartInfo("which", appname)
|
||||
{
|
||||
var psi = new System.Diagnostics.ProcessStartInfo("which", appname)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = false,
|
||||
RedirectStandardInput = false,
|
||||
UseShellExecute = false
|
||||
RedirectStandardInput = false,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var pi = System.Diagnostics.Process.Start(psi);
|
||||
@@ -940,7 +940,24 @@ namespace Duplicati.Library.Utility
|
||||
|
||||
ENVIRONMENT_VARIABLE_MATCHER_WINDOWS.Replace(str, m => Regex.Escape(lookup(m.Groups["name"].Value)));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a DateTime instance by converting to UTC and flooring to seconds.
|
||||
/// </summary>
|
||||
/// <returns>The normalized date time</returns>
|
||||
/// <param name="input">The input time</param>
|
||||
public static DateTime NormalizeDateTime(DateTime input)
|
||||
{
|
||||
var ticks = input.ToUniversalTime().Ticks;
|
||||
ticks -= ticks % TimeSpan.TicksPerSecond;
|
||||
return new DateTime(ticks, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
public static long NormalizeDateTimeToEpochSeconds(DateTime input)
|
||||
{
|
||||
return (long) Math.Floor((NormalizeDateTime(input) - EPOCH).TotalSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The format string for a DateTime
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FasterHashing" version="1.3.0" targetFramework="net45" />
|
||||
<package id="FasterHashing" version="1.3.0" targetFramework="net462" />
|
||||
</packages>
|
||||
@@ -52,7 +52,7 @@ namespace Duplicati.Server.Database
|
||||
((System.Data.IDbDataParameter)m_errorcmd.Parameters[0]).Value = id;
|
||||
((System.Data.IDbDataParameter)m_errorcmd.Parameters[1]).Value = message;
|
||||
((System.Data.IDbDataParameter)m_errorcmd.Parameters[2]).Value = ex?.ToString();
|
||||
((System.Data.IDbDataParameter)m_errorcmd.Parameters[3]).Value = NormalizeDateTimeToEpochSeconds(DateTime.UtcNow);
|
||||
((System.Data.IDbDataParameter)m_errorcmd.Parameters[3]).Value = Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(DateTime.UtcNow);
|
||||
m_errorcmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
@@ -626,9 +626,9 @@ namespace Duplicati.Server.Database
|
||||
@"INSERT INTO ""Schedule"" (""Tags"", ""Time"", ""Repeat"", ""LastRun"", ""Rule"") VALUES (?,?,?,?,?)",
|
||||
(n) => new object[] {
|
||||
string.Join(",", n.Tags),
|
||||
NormalizeDateTimeToEpochSeconds(n.Time),
|
||||
Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(n.Time),
|
||||
n.Repeat,
|
||||
NormalizeDateTimeToEpochSeconds(n.LastRun),
|
||||
Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(n.LastRun),
|
||||
n.Rule ?? "",
|
||||
update ? (object)item.ID : null
|
||||
});
|
||||
@@ -941,21 +941,9 @@ namespace Duplicati.Server.Database
|
||||
return tempfile.ID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a DateTime instance floor'ed to seconds and in UTC
|
||||
/// </summary>
|
||||
/// <returns>The normalised date time</returns>
|
||||
/// <param name="input">The input time</param>
|
||||
public static DateTime NormalizeDateTime(DateTime input)
|
||||
{
|
||||
var ticks = input.ToUniversalTime().Ticks;
|
||||
ticks -= ticks % TimeSpan.TicksPerSecond;
|
||||
return new DateTime(ticks, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
public void PurgeLogData(DateTime purgeDate)
|
||||
{
|
||||
var t = NormalizeDateTimeToEpochSeconds(purgeDate);
|
||||
var t = Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(purgeDate);
|
||||
|
||||
using(var tr = m_connection.BeginTransaction())
|
||||
using(var cmd = m_connection.CreateCommand())
|
||||
@@ -970,11 +958,6 @@ namespace Duplicati.Server.Database
|
||||
}
|
||||
}
|
||||
|
||||
private static long NormalizeDateTimeToEpochSeconds(DateTime input)
|
||||
{
|
||||
return (long)Math.Floor((NormalizeDateTime(input) - Library.Utility.Utility.EPOCH).TotalSeconds);
|
||||
}
|
||||
|
||||
private static DateTime ConvertToDateTime(System.Data.IDataReader rd, int index)
|
||||
{
|
||||
var unixTime = ConvertToInt64(rd, index);
|
||||
@@ -1174,7 +1157,7 @@ namespace Duplicati.Server.Database
|
||||
if (x.PropertyType.IsEnum)
|
||||
val = val.ToString();
|
||||
else if (x.PropertyType == typeof(DateTime))
|
||||
val = NormalizeDateTimeToEpochSeconds((DateTime)val);
|
||||
val = Library.Utility.Utility.NormalizeDateTimeToEpochSeconds((DateTime)val);
|
||||
|
||||
return val;
|
||||
}).ToArray();
|
||||
|
||||
@@ -260,10 +260,8 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
|
||||
this['oauth-base'].apply(this, arguments);
|
||||
};
|
||||
|
||||
|
||||
// Parsers take a decomposed uri input and sets up the scope variables
|
||||
EditUriBackendConfig.parsers['file'] = function(scope, module, server, port, path, options) {
|
||||
var dirsep = '/';
|
||||
if (scope.Path == null && scope.Server == null) {
|
||||
var ix = scope.uri.indexOf('?');
|
||||
if (ix < 0)
|
||||
@@ -274,17 +272,22 @@ backupApp.service('EditUriBuiltins', function(AppService, AppUtils, SystemInfo,
|
||||
if (ix < 0)
|
||||
ix = scope.uri.location;
|
||||
scope.Path = scope.uri.substr(scope.uri.indexOf('://') + 3, ix);
|
||||
|
||||
} else {
|
||||
if (scope.Path != null && scope.Path.indexOf('\\') >= 0)
|
||||
dirsep = '\\';
|
||||
|
||||
if (scope.Server != null && dirsep == '/')
|
||||
scope.Path = scope.Server + '/' + scope.Path;
|
||||
var dirsep = '/';
|
||||
var newScopePath = scope.Server;
|
||||
if (scope.Path.indexOf('\\') >= 0 || scope.Server.indexOf('\\') >= 0) {
|
||||
dirsep = '\\';
|
||||
}
|
||||
if (scope.Server.substr(scope.Server.length - 1) != dirsep) {
|
||||
newScopePath += dirsep;
|
||||
}
|
||||
if (scope.Path.length > 0) {
|
||||
newScopePath += scope.Path;
|
||||
}
|
||||
scope.Path = newScopePath;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
EditUriBackendConfig.parsers['s3'] = function(scope, module, server, port, path, options) {
|
||||
if (options['--aws_access_key_id'])
|
||||
scope.Username = options['--aws_access_key_id'];
|
||||
|
||||
@@ -200,6 +200,32 @@ namespace Duplicati.UnitTest
|
||||
Assert.IsNotNull(actualDuplicateItems);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Category("Utility")]
|
||||
public void NormalizeDateTime()
|
||||
{
|
||||
DateTime baseDateTime = new DateTime(2000, 1, 2, 3, 4, 5);
|
||||
DateTime baseDateTimeUTC = baseDateTime.ToUniversalTime();
|
||||
Assert.AreEqual(baseDateTimeUTC, Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(1)));
|
||||
Assert.AreEqual(baseDateTimeUTC, Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(500)));
|
||||
Assert.AreEqual(baseDateTimeUTC, Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(999)));
|
||||
Assert.AreEqual(baseDateTimeUTC.AddSeconds(-1), Utility.NormalizeDateTime(baseDateTime.AddMilliseconds(-1)));
|
||||
Assert.AreEqual(baseDateTimeUTC.AddSeconds(1), Utility.NormalizeDateTime(baseDateTime.AddSeconds(1.9)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Category("Utility")]
|
||||
public void NormalizeDateTimeToEpochSeconds()
|
||||
{
|
||||
DateTime baseDateTime = new DateTime(2000, 1, 2, 3, 4, 5);
|
||||
long epochSeconds = (long) (baseDateTime.ToUniversalTime() - Utility.EPOCH).TotalSeconds;
|
||||
Assert.AreEqual(epochSeconds, Utility.NormalizeDateTimeToEpochSeconds(baseDateTime.AddMilliseconds(1)));
|
||||
Assert.AreEqual(epochSeconds, Utility.NormalizeDateTimeToEpochSeconds(baseDateTime.AddMilliseconds(500)));
|
||||
Assert.AreEqual(epochSeconds, Utility.NormalizeDateTimeToEpochSeconds(baseDateTime.AddMilliseconds(999)));
|
||||
Assert.AreEqual(epochSeconds - 1, Utility.NormalizeDateTimeToEpochSeconds(baseDateTime.AddMilliseconds(-1)));
|
||||
Assert.AreEqual(epochSeconds + 1, Utility.NormalizeDateTimeToEpochSeconds(baseDateTime.AddSeconds(1.9)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Category("Utility")]
|
||||
public void ParseBool()
|
||||
|
||||
@@ -20,13 +20,25 @@
|
||||
<!-- The spaces near the equation sign are used to prevent the version being set to the current build by the VersionStamp tool -->
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0 - 99.9.9.9" newVersion = "10.0.0.0"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0 - 99.9.9.9" newVersion = "12.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
<!-- Support for backends that wants older versions of KeyVault.Core and System.Net.Http -->
|
||||
<!-- The spaces near the equation sign are used to prevent the version being set to the current build by the VersionStamp tool -->
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.4.0" newVersion = "3.0.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion = "4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
<startup useLegacyV2RuntimeActivationPolicy="true">
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -27,7 +27,7 @@
|
||||
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
|
||||
|
||||
<PropertyRef Id="WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED"/>
|
||||
<Condition Message="The .NET Framework 4.6.2 must be installed ([WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED])">
|
||||
<Condition Message="The .NET Framework 4.6.2 must be installed">
|
||||
<![CDATA[Installed OR WIX_IS_NETFRAMEWORK_462_OR_LATER_INSTALLED]]>
|
||||
</Condition>
|
||||
|
||||
@@ -84,13 +84,13 @@
|
||||
|
||||
<!-- Remove old versions -->
|
||||
<InstallExecuteSequence>
|
||||
<RemoveExistingProducts Before='InstallInitialize' />
|
||||
<RemoveExistingProducts After="InstallInitialize" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
|
||||
<Upgrade Id="$(var.UpgradeCode)">
|
||||
<UpgradeVersion Minimum="2.0.0.0" Property="PREVIOUSVERSIONSINSTALLED" Maximum="99.0.0.0" IncludeMinimum="yes" IncludeMaximum="no" />
|
||||
</Upgrade>
|
||||
|
||||
|
||||
</Product>
|
||||
</Wix>
|
||||
|
||||
@@ -1 +1 @@
|
||||
24
|
||||
28
|
||||
|
||||
@@ -1,3 +1,71 @@
|
||||
2019-09-05 - 2.0.4.28_canary_2019-09-05
|
||||
==========
|
||||
* Updated CoCoL and WiX to fix rollback and upgrade errors, thanks @BlueBlock
|
||||
|
||||
2019-09-03 - 2.0.4.27_canary_2019-09-03
|
||||
==========
|
||||
* Fixed issues with the MSI packages not upgrading correctly, thanks @BlueBlock
|
||||
* Fixed some assembly redirects and package references, thanks @BlueBlock
|
||||
* Code cleanup for EPOCH times, thanks @warwickmm
|
||||
|
||||
2019-09-02 - 2.0.4.26_canary_2019-09-02
|
||||
==========
|
||||
== This is a rebuild of 2.0.4.24 with MSI packages and **new** assembly redirect fixes ==
|
||||
|
||||
Change list from 2.0.4.24:
|
||||
* Code cleanup, thanks @warwickmm
|
||||
* Removed extra console output, thanks @wjansenw
|
||||
* Fixed disposing backends after job completion, thanks @warwickmm
|
||||
* Fixed an issue with throttled write, thanks @warwickmm
|
||||
* Spelling fix, thanks @BlueBlock
|
||||
* Fixed documetation in `run-script` examples, thanks @beppo-dd
|
||||
* Improved unittests, thanks @BlueBlock
|
||||
* Improved auto-compact and auto-vacuum, thanks @drwtsn32x
|
||||
* Fixed problem with exceeeding the number of parameters supported by SQLite, thanks @drwtsn32x
|
||||
* Improved status display, thanks @drwtsn32x
|
||||
* Improved bugreport database scrubbing, thanks @drwtsn32x
|
||||
* Removed GoogleDrive trash items in listing, thanks @BlueBlock
|
||||
* Fixed the rename method in the GoogleDrive backend, thanks @BlueBlock
|
||||
* Improved GCS storage class text, thanks @warwickmm
|
||||
* Improved unittests for easier local testing, thanks @warwickmm
|
||||
* Added workaround for AFTP upload delay, thanks @BlueBlock
|
||||
* Fixed issue with reading the largest path prefix, thanks @BlueBlock
|
||||
* Added conditional download of unittest data zip files, thanks @BlueBlock
|
||||
* CI testing improvements, thanks @BlueBlock
|
||||
* Fixed sporadic issue with backups of files being written, thanks @BlueBlock
|
||||
* Updated to .Net Framework 4.6.2
|
||||
* Fixed issue with temporary files not being deleted as expected, thanks @BlueBlock
|
||||
* Support for forcing calendar dates in time pickers, thanks @LacunaSoftware
|
||||
|
||||
2019-09-02 - 2.0.4.25_canary_2019-09-02
|
||||
==========
|
||||
== This is a rebuild of 2.0.4.24 with MSI packages and assembly redirect fixes ==
|
||||
|
||||
Change list from 2.0.4.24:
|
||||
* Code cleanup, thanks @warwickmm
|
||||
* Removed extra console output, thanks @wjansenw
|
||||
* Fixed disposing backends after job completion, thanks @warwickmm
|
||||
* Fixed an issue with throttled write, thanks @warwickmm
|
||||
* Spelling fix, thanks @BlueBlock
|
||||
* Fixed documetation in `run-script` examples, thanks @beppo-dd
|
||||
* Improved unittests, thanks @BlueBlock
|
||||
* Improved auto-compact and auto-vacuum, thanks @drwtsn32x
|
||||
* Fixed problem with exceeeding the number of parameters supported by SQLite, thanks @drwtsn32x
|
||||
* Improved status display, thanks @drwtsn32x
|
||||
* Improved bugreport database scrubbing, thanks @drwtsn32x
|
||||
* Removed GoogleDrive trash items in listing, thanks @BlueBlock
|
||||
* Fixed the rename method in the GoogleDrive backend, thanks @BlueBlock
|
||||
* Improved GCS storage class text, thanks @warwickmm
|
||||
* Improved unittests for easier local testing, thanks @warwickmm
|
||||
* Added workaround for AFTP upload delay, thanks @BlueBlock
|
||||
* Fixed issue with reading the largest path prefix, thanks @BlueBlock
|
||||
* Added conditional download of unittest data zip files, thanks @BlueBlock
|
||||
* CI testing improvements, thanks @BlueBlock
|
||||
* Fixed sporadic issue with backups of files being written, thanks @BlueBlock
|
||||
* Updated to .Net Framework 4.6.2
|
||||
* Fixed issue with temporary files not being deleted as expected, thanks @BlueBlock
|
||||
* Support for forcing calendar dates in time pickers, thanks @LacunaSoftware
|
||||
|
||||
2019-09-02 - 2.0.4.24_canary_2019-09-02
|
||||
==========
|
||||
* Code cleanup, thanks @warwickmm
|
||||
|
||||
Reference in New Issue
Block a user