using Butter;
using Butter.Settings;
using Butter.Types;
using Lactose.Context;
using Lactose.Models;
using Microsoft.AspNetCore.Identity;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
namespace Lactose.Services;
///
/// Defines the contract for database initialization.
///
interface IDbInitializer {
///
/// Applies pending migrations and seeds default data.
///
void Initialize();
}
///
/// Initializes the database — applies migrations and seeds default users, settings, and folders.
///
internal class DbInitializer(LactoseDbContext dbContext, IPasswordHasher passwordHasher) : IDbInitializer {
///
public void Initialize() {
ArgumentNullException.ThrowIfNull(dbContext, nameof(dbContext));
var task = dbContext.Database.GetPendingMigrationsAsync();
task.ContinueWith((r) => {
if (r.Result.Any()) dbContext.Database.Migrate();
}
)
.Wait();
// if(dbContext.Database.GetPendingMigrations().Any()) // Timeoout
#region Users
if (!dbContext.Users.Any()) {
var user = new User {
Username = "admin",
Email = "admin@admin.com",
AccessLevel = EAccessLevel.Admin,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
};
user.Password = passwordHasher.HashPassword(user, "admin");
dbContext.Users.Add(user);
dbContext.SaveChanges();
}
#endregion
#region Settings
var settings = System.Text.Json.JsonSerializer.Deserialize>(File.ReadAllText("DefaultSettings.json"));
if (settings is not null) {
//remove all settings that are not in the default settings file
var existingSettings = dbContext.Settings.ToList();
foreach (Setting existingSetting in existingSettings.Where(existingSetting
=> settings.All(s => s.Name != existingSetting.Name)
)) dbContext.Settings.Remove(existingSetting);
settings.First(s => s.Name == Settings.ThumbnailPath.AsString()).Value
= Path.Combine(Environment.CurrentDirectory, "thumbnails");
settings.First(s => s.Name == Settings.PreviewPath.AsString()).Value
= Path.Combine(Environment.CurrentDirectory, "previews");
// set max concurrent jobs to number of processors - 2, at least one. (who the fuck is using a single core cpu?)
settings.First(s => s.Name == Settings.MaxConcurrentJobs.AsString()).Value
= (Math.Max(Environment.ProcessorCount - 2, 1)).ToString();
// add or update settings from the default settings file leaving value unchanged
foreach (var setting in settings) {
if (!dbContext.Settings.Any(s => s.Name == setting.Name)) { dbContext.Settings.Add(setting); } else {
var dbSetting = dbContext.Settings.First(s => s.Name == setting.Name);
dbSetting.Description = setting.Description;
dbSetting.Type = setting.Type;
dbSetting.DisplayType = setting.DisplayType;
dbSetting.Options = setting.Options;
dbContext.Settings.Update(dbSetting);
}
}
dbContext.SaveChanges();
} //else, we are a bit fucked.
#endregion
#region Folders
if (!dbContext.Folders.Any()) {
dbContext.Folders.Add(
new Folder() {
BasePath = "/diary",
Active = false
}
);
}
dbContext.SaveChanges();
#endregion
}
}