diff --git a/src/BSH.Engine/Contracts/IQueryManager.cs b/src/BSH.Engine/Contracts/IQueryManager.cs index d6c42d2..fa6e1ad 100644 --- a/src/BSH.Engine/Contracts/IQueryManager.cs +++ b/src/BSH.Engine/Contracts/IQueryManager.cs @@ -24,7 +24,7 @@ public interface IQueryManager Task GetBackVersionWhereFileAsync(string startVersion, string searchString); Task GetBackVersionWhereFilesInFolderAsync(string startVersion, string path); string GetFileNameFromDrive(FileTableRow file); - Task> GetFileNameFromDriveAsync(int versionId, string fileName, string filePath, SecureString password); + Task> GetFileNameFromDriveAsync(int versionId, string fileName, string filePath, SecureString password); Task> GetFilesByVersionAsync(string version, string path); Task> GetFolderListAsync(string version, string path); Task GetFullRestoreFolderAsync(string folder, string version); diff --git a/src/BSH.Engine/QueryManager.cs b/src/BSH.Engine/QueryManager.cs index 47ce899..5008ec8 100644 --- a/src/BSH.Engine/QueryManager.cs +++ b/src/BSH.Engine/QueryManager.cs @@ -327,7 +327,7 @@ public async Task GetBackVersionWhereFilesInFolderAsync(string startVers "WHERE a.versionID < @startVersion " + "AND a.versionStatus = 0 " + "AND EXISTS (SELECT 1 FROM fileversiontable, filelink, filetable " + - "WHERE fileversiontable.fileversionid = filelink.fileversionid " + + "WHERE fileversiontable.fileversionID = filelink.fileversionID " + "AND filelink.versionID = a.versionID " + "AND filetable.fileID = fileversiontable.fileID " + "AND filetable.filePath = @path) " + @@ -579,7 +579,7 @@ public string GetFileNameFromDrive(FileTableRow file) /// /// /// - public async Task> GetFileNameFromDriveAsync(int versionId, string fileName, string filePath, SecureString password) + public async Task> GetFileNameFromDriveAsync(int versionId, string fileName, string filePath, SecureString password) { using var dbClient = dbClientFactory.CreateDbClient(); using var storage = storageFactory.GetCurrentStorageProvider(); @@ -651,7 +651,7 @@ public async Task> GetFileNameFromDriveAsync(int versionId, reader.Close(); } - return new Tuple(result, temp); + return (result, temp); } /// @@ -703,14 +703,14 @@ public async Task GetFullRestoreFolderAsync(string folder, string versio foreach (var destination in destFolders) { - var directory = new DirectoryInfo(destination); + var directoryName = destination.Split("\\", StringSplitOptions.RemoveEmptyEntries)[^1]; - if (folder.StartsWith("\\" + directory.Name + "\\")) + if (folder.StartsWith("\\" + directoryName + "\\")) { - var idx = folder.IndexOf("\\" + directory.Name + "\\"); + var idx = folder.IndexOf("\\" + directoryName + "\\"); // path found - var result = Path.Combine(destination, folder[(idx + directory.Name.Length + 2)..]); + var result = Path.Combine(destination, folder[(idx + directoryName.Length + 2)..]); if (result.EndsWith("\\")) { diff --git a/src/BSH.Main/Dialogs/frmBrowser.cs b/src/BSH.Main/Dialogs/frmBrowser.cs index 023474e..8720bf8 100644 --- a/src/BSH.Main/Dialogs/frmBrowser.cs +++ b/src/BSH.Main/Dialogs/frmBrowser.cs @@ -1141,52 +1141,43 @@ private async void ToolStripSchnellansicht_Click(object sender, EventArgs e) } // Schnellansicht laden - Tuple tmpFile = null; try { var password = BackupLogic.BackupService.GetPassword(); - tmpFile = await BackupLogic.QueryManager.GetFileNameFromDriveAsync(int.Parse(selectedVersion.Id), lvFiles.SelectedItems[0].Text, lvFiles.SelectedItems[0].Tag.ToString(), password); + var tmpFile = await BackupLogic.QueryManager.GetFileNameFromDriveAsync(int.Parse(selectedVersion.Id), lvFiles.SelectedItems[0].Text, lvFiles.SelectedItems[0].Tag.ToString(), password); -#if !WIN_UWP var procInfo = new ProcessStartInfo(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + @"\SmartPreview.exe", " -file:\"" + tmpFile.Item1 + "\"" + (tmpFile.Item2 ? " -c" : "")); procInfo.WindowStyle = ProcessWindowStyle.Normal; var proc = Process.Start(procInfo); proc.WaitForExit(); -#else - var procInfo = new ProcessStartInfo(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + @"\..\SmartPreview\SmartPreview.exe", " -file:\"" + tmpFile.Item1 + "\"" + (isTmp.Item2 ? " -c" : "")); - procInfo.WindowStyle = ProcessWindowStyle.Normal; - - var proc = Process.Start(procInfo); - proc.WaitForExit(); -#endif - } - catch - { - // Fehler: Feature nicht installiert? - MessageBox.Show(Resources.DLG_FEATURE_NOT_AVAILABLE_TEXT, Resources.DLG_FEATURE_NOT_AVAILABLE_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - } - if (tmpFile != null && tmpFile.Item2) - { - for (int i = 0; i <= 5; i++) + if (tmpFile.Item1 != null && tmpFile.Item2) { - try + for (var i = 0; i <= 5; i++) { - if (i == 5) + try { - return; - } + if (i == 5) + { + return; + } - System.IO.File.Delete(tmpFile.Item1); - break; - } - catch - { - // ignore error + System.IO.File.Delete(tmpFile.Item1); + break; + } + catch + { + // ignore error + } } } } + catch + { + // Fehler: Feature nicht installiert? + MessageBox.Show(Resources.DLG_FEATURE_NOT_AVAILABLE_TEXT, Resources.DLG_FEATURE_NOT_AVAILABLE_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } } } diff --git a/src/BSH.Main/Dialogs/frmFileProperties.cs b/src/BSH.Main/Dialogs/frmFileProperties.cs index 1afaf94..6aecb4e 100644 --- a/src/BSH.Main/Dialogs/frmFileProperties.cs +++ b/src/BSH.Main/Dialogs/frmFileProperties.cs @@ -46,49 +46,40 @@ private async void cmdPreview_Click(object sender, EventArgs e) } // Schnellansicht laden - Tuple tmpFile = null; try { - int id = int.Parse(((FileTableRow)lvVersions.SelectedItems[0].Tag).FilePackage); + var id = int.Parse(((FileTableRow)lvVersions.SelectedItems[0].Tag).FilePackage); var password = BackupLogic.BackupService.GetPassword(); - tmpFile = await BackupLogic.QueryManager.GetFileNameFromDriveAsync(id, lblFileName.Text, CurrentFileFolder, password); + var tmpFile = await BackupLogic.QueryManager.GetFileNameFromDriveAsync(id, lblFileName.Text, CurrentFileFolder, password); -#if !WIN_UWP var procInfo = new ProcessStartInfo(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + @"\SmartPreview.exe", " -file:\"" + tmpFile.Item1 + "\"" + (tmpFile.Item2 ? " -c" : "")); procInfo.WindowStyle = ProcessWindowStyle.Normal; var proc = Process.Start(procInfo); proc.WaitForExit(); -#else - var procInfo = new ProcessStartInfo(System.IO.Path.GetDirectoryName(Application.ExecutablePath) + @"\..\SmartPreview\SmartPreview.exe", " -file:\"" + tmpFile.Item1 + "\"" + (isTmp.Item2 ? " -c" : "")); - procInfo.WindowStyle = ProcessWindowStyle.Normal; - var proc = Process.Start(procInfo); - proc.WaitForExit(); -#endif + if (tmpFile.Item1 != null && tmpFile.Item2) + { + for (var i = 0; i < 5; i++) + { + try + { + System.IO.File.Delete(tmpFile.Item1); + break; + } + catch + { + // next try + } + } + } } catch { // Fehler: Feature nicht installiert? MessageBox.Show(Resources.DLG_FEATURE_NOT_AVAILABLE_TEXT, Resources.DLG_FEATURE_NOT_AVAILABLE_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } - - if (tmpFile != null && tmpFile.Item2) - { - for (int i = 0; i < 5; i++) - { - try - { - System.IO.File.Delete(tmpFile.Item1); - break; - } - catch - { - // next try - } - } - } } } diff --git a/src/BSH.Test/Mocks/StorageFactoryMock.cs b/src/BSH.Test/Mocks/StorageFactoryMock.cs new file mode 100644 index 0000000..bd6ef3c --- /dev/null +++ b/src/BSH.Test/Mocks/StorageFactoryMock.cs @@ -0,0 +1,8 @@ +using Brightbits.BSH.Engine.Contracts.Storage; +using Brightbits.BSH.Engine.Storage; + +namespace BSH.Test.Mocks; +public class StorageFactoryMock : IStorageFactory +{ + public IStorage GetCurrentStorageProvider() => new StorageMock(); +} diff --git a/src/BSH.Test/QueryManagerTests.cs b/src/BSH.Test/QueryManagerTests.cs new file mode 100644 index 0000000..99fe056 --- /dev/null +++ b/src/BSH.Test/QueryManagerTests.cs @@ -0,0 +1,316 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Brightbits.BSH.Engine; +using Brightbits.BSH.Engine.Contracts; +using Brightbits.BSH.Engine.Contracts.Database; +using Brightbits.BSH.Engine.Database; +using Brightbits.BSH.Engine.Models; +using Brightbits.BSH.Engine.Storage; +using BSH.Test.Mocks; +using NUnit.Framework; + +namespace BSH.Test; +public class QueryManagerTests +{ + private IDbClientFactory dbClientFactory; + private IConfigurationManager configurationManager; + private IQueryManager queryManager; + + [SetUp] + public async Task Setup() + { + if (dbClientFactory != null) + { + DbClientFactory.ClosePool(); + this.dbClientFactory = null; + } + + // start with clean database + if (File.Exists("testdb_querymanager.db")) + { + File.Delete("testdb_querymanager.db"); + } + + dbClientFactory = new DbClientFactory(); + await dbClientFactory.InitializeAsync(Environment.CurrentDirectory + "\\testdb_querymanager.db"); + + configurationManager = new ConfigurationManager(dbClientFactory); + await configurationManager.InitializeAsync(); + + configurationManager.BackupFolder = "X:\\Backups"; + configurationManager.SourceFolder = "Y:\\MyFiles\\source_1"; + + var storageFactory = new StorageFactoryMock(); + queryManager = new QueryManager(dbClientFactory, configurationManager, storageFactory); + + // insert some data + await PopulateExampleData(); + } + + public async Task PopulateExampleData() + { + // versions + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO versiontable (versionID, versionDate, versionTitle, versionDescription, versionStable, versionSources, versionStatus, versionType) VALUES (1, '01-01-2021 00-00-00', '1.0.0', 'Initial full version', 1, 'Y:\\MyFiles\\source_1|Y:\\MyFiles\\source_2\\', 0, 2)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO versiontable (versionID, versionDate, versionTitle, versionDescription, versionStable, versionSources, versionStatus, versionType) VALUES (2, '02-01-2021 00-00-00', '2.0.0', 'Incremental version', 1, '', 0, 1)"); + + // files + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filetable (fileID, fileName, filePath) VALUES (1, 'file1.txt', '\\source_1\\')"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filetable (fileID, fileName, filePath) VALUES (2, 'file2.txt', '\\source_1\\subfolder\\')"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filetable (fileID, fileName, filePath) VALUES (3, 'file3.txt', '\\source_2\\subfolder\\')"); + + // file links + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filelink (fileversionID, versionID) VALUES (1, 1)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filelink (fileversionID, versionID) VALUES (2, 1)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filelink (fileversionID, versionID) VALUES (3, 1)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filelink (fileversionID, versionID) VALUES (1, 2)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filelink (fileversionID, versionID) VALUES (2, 2)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO filelink (fileversionID, versionID) VALUES (3, 2)"); + + // file versions + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO fileversiontable (fileversionID, fileStatus, fileType, fileHash, fileDateModified, fileDateCreated, fileSize, filePackage, fileID) VALUES (1, 0, 1, 'hash1', '2021-01-01 00:00:00', '2021-01-01 00:00:00', 100, 1, '1')"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO fileversiontable (fileversionID, fileStatus, fileType, fileHash, fileDateModified, fileDateCreated, fileSize, filePackage, fileID) VALUES (2, 0, 1, 'hash1', '2021-01-01 00:00:00', '2021-01-01 00:00:00', 100, 1, '2')"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO fileversiontable (fileversionID, fileStatus, fileType, fileHash, fileDateModified, fileDateCreated, fileSize, filePackage, fileID) VALUES (3, 0, 1, 'hash1', '2021-01-01 00:00:00', '2021-01-01 00:00:00', 100, 1, '3')"); + + // folders + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO foldertable (id, folder) VALUES (1, '\\source_3\\')"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO foldertable (id, folder) VALUES (2, '\\source_3\\subfolder\\')"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO foldertable (id, folder) VALUES (3, '\\source_4\\subfolder\\')"); + + // folder links + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO folderlink (folderid, versionid) VALUES (1, 1)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO folderlink (folderid, versionid) VALUES (2, 1)"); + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO folderlink (folderid, versionid) VALUES (3, 1)"); + } + + [Test] + public async Task GetLastBackupAsyncTest() + { + var result = await queryManager.GetLastBackupAsync(); + Assert.AreEqual("2", result.Id); + } + + [Test] + public async Task GetLastFullBackupAsyncTest() + { + var result = await queryManager.GetLastFullBackupAsync(); + Assert.AreEqual("1", result.Id); + } + + [Test] + public void GetVersionsTest() + { + var result = queryManager.GetVersions(); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("2", result[0].Id); + + result = queryManager.GetVersions(false); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("1", result[0].Id); + } + + [Test] + public async Task GetNumberOfVersionsAsyncTest() + { + var result = await queryManager.GetNumberOfVersionsAsync(); + Assert.AreEqual(2, result); + } + + [Test] + public async Task GetOldestBackupAsyncTest() + { + var result = await queryManager.GetOldestBackupAsync(); + Assert.AreEqual("1", result.Id); + } + + [Test] + public async Task GetVersionByIdAsyncTest() + { + var result = await queryManager.GetVersionByIdAsync("1"); + Assert.AreEqual("1", result.Id); + + result = await queryManager.GetVersionByIdAsync("2"); + Assert.AreEqual("2", result.Id); + } + + [Test] + public async Task GetFolderListAsyncTest() + { + var result = await queryManager.GetFolderListAsync("1", "%"); + Assert.AreEqual(6, result.Count); + Assert.AreEqual("source_1", result[0]); + Assert.AreEqual("source_1\\subfolder", result[1]); + Assert.AreEqual("source_2\\subfolder", result[2]); + Assert.AreEqual("source_3", result[3]); + Assert.AreEqual("source_3\\subfolder", result[4]); + Assert.AreEqual("source_4\\subfolder", result[5]); + } + + [Test] + public async Task GetBackVersionWhereFileAsyncTest() + { + var result = await queryManager.GetBackVersionWhereFileAsync("2", "file1.txt"); + Assert.AreEqual("1", result); + + result = await queryManager.GetBackVersionWhereFileAsync("1", "file1.txt"); + Assert.IsNull(result); + } + + [Test] + public async Task GetBackVersionWhereFilesInFolderAsyncTest() + { + var result = await queryManager.GetBackVersionWhereFilesInFolderAsync("2", "source_1"); + Assert.AreEqual("1", result); + + result = await queryManager.GetBackVersionWhereFilesInFolderAsync("2", "\\source_1"); + Assert.AreEqual("1", result); + + result = await queryManager.GetBackVersionWhereFilesInFolderAsync("2", "source_1\\"); + Assert.AreEqual("1", result); + + result = await queryManager.GetBackVersionWhereFilesInFolderAsync("1", "source_1"); + Assert.IsNull(result); + } + + [Test] + public async Task GetNextVersionWhereFileAsyncTest() + { + var result = await queryManager.GetNextVersionWhereFileAsync("2", "file1.txt"); + Assert.IsNull(result); + + result = await queryManager.GetNextVersionWhereFileAsync("1", "file1.txt"); + Assert.AreEqual("2", result); + } + + [Test] + public async Task GetNextVersionWhereFilesInFolderAsyncTest() + { + var result = await queryManager.GetNextVersionWhereFilesInFolderAsync("1", "source_1"); + Assert.AreEqual("2", result); + + result = await queryManager.GetNextVersionWhereFilesInFolderAsync("1", "\\source_1"); + Assert.AreEqual("2", result); + + result = await queryManager.GetNextVersionWhereFilesInFolderAsync("1", "source_1\\"); + Assert.AreEqual("2", result); + + result = await queryManager.GetNextVersionWhereFilesInFolderAsync("2", "source_1"); + Assert.IsNull(result); + } + + [Test] + public async Task GetVersionsByFileAsyncTest() + { + var result = await queryManager.GetVersionsByFileAsync("file1.txt", "\\source_1\\"); + Assert.AreEqual(1, result.Count); + } + + [Test] + public async Task GetFilesByVersionAsyncTest() + { + var result = await queryManager.GetFilesByVersionAsync("1", "\\source_1\\"); + Assert.AreEqual(1, result.Count); + Assert.AreEqual("file1.txt", result[0].FileName); + + result = await queryManager.GetFilesByVersionAsync("1", "source_1"); + Assert.AreEqual(1, result.Count); + Assert.AreEqual("file1.txt", result[0].FileName); + + result = await queryManager.GetFilesByVersionAsync("2", "\\source_1\\"); + Assert.AreEqual(1, result.Count); + Assert.AreEqual("file1.txt", result[0].FileName); + } + + [Test] + public void GetFileNameFromDriveTest() + { + var file = new FileTableRow() + { + FileType = "1", + FileVersionDate = DateTime.Now, + FilePath = "\\source_1", + FileName = "file1.txt" + }; + + var result = queryManager.GetFileNameFromDrive(file); + Assert.AreEqual("X:\\Backups\\" + file.FileVersionDate.ToString("dd-MM-yyyy HH-mm-ss") + "\\source_1\\file1.txt", result); + + file.FilePath = "source_1"; + result = queryManager.GetFileNameFromDrive(file); + Assert.AreEqual("X:\\Backups\\" + file.FileVersionDate.ToString("dd-MM-yyyy HH-mm-ss") + "\\source_1\\file1.txt", result); + + file.FileLongFileName = "XYZ"; + result = queryManager.GetFileNameFromDrive(file); + Assert.AreEqual("X:\\Backups\\" + file.FileVersionDate.ToString("dd-MM-yyyy HH-mm-ss") + "\\_LONGFILES_\\XYZ", result); + + file.FileType = "2"; + result = queryManager.GetFileNameFromDrive(file); + Assert.IsNull(result); + } + + [Test] + public async Task GetFileNameFromDriveAsyncTest() + { + var result = await queryManager.GetFileNameFromDriveAsync(1, "file1.txt", "\\source_1\\", null); + Assert.AreEqual(("X:\\Backups\\01-01-2021 00-00-00\\source_1\\file1.txt", false), result); + } + + [Test] + public async Task HasChangesOrNewAsyncTest() + { + var result = await queryManager.HasChangesOrNewAsync("\\source_1\\", "1"); + Assert.IsTrue(result); + } + + [Test] + public async Task GetFullRestoreFolderAsyncTest() + { + var result = await queryManager.GetFullRestoreFolderAsync("\\source_1\\", "1"); + Assert.AreEqual("Y:\\MyFiles\\source_1", result); + + result = await queryManager.GetFullRestoreFolderAsync("source_1", "1"); + Assert.AreEqual("Y:\\MyFiles\\source_1", result); + + result = await queryManager.GetFullRestoreFolderAsync("source_1", "2"); + Assert.AreEqual("Y:\\MyFiles\\source_1", result); + + result = await queryManager.GetFullRestoreFolderAsync("source_2", "1"); + Assert.AreEqual("Y:\\MyFiles\\source_2", result); + + result = await queryManager.GetFullRestoreFolderAsync("source_3", "1"); + Assert.IsNull(result); + } + + [Test] + public async Task GetLocalizedPathAsyncTest() + { + var result = await queryManager.GetLocalizedPathAsync("\\source_1\\"); + Assert.AreEqual("source_1", result); + + // activate configuration + configurationManager.ShowLocalizedPath = "1"; + + result = await queryManager.GetLocalizedPathAsync("\\source_1\\"); + Assert.AreEqual("source_1", result); + + // add junction + await dbClientFactory.ExecuteNonQueryAsync("INSERT INTO folderjunctiontable VALUES ('source_1', 'source_1_localized')"); + + result = await queryManager.GetLocalizedPathAsync("\\source_1\\"); + Assert.AreEqual("source_1_localized", result); + } + + [Test] + public async Task GetNumberOfFilesAsyncTest() + { + var result = await queryManager.GetNumberOfFilesAsync(); + Assert.AreEqual(3, result); + } + + [Test] + public async Task GetTotalFileSizeAsyncTest() + { + var result = await queryManager.GetTotalFileSizeAsync(); + Assert.AreEqual(300d, result); + } +}