- Added factory class for EF tooling - Removed no longer needed Program.cs
130 lines
5.2 KiB
C#
130 lines
5.2 KiB
C#
using DataModel.Database;
|
|
using DataModel.Database.Common;
|
|
using DataModel.MigrationScripts;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace DataModel;
|
|
|
|
public static class Setup
|
|
{
|
|
private const string DB_READ_WRITE_MODE = "ReadWrite";
|
|
private const string DB_READ_WRITE_CREATE_MODE = "ReadWriteCreate";
|
|
|
|
private static string USED_DATA_FILE = string.Empty;
|
|
private static SetupMaintenance SETUP_MAINTENANCE = new();
|
|
|
|
public static string DataFile => Setup.USED_DATA_FILE;
|
|
|
|
public static SetupMaintenance Maintenance => Setup.SETUP_MAINTENANCE;
|
|
|
|
/// <summary>
|
|
/// Tries to migrate the database.
|
|
/// </summary>
|
|
public static async Task PerformDataMigration(DataContext dbContext)
|
|
{
|
|
var pendingMigrations = (await dbContext.Database.GetPendingMigrationsAsync()).ToList();
|
|
foreach (var pendingMigration in pendingMigrations)
|
|
{
|
|
Console.WriteLine($"The migration '{pendingMigration}' is pending.");
|
|
}
|
|
|
|
await dbContext.Database.MigrateAsync();
|
|
|
|
//
|
|
// Post migration actions:
|
|
//
|
|
if (pendingMigrations.Contains("20221106193544_202211AddUniqueIds"))
|
|
await Script202211AddUniqueIds.PostMigrationAsync(dbContext);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imports a JSON file into a new database.
|
|
/// </summary>
|
|
public static async Task ImportDataAndAddDatabase(this IServiceCollection serviceCollection, string path2JSONFile)
|
|
{
|
|
var tempPath = Path.GetTempFileName();
|
|
|
|
Setup.USED_DATA_FILE = tempPath;
|
|
Setup.SETUP_MAINTENANCE = new(path2JSONFile, true);
|
|
serviceCollection.AddDbContext<DataContext>(options => options.UseSqlite($"Filename={tempPath};Mode={DB_READ_WRITE_CREATE_MODE};"), ServiceLifetime.Transient);
|
|
|
|
// Get the database service:
|
|
await using var serviceProvider = serviceCollection.BuildServiceProvider();
|
|
var dbContext = serviceProvider.GetRequiredService<DataContext>();
|
|
|
|
// Next, we import the data from the provided JSON file:
|
|
await dbContext.ImportAsync(path2JSONFile);
|
|
|
|
//
|
|
// Next, we enable the auto-export feature to keep the source file up to date.
|
|
// The auto-export feature might exist, but we enforce it, when we work with a
|
|
// temporary database source by a JSON file.
|
|
//
|
|
|
|
// Enable the auto-export feature:
|
|
var autoExportEnabled = await dbContext.Settings.FirstAsync(n => n.Code == SettingNames.AUTO_EXPORT_ENABLED);
|
|
autoExportEnabled.BoolValue = true;
|
|
|
|
// Set the auto-export path and file:
|
|
var autoExportPath = await dbContext.Settings.FirstAsync(n => n.Code == SettingNames.AUTO_EXPORT_DESTINATION_PATH);
|
|
autoExportPath.TextValue = Path.GetDirectoryName(path2JSONFile) ?? string.Empty;
|
|
|
|
var autoExportFile = await dbContext.Settings.FirstAsync(n => n.Code == SettingNames.AUTO_EXPORT_FILENAME);
|
|
autoExportFile.TextValue = Path.GetFileName(path2JSONFile);
|
|
|
|
// Save the changes:
|
|
await dbContext.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates and adds the database instance to the DI system (extension method).
|
|
/// </summary>
|
|
public static void AddDatabase(this IServiceCollection serviceCollection, string path2DataFile, bool createWhenNecessary = true)
|
|
{
|
|
Setup.USED_DATA_FILE = path2DataFile;
|
|
Setup.SETUP_MAINTENANCE = new(path2DataFile, false);
|
|
serviceCollection.AddDbContext<DataContext>(options => options.UseSqlite($"Filename={path2DataFile};Mode={(createWhenNecessary ? DB_READ_WRITE_CREATE_MODE : DB_READ_WRITE_MODE)};"), ServiceLifetime.Transient);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create the database instance from the given path. Used for the EF tooling.
|
|
/// </summary>
|
|
public static DataContext CreateDatabaseInstance4Tooling(string path2DataFile, bool createWhenNecessary = true)
|
|
{
|
|
// Store the path to the database:
|
|
Setup.USED_DATA_FILE = path2DataFile;
|
|
Setup.SETUP_MAINTENANCE = new(path2DataFile, false);
|
|
|
|
// Create a database builder:
|
|
var builder = new DbContextOptionsBuilder<DataContext>();
|
|
|
|
// Add the database configuration to the builder:
|
|
builder.UseSqlite($"Filename={path2DataFile};Mode={(createWhenNecessary ? DB_READ_WRITE_CREATE_MODE : DB_READ_WRITE_MODE)};");
|
|
|
|
// Next, construct the database context:
|
|
var dbContext = new DataContext(builder.Options);
|
|
return dbContext;
|
|
}
|
|
|
|
|
|
public readonly record struct SetupMaintenance(string PathToDataFile = "", bool RemoveTempDatabaseAfterwards = false) : IDisposable
|
|
{
|
|
public void Dispose()
|
|
{
|
|
if (!this.RemoveTempDatabaseAfterwards)
|
|
return;
|
|
|
|
try
|
|
{
|
|
File.Delete(this.PathToDataFile);
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Console.WriteLine($"Failed to remove the temporary database file: {e.Message} // {e.InnerException?.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|