mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Storage - Clean up legacy project and refactor repositories to use short lived DB contexts
This commit is contained in:
parent
d4e4d52f84
commit
4bae9e89cf
@ -40,7 +40,7 @@
|
|||||||
<PackageReference Include="EmbedIO" />
|
<PackageReference Include="EmbedIO" />
|
||||||
<PackageReference Include="HidSharp" />
|
<PackageReference Include="HidSharp" />
|
||||||
<PackageReference Include="Humanizer.Core" />
|
<PackageReference Include="Humanizer.Core" />
|
||||||
<PackageReference Include="JetBrains.Annotations" />
|
<PackageReference Include="JetBrains.Annotations" PrivateAssets="All"/>
|
||||||
<PackageReference Include="McMaster.NETCore.Plugins" />
|
<PackageReference Include="McMaster.NETCore.Plugins" />
|
||||||
<PackageReference Include="RGB.NET.Core" />
|
<PackageReference Include="RGB.NET.Core" />
|
||||||
<PackageReference Include="RGB.NET.Layout" />
|
<PackageReference Include="RGB.NET.Layout" />
|
||||||
|
|||||||
@ -91,7 +91,7 @@ public static class Constants
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugin used by core components of Artemis
|
/// The plugin used by core components of Artemis
|
||||||
/// </summary>
|
/// </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>
|
/// <summary>
|
||||||
/// A read-only collection containing all primitive numeric types
|
/// A read-only collection containing all primitive numeric types
|
||||||
|
|||||||
@ -309,13 +309,7 @@ public class Plugin : CorePropertyChanged, IDisposable
|
|||||||
{
|
{
|
||||||
FeatureRemoved?.Invoke(this, e);
|
FeatureRemoved?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ApplyToEntity()
|
|
||||||
{
|
|
||||||
Entity.Id = Guid;
|
|
||||||
Entity.IsEnabled = IsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddFeature(PluginFeatureInfo featureInfo)
|
internal void AddFeature(PluginFeatureInfo featureInfo)
|
||||||
{
|
{
|
||||||
if (featureInfo.Plugin != this)
|
if (featureInfo.Plugin != this)
|
||||||
|
|||||||
@ -94,7 +94,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_pluginSettingEntity.Value = CoreJson.Serialize(Value);
|
_pluginSettingEntity.Value = CoreJson.Serialize(Value);
|
||||||
_pluginRepository.SaveChanges();
|
_pluginRepository.SaveSetting(_pluginSettingEntity);
|
||||||
OnSettingSaved();
|
OnSettingSaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,10 +31,13 @@ public class PluginSettings
|
|||||||
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
|
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the setting, can be any serializable type</typeparam>
|
/// <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>
|
/// <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)
|
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)
|
lock (_settingEntities)
|
||||||
{
|
{
|
||||||
// Return cached value if available
|
// Return cached value if available
|
||||||
@ -51,7 +54,7 @@ public class PluginSettings
|
|||||||
PluginGuid = Plugin.Guid,
|
PluginGuid = Plugin.Guid,
|
||||||
Value = CoreJson.Serialize(defaultValue)
|
Value = CoreJson.Serialize(defaultValue)
|
||||||
};
|
};
|
||||||
_pluginRepository.AddSetting(settingEntity);
|
_pluginRepository.SaveSetting(settingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginSetting<T> pluginSetting = new(_pluginRepository, settingEntity);
|
PluginSetting<T> pluginSetting = new(_pluginRepository, settingEntity);
|
||||||
|
|||||||
@ -202,7 +202,7 @@ internal class DeviceService : IDeviceService
|
|||||||
_enabledDevices.Add(device);
|
_enabledDevices.Add(device);
|
||||||
device.IsEnabled = true;
|
device.IsEnabled = true;
|
||||||
device.Save();
|
device.Save();
|
||||||
_deviceRepository.SaveChanges();
|
_deviceRepository.Save(device.DeviceEntity);
|
||||||
|
|
||||||
OnDeviceEnabled(new DeviceEventArgs(device));
|
OnDeviceEnabled(new DeviceEventArgs(device));
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
@ -217,7 +217,7 @@ internal class DeviceService : IDeviceService
|
|||||||
_enabledDevices.Remove(device);
|
_enabledDevices.Remove(device);
|
||||||
device.IsEnabled = false;
|
device.IsEnabled = false;
|
||||||
device.Save();
|
device.Save();
|
||||||
_deviceRepository.SaveChanges();
|
_deviceRepository.Save(device.DeviceEntity);
|
||||||
|
|
||||||
OnDeviceDisabled(new DeviceEventArgs(device));
|
OnDeviceDisabled(new DeviceEventArgs(device));
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
@ -227,7 +227,7 @@ internal class DeviceService : IDeviceService
|
|||||||
public void SaveDevice(ArtemisDevice artemisDevice)
|
public void SaveDevice(ArtemisDevice artemisDevice)
|
||||||
{
|
{
|
||||||
artemisDevice.Save();
|
artemisDevice.Save();
|
||||||
_deviceRepository.SaveChanges();
|
_deviceRepository.Save(artemisDevice.DeviceEntity);
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ internal class DeviceService : IDeviceService
|
|||||||
{
|
{
|
||||||
foreach (ArtemisDevice artemisDevice in _devices)
|
foreach (ArtemisDevice artemisDevice in _devices)
|
||||||
artemisDevice.Save();
|
artemisDevice.Save();
|
||||||
_deviceRepository.SaveChanges();
|
_deviceRepository.SaveRange(_devices.Select(d => d.DeviceEntity));
|
||||||
UpdateLeds();
|
UpdateLeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -372,12 +372,12 @@ internal class PluginManagementService : IPluginManagementService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the entity and fall back on creating a new one
|
// 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;
|
bool loadedFromStorage = entity != null;
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
entity = new PluginEntity {Id = pluginInfo.Guid};
|
entity = new PluginEntity {PluginGuid = pluginInfo.Guid};
|
||||||
_pluginRepository.AddPlugin(entity);
|
_pluginRepository.SavePlugin(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin plugin = new(pluginInfo, directory, entity, loadedFromStorage);
|
Plugin plugin = new(pluginInfo, directory, entity, loadedFromStorage);
|
||||||
@ -815,7 +815,7 @@ internal class PluginManagementService : IPluginManagementService
|
|||||||
plugin.Entity.Features.Add(featureInfo.Instance!.Entity);
|
plugin.Entity.Features.Add(featureInfo.Instance!.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pluginRepository.SaveChanges();
|
_pluginRepository.SavePlugin(plugin.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -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.
|
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the setting, can be any serializable type</typeparam>
|
/// <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>
|
/// <param name="defaultValue">The default value to use if the setting does not exist yet</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
PluginSetting<T> GetSetting<T>(string name, T? defaultValue = default);
|
PluginSetting<T> GetSetting<T>(string name, T? defaultValue = default);
|
||||||
|
|||||||
@ -54,13 +54,7 @@ public interface IProfileService : IArtemisService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="profileConfiguration">The profile configuration of the profile to activate.</param>
|
/// <param name="profileConfiguration">The profile configuration of the profile to activate.</param>
|
||||||
void DeactivateProfile(ProfileConfiguration profileConfiguration);
|
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>
|
/// <summary>
|
||||||
/// Saves the provided <see cref="ProfileCategory" /> and it's <see cref="ProfileConfiguration" />s but not the
|
/// Saves the provided <see cref="ProfileCategory" /> and it's <see cref="ProfileConfiguration" />s but not the
|
||||||
/// <see cref="Profile" />s themselves.
|
/// <see cref="Profile" />s themselves.
|
||||||
|
|||||||
@ -22,6 +22,7 @@ internal class ProfileService : IProfileService
|
|||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IProfileCategoryRepository _profileCategoryRepository;
|
private readonly IProfileCategoryRepository _profileCategoryRepository;
|
||||||
|
private readonly IProfileRepository _profileRepository;
|
||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly IDeviceService _deviceService;
|
private readonly IDeviceService _deviceService;
|
||||||
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
|
private readonly List<ArtemisKeyboardKeyEventArgs> _pendingKeyboardEvents = new();
|
||||||
@ -34,6 +35,7 @@ internal class ProfileService : IProfileService
|
|||||||
|
|
||||||
public ProfileService(ILogger logger,
|
public ProfileService(ILogger logger,
|
||||||
IProfileCategoryRepository profileCategoryRepository,
|
IProfileCategoryRepository profileCategoryRepository,
|
||||||
|
IProfileRepository profileRepository,
|
||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IInputService inputService,
|
IInputService inputService,
|
||||||
IDeviceService deviceService,
|
IDeviceService deviceService,
|
||||||
@ -41,6 +43,7 @@ internal class ProfileService : IProfileService
|
|||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_profileCategoryRepository = profileCategoryRepository;
|
_profileCategoryRepository = profileCategoryRepository;
|
||||||
|
_profileRepository = profileRepository;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_deviceService = deviceService;
|
_deviceService = deviceService;
|
||||||
_profileMigrators = profileMigrators;
|
_profileMigrators = profileMigrators;
|
||||||
@ -214,20 +217,7 @@ internal class ProfileService : IProfileService
|
|||||||
|
|
||||||
profileConfiguration.Profile.ShouldDisplay = false;
|
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 />
|
/// <inheritdoc />
|
||||||
public ProfileCategory CreateProfileCategory(string name, bool addToTop = false)
|
public ProfileCategory CreateProfileCategory(string name, bool addToTop = false)
|
||||||
{
|
{
|
||||||
@ -240,6 +230,8 @@ internal class ProfileService : IProfileService
|
|||||||
category.Order++;
|
category.Order++;
|
||||||
category.Save();
|
category.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_profileCategoryRepository.SaveRange(ProfileCategories.Select(c => c.Entity).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -274,32 +266,32 @@ internal class ProfileService : IProfileService
|
|||||||
SaveProfileCategory(category);
|
SaveProfileCategory(category);
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration)
|
public void RemoveProfileConfiguration(ProfileConfiguration profileConfiguration)
|
||||||
{
|
{
|
||||||
ProfileCategory category = profileConfiguration.Category;
|
|
||||||
category.RemoveProfileConfiguration(profileConfiguration);
|
|
||||||
|
|
||||||
DeactivateProfile(profileConfiguration);
|
DeactivateProfile(profileConfiguration);
|
||||||
SaveProfileCategory(profileConfiguration.Category);
|
|
||||||
|
|
||||||
profileConfiguration.Dispose();
|
ProfileCategory category = profileConfiguration.Category;
|
||||||
|
|
||||||
|
category.RemoveProfileConfiguration(profileConfiguration);
|
||||||
|
category.Save();
|
||||||
|
|
||||||
|
_profileRepository.Remove(profileConfiguration.Entity);
|
||||||
|
_profileCategoryRepository.Save(category.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SaveProfileCategory(ProfileCategory profileCategory)
|
public void SaveProfileCategory(ProfileCategory profileCategory)
|
||||||
{
|
{
|
||||||
profileCategory.Save();
|
profileCategory.Save();
|
||||||
_profileCategoryRepository.SaveChanges();
|
_profileCategoryRepository.Save(profileCategory.Entity);
|
||||||
ProfileCategories = new ReadOnlyCollection<ProfileCategory>(ProfileCategories.OrderBy(c => c.Order).ToList());
|
ProfileCategories = new ReadOnlyCollection<ProfileCategory>(ProfileCategories.OrderBy(c => c.Order).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SaveProfile(Profile profile, bool includeChildren)
|
public void SaveProfile(Profile profile, bool includeChildren)
|
||||||
{
|
{
|
||||||
Stopwatch sw = new();
|
|
||||||
sw.Start();
|
|
||||||
_logger.Debug("Updating profile - Saving {Profile}", profile);
|
_logger.Debug("Updating profile - Saving {Profile}", profile);
|
||||||
profile.Save();
|
profile.Save();
|
||||||
if (includeChildren)
|
if (includeChildren)
|
||||||
@ -312,7 +304,7 @@ internal class ProfileService : IProfileService
|
|||||||
profile.IsFreshImport = false;
|
profile.IsFreshImport = false;
|
||||||
profile.ProfileEntity.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
|
// 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
|
// A bit dodge but it ensures local instances always represent the latest stored version
|
||||||
@ -320,17 +312,10 @@ internal class ProfileService : IProfileService
|
|||||||
.SelectMany(c => c.ProfileConfigurations)
|
.SelectMany(c => c.ProfileConfigurations)
|
||||||
.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id);
|
.FirstOrDefault(p => p.Profile != null && p.Profile != profile && p.ProfileId == profile.ProfileEntity.Id);
|
||||||
if (localInstance == null)
|
if (localInstance == null)
|
||||||
{
|
|
||||||
sw.Stop();
|
|
||||||
_logger.Debug("Updated profile - Saved {Profile} in {Time}ms", profile, sw.Elapsed.TotalMilliseconds);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
DeactivateProfile(localInstance);
|
DeactivateProfile(localInstance);
|
||||||
ActivateProfile(localInstance);
|
ActivateProfile(localInstance);
|
||||||
|
|
||||||
sw.Stop();
|
|
||||||
_logger.Debug("Updated profile - Saved {Profile} in {Time}ms", profile, sw.Elapsed.TotalMilliseconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -393,7 +378,7 @@ internal class ProfileService : IProfileService
|
|||||||
JsonObject? profileJson = CoreJson.Deserialize<JsonObject>(await profileReader.ReadToEndAsync());
|
JsonObject? profileJson = CoreJson.Deserialize<JsonObject>(await profileReader.ReadToEndAsync());
|
||||||
|
|
||||||
// Before deserializing, apply any pending migrations
|
// Before deserializing, apply any pending migrations
|
||||||
MigrateProfile(configurationJson, profileJson);
|
_profileRepository.MigrateProfile(configurationJson, profileJson);
|
||||||
|
|
||||||
// Deserialize profile configuration to ProfileConfigurationEntity
|
// Deserialize profile configuration to ProfileConfigurationEntity
|
||||||
ProfileConfigurationEntity? configurationEntity = configurationJson?.Deserialize<ProfileConfigurationEntity>(Constants.JsonConvertSettings);
|
ProfileConfigurationEntity? configurationEntity = configurationJson?.Deserialize<ProfileConfigurationEntity>(Constants.JsonConvertSettings);
|
||||||
@ -453,7 +438,7 @@ internal class ProfileService : IProfileService
|
|||||||
{
|
{
|
||||||
ProfileConfiguration imported = await ImportProfile(archiveStream, profileConfiguration.Category, true, true, null, profileConfiguration.Order + 1);
|
ProfileConfiguration imported = await ImportProfile(archiveStream, profileConfiguration.Category, true, true, null, profileConfiguration.Order + 1);
|
||||||
|
|
||||||
DeleteProfile(profileConfiguration);
|
RemoveProfileConfiguration(profileConfiguration);
|
||||||
SaveProfileCategory(imported.Category);
|
SaveProfileCategory(imported.Category);
|
||||||
|
|
||||||
return imported;
|
return imported;
|
||||||
@ -479,24 +464,7 @@ internal class ProfileService : IProfileService
|
|||||||
{
|
{
|
||||||
_pendingKeyboardEvents.Add(e);
|
_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>
|
/// <summary>
|
||||||
/// Populates all missing LEDs on all currently active profiles
|
/// Populates all missing LEDs on all currently active profiles
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
@ -13,8 +12,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="LiteDB" Version="5.0.17" />
|
<PackageReference Include="LiteDB" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@ -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()
|
public QueuedActionEntity()
|
||||||
{
|
{
|
||||||
@ -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; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
@ -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; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
@ -1,9 +1,9 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Plugins;
|
namespace Artemis.Storage.Legacy.Entities.Plugins;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the configuration of a plugin, each plugin has one configuration
|
/// Represents the configuration of a plugin, each plugin has one configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginEntity
|
internal class PluginEntity
|
||||||
{
|
{
|
||||||
public PluginEntity()
|
public PluginEntity()
|
||||||
{
|
{
|
||||||
@ -19,7 +19,7 @@ public class PluginEntity
|
|||||||
{
|
{
|
||||||
return new Artemis.Storage.Entities.Plugins.PluginEntity()
|
return new Artemis.Storage.Entities.Plugins.PluginEntity()
|
||||||
{
|
{
|
||||||
Id = Id,
|
PluginGuid = Id,
|
||||||
IsEnabled = IsEnabled,
|
IsEnabled = IsEnabled,
|
||||||
Features = Features.Select(f => f.Migrate()).ToList()
|
Features = Features.Select(f => f.Migrate()).ToList()
|
||||||
};
|
};
|
||||||
@ -29,7 +29,7 @@ public class PluginEntity
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the configuration of a plugin feature, each feature has one configuration
|
/// Represents the configuration of a plugin feature, each feature has one configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginFeatureEntity
|
internal class PluginFeatureEntity
|
||||||
{
|
{
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; } = string.Empty;
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
@ -1,9 +1,9 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Plugins;
|
namespace Artemis.Storage.Legacy.Entities.Plugins;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the setting of a plugin, a plugin can have multiple settings
|
/// Represents the setting of a plugin, a plugin can have multiple settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginSettingEntity
|
internal class PluginSettingEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid PluginGuid { get; set; }
|
public Guid PluginGuid { get; set; }
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
using Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Abstract;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Abstract;
|
||||||
|
|
||||||
public abstract class RenderElementEntity
|
internal abstract class RenderElementEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid ParentId { get; set; }
|
public Guid ParentId { get; set; }
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.AdaptionHints;
|
namespace Artemis.Storage.Legacy.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
public class CategoryAdaptionHintEntity : IAdaptionHintEntity
|
internal class CategoryAdaptionHintEntity : IAdaptionHintEntity
|
||||||
{
|
{
|
||||||
public int Category { get; set; }
|
public int Category { get; set; }
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.AdaptionHints;
|
namespace Artemis.Storage.Legacy.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
public class DeviceAdaptionHintEntity : IAdaptionHintEntity
|
internal class DeviceAdaptionHintEntity : IAdaptionHintEntity
|
||||||
{
|
{
|
||||||
public int DeviceType { get; set; }
|
public int DeviceType { get; set; }
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.AdaptionHints;
|
namespace Artemis.Storage.Legacy.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
[JsonDerivedType(typeof(CategoryAdaptionHintEntity), "Category")]
|
[JsonDerivedType(typeof(CategoryAdaptionHintEntity), "Category")]
|
||||||
[JsonDerivedType(typeof(DeviceAdaptionHintEntity), "Device")]
|
[JsonDerivedType(typeof(DeviceAdaptionHintEntity), "Device")]
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace Artemis.Storage.Legacy.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
|
internal class KeyboardSectionAdaptionHintEntity : IAdaptionHintEntity
|
||||||
|
{
|
||||||
|
public int Section { get; set; }
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.AdaptionHints;
|
namespace Artemis.Storage.Legacy.Entities.Profile.AdaptionHints;
|
||||||
|
|
||||||
public class SingleLedAdaptionHintEntity : IAdaptionHintEntity
|
internal class SingleLedAdaptionHintEntity : IAdaptionHintEntity
|
||||||
{
|
{
|
||||||
public int LedId { get; set; }
|
public int LedId { get; set; }
|
||||||
|
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
namespace Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
|
|
||||||
|
internal class AlwaysOnConditionEntity : IConditionEntity;
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
using Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
|
|
||||||
public class EventConditionEntity : IConditionEntity
|
internal class EventConditionEntity : IConditionEntity
|
||||||
{
|
{
|
||||||
public int TriggerMode { get; set; }
|
public int TriggerMode { get; set; }
|
||||||
public int OverlapMode { get; set; }
|
public int OverlapMode { get; set; }
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
|
|
||||||
[JsonDerivedType(typeof(AlwaysOnConditionEntity), "AlwaysOn")]
|
[JsonDerivedType(typeof(AlwaysOnConditionEntity), "AlwaysOn")]
|
||||||
[JsonDerivedType(typeof(EventConditionEntity), "Event")]
|
[JsonDerivedType(typeof(EventConditionEntity), "Event")]
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
namespace Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
|
|
||||||
|
internal class PlayOnceConditionEntity : IConditionEntity;
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
using Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
|
|
||||||
|
internal class StaticConditionEntity : IConditionEntity
|
||||||
|
{
|
||||||
|
public int PlayMode { get; set; }
|
||||||
|
public int StopMode { get; set; }
|
||||||
|
public NodeScriptEntity? Script { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
using Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Legacy.Entities.Profile.DataBindings;
|
||||||
|
|
||||||
|
internal class DataBindingEntity
|
||||||
|
{
|
||||||
|
public bool IsEnabled { get; set; }
|
||||||
|
public NodeScriptEntity? NodeScript { get; set; }
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class DataModelPathEntity
|
internal class DataModelPathEntity
|
||||||
{
|
{
|
||||||
public string Path { get; set; } = string.Empty;
|
public string Path { get; set; } = string.Empty;
|
||||||
public string? DataModelId { get; set; }
|
public string? DataModelId { get; set; }
|
||||||
@ -1,9 +1,9 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Abstract;
|
using Artemis.Storage.Legacy.Entities.Profile.Abstract;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class FolderEntity : RenderElementEntity
|
internal class FolderEntity : RenderElementEntity
|
||||||
{
|
{
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public string? Name { get; set; }
|
public string? Name { get; set; }
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class KeyframeEntity
|
internal class KeyframeEntity
|
||||||
{
|
{
|
||||||
public TimeSpan Position { get; set; }
|
public TimeSpan Position { get; set; }
|
||||||
public int Timeline { get; set; }
|
public int Timeline { get; set; }
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class LayerBrushEntity
|
internal class LayerBrushEntity
|
||||||
{
|
{
|
||||||
public string ProviderId { get; set; } = string.Empty;
|
public string ProviderId { get; set; } = string.Empty;
|
||||||
public string BrushType { get; set; } = string.Empty;
|
public string BrushType { get; set; } = string.Empty;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class LayerEffectEntity
|
internal class LayerEffectEntity
|
||||||
{
|
{
|
||||||
public string ProviderId { get; set; } = string.Empty;
|
public string ProviderId { get; set; } = string.Empty;
|
||||||
public string EffectType { get; set; } = string.Empty;
|
public string EffectType { get; set; } = string.Empty;
|
||||||
@ -1,10 +1,10 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Abstract;
|
using Artemis.Storage.Legacy.Entities.Profile.Abstract;
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.AdaptionHints;
|
using Artemis.Storage.Legacy.Entities.Profile.AdaptionHints;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class LayerEntity : RenderElementEntity
|
internal class LayerEntity : RenderElementEntity
|
||||||
{
|
{
|
||||||
public LayerEntity()
|
public LayerEntity()
|
||||||
{
|
{
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class LedEntity
|
internal class LedEntity
|
||||||
{
|
{
|
||||||
public string LedName { get; set; } = string.Empty;
|
public string LedName { get; set; } = string.Empty;
|
||||||
public string DeviceIdentifier { get; set; } = string.Empty;
|
public string DeviceIdentifier { get; set; } = string.Empty;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
public class NodeConnectionEntity
|
internal class NodeConnectionEntity
|
||||||
{
|
{
|
||||||
public NodeConnectionEntity()
|
public NodeConnectionEntity()
|
||||||
{
|
{
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
public class NodeEntity
|
internal class NodeEntity
|
||||||
{
|
{
|
||||||
public NodeEntity()
|
public NodeEntity()
|
||||||
{
|
{
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
public class NodePinCollectionEntity
|
internal class NodePinCollectionEntity
|
||||||
{
|
{
|
||||||
public NodePinCollectionEntity()
|
public NodePinCollectionEntity()
|
||||||
{
|
{
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
namespace Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
public class NodeScriptEntity
|
internal class NodeScriptEntity
|
||||||
{
|
{
|
||||||
public NodeScriptEntity()
|
public NodeScriptEntity()
|
||||||
{
|
{
|
||||||
@ -3,9 +3,9 @@ using Artemis.Storage.Entities.Profile;
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class ProfileCategoryEntity
|
internal class ProfileCategoryEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
using Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class ProfileConfigurationEntity
|
internal class ProfileConfigurationEntity
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string? MaterialIcon { get; set; }
|
public string? MaterialIcon { get; set; }
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
|
internal class ProfileConfigurationHotkeyEntity
|
||||||
|
{
|
||||||
|
public int? Key { get; set; }
|
||||||
|
public int? Modifiers { get; set; }
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.General;
|
using Artemis.Storage.Legacy.Entities.General;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class ProfileEntity
|
internal class ProfileEntity
|
||||||
{
|
{
|
||||||
public ProfileEntity()
|
public ProfileEntity()
|
||||||
{
|
{
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.DataBindings;
|
using Artemis.Storage.Legacy.Entities.Profile.DataBindings;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class PropertyEntity
|
internal class PropertyEntity
|
||||||
{
|
{
|
||||||
public string Identifier { get; set; } = string.Empty;
|
public string Identifier { get; set; } = string.Empty;
|
||||||
public string Value { get; set; } = string.Empty;
|
public string Value { get; set; } = string.Empty;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class PropertyGroupEntity
|
internal class PropertyGroupEntity
|
||||||
{
|
{
|
||||||
public string Identifier { get; set; } = string.Empty;
|
public string Identifier { get; set; } = string.Empty;
|
||||||
public List<PropertyEntity> Properties { get; set; } = new();
|
public List<PropertyEntity> Properties { get; set; } = new();
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
namespace Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
|
||||||
public class TimelineEntity
|
internal class TimelineEntity
|
||||||
{
|
{
|
||||||
public TimeSpan StartSegmentLength { get; set; }
|
public TimeSpan StartSegmentLength { get; set; }
|
||||||
public TimeSpan MainSegmentLength { get; set; }
|
public TimeSpan MainSegmentLength { get; set; }
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Surface;
|
namespace Artemis.Storage.Legacy.Entities.Surface;
|
||||||
|
|
||||||
public class DeviceEntity
|
internal class DeviceEntity
|
||||||
{
|
{
|
||||||
public DeviceEntity()
|
public DeviceEntity()
|
||||||
{
|
{
|
||||||
@ -65,13 +65,13 @@ public class DeviceEntity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InputMappingEntity
|
internal class InputMappingEntity
|
||||||
{
|
{
|
||||||
public int OriginalLedId { get; set; }
|
public int OriginalLedId { get; set; }
|
||||||
public int MappedLedId { get; set; }
|
public int MappedLedId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeviceInputIdentifierEntity
|
internal class DeviceInputIdentifierEntity
|
||||||
{
|
{
|
||||||
public string InputProvider { get; set; } = string.Empty;
|
public string InputProvider { get; set; } = string.Empty;
|
||||||
public object Identifier { get; set; } = string.Empty;
|
public object Identifier { get; set; } = string.Empty;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Workshop;
|
namespace Artemis.Storage.Legacy.Entities.Workshop;
|
||||||
|
|
||||||
public class EntryEntity
|
internal class EntryEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
163
src/Artemis.Storage.Legacy/LegacyMigrationService.cs
Normal file
163
src/Artemis.Storage.Legacy/LegacyMigrationService.cs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
using Artemis.Core;
|
||||||
|
using Artemis.Storage.Legacy.Entities.General;
|
||||||
|
using Artemis.Storage.Legacy.Entities.Plugins;
|
||||||
|
using Artemis.Storage.Legacy.Entities.Profile;
|
||||||
|
using Artemis.Storage.Legacy.Entities.Surface;
|
||||||
|
using Artemis.Storage.Legacy.Entities.Workshop;
|
||||||
|
using Artemis.Storage.Legacy.Migrations;
|
||||||
|
using Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
using DryIoc;
|
||||||
|
using LiteDB;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Legacy;
|
||||||
|
|
||||||
|
public static class LegacyMigrationService
|
||||||
|
{
|
||||||
|
public static void MigrateToSqlite(IContainer container)
|
||||||
|
{
|
||||||
|
ILogger logger = container.Resolve<ILogger>();
|
||||||
|
|
||||||
|
// Before creating a DB context which is kinda expensive, check if there's anything to migrate
|
||||||
|
if (!File.Exists(Path.Combine(Constants.DataFolder, "database.db")))
|
||||||
|
{
|
||||||
|
logger.Information("No legacy database found, nothing to migrate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using ArtemisDbContext dbContext = container.Resolve<ArtemisDbContext>();
|
||||||
|
MigrateToSqlite(logger, dbContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MigrateToSqlite(ILogger logger, ArtemisDbContext dbContext)
|
||||||
|
{
|
||||||
|
if (!File.Exists(Path.Combine(Constants.DataFolder, "database.db")))
|
||||||
|
{
|
||||||
|
logger.Information("No legacy database found, nothing to migrate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Information("Migrating legacy database...");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Copy the database before using it, we're going to make some modifications to it and we don't want to mess up the original
|
||||||
|
string databasePath = Path.Combine(Constants.DataFolder, "database.db");
|
||||||
|
string tempPath = Path.Combine(Constants.DataFolder, "temp.db");
|
||||||
|
File.Copy(databasePath, tempPath, true);
|
||||||
|
|
||||||
|
using LiteRepository repository = new($"FileName={tempPath}");
|
||||||
|
|
||||||
|
// Apply pending LiteDB migrations, this includes a migration that transforms namespaces to Artemis.Storage.Legacy
|
||||||
|
ApplyPendingMigrations(logger, repository);
|
||||||
|
|
||||||
|
// Devices
|
||||||
|
if (!dbContext.Devices.Any())
|
||||||
|
{
|
||||||
|
logger.Information("Migrating devices");
|
||||||
|
List<DeviceEntity> legacyDevices = repository.Query<DeviceEntity>().Include(s => s.InputIdentifiers).ToList();
|
||||||
|
dbContext.Devices.AddRange(legacyDevices.Select(l => l.Migrate()));
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entries
|
||||||
|
if (!dbContext.Entries.Any())
|
||||||
|
{
|
||||||
|
logger.Information("Migrating entries");
|
||||||
|
List<EntryEntity> legacyEntries = repository.Query<EntryEntity>().ToList();
|
||||||
|
dbContext.Entries.AddRange(legacyEntries.Select(l => l.Migrate()));
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
if (!dbContext.Plugins.Any())
|
||||||
|
{
|
||||||
|
logger.Information("Migrating plugins");
|
||||||
|
List<PluginEntity> legacyPlugins = repository.Query<PluginEntity>().ToList();
|
||||||
|
dbContext.Plugins.AddRange(legacyPlugins.Select(l => l.Migrate()));
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// PluginSettings
|
||||||
|
if (!dbContext.PluginSettings.Any())
|
||||||
|
{
|
||||||
|
logger.Information("Migrating plugin settings");
|
||||||
|
List<PluginSettingEntity> legacyPluginSettings = repository.Query<PluginSettingEntity>().ToList();
|
||||||
|
dbContext.PluginSettings.AddRange(legacyPluginSettings.Select(l => l.Migrate()));
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProfileCategories
|
||||||
|
if (!dbContext.ProfileCategories.Any())
|
||||||
|
{
|
||||||
|
logger.Information("Migrating profile categories");
|
||||||
|
List<ProfileCategoryEntity> legacyProfileCategories = repository.Query<ProfileCategoryEntity>().ToList();
|
||||||
|
ILiteStorage<Guid> profileIcons = repository.Database.GetStorage<Guid>("profileIcons");
|
||||||
|
List<ProfileEntity> legacyProfiles = repository.Query<ProfileEntity>().ToList();
|
||||||
|
dbContext.ProfileCategories.AddRange(legacyProfileCategories.Select(l => l.Migrate(logger, legacyProfiles, profileIcons)));
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Releases
|
||||||
|
if (!dbContext.Releases.Any())
|
||||||
|
{
|
||||||
|
logger.Information("Migrating releases");
|
||||||
|
List<ReleaseEntity> legacyReleases = repository.Query<ReleaseEntity>().ToList();
|
||||||
|
dbContext.Releases.AddRange(legacyReleases.Select(l => l.Migrate()));
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// After a successful migration, keep the legacy database around for a while
|
||||||
|
File.Move(Path.Combine(Constants.DataFolder, "database.db"), Path.Combine(Constants.DataFolder, "legacy.db"));
|
||||||
|
|
||||||
|
logger.Information("Legacy database migrated");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error(e, "Failed to migrate legacy database");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
File.Delete(Path.Combine(Constants.DataFolder, "temp.db"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyPendingMigrations(ILogger logger, LiteRepository repository)
|
||||||
|
{
|
||||||
|
List<IStorageMigration> migrations =
|
||||||
|
[
|
||||||
|
new M0020AvaloniaReset(),
|
||||||
|
new M0021GradientNodes(),
|
||||||
|
new M0022TransitionNodes(),
|
||||||
|
new M0023LayoutProviders(),
|
||||||
|
new M0024NodeProviders(),
|
||||||
|
new M0025NodeProvidersProfileConfig(),
|
||||||
|
new M0026NodeStorage(logger),
|
||||||
|
new M0027Namespace()
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach (IStorageMigration storageMigration in migrations.OrderBy(m => m.UserVersion))
|
||||||
|
{
|
||||||
|
if (repository.Database.UserVersion >= storageMigration.UserVersion)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
logger.Information("Applying storage migration {storageMigration} to update DB from v{oldVersion} to v{newVersion}",
|
||||||
|
storageMigration.GetType().Name, repository.Database.UserVersion, storageMigration.UserVersion);
|
||||||
|
|
||||||
|
repository.Database.BeginTrans();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
storageMigration.Apply(repository);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
repository.Database.Rollback();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
repository.Database.Commit();
|
||||||
|
repository.Database.UserVersion = storageMigration.UserVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations;
|
namespace Artemis.Storage.Legacy.Migrations;
|
||||||
|
|
||||||
public interface IProfileMigration
|
public interface IProfileMigration
|
||||||
{
|
{
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations;
|
namespace Artemis.Storage.Legacy.Migrations;
|
||||||
|
|
||||||
public interface IStorageMigration
|
public interface IStorageMigration
|
||||||
{
|
{
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0020AvaloniaReset : IStorageMigration
|
internal class M0020AvaloniaReset : IStorageMigration
|
||||||
{
|
{
|
||||||
public int UserVersion => 20;
|
public int UserVersion => 20;
|
||||||
|
|
||||||
@ -1,10 +1,10 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
using Artemis.Storage.Legacy.Entities.Profile;
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
using Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0021GradientNodes : IStorageMigration
|
internal class M0021GradientNodes : IStorageMigration
|
||||||
{
|
{
|
||||||
private void MigrateDataBinding(PropertyEntity property)
|
private void MigrateDataBinding(PropertyEntity property)
|
||||||
{
|
{
|
||||||
@ -59,7 +59,7 @@ public class M0021GradientNodes : IStorageMigration
|
|||||||
{
|
{
|
||||||
if (propertyGroup == null)
|
if (propertyGroup == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups)
|
foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups)
|
||||||
MigrateDataBinding(propertyGroupPropertyGroup);
|
MigrateDataBinding(propertyGroupPropertyGroup);
|
||||||
|
|
||||||
@ -1,11 +1,11 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
using Artemis.Storage.Legacy.Entities.Profile;
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
using Artemis.Storage.Legacy.Entities.Profile.Conditions;
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
using Artemis.Storage.Legacy.Entities.Profile.Nodes;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0022TransitionNodes : IStorageMigration
|
internal class M0022TransitionNodes : IStorageMigration
|
||||||
{
|
{
|
||||||
private void MigrateNodeScript(NodeScriptEntity? nodeScript)
|
private void MigrateNodeScript(NodeScriptEntity? nodeScript)
|
||||||
{
|
{
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0023LayoutProviders : IStorageMigration
|
internal class M0023LayoutProviders : IStorageMigration
|
||||||
{
|
{
|
||||||
public int UserVersion => 23;
|
public int UserVersion => 23;
|
||||||
|
|
||||||
@ -19,9 +19,13 @@ public class M0023LayoutProviders : IStorageMigration
|
|||||||
bsonDocument.Add("LayoutParameter", new BsonValue(customLayoutPath.AsString));
|
bsonDocument.Add("LayoutParameter", new BsonValue(customLayoutPath.AsString));
|
||||||
}
|
}
|
||||||
else if (bsonDocument.TryGetValue("DisableDefaultLayout", out BsonValue disableDefaultLayout) && disableDefaultLayout.AsBoolean)
|
else if (bsonDocument.TryGetValue("DisableDefaultLayout", out BsonValue disableDefaultLayout) && disableDefaultLayout.AsBoolean)
|
||||||
|
{
|
||||||
bsonDocument.Add("LayoutType", new BsonValue("None"));
|
bsonDocument.Add("LayoutType", new BsonValue("None"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
bsonDocument.Add("LayoutType", new BsonValue("Default"));
|
bsonDocument.Add("LayoutType", new BsonValue("Default"));
|
||||||
|
}
|
||||||
|
|
||||||
bsonDocument.Remove("CustomLayoutPath");
|
bsonDocument.Remove("CustomLayoutPath");
|
||||||
bsonDocument.Remove("DisableDefaultLayout");
|
bsonDocument.Remove("DisableDefaultLayout");
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0024NodeProviders : IStorageMigration
|
internal class M0024NodeProviders : IStorageMigration
|
||||||
{
|
{
|
||||||
public int UserVersion => 24;
|
public int UserVersion => 24;
|
||||||
|
|
||||||
@ -20,6 +20,7 @@ public class M0024NodeProviders : IStorageMigration
|
|||||||
categoriesToUpdate.Add(profileCategoryBson);
|
categoriesToUpdate.Add(profileCategoryBson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryCollection.Update(categoriesToUpdate);
|
categoryCollection.Update(categoriesToUpdate);
|
||||||
|
|
||||||
ILiteCollection<BsonDocument> collection = repository.Database.GetCollection("ProfileEntity");
|
ILiteCollection<BsonDocument> collection = repository.Database.GetCollection("ProfileEntity");
|
||||||
@ -28,15 +29,12 @@ public class M0024NodeProviders : IStorageMigration
|
|||||||
{
|
{
|
||||||
BsonArray? folders = profileBson["Folders"]?.AsArray;
|
BsonArray? folders = profileBson["Folders"]?.AsArray;
|
||||||
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
||||||
|
|
||||||
if (folders != null)
|
if (folders != null)
|
||||||
{
|
|
||||||
foreach (BsonValue folder in folders)
|
foreach (BsonValue folder in folders)
|
||||||
MigrateProfileElement(folder.AsDocument);
|
MigrateProfileElement(folder.AsDocument);
|
||||||
}
|
|
||||||
|
|
||||||
if (layers != null)
|
if (layers != null)
|
||||||
{
|
|
||||||
foreach (BsonValue layer in layers)
|
foreach (BsonValue layer in layers)
|
||||||
{
|
{
|
||||||
MigrateProfileElement(layer.AsDocument);
|
MigrateProfileElement(layer.AsDocument);
|
||||||
@ -44,8 +42,7 @@ public class M0024NodeProviders : IStorageMigration
|
|||||||
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
||||||
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
profilesToUpdate.Add(profileBson);
|
profilesToUpdate.Add(profileBson);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,10 +53,8 @@ public class M0024NodeProviders : IStorageMigration
|
|||||||
{
|
{
|
||||||
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
||||||
if (layerEffects != null)
|
if (layerEffects != null)
|
||||||
{
|
|
||||||
foreach (BsonValue layerEffect in layerEffects)
|
foreach (BsonValue layerEffect in layerEffects)
|
||||||
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
||||||
}
|
|
||||||
|
|
||||||
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
||||||
if (displayCondition != null)
|
if (displayCondition != null)
|
||||||
@ -75,16 +70,12 @@ public class M0024NodeProviders : IStorageMigration
|
|||||||
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
||||||
|
|
||||||
if (properties != null)
|
if (properties != null)
|
||||||
{
|
|
||||||
foreach (BsonValue property in properties)
|
foreach (BsonValue property in properties)
|
||||||
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyGroups != null)
|
if (propertyGroups != null)
|
||||||
{
|
|
||||||
foreach (BsonValue childPropertyGroup in propertyGroups)
|
foreach (BsonValue childPropertyGroup in propertyGroups)
|
||||||
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
private void MigrateNodeScript(BsonDocument? nodeScript)
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0025NodeProvidersProfileConfig : IStorageMigration
|
internal class M0025NodeProvidersProfileConfig : IStorageMigration
|
||||||
{
|
{
|
||||||
public int UserVersion => 25;
|
public int UserVersion => 25;
|
||||||
|
|
||||||
@ -20,13 +20,14 @@ public class M0025NodeProvidersProfileConfig : IStorageMigration
|
|||||||
profile["Version"] = 2;
|
profile["Version"] = 2;
|
||||||
MigrateNodeScript(profile["ActivationCondition"]?.AsDocument);
|
MigrateNodeScript(profile["ActivationCondition"]?.AsDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
toUpdate.Add(profileCategoryBson);
|
toUpdate.Add(profileCategoryBson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryCollection.Update(toUpdate);
|
categoryCollection.Update(toUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
private void MigrateNodeScript(BsonDocument? nodeScript)
|
||||||
{
|
{
|
||||||
if (nodeScript == null || nodeScript.Keys.Count == 0)
|
if (nodeScript == null || nodeScript.Keys.Count == 0)
|
||||||
@ -3,9 +3,9 @@ using System.Text.Json.Nodes;
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0026NodeStorage : IStorageMigration
|
internal class M0026NodeStorage : IStorageMigration
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
@ -45,13 +45,10 @@ public class M0026NodeStorage : IStorageMigration
|
|||||||
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
||||||
|
|
||||||
if (folders != null)
|
if (folders != null)
|
||||||
{
|
|
||||||
foreach (BsonValue folder in folders)
|
foreach (BsonValue folder in folders)
|
||||||
MigrateProfileElement(folder.AsDocument);
|
MigrateProfileElement(folder.AsDocument);
|
||||||
}
|
|
||||||
|
|
||||||
if (layers != null)
|
if (layers != null)
|
||||||
{
|
|
||||||
foreach (BsonValue layer in layers)
|
foreach (BsonValue layer in layers)
|
||||||
{
|
{
|
||||||
MigrateProfileElement(layer.AsDocument);
|
MigrateProfileElement(layer.AsDocument);
|
||||||
@ -59,7 +56,6 @@ public class M0026NodeStorage : IStorageMigration
|
|||||||
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
||||||
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
profilesToUpdate.Add(profileBson);
|
profilesToUpdate.Add(profileBson);
|
||||||
}
|
}
|
||||||
@ -71,10 +67,8 @@ public class M0026NodeStorage : IStorageMigration
|
|||||||
{
|
{
|
||||||
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
||||||
if (layerEffects != null)
|
if (layerEffects != null)
|
||||||
{
|
|
||||||
foreach (BsonValue layerEffect in layerEffects)
|
foreach (BsonValue layerEffect in layerEffects)
|
||||||
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
||||||
}
|
|
||||||
|
|
||||||
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
||||||
if (displayCondition != null)
|
if (displayCondition != null)
|
||||||
@ -90,16 +84,12 @@ public class M0026NodeStorage : IStorageMigration
|
|||||||
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
||||||
|
|
||||||
if (properties != null)
|
if (properties != null)
|
||||||
{
|
|
||||||
foreach (BsonValue property in properties)
|
foreach (BsonValue property in properties)
|
||||||
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyGroups != null)
|
if (propertyGroups != null)
|
||||||
{
|
|
||||||
foreach (BsonValue childPropertyGroup in propertyGroups)
|
foreach (BsonValue childPropertyGroup in propertyGroups)
|
||||||
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
private void MigrateNodeScript(BsonDocument? nodeScript)
|
||||||
@ -112,10 +102,8 @@ public class M0026NodeStorage : IStorageMigration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (BsonValue node in nodes)
|
foreach (BsonValue node in nodes)
|
||||||
{
|
|
||||||
// Migrate the storage of the node
|
// Migrate the storage of the node
|
||||||
node["Storage"] = MigrateNodeStorageJson(node.AsDocument["Storage"]?.AsString, _logger);
|
node["Storage"] = MigrateNodeStorageJson(node.AsDocument["Storage"]?.AsString, _logger);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? MigrateNodeStorageJson(string? json, ILogger logger)
|
private static string? MigrateNodeStorageJson(string? json, ILogger logger)
|
||||||
@ -1,8 +1,8 @@
|
|||||||
using LiteDB;
|
using LiteDB;
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
namespace Artemis.Storage.Legacy.Migrations.Storage;
|
||||||
|
|
||||||
public class M0027Namespace : IStorageMigration
|
internal class M0027Namespace : IStorageMigration
|
||||||
{
|
{
|
||||||
public int UserVersion => 27;
|
public int UserVersion => 27;
|
||||||
|
|
||||||
@ -25,21 +25,17 @@ public class M0027Namespace : IStorageMigration
|
|||||||
foreach ((string? key, BsonValue? value) in document)
|
foreach ((string? key, BsonValue? value) in document)
|
||||||
{
|
{
|
||||||
if (key == "_type")
|
if (key == "_type")
|
||||||
{
|
|
||||||
document[key] = document[key].AsString
|
document[key] = document[key].AsString
|
||||||
.Replace("Artemis.Storage.Entities.Profile", "Artemis.Storage.Migrator.Legacy.Entities.Profile")
|
.Replace("Artemis.Storage.Entities", "Artemis.Storage.Legacy.Entities")
|
||||||
.Replace(", Artemis.Storage", ", Artemis.Storage.Migrator");
|
.Replace(", Artemis.Storage", ", Artemis.Storage.Legacy");
|
||||||
}
|
|
||||||
else if (value.IsDocument)
|
else if (value.IsDocument)
|
||||||
MigrateDocument(value.AsDocument);
|
MigrateDocument(value.AsDocument);
|
||||||
else if (value.IsArray)
|
else if (value.IsArray)
|
||||||
{
|
|
||||||
foreach (BsonValue bsonValue in value.AsArray)
|
foreach (BsonValue bsonValue in value.AsArray)
|
||||||
{
|
{
|
||||||
if (bsonValue.IsDocument)
|
if (bsonValue.IsDocument)
|
||||||
MigrateDocument(bsonValue.AsDocument);
|
MigrateDocument(bsonValue.AsDocument);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
22
src/Artemis.Storage.Legacy/Program.cs
Normal file
22
src/Artemis.Storage.Legacy/Program.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// using Artemis.Core.DryIoc;
|
||||||
|
// using Artemis.Storage;
|
||||||
|
// using Artemis.Storage.Legacy;
|
||||||
|
// using DryIoc;
|
||||||
|
// using Microsoft.EntityFrameworkCore;
|
||||||
|
// using Serilog;
|
||||||
|
//
|
||||||
|
// using Container container = new(rules => rules
|
||||||
|
// .WithMicrosoftDependencyInjectionRules()
|
||||||
|
// .WithConcreteTypeDynamicRegistrations()
|
||||||
|
// .WithoutThrowOnRegisteringDisposableTransient());
|
||||||
|
//
|
||||||
|
// container.RegisterCore();
|
||||||
|
//
|
||||||
|
// ILogger logger = container.Resolve<ILogger>();
|
||||||
|
// ArtemisDbContext dbContext = container.Resolve<ArtemisDbContext>();
|
||||||
|
//
|
||||||
|
// logger.Information("Applying pending migrations...");
|
||||||
|
// dbContext.Database.Migrate();
|
||||||
|
// logger.Information("Pending migrations applied");
|
||||||
|
//
|
||||||
|
// MigrationService.MigrateToSqlite(logger, dbContext);
|
||||||
@ -1,6 +0,0 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.AdaptionHints;
|
|
||||||
|
|
||||||
public class KeyboardSectionAdaptionHintEntity : IAdaptionHintEntity
|
|
||||||
{
|
|
||||||
public int Section { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
|
||||||
|
|
||||||
public class AlwaysOnConditionEntity : IConditionEntity;
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
|
||||||
|
|
||||||
public class PlayOnceConditionEntity : IConditionEntity;
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.Conditions;
|
|
||||||
|
|
||||||
public class StaticConditionEntity : IConditionEntity
|
|
||||||
{
|
|
||||||
public int PlayMode { get; set; }
|
|
||||||
public int StopMode { get; set; }
|
|
||||||
public NodeScriptEntity? Script { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile.Nodes;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile.DataBindings;
|
|
||||||
|
|
||||||
public class DataBindingEntity
|
|
||||||
{
|
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
public NodeScriptEntity? NodeScript { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
namespace Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
|
||||||
|
|
||||||
public class ProfileConfigurationHotkeyEntity
|
|
||||||
{
|
|
||||||
public int? Key { get; set; }
|
|
||||||
public int? Modifiers { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
using Artemis.Storage.Migrator.Legacy.Migrations;
|
|
||||||
using LiteDB;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator.Legacy;
|
|
||||||
|
|
||||||
public static class StorageMigrationService
|
|
||||||
{
|
|
||||||
public static void ApplyPendingMigrations(ILogger logger, LiteRepository repository, IList<IStorageMigration> migrations)
|
|
||||||
{
|
|
||||||
foreach (IStorageMigration storageMigration in migrations.OrderBy(m => m.UserVersion))
|
|
||||||
{
|
|
||||||
if (repository.Database.UserVersion >= storageMigration.UserVersion)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
logger.Information("Applying storage migration {storageMigration} to update DB from v{oldVersion} to v{newVersion}",
|
|
||||||
storageMigration.GetType().Name, repository.Database.UserVersion, storageMigration.UserVersion);
|
|
||||||
|
|
||||||
repository.Database.BeginTrans();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
storageMigration.Apply(repository);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
repository.Database.Rollback();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
repository.Database.Commit();
|
|
||||||
repository.Database.UserVersion = storageMigration.UserVersion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
using Artemis.Core;
|
|
||||||
using Artemis.Core.DryIoc;
|
|
||||||
using Artemis.Storage.Migrator.Legacy;
|
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.General;
|
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Plugins;
|
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Profile;
|
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Surface;
|
|
||||||
using Artemis.Storage.Migrator.Legacy.Entities.Workshop;
|
|
||||||
using Artemis.Storage.Migrator.Legacy.Migrations.Storage;
|
|
||||||
using DryIoc;
|
|
||||||
using LiteDB;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrator;
|
|
||||||
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
using Container container = new(rules => rules
|
|
||||||
.WithMicrosoftDependencyInjectionRules()
|
|
||||||
.WithConcreteTypeDynamicRegistrations()
|
|
||||||
.WithoutThrowOnRegisteringDisposableTransient());
|
|
||||||
|
|
||||||
container.RegisterCore();
|
|
||||||
|
|
||||||
ILogger logger = container.Resolve<ILogger>();
|
|
||||||
ArtemisDbContext dbContext = container.Resolve<ArtemisDbContext>();
|
|
||||||
logger.Information("Applying pending migrations...");
|
|
||||||
dbContext.Database.Migrate();
|
|
||||||
logger.Information("Pending migrations applied");
|
|
||||||
|
|
||||||
if (!File.Exists(Path.Combine(Constants.DataFolder, "database.db")))
|
|
||||||
{
|
|
||||||
logger.Information("No legacy database found, nothing to migrate");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Information("Migrating legacy database...");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MigrateLegacyDatabase(logger, dbContext);
|
|
||||||
// After a successful migration, keep the legacy database around for a while
|
|
||||||
File.Move(Path.Combine(Constants.DataFolder, "database.db"), Path.Combine(Constants.DataFolder, "legacy.db"));
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error(e, "Failed to migrate legacy database");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
File.Delete(Path.Combine(Constants.DataFolder, "temp.db"));
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Information("Legacy database migrated");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void MigrateLegacyDatabase(ILogger logger, ArtemisDbContext dbContext)
|
|
||||||
{
|
|
||||||
// Copy the database before using it, we're going to make some modifications to it and we don't want to mess up the original
|
|
||||||
string databasePath = Path.Combine(Constants.DataFolder, "database.db");
|
|
||||||
string tempPath = Path.Combine(Constants.DataFolder, "temp.db");
|
|
||||||
File.Copy(databasePath, tempPath, true);
|
|
||||||
|
|
||||||
using LiteRepository repository = new($"FileName={tempPath}");
|
|
||||||
|
|
||||||
// Apply pending LiteDB migrations, this includes a migration that transforms namespaces to Artemis.Storage.Migrator
|
|
||||||
StorageMigrationService.ApplyPendingMigrations(
|
|
||||||
logger,
|
|
||||||
repository,
|
|
||||||
[
|
|
||||||
new M0020AvaloniaReset(),
|
|
||||||
new M0021GradientNodes(),
|
|
||||||
new M0022TransitionNodes(),
|
|
||||||
new M0023LayoutProviders(),
|
|
||||||
new M0024NodeProviders(),
|
|
||||||
new M0025NodeProvidersProfileConfig(),
|
|
||||||
new M0026NodeStorage(logger),
|
|
||||||
new M0027Namespace(),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Devices
|
|
||||||
if (!dbContext.Devices.Any())
|
|
||||||
{
|
|
||||||
logger.Information("Migrating devices");
|
|
||||||
List<DeviceEntity> legacyDevices = repository.Query<DeviceEntity>().Include(s => s.InputIdentifiers).ToList();
|
|
||||||
dbContext.Devices.AddRange(legacyDevices.Select(l => l.Migrate()));
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entries
|
|
||||||
if (!dbContext.Entries.Any())
|
|
||||||
{
|
|
||||||
logger.Information("Migrating entries");
|
|
||||||
List<EntryEntity> legacyEntries = repository.Query<EntryEntity>().ToList();
|
|
||||||
dbContext.Entries.AddRange(legacyEntries.Select(l => l.Migrate()));
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Plugins
|
|
||||||
if (!dbContext.Plugins.Any())
|
|
||||||
{
|
|
||||||
logger.Information("Migrating plugins");
|
|
||||||
List<PluginEntity> legacyPlugins = repository.Query<PluginEntity>().ToList();
|
|
||||||
dbContext.Plugins.AddRange(legacyPlugins.Select(l => l.Migrate()));
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// PluginSettings
|
|
||||||
if (!dbContext.PluginSettings.Any())
|
|
||||||
{
|
|
||||||
logger.Information("Migrating plugin settings");
|
|
||||||
List<PluginSettingEntity> legacyPluginSettings = repository.Query<PluginSettingEntity>().ToList();
|
|
||||||
dbContext.PluginSettings.AddRange(legacyPluginSettings.Select(l => l.Migrate()));
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProfileCategories
|
|
||||||
if (!dbContext.ProfileCategories.Any())
|
|
||||||
{
|
|
||||||
logger.Information("Migrating profile categories");
|
|
||||||
List<ProfileCategoryEntity> legacyProfileCategories = repository.Query<ProfileCategoryEntity>().ToList();
|
|
||||||
ILiteStorage<Guid> profileIcons = repository.Database.GetStorage<Guid>("profileIcons");
|
|
||||||
List<ProfileEntity> legacyProfiles = repository.Query<ProfileEntity>().ToList();
|
|
||||||
dbContext.ProfileCategories.AddRange(legacyProfileCategories.Select(l => l.Migrate(logger, legacyProfiles, profileIcons)));
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Releases
|
|
||||||
if (!dbContext.Releases.Any())
|
|
||||||
{
|
|
||||||
logger.Information("Migrating releases");
|
|
||||||
List<ReleaseEntity> legacyReleases = repository.Query<ReleaseEntity>().ToList();
|
|
||||||
dbContext.Releases.AddRange(legacyReleases.Select(l => l.Migrate()));
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@ -15,8 +15,10 @@ public class ArtemisDbContext : DbContext
|
|||||||
public DbSet<DeviceEntity> Devices => Set<DeviceEntity>();
|
public DbSet<DeviceEntity> Devices => Set<DeviceEntity>();
|
||||||
public DbSet<EntryEntity> Entries => Set<EntryEntity>();
|
public DbSet<EntryEntity> Entries => Set<EntryEntity>();
|
||||||
public DbSet<PluginEntity> Plugins => Set<PluginEntity>();
|
public DbSet<PluginEntity> Plugins => Set<PluginEntity>();
|
||||||
|
public DbSet<PluginFeatureEntity> PluginFeatures => Set<PluginFeatureEntity>();
|
||||||
public DbSet<PluginSettingEntity> PluginSettings => Set<PluginSettingEntity>();
|
public DbSet<PluginSettingEntity> PluginSettings => Set<PluginSettingEntity>();
|
||||||
public DbSet<ProfileCategoryEntity> ProfileCategories => Set<ProfileCategoryEntity>();
|
public DbSet<ProfileCategoryEntity> ProfileCategories => Set<ProfileCategoryEntity>();
|
||||||
|
public DbSet<ProfileContainerEntity> ProfileContainers => Set<ProfileContainerEntity>();
|
||||||
public DbSet<ReleaseEntity> Releases => Set<ReleaseEntity>();
|
public DbSet<ReleaseEntity> Releases => Set<ReleaseEntity>();
|
||||||
|
|
||||||
public string DataFolder { get; set; } = string.Empty;
|
public string DataFolder { get; set; } = string.Empty;
|
||||||
|
|||||||
@ -1,11 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.General;
|
namespace Artemis.Storage.Entities.General;
|
||||||
|
|
||||||
|
[Index(nameof(Version), IsUnique = true)]
|
||||||
|
[Index(nameof(InstalledAt))]
|
||||||
public class ReleaseEntity
|
public class ReleaseEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(64)]
|
||||||
public string Version { get; set; } = string.Empty;
|
public string Version { get; set; } = string.Empty;
|
||||||
|
|
||||||
public DateTimeOffset? InstalledAt { get; set; }
|
public DateTimeOffset? InstalledAt { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,11 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Plugins;
|
namespace Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the configuration of a plugin, each plugin has one configuration
|
/// Represents the configuration of a plugin, each plugin has one configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Index(nameof(PluginGuid), IsUnique = true)]
|
||||||
public class PluginEntity
|
public class PluginEntity
|
||||||
{
|
{
|
||||||
public PluginEntity()
|
public PluginEntity()
|
||||||
@ -14,6 +17,7 @@ public class PluginEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
public Guid PluginGuid { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
public List<PluginFeatureEntity> Features { get; set; }
|
public List<PluginFeatureEntity> Features { get; set; }
|
||||||
@ -25,7 +29,7 @@ public class PluginEntity
|
|||||||
public class PluginFeatureEntity
|
public class PluginFeatureEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public string Type { get; set; } = string.Empty;
|
public string Type { get; set; } = string.Empty;
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,15 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Plugins;
|
namespace Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the setting of a plugin, a plugin can have multiple settings
|
/// Represents the setting of a plugin, a plugin can have multiple settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Index(nameof(Name), nameof(PluginGuid), IsUnique = true)]
|
||||||
|
[Index(nameof(PluginGuid))]
|
||||||
public class PluginSettingEntity
|
public class PluginSettingEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid PluginGuid { get; set; }
|
public Guid PluginGuid { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(128)]
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string Value { get; set; } = string.Empty;
|
public string Value { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
@ -1,12 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile;
|
namespace Artemis.Storage.Entities.Profile;
|
||||||
|
|
||||||
|
[Index(nameof(Name), IsUnique = true)]
|
||||||
public class ProfileCategoryEntity
|
public class ProfileCategoryEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(64)]
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public bool IsCollapsed { get; set; }
|
public bool IsCollapsed { get; set; }
|
||||||
public bool IsSuspended { get; set; }
|
public bool IsSuspended { get; set; }
|
||||||
|
|||||||
10
src/Artemis.Storage/Entities/RawProfileContainer.cs
Normal file
10
src/Artemis.Storage/Entities/RawProfileContainer.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Entities;
|
||||||
|
|
||||||
|
internal class RawProfileContainer
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string ProfileConfiguration { get; set; }
|
||||||
|
public string Profile { get; set; }
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Surface;
|
namespace Artemis.Storage.Entities.Surface;
|
||||||
|
|
||||||
@ -11,8 +12,12 @@ public class DeviceEntity
|
|||||||
Categories = new List<int>();
|
Categories = new List<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MaxLength(512)]
|
||||||
public string Id { get; set; } = string.Empty;
|
public string Id { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MaxLength(512)]
|
||||||
public string DeviceProvider { get; set; } = string.Empty;
|
public string DeviceProvider { get; set; } = string.Empty;
|
||||||
|
|
||||||
public float X { get; set; }
|
public float X { get; set; }
|
||||||
public float Y { get; set; }
|
public float Y { get; set; }
|
||||||
public float Rotation { get; set; }
|
public float Rotation { get; set; }
|
||||||
@ -22,10 +27,16 @@ public class DeviceEntity
|
|||||||
public float GreenScale { get; set; }
|
public float GreenScale { get; set; }
|
||||||
public float BlueScale { get; set; }
|
public float BlueScale { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
public int PhysicalLayout { get; set; }
|
public int PhysicalLayout { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(32)]
|
||||||
public string? LogicalLayout { get; set; }
|
public string? LogicalLayout { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(64)]
|
||||||
public string? LayoutType { get; set; }
|
public string? LayoutType { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(512)]
|
||||||
public string? LayoutParameter { get; set; }
|
public string? LayoutParameter { get; set; }
|
||||||
|
|
||||||
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
||||||
|
|||||||
@ -1,22 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Nodes;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Workshop;
|
namespace Artemis.Storage.Entities.Workshop;
|
||||||
|
|
||||||
|
[Index(nameof(EntryId), IsUnique = true)]
|
||||||
public class EntryEntity
|
public class EntryEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
public long EntryId { get; set; }
|
public long EntryId { get; set; }
|
||||||
public int EntryType { get; set; }
|
public int EntryType { get; set; }
|
||||||
|
|
||||||
public string Author { get; set; } = string.Empty;
|
public string Author { get; set; } = string.Empty;
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
public long ReleaseId { get; set; }
|
public long ReleaseId { get; set; }
|
||||||
public string ReleaseVersion { get; set; } = string.Empty;
|
public string ReleaseVersion { get; set; } = string.Empty;
|
||||||
public DateTimeOffset InstalledAt { get; set; }
|
public DateTimeOffset InstalledAt { get; set; }
|
||||||
|
|
||||||
public Dictionary<string, object> Metadata { get; set; }
|
public Dictionary<string, object>? Metadata { get; set; }
|
||||||
}
|
}
|
||||||
14
src/Artemis.Storage/Exceptions/ArtemisStorageException.cs
Normal file
14
src/Artemis.Storage/Exceptions/ArtemisStorageException.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Exceptions;
|
||||||
|
|
||||||
|
public class ArtemisStorageException : Exception
|
||||||
|
{
|
||||||
|
public ArtemisStorageException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArtemisStorageException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
namespace Artemis.Storage.Migrations
|
namespace Artemis.Storage.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(ArtemisDbContext))]
|
[DbContext(typeof(ArtemisDbContext))]
|
||||||
[Migration("20240308203921_Initial")]
|
[Migration("20240310201706_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -31,10 +31,16 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Version")
|
b.Property<string>("Version")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("InstalledAt");
|
||||||
|
|
||||||
|
b.HasIndex("Version")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Releases");
|
b.ToTable("Releases");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -47,8 +53,14 @@ namespace Artemis.Storage.Migrations
|
|||||||
b.Property<bool>("IsEnabled")
|
b.Property<bool>("IsEnabled")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<Guid>("PluginGuid")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PluginGuid")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Plugins");
|
b.ToTable("Plugins");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -72,7 +84,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasIndex("PluginEntityId");
|
b.HasIndex("PluginEntityId");
|
||||||
|
|
||||||
b.ToTable("PluginFeatureEntity");
|
b.ToTable("PluginFeatures");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
||||||
@ -83,6 +95,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<Guid>("PluginGuid")
|
b.Property<Guid>("PluginGuid")
|
||||||
@ -94,6 +107,11 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PluginGuid");
|
||||||
|
|
||||||
|
b.HasIndex("Name", "PluginGuid")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("PluginSettings");
|
b.ToTable("PluginSettings");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -111,6 +129,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int>("Order")
|
b.Property<int>("Order")
|
||||||
@ -118,6 +137,9 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("ProfileCategories");
|
b.ToTable("ProfileCategories");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -146,12 +168,13 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasIndex("ProfileCategoryId");
|
b.HasIndex("ProfileCategoryId");
|
||||||
|
|
||||||
b.ToTable("ProfileContainerEntity");
|
b.ToTable("ProfileContainers");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(512)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<float>("BlueScale")
|
b.Property<float>("BlueScale")
|
||||||
@ -163,6 +186,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("DeviceProvider")
|
b.Property<string>("DeviceProvider")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(512)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<float>("GreenScale")
|
b.Property<float>("GreenScale")
|
||||||
@ -172,12 +196,15 @@ namespace Artemis.Storage.Migrations
|
|||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<string>("LayoutParameter")
|
b.Property<string>("LayoutParameter")
|
||||||
|
.HasMaxLength(512)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("LayoutType")
|
b.Property<string>("LayoutType")
|
||||||
|
.HasMaxLength(64)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("LogicalLayout")
|
b.Property<string>("LogicalLayout")
|
||||||
|
.HasMaxLength(32)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int>("PhysicalLayout")
|
b.Property<int>("PhysicalLayout")
|
||||||
@ -226,7 +253,6 @@ namespace Artemis.Storage.Migrations
|
|||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("Metadata")
|
b.Property<string>("Metadata")
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -242,6 +268,9 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("EntryId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Entries");
|
b.ToTable("Entries");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -15,8 +15,8 @@ namespace Artemis.Storage.Migrations
|
|||||||
name: "Devices",
|
name: "Devices",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<string>(type: "TEXT", nullable: false),
|
Id = table.Column<string>(type: "TEXT", maxLength: 512, nullable: false),
|
||||||
DeviceProvider = table.Column<string>(type: "TEXT", nullable: false),
|
DeviceProvider = table.Column<string>(type: "TEXT", maxLength: 512, nullable: false),
|
||||||
X = table.Column<float>(type: "REAL", nullable: false),
|
X = table.Column<float>(type: "REAL", nullable: false),
|
||||||
Y = table.Column<float>(type: "REAL", nullable: false),
|
Y = table.Column<float>(type: "REAL", nullable: false),
|
||||||
Rotation = table.Column<float>(type: "REAL", nullable: false),
|
Rotation = table.Column<float>(type: "REAL", nullable: false),
|
||||||
@ -27,9 +27,9 @@ namespace Artemis.Storage.Migrations
|
|||||||
BlueScale = table.Column<float>(type: "REAL", nullable: false),
|
BlueScale = table.Column<float>(type: "REAL", nullable: false),
|
||||||
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
|
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
PhysicalLayout = table.Column<int>(type: "INTEGER", nullable: false),
|
PhysicalLayout = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
LogicalLayout = table.Column<string>(type: "TEXT", nullable: true),
|
LogicalLayout = table.Column<string>(type: "TEXT", maxLength: 32, nullable: true),
|
||||||
LayoutType = table.Column<string>(type: "TEXT", nullable: true),
|
LayoutType = table.Column<string>(type: "TEXT", maxLength: 64, nullable: true),
|
||||||
LayoutParameter = table.Column<string>(type: "TEXT", nullable: true),
|
LayoutParameter = table.Column<string>(type: "TEXT", maxLength: 512, nullable: true),
|
||||||
Categories = table.Column<string>(type: "TEXT", nullable: false),
|
Categories = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
InputIdentifiers = table.Column<string>(type: "TEXT", nullable: false),
|
InputIdentifiers = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
InputMappings = table.Column<string>(type: "TEXT", nullable: false)
|
InputMappings = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
@ -51,7 +51,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
ReleaseId = table.Column<long>(type: "INTEGER", nullable: false),
|
ReleaseId = table.Column<long>(type: "INTEGER", nullable: false),
|
||||||
ReleaseVersion = table.Column<string>(type: "TEXT", nullable: false),
|
ReleaseVersion = table.Column<string>(type: "TEXT", nullable: false),
|
||||||
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
||||||
Metadata = table.Column<string>(type: "TEXT", nullable: false)
|
Metadata = table.Column<string>(type: "TEXT", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -63,6 +63,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
|
PluginGuid = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false)
|
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
@ -76,7 +77,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
PluginGuid = table.Column<Guid>(type: "TEXT", nullable: false),
|
PluginGuid = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
Name = table.Column<string>(type: "TEXT", maxLength: 128, nullable: false),
|
||||||
Value = table.Column<string>(type: "TEXT", nullable: false)
|
Value = table.Column<string>(type: "TEXT", nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
@ -89,7 +90,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
Name = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
|
||||||
IsCollapsed = table.Column<bool>(type: "INTEGER", nullable: false),
|
IsCollapsed = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
IsSuspended = table.Column<bool>(type: "INTEGER", nullable: false),
|
IsSuspended = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
Order = table.Column<int>(type: "INTEGER", nullable: false)
|
Order = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
@ -104,7 +105,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
Version = table.Column<string>(type: "TEXT", nullable: false),
|
Version = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
|
||||||
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: true)
|
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
@ -113,7 +114,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "PluginFeatureEntity",
|
name: "PluginFeatures",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
@ -123,16 +124,16 @@ namespace Artemis.Storage.Migrations
|
|||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_PluginFeatureEntity", x => x.Id);
|
table.PrimaryKey("PK_PluginFeatures", x => x.Id);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_PluginFeatureEntity_Plugins_PluginEntityId",
|
name: "FK_PluginFeatures_Plugins_PluginEntityId",
|
||||||
column: x => x.PluginEntityId,
|
column: x => x.PluginEntityId,
|
||||||
principalTable: "Plugins",
|
principalTable: "Plugins",
|
||||||
principalColumn: "Id");
|
principalColumn: "Id");
|
||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "ProfileContainerEntity",
|
name: "ProfileContainers",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||||
@ -143,9 +144,9 @@ namespace Artemis.Storage.Migrations
|
|||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_ProfileContainerEntity", x => x.Id);
|
table.PrimaryKey("PK_ProfileContainers", x => x.Id);
|
||||||
table.ForeignKey(
|
table.ForeignKey(
|
||||||
name: "FK_ProfileContainerEntity_ProfileCategories_ProfileCategoryId",
|
name: "FK_ProfileContainers_ProfileCategories_ProfileCategoryId",
|
||||||
column: x => x.ProfileCategoryId,
|
column: x => x.ProfileCategoryId,
|
||||||
principalTable: "ProfileCategories",
|
principalTable: "ProfileCategories",
|
||||||
principalColumn: "Id",
|
principalColumn: "Id",
|
||||||
@ -153,14 +154,54 @@ namespace Artemis.Storage.Migrations
|
|||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_PluginFeatureEntity_PluginEntityId",
|
name: "IX_Entries_EntryId",
|
||||||
table: "PluginFeatureEntity",
|
table: "Entries",
|
||||||
|
column: "EntryId",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PluginFeatures_PluginEntityId",
|
||||||
|
table: "PluginFeatures",
|
||||||
column: "PluginEntityId");
|
column: "PluginEntityId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_ProfileContainerEntity_ProfileCategoryId",
|
name: "IX_Plugins_PluginGuid",
|
||||||
table: "ProfileContainerEntity",
|
table: "Plugins",
|
||||||
|
column: "PluginGuid",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PluginSettings_Name_PluginGuid",
|
||||||
|
table: "PluginSettings",
|
||||||
|
columns: new[] { "Name", "PluginGuid" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_PluginSettings_PluginGuid",
|
||||||
|
table: "PluginSettings",
|
||||||
|
column: "PluginGuid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ProfileCategories_Name",
|
||||||
|
table: "ProfileCategories",
|
||||||
|
column: "Name",
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ProfileContainers_ProfileCategoryId",
|
||||||
|
table: "ProfileContainers",
|
||||||
column: "ProfileCategoryId");
|
column: "ProfileCategoryId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Releases_InstalledAt",
|
||||||
|
table: "Releases",
|
||||||
|
column: "InstalledAt");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Releases_Version",
|
||||||
|
table: "Releases",
|
||||||
|
column: "Version",
|
||||||
|
unique: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -173,13 +214,13 @@ namespace Artemis.Storage.Migrations
|
|||||||
name: "Entries");
|
name: "Entries");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "PluginFeatureEntity");
|
name: "PluginFeatures");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "PluginSettings");
|
name: "PluginSettings");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "ProfileContainerEntity");
|
name: "ProfileContainers");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Releases");
|
name: "Releases");
|
||||||
@ -28,10 +28,16 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Version")
|
b.Property<string>("Version")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("InstalledAt");
|
||||||
|
|
||||||
|
b.HasIndex("Version")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Releases");
|
b.ToTable("Releases");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -44,8 +50,14 @@ namespace Artemis.Storage.Migrations
|
|||||||
b.Property<bool>("IsEnabled")
|
b.Property<bool>("IsEnabled")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<Guid>("PluginGuid")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PluginGuid")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Plugins");
|
b.ToTable("Plugins");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,7 +81,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasIndex("PluginEntityId");
|
b.HasIndex("PluginEntityId");
|
||||||
|
|
||||||
b.ToTable("PluginFeatureEntity");
|
b.ToTable("PluginFeatures");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
||||||
@ -80,6 +92,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<Guid>("PluginGuid")
|
b.Property<Guid>("PluginGuid")
|
||||||
@ -91,6 +104,11 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("PluginGuid");
|
||||||
|
|
||||||
|
b.HasIndex("Name", "PluginGuid")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("PluginSettings");
|
b.ToTable("PluginSettings");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,6 +126,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int>("Order")
|
b.Property<int>("Order")
|
||||||
@ -115,6 +134,9 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("ProfileCategories");
|
b.ToTable("ProfileCategories");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -143,12 +165,13 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasIndex("ProfileCategoryId");
|
b.HasIndex("ProfileCategoryId");
|
||||||
|
|
||||||
b.ToTable("ProfileContainerEntity");
|
b.ToTable("ProfileContainers");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
|
.HasMaxLength(512)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<float>("BlueScale")
|
b.Property<float>("BlueScale")
|
||||||
@ -160,6 +183,7 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.Property<string>("DeviceProvider")
|
b.Property<string>("DeviceProvider")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
|
.HasMaxLength(512)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<float>("GreenScale")
|
b.Property<float>("GreenScale")
|
||||||
@ -169,12 +193,15 @@ namespace Artemis.Storage.Migrations
|
|||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<string>("LayoutParameter")
|
b.Property<string>("LayoutParameter")
|
||||||
|
.HasMaxLength(512)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("LayoutType")
|
b.Property<string>("LayoutType")
|
||||||
|
.HasMaxLength(64)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("LogicalLayout")
|
b.Property<string>("LogicalLayout")
|
||||||
|
.HasMaxLength(32)
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int>("PhysicalLayout")
|
b.Property<int>("PhysicalLayout")
|
||||||
@ -223,7 +250,6 @@ namespace Artemis.Storage.Migrations
|
|||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("Metadata")
|
b.Property<string>("Metadata")
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -239,6 +265,9 @@ namespace Artemis.Storage.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("EntryId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("Entries");
|
b.ToTable("Entries");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,43 +1,50 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Surface;
|
using Artemis.Storage.Entities.Surface;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class DeviceRepository : IDeviceRepository
|
internal class DeviceRepository(Func<ArtemisDbContext> getContext) : IDeviceRepository
|
||||||
{
|
{
|
||||||
private readonly ArtemisDbContext _dbContext;
|
|
||||||
|
|
||||||
public DeviceRepository(ArtemisDbContext dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(DeviceEntity deviceEntity)
|
public void Add(DeviceEntity deviceEntity)
|
||||||
{
|
{
|
||||||
_dbContext.Devices.Add(deviceEntity);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
SaveChanges();
|
dbContext.Devices.Add(deviceEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(DeviceEntity deviceEntity)
|
public void Remove(DeviceEntity deviceEntity)
|
||||||
{
|
{
|
||||||
_dbContext.Devices.Remove(deviceEntity);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
SaveChanges();
|
dbContext.Devices.Remove(deviceEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceEntity? Get(string id)
|
public DeviceEntity? Get(string id)
|
||||||
{
|
{
|
||||||
return _dbContext.Devices.FirstOrDefault(d => d.Id == id);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.Devices.FirstOrDefault(d => d.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<DeviceEntity> GetAll()
|
public IEnumerable<DeviceEntity> GetAll()
|
||||||
{
|
{
|
||||||
return _dbContext.Devices;
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.Devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveChanges()
|
public void Save(DeviceEntity deviceEntity)
|
||||||
{
|
{
|
||||||
_dbContext.SaveChanges();
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.Update(deviceEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveRange(IEnumerable<DeviceEntity> deviceEntities)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.UpdateRange(deviceEntities);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,44 +6,44 @@ using Artemis.Storage.Repositories.Interfaces;
|
|||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class EntryRepository : IEntryRepository
|
internal class EntryRepository(Func<ArtemisDbContext> getContext) : IEntryRepository
|
||||||
{
|
{
|
||||||
private readonly ArtemisDbContext _dbContext;
|
|
||||||
|
|
||||||
public EntryRepository(ArtemisDbContext dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(EntryEntity entryEntity)
|
public void Add(EntryEntity entryEntity)
|
||||||
{
|
{
|
||||||
_dbContext.Entries.Add(entryEntity);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
SaveChanges();
|
dbContext.Entries.Add(entryEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(EntryEntity entryEntity)
|
public void Remove(EntryEntity entryEntity)
|
||||||
{
|
{
|
||||||
_dbContext.Entries.Remove(entryEntity);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
SaveChanges();
|
dbContext.Entries.Remove(entryEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryEntity? Get(Guid id)
|
public EntryEntity? Get(Guid id)
|
||||||
{
|
{
|
||||||
return _dbContext.Entries.FirstOrDefault(s => s.Id == id);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.Entries.FirstOrDefault(s => s.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryEntity? GetByEntryId(long entryId)
|
public EntryEntity? GetByEntryId(long entryId)
|
||||||
{
|
{
|
||||||
return _dbContext.Entries.FirstOrDefault(s => s.EntryId == entryId);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.Entries.FirstOrDefault(s => s.EntryId == entryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<EntryEntity> GetAll()
|
public IEnumerable<EntryEntity> GetAll()
|
||||||
{
|
{
|
||||||
return _dbContext.Entries;
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.Entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveChanges()
|
public void Save(EntryEntity entryEntity)
|
||||||
{
|
{
|
||||||
_dbContext.SaveChanges();
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.Update(entryEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,5 +9,6 @@ public interface IDeviceRepository : IRepository
|
|||||||
void Remove(DeviceEntity deviceEntity);
|
void Remove(DeviceEntity deviceEntity);
|
||||||
DeviceEntity? Get(string id);
|
DeviceEntity? Get(string id);
|
||||||
IEnumerable<DeviceEntity> GetAll();
|
IEnumerable<DeviceEntity> GetAll();
|
||||||
void SaveChanges();
|
void Save(DeviceEntity deviceEntity);
|
||||||
|
void SaveRange(IEnumerable<DeviceEntity> deviceEntities);
|
||||||
}
|
}
|
||||||
@ -11,5 +11,5 @@ public interface IEntryRepository : IRepository
|
|||||||
EntryEntity? Get(Guid id);
|
EntryEntity? Get(Guid id);
|
||||||
EntryEntity? GetByEntryId(long entryId);
|
EntryEntity? GetByEntryId(long entryId);
|
||||||
IEnumerable<EntryEntity> GetAll();
|
IEnumerable<EntryEntity> GetAll();
|
||||||
void SaveChanges();
|
void Save(EntryEntity entryEntity);
|
||||||
}
|
}
|
||||||
@ -5,10 +5,9 @@ namespace Artemis.Storage.Repositories.Interfaces;
|
|||||||
|
|
||||||
public interface IPluginRepository : IRepository
|
public interface IPluginRepository : IRepository
|
||||||
{
|
{
|
||||||
void AddPlugin(PluginEntity pluginEntity);
|
PluginEntity? GetPluginByPluginGuid(Guid pluginGuid);
|
||||||
PluginEntity? GetPluginByGuid(Guid pluginGuid);
|
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
void SavePlugin(PluginEntity pluginEntity);
|
||||||
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||||
void RemoveSettings(Guid pluginGuid);
|
void RemoveSettings(Guid pluginGuid);
|
||||||
void SaveChanges();
|
|
||||||
}
|
}
|
||||||
@ -12,5 +12,6 @@ public interface IProfileCategoryRepository : IRepository
|
|||||||
List<ProfileCategoryEntity> GetAll();
|
List<ProfileCategoryEntity> GetAll();
|
||||||
ProfileCategoryEntity? Get(Guid id);
|
ProfileCategoryEntity? Get(Guid id);
|
||||||
bool IsUnique(string name, Guid? id);
|
bool IsUnique(string name, Guid? id);
|
||||||
void SaveChanges();
|
void Save(ProfileCategoryEntity profileCategoryEntity);
|
||||||
|
void SaveRange(List<ProfileCategoryEntity> profileCategoryEntities);
|
||||||
}
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
using Artemis.Storage.Entities.Profile;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Repositories.Interfaces;
|
||||||
|
|
||||||
|
public interface IProfileRepository : IRepository
|
||||||
|
{
|
||||||
|
void Add(ProfileContainerEntity profileContainerEntity);
|
||||||
|
void Remove(ProfileContainerEntity profileContainerEntity);
|
||||||
|
void Save(ProfileContainerEntity profileContainerEntity);
|
||||||
|
void SaveRange(List<ProfileContainerEntity> profileContainerEntities);
|
||||||
|
void MigrateProfiles();
|
||||||
|
void MigrateProfile(JsonObject? configurationJson, JsonObject? profileJson);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
using Artemis.Storage.Entities.General;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Repositories.Interfaces;
|
||||||
|
|
||||||
|
public interface IReleaseRepository : IRepository
|
||||||
|
{
|
||||||
|
bool SaveVersionInstallDate(string version);
|
||||||
|
ReleaseEntity? GetPreviousInstalledVersion();
|
||||||
|
}
|
||||||
@ -6,44 +6,39 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class PluginRepository : IPluginRepository
|
internal class PluginRepository(Func<ArtemisDbContext> getContext) : IPluginRepository
|
||||||
{
|
{
|
||||||
private readonly ArtemisDbContext _dbContext;
|
public PluginEntity? GetPluginByPluginGuid(Guid pluginGuid)
|
||||||
|
|
||||||
public PluginRepository(ArtemisDbContext dbContext)
|
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
using ArtemisDbContext dbContext = getContext();
|
||||||
}
|
return dbContext.Plugins.Include(p => p.Features).FirstOrDefault(p => p.PluginGuid == pluginGuid);
|
||||||
|
|
||||||
public void AddPlugin(PluginEntity pluginEntity)
|
|
||||||
{
|
|
||||||
_dbContext.Plugins.Add(pluginEntity);
|
|
||||||
SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginEntity? GetPluginByGuid(Guid pluginGuid)
|
|
||||||
{
|
|
||||||
return _dbContext.Plugins.Include(p => p.Features).FirstOrDefault(p => p.Id == pluginGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
|
||||||
{
|
|
||||||
_dbContext.PluginSettings.Add(pluginSettingEntity);
|
|
||||||
SaveChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _dbContext.PluginSettings.FirstOrDefault(p => p.Name == name && p.PluginGuid == pluginGuid);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.PluginSettings.FirstOrDefault(p => p.Name == name && p.PluginGuid == pluginGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSettings(Guid pluginGuid)
|
public void RemoveSettings(Guid pluginGuid)
|
||||||
{
|
{
|
||||||
_dbContext.PluginSettings.RemoveRange(_dbContext.PluginSettings.Where(s => s.PluginGuid == pluginGuid));
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.PluginSettings.RemoveRange(dbContext.PluginSettings.Where(s => s.PluginGuid == pluginGuid));
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveChanges()
|
public void SaveSetting(PluginSettingEntity pluginSettingEntity)
|
||||||
{
|
{
|
||||||
_dbContext.SaveChanges();
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.PluginSettings.Update(pluginSettingEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SavePlugin(PluginEntity pluginEntity)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.Update(pluginEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7,47 +7,63 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class ProfileCategoryRepository : IProfileCategoryRepository
|
internal class ProfileCategoryRepository(Func<ArtemisDbContext> getContext, IProfileRepository profileRepository) : IProfileCategoryRepository
|
||||||
{
|
{
|
||||||
private readonly ArtemisDbContext _dbContext;
|
private bool _migratedProfiles;
|
||||||
|
|
||||||
public ProfileCategoryRepository(ArtemisDbContext dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(ProfileCategoryEntity profileCategoryEntity)
|
public void Add(ProfileCategoryEntity profileCategoryEntity)
|
||||||
{
|
{
|
||||||
_dbContext.ProfileCategories.Add(profileCategoryEntity);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
SaveChanges();
|
dbContext.ProfileCategories.Add(profileCategoryEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(ProfileCategoryEntity profileCategoryEntity)
|
public void Remove(ProfileCategoryEntity profileCategoryEntity)
|
||||||
{
|
{
|
||||||
_dbContext.ProfileCategories.Remove(profileCategoryEntity);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
SaveChanges();
|
dbContext.ProfileCategories.Remove(profileCategoryEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ProfileCategoryEntity> GetAll()
|
public List<ProfileCategoryEntity> GetAll()
|
||||||
{
|
{
|
||||||
return _dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).ToList();
|
if (!_migratedProfiles)
|
||||||
|
{
|
||||||
|
profileRepository.MigrateProfiles();
|
||||||
|
_migratedProfiles = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileCategoryEntity? Get(Guid id)
|
public ProfileCategoryEntity? Get(Guid id)
|
||||||
{
|
{
|
||||||
return _dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).FirstOrDefault(c => c.Id == id);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).FirstOrDefault(c => c.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(ProfileCategoryEntity profileCategoryEntity)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.Update(profileCategoryEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveRange(List<ProfileCategoryEntity> profileCategoryEntities)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.UpdateRange(profileCategoryEntities);
|
||||||
|
dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsUnique(string name, Guid? id)
|
public bool IsUnique(string name, Guid? id)
|
||||||
{
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
|
||||||
name = name.Trim();
|
name = name.Trim();
|
||||||
if (id == null)
|
return id == null
|
||||||
return _dbContext.ProfileCategories.Any(p => p.Name == name);
|
? dbContext.ProfileCategories.Any(p => p.Name == name)
|
||||||
return _dbContext.ProfileCategories.Any(p => p.Name == name && p.Id != id.Value);
|
: dbContext.ProfileCategories.Any(p => p.Name == name && p.Id != id.Value);
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveChanges()
|
|
||||||
{
|
|
||||||
_dbContext.SaveChanges();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
91
src/Artemis.Storage/Repositories/ProfileRepository.cs
Normal file
91
src/Artemis.Storage/Repositories/ProfileRepository.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
using Artemis.Storage.Entities;
|
||||||
|
using Artemis.Storage.Entities.Profile;
|
||||||
|
using Artemis.Storage.Exceptions;
|
||||||
|
using Artemis.Storage.Migrations;
|
||||||
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
|
public class ProfileRepository(Func<ArtemisDbContext> getContext, List<IProfileMigration> profileMigrators) : IProfileRepository
|
||||||
|
{
|
||||||
|
public void Add(ProfileContainerEntity profileContainerEntity)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.ProfileContainers.Add(profileContainerEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(ProfileContainerEntity profileContainerEntity)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.ProfileContainers.Remove(profileContainerEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(ProfileContainerEntity profileContainerEntity)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.Update(profileContainerEntity);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveRange(List<ProfileContainerEntity> profileContainerEntities)
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
dbContext.UpdateRange(profileContainerEntities);
|
||||||
|
dbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MigrateProfiles()
|
||||||
|
{
|
||||||
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
int max = profileMigrators.Max(m => m.Version);
|
||||||
|
|
||||||
|
// Query the ProfileContainerEntity table directly, grabbing the ID, profile, and configuration
|
||||||
|
List<RawProfileContainer> containers = dbContext.Database
|
||||||
|
.SqlQueryRaw<RawProfileContainer>("SELECT Id, Profile, ProfileConfiguration FROM ProfileContainers WHERE json_extract(ProfileConfiguration, '$.Version') < {0}", max)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (RawProfileContainer rawProfileContainer in containers)
|
||||||
|
{
|
||||||
|
JsonObject? profileConfiguration = JsonNode.Parse(rawProfileContainer.ProfileConfiguration)?.AsObject();
|
||||||
|
JsonObject? profile = JsonNode.Parse(rawProfileContainer.Profile)?.AsObject();
|
||||||
|
|
||||||
|
if (profileConfiguration == null || profile == null)
|
||||||
|
throw new ArtemisStorageException("Failed to parse profile or profile configuration");
|
||||||
|
|
||||||
|
MigrateProfile(profileConfiguration, profile);
|
||||||
|
rawProfileContainer.Profile = profile.ToString();
|
||||||
|
rawProfileContainer.ProfileConfiguration = profileConfiguration.ToString();
|
||||||
|
|
||||||
|
// Write the updated containers back to the database
|
||||||
|
dbContext.Database.ExecuteSqlRaw(
|
||||||
|
"UPDATE ProfileContainers SET Profile = {0}, ProfileConfiguration = {1} WHERE Id = {2}",
|
||||||
|
rawProfileContainer.Profile,
|
||||||
|
rawProfileContainer.ProfileConfiguration,
|
||||||
|
rawProfileContainer.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,34 +5,24 @@ using Artemis.Storage.Repositories.Interfaces;
|
|||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
public class ReleaseRepository : IReleaseRepository
|
public class ReleaseRepository(Func<ArtemisDbContext> getContext) : IReleaseRepository
|
||||||
{
|
{
|
||||||
private readonly ArtemisDbContext _dbContext;
|
|
||||||
|
|
||||||
public ReleaseRepository(ArtemisDbContext dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SaveVersionInstallDate(string version)
|
public bool SaveVersionInstallDate(string version)
|
||||||
{
|
{
|
||||||
ReleaseEntity? release = _dbContext.Releases.FirstOrDefault(r => r.Version == version);
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
|
||||||
|
ReleaseEntity? release = dbContext.Releases.FirstOrDefault(r => r.Version == version);
|
||||||
if (release != null)
|
if (release != null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_dbContext.Releases.Add(new ReleaseEntity {Version = version, InstalledAt = DateTimeOffset.UtcNow});
|
dbContext.Releases.Add(new ReleaseEntity {Version = version, InstalledAt = DateTimeOffset.UtcNow});
|
||||||
_dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReleaseEntity? GetPreviousInstalledVersion()
|
public ReleaseEntity? GetPreviousInstalledVersion()
|
||||||
{
|
{
|
||||||
return _dbContext.Releases.OrderByDescending(r => r.InstalledAt).Skip(1).FirstOrDefault();
|
using ArtemisDbContext dbContext = getContext();
|
||||||
|
return dbContext.Releases.OrderByDescending(r => r.InstalledAt).Skip(1).FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public interface IReleaseRepository : IRepository
|
|
||||||
{
|
|
||||||
bool SaveVersionInstallDate(string version);
|
|
||||||
ReleaseEntity? GetPreviousInstalledVersion();
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.Storage.Legacy;
|
||||||
using Artemis.UI.Linux.DryIoc;
|
using Artemis.UI.Linux.DryIoc;
|
||||||
using Artemis.UI.Linux.Providers.Input;
|
using Artemis.UI.Linux.Providers.Input;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
@ -20,7 +21,10 @@ public class App : Application
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_container = ArtemisBootstrapper.Bootstrap(this, c => c.RegisterProviders());
|
_container = ArtemisBootstrapper.Bootstrap(this, c => c.RegisterProviders());
|
||||||
|
|
||||||
Program.CreateLogger(_container);
|
Program.CreateLogger(_container);
|
||||||
|
LegacyMigrationService.MigrateToSqlite(_container);
|
||||||
|
|
||||||
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Artemis.Storage.Legacy\Artemis.Storage.Legacy.csproj" />
|
||||||
<ProjectReference Include="..\Artemis.UI\Artemis.UI.csproj" />
|
<ProjectReference Include="..\Artemis.UI\Artemis.UI.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using Artemis.Storage.Legacy;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
@ -14,7 +15,10 @@ public class App : Application
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_container = ArtemisBootstrapper.Bootstrap(this);
|
_container = ArtemisBootstrapper.Bootstrap(this);
|
||||||
|
|
||||||
Program.CreateLogger(_container);
|
Program.CreateLogger(_container);
|
||||||
|
LegacyMigrationService.MigrateToSqlite(_container);
|
||||||
|
|
||||||
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Artemis.Storage.Legacy\Artemis.Storage.Legacy.csproj" />
|
||||||
<ProjectReference Include="..\Artemis.UI\Artemis.UI.csproj" />
|
<ProjectReference Include="..\Artemis.UI\Artemis.UI.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -21,6 +21,7 @@
|
|||||||
<PackageReference Include="Material.Icons.Avalonia" />
|
<PackageReference Include="Material.Icons.Avalonia" />
|
||||||
<PackageReference Include="ReactiveUI" />
|
<PackageReference Include="ReactiveUI" />
|
||||||
<PackageReference Include="ReactiveUI.Validation" />
|
<PackageReference Include="ReactiveUI.Validation" />
|
||||||
|
<PackageReference Include="JetBrains.Annotations" PrivateAssets="All"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
|||||||
@ -7,6 +7,7 @@ using System.Net.Http;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
|
using Artemis.Storage.Legacy;
|
||||||
using Artemis.UI.Windows.DryIoc;
|
using Artemis.UI.Windows.DryIoc;
|
||||||
using Artemis.UI.Windows.Providers.Input;
|
using Artemis.UI.Windows.Providers.Input;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
@ -34,7 +35,10 @@ public class App : Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
_container = ArtemisBootstrapper.Bootstrap(this, c => c.RegisterProviders());
|
_container = ArtemisBootstrapper.Bootstrap(this, c => c.RegisterProviders());
|
||||||
|
|
||||||
Program.CreateLogger(_container);
|
Program.CreateLogger(_container);
|
||||||
|
LegacyMigrationService.MigrateToSqlite(_container);
|
||||||
|
|
||||||
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
<ProjectReference Include="..\Artemis.Core\Artemis.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Artemis.Storage.Legacy\Artemis.Storage.Legacy.csproj" />
|
||||||
<ProjectReference Include="..\Artemis.UI\Artemis.UI.csproj" />
|
<ProjectReference Include="..\Artemis.UI\Artemis.UI.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user