More features
This commit is contained in:
@@ -1,30 +1,108 @@
|
||||
using DCGEngine.Database;
|
||||
using DCGEngine.Database.Configuration;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using SVSim.Database.Common;
|
||||
using SVSim.Database.DataSeeders;
|
||||
using SVSim.Database.Models;
|
||||
|
||||
namespace SVSim.Database;
|
||||
|
||||
public class SVSimDbContext : DCGEDbContext
|
||||
public class SVSimDbContext : DbContext
|
||||
{
|
||||
public SVSimDbContext(IOptions<DCGEDatabaseConfiguration> configuration, ILogger<DCGEDbContext> logger, DbContextOptions options) : base(configuration, logger, options)
|
||||
private readonly ILogger<SVSimDbContext> _logger;
|
||||
|
||||
public SVSimDbContext(ILogger<SVSimDbContext> logger, DbContextOptions<SVSimDbContext> options) : base(options)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
#region DbSets
|
||||
|
||||
public DbSet<Viewer> Viewers => Set<Viewer>();
|
||||
|
||||
public DbSet<ShadowverseCardEntry> Cards => Set<ShadowverseCardEntry>();
|
||||
public DbSet<ShadowverseCardSetEntry> CardSets => Set<ShadowverseCardSetEntry>();
|
||||
public DbSet<ShadowverseDeckEntry> Decks => Set<ShadowverseDeckEntry>();
|
||||
|
||||
public DbSet<ClassEntry> Classes => Set<ClassEntry>();
|
||||
public DbSet<ClassExpEntry> ClassExpCurve => Set<ClassExpEntry>();
|
||||
public DbSet<LeaderSkinEntry> LeaderSkins => Set<LeaderSkinEntry>();
|
||||
public DbSet<SleeveEntry> Sleeves => Set<SleeveEntry>();
|
||||
public DbSet<EmblemEntry> Emblems => Set<EmblemEntry>();
|
||||
public DbSet<DegreeEntry> Degrees => Set<DegreeEntry>();
|
||||
public DbSet<MyPageBackgroundEntry> MyPageBackgrounds => Set<MyPageBackgroundEntry>();
|
||||
public DbSet<BattlefieldEntry> Battlefields => Set<BattlefieldEntry>();
|
||||
public DbSet<RankInfoEntry> RankInfo => Set<RankInfoEntry>();
|
||||
public DbSet<ItemEntry> Items => Set<ItemEntry>();
|
||||
|
||||
public DbSet<GameConfiguration> GameConfigurations => Set<GameConfiguration>();
|
||||
|
||||
#endregion
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
foreach (var entityEntry in ChangeTracker.Entries())
|
||||
{
|
||||
if (entityEntry.Entity is ITimeTrackedEntity timeTrackedEntity)
|
||||
{
|
||||
if (entityEntry.State is EntityState.Added && timeTrackedEntity.DateCreated == DateTime.MinValue)
|
||||
{
|
||||
timeTrackedEntity.DateCreated = DateTime.UtcNow;
|
||||
}
|
||||
if (entityEntry.State is EntityState.Modified or EntityState.Added)
|
||||
{
|
||||
timeTrackedEntity.DateUpdated = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await base.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
modelBuilder.Entity<ShadowverseDeckEntry>()
|
||||
.OwnsMany(de => de.Cards);
|
||||
|
||||
// For whatever reason it cannot figure out this relationship on it's own
|
||||
// BaseEntity<TKey> annotates Id with [DatabaseGenerated(None)] for the integer-PK
|
||||
// entities seeded via HasData. ShadowverseDeckEntry uses Guid and is created at
|
||||
// runtime — without client-side generation every new deck gets Guid.Empty and the
|
||||
// second deck insert collides on PK. (DDL has no column default; this only works
|
||||
// because EF generates a sequential Guid before INSERT.)
|
||||
modelBuilder.Entity<ShadowverseDeckEntry>()
|
||||
.Property(d => d.Id)
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
// EF can't figure this many-to-many out on its own
|
||||
modelBuilder.Entity<SleeveEntry>()
|
||||
.HasMany<Viewer>(se => se.Viewers)
|
||||
.HasMany(se => se.Viewers)
|
||||
.WithMany(v => v.Sleeves);
|
||||
|
||||
modelBuilder.HasSequence<long>("ShortUdidSequence").StartsAt(400000000);
|
||||
modelBuilder.Entity<Viewer>()
|
||||
.Property(v => v.ShortUdid)
|
||||
.UseSequence("ShortUdidSequence");
|
||||
|
||||
new BaseDataSeeder().Seed(modelBuilder);
|
||||
new DefaultSettingsSeeder().Seed(modelBuilder);
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateDatabase()
|
||||
{
|
||||
IEnumerable<string> pendingMigrations = Database.GetPendingMigrations();
|
||||
if (!pendingMigrations.Any())
|
||||
{
|
||||
_logger.LogDebug("No pending migrations found, continuing.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string migration in pendingMigrations)
|
||||
{
|
||||
_logger.LogInformation("Found pending migration with name {migrationName}.", migration);
|
||||
}
|
||||
_logger.LogInformation("Attempting to apply pending migrations...");
|
||||
Database.Migrate();
|
||||
_logger.LogInformation("Migrations applied.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user