we can now prevent saving to the database when a save was triggered for a local-only property change

this will prevent unnecessary db saves
This commit is contained in:
David Sparer
2018-11-03 10:34:30 -05:00
parent 78bf40282a
commit 0427956e8b
9 changed files with 80 additions and 28 deletions

View File

@@ -24,7 +24,7 @@ namespace mRemoteNG.Config.Connections
_saveFilter = saveFilter;
}
public void Save(ConnectionTreeModel connectionTreeModel)
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
{
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, Runtime.CredentialProviderCatalog);
var dataProvider = new FileDataProvider(_connectionFileName);

View File

@@ -33,7 +33,7 @@ namespace mRemoteNG.Config.Connections
private void ConnectionTreeModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
SaveConnectionOnEdit();
SaveConnectionOnEdit(propertyChangedEventArgs.PropertyName);
}
private void ConnectionTreeModelOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
@@ -41,14 +41,14 @@ namespace mRemoteNG.Config.Connections
SaveConnectionOnEdit();
}
private void SaveConnectionOnEdit()
private void SaveConnectionOnEdit(string propertyName = "")
{
if (!mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit)
return;
if (FrmMain.Default.IsClosing)
return;
_connectionsService.SaveConnectionsAsync();
_connectionsService.SaveConnectionsAsync(propertyName);
}
}
}

View File

@@ -18,6 +18,7 @@ using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Security;
using mRemoteNG.Connection;
namespace mRemoteNG.Config.Connections
{
@@ -40,12 +41,19 @@ namespace mRemoteNG.Config.Connections
_dataProvider = localPropertiesDataProvider.ThrowIfNull(nameof(localPropertiesDataProvider));
}
public void Save(ConnectionTreeModel connectionTreeModel)
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
{
var rootTreeNode = connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
UpdateLocalConnectionProperties(rootTreeNode);
if (PropertyIsLocalOnly(propertyNameTrigger))
{
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg,
$"Property {propertyNameTrigger} is local only. Not saving to database.");
return;
}
if (SqlUserIsReadOnly())
{
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Trying to save connection tree but the SQL read only checkbox is checked, aborting!");
@@ -71,6 +79,20 @@ namespace mRemoteNG.Config.Connections
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Saved connections to database");
}
/// <summary>
/// Determines if a given property name should be only saved
/// locally.
/// </summary>
/// <param name="property">
/// The name of the property that triggered the save event
/// </param>
/// <returns></returns>
private bool PropertyIsLocalOnly(string property)
{
return property == nameof(ConnectionInfo.OpenConnections) ||
property == nameof(ContainerInfo.IsExpanded);
}
private void UpdateLocalConnectionProperties(ContainerInfo rootNode)
{
var a = rootNode.GetRecursiveChildList().Select(info => new LocalConnectionPropertiesModel

View File

@@ -27,7 +27,7 @@ namespace mRemoteNG.Config.Connections
_saveFilter = saveFilter;
}
public void Save(ConnectionTreeModel connectionTreeModel)
public void Save(ConnectionTreeModel connectionTreeModel, string propertyNameTrigger = "")
{
try
{

View File

@@ -18,7 +18,7 @@ namespace mRemoteNG.Config
_dataProvider = dataProvider;
}
public void Save(IEnumerable<ICredentialRepository> repositories)
public void Save(IEnumerable<ICredentialRepository> repositories, string propertyNameTrigger = "")
{
var serializer = new CredentialRepositoryListSerializer();
var data = serializer.Serialize(repositories);

View File

@@ -2,6 +2,6 @@
{
public interface ISaver<in T>
{
void Save(T model);
void Save(T model, string propertyNameTrigger = "");
}
}

View File

@@ -674,7 +674,7 @@ namespace mRemoteNG.Connection
PropertyChanged?.Invoke(sender, new PropertyChangedEventArgs(args.PropertyName));
}
private void SetField<T>(ref T field, T value, string propertyName = null)
protected void SetField<T>(ref T field, T value, string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return;
field = value;

View File

@@ -16,6 +16,7 @@ using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.Config;
namespace mRemoteNG.Connection
{
@@ -187,7 +188,17 @@ namespace mRemoteNG.Connection
/// <param name="saveFilter"></param>
/// <param name="connectionFileName"></param>
/// <param name="forceSave">Bypasses safety checks that prevent saving if a connection file isn't loaded.</param>
public void SaveConnections(ConnectionTreeModel connectionTreeModel, bool useDatabase, SaveFilter saveFilter, string connectionFileName, bool forceSave = false)
/// <param name="propertyNameTrigger">
/// Optional. The name of the property that triggered
/// this save.
/// </param>
public void SaveConnections(
ConnectionTreeModel connectionTreeModel,
bool useDatabase,
SaveFilter saveFilter,
string connectionFileName,
bool forceSave = false,
string propertyNameTrigger = "")
{
if (connectionTreeModel == null)
return;
@@ -207,10 +218,13 @@ namespace mRemoteNG.Connection
RemoteConnectionsSyncronizer?.Disable();
var previouslyUsingDatabase = UsingDatabase;
if (useDatabase)
new SqlConnectionsSaver(saveFilter, _localConnectionPropertiesSerializer, _localConnectionPropertiesDataProvider).Save(connectionTreeModel);
else
new XmlConnectionsSaver(connectionFileName, saveFilter).Save(connectionTreeModel);
var saver = useDatabase
? (ISaver<ConnectionTreeModel>)new SqlConnectionsSaver(saveFilter, _localConnectionPropertiesSerializer,
_localConnectionPropertiesDataProvider)
: new XmlConnectionsSaver(connectionFileName, saveFilter);
saver.Save(connectionTreeModel, propertyNameTrigger);
if (UsingDatabase)
LastSqlUpdate = DateTime.Now;
@@ -230,7 +244,14 @@ namespace mRemoteNG.Connection
}
}
public void SaveConnectionsAsync()
/// <summary>
/// Save the currently loaded connections asynchronously
/// </summary>
/// <param name="propertyNameTrigger">
/// Optional. The name of the property that triggered
/// this save.
/// </param>
public void SaveConnectionsAsync(string propertyNameTrigger = "")
{
if (_batchingSaves)
{
@@ -238,19 +259,22 @@ namespace mRemoteNG.Connection
return;
}
var t = new Thread(SaveConnectionsBGd);
var t = new Thread(() =>
{
lock (SaveLock)
{
SaveConnections(
ConnectionTreeModel,
UsingDatabase,
new SaveFilter(),
ConnectionFileName,
propertyNameTrigger: propertyNameTrigger);
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private void SaveConnectionsBGd()
{
lock (SaveLock)
{
SaveConnections();
}
}
public string GetStartupConnectionFileName()
{
return Settings.Default.LoadConsFromCustomLocation == false

View File

@@ -12,13 +12,19 @@ namespace mRemoteNG.Container
[DefaultProperty("Name")]
public class ContainerInfo : ConnectionInfo, INotifyCollectionChanged
{
[Browsable(false)]
private bool _isExpanded;
[Browsable(false)]
public List<ConnectionInfo> Children { get; } = new List<ConnectionInfo>();
[Category(""), Browsable(false), ReadOnly(false), Bindable(false), DefaultValue(""), DesignOnly(false)]
public bool IsExpanded { get; set; }
[Category(""), Browsable(false), ReadOnly(false), Bindable(false), DefaultValue(""), DesignOnly(false)]
public bool IsExpanded
{
get => _isExpanded;
set => SetField(ref _isExpanded, value, "IsExpanded");
}
[Browsable(false)]
[Browsable(false)]
public override bool IsContainer { get { return true; } set {} }
public ContainerInfo(string uniqueId)