mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Storage - Replace LiteDB with SQLite + EF Core (#843)
Storage - Added LiteDB to SQLite migration UI - Try to die a bit more gracefully Core - Delay start watching plugins for hot reload after initializing UI - Simplify category management logic UI - Avoid crash during profile icon load Storage - Fix entry metadata retrieval
This commit is contained in:
1 parent
9132301dbf
commit
551921db9f
130 files changed
+2965
-1135
No files matched your search
@@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LiteDB" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
|
||||
<PackageReference Include="Serilog" />
|
||||
<PackageReference Include="System.Text.Json" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
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<PluginFeatureEntity> PluginFeatures => Set<PluginFeatureEntity>();
|
||||
public DbSet<PluginSettingEntity> PluginSettings => Set<PluginSettingEntity>();
|
||||
public DbSet<ProfileCategoryEntity> ProfileCategories => Set<ProfileCategoryEntity>();
|
||||
public DbSet<ProfileContainerEntity> ProfileContainers => Set<ProfileContainerEntity>();
|
||||
public DbSet<ReleaseEntity> Releases => Set<ReleaseEntity>();
|
||||
|
||||
public string DataFolder { get; set; } = string.Empty;
|
||||
public JsonSerializerOptions JsonSerializerOptions { get; set; } = JsonSerializerOptions.Default;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseSqlite($"Data Source={Path.Combine(DataFolder, "artemis.db")}");
|
||||
}
|
||||
|
||||
/// <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>()
|
||||
.Property(e => e.Metadata)
|
||||
.HasConversion(
|
||||
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
|
||||
v => JsonSerializer.Deserialize<Dictionary<string, JsonNode>>(v, JsonSerializerOptions) ?? new Dictionary<string, JsonNode>());
|
||||
|
||||
modelBuilder.Entity<ProfileContainerEntity>()
|
||||
.Property(e => e.ProfileConfiguration)
|
||||
.HasConversion(
|
||||
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
|
||||
v => JsonSerializer.Deserialize<ProfileConfigurationEntity>(v, JsonSerializerOptions) ?? new ProfileConfigurationEntity());
|
||||
|
||||
modelBuilder.Entity<ProfileContainerEntity>()
|
||||
.Property(e => e.Profile)
|
||||
.HasConversion(
|
||||
v => JsonSerializer.Serialize(v, JsonSerializerOptions),
|
||||
v => JsonSerializer.Deserialize<ProfileEntity>(v, JsonSerializerOptions) ?? new ProfileEntity());
|
||||
}
|
||||
}
|
||||
@@ -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,11 +1,17 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Entities.General;
|
||||
|
||||
[Index(nameof(Version), IsUnique = true)]
|
||||
[Index(nameof(InstalledAt))]
|
||||
public class ReleaseEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string Version { get; set; } = string.Empty;
|
||||
|
||||
public DateTimeOffset? InstalledAt { get; set; }
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Entities.Plugins;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the configuration of a plugin, each plugin has one configuration
|
||||
/// </summary>
|
||||
[Index(nameof(PluginGuid), IsUnique = true)]
|
||||
public class PluginEntity
|
||||
{
|
||||
public PluginEntity()
|
||||
@@ -14,6 +17,7 @@ public class PluginEntity
|
||||
}
|
||||
|
||||
public Guid Id { get; set; }
|
||||
public Guid PluginGuid { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
public List<PluginFeatureEntity> Features { get; set; }
|
||||
@@ -24,6 +28,8 @@ public class PluginEntity
|
||||
/// </summary>
|
||||
public class PluginFeatureEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public bool IsEnabled { get; set; }
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Entities.Plugins;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the setting of a plugin, a plugin can have multiple settings
|
||||
/// </summary>
|
||||
[Index(nameof(Name), nameof(PluginGuid), IsUnique = true)]
|
||||
[Index(nameof(PluginGuid))]
|
||||
public class PluginSettingEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid PluginGuid { get; set; }
|
||||
|
||||
[MaxLength(128)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Value { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Storage.Entities.Profile.Abstract;
|
||||
using LiteDB;
|
||||
|
||||
namespace Artemis.Storage.Entities.Profile;
|
||||
|
||||
@@ -11,8 +10,5 @@ public class FolderEntity : RenderElementEntity
|
||||
public bool IsExpanded { get; set; }
|
||||
public bool Suspended { get; set; }
|
||||
|
||||
[BsonRef("ProfileEntity")]
|
||||
public ProfileEntity Profile { get; set; } = null!;
|
||||
|
||||
public Guid ProfileId { get; set; }
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Storage.Entities.Profile.Abstract;
|
||||
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||
using LiteDB;
|
||||
|
||||
namespace Artemis.Storage.Entities.Profile;
|
||||
|
||||
@@ -25,8 +24,5 @@ public class LayerEntity : RenderElementEntity
|
||||
public PropertyGroupEntity? TransformPropertyGroup { get; set; }
|
||||
public LayerBrushEntity? LayerBrush { get; set; }
|
||||
|
||||
[BsonRef("ProfileEntity")]
|
||||
public ProfileEntity Profile { get; set; } = null!;
|
||||
|
||||
public Guid ProfileId { get; set; }
|
||||
}
|
||||
@@ -1,16 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Entities.Profile;
|
||||
|
||||
[Index(nameof(Name), IsUnique = true)]
|
||||
public class ProfileCategoryEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public bool IsCollapsed { get; set; }
|
||||
public bool IsSuspended { get; set; }
|
||||
public int Order { get; set; }
|
||||
|
||||
public List<ProfileConfigurationEntity> ProfileConfigurations { get; set; } = new();
|
||||
public List<ProfileContainerEntity> ProfileConfigurations { get; set; } = new();
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Artemis.Storage.Entities.Profile.Nodes;
|
||||
using Serilog.Core;
|
||||
|
||||
namespace Artemis.Storage.Entities.Profile;
|
||||
|
||||
@@ -8,7 +7,6 @@ public class ProfileConfigurationEntity
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? MaterialIcon { get; set; }
|
||||
public Guid FileIconId { get; set; }
|
||||
public int IconType { get; set; }
|
||||
public bool IconFill { get; set; }
|
||||
public int Order { get; set; }
|
||||
@@ -27,5 +25,5 @@ public class ProfileConfigurationEntity
|
||||
public Guid ProfileId { get; set; }
|
||||
|
||||
public bool FadeInAndOut { get; set; }
|
||||
public int Version { get; set; } = StorageMigrationService.PROFILE_VERSION;
|
||||
public int Version { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Storage.Entities.Profile;
|
||||
|
||||
public class ProfileContainerEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public byte[] Icon { get; set; } = Array.Empty<byte>();
|
||||
|
||||
public ProfileCategoryEntity ProfileCategory { get; set; } = null!;
|
||||
|
||||
public ProfileConfigurationEntity ProfileConfiguration { get; set; } = new();
|
||||
public ProfileEntity Profile { get; set; } = new();
|
||||
}
|
||||
@@ -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.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Artemis.Storage.Entities.Surface;
|
||||
|
||||
@@ -11,8 +12,12 @@ public class DeviceEntity
|
||||
Categories = new List<int>();
|
||||
}
|
||||
|
||||
[MaxLength(512)]
|
||||
public string Id { get; set; } = string.Empty;
|
||||
|
||||
[MaxLength(512)]
|
||||
public string DeviceProvider { get; set; } = string.Empty;
|
||||
|
||||
public float X { get; set; }
|
||||
public float Y { get; set; }
|
||||
public float Rotation { get; set; }
|
||||
@@ -22,10 +27,16 @@ public class DeviceEntity
|
||||
public float GreenScale { get; set; }
|
||||
public float BlueScale { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
|
||||
|
||||
public int PhysicalLayout { get; set; }
|
||||
|
||||
[MaxLength(32)]
|
||||
public string? LogicalLayout { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? LayoutType { get; set; }
|
||||
|
||||
[MaxLength(512)]
|
||||
public string? LayoutParameter { get; set; }
|
||||
|
||||
public List<DeviceInputIdentifierEntity> InputIdentifiers { get; set; }
|
||||
@@ -42,5 +53,5 @@ public class InputMappingEntity
|
||||
public class DeviceInputIdentifierEntity
|
||||
{
|
||||
public string InputProvider { get; set; } = string.Empty;
|
||||
public object Identifier { get; set; } = string.Empty;
|
||||
public string Identifier { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -1,21 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Entities.Workshop;
|
||||
|
||||
[Index(nameof(EntryId), IsUnique = true)]
|
||||
public class EntryEntity
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
|
||||
public long EntryId { 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 long ReleaseId { get; set; }
|
||||
public string ReleaseVersion { get; set; } = string.Empty;
|
||||
public DateTimeOffset InstalledAt { get; set; }
|
||||
|
||||
public Dictionary<string,object>? Metadata { get; set; }
|
||||
public Dictionary<string, JsonNode>? Metadata { get; set; }
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Artemis.Storage;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Artemis.Storage.Migrations
|
||||
{
|
||||
[DbContext(typeof(ArtemisDbContext))]
|
||||
[Migration("20240310201706_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.2");
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.General.ReleaseEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("InstalledAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Version")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstalledAt");
|
||||
|
||||
b.HasIndex("Version")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Releases");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("PluginGuid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PluginGuid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Plugins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("PluginEntityId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PluginEntityId");
|
||||
|
||||
b.ToTable("PluginFeatures");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("PluginGuid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PluginGuid");
|
||||
|
||||
b.HasIndex("Name", "PluginGuid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("PluginSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsCollapsed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsSuspended")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ProfileCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<byte[]>("Icon")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB");
|
||||
|
||||
b.Property<string>("Profile")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ProfileCategoryId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProfileConfiguration")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProfileCategoryId");
|
||||
|
||||
b.ToTable("ProfileContainers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<float>("BlueScale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Categories")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeviceProvider")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<float>("GreenScale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<bool>("IsEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("LayoutParameter")
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LayoutType")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LogicalLayout")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PhysicalLayout")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<float>("RedScale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("Rotation")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("Scale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("X")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("Y")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<int>("ZIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Devices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Workshop.EntryEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Author")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("EntryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("EntryType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("InstalledAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Metadata")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("ReleaseId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ReleaseVersion")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EntryId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||
{
|
||||
b.HasOne("Artemis.Storage.Entities.Plugins.PluginEntity", null)
|
||||
.WithMany("Features")
|
||||
.HasForeignKey("PluginEntityId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||
{
|
||||
b.HasOne("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", "ProfileCategory")
|
||||
.WithMany("ProfileConfigurations")
|
||||
.HasForeignKey("ProfileCategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ProfileCategory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||
{
|
||||
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.DeviceInputIdentifierEntity>", "InputIdentifiers", b1 =>
|
||||
{
|
||||
b1.Property<string>("DeviceEntityId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b1.Property<int>("Capacity")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b1.HasKey("DeviceEntityId");
|
||||
|
||||
b1.ToTable("Devices");
|
||||
|
||||
b1.ToJson("InputIdentifiers");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("DeviceEntityId");
|
||||
});
|
||||
|
||||
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.InputMappingEntity>", "InputMappings", b1 =>
|
||||
{
|
||||
b1.Property<string>("DeviceEntityId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b1.Property<int>("Capacity")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b1.HasKey("DeviceEntityId");
|
||||
|
||||
b1.ToTable("Devices");
|
||||
|
||||
b1.ToJson("InputMappings");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("DeviceEntityId");
|
||||
});
|
||||
|
||||
b.Navigation("InputIdentifiers")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("InputMappings")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||
{
|
||||
b.Navigation("Features");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||
{
|
||||
b.Navigation("ProfileConfigurations");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Artemis.Storage.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Initial : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Devices",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "TEXT", maxLength: 512, nullable: false),
|
||||
DeviceProvider = table.Column<string>(type: "TEXT", maxLength: 512, nullable: false),
|
||||
X = table.Column<float>(type: "REAL", nullable: false),
|
||||
Y = table.Column<float>(type: "REAL", nullable: false),
|
||||
Rotation = table.Column<float>(type: "REAL", nullable: false),
|
||||
Scale = table.Column<float>(type: "REAL", nullable: false),
|
||||
ZIndex = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
RedScale = table.Column<float>(type: "REAL", nullable: false),
|
||||
GreenScale = table.Column<float>(type: "REAL", nullable: false),
|
||||
BlueScale = table.Column<float>(type: "REAL", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
PhysicalLayout = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
LogicalLayout = table.Column<string>(type: "TEXT", maxLength: 32, nullable: true),
|
||||
LayoutType = table.Column<string>(type: "TEXT", maxLength: 64, nullable: true),
|
||||
LayoutParameter = table.Column<string>(type: "TEXT", maxLength: 512, nullable: true),
|
||||
Categories = table.Column<string>(type: "TEXT", nullable: false),
|
||||
InputIdentifiers = table.Column<string>(type: "TEXT", nullable: false),
|
||||
InputMappings = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Devices", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Entries",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
EntryId = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
EntryType = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Author = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ReleaseId = table.Column<long>(type: "INTEGER", nullable: false),
|
||||
ReleaseVersion = table.Column<string>(type: "TEXT", nullable: false),
|
||||
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: false),
|
||||
Metadata = table.Column<string>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Entries", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Plugins",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
PluginGuid = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Plugins", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PluginSettings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
PluginGuid = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", maxLength: 128, nullable: false),
|
||||
Value = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PluginSettings", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProfileCategories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
|
||||
IsCollapsed = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
IsSuspended = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Order = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProfileCategories", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Releases",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Version = table.Column<string>(type: "TEXT", maxLength: 64, nullable: false),
|
||||
InstalledAt = table.Column<DateTimeOffset>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Releases", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "PluginFeatures",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Type = table.Column<string>(type: "TEXT", nullable: false),
|
||||
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
PluginEntityId = table.Column<Guid>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_PluginFeatures", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_PluginFeatures_Plugins_PluginEntityId",
|
||||
column: x => x.PluginEntityId,
|
||||
principalTable: "Plugins",
|
||||
principalColumn: "Id");
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ProfileContainers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Icon = table.Column<byte[]>(type: "BLOB", nullable: false),
|
||||
ProfileCategoryId = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
ProfileConfiguration = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Profile = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ProfileContainers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ProfileContainers_ProfileCategories_ProfileCategoryId",
|
||||
column: x => x.ProfileCategoryId,
|
||||
principalTable: "ProfileCategories",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Entries_EntryId",
|
||||
table: "Entries",
|
||||
column: "EntryId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_PluginFeatures_PluginEntityId",
|
||||
table: "PluginFeatures",
|
||||
column: "PluginEntityId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Plugins_PluginGuid",
|
||||
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");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Releases_InstalledAt",
|
||||
table: "Releases",
|
||||
column: "InstalledAt");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Releases_Version",
|
||||
table: "Releases",
|
||||
column: "Version",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Devices");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Entries");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PluginFeatures");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PluginSettings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ProfileContainers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Releases");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Plugins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ProfileCategories");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Artemis.Storage;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Artemis.Storage.Migrations
|
||||
{
|
||||
[DbContext(typeof(ArtemisDbContext))]
|
||||
partial class ArtemisDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.2");
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.General.ReleaseEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTimeOffset?>("InstalledAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Version")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("InstalledAt");
|
||||
|
||||
b.HasIndex("Version")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Releases");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid>("PluginGuid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PluginGuid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Plugins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<Guid?>("PluginEntityId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PluginEntityId");
|
||||
|
||||
b.ToTable("PluginFeatures");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginSettingEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("PluginGuid")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PluginGuid");
|
||||
|
||||
b.HasIndex("Name", "PluginGuid")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("PluginSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsCollapsed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsSuspended")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Order")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ProfileCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<byte[]>("Icon")
|
||||
.IsRequired()
|
||||
.HasColumnType("BLOB");
|
||||
|
||||
b.Property<string>("Profile")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid>("ProfileCategoryId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProfileConfiguration")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ProfileCategoryId");
|
||||
|
||||
b.ToTable("ProfileContainers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<float>("BlueScale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Categories")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeviceProvider")
|
||||
.IsRequired()
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<float>("GreenScale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<bool>("IsEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("LayoutParameter")
|
||||
.HasMaxLength(512)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LayoutType")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LogicalLayout")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("PhysicalLayout")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<float>("RedScale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("Rotation")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("Scale")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("X")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<float>("Y")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<int>("ZIndex")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Devices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Workshop.EntryEntity", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Author")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("EntryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("EntryType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset>("InstalledAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Metadata")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<long>("ReleaseId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ReleaseVersion")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("EntryId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Entries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginFeatureEntity", b =>
|
||||
{
|
||||
b.HasOne("Artemis.Storage.Entities.Plugins.PluginEntity", null)
|
||||
.WithMany("Features")
|
||||
.HasForeignKey("PluginEntityId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileContainerEntity", b =>
|
||||
{
|
||||
b.HasOne("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", "ProfileCategory")
|
||||
.WithMany("ProfileConfigurations")
|
||||
.HasForeignKey("ProfileCategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ProfileCategory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Surface.DeviceEntity", b =>
|
||||
{
|
||||
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.DeviceInputIdentifierEntity>", "InputIdentifiers", b1 =>
|
||||
{
|
||||
b1.Property<string>("DeviceEntityId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b1.Property<int>("Capacity")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b1.HasKey("DeviceEntityId");
|
||||
|
||||
b1.ToTable("Devices");
|
||||
|
||||
b1.ToJson("InputIdentifiers");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("DeviceEntityId");
|
||||
});
|
||||
|
||||
b.OwnsOne("System.Collections.Generic.List<Artemis.Storage.Entities.Surface.InputMappingEntity>", "InputMappings", b1 =>
|
||||
{
|
||||
b1.Property<string>("DeviceEntityId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b1.Property<int>("Capacity")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b1.HasKey("DeviceEntityId");
|
||||
|
||||
b1.ToTable("Devices");
|
||||
|
||||
b1.ToJson("InputMappings");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("DeviceEntityId");
|
||||
});
|
||||
|
||||
b.Navigation("InputIdentifiers")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("InputMappings")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Plugins.PluginEntity", b =>
|
||||
{
|
||||
b.Navigation("Features");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Artemis.Storage.Entities.Profile.ProfileCategoryEntity", b =>
|
||||
{
|
||||
b.Navigation("ProfileConfigurations");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,50 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Surface;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using LiteDB;
|
||||
|
||||
namespace Artemis.Storage.Repositories;
|
||||
|
||||
internal class DeviceRepository : IDeviceRepository
|
||||
internal class DeviceRepository(Func<ArtemisDbContext> getContext) : IDeviceRepository
|
||||
{
|
||||
private readonly LiteRepository _repository;
|
||||
|
||||
public DeviceRepository(LiteRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
_repository.Database.GetCollection<DeviceEntity>().EnsureIndex(s => s.Id);
|
||||
}
|
||||
|
||||
public void Add(DeviceEntity deviceEntity)
|
||||
{
|
||||
_repository.Insert(deviceEntity);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Devices.Add(deviceEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Remove(DeviceEntity deviceEntity)
|
||||
{
|
||||
_repository.Delete<DeviceEntity>(deviceEntity.Id);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Devices.Remove(deviceEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public DeviceEntity? Get(string id)
|
||||
{
|
||||
return _repository.FirstOrDefault<DeviceEntity>(s => s.Id == id);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Devices.FirstOrDefault(d => d.Id == id);
|
||||
}
|
||||
|
||||
public List<DeviceEntity> GetAll()
|
||||
{
|
||||
return _repository.Query<DeviceEntity>().Include(s => s.InputIdentifiers).ToList();
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Devices.ToList();
|
||||
}
|
||||
|
||||
|
||||
public void Save(DeviceEntity deviceEntity)
|
||||
{
|
||||
_repository.Upsert(deviceEntity);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Update(deviceEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Save(IEnumerable<DeviceEntity> deviceEntities)
|
||||
|
||||
public void SaveRange(IEnumerable<DeviceEntity> deviceEntities)
|
||||
{
|
||||
_repository.Upsert(deviceEntities);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.UpdateRange(deviceEntities);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Workshop;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using LiteDB;
|
||||
|
||||
namespace Artemis.Storage.Repositories;
|
||||
|
||||
internal class EntryRepository : IEntryRepository
|
||||
internal class EntryRepository(Func<ArtemisDbContext> getContext) : IEntryRepository
|
||||
{
|
||||
private readonly LiteRepository _repository;
|
||||
|
||||
public EntryRepository(LiteRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
_repository.Database.GetCollection<EntryEntity>().EnsureIndex(s => s.Id);
|
||||
_repository.Database.GetCollection<EntryEntity>().EnsureIndex(s => s.EntryId);
|
||||
}
|
||||
|
||||
public void Add(EntryEntity entryEntity)
|
||||
{
|
||||
_repository.Insert(entryEntity);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Entries.Add(entryEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Remove(EntryEntity entryEntity)
|
||||
{
|
||||
_repository.Delete<EntryEntity>(entryEntity.Id);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Entries.Remove(entryEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public EntryEntity? Get(Guid id)
|
||||
{
|
||||
return _repository.FirstOrDefault<EntryEntity>(s => s.Id == id);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Entries.FirstOrDefault(s => s.Id == id);
|
||||
}
|
||||
|
||||
public EntryEntity? GetByEntryId(long entryId)
|
||||
{
|
||||
return _repository.FirstOrDefault<EntryEntity>(s => s.EntryId == entryId);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Entries.FirstOrDefault(s => s.EntryId == entryId);
|
||||
}
|
||||
|
||||
public List<EntryEntity> GetAll()
|
||||
{
|
||||
return _repository.Query<EntryEntity>().ToList();
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Entries.ToList();
|
||||
}
|
||||
|
||||
|
||||
public void Save(EntryEntity entryEntity)
|
||||
{
|
||||
_repository.Upsert(entryEntity);
|
||||
}
|
||||
|
||||
public void Save(IEnumerable<EntryEntity> entryEntities)
|
||||
{
|
||||
_repository.Upsert(entryEntities);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Update(entryEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,5 @@ public interface IDeviceRepository : IRepository
|
||||
DeviceEntity? Get(string id);
|
||||
List<DeviceEntity> GetAll();
|
||||
void Save(DeviceEntity deviceEntity);
|
||||
void Save(IEnumerable<DeviceEntity> deviceEntities);
|
||||
void SaveRange(IEnumerable<DeviceEntity> deviceEntities);
|
||||
}
|
||||
@@ -12,5 +12,4 @@ public interface IEntryRepository : IRepository
|
||||
EntryEntity? GetByEntryId(long entryId);
|
||||
List<EntryEntity> GetAll();
|
||||
void Save(EntryEntity entryEntity);
|
||||
void Save(IEnumerable<EntryEntity> entryEntities);
|
||||
}
|
||||
@@ -5,13 +5,9 @@ namespace Artemis.Storage.Repositories.Interfaces;
|
||||
|
||||
public interface IPluginRepository : IRepository
|
||||
{
|
||||
void AddPlugin(PluginEntity pluginEntity);
|
||||
PluginEntity? GetPluginByGuid(Guid pluginGuid);
|
||||
void SavePlugin(PluginEntity pluginEntity);
|
||||
|
||||
void AddSetting(PluginSettingEntity pluginSettingEntity);
|
||||
PluginSettingEntity? GetSettingByGuid(Guid pluginGuid);
|
||||
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||
PluginEntity? GetPluginByPluginGuid(Guid pluginGuid);
|
||||
void SaveSetting(PluginSettingEntity pluginSettingEntity);
|
||||
void SavePlugin(PluginEntity pluginEntity);
|
||||
PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid);
|
||||
void RemoveSettings(Guid pluginGuid);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Storage.Repositories.Interfaces;
|
||||
@@ -11,8 +10,7 @@ public interface IProfileCategoryRepository : IRepository
|
||||
void Remove(ProfileCategoryEntity profileCategoryEntity);
|
||||
List<ProfileCategoryEntity> GetAll();
|
||||
ProfileCategoryEntity? Get(Guid id);
|
||||
Stream? GetProfileIconStream(Guid id);
|
||||
void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream);
|
||||
ProfileCategoryEntity IsUnique(string name, Guid? id);
|
||||
bool IsUnique(string name, Guid? id);
|
||||
void Save(ProfileCategoryEntity profileCategoryEntity);
|
||||
void SaveRange(List<ProfileCategoryEntity> profileCategoryEntities);
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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(ProfileEntity profileEntity);
|
||||
void Remove(ProfileEntity profileEntity);
|
||||
List<ProfileEntity> GetAll();
|
||||
ProfileEntity? Get(Guid id);
|
||||
void Save(ProfileEntity profileEntity);
|
||||
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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Artemis.Storage.Entities.General;
|
||||
|
||||
namespace Artemis.Storage.Repositories.Interfaces;
|
||||
|
||||
public interface IReleaseRepository : IRepository
|
||||
{
|
||||
bool SaveVersionInstallDate(string version);
|
||||
ReleaseEntity? GetPreviousInstalledVersion();
|
||||
}
|
||||
@@ -1,59 +1,44 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Plugins;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using LiteDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Repositories;
|
||||
|
||||
internal class PluginRepository : IPluginRepository
|
||||
internal class PluginRepository(Func<ArtemisDbContext> getContext) : IPluginRepository
|
||||
{
|
||||
private readonly LiteRepository _repository;
|
||||
|
||||
public PluginRepository(LiteRepository repository)
|
||||
public PluginEntity? GetPluginByPluginGuid(Guid pluginGuid)
|
||||
{
|
||||
_repository = repository;
|
||||
|
||||
_repository.Database.GetCollection<PluginSettingEntity>().EnsureIndex(s => new {s.Name, s.PluginGuid}, true);
|
||||
}
|
||||
|
||||
public void AddPlugin(PluginEntity pluginEntity)
|
||||
{
|
||||
_repository.Insert(pluginEntity);
|
||||
}
|
||||
|
||||
public PluginEntity? GetPluginByGuid(Guid pluginGuid)
|
||||
{
|
||||
return _repository.FirstOrDefault<PluginEntity>(p => p.Id == pluginGuid);
|
||||
}
|
||||
|
||||
public void SavePlugin(PluginEntity pluginEntity)
|
||||
{
|
||||
_repository.Upsert(pluginEntity);
|
||||
}
|
||||
|
||||
public void AddSetting(PluginSettingEntity pluginSettingEntity)
|
||||
{
|
||||
_repository.Insert(pluginSettingEntity);
|
||||
}
|
||||
|
||||
public PluginSettingEntity? GetSettingByGuid(Guid pluginGuid)
|
||||
{
|
||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.PluginGuid == pluginGuid);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Plugins.Include(p => p.Features).FirstOrDefault(p => p.PluginGuid == pluginGuid);
|
||||
}
|
||||
|
||||
public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid)
|
||||
{
|
||||
return _repository.FirstOrDefault<PluginSettingEntity>(p => p.Name == name && p.PluginGuid == pluginGuid);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
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)
|
||||
{
|
||||
_repository.DeleteMany<PluginSettingEntity>(s => s.PluginGuid == pluginGuid);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.PluginSettings.RemoveRange(dbContext.PluginSettings.Where(s => s.PluginGuid == pluginGuid));
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void SaveSetting(PluginSettingEntity pluginSettingEntity)
|
||||
{
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.PluginSettings.Update(pluginSettingEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void SavePlugin(PluginEntity pluginEntity)
|
||||
{
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Update(pluginEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using LiteDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage.Repositories;
|
||||
|
||||
internal class ProfileCategoryRepository : IProfileCategoryRepository
|
||||
internal class ProfileCategoryRepository(Func<ArtemisDbContext> getContext, IProfileRepository profileRepository) : IProfileCategoryRepository
|
||||
{
|
||||
private readonly ILiteStorage<Guid> _profileIcons;
|
||||
private readonly LiteRepository _repository;
|
||||
|
||||
public ProfileCategoryRepository(LiteRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
_repository.Database.GetCollection<ProfileCategoryEntity>().EnsureIndex(s => s.Name, true);
|
||||
_profileIcons = _repository.Database.GetStorage<Guid>("profileIcons");
|
||||
}
|
||||
private bool _migratedProfiles;
|
||||
|
||||
public void Add(ProfileCategoryEntity profileCategoryEntity)
|
||||
{
|
||||
_repository.Insert(profileCategoryEntity);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.ProfileCategories.Add(profileCategoryEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Remove(ProfileCategoryEntity profileCategoryEntity)
|
||||
{
|
||||
_repository.Delete<ProfileCategoryEntity>(profileCategoryEntity.Id);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.ProfileCategories.Remove(profileCategoryEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public List<ProfileCategoryEntity> GetAll()
|
||||
{
|
||||
List<ProfileCategoryEntity> categories = _repository.Query<ProfileCategoryEntity>().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);
|
||||
if (!_migratedProfiles)
|
||||
{
|
||||
profileRepository.MigrateProfiles();
|
||||
_migratedProfiles = true;
|
||||
}
|
||||
|
||||
return categories;
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).ToList();
|
||||
}
|
||||
|
||||
public ProfileCategoryEntity? Get(Guid id)
|
||||
{
|
||||
ProfileCategoryEntity? result = _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Id == id);
|
||||
if (result == null)
|
||||
return null;
|
||||
if (!_migratedProfiles)
|
||||
{
|
||||
profileRepository.MigrateProfiles();
|
||||
_migratedProfiles = true;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
name = name.Trim();
|
||||
if (id == null)
|
||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Name == name);
|
||||
return _repository.FirstOrDefault<ProfileCategoryEntity>(p => p.Name == name && p.Id != id.Value);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.ProfileCategories.Include(c => c.ProfileConfigurations).FirstOrDefault(c => c.Id == id);
|
||||
}
|
||||
|
||||
public void Save(ProfileCategoryEntity profileCategoryEntity)
|
||||
{
|
||||
_repository.Upsert(profileCategoryEntity);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Update(profileCategoryEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public Stream? GetProfileIconStream(Guid id)
|
||||
public void SaveRange(List<ProfileCategoryEntity> profileCategoryEntities)
|
||||
{
|
||||
if (!_profileIcons.Exists(id))
|
||||
return null;
|
||||
|
||||
MemoryStream stream = new();
|
||||
_profileIcons.Download(id, stream);
|
||||
return stream;
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.UpdateRange(profileCategoryEntities);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream)
|
||||
public bool IsUnique(string name, Guid? id)
|
||||
{
|
||||
if (profileConfigurationEntity.FileIconId == Guid.Empty)
|
||||
profileConfigurationEntity.FileIconId = Guid.NewGuid();
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
|
||||
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)
|
||||
{
|
||||
foreach (ProfileConfigurationEntity profileConfigurationEntity in profileCategoryEntity.ProfileConfigurations)
|
||||
profileConfigurationEntity.Version = StorageMigrationService.PROFILE_VERSION;
|
||||
name = name.Trim();
|
||||
return id == null
|
||||
? dbContext.ProfileCategories.Any(p => p.Name == name)
|
||||
: dbContext.ProfileCategories.Any(p => p.Name == name && p.Id != id.Value);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,104 @@
|
||||
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 LiteDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Serilog;
|
||||
|
||||
namespace Artemis.Storage.Repositories;
|
||||
|
||||
internal class ProfileRepository : IProfileRepository
|
||||
public class ProfileRepository(ILogger logger, Func<ArtemisDbContext> getContext, List<IProfileMigration> profileMigrators) : IProfileRepository
|
||||
{
|
||||
private readonly LiteRepository _repository;
|
||||
|
||||
public ProfileRepository(LiteRepository repository)
|
||||
public void Add(ProfileContainerEntity profileContainerEntity)
|
||||
{
|
||||
_repository = repository;
|
||||
_repository.Database.GetCollection<ProfileEntity>().EnsureIndex(s => s.Name);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.ProfileContainers.Add(profileContainerEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Add(ProfileEntity profileEntity)
|
||||
public void Remove(ProfileContainerEntity profileContainerEntity)
|
||||
{
|
||||
_repository.Insert(profileEntity);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.ProfileContainers.Remove(profileContainerEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Remove(ProfileEntity profileEntity)
|
||||
public void Save(ProfileContainerEntity profileContainerEntity)
|
||||
{
|
||||
_repository.Delete<ProfileEntity>(profileEntity.Id);
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.Update(profileContainerEntity);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public List<ProfileEntity> GetAll()
|
||||
public void SaveRange(List<ProfileContainerEntity> profileContainerEntities)
|
||||
{
|
||||
return _repository.Query<ProfileEntity>().ToList();
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
dbContext.UpdateRange(profileContainerEntities);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public ProfileEntity? Get(Guid id)
|
||||
public void MigrateProfiles()
|
||||
{
|
||||
return _repository.FirstOrDefault<ProfileEntity>(p => p.Id == id);
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
JsonObject? profileConfiguration = JsonNode.Parse(rawProfileContainer.ProfileConfiguration)?.AsObject();
|
||||
JsonObject? profile = JsonNode.Parse(rawProfileContainer.Profile)?.AsObject();
|
||||
|
||||
if (profileConfiguration == null || profile == null)
|
||||
{
|
||||
logger.Error("Failed to parse profile or profile configuration of profile container {Id}", rawProfileContainer.Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, "Failed to migrate profile container {Id}", rawProfileContainer.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(ProfileEntity profileEntity)
|
||||
public void MigrateProfile(JsonObject? configurationJson, JsonObject? profileJson)
|
||||
{
|
||||
_repository.Upsert(profileEntity);
|
||||
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;
|
||||
|
||||
logger.Information("Migrating profile '{Name}' from version {OldVersion} to {NewVersion}", configurationJson["Name"], configurationJson["Version"], profileMigrator.Version);
|
||||
|
||||
profileMigrator.Migrate(configurationJson, profileJson);
|
||||
configurationJson["Version"] = profileMigrator.Version;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,28 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.General;
|
||||
using Artemis.Storage.Repositories.Interfaces;
|
||||
using LiteDB;
|
||||
|
||||
namespace Artemis.Storage.Repositories;
|
||||
|
||||
public class ReleaseRepository : IReleaseRepository
|
||||
public class ReleaseRepository(Func<ArtemisDbContext> getContext) : IReleaseRepository
|
||||
{
|
||||
private readonly LiteRepository _repository;
|
||||
|
||||
public ReleaseRepository(LiteRepository repository)
|
||||
{
|
||||
_repository = repository;
|
||||
_repository.Database.GetCollection<ReleaseEntity>().EnsureIndex(s => s.Version, true);
|
||||
}
|
||||
|
||||
public bool SaveVersionInstallDate(string version)
|
||||
{
|
||||
ReleaseEntity release = _repository.Query<ReleaseEntity>().Where(r => r.Version == version).FirstOrDefault();
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
|
||||
ReleaseEntity? release = dbContext.Releases.FirstOrDefault(r => r.Version == version);
|
||||
if (release != null)
|
||||
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;
|
||||
}
|
||||
|
||||
public ReleaseEntity GetPreviousInstalledVersion()
|
||||
public ReleaseEntity? GetPreviousInstalledVersion()
|
||||
{
|
||||
return _repository.Query<ReleaseEntity>().OrderByDescending(r => r.InstalledAt).Skip(1).FirstOrDefault();
|
||||
using ArtemisDbContext dbContext = getContext();
|
||||
return dbContext.Releases.AsEnumerable().OrderByDescending(r => r.InstalledAt).Skip(1).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IReleaseRepository : IRepository
|
||||
{
|
||||
bool SaveVersionInstallDate(string version);
|
||||
ReleaseEntity GetPreviousInstalledVersion();
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using LiteDB;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Artemis.Storage;
|
||||
|
||||
public static class StorageManager
|
||||
{
|
||||
private static bool _ranMigrations;
|
||||
private static bool _inUse;
|
||||
|
||||
/// <summary>
|
||||
@@ -19,7 +20,7 @@ public static class StorageManager
|
||||
if (_inUse)
|
||||
throw new Exception("Storage is already in use, can't backup now.");
|
||||
|
||||
string database = Path.Combine(dataFolder, "database.db");
|
||||
string database = Path.Combine(dataFolder, "artemis.db");
|
||||
if (!File.Exists(database))
|
||||
return;
|
||||
|
||||
@@ -36,27 +37,21 @@ public static class StorageManager
|
||||
oldest.Delete();
|
||||
}
|
||||
|
||||
File.Copy(database, Path.Combine(backupFolder, $"database-{DateTime.Now:yyyy-dd-M--HH-mm-ss}.db"));
|
||||
File.Copy(database, Path.Combine(backupFolder, $"artemis-{DateTime.Now:yyyy-dd-M--HH-mm-ss}.db"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the LiteRepository that will be managed by dependency injection
|
||||
/// </summary>
|
||||
/// <param name="dataFolder">The Artemis data folder</param>
|
||||
public static LiteRepository CreateRepository(string dataFolder)
|
||||
|
||||
public static ArtemisDbContext CreateDbContext(string dataFolder)
|
||||
{
|
||||
if (_inUse)
|
||||
throw new Exception("Storage is already in use, use dependency injection to get the repository.");
|
||||
_inUse = true;
|
||||
|
||||
try
|
||||
{
|
||||
_inUse = true;
|
||||
return new LiteRepository($"FileName={Path.Combine(dataFolder, "database.db")}");
|
||||
}
|
||||
catch (LiteException e)
|
||||
{
|
||||
// I don't like this way of error reporting, now I need to use reflection if I want a meaningful error message
|
||||
throw new Exception($"LiteDB threw error code {e.ErrorCode}. See inner exception for more details", e);
|
||||
}
|
||||
ArtemisDbContext dbContext = new() {DataFolder = dataFolder};
|
||||
if (_ranMigrations)
|
||||
return dbContext;
|
||||
|
||||
dbContext.Database.Migrate();
|
||||
dbContext.Database.ExecuteSqlRaw("PRAGMA optimize");
|
||||
_ranMigrations = true;
|
||||
|
||||
return dbContext;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user