Skip to content

Commit

Permalink
WIP: Remove JSON data and move to plain old DB columns
Browse files Browse the repository at this point in the history
First piece of implementation, migration is missing

Refs #16
  • Loading branch information
mormegil-cz committed Aug 30, 2024
1 parent 69db90e commit 3a1aab6
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 150 deletions.
5 changes: 3 additions & 2 deletions KdyPojedeVlak.Web/Controllers/TrainController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion KdyPojedeVlak.Web/Controllers/TransitsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
108 changes: 21 additions & 87 deletions KdyPojedeVlak.Web/Engine/DbStorage/DbModelContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string> Data { get; set; }

// TODO: Point attributes
[NotMapped]
public PointType Type => Program.PointCodebook.Find(Code)?.Type ?? PointType.Unknown;
Expand All @@ -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; }
Expand All @@ -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<string, string> data;

public int Id { get; set; }

[Required]
Expand All @@ -288,40 +276,20 @@ public class TrainTimetable
[MaxLength(100)]
public string Name { get; set; }

public string DataJson { get; set; }

[InverseProperty("Timetable")]
public virtual List<TrainTimetableVariant> Variants { get; set; }

[NotMapped]
public Dictionary<string, string> 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; }
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<string, string> Data
{
get
{
if (data != null) return data;
data = LoadDataJson(DataJson);
return data;
}
set
{
data = value;
DataJson = StoreDataJson(value);
}
}

private Dictionary<string, string> data;

[NotMapped]
public bool IsMajorPoint => ArrivalTime != null || DwellTime != null;

Expand All @@ -437,17 +380,17 @@ public Dictionary<string, string> Data
: (DisplayConsts.SubsidiaryLocationTypeNames[SubsidiaryLocationType] + " " + SubsidiaryLocation + " " +
SubsidiaryLocationName).Trim();

[NotMapped]
public List<TrainOperation> TrainOperations => GetAttributeEnumList<TrainOperation>(Data, AttribTrainOperations);
[Column("TrainOperations")]
public string TrainOperationsStr { get; set; }

[NotMapped]
public string SubsidiaryLocation => GetAttribute(Data, AttribSubsidiaryLocation, null);
public List<TrainOperation> TrainOperations => ParseEnumList<TrainOperation>(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)
{
Expand Down Expand Up @@ -563,20 +506,11 @@ public class TrainCancellation

public static class DbModelUtils
{
public static Dictionary<string, string> LoadDataJson(string json) => JsonConvert.DeserializeObject<Dictionary<string, string>>(json ?? "{}");

public static string StoreDataJson(Dictionary<string, string> json) => JsonConvert.SerializeObject(json);

public static string GetAttribute(Dictionary<string, string> data, string key, string defaultValue) => data.TryGetValue(key, out var result) ? result : defaultValue;

public static TEnum GetAttributeEnum<TEnum>(Dictionary<string, string> data, string key, TEnum defaultValue)
public static List<TEnum> ParseEnumList<TEnum>(string data)
where TEnum : struct =>
Enum.TryParse<TEnum>(GetAttribute(data, key, null), out var result) ? result : defaultValue;

public static List<TEnum> GetAttributeEnumList<TEnum>(Dictionary<string, string> data, string key)
where TEnum : struct =>
GetAttribute(data, key, "")
.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(Enum.Parse<TEnum>)
.ToList();
data == null
? []
: data.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(Enum.Parse<TEnum>)
.ToList();
}
53 changes: 20 additions & 33 deletions KdyPojedeVlak.Web/Engine/Djr/DjrSchedule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -337,13 +337,9 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream)
Train = train,
TimetableYear = dbTimetableYear,
Name = trainName,
Data = new Dictionary<string, string>
{
{ TrainTimetable.AttribTrafficType, trafficTypes.FirstOrDefault().ToString() },
{ TrainTimetable.AttribTrainCategory, trainCategories.FirstOrDefault().ToString() },
// { TrainTimetable.AttribTrainType, train.TrainType.ToString() },
},
Variants = new List<TrainTimetableVariant>()
TrafficType = trafficTypes.FirstOrDefault(),
TrainCategory = trainCategories.FirstOrDefault(),
Variants = []
};
dbModelContext.TrainTimetables.Add(trainTimetable);
}
Expand Down Expand Up @@ -393,10 +389,7 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream)
Name = codebookEntry.LongName,
Latitude = codebookEntry.Latitude,
Longitude = codebookEntry.Longitude,
Data = new Dictionary<string, string>
{
// TODO: Routing point data
}
// TODO: Routing point data
};
dbModelContext.RoutingPoints.Add(dbPoint);
dbModelContext.SaveChanges();
Expand Down Expand Up @@ -466,27 +459,21 @@ private static CZPTTCISMessageBase LoadXmlFile(Stream stream)
DepartureDay = departureTiming?.Offset ?? 0,
DepartureTime = departureTiming?.AsTimeSpan(),
DwellTime = locationFull?.TimingAtLocation?.DwellTime,
Data = new Dictionary<string, string?>
{
// 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<Passage>(1) { passage };
if (passages.Count == 0) passages["_FIRST"] = [passage];

if (!passages.TryGetValue(locationRawID, out var passageListPerID)) passageListPerID = new List<Passage>(2);
passageListPerID.Add(passage);
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -912,7 +899,7 @@ public enum TrafficType
Lv,
Vleč,
Služ,
Pom
Pom,
}

public enum TrainCategory
Expand Down
32 changes: 8 additions & 24 deletions KdyPojedeVlak.Web/Models/BasicTrainInfo.cs
Original file line number Diff line number Diff line change
@@ -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<string, string> 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;
}
4 changes: 1 addition & 3 deletions KdyPojedeVlak.Web/Models/NearestTransits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

0 comments on commit 3a1aab6

Please sign in to comment.