mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Storage - Introduce SQLite+EF Core
This commit is contained in:
parent
9132301dbf
commit
10850adb24
@ -31,11 +31,9 @@ public static class ContainerExtensions
|
|||||||
|
|
||||||
// Bind storage
|
// Bind storage
|
||||||
container.RegisterDelegate(() => StorageManager.CreateRepository(Constants.DataFolder), Reuse.Singleton);
|
container.RegisterDelegate(() => StorageManager.CreateRepository(Constants.DataFolder), Reuse.Singleton);
|
||||||
container.Register<StorageMigrationService>(Reuse.Singleton);
|
|
||||||
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IRepository>(), Reuse.Singleton);
|
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IRepository>(), Reuse.Singleton);
|
||||||
|
|
||||||
// Bind migrations
|
// Bind migrations
|
||||||
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IStorageMigration>(), Reuse.Singleton, nonPublicServiceTypes: true);
|
|
||||||
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IProfileMigration>(), Reuse.Singleton, nonPublicServiceTypes: true);
|
container.RegisterMany(storageAssembly, type => type.IsAssignableTo<IProfileMigration>(), Reuse.Singleton, nonPublicServiceTypes: true);
|
||||||
|
|
||||||
container.RegisterMany(coreAssembly, type => type.IsAssignableTo<ILayoutProvider>(), Reuse.Singleton);
|
container.RegisterMany(coreAssembly, type => type.IsAssignableTo<ILayoutProvider>(), Reuse.Singleton);
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class ArtemisDeviceInputIdentifier
|
|||||||
/// used by
|
/// used by
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="identifier">A value used to identify the device</param>
|
/// <param name="identifier">A value used to identify the device</param>
|
||||||
internal ArtemisDeviceInputIdentifier(string inputProvider, object identifier)
|
internal ArtemisDeviceInputIdentifier(string inputProvider, string identifier)
|
||||||
{
|
{
|
||||||
InputProvider = inputProvider;
|
InputProvider = inputProvider;
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
@ -28,5 +28,5 @@ public class ArtemisDeviceInputIdentifier
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value used to identify the device
|
/// Gets or sets a value used to identify the device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Identifier { get; set; }
|
public string Identifier { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Artemis.Core;
|
namespace Artemis.Core;
|
||||||
|
|
||||||
@ -7,6 +8,11 @@ namespace Artemis.Core;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPluginSetting
|
public interface IPluginSetting
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The JSON serializer options used when serializing settings
|
||||||
|
/// </summary>
|
||||||
|
protected static readonly JsonSerializerOptions SerializerOptions = CoreJson.GetJsonSerializerOptions();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the setting, unique to this plugin
|
/// The name of the setting, unique to this plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
Name = pluginSettingEntity.Name;
|
Name = pluginSettingEntity.Name;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_value = CoreJson.Deserialize<T>(pluginSettingEntity.Value)!;
|
_value = pluginSettingEntity.Value.Deserialize<T>(IPluginSetting.SerializerOptions) ?? default!;
|
||||||
}
|
}
|
||||||
catch (JsonException)
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
@ -76,7 +77,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool HasChanged => CoreJson.Serialize(Value) != _pluginSettingEntity.Value;
|
public bool HasChanged => !JsonNode.DeepEquals(JsonSerializer.SerializeToNode(Value, IPluginSetting.SerializerOptions), _pluginSettingEntity.Value);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool AutoSave { get; set; }
|
public bool AutoSave { get; set; }
|
||||||
@ -84,7 +85,7 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void RejectChanges()
|
public void RejectChanges()
|
||||||
{
|
{
|
||||||
Value = CoreJson.Deserialize<T>(_pluginSettingEntity.Value);
|
Value = _pluginSettingEntity.Value.Deserialize<T>(IPluginSetting.SerializerOptions) ?? default!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -93,8 +94,8 @@ public class PluginSetting<T> : CorePropertyChanged, IPluginSetting
|
|||||||
if (!HasChanged)
|
if (!HasChanged)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_pluginSettingEntity.Value = CoreJson.Serialize(Value);
|
_pluginSettingEntity.Value = JsonSerializer.SerializeToNode(Value, IPluginSetting.SerializerOptions) ?? new JsonObject();
|
||||||
_pluginRepository.SaveSetting(_pluginSettingEntity);
|
_pluginRepository.SaveChanges();
|
||||||
OnSettingSaved();
|
OnSettingSaved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ public class InputProviderIdentifierEventArgs : EventArgs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identifier">A value that can be used to identify this device</param>
|
/// <param name="identifier">A value that can be used to identify this device</param>
|
||||||
/// <param name="deviceType">The type of device this identifier belongs to</param>
|
/// <param name="deviceType">The type of device this identifier belongs to</param>
|
||||||
public InputProviderIdentifierEventArgs(object identifier, InputDeviceType deviceType)
|
public InputProviderIdentifierEventArgs(string identifier, InputDeviceType deviceType)
|
||||||
{
|
{
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
DeviceType = deviceType;
|
DeviceType = deviceType;
|
||||||
@ -21,7 +21,7 @@ public class InputProviderIdentifierEventArgs : EventArgs
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value that can be used to identify this device
|
/// Gets a value that can be used to identify this device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Identifier { get; }
|
public string Identifier { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of device this identifier belongs to
|
/// Gets the type of device this identifier belongs to
|
||||||
|
|||||||
@ -113,7 +113,7 @@ public abstract class InputProvider : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identifier">A value that can be used to identify this device</param>
|
/// <param name="identifier">A value that can be used to identify this device</param>
|
||||||
/// <param name="deviceType">The type of device this identifier belongs to</param>
|
/// <param name="deviceType">The type of device this identifier belongs to</param>
|
||||||
protected virtual void OnIdentifierReceived(object identifier, InputDeviceType deviceType)
|
protected virtual void OnIdentifierReceived(string identifier, InputDeviceType deviceType)
|
||||||
{
|
{
|
||||||
IdentifierReceived?.Invoke(this, new InputProviderIdentifierEventArgs(identifier, deviceType));
|
IdentifierReceived?.Invoke(this, new InputProviderIdentifierEventArgs(identifier, deviceType));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,19 +145,7 @@ public interface IPluginManagementService : IArtemisService, IDisposable
|
|||||||
/// <param name="device"></param>
|
/// <param name="device"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
DeviceProvider GetDeviceProviderByDevice(IRGBDevice device);
|
DeviceProvider GetDeviceProviderByDevice(IRGBDevice device);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queues the provided plugin to be deleted the next time Artemis starts, before plugins are loaded
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plugin">The plugin to delete</param>
|
|
||||||
void QueuePluginDeletion(Plugin plugin);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the provided plugin for the deletion queue it was added to via <see cref="QueuePluginDeletion" />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="plugin">The plugin to dequeue</param>
|
|
||||||
void DequeuePluginDeletion(Plugin plugin);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when built-in plugins are being loaded
|
/// Occurs when built-in plugins are being loaded
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -30,22 +30,18 @@ internal class PluginManagementService : IPluginManagementService
|
|||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IPluginRepository _pluginRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private readonly List<Plugin> _plugins;
|
private readonly List<Plugin> _plugins;
|
||||||
private readonly IQueuedActionRepository _queuedActionRepository;
|
|
||||||
private FileSystemWatcher? _hotReloadWatcher;
|
private FileSystemWatcher? _hotReloadWatcher;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private bool _isElevated;
|
private bool _isElevated;
|
||||||
|
|
||||||
public PluginManagementService(IContainer container, ILogger logger, IPluginRepository pluginRepository, IDeviceRepository deviceRepository, IQueuedActionRepository queuedActionRepository)
|
public PluginManagementService(IContainer container, ILogger logger, IPluginRepository pluginRepository, IDeviceRepository deviceRepository)
|
||||||
{
|
{
|
||||||
_container = container;
|
_container = container;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_pluginRepository = pluginRepository;
|
_pluginRepository = pluginRepository;
|
||||||
_deviceRepository = deviceRepository;
|
_deviceRepository = deviceRepository;
|
||||||
_queuedActionRepository = queuedActionRepository;
|
|
||||||
_plugins = new List<Plugin>();
|
_plugins = new List<Plugin>();
|
||||||
|
|
||||||
ProcessPluginDeletionQueue();
|
|
||||||
|
|
||||||
StartHotReload();
|
StartHotReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,59 +796,7 @@ internal class PluginManagementService : IPluginManagementService
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Queued actions
|
|
||||||
|
|
||||||
public void QueuePluginDeletion(Plugin plugin)
|
|
||||||
{
|
|
||||||
_queuedActionRepository.Add(new QueuedActionEntity
|
|
||||||
{
|
|
||||||
Type = "DeletePlugin",
|
|
||||||
CreatedAt = DateTimeOffset.Now,
|
|
||||||
Parameters = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{"pluginGuid", plugin.Guid.ToString()},
|
|
||||||
{"plugin", plugin.ToString()},
|
|
||||||
{"directory", plugin.Directory.FullName}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DequeuePluginDeletion(Plugin plugin)
|
|
||||||
{
|
|
||||||
QueuedActionEntity? queuedActionEntity = _queuedActionRepository.GetByType("DeletePlugin").FirstOrDefault(q => q.Parameters["pluginGuid"].Equals(plugin.Guid.ToString()));
|
|
||||||
if (queuedActionEntity != null)
|
|
||||||
_queuedActionRepository.Remove(queuedActionEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessPluginDeletionQueue()
|
|
||||||
{
|
|
||||||
foreach (QueuedActionEntity queuedActionEntity in _queuedActionRepository.GetByType("DeletePlugin"))
|
|
||||||
{
|
|
||||||
string? directory = queuedActionEntity.Parameters["directory"].ToString();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Directory.Exists(directory))
|
|
||||||
{
|
|
||||||
_logger.Information("Queued plugin deletion - deleting folder - {plugin}", queuedActionEntity.Parameters["plugin"]);
|
|
||||||
Directory.Delete(directory!, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Information("Queued plugin deletion - folder already deleted - {plugin}", queuedActionEntity.Parameters["plugin"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_queuedActionRepository.Remove(queuedActionEntity);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Warning(e, "Queued plugin deletion failed - {plugin}", queuedActionEntity.Parameters["plugin"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Storage
|
#region Storage
|
||||||
|
|
||||||
private void SavePlugin(Plugin plugin)
|
private void SavePlugin(Plugin plugin)
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="LiteDB" />
|
<PackageReference Include="LiteDB" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||||
<PackageReference Include="Serilog" />
|
<PackageReference Include="Serilog" />
|
||||||
<PackageReference Include="System.Text.Json" />
|
<PackageReference Include="System.Text.Json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
37
src/Artemis.Storage/ArtemisDbContext.cs
Normal file
37
src/Artemis.Storage/ArtemisDbContext.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Artemis.Storage.Entities.General;
|
||||||
|
using Artemis.Storage.Entities.Plugins;
|
||||||
|
using Artemis.Storage.Entities.Profile;
|
||||||
|
using Artemis.Storage.Entities.Surface;
|
||||||
|
using Artemis.Storage.Entities.Workshop;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Artemis.Storage;
|
||||||
|
|
||||||
|
public class ArtemisDbContext : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<DeviceEntity> Devices => Set<DeviceEntity>();
|
||||||
|
public DbSet<EntryEntity> Entries => Set<EntryEntity>();
|
||||||
|
public DbSet<PluginEntity> Plugins => Set<PluginEntity>();
|
||||||
|
public DbSet<PluginSettingEntity> PluginSettings => Set<PluginSettingEntity>();
|
||||||
|
public DbSet<ProfileCategoryEntity> ProfileCategories => Set<ProfileCategoryEntity>();
|
||||||
|
public DbSet<ProfileContainerEntity> Profiles => Set<ProfileContainerEntity>();
|
||||||
|
public DbSet<ReleaseEntity> Releases => Set<ReleaseEntity>();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
modelBuilder.Entity<DeviceEntity>()
|
||||||
|
.OwnsOne(d => d.InputIdentifiers, builder => builder.ToJson())
|
||||||
|
.OwnsOne(d => d.InputMappings, builder => builder.ToJson());
|
||||||
|
|
||||||
|
modelBuilder.Entity<EntryEntity>()
|
||||||
|
.OwnsOne(e => e.Metadata, builder => builder.ToJson());
|
||||||
|
|
||||||
|
modelBuilder.Entity<PluginSettingEntity>()
|
||||||
|
.OwnsOne(s => s.Value, builder => builder.ToJson());
|
||||||
|
|
||||||
|
modelBuilder.Entity<ProfileContainerEntity>()
|
||||||
|
.OwnsOne(c => c.ProfileConfiguration, builder => builder.ToJson())
|
||||||
|
.OwnsOne(c => c.Profile, builder => builder.ToJson());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.General;
|
|
||||||
|
|
||||||
public class QueuedActionEntity
|
|
||||||
{
|
|
||||||
public QueuedActionEntity()
|
|
||||||
{
|
|
||||||
Parameters = new Dictionary<string, object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string Type { get; set; } = string.Empty;
|
|
||||||
public DateTimeOffset CreatedAt { get; set; }
|
|
||||||
|
|
||||||
public Dictionary<string, object> Parameters { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Plugins;
|
namespace Artemis.Storage.Entities.Plugins;
|
||||||
|
|
||||||
@ -11,5 +12,5 @@ public class PluginSettingEntity
|
|||||||
public Guid PluginGuid { get; set; }
|
public Guid PluginGuid { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string Value { get; set; } = string.Empty;
|
public JsonNode Value { get; set; } = new JsonObject();
|
||||||
}
|
}
|
||||||
@ -12,5 +12,12 @@ public class ProfileCategoryEntity
|
|||||||
public bool IsSuspended { get; set; }
|
public bool IsSuspended { get; set; }
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
public List<ProfileConfigurationEntity> ProfileConfigurations { get; set; } = new();
|
public List<ProfileContainerEntity> ProfileConfigurations { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProfileContainerEntity
|
||||||
|
{
|
||||||
|
public byte[] Icon { get; set; } = Array.Empty<byte>();
|
||||||
|
public ProfileConfigurationEntity ProfileConfiguration { get; set; } = new();
|
||||||
|
public ProfileEntity Profile { get; set; } = new();
|
||||||
}
|
}
|
||||||
@ -27,5 +27,5 @@ public class ProfileConfigurationEntity
|
|||||||
public Guid ProfileId { get; set; }
|
public Guid ProfileId { get; set; }
|
||||||
|
|
||||||
public bool FadeInAndOut { get; set; }
|
public bool FadeInAndOut { get; set; }
|
||||||
public int Version { get; set; } = StorageMigrationService.PROFILE_VERSION;
|
public int Version { get; set; }
|
||||||
}
|
}
|
||||||
@ -42,5 +42,5 @@ public class InputMappingEntity
|
|||||||
public class DeviceInputIdentifierEntity
|
public class DeviceInputIdentifierEntity
|
||||||
{
|
{
|
||||||
public string InputProvider { get; set; } = string.Empty;
|
public string InputProvider { get; set; } = string.Empty;
|
||||||
public object Identifier { get; set; } = string.Empty;
|
public string Identifier { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Workshop;
|
namespace Artemis.Storage.Entities.Workshop;
|
||||||
|
|
||||||
@ -17,5 +18,5 @@ public class EntryEntity
|
|||||||
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,JsonNode>? Metadata { get; set; }
|
||||||
}
|
}
|
||||||
@ -1,9 +0,0 @@
|
|||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations;
|
|
||||||
|
|
||||||
public interface IStorageMigration
|
|
||||||
{
|
|
||||||
int UserVersion { get; }
|
|
||||||
void Apply(LiteRepository repository);
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0020AvaloniaReset : IStorageMigration
|
|
||||||
{
|
|
||||||
public int UserVersion => 20;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
repository.Database.Commit();
|
|
||||||
|
|
||||||
List<string> collectionNames = repository.Database.GetCollectionNames().ToList();
|
|
||||||
foreach (string collectionName in collectionNames)
|
|
||||||
repository.Database.DropCollection(collectionName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
using Artemis.Storage.Entities.Profile.Nodes;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0021GradientNodes : IStorageMigration
|
|
||||||
{
|
|
||||||
private void MigrateDataBinding(PropertyEntity property)
|
|
||||||
{
|
|
||||||
NodeScriptEntity? script = property.DataBinding?.NodeScript;
|
|
||||||
NodeEntity? exitNode = script?.Nodes.FirstOrDefault(s => s.IsExitNode);
|
|
||||||
if (script == null || exitNode == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Create a new node at the same position of the exit node
|
|
||||||
NodeEntity gradientNode = new()
|
|
||||||
{
|
|
||||||
Id = Guid.NewGuid(),
|
|
||||||
Type = "ColorGradientNode",
|
|
||||||
ProviderId = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78",
|
|
||||||
Name = "Color Gradient",
|
|
||||||
Description = "Outputs a color gradient with the given colors",
|
|
||||||
X = exitNode.X,
|
|
||||||
Y = exitNode.Y,
|
|
||||||
Storage = property.Value // Copy the value of the property into the node storage
|
|
||||||
};
|
|
||||||
script.Nodes.Add(gradientNode);
|
|
||||||
|
|
||||||
// Move all connections of the exit node to the new node
|
|
||||||
foreach (NodeConnectionEntity connection in script.Connections)
|
|
||||||
{
|
|
||||||
if (connection.SourceNode == exitNode.Id)
|
|
||||||
{
|
|
||||||
connection.SourceNode = gradientNode.Id;
|
|
||||||
connection.SourcePinId++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect the data binding node to the source node
|
|
||||||
script.Connections.Add(new NodeConnectionEntity
|
|
||||||
{
|
|
||||||
SourceType = "ColorGradient",
|
|
||||||
SourceNode = exitNode.Id,
|
|
||||||
SourcePinCollectionId = -1,
|
|
||||||
SourcePinId = 0,
|
|
||||||
TargetType = "ColorGradient",
|
|
||||||
TargetNode = gradientNode.Id,
|
|
||||||
TargetPinCollectionId = -1,
|
|
||||||
TargetPinId = 0
|
|
||||||
});
|
|
||||||
|
|
||||||
// Move the exit node to the right
|
|
||||||
exitNode.X += 300;
|
|
||||||
exitNode.Y += 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateDataBinding(PropertyGroupEntity? propertyGroup)
|
|
||||||
{
|
|
||||||
if (propertyGroup == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups)
|
|
||||||
MigrateDataBinding(propertyGroupPropertyGroup);
|
|
||||||
|
|
||||||
foreach (PropertyEntity property in propertyGroup.Properties)
|
|
||||||
{
|
|
||||||
if (property.Value.StartsWith("[{\"Color\":\"") && property.DataBinding?.NodeScript != null && property.DataBinding.IsEnabled)
|
|
||||||
MigrateDataBinding(property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int UserVersion => 21;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
// Find all color gradient data bindings, there's no really good way to do this so infer it from the value
|
|
||||||
List<ProfileEntity> profiles = repository.Query<ProfileEntity>().ToList();
|
|
||||||
foreach (ProfileEntity profileEntity in profiles)
|
|
||||||
{
|
|
||||||
foreach (LayerEntity layer in profileEntity.Layers.Where(le => le.LayerBrush != null))
|
|
||||||
MigrateDataBinding(layer.LayerBrush?.PropertyGroup);
|
|
||||||
|
|
||||||
repository.Update(profileEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
using Artemis.Storage.Entities.Profile.Abstract;
|
|
||||||
using Artemis.Storage.Entities.Profile.Conditions;
|
|
||||||
using Artemis.Storage.Entities.Profile.Nodes;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0022TransitionNodes : IStorageMigration
|
|
||||||
{
|
|
||||||
private void MigrateNodeScript(NodeScriptEntity? nodeScript)
|
|
||||||
{
|
|
||||||
if (nodeScript == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (NodeEntity node in nodeScript.Nodes)
|
|
||||||
{
|
|
||||||
if (node.Type == "NumericEasingNode")
|
|
||||||
node.Type = "NumericTransitionNode";
|
|
||||||
else if (node.Type == "ColorGradientEasingNode")
|
|
||||||
node.Type = "ColorGradientTransitionNode";
|
|
||||||
else if (node.Type == "SKColorEasingNode")
|
|
||||||
node.Type = "SKColorTransitionNode";
|
|
||||||
else if (node.Type == "EasingTypeNode")
|
|
||||||
node.Type = "EasingFunctionNode";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigratePropertyGroup(PropertyGroupEntity? propertyGroup)
|
|
||||||
{
|
|
||||||
if (propertyGroup == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (PropertyGroupEntity childPropertyGroup in propertyGroup.PropertyGroups)
|
|
||||||
MigratePropertyGroup(childPropertyGroup);
|
|
||||||
foreach (PropertyEntity property in propertyGroup.Properties)
|
|
||||||
MigrateNodeScript(property.DataBinding?.NodeScript);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateDisplayCondition(IConditionEntity? conditionEntity)
|
|
||||||
{
|
|
||||||
if (conditionEntity is EventConditionEntity eventConditionEntity)
|
|
||||||
MigrateNodeScript(eventConditionEntity.Script);
|
|
||||||
else if (conditionEntity is StaticConditionEntity staticConditionEntity)
|
|
||||||
MigrateNodeScript(staticConditionEntity.Script);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int UserVersion => 22;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
// Migrate profile configuration display conditions
|
|
||||||
List<ProfileCategoryEntity> categories = repository.Query<ProfileCategoryEntity>().ToList();
|
|
||||||
foreach (ProfileCategoryEntity profileCategoryEntity in categories)
|
|
||||||
{
|
|
||||||
foreach (ProfileConfigurationEntity profileConfigurationEntity in profileCategoryEntity.ProfileConfigurations)
|
|
||||||
MigrateNodeScript(profileConfigurationEntity.ActivationCondition);
|
|
||||||
repository.Update(profileCategoryEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Migrate profile display conditions and data bindings
|
|
||||||
List<ProfileEntity> profiles = repository.Query<ProfileEntity>().ToList();
|
|
||||||
foreach (ProfileEntity profileEntity in profiles)
|
|
||||||
{
|
|
||||||
foreach (LayerEntity layer in profileEntity.Layers)
|
|
||||||
{
|
|
||||||
MigratePropertyGroup(layer.LayerBrush?.PropertyGroup);
|
|
||||||
MigratePropertyGroup(layer.GeneralPropertyGroup);
|
|
||||||
MigratePropertyGroup(layer.TransformPropertyGroup);
|
|
||||||
foreach (LayerEffectEntity layerEffectEntity in layer.LayerEffects)
|
|
||||||
MigratePropertyGroup(layerEffectEntity.PropertyGroup);
|
|
||||||
MigrateDisplayCondition(layer.DisplayCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (FolderEntity folder in profileEntity.Folders)
|
|
||||||
{
|
|
||||||
foreach (LayerEffectEntity folderLayerEffect in folder.LayerEffects)
|
|
||||||
MigratePropertyGroup(folderLayerEffect.PropertyGroup);
|
|
||||||
MigrateDisplayCondition(folder.DisplayCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
repository.Update(profileEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0023LayoutProviders : IStorageMigration
|
|
||||||
{
|
|
||||||
public int UserVersion => 23;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
ILiteCollection<BsonDocument> deviceEntities = repository.Database.GetCollection("DeviceEntity");
|
|
||||||
List<BsonDocument> toUpdate = new();
|
|
||||||
|
|
||||||
foreach (BsonDocument bsonDocument in deviceEntities.FindAll())
|
|
||||||
{
|
|
||||||
if (bsonDocument.TryGetValue("CustomLayoutPath", out BsonValue customLayoutPath) && customLayoutPath.IsString && !string.IsNullOrEmpty(customLayoutPath.AsString))
|
|
||||||
{
|
|
||||||
bsonDocument.Add("LayoutType", new BsonValue("CustomPath"));
|
|
||||||
bsonDocument.Add("LayoutParameter", new BsonValue(customLayoutPath.AsString));
|
|
||||||
}
|
|
||||||
else if (bsonDocument.TryGetValue("DisableDefaultLayout", out BsonValue disableDefaultLayout) && disableDefaultLayout.AsBoolean)
|
|
||||||
bsonDocument.Add("LayoutType", new BsonValue("None"));
|
|
||||||
else
|
|
||||||
bsonDocument.Add("LayoutType", new BsonValue("Default"));
|
|
||||||
|
|
||||||
bsonDocument.Remove("CustomLayoutPath");
|
|
||||||
bsonDocument.Remove("DisableDefaultLayout");
|
|
||||||
toUpdate.Add(bsonDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
deviceEntities.Update(toUpdate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0024NodeProviders : IStorageMigration
|
|
||||||
{
|
|
||||||
public int UserVersion => 24;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
ILiteCollection<BsonDocument> categoryCollection = repository.Database.GetCollection("ProfileCategoryEntity");
|
|
||||||
List<BsonDocument> categoriesToUpdate = new();
|
|
||||||
foreach (BsonDocument profileCategoryBson in categoryCollection.FindAll())
|
|
||||||
{
|
|
||||||
BsonArray? profiles = profileCategoryBson["ProfileConfigurations"]?.AsArray;
|
|
||||||
if (profiles != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue profile in profiles)
|
|
||||||
profile["Version"] = 1;
|
|
||||||
categoriesToUpdate.Add(profileCategoryBson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
categoryCollection.Update(categoriesToUpdate);
|
|
||||||
|
|
||||||
ILiteCollection<BsonDocument> collection = repository.Database.GetCollection("ProfileEntity");
|
|
||||||
List<BsonDocument> profilesToUpdate = new();
|
|
||||||
foreach (BsonDocument profileBson in collection.FindAll())
|
|
||||||
{
|
|
||||||
BsonArray? folders = profileBson["Folders"]?.AsArray;
|
|
||||||
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
|
||||||
|
|
||||||
if (folders != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue folder in folders)
|
|
||||||
MigrateProfileElement(folder.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layers != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue layer in layers)
|
|
||||||
{
|
|
||||||
MigrateProfileElement(layer.AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["GeneralPropertyGroup"].AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
profilesToUpdate.Add(profileBson);
|
|
||||||
}
|
|
||||||
|
|
||||||
collection.Update(profilesToUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateProfileElement(BsonDocument profileElement)
|
|
||||||
{
|
|
||||||
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
|
||||||
if (layerEffects != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue layerEffect in layerEffects)
|
|
||||||
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
|
||||||
if (displayCondition != null)
|
|
||||||
MigrateNodeScript(displayCondition.AsDocument["Script"].AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigratePropertyGroup(BsonDocument? propertyGroup)
|
|
||||||
{
|
|
||||||
if (propertyGroup == null || propertyGroup.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? properties = propertyGroup["Properties"]?.AsArray;
|
|
||||||
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
|
||||||
|
|
||||||
if (properties != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue property in properties)
|
|
||||||
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyGroups != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue childPropertyGroup in propertyGroups)
|
|
||||||
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
|
||||||
{
|
|
||||||
if (nodeScript == null || nodeScript.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? nodes = nodeScript["Nodes"]?.AsArray;
|
|
||||||
if (nodes == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (BsonValue node in nodes)
|
|
||||||
{
|
|
||||||
node.AsDocument["Type"] = node.AsDocument["Type"]?.AsString?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes");
|
|
||||||
node.AsDocument["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0025NodeProvidersProfileConfig : IStorageMigration
|
|
||||||
{
|
|
||||||
public int UserVersion => 25;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
ILiteCollection<BsonDocument> categoryCollection = repository.Database.GetCollection("ProfileCategoryEntity");
|
|
||||||
List<BsonDocument> toUpdate = new();
|
|
||||||
foreach (BsonDocument profileCategoryBson in categoryCollection.FindAll())
|
|
||||||
{
|
|
||||||
BsonArray? profiles = profileCategoryBson["ProfileConfigurations"]?.AsArray;
|
|
||||||
if (profiles != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue profile in profiles)
|
|
||||||
{
|
|
||||||
profile["Version"] = 2;
|
|
||||||
MigrateNodeScript(profile["ActivationCondition"]?.AsDocument);
|
|
||||||
}
|
|
||||||
toUpdate.Add(profileCategoryBson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryCollection.Update(toUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
|
||||||
{
|
|
||||||
if (nodeScript == null || nodeScript.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? nodes = nodeScript["Nodes"]?.AsArray;
|
|
||||||
if (nodes == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (BsonValue node in nodes)
|
|
||||||
{
|
|
||||||
node.AsDocument["Type"] = node.AsDocument["Type"]?.AsString?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes");
|
|
||||||
node.AsDocument["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Migrations.Profile;
|
|
||||||
using LiteDB;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Migrations.Storage;
|
|
||||||
|
|
||||||
public class M0026NodeStorage : IStorageMigration
|
|
||||||
{
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
|
|
||||||
public M0026NodeStorage(ILogger logger)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
public int UserVersion => 26;
|
|
||||||
|
|
||||||
public void Apply(LiteRepository repository)
|
|
||||||
{
|
|
||||||
ILiteCollection<BsonDocument> categoryCollection = repository.Database.GetCollection("ProfileCategoryEntity");
|
|
||||||
List<BsonDocument> toUpdate = new();
|
|
||||||
foreach (BsonDocument profileCategoryBson in categoryCollection.FindAll())
|
|
||||||
{
|
|
||||||
BsonArray? profiles = profileCategoryBson["ProfileConfigurations"]?.AsArray;
|
|
||||||
if (profiles != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue profile in profiles)
|
|
||||||
{
|
|
||||||
profile["Version"] = 4;
|
|
||||||
MigrateNodeScript(profile["ActivationCondition"]?.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
toUpdate.Add(profileCategoryBson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryCollection.Update(toUpdate);
|
|
||||||
|
|
||||||
ILiteCollection<BsonDocument> collection = repository.Database.GetCollection("ProfileEntity");
|
|
||||||
List<BsonDocument> profilesToUpdate = new();
|
|
||||||
foreach (BsonDocument profileBson in collection.FindAll())
|
|
||||||
{
|
|
||||||
BsonArray? folders = profileBson["Folders"]?.AsArray;
|
|
||||||
BsonArray? layers = profileBson["Layers"]?.AsArray;
|
|
||||||
|
|
||||||
if (folders != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue folder in folders)
|
|
||||||
MigrateProfileElement(folder.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layers != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue layer in layers)
|
|
||||||
{
|
|
||||||
MigrateProfileElement(layer.AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["GeneralPropertyGroup"].AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument);
|
|
||||||
MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
profilesToUpdate.Add(profileBson);
|
|
||||||
}
|
|
||||||
|
|
||||||
collection.Update(profilesToUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateProfileElement(BsonDocument profileElement)
|
|
||||||
{
|
|
||||||
BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray;
|
|
||||||
if (layerEffects != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue layerEffect in layerEffects)
|
|
||||||
MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
BsonValue? displayCondition = profileElement["DisplayCondition"];
|
|
||||||
if (displayCondition != null)
|
|
||||||
MigrateNodeScript(displayCondition.AsDocument["Script"].AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigratePropertyGroup(BsonDocument? propertyGroup)
|
|
||||||
{
|
|
||||||
if (propertyGroup == null || propertyGroup.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? properties = propertyGroup["Properties"]?.AsArray;
|
|
||||||
BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray;
|
|
||||||
|
|
||||||
if (properties != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue property in properties)
|
|
||||||
MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyGroups != null)
|
|
||||||
{
|
|
||||||
foreach (BsonValue childPropertyGroup in propertyGroups)
|
|
||||||
MigratePropertyGroup(childPropertyGroup.AsDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MigrateNodeScript(BsonDocument? nodeScript)
|
|
||||||
{
|
|
||||||
if (nodeScript == null || nodeScript.Keys.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BsonArray? nodes = nodeScript["Nodes"]?.AsArray;
|
|
||||||
if (nodes == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (BsonValue node in nodes)
|
|
||||||
{
|
|
||||||
// Migrate the storage of the node
|
|
||||||
node["Storage"] = M0004NodeStorage.MigrateNodeStorageJson(node.AsDocument["Storage"]?.AsString, _logger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,47 +1,43 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Surface;
|
using Artemis.Storage.Entities.Surface;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class DeviceRepository : IDeviceRepository
|
internal class DeviceRepository : IDeviceRepository
|
||||||
{
|
{
|
||||||
private readonly LiteRepository _repository;
|
private readonly ArtemisDbContext _dbContext;
|
||||||
|
|
||||||
public DeviceRepository(LiteRepository repository)
|
public DeviceRepository(ArtemisDbContext dbContext)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_dbContext = dbContext;
|
||||||
_repository.Database.GetCollection<DeviceEntity>().EnsureIndex(s => s.Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(DeviceEntity deviceEntity)
|
public void Add(DeviceEntity deviceEntity)
|
||||||
{
|
{
|
||||||
_repository.Insert(deviceEntity);
|
_dbContext.Devices.Add(deviceEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(DeviceEntity deviceEntity)
|
public void Remove(DeviceEntity deviceEntity)
|
||||||
{
|
{
|
||||||
_repository.Delete<DeviceEntity>(deviceEntity.Id);
|
_dbContext.Devices.Remove(deviceEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceEntity? Get(string id)
|
public DeviceEntity? Get(string id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<DeviceEntity>(s => s.Id == id);
|
return _dbContext.Devices.FirstOrDefault(d => d.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DeviceEntity> GetAll()
|
public List<DeviceEntity> GetAll()
|
||||||
{
|
{
|
||||||
return _repository.Query<DeviceEntity>().Include(s => s.InputIdentifiers).ToList();
|
return _dbContext.Devices.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(DeviceEntity deviceEntity)
|
public void SaveChanges()
|
||||||
{
|
{
|
||||||
_repository.Upsert(deviceEntity);
|
_dbContext.SaveChanges();
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(IEnumerable<DeviceEntity> deviceEntities)
|
|
||||||
{
|
|
||||||
_repository.Upsert(deviceEntities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,54 +1,49 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Workshop;
|
using Artemis.Storage.Entities.Workshop;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class EntryRepository : IEntryRepository
|
internal class EntryRepository : IEntryRepository
|
||||||
{
|
{
|
||||||
private readonly LiteRepository _repository;
|
private readonly ArtemisDbContext _dbContext;
|
||||||
|
|
||||||
public EntryRepository(LiteRepository repository)
|
public EntryRepository(ArtemisDbContext dbContext)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_dbContext = dbContext;
|
||||||
_repository.Database.GetCollection<EntryEntity>().EnsureIndex(s => s.Id);
|
|
||||||
_repository.Database.GetCollection<EntryEntity>().EnsureIndex(s => s.EntryId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(EntryEntity entryEntity)
|
public void Add(EntryEntity entryEntity)
|
||||||
{
|
{
|
||||||
_repository.Insert(entryEntity);
|
_dbContext.Entries.Add(entryEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(EntryEntity entryEntity)
|
public void Remove(EntryEntity entryEntity)
|
||||||
{
|
{
|
||||||
_repository.Delete<EntryEntity>(entryEntity.Id);
|
_dbContext.Entries.Remove(entryEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryEntity? Get(Guid id)
|
public EntryEntity? Get(Guid id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<EntryEntity>(s => s.Id == id);
|
return _dbContext.Entries.FirstOrDefault(s => s.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntryEntity? GetByEntryId(long entryId)
|
public EntryEntity? GetByEntryId(long entryId)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<EntryEntity>(s => s.EntryId == entryId);
|
return _dbContext.Entries.FirstOrDefault(s => s.EntryId == entryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<EntryEntity> GetAll()
|
public List<EntryEntity> GetAll()
|
||||||
{
|
{
|
||||||
return _repository.Query<EntryEntity>().ToList();
|
return _dbContext.Entries.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(EntryEntity entryEntity)
|
public void SaveChanges()
|
||||||
{
|
{
|
||||||
_repository.Upsert(entryEntity);
|
_dbContext.SaveChanges();
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(IEnumerable<EntryEntity> entryEntities)
|
|
||||||
{
|
|
||||||
_repository.Upsert(entryEntities);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,6 +9,5 @@ public interface IDeviceRepository : IRepository
|
|||||||
void Remove(DeviceEntity deviceEntity);
|
void Remove(DeviceEntity deviceEntity);
|
||||||
DeviceEntity? Get(string id);
|
DeviceEntity? Get(string id);
|
||||||
List<DeviceEntity> GetAll();
|
List<DeviceEntity> GetAll();
|
||||||
void Save(DeviceEntity deviceEntity);
|
void SaveChanges();
|
||||||
void Save(IEnumerable<DeviceEntity> deviceEntities);
|
|
||||||
}
|
}
|
||||||
@ -11,6 +11,5 @@ public interface IEntryRepository : IRepository
|
|||||||
EntryEntity? Get(Guid id);
|
EntryEntity? Get(Guid id);
|
||||||
EntryEntity? GetByEntryId(long entryId);
|
EntryEntity? GetByEntryId(long entryId);
|
||||||
List<EntryEntity> GetAll();
|
List<EntryEntity> GetAll();
|
||||||
void Save(EntryEntity entryEntity);
|
void SaveChanges();
|
||||||
void Save(IEnumerable<EntryEntity> entryEntities);
|
|
||||||
}
|
}
|
||||||
@ -7,11 +7,9 @@ public interface IPluginRepository : IRepository
|
|||||||
{
|
{
|
||||||
void AddPlugin(PluginEntity pluginEntity);
|
void AddPlugin(PluginEntity pluginEntity);
|
||||||
PluginEntity? GetPluginByGuid(Guid pluginGuid);
|
PluginEntity? GetPluginByGuid(Guid pluginGuid);
|
||||||
void SavePlugin(PluginEntity pluginEntity);
|
|
||||||
|
|
||||||
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
||||||
PluginSettingEntity? GetSettingByGuid(Guid pluginGuid);
|
PluginSettingEntity? GetSettingByGuid(Guid pluginGuid);
|
||||||
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||||
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
|
||||||
void RemoveSettings(Guid pluginGuid);
|
void RemoveSettings(Guid pluginGuid);
|
||||||
|
void SaveChanges();
|
||||||
}
|
}
|
||||||
@ -11,8 +11,6 @@ public interface IProfileCategoryRepository : IRepository
|
|||||||
void Remove(ProfileCategoryEntity profileCategoryEntity);
|
void Remove(ProfileCategoryEntity profileCategoryEntity);
|
||||||
List<ProfileCategoryEntity> GetAll();
|
List<ProfileCategoryEntity> GetAll();
|
||||||
ProfileCategoryEntity? Get(Guid id);
|
ProfileCategoryEntity? Get(Guid id);
|
||||||
Stream? GetProfileIconStream(Guid id);
|
bool IsUnique(string name, Guid? id);
|
||||||
void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream);
|
void SaveChanges();
|
||||||
ProfileCategoryEntity IsUnique(string name, Guid? id);
|
|
||||||
void Save(ProfileCategoryEntity profileCategoryEntity);
|
|
||||||
}
|
}
|
||||||
@ -6,9 +6,9 @@ namespace Artemis.Storage.Repositories.Interfaces;
|
|||||||
|
|
||||||
public interface IProfileRepository : IRepository
|
public interface IProfileRepository : IRepository
|
||||||
{
|
{
|
||||||
void Add(ProfileEntity profileEntity);
|
void Add(ProfileContainerEntity profileContainerEntity);
|
||||||
void Remove(ProfileEntity profileEntity);
|
void Remove(ProfileContainerEntity profileContainerEntity);
|
||||||
List<ProfileEntity> GetAll();
|
List<ProfileContainerEntity> GetAll();
|
||||||
ProfileEntity? Get(Guid id);
|
ProfileContainerEntity? Get(Guid id);
|
||||||
void Save(ProfileEntity profileEntity);
|
void SaveChanges();
|
||||||
}
|
}
|
||||||
@ -1,14 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.General;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories.Interfaces;
|
|
||||||
|
|
||||||
public interface IQueuedActionRepository : IRepository
|
|
||||||
{
|
|
||||||
void Add(QueuedActionEntity queuedActionEntity);
|
|
||||||
void Remove(QueuedActionEntity queuedActionEntity);
|
|
||||||
List<QueuedActionEntity> GetAll();
|
|
||||||
List<QueuedActionEntity> GetByType(string type);
|
|
||||||
bool IsTypeQueued(string type);
|
|
||||||
void ClearByType(string type);
|
|
||||||
}
|
|
||||||
@ -1,59 +1,53 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class PluginRepository : IPluginRepository
|
internal class PluginRepository : IPluginRepository
|
||||||
{
|
{
|
||||||
private readonly LiteRepository _repository;
|
private readonly ArtemisDbContext _dbContext;
|
||||||
|
|
||||||
public PluginRepository(LiteRepository repository)
|
public PluginRepository(ArtemisDbContext dbContext)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_dbContext = dbContext;
|
||||||
|
|
||||||
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => new {s.Name, s.PluginGuid}, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPlugin(PluginEntity pluginEntity)
|
public void AddPlugin(PluginEntity pluginEntity)
|
||||||
{
|
{
|
||||||
_repository.Insert(pluginEntity);
|
_dbContext.Plugins.Add(pluginEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginEntity? GetPluginByGuid(Guid pluginGuid)
|
public PluginEntity? GetPluginByGuid(Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<PluginEntity>(p => p.Id == pluginGuid);
|
return _dbContext.Plugins.FirstOrDefault(p => p.Id == pluginGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SavePlugin(PluginEntity pluginEntity)
|
|
||||||
{
|
|
||||||
_repository.Upsert(pluginEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
||||||
{
|
{
|
||||||
_repository.Insert(pluginSettingEntity);
|
_dbContext.PluginSettings.Add(pluginSettingEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSettingEntity? GetSettingByGuid(Guid pluginGuid)
|
public PluginSettingEntity? GetSettingByGuid(Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.PluginGuid == pluginGuid);
|
return _dbContext.PluginSettings.FirstOrDefault(p => p.PluginGuid == pluginGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.Name == name && p.PluginGuid == pluginGuid);
|
return _dbContext.PluginSettings.FirstOrDefault(p => p.Name == name && p.PluginGuid == pluginGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveSetting(PluginSettingEntity pluginSettingEntity)
|
|
||||||
{
|
|
||||||
_repository.Upsert(pluginSettingEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void RemoveSettings(Guid pluginGuid)
|
public void RemoveSettings(Guid pluginGuid)
|
||||||
{
|
{
|
||||||
_repository.DeleteMany<PluginSettingEntity>(s => s.PluginGuid == pluginGuid);
|
_dbContext.PluginSettings.RemoveRange(_dbContext.PluginSettings.Where(s => s.PluginGuid == pluginGuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveChanges()
|
||||||
|
{
|
||||||
|
_dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,93 +1,53 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
internal class ProfileCategoryRepository : IProfileCategoryRepository
|
internal class ProfileCategoryRepository : IProfileCategoryRepository
|
||||||
{
|
{
|
||||||
private readonly ILiteStorage<Guid> _profileIcons;
|
private readonly ArtemisDbContext _dbContext;
|
||||||
private readonly LiteRepository _repository;
|
|
||||||
|
|
||||||
public ProfileCategoryRepository(LiteRepository repository)
|
public ProfileCategoryRepository(ArtemisDbContext dbContext)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_dbContext = dbContext;
|
||||||
_repository.Database.GetCollection<ProfileCategoryEntity>().EnsureIndex(s => s.Name, true);
|
|
||||||
_profileIcons = _repository.Database.GetStorage<Guid>("profileIcons");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(ProfileCategoryEntity profileCategoryEntity)
|
public void Add(ProfileCategoryEntity profileCategoryEntity)
|
||||||
{
|
{
|
||||||
_repository.Insert(profileCategoryEntity);
|
_dbContext.ProfileCategories.Add(profileCategoryEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(ProfileCategoryEntity profileCategoryEntity)
|
public void Remove(ProfileCategoryEntity profileCategoryEntity)
|
||||||
{
|
{
|
||||||
_repository.Delete<ProfileCategoryEntity>(profileCategoryEntity.Id);
|
_dbContext.ProfileCategories.Remove(profileCategoryEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ProfileCategoryEntity> GetAll()
|
public List<ProfileCategoryEntity> GetAll()
|
||||||
{
|
{
|
||||||
List<ProfileCategoryEntity> categories = _repository.Query<ProfileCategoryEntity>().ToList();
|
return _dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).ToList();
|
||||||
|
|
||||||
// Update all profile versions to the current version, profile migrations don't apply to LiteDB so anything loadable is assumed to be up to date
|
|
||||||
foreach (ProfileCategoryEntity profileCategoryEntity in categories)
|
|
||||||
UpdateProfileVersions(profileCategoryEntity);
|
|
||||||
|
|
||||||
return categories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileCategoryEntity? Get(Guid id)
|
public ProfileCategoryEntity? Get(Guid id)
|
||||||
{
|
{
|
||||||
ProfileCategoryEntity? result = _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Id == id);
|
return _dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).FirstOrDefault(c => c.Id == id);
|
||||||
if (result == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Update all profile versions to the current version, profile migrations don't apply to LiteDB so anything loadable is assumed to be up to date
|
|
||||||
UpdateProfileVersions(result);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileCategoryEntity IsUnique(string name, Guid? id)
|
public bool IsUnique(string name, Guid? id)
|
||||||
{
|
{
|
||||||
name = name.Trim();
|
name = name.Trim();
|
||||||
if (id == null)
|
if (id == null)
|
||||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Name == name);
|
return _dbContext.ProfileCategories.Any(p => p.Name == name);
|
||||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Name == name && p.Id != id.Value);
|
return _dbContext.ProfileCategories.Any(p => p.Name == name && p.Id != id.Value);
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(ProfileCategoryEntity profileCategoryEntity)
|
|
||||||
{
|
|
||||||
_repository.Upsert(profileCategoryEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Stream? GetProfileIconStream(Guid id)
|
|
||||||
{
|
|
||||||
if (!_profileIcons.Exists(id))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
MemoryStream stream = new();
|
|
||||||
_profileIcons.Download(id, stream);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream)
|
|
||||||
{
|
|
||||||
if (profileConfigurationEntity.FileIconId == Guid.Empty)
|
|
||||||
profileConfigurationEntity.FileIconId = Guid.NewGuid();
|
|
||||||
|
|
||||||
if (stream == null && _profileIcons.Exists(profileConfigurationEntity.FileIconId))
|
|
||||||
_profileIcons.Delete(profileConfigurationEntity.FileIconId);
|
|
||||||
|
|
||||||
_profileIcons.Upload(profileConfigurationEntity.FileIconId, profileConfigurationEntity.FileIconId + ".png", stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateProfileVersions(ProfileCategoryEntity profileCategoryEntity)
|
public void SaveChanges()
|
||||||
{
|
{
|
||||||
foreach (ProfileConfigurationEntity profileConfigurationEntity in profileCategoryEntity.ProfileConfigurations)
|
_dbContext.SaveChanges();
|
||||||
profileConfigurationEntity.Version = StorageMigrationService.PROFILE_VERSION;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
using LiteDB;
|
||||||
@ -8,36 +9,37 @@ namespace Artemis.Storage.Repositories;
|
|||||||
|
|
||||||
internal class ProfileRepository : IProfileRepository
|
internal class ProfileRepository : IProfileRepository
|
||||||
{
|
{
|
||||||
private readonly LiteRepository _repository;
|
private readonly ArtemisDbContext _dbContext;
|
||||||
|
|
||||||
public ProfileRepository(LiteRepository repository)
|
public ProfileRepository(ArtemisDbContext dbContext)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_dbContext = dbContext;
|
||||||
_repository.Database.GetCollection<ProfileEntity>().EnsureIndex(s => s.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(ProfileEntity profileEntity)
|
public void Add(ProfileContainerEntity profileContainerEntity)
|
||||||
{
|
{
|
||||||
_repository.Insert(profileEntity);
|
_dbContext.Profiles.Add(profileContainerEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(ProfileEntity profileEntity)
|
public void Remove(ProfileContainerEntity profileContainerEntity)
|
||||||
{
|
{
|
||||||
_repository.Delete<ProfileEntity>(profileEntity.Id);
|
_dbContext.Profiles.Remove(profileContainerEntity);
|
||||||
|
SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ProfileEntity> GetAll()
|
public List<ProfileContainerEntity> GetAll()
|
||||||
{
|
{
|
||||||
return _repository.Query<ProfileEntity>().ToList();
|
return _dbContext.Profiles.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileEntity? Get(Guid id)
|
public ProfileContainerEntity? Get(Guid id)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<ProfileEntity>(p => p.Id == id);
|
return _dbContext.Profiles.FirstOrDefault(c => c.Profile.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(ProfileEntity profileEntity)
|
public void SaveChanges()
|
||||||
{
|
{
|
||||||
_repository.Upsert(profileEntity);
|
_dbContext.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,57 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.General;
|
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
|
||||||
|
|
||||||
public class QueuedActionRepository : IQueuedActionRepository
|
|
||||||
{
|
|
||||||
private readonly LiteRepository _repository;
|
|
||||||
|
|
||||||
public QueuedActionRepository(LiteRepository repository)
|
|
||||||
{
|
|
||||||
_repository = repository;
|
|
||||||
_repository.Database.GetCollection<QueuedActionEntity>().EnsureIndex(s => s.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Implementation of IQueuedActionRepository
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Add(QueuedActionEntity queuedActionEntity)
|
|
||||||
{
|
|
||||||
_repository.Insert(queuedActionEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Remove(QueuedActionEntity queuedActionEntity)
|
|
||||||
{
|
|
||||||
_repository.Delete<QueuedActionEntity>(queuedActionEntity.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public List<QueuedActionEntity> GetAll()
|
|
||||||
{
|
|
||||||
return _repository.Query<QueuedActionEntity>().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public List<QueuedActionEntity> GetByType(string type)
|
|
||||||
{
|
|
||||||
return _repository.Query<QueuedActionEntity>().Where(q => q.Type == type).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsTypeQueued(string type)
|
|
||||||
{
|
|
||||||
return _repository.Query<QueuedActionEntity>().Where(q => q.Type == type).Count() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void ClearByType(string type)
|
|
||||||
{
|
|
||||||
_repository.DeleteMany<QueuedActionEntity>(q => q.Type == type);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
@ -1,38 +1,38 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.General;
|
using Artemis.Storage.Entities.General;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using LiteDB;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories;
|
namespace Artemis.Storage.Repositories;
|
||||||
|
|
||||||
public class ReleaseRepository : IReleaseRepository
|
public class ReleaseRepository : IReleaseRepository
|
||||||
{
|
{
|
||||||
private readonly LiteRepository _repository;
|
private readonly ArtemisDbContext _dbContext;
|
||||||
|
|
||||||
public ReleaseRepository(LiteRepository repository)
|
public ReleaseRepository(ArtemisDbContext dbContext)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_dbContext = dbContext;
|
||||||
_repository.Database.GetCollection<ReleaseEntity>().EnsureIndex(s => s.Version, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SaveVersionInstallDate(string version)
|
public bool SaveVersionInstallDate(string version)
|
||||||
{
|
{
|
||||||
ReleaseEntity release = _repository.Query<ReleaseEntity>().Where(r => r.Version == version).FirstOrDefault();
|
ReleaseEntity? release = _dbContext.Releases.FirstOrDefault(r => r.Version == version);
|
||||||
if (release != null)
|
if (release != null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_repository.Insert(new ReleaseEntity {Version = version, InstalledAt = DateTimeOffset.UtcNow});
|
_dbContext.Releases.Add(new ReleaseEntity {Version = version, InstalledAt = DateTimeOffset.UtcNow});
|
||||||
|
_dbContext.SaveChanges();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReleaseEntity GetPreviousInstalledVersion()
|
public ReleaseEntity? GetPreviousInstalledVersion()
|
||||||
{
|
{
|
||||||
return _repository.Query<ReleaseEntity>().OrderByDescending(r => r.InstalledAt).Skip(1).FirstOrDefault();
|
return _dbContext.Releases.OrderByDescending(r => r.InstalledAt).Skip(1).FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IReleaseRepository : IRepository
|
public interface IReleaseRepository : IRepository
|
||||||
{
|
{
|
||||||
bool SaveVersionInstallDate(string version);
|
bool SaveVersionInstallDate(string version);
|
||||||
ReleaseEntity GetPreviousInstalledVersion();
|
ReleaseEntity? GetPreviousInstalledVersion();
|
||||||
}
|
}
|
||||||
@ -1,53 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Artemis.Storage.Migrations;
|
|
||||||
using LiteDB;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Artemis.Storage;
|
|
||||||
|
|
||||||
public class StorageMigrationService
|
|
||||||
{
|
|
||||||
public const int PROFILE_VERSION = 4;
|
|
||||||
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private readonly IList<IStorageMigration> _migrations;
|
|
||||||
private readonly LiteRepository _repository;
|
|
||||||
|
|
||||||
public StorageMigrationService(ILogger logger, LiteRepository repository, IList<IStorageMigration> migrations)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_repository = repository;
|
|
||||||
_migrations = migrations;
|
|
||||||
|
|
||||||
ApplyPendingMigrations();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ApplyPendingMigrations()
|
|
||||||
{
|
|
||||||
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,12 +1,16 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
using Artemis.Core;
|
using Artemis.Core;
|
||||||
using Artemis.Storage.Entities.Workshop;
|
using Artemis.Storage.Entities.Workshop;
|
||||||
|
using Artemis.WebClient.Workshop.Exceptions;
|
||||||
|
|
||||||
namespace Artemis.WebClient.Workshop.Models;
|
namespace Artemis.WebClient.Workshop.Models;
|
||||||
|
|
||||||
public class InstalledEntry
|
public class InstalledEntry
|
||||||
{
|
{
|
||||||
private Dictionary<string, object> _metadata = new();
|
private static readonly JsonSerializerOptions JsonSerializerOptions = CoreJson.GetJsonSerializerOptions();
|
||||||
|
private Dictionary<string, JsonNode> _metadata = new();
|
||||||
|
|
||||||
internal InstalledEntry(EntryEntity entity)
|
internal InstalledEntry(EntryEntity entity)
|
||||||
{
|
{
|
||||||
@ -52,7 +56,7 @@ public class InstalledEntry
|
|||||||
ReleaseVersion = Entity.ReleaseVersion;
|
ReleaseVersion = Entity.ReleaseVersion;
|
||||||
InstalledAt = Entity.InstalledAt;
|
InstalledAt = Entity.InstalledAt;
|
||||||
|
|
||||||
_metadata = Entity.Metadata != null ? new Dictionary<string, object>(Entity.Metadata) : new Dictionary<string, object>();
|
_metadata = Entity.Metadata != null ? new Dictionary<string, JsonNode>(Entity.Metadata) : new Dictionary<string, JsonNode>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Save()
|
internal void Save()
|
||||||
@ -67,7 +71,7 @@ public class InstalledEntry
|
|||||||
Entity.ReleaseVersion = ReleaseVersion;
|
Entity.ReleaseVersion = ReleaseVersion;
|
||||||
Entity.InstalledAt = InstalledAt;
|
Entity.InstalledAt = InstalledAt;
|
||||||
|
|
||||||
Entity.Metadata = new Dictionary<string, object>(_metadata);
|
Entity.Metadata = new Dictionary<string, JsonNode>(_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -80,14 +84,29 @@ public class InstalledEntry
|
|||||||
/// <returns><see langword="true"/> if the metadata contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
|
/// <returns><see langword="true"/> if the metadata contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
|
||||||
public bool TryGetMetadata<T>(string key, [NotNullWhen(true)] out T? value)
|
public bool TryGetMetadata<T>(string key, [NotNullWhen(true)] out T? value)
|
||||||
{
|
{
|
||||||
if (!_metadata.TryGetValue(key, out object? objectValue) || objectValue is not T result)
|
if (!_metadata.TryGetValue(key, out JsonNode? jsonNode))
|
||||||
{
|
{
|
||||||
value = default;
|
value = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = result;
|
try
|
||||||
return true;
|
{
|
||||||
|
T? deserialized = jsonNode.Deserialize<T>(JsonSerializerOptions);
|
||||||
|
if (deserialized != null)
|
||||||
|
{
|
||||||
|
value = deserialized;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
value = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -97,7 +116,8 @@ public class InstalledEntry
|
|||||||
/// <param name="value">The value to set.</param>
|
/// <param name="value">The value to set.</param>
|
||||||
public void SetMetadata(string key, object value)
|
public void SetMetadata(string key, object value)
|
||||||
{
|
{
|
||||||
_metadata[key] = value;
|
JsonNode? jsonNode = JsonSerializer.SerializeToNode(value, JsonSerializerOptions);
|
||||||
|
_metadata[key] = jsonNode ?? throw new ArtemisWorkshopException("Failed to serialize metadata value");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -171,7 +171,7 @@ public class WorkshopService : IWorkshopService
|
|||||||
public void SaveInstalledEntry(InstalledEntry entry)
|
public void SaveInstalledEntry(InstalledEntry entry)
|
||||||
{
|
{
|
||||||
entry.Save();
|
entry.Save();
|
||||||
_entryRepository.Save(entry.Entity);
|
_entryRepository.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
<PackageVersion Include="Markdown.Avalonia.Tight" Version="11.0.2" />
|
<PackageVersion Include="Markdown.Avalonia.Tight" Version="11.0.2" />
|
||||||
<PackageVersion Include="Material.Icons.Avalonia" Version="2.1.0" />
|
<PackageVersion Include="Material.Icons.Avalonia" Version="2.1.0" />
|
||||||
<PackageVersion Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
<PackageVersion Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.2" />
|
||||||
|
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.2" />
|
||||||
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||||
<PackageVersion Include="Microsoft.Win32" Version="2.0.1" />
|
<PackageVersion Include="Microsoft.Win32" Version="2.0.1" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user