From eda873911a08abbfc9736975ce929fe97cfb18de Mon Sep 17 00:00:00 2001 From: Filippo Ferrazini Date: Sat, 28 Dec 2019 16:03:18 +0100 Subject: [PATCH] Change behaviour in sql save, don't rewrite all database --- .../Config/Connections/SqlConnectionsSaver.cs | 10 ++-- .../MsSql/DataTableSerializer.cs | 56 ++++++++++++++++--- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/mRemoteV1/Config/Connections/SqlConnectionsSaver.cs b/mRemoteV1/Config/Connections/SqlConnectionsSaver.cs index a3a24dd14..f858ccaeb 100644 --- a/mRemoteV1/Config/Connections/SqlConnectionsSaver.cs +++ b/mRemoteV1/Config/Connections/SqlConnectionsSaver.cs @@ -153,14 +153,16 @@ namespace mRemoteNG.Config.Connections private void UpdateConnectionsTable(RootNodeInfo rootTreeNode, IDatabaseConnector databaseConnector) { + var dataProvider = new SqlDataProvider(databaseConnector); + var currentDataTable = dataProvider.Load(); + var cryptoProvider = new LegacyRijndaelCryptographyProvider(); var serializer = new DataTableSerializer(_saveFilter, cryptoProvider, rootTreeNode.PasswordString.ConvertToSecureString()); + serializer.SetSourceDataTable(currentDataTable); var dataTable = serializer.Serialize(rootTreeNode); - var dataProvider = new SqlDataProvider(databaseConnector); - - var dbQuery = databaseConnector.DbCommand("DELETE FROM tblCons"); - dbQuery.ExecuteNonQuery(); + //var dbQuery = databaseConnector.DbCommand("DELETE FROM tblCons"); + //dbQuery.ExecuteNonQuery(); dataProvider.Save(dataTable); } diff --git a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs index 489c6c5af..d712784cb 100644 --- a/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs +++ b/mRemoteV1/Config/Serializers/ConnectionSerializers/MsSql/DataTableSerializer.cs @@ -5,6 +5,7 @@ using mRemoteNG.Tools; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using System; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Security; @@ -13,9 +14,15 @@ namespace mRemoteNG.Config.Serializers.MsSql { public class DataTableSerializer : ISerializer { + public readonly int DELETE = 0; + public readonly int ADD = 1; + public readonly int UPDATE = 2; private readonly ICryptographyProvider _cryptographyProvider; private readonly SecureString _encryptionKey; private DataTable _dataTable; + private DataTable _sourceDataTable; + private Dictionary modifiedPrimaryKeyDict = new Dictionary(); + private Dictionary sourcePrimaryKeyDict = new Dictionary(); private const string TableName = "tblCons"; private readonly SaveFilter _saveFilter; private int _currentNodeIndex; @@ -31,6 +38,11 @@ namespace mRemoteNG.Config.Serializers.MsSql _encryptionKey = encryptionKey.ThrowIfNull(nameof(encryptionKey)); } + public void SetSourceDataTable(DataTable sourceDataTable) + { + _sourceDataTable = sourceDataTable; + } + public DataTable Serialize(ConnectionTreeModel connectionTreeModel) { @@ -51,15 +63,33 @@ namespace mRemoteNG.Config.Serializers.MsSql { _dataTable = BuildTable(); _currentNodeIndex = 0; + // Register add or update row SerializeNodesRecursive(serializationTarget); + var entryToDelete = sourcePrimaryKeyDict.Keys.Where(x => !modifiedPrimaryKeyDict.ContainsKey(x)).ToList(); + foreach( var entry in entryToDelete) + { + _dataTable.Rows.Find(entry).Delete(); + } return _dataTable; } private DataTable BuildTable() { - var dataTable = new DataTable(TableName); - CreateSchema(dataTable); - SetPrimaryKey(dataTable); + DataTable dataTable; + if (_sourceDataTable != null) + { + dataTable = _sourceDataTable; + }else + { + dataTable = new DataTable(TableName); + + } + if (dataTable.Columns.Count == 0) CreateSchema(dataTable); + if (dataTable.PrimaryKey.Length == 0 ) SetPrimaryKey(dataTable); + foreach(DataRow row in dataTable.Rows) + { + sourcePrimaryKeyDict.Add((string)row["ConstantID"], DELETE); + } return dataTable; } @@ -219,11 +249,22 @@ namespace mRemoteNG.Config.Serializers.MsSql private void SerializeConnectionInfo(ConnectionInfo connectionInfo) { _currentNodeIndex++; - var dataRow = _dataTable.NewRow(); - dataRow["ID"] = DBNull.Value; + var isNewRow = false; + DataRow dataRow = _dataTable.Rows.Find(connectionInfo.ConstantID); + if (dataRow == null) + { + dataRow = _dataTable.NewRow(); + //dataRow["ID"] = DBNull.Value; + dataRow["ConstantID"] = connectionInfo.ConstantID; + isNewRow = true; + modifiedPrimaryKeyDict.Add(connectionInfo.ConstantID, ADD); + } + else + { + modifiedPrimaryKeyDict.Add(connectionInfo.ConstantID, UPDATE); + } dataRow["Name"] = connectionInfo.Name; dataRow["Type"] = connectionInfo.GetTreeNodeType().ToString(); - dataRow["ConstantID"] = connectionInfo.ConstantID; dataRow["ParentID"] = connectionInfo.Parent?.ConstantID ?? ""; dataRow["PositionID"] = _currentNodeIndex; dataRow["LastChange"] = MiscTools.DBTimeStampNow(); @@ -419,8 +460,7 @@ namespace mRemoteNG.Config.Serializers.MsSql dataRow["InheritRDGatewayDomain"] = false; dataRow["InheritRdpVersion"] = false; } - - _dataTable.Rows.Add(dataRow); + if (isNewRow)_dataTable.Rows.Add(dataRow); } } } \ No newline at end of file