Skip to content

Commit

Permalink
Storage - Clean up legacy project and refactor repositories to use sh…
Browse files Browse the repository at this point in the history
…ort lived DB contexts
  • Loading branch information
RobertBeekman committed Mar 10, 2024
1 parent d4e4d52 commit 4bae9e8
Show file tree
Hide file tree
Showing 105 changed files with 815 additions and 575 deletions.
2 changes: 1 addition & 1 deletion src/Artemis.Core/Artemis.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<PackageReference Include="EmbedIO" />
<PackageReference Include="HidSharp" />
<PackageReference Include="Humanizer.Core" />
<PackageReference Include="JetBrains.Annotations" />
<PackageReference Include="JetBrains.Annotations" PrivateAssets="All"/>
<PackageReference Include="McMaster.NETCore.Plugins" />
<PackageReference Include="RGB.NET.Core" />
<PackageReference Include="RGB.NET.Layout" />
Expand Down
2 changes: 1 addition & 1 deletion src/Artemis.Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public static class Constants
/// <summary>
/// The plugin used by core components of Artemis
/// </summary>
public static readonly Plugin CorePlugin = new(CorePluginInfo, new DirectoryInfo(ApplicationFolder), new PluginEntity(){Id = CorePluginInfo.Guid}, false);
public static readonly Plugin CorePlugin = new(CorePluginInfo, new DirectoryInfo(ApplicationFolder), new PluginEntity(){PluginGuid = CorePluginInfo.Guid}, false);

/// <summary>
/// A read-only collection containing all primitive numeric types
Expand Down
8 changes: 1 addition & 7 deletions src/Artemis.Core/Plugins/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,7 @@ protected virtual void OnFeatureRemoved(PluginFeatureInfoEventArgs e)
{
FeatureRemoved?.Invoke(this, e);
}

internal void ApplyToEntity()
{
Entity.Id = Guid;
Entity.IsEnabled = IsEnabled;
}


internal void AddFeature(PluginFeatureInfo featureInfo)
{
if (featureInfo.Plugin != this)
Expand Down
2 changes: 1 addition & 1 deletion src/Artemis.Core/Plugins/Settings/PluginSetting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public void Save()
return;

_pluginSettingEntity.Value = CoreJson.Serialize(Value);
_pluginRepository.SaveChanges();
_pluginRepository.SaveSetting(_pluginSettingEntity);
OnSettingSaved();
}

Expand Down
7 changes: 5 additions & 2 deletions src/Artemis.Core/Plugins/Settings/PluginSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ internal PluginSettings(Plugin plugin, IPluginRepository pluginRepository)
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
/// </summary>
/// <typeparam name="T">The type of the setting, can be any serializable type</typeparam>
/// <param name="name">The name of the setting</param>
/// <param name="name">The name of the setting, may not be longer than 128 characters</param>
/// <param name="defaultValue">The default value to use if the setting does not exist yet</param>
public PluginSetting<T> GetSetting<T>(string name, T? defaultValue = default)
{
if (name.Length > 128)
throw new ArtemisCoreException("Setting name cannot be longer than 128 characters");

lock (_settingEntities)
{
// Return cached value if available
Expand All @@ -51,7 +54,7 @@ public PluginSetting<T> GetSetting<T>(string name, T? defaultValue = default)
PluginGuid = Plugin.Guid,
Value = CoreJson.Serialize(defaultValue)
};
_pluginRepository.AddSetting(settingEntity);
_pluginRepository.SaveSetting(settingEntity);
}

PluginSetting<T> pluginSetting = new(_pluginRepository, settingEntity);
Expand Down
8 changes: 4 additions & 4 deletions src/Artemis.Core/Services/DeviceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public void EnableDevice(ArtemisDevice device)
_enabledDevices.Add(device);
device.IsEnabled = true;
device.Save();
_deviceRepository.SaveChanges();
_deviceRepository.Save(device.DeviceEntity);

OnDeviceEnabled(new DeviceEventArgs(device));
UpdateLeds();
Expand All @@ -217,7 +217,7 @@ public void DisableDevice(ArtemisDevice device)
_enabledDevices.Remove(device);
device.IsEnabled = false;
device.Save();
_deviceRepository.SaveChanges();
_deviceRepository.Save(device.DeviceEntity);

OnDeviceDisabled(new DeviceEventArgs(device));
UpdateLeds();
Expand All @@ -227,7 +227,7 @@ public void DisableDevice(ArtemisDevice device)
public void SaveDevice(ArtemisDevice artemisDevice)
{
artemisDevice.Save();
_deviceRepository.SaveChanges();
_deviceRepository.Save(artemisDevice.DeviceEntity);
UpdateLeds();
}

Expand All @@ -236,7 +236,7 @@ public void SaveDevices()
{
foreach (ArtemisDevice artemisDevice in _devices)
artemisDevice.Save();
_deviceRepository.SaveChanges();
_deviceRepository.SaveRange(_devices.Select(d => d.DeviceEntity));
UpdateLeds();
}

Expand Down
8 changes: 4 additions & 4 deletions src/Artemis.Core/Services/PluginManagementService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,12 @@ public void UnloadPlugins()
}

// Load the entity and fall back on creating a new one
PluginEntity? entity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid);
PluginEntity? entity = _pluginRepository.GetPluginByPluginGuid(pluginInfo.Guid);
bool loadedFromStorage = entity != null;
if (entity == null)
{
entity = new PluginEntity {Id = pluginInfo.Guid};
_pluginRepository.AddPlugin(entity);
entity = new PluginEntity {PluginGuid = pluginInfo.Guid};
_pluginRepository.SavePlugin(entity);
}

Plugin plugin = new(pluginInfo, directory, entity, loadedFromStorage);
Expand Down Expand Up @@ -815,7 +815,7 @@ private void SavePlugin(Plugin plugin)
plugin.Entity.Features.Add(featureInfo.Instance!.Entity);
}

_pluginRepository.SaveChanges();
_pluginRepository.SavePlugin(plugin.Entity);
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion src/Artemis.Core/Services/SettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface ISettingsService : IProtectedArtemisService
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
/// </summary>
/// <typeparam name="T">The type of the setting, can be any serializable type</typeparam>
/// <param name="name">The name of the setting</param>
/// <param name="name">The name of the setting, may not be longer than 128 characters</param>
/// <param name="defaultValue">The default value to use if the setting does not exist yet</param>
/// <returns></returns>
PluginSetting<T> GetSetting<T>(string name, T? defaultValue = default);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,7 @@ public interface IProfileService : IArtemisService
/// </summary>
/// <param name="profileConfiguration">The profile configuration of the profile to activate.</param>
void DeactivateProfile(ProfileConfiguration profileConfiguration);

/// <summary>
/// Permanently deletes the profile of the given <see cref="ProfileConfiguration" />.
/// </summary>
/// <param name="profileConfiguration">The profile configuration of the profile to delete.</param>
void DeleteProfile(ProfileConfiguration profileConfiguration);


/// <summary>
/// Saves the provided <see cref="ProfileCategory" /> and it's <see cref="ProfileConfiguration" />s but not the
/// <see cref="Profile" />s themselves.
Expand Down
68 changes: 18 additions & 50 deletions src/Artemis.Core/Services/Storage/ProfileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal class ProfileService : IProfileService
{
private readonly ILogger _logger;
private readonly IProfileCategoryRepository _profileCategoryRepository;
private readonly IProfileRepository _profileRepository;
private readonly IPluginManagementService _pluginManagementService;
private readonly IDeviceService _deviceService;
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
Expand All @@ -34,13 +35,15 @@ internal class ProfileService : IProfileService

public ProfileService(ILogger logger,
IProfileCategoryRepository profileCategoryRepository,
IProfileRepository profileRepository,
IPluginManagementService pluginManagementService,
IInputService inputService,
IDeviceService deviceService,
List<IProfileMigration> profileMigrators)
{
_logger = logger;
_profileCategoryRepository = profileCategoryRepository;
_profileRepository = profileRepository;
_pluginManagementService = pluginManagementService;
_deviceService = deviceService;
_profileMigrators = profileMigrators;
Expand Down Expand Up @@ -214,20 +217,7 @@ private void RequestDeactivation(ProfileConfiguration profileConfiguration)

profileConfiguration.Profile.ShouldDisplay = false;
}

/// <inheritdoc />
public void DeleteProfile(ProfileConfiguration profileConfiguration)
{
DeactivateProfile(profileConfiguration);

ProfileCategory category = profileConfiguration.Category;

category.RemoveProfileConfiguration(profileConfiguration);
category.Entity.ProfileConfigurations.Remove(profileConfiguration.Entity);

_profileCategoryRepository.SaveChanges();
}


/// <inheritdoc />
public ProfileCategory CreateProfileCategory(string name, bool addToTop = false)
{
Expand All @@ -240,6 +230,8 @@ public ProfileCategory CreateProfileCategory(string name, bool addToTop = false)
category.Order++;
category.Save();
}

_profileCategoryRepository.SaveRange(ProfileCategories.Select(c => c.Entity).ToList());
}
else
{
Expand Down Expand Up @@ -274,32 +266,32 @@ public ProfileConfiguration CreateProfileConfiguration(ProfileCategory category,
SaveProfileCategory(category);
return configuration;
}

/// <inheritdoc />
public void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration)
{
DeactivateProfile(profileConfiguration);

ProfileCategory category = profileConfiguration.Category;
category.RemoveProfileConfiguration(profileConfiguration);

DeactivateProfile(profileConfiguration);
SaveProfileCategory(profileConfiguration.Category);
category.RemoveProfileConfiguration(profileConfiguration);
category.Save();

profileConfiguration.Dispose();
_profileRepository.Remove(profileConfiguration.Entity);
_profileCategoryRepository.Save(category.Entity);
}

/// <inheritdoc />
public void SaveProfileCategory(ProfileCategory profileCategory)
{
profileCategory.Save();
_profileCategoryRepository.SaveChanges();
_profileCategoryRepository.Save(profileCategory.Entity);
ProfileCategories = new ReadOnlyCollection<ProfileCategory>(ProfileCategories.OrderBy(c => c.Order).ToList());
}

/// <inheritdoc />
public void SaveProfile(Profile profile, bool includeChildren)
{
Stopwatch sw = new();
sw.Start();
_logger.Debug("Updating profile - Saving {Profile}", profile);
profile.Save();
if (includeChildren)
Expand All @@ -312,25 +304,18 @@ public void SaveProfile(Profile profile, bool includeChildren)
profile.IsFreshImport = false;
profile.ProfileEntity.IsFreshImport = false;

SaveProfileCategory(profile.Configuration.Category);
_profileRepository.Save(profile.Configuration.Entity);

// If the provided profile is external (cloned or from the workshop?) but it is loaded locally too, reload the local instance
// A bit dodge but it ensures local instances always represent the latest stored version
ProfileConfiguration? localInstance = ProfileCategories
.SelectMany(c => c.ProfileConfigurations)
.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id);
if (localInstance == null)
{
sw.Stop();
_logger.Debug("Updated profile - Saved {Profile} in {Time}ms", profile, sw.Elapsed.TotalMilliseconds);
return;
}

DeactivateProfile(localInstance);
ActivateProfile(localInstance);

sw.Stop();
_logger.Debug("Updated profile - Saved {Profile} in {Time}ms", profile, sw.Elapsed.TotalMilliseconds);
}

/// <inheritdoc />
Expand Down Expand Up @@ -393,7 +378,7 @@ public async Task<ProfileConfiguration> ImportProfile(Stream archiveStream, Prof
JsonObject? profileJson = CoreJson.Deserialize<JsonObject>(await profileReader.ReadToEndAsync());

// Before deserializing, apply any pending migrations
MigrateProfile(configurationJson, profileJson);
_profileRepository.MigrateProfile(configurationJson, profileJson);

// Deserialize profile configuration to ProfileConfigurationEntity
ProfileConfigurationEntity? configurationEntity = configurationJson?.Deserialize<ProfileConfigurationEntity>(Constants.JsonConvertSettings);
Expand Down Expand Up @@ -453,7 +438,7 @@ public async Task<ProfileConfiguration> OverwriteProfile(MemoryStream archiveStr
{
ProfileConfiguration imported = await ImportProfile(archiveStream, profileConfiguration.Category, true, true, null, profileConfiguration.Order + 1);

DeleteProfile(profileConfiguration);
RemoveProfileConfiguration(profileConfiguration);
SaveProfileCategory(imported.Category);

return imported;
Expand All @@ -479,24 +464,7 @@ private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEvent
{
_pendingKeyboardEvents.Add(e);
}

private void MigrateProfile(JsonObject? configurationJson, JsonObject? profileJson)
{
if (configurationJson == null || profileJson == null)
return;

configurationJson["Version"] ??= 0;

foreach (IProfileMigration profileMigrator in _profileMigrators.OrderBy(m => m.Version))
{
if (profileMigrator.Version <= configurationJson["Version"]!.GetValue<int>())
continue;

profileMigrator.Migrate(configurationJson, profileJson);
configurationJson["Version"] = profileMigrator.Version;
}
}


/// <summary>
/// Populates all missing LEDs on all currently active profiles
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -13,8 +12,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="LiteDB" Version="5.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<PackageReference Include="LiteDB" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Artemis.Storage.Migrator.Legacy.Entities.General;
namespace Artemis.Storage.Legacy.Entities.General;

public class QueuedActionEntity
internal class QueuedActionEntity
{
public QueuedActionEntity()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Artemis.Storage.Migrator.Legacy.Entities.General;
namespace Artemis.Storage.Legacy.Entities.General;

public class ReleaseEntity
internal class ReleaseEntity
{
public Guid Id { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Artemis.Storage.Migrator.Legacy.Entities.General;
namespace Artemis.Storage.Legacy.Entities.General;

public class ScriptConfigurationEntity
internal class ScriptConfigurationEntity
{
public Guid Id { get; set; }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace Artemis.Storage.Migrator.Legacy.Entities.Plugins;
namespace Artemis.Storage.Legacy.Entities.Plugins;

/// <summary>
/// Represents the configuration of a plugin, each plugin has one configuration
/// </summary>
public class PluginEntity
internal class PluginEntity
{
public PluginEntity()
{
Expand All @@ -19,7 +19,7 @@ public Artemis.Storage.Entities.Plugins.PluginEntity Migrate()
{
return new Artemis.Storage.Entities.Plugins.PluginEntity()
{
Id = Id,
PluginGuid = Id,
IsEnabled = IsEnabled,
Features = Features.Select(f => f.Migrate()).ToList()
};
Expand All @@ -29,7 +29,7 @@ public Artemis.Storage.Entities.Plugins.PluginEntity Migrate()
/// <summary>
/// Represents the configuration of a plugin feature, each feature has one configuration
/// </summary>
public class PluginFeatureEntity
internal class PluginFeatureEntity
{
public string Type { get; set; } = string.Empty;
public bool IsEnabled { get; set; }
Expand Down
Loading

0 comments on commit 4bae9e8

Please sign in to comment.