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 } }