I18NCommander/I18N Commander/DataModel/Setup.cs

163 lines
6.9 KiB
C#
Raw Normal View History

using System.Diagnostics;
using DataModel.Database;
using DataModel.Database.Common;
using DataModel.MigrationScripts;
2022-06-12 15:16:01 +00:00
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
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;
public static SetupMaintenance SETUP_MAINTENANCE = new();
public static string DataFile => Setup.USED_DATA_FILE;
2022-06-12 15:16:01 +00:00
/// <summary>
2023-01-18 18:59:18 +00:00
/// Tries to migrate the database.
2022-06-12 15:16:01 +00:00
/// </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);
2022-06-12 15:16:01 +00:00
}
2023-01-18 18:59:18 +00:00
2022-06-12 15:16:01 +00:00
/// <summary>
/// Imports a JSON file into a new database.
2022-06-12 15:16:01 +00:00
/// </summary>
public static async Task ImportDataAndAddDatabase(this IServiceCollection serviceCollection, string path2JSONFile)
2022-06-12 15:16:01 +00:00
{
Console.WriteLine($"Importing the data from the JSON file '{path2JSONFile}' into a new database.");
var tempPath = Path.GetTempFileName();
Console.WriteLine($"The temporary database file is: {tempPath}");
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>();
Setup.USED_DATA_FILE = tempPath;
Setup.SETUP_MAINTENANCE = new(tempPath, true);
// Migrate the database to create the tables etc.:
await Setup.PerformDataMigration(dbContext);
// 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:
//
if (await dbContext.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.AUTO_EXPORT_ENABLED) is { } autoExportEnabled)
autoExportEnabled.BoolValue = true;
else
dbContext.Settings.Add(new Setting {Code = SettingNames.AUTO_EXPORT_ENABLED, BoolValue = true});
//
// Set the auto-export path and file:
//
if(await dbContext.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.AUTO_EXPORT_DESTINATION_PATH) is { } autoExportPath)
autoExportPath.TextValue = Path.GetDirectoryName(path2JSONFile) ?? string.Empty;
else
dbContext.Settings.Add(new Setting {Code = SettingNames.AUTO_EXPORT_DESTINATION_PATH, TextValue = Path.GetDirectoryName(path2JSONFile) ?? string.Empty});
if(await dbContext.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.AUTO_EXPORT_FILENAME) is { } autoExportFile)
autoExportFile.TextValue = Path.GetFileName(path2JSONFile);
else
dbContext.Settings.Add(new Setting {Code = SettingNames.AUTO_EXPORT_FILENAME, TextValue = Path.GetFileName(path2JSONFile)});
// Ensure that the sensitive data setting is present and disabled by default:
var _ = await dbContext.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.AUTO_EXPORT_SENSITIVE_DATA) ?? new Setting
{
Code = SettingNames.AUTO_EXPORT_SENSITIVE_DATA,
BoolValue = false,
};
// Save the changes:
await dbContext.SaveChangesAsync();
2022-06-12 15:16:01 +00:00
}
2022-08-17 19:00:58 +00:00
/// <summary>
/// Creates and adds the database instance to the DI system (extension method).
2022-08-17 19:00:58 +00:00
/// </summary>
public static void AddDatabase(this IServiceCollection serviceCollection, string path2DataFile, bool createWhenNecessary = true)
2022-08-17 19:00:58 +00:00
{
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);
2022-08-17 19:00:58 +00:00
}
2022-06-12 15:16:01 +00:00
/// <summary>
/// Create the database instance from the given path. Used for the EF tooling.
2022-06-12 15:16:01 +00:00
/// </summary>
public static DataContext CreateDatabaseInstance4Tooling(string path2DataFile, bool createWhenNecessary = true)
2022-06-12 15:16:01 +00:00
{
// Store the path to the database:
Setup.USED_DATA_FILE = path2DataFile;
Setup.SETUP_MAINTENANCE = new(path2DataFile, false);
2022-06-12 15:16:01 +00:00
// 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;
2022-06-12 15:16:01 +00:00
}
public readonly record struct SetupMaintenance(string PathToDataFile = "", bool RemoveTempDatabaseAfterwards = false) : IDisposable
{
public void Dispose()
{
if (!this.RemoveTempDatabaseAfterwards)
return;
Console.WriteLine("Removing the temporary database file...");
try
{
var process = new Process
{
StartInfo = new()
{
FileName = "cmd.exe",
Arguments = $@"/C del /Q /F ""{Setup.SETUP_MAINTENANCE.PathToDataFile}""",
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();
Console.WriteLine($"The temporary database file '{this.PathToDataFile}' has been removed.");
}
catch(Exception e)
{
Console.WriteLine($"Failed to remove the temporary database file: {e.Message} // {e.InnerException?.Message}");
}
}
}
2022-06-12 15:16:01 +00:00
}