diff --git a/.gitignore b/.gitignore index 2577fafa1..7ba91052e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ binfiles.wxs .idea/ .vs/ +Installer/debian/*.buildinfo diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj index 98d9b0b79..ea32a8023 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj @@ -69,8 +69,8 @@ app.manifest - - ..\..\..\packages\CoCoL.1.6.1\lib\net45\CoCoL.dll + + ..\..\..\packages\CoCoL.1.6.2\lib\net45\CoCoL.dll ..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs index 9e1a1180a..a1360e670 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Properties/AssemblyInfo.cs @@ -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("")] diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config b/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config index 54fa558e1..2150f07f7 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/Duplicati/Library/Main/Database/LocalBackupDatabase.cs b/Duplicati/Library/Main/Database/LocalBackupDatabase.cs index 604877aec..292e5cc01 100644 --- a/Duplicati/Library/Main/Database/LocalBackupDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalBackupDatabase.cs @@ -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; } diff --git a/Duplicati/Library/Main/Database/LocalDatabase.cs b/Duplicati/Library/Main/Database/LocalDatabase.cs index 09cbbf537..0e589c73c 100644 --- a/Duplicati/Library/Main/Database/LocalDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalDatabase.cs @@ -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; } - /// - /// Normalizes a DateTime instance floor'ed to seconds and in UTC - /// - /// The normalised date time - /// The input time - 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); - } - /// /// Creates a DateTime instance by adding the specified number of seconds to the EPOCH value /// @@ -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); diff --git a/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs b/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs index 3eaefc1c9..4319095f7 100644 --- a/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalDeleteDatabase.cs @@ -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().ToArray()); + deleted += cmd.ExecuteNonQuery(@"DELETE FROM ""Fileset"" WHERE ""Timestamp"" IN (" + q + @") ", toDelete.Skip(sliceStart).Take(sliceLen).Select(Library.Utility.Utility.NormalizeDateTimeToEpochSeconds).Cast().ToArray()); } if (deleted != toDelete.Length) diff --git a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs index 4ec010b1b..b013e2c89 100644 --- a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs @@ -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]; diff --git a/Duplicati/Library/Main/Duplicati.Library.Main.csproj b/Duplicati/Library/Main/Duplicati.Library.Main.csproj index 9f89a0d6b..e94583783 100644 --- a/Duplicati/Library/Main/Duplicati.Library.Main.csproj +++ b/Duplicati/Library/Main/Duplicati.Library.Main.csproj @@ -36,8 +36,8 @@ 4 - - ..\..\..\packages\CoCoL.1.6.1\lib\net45\CoCoL.dll + + ..\..\..\packages\CoCoL.1.6.2\lib\net45\CoCoL.dll ..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll diff --git a/Duplicati/Library/Main/packages.config b/Duplicati/Library/Main/packages.config index b9e1d2970..2150f07f7 100644 --- a/Duplicati/Library/Main/packages.config +++ b/Duplicati/Library/Main/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj b/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj index 416734f7d..d304c5adf 100644 --- a/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj +++ b/Duplicati/Library/UsageReporter/Duplicati.Library.UsageReporter.csproj @@ -31,8 +31,8 @@ false - - ..\..\..\packages\CoCoL.1.6.1\lib\net45\CoCoL.dll + + ..\..\..\packages\CoCoL.1.6.2\lib\net45\CoCoL.dll ..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll diff --git a/Duplicati/Library/UsageReporter/packages.config b/Duplicati/Library/UsageReporter/packages.config index b9e1d2970..2150f07f7 100644 --- a/Duplicati/Library/UsageReporter/packages.config +++ b/Duplicati/Library/UsageReporter/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/Duplicati/Library/Utility/Utility.cs b/Duplicati/Library/Utility/Utility.cs index 3b37c002c..8a8d98933 100644 --- a/Duplicati/Library/Utility/Utility.cs +++ b/Duplicati/Library/Utility/Utility.cs @@ -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))); } - + + /// + /// Normalizes a DateTime instance by converting to UTC and flooring to seconds. + /// + /// The normalized date time + /// The input time + 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); + } + /// /// The format string for a DateTime /// diff --git a/Duplicati/Library/Utility/packages.config b/Duplicati/Library/Utility/packages.config index 621af80a6..6a42a4b95 100644 --- a/Duplicati/Library/Utility/packages.config +++ b/Duplicati/Library/Utility/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Duplicati/Server/Database/Connection.cs b/Duplicati/Server/Database/Connection.cs index beadb929d..7f7bcb212 100644 --- a/Duplicati/Server/Database/Connection.cs +++ b/Duplicati/Server/Database/Connection.cs @@ -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; } - /// - /// Normalizes a DateTime instance floor'ed to seconds and in UTC - /// - /// The normalised date time - /// The input time - 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(); diff --git a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js index f82a8bade..3651e6797 100644 --- a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js +++ b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js @@ -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']; diff --git a/Duplicati/UnitTest/UtilityTests.cs b/Duplicati/UnitTest/UtilityTests.cs index 437889f77..66823f16d 100644 --- a/Duplicati/UnitTest/UtilityTests.cs +++ b/Duplicati/UnitTest/UtilityTests.cs @@ -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() diff --git a/Installer/AssemblyRedirects.xml b/Installer/AssemblyRedirects.xml index f031c1dc1..57f8304b0 100644 --- a/Installer/AssemblyRedirects.xml +++ b/Installer/AssemblyRedirects.xml @@ -20,13 +20,25 @@ - + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/Installer/Windows/Duplicati.wxs b/Installer/Windows/Duplicati.wxs index 0ee98959e..06f68b91d 100644 --- a/Installer/Windows/Duplicati.wxs +++ b/Installer/Windows/Duplicati.wxs @@ -27,7 +27,7 @@ - + @@ -84,13 +84,13 @@ - + - + diff --git a/Updates/build_version.txt b/Updates/build_version.txt index a45fd52cc..9902f1784 100644 --- a/Updates/build_version.txt +++ b/Updates/build_version.txt @@ -1 +1 @@ -24 +28 diff --git a/changelog.txt b/changelog.txt index 999fcd9d7..167ecc513 100644 --- a/changelog.txt +++ b/changelog.txt @@ -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