Setup CSV Fleet import and EF Fleet Entity, fix a few bugs
This commit is contained in:
		@@ -35,61 +35,116 @@ public class Fleet
 | 
				
			|||||||
    [Index(9)]
 | 
					    [Index(9)]
 | 
				
			||||||
    public int Germanium { get; set; }
 | 
					    public int Germanium { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(0)]
 | 
					    [Index(10)]
 | 
				
			||||||
    public int Colonists { get; set; }
 | 
					    public int Colonists { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(1)]
 | 
					    [Index(11)]
 | 
				
			||||||
    public int Fuel { get; set; }
 | 
					    public int Fuel { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(2)]
 | 
					    [Index(12)]
 | 
				
			||||||
    public int OwnerPlayerNumber { get; set; }
 | 
					    public int OwnerFileId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(3)]
 | 
					    [Ignore()]
 | 
				
			||||||
    public int ETA { get; set; }
 | 
					    public int ETA { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(4)]
 | 
					    [Index(13)]
 | 
				
			||||||
 | 
					    public string CSVETA {
 | 
				
			||||||
 | 
					        set {
 | 
				
			||||||
 | 
					            if (   value.Length >= 2
 | 
				
			||||||
 | 
					                && int.TryParse(value[..^1], out int result))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ETA = result;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                ETA = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Index(14)]
 | 
				
			||||||
    public int Warp { get; set; }
 | 
					    public int Warp { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(5)]
 | 
					    [Index(15)]
 | 
				
			||||||
    public int Mass { get; set; }
 | 
					    public int Mass { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(6)]
 | 
					    [Index(16)]
 | 
				
			||||||
    public int Cloak { get; set; }
 | 
					    public int Cloak { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(7)]
 | 
					    [Index(17)]
 | 
				
			||||||
    public int Scan { get; set; }
 | 
					    public int Scan { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(8)]
 | 
					    [Index(18)]
 | 
				
			||||||
    public int PenScan { get; set; }
 | 
					    public int PenScan { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(9)]
 | 
					    [Index(19)]
 | 
				
			||||||
    public string Task { get; set; } = String.Empty;
 | 
					    public string Task { get; set; } = String.Empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(0)]
 | 
					    [Index(20)]
 | 
				
			||||||
    public int Mining { get; set; }
 | 
					    public int Mining { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(1)]
 | 
					    [Index(21)]
 | 
				
			||||||
    public int Sweep { get; set; }
 | 
					    public int Sweep { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(2)]
 | 
					    [Index(22)]
 | 
				
			||||||
    public int Laying { get; set; }
 | 
					    public int Laying { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(3)]
 | 
					    [Index(23)]
 | 
				
			||||||
    public int Terraforming { get; set; }
 | 
					    public int Terraforming { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(4)]
 | 
					    [Index(24)]
 | 
				
			||||||
    public int Unarmed { get; set; }
 | 
					    public int Unarmed { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(5)]
 | 
					    [Index(25)]
 | 
				
			||||||
    public int Scout { get; set; }
 | 
					    public int Scout { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(6)]
 | 
					    [Index(26)]
 | 
				
			||||||
    public int Warship { get; set; }
 | 
					    public int Warship { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(7)]
 | 
					    [Index(27)]
 | 
				
			||||||
    public int Utility { get; set; }
 | 
					    public int Utility { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Index(8)]
 | 
					    [Index(28)]
 | 
				
			||||||
    public int Bomber { get; set; }
 | 
					    public int Bomber { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// This will update a DB Fleet recrod with this CSV Data. DB/EF Handling
 | 
				
			||||||
 | 
					    /// has to be done by the caller, we'll take care of none PK properties
 | 
				
			||||||
 | 
					    /// only.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="dbFleet">record to fill</param>
 | 
				
			||||||
 | 
					    public void UpdateDbFleet(Model.Fleet dbFleet) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (dbFleet == null)
 | 
				
			||||||
 | 
					            throw new InvalidOperationException("Cannot update a null DB fleet instance");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dbFleet.FleetName = FleetName;
 | 
				
			||||||
 | 
					        dbFleet.X = X;
 | 
				
			||||||
 | 
					        dbFleet.Y = Y;
 | 
				
			||||||
 | 
					        dbFleet.Planet = Planet;
 | 
				
			||||||
 | 
					        dbFleet.Destination = Destination;
 | 
				
			||||||
 | 
					        dbFleet.BattlePlan = BattlePlan;
 | 
				
			||||||
 | 
					        dbFleet.ShipCount = ShipCount;
 | 
				
			||||||
 | 
					        dbFleet.Ironium = Ironium;
 | 
				
			||||||
 | 
					        dbFleet.Boranium = Boranium;
 | 
				
			||||||
 | 
					        dbFleet.Germanium = Germanium;
 | 
				
			||||||
 | 
					        dbFleet.Colonists = Colonists;
 | 
				
			||||||
 | 
					        dbFleet.Fuel = Fuel;
 | 
				
			||||||
 | 
					        dbFleet.OwnerFileId = OwnerFileId;
 | 
				
			||||||
 | 
					        dbFleet.ETA = ETA;
 | 
				
			||||||
 | 
					        dbFleet.Warp = Warp;
 | 
				
			||||||
 | 
					        dbFleet.Mass = Mass;
 | 
				
			||||||
 | 
					        dbFleet.Cloak = Cloak;
 | 
				
			||||||
 | 
					        dbFleet.Scan = Scan;
 | 
				
			||||||
 | 
					        dbFleet.PenScan = PenScan;
 | 
				
			||||||
 | 
					        dbFleet.Task = Task;
 | 
				
			||||||
 | 
					        dbFleet.Mining = Mining;
 | 
				
			||||||
 | 
					        dbFleet.Sweep = Sweep;
 | 
				
			||||||
 | 
					        dbFleet.Laying = Laying;
 | 
				
			||||||
 | 
					        dbFleet.Terraforming = Terraforming;
 | 
				
			||||||
 | 
					        dbFleet.Unarmed = Unarmed;
 | 
				
			||||||
 | 
					        dbFleet.Scout = Scout;
 | 
				
			||||||
 | 
					        dbFleet.Warship = Warship;
 | 
				
			||||||
 | 
					        dbFleet.Utility = Utility;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										77
									
								
								Stars Assistant/CSV/FleetLoader.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								Stars Assistant/CSV/FleetLoader.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Diagnostics.CodeAnalysis;
 | 
				
			||||||
 | 
					using CsvHelper.Configuration;
 | 
				
			||||||
 | 
					using CsvHelper;
 | 
				
			||||||
 | 
					using System.Globalization;
 | 
				
			||||||
 | 
					using Splat;
 | 
				
			||||||
 | 
					using StarsAssistant.Services;
 | 
				
			||||||
 | 
					using Avalonia.Animation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace StarsAssistant.CSV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class FleetLoader
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Reference to the game metadata, retrieved by DI
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    protected Services.Game Game = Locator.Current.GetService<Services.Game>()!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// CSV Configuration to use for importing Planet files.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    protected CsvConfiguration CsvConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Construction
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public FleetLoader()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CreateConfig();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Creates the CSV configuration for planets.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    [MemberNotNull(nameof(CsvConfig))]
 | 
				
			||||||
 | 
					    protected void CreateConfig() 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CsvConfig = CsvConfiguration.FromAttributes<Fleet>(CultureInfo.InvariantCulture);
 | 
				
			||||||
 | 
					        CsvConfig.Delimiter = "\t";
 | 
				
			||||||
 | 
					        CsvConfig.Escape = '\0';
 | 
				
			||||||
 | 
					        CsvConfig.MissingFieldFound = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Import the fleet file for the given Race, all other records will be ignored.
 | 
				
			||||||
 | 
					    /// Since we can't update existing records, we will delete all applicable ones
 | 
				
			||||||
 | 
					    /// before inserting new Fleets.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="race">Import File</param>
 | 
				
			||||||
 | 
					    public void ImportForRace(Model.Race race)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var db = Locator.Current.GetService<Model.StarsDatabase>()!;
 | 
				
			||||||
 | 
					        using var reader = new StreamReader(Game.FleetFileForRace(race), System.Text.Encoding.Latin1);
 | 
				
			||||||
 | 
					        using var csv = new CsvReader(reader, CsvConfig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var oldFleetsToDelete = from flt in db.Fleet
 | 
				
			||||||
 | 
					            where flt.OwnerFileId == race.PlayerFileId
 | 
				
			||||||
 | 
					            select flt;
 | 
				
			||||||
 | 
					        db.RemoveRange(oldFleetsToDelete);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<CSV.Fleet> records = csv.GetRecords<Fleet>().ToList();
 | 
				
			||||||
 | 
					        var fleetsForPlayer = from flt in records
 | 
				
			||||||
 | 
					            where flt.OwnerFileId == race.PlayerFileId
 | 
				
			||||||
 | 
					            select flt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var csvFleet in fleetsForPlayer)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Model.Fleet dbFleet = new();
 | 
				
			||||||
 | 
					            csvFleet.UpdateDbFleet(dbFleet);
 | 
				
			||||||
 | 
					            dbFleet.OwnerId = race.Name;
 | 
				
			||||||
 | 
					            db.Add(dbFleet);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        db.SaveChanges();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -215,7 +215,7 @@ public class Planet
 | 
				
			|||||||
    public int? DriverWarp { get; set; }
 | 
					    public int? DriverWarp { get; set; }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    [Index(32)]
 | 
					    [Index(32)]
 | 
				
			||||||
    public string? RouteTarget { get; set; }
 | 
					    public string RouteTarget { get; set; } = String.Empty;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    [Index(33)]
 | 
					    [Index(33)]
 | 
				
			||||||
    public int? GateRange { get; set; }
 | 
					    public int? GateRange { get; set; }
 | 
				
			||||||
@@ -231,7 +231,7 @@ public class Planet
 | 
				
			|||||||
    /// must already be set, DB/EF Handling has to be done by the caller, we'll take
 | 
					    /// must already be set, DB/EF Handling has to be done by the caller, we'll take
 | 
				
			||||||
    /// care of none PK properties only.
 | 
					    /// care of none PK properties only.
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    /// <param name="dbPlanet"></param>
 | 
					    /// <param name="dbPlanet">record to fill</param>
 | 
				
			||||||
    public void UpdateDbPlanet(Model.Planet dbPlanet)
 | 
					    public void UpdateDbPlanet(Model.Planet dbPlanet)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (dbPlanet == null)
 | 
					        if (dbPlanet == null)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,15 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations;
 | 
					using System.ComponentModel.DataAnnotations;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace StarsAssistant.Model;
 | 
					namespace StarsAssistant.Model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Fleet
 | 
					public class Fleet
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    [Key]
 | 
				
			||||||
 | 
					    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
 | 
				
			||||||
 | 
					    public int Id { get; set; }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
    #region Persistant propeties (from Stars)
 | 
					    #region Persistant propeties (from Stars)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public string FleetName { get; set; } = String.Empty;
 | 
					    public string FleetName { get; set; } = String.Empty;
 | 
				
			||||||
@@ -31,7 +36,9 @@ public class Fleet
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public int Fuel { get; set; }
 | 
					    public int Fuel { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public int OwnerPlayerNumber { get; set; }
 | 
					    public string OwnerId { get; set; } = String.Empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public int OwnerFileId { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public int ETA { get; set; }
 | 
					    public int ETA { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,4 +73,10 @@ public class Fleet
 | 
				
			|||||||
    public int Bomber { get; set; }
 | 
					    public int Bomber { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #endregion
 | 
					    #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #region Relationships
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Race? Owner { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #endregion
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,9 @@ public class Race
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #region Relationships
 | 
					    #region Relationships
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ICollection<Planet> Planets { get; } = new List<Planet>();
 | 
					    public ICollection<Planet> Planets { get; set; } = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ICollection<Fleet> Fleets { get; set; } = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #endregion
 | 
					    #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,15 +29,18 @@ public class StarsDatabase(string DbPath) : DbContext
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #endregion
 | 
					    #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #region IStarsDatabase Implementation
 | 
					    #region DbSets
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public DbContext DbContext => this;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// List of all Planets read.
 | 
					    /// List of all Planets read.
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public DbSet<Planet> Planet { get; set; }
 | 
					    public DbSet<Planet> Planet { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// List of all Fleets read.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<Fleet> Fleet { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Lists of all defined races.
 | 
					    /// Lists of all defined races.
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,6 +89,13 @@ public class Game
 | 
				
			|||||||
    /// <returns>Fully qualified file path.</returns>
 | 
					    /// <returns>Fully qualified file path.</returns>
 | 
				
			||||||
    public string PlanetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.p{r.PlayerFileId}");
 | 
					    public string PlanetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.p{r.PlayerFileId}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Get the name of a planet file for a given race.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="r">The race to load.</param>
 | 
				
			||||||
 | 
					    /// <returns>Fully qualified file path.</returns>
 | 
				
			||||||
 | 
					    public string FleetFileForRace (Race r) => Path.Combine(GamePath, $"{BaseName}.f{r.PlayerFileId}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Save this record in the database. Uses the service locator to access the 
 | 
					    /// Save this record in the database. Uses the service locator to access the 
 | 
				
			||||||
    /// database unless you specify an instance. This is needed during initial
 | 
					    /// database unless you specify an instance. This is needed during initial
 | 
				
			||||||
@@ -176,8 +183,12 @@ public class Game
 | 
				
			|||||||
        db.Add(r);
 | 
					        db.Add(r);
 | 
				
			||||||
        db.SaveChanges();
 | 
					        db.SaveChanges();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var loader = new CSV.PlanetLoader();
 | 
					        var planetLoader = new CSV.PlanetLoader();
 | 
				
			||||||
        loader.ImportForRace(Services.Game.Player);
 | 
					        planetLoader.ImportForRace(Services.Game.Player);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        var fleetLoader = new CSV.FleetLoader();
 | 
				
			||||||
 | 
					        fleetLoader.ImportForRace(Services.Game.Player);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user