diff --git a/Duplicati/Library/Main/Database/ExtensionMethods.cs b/Duplicati/Library/Main/Database/ExtensionMethods.cs
index 87709473a..aa6364103 100644
--- a/Duplicati/Library/Main/Database/ExtensionMethods.cs
+++ b/Duplicati/Library/Main/Database/ExtensionMethods.cs
@@ -211,7 +211,7 @@ public static class ExtensionMethods
/// The command instance to execute on
/// The transaction to use for the command
/// The number of rows affected
- public static int ExecuteNonQuery(this IDbCommand self, IDbTransaction transaction)
+ public static int ExecuteNonQuery(this IDbCommand self, IDbTransaction? transaction)
{
self.Transaction = transaction;
return self.ExecuteNonQuery();
@@ -274,7 +274,7 @@ public static class ExtensionMethods
/// The transaction to use for the command
/// The default value to return if no value is found
/// The scalar int64 value of the first row as a string
- public static long ExecuteScalarInt64(this IDbCommand self, IDbTransaction transaction, long defaultvalue = -1)
+ public static long ExecuteScalarInt64(this IDbCommand self, IDbTransaction? transaction, long defaultvalue = -1)
{
self.Transaction = transaction;
return ExecuteScalarInt64(self, true, null, defaultvalue);
@@ -320,7 +320,7 @@ public static class ExtensionMethods
/// The command string to execute
/// The values to use as parameters. The parameters must already be added.
/// A instance
- public static IDataReader ExecuteReader(this IDbCommand self, string cmd, Dictionary values)
+ public static IDataReader ExecuteReader(this IDbCommand self, string cmd, Dictionary? values)
{
return ExecuteReader(self, true, cmd, values);
}
@@ -361,7 +361,7 @@ public static class ExtensionMethods
/// The command string to execute
/// The values to use as parameters. The parameters must already be added.
/// A instance
- public static IDataReader ExecuteReader(this IDbCommand self, bool writeLog, string? cmd, Dictionary values)
+ public static IDataReader ExecuteReader(this IDbCommand self, bool writeLog, string? cmd, Dictionary? values)
{
if (cmd != null)
self.SetCommandAndParameters(cmd);
diff --git a/Duplicati/Library/Main/Database/LocalDatabase.cs b/Duplicati/Library/Main/Database/LocalDatabase.cs
index dced583d3..ebc6bd920 100644
--- a/Duplicati/Library/Main/Database/LocalDatabase.cs
+++ b/Duplicati/Library/Main/Database/LocalDatabase.cs
@@ -18,6 +18,9 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+
+#nullable enable
+
using System;
using System.Collections.Generic;
using System.Data;
@@ -83,7 +86,7 @@ namespace Duplicati.Library.Main.Database
{
path = Path.GetFullPath(path);
if (!Directory.Exists(Path.GetDirectoryName(path)))
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new DirectoryNotFoundException("Path was a root folder."));
var c = SQLiteHelper.SQLiteLoader.LoadConnection(path);
@@ -174,6 +177,7 @@ namespace Duplicati.Library.Main.Database
private LocalDatabase(IDbConnection connection)
{
+ m_connection = connection;
m_insertlogCommand = connection.CreateCommand(@"INSERT INTO ""LogData"" (""OperationID"", ""Timestamp"", ""Type"", ""Message"", ""Exception"") VALUES (@OperationID, @Timestamp, @Type, @Message, @Exception)");
m_insertremotelogCommand = connection.CreateCommand(@"INSERT INTO ""RemoteOperation"" (""OperationID"", ""Timestamp"", ""Operation"", ""Path"", ""Data"") VALUES (@OperationID, @Timestamp, @Operation, @Path, @Data)");
m_updateremotevolumeCommand = connection.CreateCommand(@"UPDATE ""Remotevolume"" SET ""OperationID"" = @OperationID, ""State"" = @State, ""Hash"" = @Hash, ""Size"" = @Size WHERE ""Name"" = @Name");
@@ -197,17 +201,17 @@ namespace Duplicati.Library.Main.Database
return Library.Utility.Utility.EPOCH.AddSeconds(seconds);
}
- public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, IDbTransaction transaction = null)
+ public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, IDbTransaction? transaction = null)
{
UpdateRemoteVolume(name, state, size, hash, false, transaction);
}
- public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup, IDbTransaction transaction = null)
+ public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup, IDbTransaction? transaction = null)
{
UpdateRemoteVolume(name, state, size, hash, suppressCleanup, new TimeSpan(0), transaction);
}
- public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup, TimeSpan deleteGraceTime, IDbTransaction transaction = null)
+ public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup, TimeSpan deleteGraceTime, IDbTransaction? transaction = null)
{
m_updateremotevolumeCommand.Transaction = transaction;
var c = m_updateremotevolumeCommand.SetParameterValue("@OperationID", m_operationid)
@@ -253,11 +257,11 @@ namespace Duplicati.Library.Main.Database
}
}
- public (string Query, Dictionary Values) GetFilelistWhereClause(DateTime time, long[] versions, IEnumerable> filesetslist = null, bool singleTimeMatch = false)
+ public (string Query, Dictionary Values) GetFilelistWhereClause(DateTime time, long[] versions, IEnumerable>? filesetslist = null, bool singleTimeMatch = false)
{
var filesets = (filesetslist ?? FilesetTimes).ToArray();
var query = new StringBuilder();
- var args = new Dictionary();
+ var args = new Dictionary();
if (time.Ticks > 0 || (versions != null && versions.Length > 0))
{
var hasTime = false;
@@ -306,13 +310,13 @@ namespace Duplicati.Library.Main.Database
return (query.ToString(), args);
}
- public long GetRemoteVolumeID(string file, IDbTransaction transaction = null)
+ public long GetRemoteVolumeID(string file, IDbTransaction? transaction = null)
{
m_selectremotevolumeIdCommand.Transaction = transaction;
return m_selectremotevolumeIdCommand.SetParameterValue("@Name", file).ExecuteScalarInt64(-1);
}
- public IEnumerable> GetRemoteVolumeIDs(IEnumerable files, IDbTransaction transaction = null)
+ public IEnumerable> GetRemoteVolumeIDs(IEnumerable files, IDbTransaction? transaction = null)
{
using (var cmd = m_connection.CreateCommand(transaction))
{
@@ -326,7 +330,7 @@ namespace Duplicati.Library.Main.Database
}
}
- public RemoteVolumeEntry GetRemoteVolume(string file, IDbTransaction transaction = null)
+ public RemoteVolumeEntry GetRemoteVolume(string file, IDbTransaction? transaction = null)
{
m_selectremotevolumeCommand.Transaction = transaction;
m_selectremotevolumeCommand.SetParameterValue("@Name", file);
@@ -334,11 +338,11 @@ namespace Duplicati.Library.Main.Database
if (rd.Read())
return new RemoteVolumeEntry(
rd.ConvertValueToInt64(0),
- rd.GetValue(1).ToString(),
- (rd.GetValue(4) == null || rd.GetValue(4) == DBNull.Value) ? null : rd.GetValue(4).ToString(),
+ rd.ConvertValueToString(1),
+ rd.ConvertValueToString(4),
rd.ConvertValueToInt64(3, -1),
- (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.GetValue(2).ToString()),
- (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.GetValue(5).ToString()),
+ (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.ConvertValueToString(2) ?? ""),
+ (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.ConvertValueToString(5) ?? ""),
ParseFromEpochSeconds(rd.ConvertValueToInt64(6, 0))
);
@@ -347,16 +351,16 @@ namespace Duplicati.Library.Main.Database
public IEnumerable> DuplicateRemoteVolumes()
{
- foreach (var rd in m_selectduplicateRemoteVolumesCommand.ExecuteReaderEnumerable(null))
+ foreach (var rd in m_selectduplicateRemoteVolumesCommand.ExecuteReaderEnumerable())
{
yield return new KeyValuePair(
- rd.GetValue(0).ToString(),
- (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.GetValue(1).ToString())
+ rd.ConvertValueToString(0) ?? throw new Exception("Name was null"),
+ (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.ConvertValueToString(1) ?? "")
);
}
}
- public IEnumerable GetRemoteVolumes(IDbTransaction transaction = null)
+ public IEnumerable GetRemoteVolumes(IDbTransaction? transaction = null)
{
m_selectremotevolumesCommand.Transaction = transaction;
using (var rd = m_selectremotevolumesCommand.ExecuteReader())
@@ -365,11 +369,11 @@ namespace Duplicati.Library.Main.Database
{
yield return new RemoteVolumeEntry(
rd.ConvertValueToInt64(0),
- rd.GetValue(1).ToString(),
- (rd.GetValue(4) == null || rd.GetValue(4) == DBNull.Value) ? null : rd.GetValue(4).ToString(),
+ rd.ConvertValueToString(1),
+ rd.ConvertValueToString(4),
rd.ConvertValueToInt64(3, -1),
- (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.GetValue(2).ToString()),
- (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.GetValue(5).ToString()),
+ (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.ConvertValueToString(2) ?? ""),
+ (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.ConvertValueToString(5) ?? ""),
ParseFromEpochSeconds(rd.ConvertValueToInt64(6, 0))
);
}
@@ -399,7 +403,7 @@ namespace Duplicati.Library.Main.Database
/// The message type
/// The message
/// An optional exception
- public void LogMessage(string type, string message, Exception exception, IDbTransaction transaction)
+ public void LogMessage(string type, string message, Exception? exception, IDbTransaction? transaction)
{
m_insertlogCommand.SetParameterValue("@OperationID", m_operationid)
.SetParameterValue("@Timestamp", Library.Utility.Utility.NormalizeDateTimeToEpochSeconds(DateTime.UtcNow))
@@ -409,7 +413,7 @@ namespace Duplicati.Library.Main.Database
.ExecuteNonQuery(transaction);
}
- public void UnlinkRemoteVolume(string name, RemoteVolumeState state, IDbTransaction transaction = null)
+ public void UnlinkRemoteVolume(string name, RemoteVolumeState state, IDbTransaction? transaction = null)
{
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
using (var cmd = m_connection.CreateCommand(tr.Parent))
@@ -426,12 +430,12 @@ namespace Duplicati.Library.Main.Database
}
}
- public void RemoveRemoteVolume(string name, IDbTransaction transaction = null)
+ public void RemoveRemoteVolume(string name, IDbTransaction? transaction = null)
{
RemoveRemoteVolumes([name], transaction);
}
- public void RemoveRemoteVolumes(IEnumerable names, IDbTransaction transaction = null)
+ public void RemoveRemoteVolumes(IEnumerable names, IDbTransaction? transaction = null)
{
if (names == null || !names.Any()) return;
@@ -559,17 +563,17 @@ AND Fileset.ID NOT IN
return RegisterRemoteVolume(name, type, state, size, new TimeSpan(0), null);
}
- public long RegisterRemoteVolume(string name, RemoteVolumeType type, RemoteVolumeState state, IDbTransaction transaction)
+ public long RegisterRemoteVolume(string name, RemoteVolumeType type, RemoteVolumeState state, IDbTransaction? transaction)
{
return RegisterRemoteVolume(name, type, state, new TimeSpan(0), transaction);
}
- public long RegisterRemoteVolume(string name, RemoteVolumeType type, RemoteVolumeState state, TimeSpan deleteGraceTime, IDbTransaction transaction)
+ public long RegisterRemoteVolume(string name, RemoteVolumeType type, RemoteVolumeState state, TimeSpan deleteGraceTime, IDbTransaction? transaction)
{
return RegisterRemoteVolume(name, type, state, -1, deleteGraceTime, transaction);
}
- public long RegisterRemoteVolume(string name, RemoteVolumeType type, RemoteVolumeState state, long size, TimeSpan deleteGraceTime, IDbTransaction transaction)
+ public long RegisterRemoteVolume(string name, RemoteVolumeType type, RemoteVolumeState state, long size, TimeSpan deleteGraceTime, IDbTransaction? transaction)
{
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
{
@@ -592,14 +596,11 @@ AND Fileset.ID NOT IN
if (restoretime.Kind == DateTimeKind.Unspecified)
throw new Exception("Invalid DateTime given, must be either local or UTC");
- var tmp = GetFilelistWhereClause(restoretime, versions);
- string query = tmp.Item1;
- var args = tmp.Item2;
-
+ (var query, var values) = GetFilelistWhereClause(restoretime, versions);
var res = new List();
using (var cmd = m_connection.CreateCommand())
{
- using (var rd = cmd.ExecuteReader($@"SELECT ""ID"" FROM ""Fileset"" {query} ORDER BY ""Timestamp"" DESC", args))
+ using (var rd = cmd.ExecuteReader($@"SELECT ""ID"" FROM ""Fileset"" {query} ORDER BY ""Timestamp"" DESC", values))
while (rd.Read())
res.Add(rd.GetInt64(0));
@@ -661,7 +662,7 @@ AND Fileset.ID NOT IN
private readonly IDbTransaction m_parent;
private readonly bool m_isTemporary;
- public TemporaryTransactionWrapper(IDbConnection connection, IDbTransaction transaction)
+ public TemporaryTransactionWrapper(IDbConnection connection, IDbTransaction? transaction)
{
if (transaction != null)
{
@@ -690,15 +691,15 @@ AND Fileset.ID NOT IN
public IDbTransaction Parent { get { return m_parent; } }
}
- private IEnumerable> GetDbOptionList(IDbTransaction transaction = null)
+ private IEnumerable> GetDbOptionList(IDbTransaction? transaction = null)
{
using (var cmd = m_connection.CreateCommand(transaction))
using (var rd = cmd.ExecuteReader(@"SELECT ""Key"", ""Value"" FROM ""Configuration"" "))
while (rd.Read())
- yield return new KeyValuePair(rd.GetValue(0).ToString(), rd.GetValue(1).ToString());
+ yield return new KeyValuePair(rd.ConvertValueToString(0) ?? "", rd.ConvertValueToString(1) ?? "");
}
- public IDictionary GetDbOptions(IDbTransaction transaction = null)
+ public IDictionary GetDbOptions(IDbTransaction? transaction = null)
{
return GetDbOptionList(transaction).ToDictionary(x => x.Key, x => x.Value);
}
@@ -752,7 +753,7 @@ AND Fileset.ID NOT IN
///
/// The options to set
/// An optional transaction
- public void SetDbOptions(IDictionary options, IDbTransaction transaction = null)
+ public void SetDbOptions(IDictionary options, IDbTransaction? transaction = null)
{
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
using (var cmd = m_connection.CreateCommand(tr.Parent))
@@ -1001,25 +1002,26 @@ ON
}
}
- public IEnumerable GetBlocks(long volumeid, IDbTransaction transaction = null)
+ public IEnumerable GetBlocks(long volumeid, IDbTransaction? transaction = null)
{
- using (var cmd = m_connection.CreateCommand(transaction))
- using (var rd = cmd.SetCommandAndParameters(@"SELECT DISTINCT ""Hash"", ""Size"" FROM ""Block"" WHERE ""VolumeID"" = @VolumeId")
- .SetParameterValue("@VolumeId", volumeid)
- .ExecuteReader())
+ using var cmd = m_connection.CreateCommand(transaction)
+ .SetCommandAndParameters(@"SELECT DISTINCT ""Hash"", ""Size"" FROM ""Block"" WHERE ""VolumeID"" = @VolumeId")
+ .SetParameterValue("@VolumeId", volumeid);
+ using (var rd = cmd.ExecuteReader())
while (rd.Read())
- yield return new Block(rd.GetValue(0).ToString(), rd.GetInt64(1));
+ yield return new Block(rd.ConvertValueToString(0) ?? throw new Exception("Hash is null"), rd.ConvertValueToInt64(1));
}
+ // TODO: Replace this with an enumerable method
private class BlocklistHashEnumerable : IEnumerable
{
private class BlocklistHashEnumerator : IEnumerator
{
private readonly IDataReader m_reader;
private readonly BlocklistHashEnumerable m_parent;
- private string m_path = null;
+ private string? m_path = null;
private bool m_first = true;
- private string m_current = null;
+ private string? m_current = null;
public BlocklistHashEnumerator(BlocklistHashEnumerable parent, IDataReader reader)
{
@@ -1027,7 +1029,7 @@ ON
m_parent = parent;
}
- public string Current { get { return m_current; } }
+ public string Current { get { return m_current!; } }
public void Dispose()
{
@@ -1041,8 +1043,8 @@ ON
if (m_path == null)
{
- m_path = m_reader.GetValue(0).ToString();
- m_current = m_reader.GetValue(6).ToString();
+ m_path = m_reader.ConvertValueToString(0);
+ m_current = m_reader.ConvertValueToString(6);
return true;
}
else
@@ -1057,14 +1059,14 @@ ON
return false;
}
- var np = m_reader.GetValue(0).ToString();
+ var np = m_reader.ConvertValueToString(0);
if (m_path != np)
{
m_current = null;
return false;
}
- m_current = m_reader.GetValue(6).ToString();
+ m_current = m_reader.ConvertValueToString(6);
return true;
}
}
@@ -1236,7 +1238,7 @@ ORDER BY
.SetParameterValue("@FolderBlocksetId", FOLDER_BLOCKSET_ID)
.SetParameterValue("@SymlinkBlocksetId", SYMLINK_BLOCKSET_ID);
- string lastpath = null;
+ string? lastpath = null;
using (var rd = cmd.ExecuteReader())
while (rd.Read())
{
@@ -1269,19 +1271,19 @@ ORDER BY
var more = false;
do
{
- var path = rd.GetValue(0).ToString();
- var filehash = rd.GetValue(3).ToString();
+ var path = rd.ConvertValueToString(0);
+ var filehash = rd.ConvertValueToString(3);
var size = rd.ConvertValueToInt64(2);
var lastmodified = new DateTime(rd.ConvertValueToInt64(1, 0), DateTimeKind.Utc);
- var metahash = rd.GetValue(4).ToString();
+ var metahash = rd.ConvertValueToString(4);
var metasize = rd.ConvertValueToInt64(5, -1);
var p = rd.GetValue(6);
var blrd = (p == null || p == DBNull.Value) ? null : new BlocklistHashEnumerable(rd);
- var blockhash = rd.GetValue(7).ToString();
+ var blockhash = rd.ConvertValueToString(7);
var blocksize = rd.ConvertValueToInt64(8, -1);
- var metablockhash = rd.GetValue(9).ToString();
+ var metablockhash = rd.ConvertValueToString(9);
//var metablocksize = rd.ConvertValueToInt64(10, -1);
- var metablocklisthash = rd.GetValue(11).ToString();
+ var metablocklisthash = rd.ConvertValueToString(11);
if (blockhash == filehash)
blockhash = null;
@@ -1346,7 +1348,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
type = expression.Type;
// Bugfix: SQLite does not handle case-insensitive LIKE with non-ascii characters
- if (type != FilterType.Regexp && !Library.Utility.Utility.IsFSCaseSensitive && filter.ToString().Any(x => x > 127))
+ if (type != FilterType.Regexp && !Library.Utility.Utility.IsFSCaseSensitive && filter.ToString()!.Any(x => x > 127))
type = FilterType.Regexp;
if (filter.Empty)
@@ -1385,7 +1387,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
else
{
var sb = new StringBuilder();
- var args = new Dictionary();
+ var args = new Dictionary();
foreach (var f in ((FilterExpression)filter).GetSimpleList())
{
if (sb.Length != 0)
@@ -1423,7 +1425,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
cmd.ExecuteNonQuery(FormatInvariant(@$"DROP TABLE IF EXISTS ""{Tablename}"" "));
}
catch { }
- finally { Tablename = null; }
+ finally { Tablename = null!; }
}
}
@@ -1447,7 +1449,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
cmd.SetCommandAndParameters(@"SELECT ""Type"" FROM ""Remotevolume"" WHERE ""Name"" = @Name")
.SetParameterValue("@Name", newname)
.ExecuteScalar()
- .ToString(),
+ ?.ToString() ?? "",
true);
//Create a fake new entry with the old name and mark as deleting
@@ -1464,7 +1466,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
/// The ID of the fileset volume to update
/// The timestamp of the operation to create
/// An optional external transaction
- public virtual long CreateFileset(long volumeid, DateTime timestamp, IDbTransaction transaction = null)
+ public virtual long CreateFileset(long volumeid, DateTime timestamp, IDbTransaction? transaction = null)
{
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
using (var cmd = m_connection.CreateCommand(tr.Parent))
@@ -1495,7 +1497,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
/// The size of the hash
/// An optional external transaction
/// An enumerable of tuples containing the blocklist hash, the blocklist data and the length of the data
- public IEnumerable> GetBlocklists(long volumeid, long blocksize, int hashsize, IDbTransaction transaction = null)
+ public IEnumerable> GetBlocklists(long volumeid, long blocksize, int hashsize, IDbTransaction? transaction = null)
{
using (var cmd = m_connection.CreateCommand(transaction))
{
@@ -1506,9 +1508,9 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
""B"".""Index"" >= (""A"".""Index"" * {blocksize / hashsize}) AND ""B"".""Index"" < ((""A"".""Index"" + 1) * {blocksize / hashsize}) AND ""C"".""ID"" = ""B"".""BlockID""
ORDER BY ""A"".""BlocksetID"", ""B"".""Index""");
- string curHash = null;
- int count = 0;
- byte[] buffer = new byte[blocksize];
+ string? curHash = null;
+ var count = 0;
+ var buffer = new byte[blocksize];
using (var rd = cmd.SetCommandAndParameters(sql).SetParameterValue("@VolumeId", volumeid).ExecuteReader())
while (rd.Read())
@@ -1516,12 +1518,12 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
var blockhash = rd.GetValue(0).ToString();
if ((blockhash != curHash && curHash != null) || count + hashsize > buffer.Length)
{
- yield return new Tuple(curHash, buffer, count);
+ yield return new Tuple(curHash!, buffer, count);
buffer = new byte[blocksize];
count = 0;
}
- var hash = Convert.FromBase64String(rd.GetValue(1).ToString());
+ var hash = Convert.FromBase64String(rd.ConvertValueToString(1) ?? throw new Exception("Hash is null"));
Array.Copy(hash, 0, buffer, count, hashsize);
curHash = blockhash;
count += hashsize;
@@ -1538,7 +1540,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
/// Existing file set to update
/// Full backup state
/// An optional external transaction
- public void UpdateFullBackupStateInFileset(long fileSetId, bool isFullBackup, IDbTransaction transaction = null)
+ public void UpdateFullBackupStateInFileset(long fileSetId, bool isFullBackup, IDbTransaction? transaction = null)
{
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
using (var cmd = m_connection.CreateCommand(tr.Parent))
@@ -1589,7 +1591,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
/// The fileset ID
/// An optional transaction
/// The remote volume entry or default
- public RemoteVolumeEntry GetRemoteVolumeFromFilesetID(long filesetID, IDbTransaction transaction = null)
+ public RemoteVolumeEntry GetRemoteVolumeFromFilesetID(long filesetID, IDbTransaction? transaction = null)
{
using (var cmd = m_connection.CreateCommand(transaction))
using (var rd = cmd.SetCommandAndParameters(@"SELECT ""RemoteVolume"".""ID"", ""Name"", ""Type"", ""Size"", ""Hash"", ""State"", ""DeleteGraceTime"" FROM ""RemoteVolume"", ""Fileset"" WHERE ""Fileset"".""VolumeID"" = ""RemoteVolume"".""ID"" AND ""Fileset"".""ID"" = @FilesetId")
@@ -1598,12 +1600,12 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
if (rd.Read())
return new RemoteVolumeEntry(
rd.ConvertValueToInt64(0, -1),
- rd.GetValue(1).ToString(),
- (rd.GetValue(4) == null || rd.GetValue(4) == DBNull.Value) ? null : rd.GetValue(4).ToString(),
+ rd.ConvertValueToString(1),
+ rd.ConvertValueToString(4),
rd.ConvertValueToInt64(3, -1),
- (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.GetValue(2).ToString()),
- (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.GetValue(5).ToString()),
- ParseFromEpochSeconds(rd.GetInt64(6)).ToLocalTime()
+ (RemoteVolumeType)Enum.Parse(typeof(RemoteVolumeType), rd.ConvertValueToString(2) ?? ""),
+ (RemoteVolumeState)Enum.Parse(typeof(RemoteVolumeState), rd.ConvertValueToString(5) ?? ""),
+ ParseFromEpochSeconds(rd.ConvertValueToInt64(6)).ToLocalTime()
);
else
return default;
@@ -1752,7 +1754,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
/// The path prefix ID.
/// The path to get the prefix for.
/// The transaction to use for insertion, or null for no transaction
- public long GetOrCreatePathPrefix(string prefix, IDbTransaction transaction)
+ public long GetOrCreatePathPrefix(string prefix, IDbTransaction? transaction)
{
// Ring-buffer style lookup
for (var i = 0; i < m_pathPrefixLookup.Length; i++)