From 63761001fa19602651f8e9307735381883ed130f Mon Sep 17 00:00:00 2001 From: Torben Nehmer Date: Fri, 20 Sep 2024 19:01:09 +0200 Subject: [PATCH] implement startup database loading (path still hardcoded) --- Stars Assistant/Model/Game.cs | 23 +++++++++++++ Stars Assistant/Model/StarsDatabase.cs | 2 +- Stars Assistant/Program.cs | 40 +++++++++++++++-------- Stars Assistant/Services/Game.cs | 45 ++++++++++++++++++++++++-- 4 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 Stars Assistant/Model/Game.cs diff --git a/Stars Assistant/Model/Game.cs b/Stars Assistant/Model/Game.cs new file mode 100644 index 0000000..1640975 --- /dev/null +++ b/Stars Assistant/Model/Game.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace StarsAssistant.Model; + +public class Game +{ + /// + /// Dummy primary key, normally not used, but makes working with EF easier. + /// + public int GameId { get; set; } + + /// + /// The base path in which all game files reside. + /// + public string GamePath { get; set; } = String.Empty; + + /// + /// The base name without extensions of your game, inside the GamePath folder. + /// All dependant files are resolved using this name. + /// + public string BaseName { get; set; } = String.Empty; +} diff --git a/Stars Assistant/Model/StarsDatabase.cs b/Stars Assistant/Model/StarsDatabase.cs index 0181803..58bc17d 100644 --- a/Stars Assistant/Model/StarsDatabase.cs +++ b/Stars Assistant/Model/StarsDatabase.cs @@ -37,7 +37,7 @@ public class StarsDatabase(string DbPath) : DbContext /// /// The record with all game metadata, will only contain a single line at all times. /// - // public DbSet Game { get; set; } + public DbSet Game { get; set; } #endregion } \ No newline at end of file diff --git a/Stars Assistant/Program.cs b/Stars Assistant/Program.cs index fc460e4..4458e27 100644 --- a/Stars Assistant/Program.cs +++ b/Stars Assistant/Program.cs @@ -25,19 +25,37 @@ sealed class Program var logger = new ConsoleLogger() { Level = LogLevel.Debug }; Locator.CurrentMutable.RegisterConstant(logger, typeof(ILogger)); - Services.Game g = new() + bool newGame = false; + string dbPath = "/home/torben/Nextcloud/Documents/Stars!/Games/goingth/GOINGTH.sqlite"; + Services.Game gameSvc; + + using (StarsDatabase starsDB = new(dbPath)) { - BaseName = "GOINGTH", - GamePath = "/home/torben/goingth/" - }; + if (Path.Exists(dbPath)) + { + Model.Game dbGame = starsDB.Game.First(); + gameSvc = new Services.Game(dbGame); + } + else + { + starsDB.Database.EnsureCreated(); + gameSvc = new() + { + BaseName = "GOINGTH", + GamePath = "/home/torben/Nextcloud/Documents/Stars!/Games/goingth/" + }; + gameSvc.SaveToDatabase(starsDB); + newGame = true; + } + } - Locator.CurrentMutable.RegisterConstant(g, typeof(Services.Game)); - Locator.CurrentMutable.RegisterConstant(new Services.CSVDataLoader(), typeof(Services.CSVDataLoader)); - Locator.CurrentMutable.Register(() => new StarsDatabase(g.DatabaseFileName), typeof(StarsDatabase)); + Locator.CurrentMutable.RegisterConstant(gameSvc, typeof(Services.Game)); Locator.CurrentMutable.RegisterConstant(new Services.CSVDataLoader(), typeof(Services.CSVDataLoader)); + Locator.CurrentMutable.Register(() => new StarsDatabase(gameSvc.DatabaseFileName), typeof(StarsDatabase)); + + if (newGame) + __createTestData(); - __createTestData(); - BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); } @@ -53,12 +71,8 @@ sealed class Program public static void __createTestData () { - Services.Game game = Locator.Current.GetService()!; using var db = Locator.Current.GetService()!; - db.Database.EnsureDeleted(); - db.Database.EnsureCreated(); - // Note: This sample requires the database to be created before running. // Console.WriteLine($"Database path: {db.DbPath}."); diff --git a/Stars Assistant/Services/Game.cs b/Stars Assistant/Services/Game.cs index 019af0c..e7d49f1 100644 --- a/Stars Assistant/Services/Game.cs +++ b/Stars Assistant/Services/Game.cs @@ -1,17 +1,58 @@ +using Splat; + namespace StarsAssistant.Services; public class Game { + /// + /// Default constructor, initialize required fields manually, targeted + /// for Initial DB creation. + /// + public Game() {} + + /// + /// Init game state from database, targeted for CLI arg. + /// + /// Record loaded from DB + public Game(Model.Game dbGame) + { + GamePath = dbGame.GamePath; + BaseName = dbGame.BaseName; + } + + /// + /// Save this record in the database. Uses the service locator to access the + /// database unless you specify an instance. This is needed during initial + /// game creation, where the services are not yet established. + /// + /// Optional DB instance if services are yet unavailable. + public void SaveToDatabase(Model.StarsDatabase? db = null) + { + db ??= Locator.Current.GetService()!; + + Model.Game? dbGame = db.Game.FirstOrDefault(); + if (dbGame == null) + { + dbGame = new Model.Game(); + db.Add(dbGame); + db.SaveChanges(); + } + dbGame.GamePath = GamePath; + dbGame.BaseName = BaseName; + db.Update(dbGame); + db.SaveChanges(); + } + /// /// The base path in which all game files reside. /// - public required string GamePath { get; set; } + public string GamePath { get; set; } = String.Empty; /// /// The base name without extensions of your game, inside the GamePath folder. /// All dependant files are resolved using this name. /// - public required string BaseName { get; set; } + public string BaseName { get; set; } = String.Empty; /// /// Combine into the DatabaseName