From 3a1aab6da9702d0b5a6283576936af9c9b1d7e0a Mon Sep 17 00:00:00 2001 From: mormegil Date: Fri, 30 Aug 2024 20:01:06 +0200 Subject: [PATCH] WIP: Remove JSON data and move to plain old DB columns First piece of implementation, migration is missing Refs #16 --- .../Controllers/TrainController.cs | 5 +- .../Controllers/TransitsController.cs | 2 +- .../Engine/DbStorage/DbModelContext.cs | 108 ++++-------------- KdyPojedeVlak.Web/Engine/Djr/DjrSchedule.cs | 53 ++++----- KdyPojedeVlak.Web/Models/BasicTrainInfo.cs | 32 ++---- KdyPojedeVlak.Web/Models/NearestTransits.cs | 4 +- 6 files changed, 54 insertions(+), 150 deletions(-) diff --git a/KdyPojedeVlak.Web/Controllers/TrainController.cs b/KdyPojedeVlak.Web/Controllers/TrainController.cs index a14b11f..3b7e2de 100644 --- a/KdyPojedeVlak.Web/Controllers/TrainController.cs +++ b/KdyPojedeVlak.Web/Controllers/TrainController.cs @@ -108,9 +108,10 @@ public IActionResult Newest() ttv.Calendar.TimetableYearYear, ttv.Timetable.Train.Number, ttv.Timetable.Name, - ttv.Timetable.DataJson, ttv.Points.OrderBy(np => np.Order).Select(np => np.Point.Name).FirstOrDefault(), - ttv.Points.OrderByDescending(np => np.Order).Select(np => np.Point.Name).FirstOrDefault() + ttv.Points.OrderByDescending(np => np.Order).Select(np => np.Point.Name).FirstOrDefault(), + ttv.Timetable.TrainCategory, + ttv.Timetable.TrafficType ) ) .Take(limit) diff --git a/KdyPojedeVlak.Web/Controllers/TransitsController.cs b/KdyPojedeVlak.Web/Controllers/TransitsController.cs index 7227a63..8ff9cf6 100644 --- a/KdyPojedeVlak.Web/Controllers/TransitsController.cs +++ b/KdyPojedeVlak.Web/Controllers/TransitsController.cs @@ -106,7 +106,7 @@ public IActionResult Nearest(string id, DateTime? at) p.TrainTimetableVariant.Calendar, p.ArrivalTime, p.DepartureTime, - p.TrainTimetableVariant.Timetable.DataJson, + p.TrainTimetableVariant.Timetable.TrainCategory, p.TrainTimetableVariant.Timetable.Train.Number, p.TrainTimetableVariant.Timetable.Name, p.SubsidiaryLocationDescription, diff --git a/KdyPojedeVlak.Web/Engine/DbStorage/DbModelContext.cs b/KdyPojedeVlak.Web/Engine/DbStorage/DbModelContext.cs index 07e768a..94daf20 100644 --- a/KdyPojedeVlak.Web/Engine/DbStorage/DbModelContext.cs +++ b/KdyPojedeVlak.Web/Engine/DbStorage/DbModelContext.cs @@ -223,12 +223,6 @@ public class RoutingPoint public float? Latitude { get; set; } public float? Longitude { get; set; } - public string DataJson { get; set; } - - [NotMapped] - // TODO: Decode data JSON - public Dictionary Data { get; set; } - // TODO: Point attributes [NotMapped] public PointType Type => Program.PointCodebook.Find(Code)?.Type ?? PointType.Unknown; @@ -250,8 +244,8 @@ public class RoutingPoint } /** - * Label of a train, common for all timetable years - */ + * Label of a train, common for all timetable years + */ public class Train { public int Id { get; set; } @@ -261,16 +255,10 @@ public class Train } /** - * Train in a single timetable year - */ + * Train in a single timetable year + */ public class TrainTimetable { - public static readonly string AttribTrafficType = "TrafficType"; - public static readonly string AttribTrainCategory = "TrainCategory"; - public static readonly string AttribTrainType = "TrainType"; - - private Dictionary data; - public int Id { get; set; } [Required] @@ -288,40 +276,20 @@ public class TrainTimetable [MaxLength(100)] public string Name { get; set; } - public string DataJson { get; set; } - [InverseProperty("Timetable")] public virtual List Variants { get; set; } - [NotMapped] - public Dictionary Data - { - get - { - if (data != null) return data; - data = LoadDataJson(DataJson); - return data; - } - set - { - data = value; - DataJson = StoreDataJson(value); - } - } - [NotMapped] public string TrainNumber => Train?.Number; - [NotMapped] - public TrainCategory TrainCategory => GetAttributeEnum(Data, AttribTrainCategory, TrainCategory.Unknown); + public TrainCategory TrainCategory { get; set; } - [NotMapped] - public TrafficType TrafficType => GetAttributeEnum(Data, AttribTrafficType, TrafficType.Unknown); + public TrafficType TrafficType { get; set; } } /** - * Variant of a train in the respective timetable year - */ + * Variant of a train in the respective timetable year + */ public class TrainTimetableVariant { public int Id { get; set; } @@ -359,11 +327,6 @@ public class TrainTimetableVariant public class Passage { - public static readonly string AttribTrainOperations = "TrainOperations"; - public static readonly string AttribSubsidiaryLocation = "SubsidiaryLocation"; - public static readonly string AttribSubsidiaryLocationName = "SubsidiaryLocationName"; - public static readonly string AttribSubsidiaryLocationType = "SubsidiaryLocationType"; - public int Id { get; set; } // note that this is denormalized: TrainId implies YearId, but it would be difficult to normalize it @@ -395,26 +358,6 @@ public class Passage public int ArrivalDay { get; set; } public int DepartureDay { get; set; } - public string DataJson { get; set; } - - [NotMapped] - public Dictionary Data - { - get - { - if (data != null) return data; - data = LoadDataJson(DataJson); - return data; - } - set - { - data = value; - DataJson = StoreDataJson(value); - } - } - - private Dictionary data; - [NotMapped] public bool IsMajorPoint => ArrivalTime != null || DwellTime != null; @@ -437,17 +380,17 @@ public Dictionary Data : (DisplayConsts.SubsidiaryLocationTypeNames[SubsidiaryLocationType] + " " + SubsidiaryLocation + " " + SubsidiaryLocationName).Trim(); - [NotMapped] - public List TrainOperations => GetAttributeEnumList(Data, AttribTrainOperations); + [Column("TrainOperations")] + public string TrainOperationsStr { get; set; } [NotMapped] - public string SubsidiaryLocation => GetAttribute(Data, AttribSubsidiaryLocation, null); + public List TrainOperations => ParseEnumList(TrainOperationsStr); - [NotMapped] - public string SubsidiaryLocationName => GetAttribute(Data, AttribSubsidiaryLocationName, null); + public string SubsidiaryLocation { get; set; } - [NotMapped] - public SubsidiaryLocationType SubsidiaryLocationType => GetAttributeEnum(Data, AttribSubsidiaryLocationType, SubsidiaryLocationType.None); + public string SubsidiaryLocationName { get; set; } + + public SubsidiaryLocationType SubsidiaryLocationType { get; set; } private TimeSpan? TimeOfDayOfTimeSpan(TimeSpan? timeSpan) { @@ -563,20 +506,11 @@ public class TrainCancellation public static class DbModelUtils { - public static Dictionary LoadDataJson(string json) => JsonConvert.DeserializeObject>(json ?? "{}"); - - public static string StoreDataJson(Dictionary json) => JsonConvert.SerializeObject(json); - - public static string GetAttribute(Dictionary data, string key, string defaultValue) => data.TryGetValue(key, out var result) ? result : defaultValue; - - public static TEnum GetAttributeEnum(Dictionary data, string key, TEnum defaultValue) + public static List ParseEnumList(string data) where TEnum : struct => - Enum.TryParse(GetAttribute(data, key, null), out var result) ? result : defaultValue; - - public static List GetAttributeEnumList(Dictionary data, string key) - where TEnum : struct => - GetAttribute(data, key, "") - .Split(';', StringSplitOptions.RemoveEmptyEntries) - .Select(Enum.Parse) - .ToList(); + data == null + ? [] + : data.Split(';', StringSplitOptions.RemoveEmptyEntries) + .Select(Enum.Parse) + .ToList(); } \ No newline at end of file diff --git a/KdyPojedeVlak.Web/Engine/Djr/DjrSchedule.cs b/KdyPojedeVlak.Web/Engine/Djr/DjrSchedule.cs index 0b6d7d0..461bf0a 100644 --- a/KdyPojedeVlak.Web/Engine/Djr/DjrSchedule.cs +++ b/KdyPojedeVlak.Web/Engine/Djr/DjrSchedule.cs @@ -50,8 +50,8 @@ public static void RecomputeYearLimits(DbModelContext dbModelContext) { foreach (var year in dbModelContext.TimetableYears) { - var minDate = dbModelContext.CalendarDefinitions.Where(c => c.TimetableYear == year).Min(c => (DateTime?)c.StartDate); - var maxDate = dbModelContext.CalendarDefinitions.Where(c => c.TimetableYear == year).Max(c => (DateTime?)c.EndDate); + var minDate = dbModelContext.CalendarDefinitions.Where(c => c.TimetableYear == year).Min(c => (DateTime?) c.StartDate); + var maxDate = dbModelContext.CalendarDefinitions.Where(c => c.TimetableYear == year).Max(c => (DateTime?) c.EndDate); if (minDate != null && year.MinDate > minDate) { @@ -260,7 +260,7 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream) _ => throw new FormatException($"Unsupported XML element: ${xmlReader.LocalName}") }; - return (CZPTTCISMessageBase)ser.Deserialize(xmlReader)!; + return (CZPTTCISMessageBase) ser.Deserialize(xmlReader)!; } private static string? ImportTrainToDatabase(CZPTTCISMessage message, ImportedFile importedFile, DbModelContext dbModelContext) @@ -337,13 +337,9 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream) Train = train, TimetableYear = dbTimetableYear, Name = trainName, - Data = new Dictionary - { - { TrainTimetable.AttribTrafficType, trafficTypes.FirstOrDefault().ToString() }, - { TrainTimetable.AttribTrainCategory, trainCategories.FirstOrDefault().ToString() }, - // { TrainTimetable.AttribTrainType, train.TrainType.ToString() }, - }, - Variants = new List() + TrafficType = trafficTypes.FirstOrDefault(), + TrainCategory = trainCategories.FirstOrDefault(), + Variants = [] }; dbModelContext.TrainTimetables.Add(trainTimetable); } @@ -393,10 +389,7 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream) Name = codebookEntry.LongName, Latitude = codebookEntry.Latitude, Longitude = codebookEntry.Longitude, - Data = new Dictionary - { - // TODO: Routing point data - } + // TODO: Routing point data }; dbModelContext.RoutingPoints.Add(dbPoint); dbModelContext.SaveChanges(); @@ -466,27 +459,21 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream) DepartureDay = departureTiming?.Offset ?? 0, DepartureTime = departureTiming?.AsTimeSpan(), DwellTime = locationFull?.TimingAtLocation?.DwellTime, - Data = new Dictionary - { - // TODO: JourneyLocationTypeCode - { Passage.AttribTrainOperations, String.Join(';', trainOperations) }, - { Passage.AttribSubsidiaryLocation, locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryCode?.Code }, - { Passage.AttribSubsidiaryLocationName, locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryName }, - { - Passage.AttribSubsidiaryLocationType, - (locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryCode - ?.LocationSubsidiaryTypeCode == null - ? SubsidiaryLocationType.None - : defSubsidiaryLocationType[ - locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryCode - ?.LocationSubsidiaryTypeCode ?? "0"]).ToString() - }, - }, + TrainOperationsStr = String.Join(';', trainOperations), + SubsidiaryLocation = locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryCode?.Code, + SubsidiaryLocationName = locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryName, + SubsidiaryLocationType = locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryCode + ?.LocationSubsidiaryTypeCode == null + ? SubsidiaryLocationType.None + : defSubsidiaryLocationType[ + locationFull?.LocationSubsidiaryIdentification?.LocationSubsidiaryCode + ?.LocationSubsidiaryTypeCode ?? "0"] + // TODO: JourneyLocationTypeCode }; trainTimetableVariant.Points.Add(passage); dbModelContext.Add(passage); - if (passages.Count == 0) passages["_FIRST"] = new List(1) { passage }; + if (passages.Count == 0) passages["_FIRST"] = [passage]; if (!passages.TryGetValue(locationRawID, out var passageListPerID)) passageListPerID = new List(2); passageListPerID.Add(passage); @@ -581,7 +568,7 @@ private static void LinkCancellations(DbModelContext dbModelContext) .Where(ttv => ttv.YearId == cancellation.Calendar.TimetableYearYear && ttv.TrainVariantId == cancellation.TrainVariantId && ttv.PathVariantId == cancellation.PathVariantId) - .Select(ttv => (int?)ttv.Id) + .Select(ttv => (int?) ttv.Id) .SingleOrDefault(); if (trainTimetableVariantId == null) { @@ -912,7 +899,7 @@ public enum TrafficType Lv, Vleč, Služ, - Pom + Pom, } public enum TrainCategory diff --git a/KdyPojedeVlak.Web/Models/BasicTrainInfo.cs b/KdyPojedeVlak.Web/Models/BasicTrainInfo.cs index 692086b..ad41821 100644 --- a/KdyPojedeVlak.Web/Models/BasicTrainInfo.cs +++ b/KdyPojedeVlak.Web/Models/BasicTrainInfo.cs @@ -1,30 +1,14 @@ -using System.Collections.Generic; -using KdyPojedeVlak.Web.Engine.DbStorage; using KdyPojedeVlak.Web.Engine.Djr; namespace KdyPojedeVlak.Web.Models; -public class BasicTrainInfo +public class BasicTrainInfo(int timetableYear, string number, string name, string firstPointName, string lastPointName, TrainCategory trainCategory, TrafficType trafficType) { - private readonly Dictionary data; - - public BasicTrainInfo(int timetableYear, string number, string name, string dataJson, string firstPointName, string lastPointName) - { - this.TimetableYear = timetableYear; - this.Number = number; - this.Name = name; - this.FirstPointName = firstPointName; - this.LastPointName = lastPointName; - this.data = DbModelUtils.LoadDataJson(dataJson); - } - - public TrainCategory TrainCategory => DbModelUtils.GetAttributeEnum(data, TrainTimetable.AttribTrainCategory, TrainCategory.Unknown); - - public TrafficType TrafficType => DbModelUtils.GetAttributeEnum(data, TrainTimetable.AttribTrafficType, TrafficType.Unknown); - - public int TimetableYear { get; init; } - public string Number { get; init; } - public string Name { get; init; } - public string FirstPointName { get; init; } - public string LastPointName { get; init; } + public int TimetableYear { get; } = timetableYear; + public string Number { get; } = number; + public string Name { get; } = name; + public string FirstPointName { get; } = firstPointName; + public string LastPointName { get; } = lastPointName; + public TrainCategory TrainCategory { get; } = trainCategory; + public TrafficType TrafficType { get; } = trafficType; } \ No newline at end of file diff --git a/KdyPojedeVlak.Web/Models/NearestTransits.cs b/KdyPojedeVlak.Web/Models/NearestTransits.cs index ca09fce..5be4fd9 100644 --- a/KdyPojedeVlak.Web/Models/NearestTransits.cs +++ b/KdyPojedeVlak.Web/Models/NearestTransits.cs @@ -29,13 +29,11 @@ public NearestTransits(RoutingPoint point, DateTime startDate, int currentTimeta NearestPoints = nearestPoints == null || nearestPoints.Count == 0 ? null : nearestPoints; } - public record Transit(int TimetableYear, CalendarDefinition Calendar, TimeSpan? ArrivalTime, TimeSpan? DepartureTime, string DataJson, string? TrainNumber, string? TrainName, string? SubsidiaryLocationDescription, string? PreviousPointName, string? NextPointName) + public record Transit(int TimetableYear, CalendarDefinition Calendar, TimeSpan? ArrivalTime, TimeSpan? DepartureTime, TrainCategory TrainCategory, string? TrainNumber, string? TrainName, string? SubsidiaryLocationDescription, string? PreviousPointName, string? NextPointName) { public TimeSpan? AnyScheduledTime => ArrivalTime ?? DepartureTime; public TimeSpan? AnyScheduledTimeOfDay => AnyScheduledTime?.GetTimeOfDay(); - - public TrainCategory TrainCategory => DbModelUtils.GetAttributeEnum(DbModelUtils.LoadDataJson(DataJson), TrainTimetable.AttribTrainCategory, TrainCategory.Unknown); } } } \ No newline at end of file