diff --git a/Core/Assets/ErrorMessages.Designer.cs b/Core/Assets/ErrorMessages.Designer.cs
new file mode 100644
index 0000000..9449e1b
--- /dev/null
+++ b/Core/Assets/ErrorMessages.Designer.cs
@@ -0,0 +1,242 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace TagHierarchyManager.Assets {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class ErrorMessages {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal ErrorMessages() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TagHierarchyManager.Assets.ErrorMessages", typeof(ErrorMessages).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Excessive indent was detected at line {0}..
+ ///
+ internal static string ImporterMusicBeeIndentExcessive {
+ get {
+ return ResourceManager.GetString("ImporterMusicBeeIndentExcessive", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Uneven indent was found at line {0}..
+ ///
+ internal static string ImporterMusicBeeIndentUneven {
+ get {
+ return ResourceManager.GetString("ImporterMusicBeeIndentUneven", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Process exited abruptly due to an error with handling the indent. (current line's indent level was greater than the amount of tags in the parent stack).
+ ///
+ internal static string ImporterMusicBeePopOutOfRange {
+ get {
+ return ResourceManager.GetString("ImporterMusicBeePopOutOfRange", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Tag hierarchy starts with a space, which is not valid for a tag hierarchy template's structure..
+ ///
+ internal static string ImporterMusicBeeStartsWithSpace {
+ get {
+ return ResourceManager.GetString("ImporterMusicBeeStartsWithSpace", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Tab characters were detected, which is an invalid structure for MusicBee tag hierarchy templates..
+ ///
+ internal static string ImporterMusicBeeTabsDetected {
+ get {
+ return ResourceManager.GetString("ImporterMusicBeeTabsDetected", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to This setting is required and cannot be deleted..
+ ///
+ internal static string TagDatabaseDeletingRequiredSetting {
+ get {
+ return ResourceManager.GetString("TagDatabaseDeletingRequiredSetting", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to No usable parameters received..
+ ///
+ internal static string TagDatabaseEmptyParameters {
+ get {
+ return ResourceManager.GetString("TagDatabaseEmptyParameters", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to File path cannot be empty..
+ ///
+ internal static string TagDatabaseFilePathEmpty {
+ get {
+ return ResourceManager.GetString("TagDatabaseFilePathEmpty", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to This is not a valid SQLite database..
+ ///
+ internal static string TagDatabaseInvalidFile {
+ get {
+ return ResourceManager.GetString("TagDatabaseInvalidFile", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to File extension must be .thdb..
+ ///
+ internal static string TagDatabaseInvalidFileExt {
+ get {
+ return ResourceManager.GetString("TagDatabaseInvalidFileExt", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to This is not a valid database file for the Tag Hierarchy Manager application..
+ ///
+ internal static string TagDatabaseInvalidStructure {
+ get {
+ return ResourceManager.GetString("TagDatabaseInvalidStructure", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The tag hierarchy database has not been initialised..
+ ///
+ internal static string TagDatabaseNotInitialised {
+ get {
+ return ResourceManager.GetString("TagDatabaseNotInitialised", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Setting {0} already exists in the database..
+ ///
+ internal static string TagDatabaseSettingKeyExists {
+ get {
+ return ResourceManager.GetString("TagDatabaseSettingKeyExists", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Setting {0} was not found in the settings table..
+ ///
+ internal static string TagDatabaseSettingKeyNotFound {
+ get {
+ return ResourceManager.GetString("TagDatabaseSettingKeyNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot execute function on database due to SQLite error. Error code: {0}.
+ ///
+ internal static string TagDatabaseSqliteGeneric {
+ get {
+ return ResourceManager.GetString("TagDatabaseSqliteGeneric", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The tag requested has child tags and cannot currently be deleted. Delete its children first and try again..
+ ///
+ internal static string TagDatabaseTagHasChildren {
+ get {
+ return ResourceManager.GetString("TagDatabaseTagHasChildren", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The tag requested does not exist in the database..
+ ///
+ internal static string TagDatabaseTagNotFound {
+ get {
+ return ResourceManager.GetString("TagDatabaseTagNotFound", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Tag {0} has no parents specified and is not top-level, which is invalid..
+ ///
+ internal static string TagNameIsBlank {
+ get {
+ return ResourceManager.GetString("TagNameIsBlank", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Tag {0} has no parents specified and is not top-level, which is invalid..
+ ///
+ internal static string TagOrphanAttempt {
+ get {
+ return ResourceManager.GetString("TagOrphanAttempt", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Tag {0} has itself in Parents, which is invalid..
+ ///
+ internal static string TagSelfParentAttempt {
+ get {
+ return ResourceManager.GetString("TagSelfParentAttempt", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/Core/Assets/ErrorMessages.resx b/Core/Assets/ErrorMessages.resx
new file mode 100644
index 0000000..eb587b7
--- /dev/null
+++ b/Core/Assets/ErrorMessages.resx
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Tag {0} has itself in Parents, which is invalid.
+
+
+ Tag {0} has no parents specified and is not top-level, which is invalid.
+
+
+ Tag {0} has no parents specified and is not top-level, which is invalid.
+
+
+ This is not a valid SQLite database.
+
+
+ This is not a valid database file for the Tag Hierarchy Manager application.
+
+
+ File extension must be .thdb.
+
+
+ The tag hierarchy database has not been initialised.
+
+
+ No usable parameters received.
+
+
+ File path cannot be empty.
+
+
+ This setting is required and cannot be deleted.
+
+
+
+ The tag requested has child tags and cannot currently be deleted. Delete its children first and try again.
+
+
+ The tag requested does not exist in the database.
+
+
+ Setting {0} already exists in the database.
+
+
+ Setting {0} was not found in the settings table.
+
+
+ Cannot execute function on database due to SQLite error. Error code: {0}
+
+
+ Excessive indent was detected at line {0}.
+
+
+ Uneven indent was found at line {0}.
+
+
+ Process exited abruptly due to an error with handling the indent. (current line's indent level was greater than the amount of tags in the parent stack)
+
+
+ Tag hierarchy starts with a space, which is not valid for a tag hierarchy template's structure.
+
+
+ Tab characters were detected, which is an invalid structure for MusicBee tag hierarchy templates.
+
+
+
\ No newline at end of file
diff --git a/Core/ErrorMessages.cs b/Core/ErrorMessages.cs
index 77e92d8..6d7a630 100644
--- a/Core/ErrorMessages.cs
+++ b/Core/ErrorMessages.cs
@@ -1,104 +1,3 @@
using TagHierarchyManager.Models;
namespace TagHierarchyManager;
-
-// TODO Migrate to RESX
-///
-/// A static class storing error message strings for use when showing errors or throwing exceptions.
-/// Some classes can have their own error message classes for more specific messages, this is intended for error
-/// messages that are used by multiple classes or do not fit into a specific class.
-///
-public static class ErrorMessages
-{
- ///
- /// Indicates an attempt to load a file that is not a valid SQLite database.
- ///
- public const string DbFileNotValid = "This is not a valid SQLite database file.";
-
- ///
- /// Indicates an attempt to use a that has not been fully initialised yet.
- ///
- public const string DbNotInitialised = "The tag hierarchy database has not been initialised.";
-
- ///
- /// Indicates an attempt to load a database with a structure that doesn't match what the application expects.
- ///
- public const string DbNotValid = "This is not a valid database file for the Tag Hierarchy Manager application.";
-
- ///
- /// Indicates no parameters being received in a method.
- ///
- public const string EmptyParameters = "No usable parameters received.";
-
- ///
- /// Indicates an attempt to send an empty file path.
- ///
- public const string FilePathIsEmpty = "File path cannot be empty.";
-
- ///
- /// Indicates an attempt to load a file that does not exist, when loading a .
- ///
- public const string FilePathNotFound = "No file exists at the specified path.";
-
- ///
- /// Indicates an attempt to save to/load a file with an extension other than .thdb.
- ///
- public const string InvalidFileExtension = "File extension must be .thdb.";
-
- // Settings
- ///
- /// Indicates an attempt to delete a setting that is required.
- ///
- public const string SettingIsRequired = "This setting is required and cannot be deleted.";
-
- ///
- /// Indicates that the specified tag cannot be deleted since it has child tags.
- ///
- public const string TagHasChildren =
- "The tag requested has child tags and cannot currently be deleted. Delete its children first and try again.";
-
- ///
- /// Indicates that the specified tag doesn't exist in the database.
- ///
- public const string TagNotFound = "The tag requested does not exist in the database.";
-
- ///
- /// Generates a string indicating that the specified setting already exists in the .
- ///
- /// The specified setting key.
- /// A string indicating the setting already exists.
- public static string SettingKeyAlreadyExists(string key)
- {
- return $"Setting {key} already exists in the database.";
- }
-
- ///
- /// Generates a string indicating that the specified setting does not exist in the .
- ///
- /// The specified setting key.
- /// A string indicating the setting does not exist.
- public static string SettingKeyNotFound(string key)
- {
- return $"The setting key \"{key}\" was not found in the settings table.";
- }
-
- ///
- /// Method to construct a string for generic errors from SQLite.
- ///
- /// The SQLite error code.
- /// A string indicating that the database couldn't be loaded due to an error in SQLite.
- public static string SqliteGenericWithCode(int errorCode)
- {
- return $"Cannot load database due to an a SQLite error. Error code: {errorCode}";
- }
-
- ///
- /// Method to construct a string for when attempting to save a new tag that already exists into the TagDatabase.
- ///
- /// The offending name of the tag.
- /// A string indicating that the specified tag already exists in the TagDatabase.
- public static string TagAlreadyExists(string tagName)
- {
- return $"Tag \"{tagName}\" already exists in the database.";
- }
-}
\ No newline at end of file
diff --git a/Core/Importers/MusicBeeTagHierarchyImporter/MusicBeeTagHierarchyImporter.cs b/Core/Importers/MusicBeeTagHierarchyImporter.cs
similarity index 93%
rename from Core/Importers/MusicBeeTagHierarchyImporter/MusicBeeTagHierarchyImporter.cs
rename to Core/Importers/MusicBeeTagHierarchyImporter.cs
index c9dcdef..235460b 100644
--- a/Core/Importers/MusicBeeTagHierarchyImporter/MusicBeeTagHierarchyImporter.cs
+++ b/Core/Importers/MusicBeeTagHierarchyImporter.cs
@@ -1,3 +1,4 @@
+using TagHierarchyManager.Assets;
using TagHierarchyManager.Common;
using TagHierarchyManager.Models;
@@ -6,7 +7,7 @@ namespace TagHierarchyManager.Importers;
/// Implements an importer for converting a MusicBee tag hierarchy template to a Dictionary of s.
///
/// TODO add manual intervention for tags with duplicate names.
-public partial class MusicBeeTagHierarchyImporter : Importer
+public class MusicBeeTagHierarchyImporter : Importer
{
private const int IndentSize = 4; // MusicBee is strict about having an indent size of 4 spaces.
private const string TagBindingSeparator = "::";
@@ -78,7 +79,7 @@ public partial class MusicBeeTagHierarchyImporter : Importer
{
if (currentLine.IndentLevel - previousIndent > 1)
throw new ArgumentException(
- ErrorMessages.TagHierarchyIndentIsExcessive(currentLine.LineNumber));
+ string.Format(ErrorMessages.ImporterMusicBeeIndentExcessive, currentLine.LineNumber));
if (!string.IsNullOrEmpty(parentName)) parentStack.Add(parentName);
}
@@ -87,16 +88,16 @@ public partial class MusicBeeTagHierarchyImporter : Importer
if (currentLine.IndentLevel <= parentStack.Count)
parentStack.RemoveRange(currentLine.IndentLevel, parentStack.Count - currentLine.IndentLevel);
else
- throw new InvalidOperationException(ErrorMessages.TagHierarchyPopAttemptOutOfRange);
+ throw new InvalidOperationException(ErrorMessages.ImporterMusicBeePopOutOfRange);
}
}
private static void ValidateHierarchyData(string tagHierarchyData)
{
// TODO change on the fly instead of erroring out?
- if (tagHierarchyData.Contains('\t')) throw new ArgumentException(ErrorMessages.TagHierarchyTabsDetected);
+ if (tagHierarchyData.Contains('\t')) throw new ArgumentException(ErrorMessages.ImporterMusicBeeTabsDetected);
- if (tagHierarchyData.StartsWith(' ')) throw new ArgumentException(ErrorMessages.TagHierarchyStartsWithSpace);
+ if (tagHierarchyData.StartsWith(' ')) throw new ArgumentException(ErrorMessages.ImporterMusicBeeStartsWithSpace);
}
private static void ImportTag(Dictionary importDict, TagHierarchyLine line, List parentStack)
@@ -158,7 +159,7 @@ public partial class MusicBeeTagHierarchyImporter : Importer
int indentRemainder = (line.Length - trimmedLine.Length) % IndentSize;
if (indentRemainder != 0)
throw new ArgumentException(
- ErrorMessages.TagHierarchyIndentIsUneven(lineCounter));
+ string.Format(ErrorMessages.ImporterMusicBeeIndentUneven, lineCounter));
this.IndentLevel = (line.Length - trimmedLine.Length) / IndentSize;
}
diff --git a/Core/Importers/MusicBeeTagHierarchyImporter/ErrorMessages.cs b/Core/Importers/MusicBeeTagHierarchyImporter/ErrorMessages.cs
deleted file mode 100644
index 0782726..0000000
--- a/Core/Importers/MusicBeeTagHierarchyImporter/ErrorMessages.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-namespace TagHierarchyManager.Importers;
-
-public partial class MusicBeeTagHierarchyImporter
-{
- ///
- /// A class storing error messages for exceptions.
- ///
- public static class ErrorMessages
- {
- ///
- /// Indicates that an excessive amount of indents was detected in the tag hierarchy template, with a
- /// placeholder for the line number.
- ///
- public const string IndentIsExcessiveTemplate =
- "Excessive indent was detected at line {0}.";
-
- ///
- /// Indicates that an uneven amount of indents was detected in the tag hierarchy template, with a
- /// placeholder for the line number.
- ///
- public const string IndentIsUnevenTemplate =
- "Uneven indent was found at line {0}.";
-
- ///
- /// Indicates an attempt to remove a parent tag from the parent stack resulting in an Exception.
- ///
- public const string TagHierarchyPopAttemptOutOfRange =
- "Process exited abruptly due to an error with handling the indent. (current line's indent level was greater than the amount of tags in the parent stack)";
-
- ///
- /// Indicates that a space character was detected at the beginning of the tag hierarchy template.
- ///
- public const string TagHierarchyStartsWithSpace =
- "Tag hierarchy starts with a space, which is not valid for a tag hierarchy template's structure.";
-
- ///
- /// Indicates that a tab character was detected in tag hierarchy template.
- ///
- public const string TagHierarchyTabsDetected =
- "Tab characters were detected, which is an invalid structure for MusicBee tag hierarchy templates.";
-
- ///
- /// Constructs a string indicating an excessive amount of indents in the tag hierarchy template.
- ///
- /// The offending line number of the template.
- /// A string stating that an excessive amount of indents was found at a particular given line.
- public static string TagHierarchyIndentIsExcessive(int lineNumber)
- {
- return string.Format(IndentIsExcessiveTemplate, lineNumber);
- }
-
- ///
- /// Constructs a string indicating an uneven indent in the tag hierarchy template.
- ///
- /// The offending line number of the template.
- /// A formatted string stating that an uneven indent was found at a particular given line.
- public static string TagHierarchyIndentIsUneven(int lineNumber)
- {
- return string.Format(IndentIsUnevenTemplate, lineNumber);
- }
- }
-}
\ No newline at end of file
diff --git a/Core/Models/Tag/Tag.ErrorMessages.cs b/Core/Models/Tag/Tag.ErrorMessages.cs
deleted file mode 100644
index c28d130..0000000
--- a/Core/Models/Tag/Tag.ErrorMessages.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-namespace TagHierarchyManager.Models;
-
-// TODO migrate to RESX
-public partial class Tag
-{
- ///
- /// Error messages associated with the Tag object.
- ///
- public static class ErrorMessages
- {
- ///
- /// Constructs a string indicating an attempt to make a tag a parent of itself.
- ///
- /// The name of the offending Tag object.
- ///
- /// An error message string indicating that the tag has itself in Parents (id) or ParentNames (name).
- ///
- public static string MakingSelfParentAttempt(string name)
- {
- return $"Tag '{name}' has itself in Parents or ParentNames, which is invalid.";
- }
-
- ///
- /// Constructs a string indicating that a specified tag is an orphan.
- ///
- /// The name of the offending Tag object.
- /// A string indicating that the tag has no parents specified and can't be top level.
- public static string OrphanTagAttempt(string name)
- {
- return $"Tag '{name}' has no parents specified, so cannot be non-top-level.";
- }
- }
-}
\ No newline at end of file
diff --git a/Core/Models/Tag/Tag.cs b/Core/Models/Tag/Tag.cs
index 1c7c1d4..19ecbd3 100644
--- a/Core/Models/Tag/Tag.cs
+++ b/Core/Models/Tag/Tag.cs
@@ -1,3 +1,5 @@
+using TagHierarchyManager.Assets;
+
namespace TagHierarchyManager.Models;
///
@@ -79,13 +81,17 @@ public partial class Tag
public bool Validate()
{
if (string.IsNullOrWhiteSpace(this.Name))
- throw new TagValidationException("Tag name cannot be blank.");
+ throw new TagValidationException(ErrorMessages.TagNameIsBlank);
if (!this.IsTopLevel && this.ParentIds.Count == 0 && this.Parents.Count == 0)
- throw new TagValidationException(ErrorMessages.OrphanTagAttempt(this.Name));
+ throw new TagValidationException(
+ string.Format(ErrorMessages.TagOrphanAttempt, this.Name)
+ );
if (this.Parents.Contains(this.Name) || this.ParentIds.Contains(this.Id))
- throw new TagValidationException(ErrorMessages.MakingSelfParentAttempt(this.Name));
+ throw new TagValidationException(
+ string.Format(ErrorMessages.TagSelfParentAttempt, this.Name)
+ );
return true;
}
diff --git a/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs b/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs
index 0028e8d..84967d9 100644
--- a/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs
+++ b/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs
@@ -1,5 +1,6 @@
using System.Diagnostics;
using Microsoft.Data.Sqlite;
+using TagHierarchyManager.Assets;
namespace TagHierarchyManager.Models;
@@ -98,9 +99,9 @@ partial class TagDatabase
private void PerformDeletionChecks(Tag? targetTag)
{
- if (targetTag is null) throw new ArgumentException(ErrorMessages.TagNotFound);
+ if (targetTag is null) throw new ArgumentException(ErrorMessages.TagDatabaseTagNotFound);
if (this.GetTagChildren(targetTag.Id).Count > 0)
- throw new InvalidOperationException(ErrorMessages.TagHasChildren);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseTagHasChildren);
}
}
\ No newline at end of file
diff --git a/Core/Models/TagDatabase/TagDatabase.ImportMethods.cs b/Core/Models/TagDatabase/TagDatabase.ImportMethods.cs
index bdca1bf..5d7b0a3 100644
--- a/Core/Models/TagDatabase/TagDatabase.ImportMethods.cs
+++ b/Core/Models/TagDatabase/TagDatabase.ImportMethods.cs
@@ -1,4 +1,5 @@
using Microsoft.Data.Sqlite;
+using TagHierarchyManager.Assets;
using TagHierarchyManager.Utilities;
namespace TagHierarchyManager.Models;
@@ -8,7 +9,7 @@ public partial class TagDatabase
private async Task ImportAsync(Dictionary importDict)
{
if (this.currentConnection is null)
- throw new InvalidOperationException(ErrorMessages.DbNotInitialised);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseNotInitialised);
await using SqliteTransaction transaction =
(SqliteTransaction)await this.currentConnection.BeginTransactionAsync().ConfigureAwait(false);
@@ -30,7 +31,7 @@ public partial class TagDatabase
//currentTag = currentTagList[0];
}
if (currentTag is null)
- throw new InvalidOperationException(ErrorMessages.TagNotFound);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseTagNotFound);
// todo search parent here then save the parents.
await this.SaveTagParents(transaction, currentTag.Id, tag.Parents, currentTag).ConfigureAwait(false);
}
@@ -48,7 +49,7 @@ public partial class TagDatabase
private async Task WriteImportedTagToDatabase(SqliteTransaction transaction, ImportedTag tag)
{
if (this.currentConnection is null)
- throw new InvalidOperationException(ErrorMessages.DbNotInitialised);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseNotInitialised);
SqliteCommand addCommand = this.currentConnection.CreateCommand();
addCommand.Transaction = transaction;
diff --git a/Core/Models/TagDatabase/TagDatabase.Initialisation.cs b/Core/Models/TagDatabase/TagDatabase.Initialisation.cs
index 43df686..c40a16e 100644
--- a/Core/Models/TagDatabase/TagDatabase.Initialisation.cs
+++ b/Core/Models/TagDatabase/TagDatabase.Initialisation.cs
@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using Microsoft.Data.Sqlite;
+using TagHierarchyManager.Assets;
namespace TagHierarchyManager.Models;
@@ -24,7 +25,7 @@ public partial class TagDatabase
private void CheckInitialisation()
{
if (!this.Initialised || this.currentConnection is null || this.Connection is null)
- throw new InvalidOperationException(ErrorMessages.DbNotInitialised);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseNotInitialised);
}
///
@@ -66,12 +67,12 @@ public partial class TagDatabase
{
if (filePath == InMemoryDbPath) return null;
- if (string.IsNullOrEmpty(filePath)) return ErrorMessages.FilePathIsEmpty;
+ if (string.IsNullOrWhiteSpace(filePath)) throw new ArgumentException(ErrorMessages.TagDatabaseFilePathEmpty);
string fileExt = Path.GetExtension(filePath);
- if (fileExt != TagHierarchyDbFileExt) return ErrorMessages.InvalidFileExtension;
+ if (fileExt != TagHierarchyDbFileExt) throw new ArgumentException(ErrorMessages.TagDatabaseInvalidFileExt);
- if (loadMode && !File.Exists(filePath)) return ErrorMessages.FilePathNotFound;
+ if (loadMode && !File.Exists(filePath)) throw new FileNotFoundException(null, filePath);
return null;
}
@@ -83,11 +84,7 @@ public partial class TagDatabase
{
if (overwrite && File.Exists(filePath)) File.Delete(filePath);
- string? errorString = ValidateFilePath(filePath);
- if (errorString is not null)
- {
- throw new ArgumentException(errorString);
- }
+ ValidateFilePath(filePath);
this.currentConnection = new SqliteConnection($"Data Source={filePath};Pooling=False");
@@ -164,7 +161,7 @@ public partial class TagDatabase
{
this.Logger.Information("[TagHierarchyDatabase.Initialise] Initialising...");
SqliteCommand command = this.currentConnection?.CreateCommand() ??
- throw new InvalidOperationException(ErrorMessages.DbNotInitialised);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseNotInitialised);
command.CommandText = "SELECT * FROM SETTINGS;";
try
{
@@ -278,14 +275,14 @@ public partial class TagDatabase
if (notTagDatabase)
{
this.Close();
- throw new ArgumentException(ErrorMessages.DbNotValid);
+ throw new ArgumentException(ErrorMessages.TagDatabaseInvalidStructure);
}
}
catch (SqliteException ex)
{
this.Close();
if (ex.SqliteErrorCode == 1)
- throw new ArgumentException(ErrorMessages.DbNotValid);
+ throw new ArgumentException(ErrorMessages.TagDatabaseInvalidStructure);
throw;
}
@@ -302,14 +299,14 @@ public partial class TagDatabase
CultureInfo.InvariantCulture);
if (schemaVersion == 0)
{
- throw new ArgumentException(ErrorMessages.DbFileNotValid);
+ throw new ArgumentException(ErrorMessages.TagDatabaseInvalidFile);
}
}
catch (SqliteException ex)
{
this.Close();
if (ex.SqliteErrorCode == 26)
- throw new ArgumentException(ErrorMessages.DbFileNotValid);
+ throw new ArgumentException(ErrorMessages.TagDatabaseInvalidFile);
throw;
}
diff --git a/Core/Models/TagDatabase/TagDatabase.Migration.cs b/Core/Models/TagDatabase/TagDatabase.Migration.cs
index 77888cf..6aee9b4 100644
--- a/Core/Models/TagDatabase/TagDatabase.Migration.cs
+++ b/Core/Models/TagDatabase/TagDatabase.Migration.cs
@@ -1,4 +1,5 @@
using Microsoft.Data.Sqlite;
+using TagHierarchyManager.Assets;
namespace TagHierarchyManager.Models;
@@ -11,7 +12,7 @@ public partial class TagDatabase
private async Task PerformNeededMigrations()
{
if (this.currentConnection is null)
- throw new InvalidOperationException(ErrorMessages.DbNotInitialised);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseNotInitialised);
var transaction =
(SqliteTransaction)
await this.currentConnection.BeginTransactionAsync().ConfigureAwait(false);
@@ -36,7 +37,7 @@ public partial class TagDatabase
updateModifiedCommand.ExecuteNonQuery();
var deleteOldTableCommand = this.currentConnection.CreateCommand() ??
- throw new InvalidOperationException(ErrorMessages.DbNotInitialised);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseNotInitialised);
deleteOldTableCommand.Transaction = transaction;
deleteOldTableCommand.CommandText =
"DROP TABLE alias;";
diff --git a/Core/Models/TagDatabase/TagDatabase.QueryProcessorHandler.cs b/Core/Models/TagDatabase/TagDatabase.QueryProcessorHandler.cs
index 7315f2b..1779ee6 100644
--- a/Core/Models/TagDatabase/TagDatabase.QueryProcessorHandler.cs
+++ b/Core/Models/TagDatabase/TagDatabase.QueryProcessorHandler.cs
@@ -1,4 +1,5 @@
using Microsoft.Data.Sqlite;
+using TagHierarchyManager.Assets;
namespace TagHierarchyManager.Models;
@@ -79,7 +80,7 @@ public partial class TagDatabase
private static void ProcessTagParentSelectionInt(SqliteCommand command, int id)
{
if (id == 0)
- throw new ArgumentException(ErrorMessages.EmptyParameters);
+ throw new ArgumentException(ErrorMessages.TagDatabaseEmptyParameters);
command.CommandText = TagParentSelectionBaseCommand;
command.Parameters.AddWithValue("@target_id", id);
diff --git a/Core/Models/TagDatabase/TagDatabase.SettingsHandler.cs b/Core/Models/TagDatabase/TagDatabase.SettingsHandler.cs
index 6fc8c17..0d0ecb8 100644
--- a/Core/Models/TagDatabase/TagDatabase.SettingsHandler.cs
+++ b/Core/Models/TagDatabase/TagDatabase.SettingsHandler.cs
@@ -1,5 +1,6 @@
using System.Globalization;
using Microsoft.Data.Sqlite;
+using TagHierarchyManager.Assets;
namespace TagHierarchyManager.Models;
@@ -49,7 +50,7 @@ public partial class TagDatabase
db.CheckInitialisation();
if (await this.CheckSettingExistenceAsync(key).ConfigureAwait(false))
- throw new ArgumentException(ErrorMessages.SettingKeyAlreadyExists(key));
+ throw new ArgumentException(string.Format(ErrorMessages.TagDatabaseSettingKeyExists, key));
SqliteCommand insertCommand = db.Connection.CreateCommand();
insertCommand.CommandText = $"""
@@ -74,10 +75,10 @@ public partial class TagDatabase
db.CheckInitialisation();
if (RequiredSettingsKeys.Contains(key))
- throw new InvalidOperationException(ErrorMessages.SettingIsRequired);
+ throw new InvalidOperationException(ErrorMessages.TagDatabaseDeletingRequiredSetting);
if (!await this.CheckSettingExistenceAsync(key).ConfigureAwait(false))
- throw new KeyNotFoundException(ErrorMessages.SettingKeyNotFound(key));
+ throw new KeyNotFoundException(string.Format(ErrorMessages.TagDatabaseSettingKeyNotFound, key));
SqliteCommand command = db.Connection.CreateCommand();
command.CommandText = $"""
DELETE FROM settings
@@ -120,7 +121,7 @@ public partial class TagDatabase
db.CheckInitialisation();
if (!await this.CheckSettingExistenceAsync(key).ConfigureAwait(false))
- throw new KeyNotFoundException(ErrorMessages.SettingKeyNotFound(key));
+ throw new KeyNotFoundException(string.Format(ErrorMessages.TagDatabaseSettingKeyNotFound, key));
SqliteCommand command = db.Connection.CreateCommand();
command.CommandText = $"""
SELECT value FROM settings
@@ -153,7 +154,7 @@ public partial class TagDatabase
db.CheckInitialisation();
if (!await this.CheckSettingExistenceAsync(key).ConfigureAwait(false))
- throw new KeyNotFoundException(ErrorMessages.SettingKeyNotFound(key));
+ throw new KeyNotFoundException(string.Format(ErrorMessages.TagDatabaseSettingKeyNotFound, key));
SqliteCommand command = db.Connection.CreateCommand();
command.CommandText = $"""
UPDATE settings
diff --git a/Core/TagHierarchyManager.csproj b/Core/TagHierarchyManager.csproj
index 7dcc757..0526602 100644
--- a/Core/TagHierarchyManager.csproj
+++ b/Core/TagHierarchyManager.csproj
@@ -15,4 +15,19 @@
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+ True
+ True
+ ErrorMessages.resx
+
+
+
diff --git a/Tests/ImporterTests.cs b/Tests/ImporterTests.cs
index 8373001..c04b85b 100644
--- a/Tests/ImporterTests.cs
+++ b/Tests/ImporterTests.cs
@@ -79,7 +79,6 @@ public class ImporterTests : TestBase
/// that starts with a space.
///
/// The string to attempt to send to the importer.
- /// The expected error message.
[Test]
[TestCase(
#pragma warning disable SA1027
@@ -87,10 +86,9 @@ public class ImporterTests : TestBase
Ambient
Ambient::genre
Ambient::style
- """, MusicBeeTagHierarchyImporter.ErrorMessages.TagHierarchyTabsDetected)]
- [TestCase(" Ambient", MusicBeeTagHierarchyImporter.ErrorMessages.TagHierarchyStartsWithSpace)]
- public async Task ImportAsync_ImportMusicBeeTagHierarchy_ArgumentExceptionThrown(string brokenHierarchy,
- string exceptionMessage)
+ """)]
+ [TestCase(" Ambient")]
+ public async Task ImportAsync_ImportMusicBeeTagHierarchy_ArgumentExceptionThrown(string brokenHierarchy)
{
string tempFilePath = Path.GetTempFileName();
await File.WriteAllTextAsync(tempFilePath, brokenHierarchy);
@@ -98,7 +96,6 @@ public class ImporterTests : TestBase
Importer importer = new MusicBeeTagHierarchyImporter();
Exception? ex =
Assert.ThrowsAsync(async () => await importer.ImportFromFileAsync(tempFilePath));
- Assert.That(ex!.Message, Is.EqualTo(exceptionMessage));
}
///
@@ -108,30 +105,26 @@ public class ImporterTests : TestBase
///
/// The string to attempt to send to the importer.
/// The line number to be expected.
- /// The expected error message template.
[Test]
[TestCase(
"""
Ambient
Ambient::genre
Ambient::style
- """, 2, MusicBeeTagHierarchyImporter.ErrorMessages.IndentIsUnevenTemplate)]
+ """, 2)]
[TestCase(
"""
Ambient
Ambient::genre
Ambient::style
- """, 2, MusicBeeTagHierarchyImporter.ErrorMessages.IndentIsExcessiveTemplate)]
+ """, 2)]
public async Task ImportAsync_ImportMusicBeeTagHierarchy_TagHierarchyDataExceptionThrown(string brokenHierarchy,
- int lineNumber, string exceptionMessage)
+ int lineNumber)
{
- // Arrange
- string expectedExceptionMessage = string.Format(exceptionMessage, lineNumber);
string tempFilePath = Path.GetTempFileName();
await File.WriteAllTextAsync(tempFilePath, brokenHierarchy);
Importer importer = new MusicBeeTagHierarchyImporter();
Exception? ex =
Assert.ThrowsAsync(async () => await importer.ImportFromFileAsync(tempFilePath));
- Assert.That(ex!.Message, Is.EqualTo(expectedExceptionMessage));
}
}
\ No newline at end of file
diff --git a/Tests/SettingsTests.cs b/Tests/SettingsTests.cs
index c5a776a..eca21ca 100644
--- a/Tests/SettingsTests.cs
+++ b/Tests/SettingsTests.cs
@@ -41,7 +41,6 @@ public class SettingsTests : TestBase
// Act/Assert
ArgumentException ex = Assert.ThrowsAsync(async () =>
await this.Database.Settings.CreateSettingAsync(AddedTestKey, AddedTestValue)) !;
- Assert.That(ex.Message, Is.EqualTo(ErrorMessages.SettingKeyAlreadyExists(AddedTestKey)));
}
///
@@ -56,7 +55,7 @@ public class SettingsTests : TestBase
List changedTagBindings = ["genre", "album genre"];
// Act
- this.Database.DefaultTagBindings = changedTagBindings;
+ await this.Database.SetDefaultTagBindingsAsync(changedTagBindings);
// Assert
string? settingValueString = await this.Database.Settings.GetSettingValueAsync(ExpectedTagBindKey);
@@ -105,7 +104,6 @@ public class SettingsTests : TestBase
{
KeyNotFoundException ex = Assert.ThrowsAsync(async () =>
await this.Database.Settings.DeleteSettingAsync(NonExistentKey)) !;
- Assert.That(ex.Message, Is.EqualTo(ErrorMessages.SettingKeyNotFound(NonExistentKey)));
}
///
@@ -180,7 +178,6 @@ public class SettingsTests : TestBase
{
KeyNotFoundException? ex = Assert.ThrowsAsync(async () =>
await this.Database.Settings.UpdateSettingAsync(NonExistentKey, "testvalue"));
- Assert.That(ex!.Message, Is.EqualTo(ErrorMessages.SettingKeyNotFound(NonExistentKey)));
}
///
diff --git a/Tests/TagDatabaseInitTests.cs b/Tests/TagDatabaseInitTests.cs
index 3b9f30f..80936ae 100644
--- a/Tests/TagDatabaseInitTests.cs
+++ b/Tests/TagDatabaseInitTests.cs
@@ -41,10 +41,9 @@ public class TagDatabaseInitTests : TestBase
}
TagDatabase dummyDb = new();
- Exception? ex = Assert.ThrowsAsync(async () => await dummyDb.LoadAsync(invalidDbPath));
-
+
// Act/Assert
- Assert.That(ex?.Message, Is.EqualTo(ErrorMessages.DbFileNotValid));
+ Exception? ex = Assert.ThrowsAsync(async () => await dummyDb.LoadAsync(invalidDbPath));
}
///
@@ -54,14 +53,12 @@ public class TagDatabaseInitTests : TestBase
/// The expected error message.
/// A representing the asynchronous test.
[Test]
- [TestCase("", ErrorMessages.FilePathIsEmpty)]
- [TestCase("invalid_file.exe", ErrorMessages.InvalidFileExtension)]
- public void TagDatabaseInit_NewTagDatabase_ErrorCaughtFileBased(string fileName, string errorMessage)
+ [TestCase("")]
+ [TestCase("invalid_file.exe")]
+ public void TagDatabaseInit_NewTagDatabase_ErrorCaughtFileBased(string fileName)
{
TagDatabase invalidDb = new();
Exception? ex = Assert.ThrowsAsync(async () => await invalidDb.CreateAsync(fileName));
-
- Assert.That(ex?.Message, Is.EqualTo(errorMessage));
}
///
@@ -82,12 +79,10 @@ public class TagDatabaseInitTests : TestBase
""";
await command.ExecuteNonQueryAsync();
+ // Act/Assert
Exception? ex =
Assert.ThrowsAsync(async () =>
await this.Database.LoadAsync(connection: invalidConnection));
-
- // Act/Assert
- Assert.That(ex?.Message, Is.EqualTo(ErrorMessages.DbNotValid));
}
///
diff --git a/Tests/TagDatabaseSaveTests.cs b/Tests/TagDatabaseSaveTests.cs
index b51cfd1..1b5119f 100644
--- a/Tests/TagDatabaseSaveTests.cs
+++ b/Tests/TagDatabaseSaveTests.cs
@@ -72,7 +72,6 @@ public class TagDatabaseWriteTests : TestBase
{
ArgumentException? exId =
Assert.ThrowsAsync(async () => await this.Database.DeleteTag(1000));
- Assert.That(exId?.Message, Is.EqualTo(ErrorMessages.TagNotFound));
}
///