Merge remote-tracking branch 'upstream/master' into fix-stop-after-current-file

This commit is contained in:
BlueBlock
2019-09-07 11:27:20 -04:00
21 changed files with 179 additions and 86 deletions
+1
View File
@@ -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 -1
View File
@@ -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>
+24 -7
View File
@@ -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 -1
View File
@@ -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>
+5 -22
View File
@@ -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'];
+26
View File
@@ -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()
+14 -2
View File
@@ -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>
+3 -3
View File
@@ -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
View File
@@ -1 +1 @@
24
28
+68
View File
@@ -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