* Introduced IFileStorage interface: Better abstraction than current IOConnection (suitable for cloud support). Currently only implemented by the built-in IOConnection (local/http/ftp)

* Implemented Merge functionality for SaveDB. UI is not yet implemented!
* Added tests for merge functionality
This commit is contained in:
Philipp Crocoll
2013-07-09 09:59:17 +02:00
parent 64e62cae70
commit 84aeb31fd0
42 changed files with 912 additions and 161 deletions

View File

@@ -562,22 +562,40 @@ namespace KeePassLib
/// Open a database. The URL may point to any supported data source.
/// </summary>
/// <param name="ioSource">IO connection to load the database from.</param>
/// <param name="pwKey">Key used to open the specified database.</param>
/// s<param name="pwKey">Key used to open the specified database.</param>
/// <param name="slLogger">Logger, which gets all status messages.</param>
public void Open(IOConnectionInfo ioSource, CompositeKey pwKey,
IStatusLogger slLogger)
{
Debug.Assert(ioSource != null);
if(ioSource == null) throw new ArgumentNullException("ioSource");
Open(IOConnection.OpenRead(ioSource), UrlUtil.StripExtension(
UrlUtil.GetFileName(ioSource.Path)), ioSource, pwKey, slLogger );
}
/// <summary>
/// Open a database. The URL may point to any supported data source.
/// </summary>
/// <param name="ioSource">IO connection to load the database from.</param>
/// <param name="pwKey">Key used to open the specified database.</param>
/// <param name="slLogger">Logger, which gets all status messages.</param>
public void Open(Stream s, string fileNameWithoutPathAndExt, IOConnectionInfo ioSource, CompositeKey pwKey,
IStatusLogger slLogger)
{
Debug.Assert(s != null);
if (s == null) throw new ArgumentNullException("s");
Debug.Assert(fileNameWithoutPathAndExt != null);
if (fileNameWithoutPathAndExt == null) throw new ArgumentException("fileNameWithoutPathAndExt");
Debug.Assert(pwKey != null);
if(pwKey == null) throw new ArgumentNullException("pwKey");
Debug.Assert(ioSource != null);
if (ioSource == null) throw new ArgumentNullException("ioSource");
if (pwKey == null) throw new ArgumentNullException("pwKey");
Close();
try
{
m_pgRootGroup = new PwGroup(true, true, UrlUtil.StripExtension(
UrlUtil.GetFileName(ioSource.Path)), PwIcon.FolderOpen);
m_pgRootGroup = new PwGroup(true, true, fileNameWithoutPathAndExt, PwIcon.FolderOpen);
m_pgRootGroup.IsExpanded = true;
m_pwUserKey = pwKey;
@@ -587,8 +605,8 @@ namespace KeePassLib
KdbxFile kdbx = new KdbxFile(this);
kdbx.DetachBinaries = m_strDetachBins;
Stream s = IOConnection.OpenRead(ioSource);
kdbx.Load(s, KdbxFormat.Default, slLogger);
s.Close();
m_pbHashOfLastIO = kdbx.HashOfFileOnDisk;
@@ -598,13 +616,14 @@ namespace KeePassLib
m_bDatabaseOpened = true;
m_ioSource = ioSource;
}
catch(Exception)
catch (Exception)
{
Clear();
throw;
}
}
/// <summary>
/// Save the currently opened database. The file is written to the location
/// it has been opened from.
@@ -626,7 +645,7 @@ namespace KeePassLib
kdb.Save(s, null, KdbxFormat.Default, slLogger);
ft.CommitWrite();
m_pbHashOfLastIO = kdb.HashOfFileOnDisk;
m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
Debug.Assert(m_pbHashOfFileOnDisk != null);
@@ -636,6 +655,23 @@ namespace KeePassLib
m_bModified = false;
}
/// <summary>
/// Save the currently opened database. The file is written to the given stream which is expected to be the original location.
/// </summary>
/// This allows to save to cloud locations etc.
public void Save(Stream streamOfOriginalLocation, IStatusLogger slLogger)
{
Debug.Assert(ValidateUuidUniqueness());
Stream s = streamOfOriginalLocation;
KdbxFile kdb = new KdbxFile(this);
kdb.Save(s, null, KdbxFormat.Default, slLogger);
m_pbHashOfLastIO = kdb.HashOfFileOnDisk;
m_pbHashOfFileOnDisk = kdb.HashOfFileOnDisk;
Debug.Assert(m_pbHashOfFileOnDisk != null);
m_bModified = false;
}
/// <summary>
/// Save the currently opened database to a different location. If
/// <paramref name="bIsPrimaryNow" /> is <c>true</c>, the specified