From d65ce8288bbda3cb6e0b37613c29d7bf52703ba7 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Fri, 12 Dec 2025 08:56:32 +0100 Subject: Some rework on the ServiceViewer (which will be repurposed for live multi-GTFS serving) --- .../AppDbContextDesignTimeFactory.cs | 4 +- .../Controllers/ServicesController.cs | 28 +- .../Costasdev.Busurbano.ServiceViewer.csproj | 58 ++- .../Data/AppDbContext.cs | 45 +- .../Data/Extensions/TimeExtensions.cs | 20 + .../Data/Gtfs/Feed.cs | 21 + .../Data/Gtfs/GtfsAgency.cs | 7 +- .../Data/Gtfs/GtfsCalendar.cs | 7 +- .../Data/Gtfs/GtfsCalendarDate.cs | 7 +- .../Data/Gtfs/GtfsRoute.cs | 12 +- .../Data/Gtfs/GtfsStop.cs | 16 +- .../Data/Gtfs/GtfsStopTime.cs | 16 +- .../Data/Gtfs/GtfsTrip.cs | 25 +- .../20250821135143_InitialGtfsData.Designer.cs | 398 --------------- .../Migrations/20250821135143_InitialGtfsData.cs | 215 -------- .../Migrations/20251211153852_Initial.Designer.cs | 547 +++++++++++++++++++++ .../Data/Migrations/20251211153852_Initial.cs | 318 ++++++++++++ .../Data/Migrations/AppDbContextModelSnapshot.cs | 365 ++++++++++---- src/Costasdev.Busurbano.ServiceViewer/Program.cs | 5 +- 19 files changed, 1319 insertions(+), 795 deletions(-) create mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs create mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.Designer.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.cs create mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs create mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs (limited to 'src/Costasdev.Busurbano.ServiceViewer') diff --git a/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs b/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs index 4caaabc..919c131 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs @@ -31,9 +31,9 @@ public class AppDbContextDesignTimeFactory : IDesignTimeDbContextFactory options.MigrationsAssembly(typeof(AppDbContext).Assembly.FullName) + options => options.UseNetTopologySuite() ); return new AppDbContext(builder.Options); diff --git a/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs b/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs index 64f1084..bfb2a99 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs @@ -101,7 +101,7 @@ public class ServicesController : Controller .Select(t => new { Trip = t, - Sequence = int.TryParse(t.TripId.Split('_').LastOrDefault(), out var seq) ? seq : int.MaxValue + Sequence = int.TryParse(t.Id.Split('_').LastOrDefault(), out var seq) ? seq : int.MaxValue }) .OrderBy(t => t.Sequence) .ThenBy(t => t.Trip.TripHeadsign) // Secondary sort to ensure consistent ordering @@ -113,8 +113,8 @@ public class ServicesController : Controller continue; } - tripsWhoseFirstStopWeWant.Add(orderedTrips.First().TripId); - tripsWhoseLastStopWeWant.Add(orderedTrips.Last().TripId); + tripsWhoseFirstStopWeWant.Add(orderedTrips.First().Id); + tripsWhoseLastStopWeWant.Add(orderedTrips.Last().Id); serviceInformations.Add(new ServiceInformation( service, GetNameForServiceId(service), @@ -130,7 +130,7 @@ public class ServicesController : Controller .OrderBy(st => st.StopSequence) .GroupBy(st => st.TripId) .Select(g => g.First()) - .ToDictionary(st => st.TripId, st => st.DepartureTime); + .ToDictionary(st => st.TripId, st => st.Departure); var lastStopTimePerTrip = _db.StopTimes .AsSplitQuery().AsNoTracking() @@ -138,7 +138,7 @@ public class ServicesController : Controller .OrderByDescending(st => st.StopSequence) .GroupBy(st => st.TripId) .Select(g => g.First()) - .ToDictionary(st => st.TripId, st => st.ArrivalTime); + .ToDictionary(st => st.TripId, st => st.Arrival); // 4. Create a view model List serviceCards = []; @@ -147,7 +147,7 @@ public class ServicesController : Controller // For lines 16-24 switching during the day we want (16, 2), (24,2), (16,1), (24,2)... in sequence // TODO: Fix getting the trip sequence for any operator var tripsOrdered = serviceInfo.Trips - .OrderBy(t => int.Parse(t.TripId.Split('_').LastOrDefault() ?? string.Empty)) + .OrderBy(t => int.Parse(t.Id.Split('_').LastOrDefault() ?? string.Empty)) .ToList(); List tripGroups = []; @@ -174,10 +174,10 @@ public class ServicesController : Controller serviceInfo.ServiceName, serviceInfo.Trips, tripGroups, - firstStopTimePerTrip.TryGetValue(serviceInfo.FirstTrip.TripId, out var shiftStart) + firstStopTimePerTrip.TryGetValue(serviceInfo.FirstTrip.Id, out var shiftStart) ? shiftStart : string.Empty, - lastStopTimePerTrip.TryGetValue(serviceInfo.LastTrip.TripId, out var shiftEnd) ? shiftEnd : string.Empty + lastStopTimePerTrip.TryGetValue(serviceInfo.LastTrip.Id, out var shiftEnd) ? shiftEnd : string.Empty )); } @@ -248,7 +248,7 @@ public class ServicesController : Controller .Select(t => new { Trip = t, - Sequence = int.TryParse(t.TripId.Split('_').LastOrDefault(), out var seq) ? seq : int.MaxValue + Sequence = int.TryParse(t.Id.Split('_').LastOrDefault(), out var seq) ? seq : int.MaxValue }) .OrderBy(t => t.Sequence) .ThenBy(t => t.Trip.TripHeadsign) // Secondary sort to ensure consistent ordering @@ -263,7 +263,7 @@ public class ServicesController : Controller var stopTimes = _db.StopTimes .AsSplitQuery().AsNoTracking() .Include(gtfsStopTime => gtfsStopTime.GtfsStop) - .Where(st => st.TripId == trip.TripId) + .Where(st => st.TripId == trip.Id) .OrderBy(st => st.StopSequence) .ToList(); @@ -277,19 +277,19 @@ public class ServicesController : Controller var tripDistance = (int?)(lastStop.ShapeDistTraveled - firstStop.ShapeDistTraveled); totalDistance += tripDistance ?? 0; - totalDrivingMinutes += (lastStop.ArrivalTimeOnly - firstStop.DepartureTimeOnly); + totalDrivingMinutes += (lastStop.ArrivalTime - firstStop.DepartureTime); items.Add(new ServiceDetailsItem { - TripId = trip.TripId, + TripId = trip.Id, SafeRouteId = trip.Route.SafeId, ShortName = trip.Route.ShortName, LongName = trip.TripHeadsign ?? trip.Route.LongName, TotalDistance = tripDistance.HasValue ? $"{tripDistance.Value/1_000:F2} km" : "N/A", FirstStopName = firstStop.GtfsStop.Name, - FirstStopTime = firstStop.DepartureTime, + FirstStopTime = firstStop.Departure, LastStopName = lastStop.GtfsStop.Name, - LastStopTime = lastStop.ArrivalTime + LastStopTime = lastStop.Arrival }); } diff --git a/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj b/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj index 4aab7d4..afa2489 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj +++ b/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable Costasdev.ServiceViewer @@ -9,7 +9,59 @@ - - + + + + + + + + + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\Microsoft.Build.Locator.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.deps.json" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll.config" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.runtimeconfig.json" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\Newtonsoft.Json.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\System.Collections.Immutable.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\System.CommandLine.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\cs\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\de\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\es\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\fr\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\it\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\ja\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\ko\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\pl\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\pt-BR\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\ru\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\tr\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\zh-Hans\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-netcore\zh-Hant\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\Microsoft.Build.Locator.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe.config" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\Microsoft.IO.Redist.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\Newtonsoft.Json.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.Buffers.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.Collections.Immutable.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.CommandLine.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.Memory.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.Numerics.Vectors.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.Runtime.CompilerServices.Unsafe.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\System.Threading.Tasks.Extensions.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\cs\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\de\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\es\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\fr\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\it\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\ja\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\ko\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\pl\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\pt-BR\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\ru\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\tr\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\zh-Hans\System.CommandLine.resources.dll" /> + <_ContentIncludedByDefault Remove="C:\Users\ariel\.nuget\packages\microsoft.codeanalysis.workspaces.msbuild\4.14.0\contentFiles\any\any\BuildHost-net472\zh-Hant\System.CommandLine.resources.dll" /> diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs index 55a5a08..50f0791 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs @@ -12,26 +12,33 @@ public class AppDbContext : DbContext protected override void OnModelCreating(ModelBuilder modelBuilder) { - // Relación Trip -> StopTimes (cascade delete) - modelBuilder.Entity() - .HasMany() - .WithOne(st => st.GtfsTrip) - .HasForeignKey(st => st.TripId) - .OnDelete(DeleteBehavior.Cascade); - - // Relación Stop -> StopTimes (cascade delete) - modelBuilder.Entity() - .HasMany() - .WithOne(st => st.GtfsStop) - .HasForeignKey(st => st.StopId) - .OnDelete(DeleteBehavior.Cascade); - - // Relación Route -> Trips (cascade delete) + // Route -> Agency modelBuilder.Entity() - .HasMany() - .WithOne(t => t.Route) - .HasForeignKey(t => t.RouteId) - .OnDelete(DeleteBehavior.Cascade); + .HasOne(r => r.Agency) + .WithMany() + .HasForeignKey(r => new { r.AgencyId, r.FeedId }) + .HasPrincipalKey(a => new { a.Id, a.FeedId }); + + // Trip -> Route + modelBuilder.Entity() + .HasOne(t => t.Route) + .WithMany() + .HasForeignKey(t => new { t.RouteId, t.FeedId }) + .HasPrincipalKey(a => new { a.Id, a.FeedId }); + + // Relación StopTimes -> Trip + modelBuilder.Entity() + .HasOne(st => st.GtfsTrip) + .WithMany() + .HasForeignKey(st => new { st.TripId, st.FeedId }) + .HasPrincipalKey(a => new { a.Id, a.FeedId }); + + // Relación StopTimes -> Stop + modelBuilder.Entity() + .HasOne(st => st.GtfsStop) + .WithMany() + .HasForeignKey(st => new { st.StopId, st.FeedId }) + .HasPrincipalKey(a => new { a.Id, a.FeedId }); modelBuilder.Entity() .Property(t => t.TripWheelchairAccessible) diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs new file mode 100644 index 0000000..7fa487d --- /dev/null +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs @@ -0,0 +1,20 @@ +namespace Costasdev.ServiceViewer.Data.Extensions; + +public static class TimeExtensions +{ + extension(TimeSpan) { + public static TimeSpan FromGtfsTime(string gtfsTime) + { + var parts = gtfsTime.Split(":", 3); + + var hours = int.Parse(parts[0]); + var minutes = int.Parse(parts[1]); + var seconds = int.Parse(parts[2]); + + int days = hours / 24; + int leftoverHours = hours % 24; + + return new TimeSpan(days, leftoverHours, minutes, seconds); + } + } +} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs new file mode 100644 index 0000000..065250b --- /dev/null +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Costasdev.ServiceViewer.Data.Gtfs; + +[Table("feeds")] +public class Feed +{ + /// + /// Auto-incrementing ID value for each feed, to identify it and its version + /// + [Key] + public int Id { get; set; } + + [MaxLength(32)] public string ShortName { get; set; } + [MaxLength(32)] public string LongName { get; set; } + [MaxLength(255)] public string DownloadUrl { get; set; } + [MaxLength(32)] public string Etag { get; set; } + + public DateTime InsertedAt { get; set; } +} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs index 999adb8..89b5518 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs @@ -1,9 +1,11 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("agencies")] +[Table("gtfs_agencies")] +[PrimaryKey(nameof(Id), nameof(FeedId))] public class GtfsAgency { [Key] @@ -11,6 +13,9 @@ public class GtfsAgency [MaxLength(255)] public required string Id { get; set; } + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + [Column("agency_name")] [MaxLength(255)] public string Name { get; set; } = string.Empty; diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs index 56f3f85..cfb144c 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs @@ -1,9 +1,11 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("calendar")] +[Table("gtfs_calendar")] +[PrimaryKey(nameof(ServiceId), nameof(FeedId))] public class GtfsCalendar { [Key] @@ -11,6 +13,9 @@ public class GtfsCalendar [MaxLength(32)] public string ServiceId { get; set; } = null!; + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + [Column("monday")] public bool Monday { get; set; } diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs index 977fb74..1543ef5 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs @@ -5,8 +5,8 @@ using Microsoft.EntityFrameworkCore; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("calendar_dates")] -[PrimaryKey(nameof(ServiceId), nameof(Date))] +[Table("gtfs_calendar_dates")] +[PrimaryKey(nameof(ServiceId), nameof(Date), nameof(FeedId))] public class GtfsCalendarDate { [Column("service_id")] @@ -16,6 +16,9 @@ public class GtfsCalendarDate [Column("date")] public required DateTime Date { get; set; } + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + [Column("exception_type")] public required ExceptionType ExceptionType { get; set; } } diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs index 261e183..c34353c 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs @@ -1,26 +1,30 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Costasdev.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("routes")] +[Table("gtfs_routes")] +[PrimaryKey(nameof(Id), nameof(FeedId))] public class GtfsRoute { - [Key] [Column("route_id")] [MaxLength(255)] public required string Id { get; set; } public string SafeId => Id.Replace(" ", "_").Replace("-", "_"); + [Column("feed_id")]public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + [Column("agency_id")] - [ForeignKey(nameof(GtfsAgency))] + [ForeignKey(nameof(Agency))] [MaxLength(255)] public required string AgencyId { get; set; } [ForeignKey(nameof(AgencyId))] - public GtfsAgency GtfsAgency { get; set; } = null!; + public GtfsAgency Agency { get; set; } = null!; /// /// Short name of a route. Often a short, abstract identifier (e.g., "32", "100X", "Green") diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs index 20900d7..f604c5f 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs @@ -1,17 +1,22 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Costasdev.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; +using NetTopologySuite.Geometries; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("stops")] +[Table("gtfs_stops")] +[PrimaryKey(nameof(Id), nameof(FeedId))] public class GtfsStop { - [Key] [Column("stop_id")] [MaxLength(32)] public required string Id { get; set; } + [Column("feed_id")]public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + [Column("stop_code")] [MaxLength(32)] public string Code { get; set; } = string.Empty; @@ -24,11 +29,8 @@ public class GtfsStop [MaxLength(255)] public string? Description { get; set; } - [Column("stop_lat")] - public double Latitude { get; set; } - - [Column("stop_lon")] - public double Longitude { get; set; } + [Column("stop_pos")] + public Point? Position { get; set; } [Column("stop_url")] [MaxLength(255)] diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs index 07b6732..9599947 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs @@ -1,11 +1,12 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Costasdev.ServiceViewer.Data.Extensions; using Microsoft.EntityFrameworkCore; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("stop_times")] -[PrimaryKey(nameof(TripId), nameof(StopSequence))] +[Table("gtfs_stop_times")] +[PrimaryKey(nameof(TripId), nameof(StopSequence), nameof(FeedId))] public class GtfsStopTime { [Column("trip_id")] @@ -13,13 +14,16 @@ public class GtfsStopTime [MaxLength(32)] public string TripId { get; set; } = null!; + [Column("feed_id")]public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } + [ForeignKey(nameof(TripId))] public GtfsTrip GtfsTrip { get; set; } = null!; - [Column("arrival_time")] public string ArrivalTime { get; set; } - public TimeOnly ArrivalTimeOnly => TimeOnly.Parse(ArrivalTime); + [Column("arrival_time")] public string Arrival { get; set; } + public TimeSpan ArrivalTime => TimeSpan.FromGtfsTime(Arrival); - [Column("departure_time")] public string DepartureTime { get; set; } - public TimeOnly DepartureTimeOnly => TimeOnly.Parse(DepartureTime); + [Column("departure_time")] public string Departure { get; set; } + public TimeSpan DepartureTime => TimeSpan.FromGtfsTime(Departure); [Column("stop_id")] [ForeignKey(nameof(GtfsStop))] diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs index d68cbdd..3614120 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs @@ -1,28 +1,27 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Costasdev.ServiceViewer.Data.Gtfs.Enums; +using Microsoft.EntityFrameworkCore; namespace Costasdev.ServiceViewer.Data.Gtfs; -[Table("trips")] +[Table("gtfs_trips")] +[PrimaryKey(nameof(Id), nameof(FeedId))] public class GtfsTrip { - [Key] - [Column("trip_id")] - [MaxLength(32)] - public string TripId { get; set; } = null!; + [Column("trip_id")] [MaxLength(32)] public string Id { get; set; } = null!; + + [Column("feed_id")] public int FeedId { get; set; } + [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } [Column("route_id")] [MaxLength(32)] [ForeignKey(nameof(Route))] public string RouteId { get; set; } = null!; - [ForeignKey(nameof(RouteId))] - public GtfsRoute Route { get; set; } = null!; + [ForeignKey(nameof(RouteId))] public GtfsRoute Route { get; set; } = null!; - [Column("service_id")] - [MaxLength(32)] - public string ServiceId { get; set; } = null!; + [Column("service_id")] [MaxLength(32)] public string ServiceId { get; set; } = null!; [Column("trip_headsign")] [MaxLength(255)] @@ -32,8 +31,7 @@ public class GtfsTrip [MaxLength(255)] public string? TripShortName { get; set; } - [Column("direction_id")] - public DirectionId DirectionId { get; set; } = DirectionId.Outbound; + [Column("direction_id")] public DirectionId DirectionId { get; set; } = DirectionId.Outbound; /// /// Identifies the block to which the trip belongs. A block consists of a single trip or many @@ -55,6 +53,5 @@ public class GtfsTrip [Column("trip_wheelchair_accessible")] public TripWheelchairAccessible TripWheelchairAccessible { get; set; } = TripWheelchairAccessible.Empty; - [Column("trip_bikes_allowed")] - public TripBikesAllowed TripBikesAllowed { get; set; } = TripBikesAllowed.Empty; + [Column("trip_bikes_allowed")] public TripBikesAllowed TripBikesAllowed { get; set; } = TripBikesAllowed.Empty; } diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.Designer.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.Designer.cs deleted file mode 100644 index d123034..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.Designer.cs +++ /dev/null @@ -1,398 +0,0 @@ -// -using System; -using Costasdev.Busurbano.Database; -using Costasdev.ServiceViewer; -using Costasdev.ServiceViewer.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Costasdev.Busurbano.Database.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20250821135143_InitialGtfsData")] - partial class InitialGtfsData - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "9.0.8") - .HasAnnotation("Relational:MaxIdentifierLength", 64); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Agency", b => - { - b.Property("Id") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("agency_id"); - - b.Property("Email") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("agency_email"); - - b.Property("FareUrl") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("agency_fare_url"); - - b.Property("Language") - .IsRequired() - .HasMaxLength(5) - .HasColumnType("varchar(5)") - .HasColumnName("agency_lang"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("agency_name"); - - b.Property("Phone") - .HasMaxLength(30) - .HasColumnType("varchar(30)") - .HasColumnName("agency_phone"); - - b.Property("Timezone") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("varchar(50)") - .HasColumnName("agency_timezone"); - - b.Property("Url") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("agency_url"); - - b.HasKey("Id"); - - b.ToTable("agencies"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Calendar", b => - { - b.Property("ServiceId") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("service_id"); - - b.Property("EndDate") - .HasColumnType("date") - .HasColumnName("end_date"); - - b.Property("Friday") - .HasColumnType("tinyint(1)") - .HasColumnName("friday"); - - b.Property("Monday") - .HasColumnType("tinyint(1)") - .HasColumnName("monday"); - - b.Property("Saturday") - .HasColumnType("tinyint(1)") - .HasColumnName("saturday"); - - b.Property("StartDate") - .HasColumnType("date") - .HasColumnName("start_date"); - - b.Property("Sunday") - .HasColumnType("tinyint(1)") - .HasColumnName("sunday"); - - b.Property("Thursday") - .HasColumnType("tinyint(1)") - .HasColumnName("thursday"); - - b.Property("Tuesday") - .HasColumnType("tinyint(1)") - .HasColumnName("tuesday"); - - b.Property("Wednesday") - .HasColumnType("tinyint(1)") - .HasColumnName("wednesday"); - - b.HasKey("ServiceId"); - - b.ToTable("calendar"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.CalendarDate", b => - { - b.Property("ServiceId") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("service_id"); - - b.Property("Date") - .HasColumnType("date") - .HasColumnName("date"); - - b.Property("ExceptionType") - .HasColumnType("int") - .HasColumnName("exception_type"); - - b.HasKey("ServiceId", "Date"); - - b.ToTable("calendar_dates"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Route", b => - { - b.Property("Id") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("route_id"); - - b.Property("AgencyId") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("agency_id"); - - b.Property("Color") - .HasMaxLength(7) - .HasColumnType("varchar(7)") - .HasColumnName("route_color"); - - b.Property("Description") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("route_desc"); - - b.Property("LongName") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("route_long_name"); - - b.Property("ShortName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("route_short_name"); - - b.Property("SortOrder") - .HasColumnType("int") - .HasColumnName("route_sort_order"); - - b.Property("TextColor") - .HasMaxLength(7) - .HasColumnType("varchar(7)") - .HasColumnName("route_text_color"); - - b.Property("Type") - .HasColumnType("int") - .HasColumnName("route_type"); - - b.Property("Url") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("route_url"); - - b.HasKey("Id"); - - b.HasIndex("AgencyId"); - - b.ToTable("routes"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Stop", b => - { - b.Property("Id") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("stop_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("stop_code"); - - b.Property("Description") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("stop_desc"); - - b.Property("Latitude") - .HasColumnType("double") - .HasColumnName("stop_lat"); - - b.Property("Longitude") - .HasColumnType("double") - .HasColumnName("stop_lon"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("stop_name"); - - b.Property("Timezone") - .HasMaxLength(50) - .HasColumnType("varchar(50)") - .HasColumnName("stop_timezone"); - - b.Property("Url") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("stop_url"); - - b.Property("WheelchairBoarding") - .HasColumnType("int") - .HasColumnName("wheelchair_boarding"); - - b.HasKey("Id"); - - b.ToTable("stops"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.StopTime", b => - { - b.Property("TripId") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("trip_id"); - - b.Property("StopSequence") - .HasColumnType("int") - .HasColumnName("stop_sequence"); - - b.Property("ArrivalTime") - .HasMaxLength(8) - .HasColumnType("varchar(8)") - .HasColumnName("arrival_time"); - - b.Property("DepartureTime") - .HasMaxLength(8) - .HasColumnType("varchar(8)") - .HasColumnName("departure_time"); - - b.Property("ShapeDistTraveled") - .HasColumnType("double") - .HasColumnName("shape_dist_traveled"); - - b.Property("StopId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("stop_id"); - - b.HasKey("TripId", "StopSequence"); - - b.HasIndex("StopId"); - - b.ToTable("stop_times"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Trip", b => - { - b.Property("TripId") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("trip_id"); - - b.Property("BlockId") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("block_id"); - - b.Property("DirectionId") - .HasColumnType("int") - .HasColumnName("direction_id"); - - b.Property("RouteId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("route_id"); - - b.Property("ServiceId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("service_id"); - - b.Property("ShapeId") - .HasMaxLength(32) - .HasColumnType("varchar(32)") - .HasColumnName("shape_id"); - - b.Property("TripBikesAllowed") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValue(0) - .HasColumnName("trip_bikes_allowed"); - - b.Property("TripHeadsign") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("trip_headsign"); - - b.Property("TripShortName") - .HasMaxLength(255) - .HasColumnType("varchar(255)") - .HasColumnName("trip_short_name"); - - b.Property("TripWheelchairAccessible") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValue(0) - .HasColumnName("trip_wheelchair_accessible"); - - b.HasKey("TripId"); - - b.HasIndex("RouteId"); - - b.ToTable("trips"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Route", b => - { - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Agency", "Agency") - .WithMany() - .HasForeignKey("AgencyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Agency"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.StopTime", b => - { - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Stop", "Stop") - .WithMany() - .HasForeignKey("StopId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Trip", "Trip") - .WithMany() - .HasForeignKey("TripId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Stop"); - - b.Navigation("Trip"); - }); - - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Trip", b => - { - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Route", null) - .WithMany() - .HasForeignKey("RouteId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.cs deleted file mode 100644 index 3cf6ab8..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20250821135143_InitialGtfsData.cs +++ /dev/null @@ -1,215 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Costasdev.Busurbano.Database.Migrations -{ - /// - public partial class InitialGtfsData : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterDatabase() - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "agencies", - columns: table => new - { - agency_id = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - agency_name = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - agency_url = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - agency_timezone = table.Column(type: "varchar(50)", maxLength: 50, nullable: false), - agency_lang = table.Column(type: "varchar(5)", maxLength: 5, nullable: false), - agency_phone = table.Column(type: "varchar(30)", maxLength: 30, nullable: true), - agency_email = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - agency_fare_url = table.Column(type: "varchar(255)", maxLength: 255, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_agencies", x => x.agency_id); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "calendar", - columns: table => new - { - service_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - monday = table.Column(type: "tinyint(1)", nullable: false), - tuesday = table.Column(type: "tinyint(1)", nullable: false), - wednesday = table.Column(type: "tinyint(1)", nullable: false), - thursday = table.Column(type: "tinyint(1)", nullable: false), - friday = table.Column(type: "tinyint(1)", nullable: false), - saturday = table.Column(type: "tinyint(1)", nullable: false), - sunday = table.Column(type: "tinyint(1)", nullable: false), - start_date = table.Column(type: "date", nullable: false), - end_date = table.Column(type: "date", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_calendar", x => x.service_id); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "calendar_dates", - columns: table => new - { - service_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - date = table.Column(type: "date", nullable: false), - exception_type = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_calendar_dates", x => new { x.service_id, x.date }); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "stops", - columns: table => new - { - stop_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - stop_code = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - stop_name = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - stop_desc = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - stop_lat = table.Column(type: "double", nullable: false), - stop_lon = table.Column(type: "double", nullable: false), - stop_url = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - stop_timezone = table.Column(type: "varchar(50)", maxLength: 50, nullable: true), - wheelchair_boarding = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_stops", x => x.stop_id); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "routes", - columns: table => new - { - route_id = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - agency_id = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - route_short_name = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - route_long_name = table.Column(type: "varchar(255)", maxLength: 255, nullable: false), - route_desc = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - route_type = table.Column(type: "int", nullable: false), - route_url = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - route_color = table.Column(type: "varchar(7)", maxLength: 7, nullable: true), - route_text_color = table.Column(type: "varchar(7)", maxLength: 7, nullable: true), - route_sort_order = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_routes", x => x.route_id); - table.ForeignKey( - name: "FK_routes_agencies_agency_id", - column: x => x.agency_id, - principalTable: "agencies", - principalColumn: "agency_id", - onDelete: ReferentialAction.Cascade); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "trips", - columns: table => new - { - trip_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - route_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - service_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - trip_headsign = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - trip_short_name = table.Column(type: "varchar(255)", maxLength: 255, nullable: true), - direction_id = table.Column(type: "int", nullable: false), - block_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: true), - shape_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: true), - trip_wheelchair_accessible = table.Column(type: "int", nullable: false, defaultValue: 0), - trip_bikes_allowed = table.Column(type: "int", nullable: false, defaultValue: 0) - }, - constraints: table => - { - table.PrimaryKey("PK_trips", x => x.trip_id); - table.ForeignKey( - name: "FK_trips_routes_route_id", - column: x => x.route_id, - principalTable: "routes", - principalColumn: "route_id", - onDelete: ReferentialAction.Cascade); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateTable( - name: "stop_times", - columns: table => new - { - trip_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - stop_sequence = table.Column(type: "int", nullable: false), - arrival_time = table.Column(type: "varchar(8)", maxLength: 8, nullable: false), - departure_time = table.Column(type: "varchar(8)", maxLength: 8, nullable: false), - stop_id = table.Column(type: "varchar(32)", maxLength: 32, nullable: false), - shape_dist_traveled = table.Column(type: "double", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_stop_times", x => new { x.trip_id, x.stop_sequence }); - table.ForeignKey( - name: "FK_stop_times_stops_stop_id", - column: x => x.stop_id, - principalTable: "stops", - principalColumn: "stop_id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_stop_times_trips_trip_id", - column: x => x.trip_id, - principalTable: "trips", - principalColumn: "trip_id", - onDelete: ReferentialAction.Cascade); - }) - .Annotation("MySQL:Charset", "utf8mb4"); - - migrationBuilder.CreateIndex( - name: "IX_routes_agency_id", - table: "routes", - column: "agency_id"); - - migrationBuilder.CreateIndex( - name: "IX_stop_times_stop_id", - table: "stop_times", - column: "stop_id"); - - migrationBuilder.CreateIndex( - name: "IX_trips_route_id", - table: "trips", - column: "route_id"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "calendar"); - - migrationBuilder.DropTable( - name: "calendar_dates"); - - migrationBuilder.DropTable( - name: "stop_times"); - - migrationBuilder.DropTable( - name: "stops"); - - migrationBuilder.DropTable( - name: "trips"); - - migrationBuilder.DropTable( - name: "routes"); - - migrationBuilder.DropTable( - name: "agencies"); - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs new file mode 100644 index 0000000..79f3e87 --- /dev/null +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs @@ -0,0 +1,547 @@ +// +using System; +using Costasdev.ServiceViewer.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NetTopologySuite.Geometries; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Data.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20251211153852_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.Feed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Etag") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("InsertedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LongName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ShortName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.HasKey("Id"); + + b.ToTable("feeds"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => + { + b.Property("Id") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agency_id"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("Email") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agency_email"); + + b.Property("FareUrl") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agency_fare_url"); + + b.Property("Language") + .IsRequired() + .HasMaxLength(5) + .HasColumnType("character varying(5)") + .HasColumnName("agency_lang"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agency_name"); + + b.Property("Phone") + .HasMaxLength(30) + .HasColumnType("character varying(30)") + .HasColumnName("agency_phone"); + + b.Property("Timezone") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("agency_timezone"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agency_url"); + + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); + + b.ToTable("gtfs_agencies"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => + { + b.Property("ServiceId") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("service_id"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("EndDate") + .HasColumnType("date") + .HasColumnName("end_date"); + + b.Property("Friday") + .HasColumnType("boolean") + .HasColumnName("friday"); + + b.Property("Monday") + .HasColumnType("boolean") + .HasColumnName("monday"); + + b.Property("Saturday") + .HasColumnType("boolean") + .HasColumnName("saturday"); + + b.Property("StartDate") + .HasColumnType("date") + .HasColumnName("start_date"); + + b.Property("Sunday") + .HasColumnType("boolean") + .HasColumnName("sunday"); + + b.Property("Thursday") + .HasColumnType("boolean") + .HasColumnName("thursday"); + + b.Property("Tuesday") + .HasColumnType("boolean") + .HasColumnName("tuesday"); + + b.Property("Wednesday") + .HasColumnType("boolean") + .HasColumnName("wednesday"); + + b.HasKey("ServiceId", "FeedId"); + + b.HasIndex("FeedId"); + + b.ToTable("gtfs_calendar"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => + { + b.Property("ServiceId") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("service_id"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("ExceptionType") + .HasColumnType("integer") + .HasColumnName("exception_type"); + + b.HasKey("ServiceId", "Date", "FeedId"); + + b.HasIndex("FeedId"); + + b.ToTable("gtfs_calendar_dates"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => + { + b.Property("Id") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("route_id"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("AgencyId") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("agency_id"); + + b.Property("Color") + .HasMaxLength(7) + .HasColumnType("character varying(7)") + .HasColumnName("route_color"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("route_desc"); + + b.Property("LongName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("route_long_name"); + + b.Property("ShortName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("route_short_name"); + + b.Property("SortOrder") + .HasColumnType("integer") + .HasColumnName("route_sort_order"); + + b.Property("TextColor") + .HasMaxLength(7) + .HasColumnType("character varying(7)") + .HasColumnName("route_text_color"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("route_type"); + + b.Property("Url") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("route_url"); + + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); + + b.HasIndex("AgencyId", "FeedId"); + + b.ToTable("gtfs_routes"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => + { + b.Property("Id") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("stop_id"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("stop_code"); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("stop_desc"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("stop_name"); + + b.Property("Position") + .HasColumnType("geometry") + .HasColumnName("stop_pos"); + + b.Property("Timezone") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("stop_timezone"); + + b.Property("Url") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("stop_url"); + + b.Property("WheelchairBoarding") + .HasColumnType("integer") + .HasColumnName("wheelchair_boarding"); + + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); + + b.ToTable("gtfs_stops"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => + { + b.Property("TripId") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("trip_id"); + + b.Property("StopSequence") + .HasColumnType("integer") + .HasColumnName("stop_sequence"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("Arrival") + .IsRequired() + .HasColumnType("text") + .HasColumnName("arrival_time"); + + b.Property("Departure") + .IsRequired() + .HasColumnType("text") + .HasColumnName("departure_time"); + + b.Property("ShapeDistTraveled") + .HasColumnType("double precision") + .HasColumnName("shape_dist_traveled"); + + b.Property("StopId") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("stop_id"); + + b.HasKey("TripId", "StopSequence", "FeedId"); + + b.HasIndex("FeedId"); + + b.HasIndex("StopId", "FeedId"); + + b.HasIndex("TripId", "FeedId"); + + b.ToTable("gtfs_stop_times"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => + { + b.Property("Id") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("trip_id"); + + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("BlockId") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("block_id"); + + b.Property("DirectionId") + .HasColumnType("integer") + .HasColumnName("direction_id"); + + b.Property("RouteId") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("route_id"); + + b.Property("ServiceId") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("service_id"); + + b.Property("ShapeId") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("shape_id"); + + b.Property("TripBikesAllowed") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0) + .HasColumnName("trip_bikes_allowed"); + + b.Property("TripHeadsign") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("trip_headsign"); + + b.Property("TripShortName") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("trip_short_name"); + + b.Property("TripWheelchairAccessible") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0) + .HasColumnName("trip_wheelchair_accessible"); + + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); + + b.HasIndex("RouteId", "FeedId"); + + b.ToTable("gtfs_trips"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", "Agency") + .WithMany() + .HasForeignKey("AgencyId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agency"); + + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", "GtfsStop") + .WithMany() + .HasForeignKey("StopId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", "GtfsTrip") + .WithMany() + .HasForeignKey("TripId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + + b.Navigation("GtfsStop"); + + b.Navigation("GtfsTrip"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", "Route") + .WithMany() + .HasForeignKey("RouteId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + + b.Navigation("Route"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs new file mode 100644 index 0000000..5a75d40 --- /dev/null +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs @@ -0,0 +1,318 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using NetTopologySuite.Geometries; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Data.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("Npgsql:PostgresExtension:postgis", ",,"); + + migrationBuilder.CreateTable( + name: "feeds", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ShortName = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + LongName = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + DownloadUrl = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + Etag = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + InsertedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_feeds", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "gtfs_agencies", + columns: table => new + { + agency_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + agency_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + agency_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + agency_timezone = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), + agency_lang = table.Column(type: "character varying(5)", maxLength: 5, nullable: false), + agency_phone = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), + agency_email = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + agency_fare_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_agencies", x => new { x.agency_id, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_agencies_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "gtfs_calendar", + columns: table => new + { + service_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + monday = table.Column(type: "boolean", nullable: false), + tuesday = table.Column(type: "boolean", nullable: false), + wednesday = table.Column(type: "boolean", nullable: false), + thursday = table.Column(type: "boolean", nullable: false), + friday = table.Column(type: "boolean", nullable: false), + saturday = table.Column(type: "boolean", nullable: false), + sunday = table.Column(type: "boolean", nullable: false), + start_date = table.Column(type: "date", nullable: false), + end_date = table.Column(type: "date", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_calendar", x => new { x.service_id, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_calendar_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "gtfs_calendar_dates", + columns: table => new + { + service_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + date = table.Column(type: "timestamp with time zone", nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + exception_type = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_calendar_dates", x => new { x.service_id, x.date, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_calendar_dates_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "gtfs_stops", + columns: table => new + { + stop_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + stop_code = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + stop_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + stop_desc = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + stop_pos = table.Column(type: "geometry", nullable: true), + stop_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + stop_timezone = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), + wheelchair_boarding = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_stops", x => new { x.stop_id, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_stops_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "gtfs_routes", + columns: table => new + { + route_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + agency_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + route_short_name = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + route_long_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), + route_desc = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + route_type = table.Column(type: "integer", nullable: false), + route_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + route_color = table.Column(type: "character varying(7)", maxLength: 7, nullable: true), + route_text_color = table.Column(type: "character varying(7)", maxLength: 7, nullable: true), + route_sort_order = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_routes", x => new { x.route_id, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_routes_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_gtfs_routes_gtfs_agencies_agency_id_feed_id", + columns: x => new { x.agency_id, x.feed_id }, + principalTable: "gtfs_agencies", + principalColumns: new[] { "agency_id", "feed_id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "gtfs_trips", + columns: table => new + { + trip_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + route_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + service_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + trip_headsign = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + trip_short_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), + direction_id = table.Column(type: "integer", nullable: false), + block_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + shape_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), + trip_wheelchair_accessible = table.Column(type: "integer", nullable: false, defaultValue: 0), + trip_bikes_allowed = table.Column(type: "integer", nullable: false, defaultValue: 0) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_trips", x => new { x.trip_id, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_trips_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_gtfs_trips_gtfs_routes_route_id_feed_id", + columns: x => new { x.route_id, x.feed_id }, + principalTable: "gtfs_routes", + principalColumns: new[] { "route_id", "feed_id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "gtfs_stop_times", + columns: table => new + { + trip_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + feed_id = table.Column(type: "integer", nullable: false), + stop_sequence = table.Column(type: "integer", nullable: false), + arrival_time = table.Column(type: "text", nullable: false), + departure_time = table.Column(type: "text", nullable: false), + stop_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), + shape_dist_traveled = table.Column(type: "double precision", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_gtfs_stop_times", x => new { x.trip_id, x.stop_sequence, x.feed_id }); + table.ForeignKey( + name: "FK_gtfs_stop_times_feeds_feed_id", + column: x => x.feed_id, + principalTable: "feeds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_gtfs_stop_times_gtfs_stops_stop_id_feed_id", + columns: x => new { x.stop_id, x.feed_id }, + principalTable: "gtfs_stops", + principalColumns: new[] { "stop_id", "feed_id" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_gtfs_stop_times_gtfs_trips_trip_id_feed_id", + columns: x => new { x.trip_id, x.feed_id }, + principalTable: "gtfs_trips", + principalColumns: new[] { "trip_id", "feed_id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_agencies_feed_id", + table: "gtfs_agencies", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_calendar_feed_id", + table: "gtfs_calendar", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_calendar_dates_feed_id", + table: "gtfs_calendar_dates", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_routes_agency_id_feed_id", + table: "gtfs_routes", + columns: new[] { "agency_id", "feed_id" }); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_routes_feed_id", + table: "gtfs_routes", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_stop_times_feed_id", + table: "gtfs_stop_times", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_stop_times_stop_id_feed_id", + table: "gtfs_stop_times", + columns: new[] { "stop_id", "feed_id" }); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_stop_times_trip_id_feed_id", + table: "gtfs_stop_times", + columns: new[] { "trip_id", "feed_id" }); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_stops_feed_id", + table: "gtfs_stops", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_trips_feed_id", + table: "gtfs_trips", + column: "feed_id"); + + migrationBuilder.CreateIndex( + name: "IX_gtfs_trips_route_id_feed_id", + table: "gtfs_trips", + columns: new[] { "route_id", "feed_id" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "gtfs_calendar"); + + migrationBuilder.DropTable( + name: "gtfs_calendar_dates"); + + migrationBuilder.DropTable( + name: "gtfs_stop_times"); + + migrationBuilder.DropTable( + name: "gtfs_stops"); + + migrationBuilder.DropTable( + name: "gtfs_trips"); + + migrationBuilder.DropTable( + name: "gtfs_routes"); + + migrationBuilder.DropTable( + name: "gtfs_agencies"); + + migrationBuilder.DropTable( + name: "feeds"); + } + } +} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs index a77ecf5..feb3813 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs @@ -1,15 +1,15 @@ // using System; -using Costasdev.Busurbano.Database; -using Costasdev.ServiceViewer; using Costasdev.ServiceViewer.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NetTopologySuite.Geometries; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #nullable disable -namespace Costasdev.Busurbano.Database.Migrations +namespace Data.Migrations { [DbContext(typeof(AppDbContext))] partial class AppDbContextModelSnapshot : ModelSnapshot @@ -18,81 +18,130 @@ namespace Costasdev.Busurbano.Database.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "9.0.8") - .HasAnnotation("Relational:MaxIdentifierLength", 64); + .HasAnnotation("ProductVersion", "10.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Agency", b => + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.Feed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Etag") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("InsertedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LongName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ShortName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.HasKey("Id"); + + b.ToTable("feeds"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => { b.Property("Id") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("agency_id"); + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + b.Property("Email") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("agency_email"); b.Property("FareUrl") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("agency_fare_url"); b.Property("Language") .IsRequired() .HasMaxLength(5) - .HasColumnType("varchar(5)") + .HasColumnType("character varying(5)") .HasColumnName("agency_lang"); b.Property("Name") .IsRequired() .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("agency_name"); b.Property("Phone") .HasMaxLength(30) - .HasColumnType("varchar(30)") + .HasColumnType("character varying(30)") .HasColumnName("agency_phone"); b.Property("Timezone") .IsRequired() .HasMaxLength(50) - .HasColumnType("varchar(50)") + .HasColumnType("character varying(50)") .HasColumnName("agency_timezone"); b.Property("Url") .IsRequired() .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("agency_url"); - b.HasKey("Id"); + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); - b.ToTable("agencies"); + b.ToTable("gtfs_agencies"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Calendar", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => { b.Property("ServiceId") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("service_id"); + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + b.Property("EndDate") .HasColumnType("date") .HasColumnName("end_date"); b.Property("Friday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("friday"); b.Property("Monday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("monday"); b.Property("Saturday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("saturday"); b.Property("StartDate") @@ -100,294 +149,394 @@ namespace Costasdev.Busurbano.Database.Migrations .HasColumnName("start_date"); b.Property("Sunday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("sunday"); b.Property("Thursday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("thursday"); b.Property("Tuesday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("tuesday"); b.Property("Wednesday") - .HasColumnType("tinyint(1)") + .HasColumnType("boolean") .HasColumnName("wednesday"); - b.HasKey("ServiceId"); + b.HasKey("ServiceId", "FeedId"); + + b.HasIndex("FeedId"); - b.ToTable("calendar"); + b.ToTable("gtfs_calendar"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.CalendarDate", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => { b.Property("ServiceId") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("service_id"); - b.Property("Date") - .HasColumnType("date") + b.Property("Date") + .HasColumnType("timestamp with time zone") .HasColumnName("date"); + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + b.Property("ExceptionType") - .HasColumnType("int") + .HasColumnType("integer") .HasColumnName("exception_type"); - b.HasKey("ServiceId", "Date"); + b.HasKey("ServiceId", "Date", "FeedId"); + + b.HasIndex("FeedId"); - b.ToTable("calendar_dates"); + b.ToTable("gtfs_calendar_dates"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Route", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => { b.Property("Id") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("route_id"); + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + b.Property("AgencyId") .IsRequired() .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("agency_id"); b.Property("Color") .HasMaxLength(7) - .HasColumnType("varchar(7)") + .HasColumnType("character varying(7)") .HasColumnName("route_color"); b.Property("Description") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("route_desc"); b.Property("LongName") .IsRequired() .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("route_long_name"); b.Property("ShortName") .IsRequired() .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("route_short_name"); b.Property("SortOrder") - .HasColumnType("int") + .HasColumnType("integer") .HasColumnName("route_sort_order"); b.Property("TextColor") .HasMaxLength(7) - .HasColumnType("varchar(7)") + .HasColumnType("character varying(7)") .HasColumnName("route_text_color"); b.Property("Type") - .HasColumnType("int") + .HasColumnType("integer") .HasColumnName("route_type"); b.Property("Url") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("route_url"); - b.HasKey("Id"); + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); - b.HasIndex("AgencyId"); + b.HasIndex("AgencyId", "FeedId"); - b.ToTable("routes"); + b.ToTable("gtfs_routes"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Stop", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => { b.Property("Id") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("stop_id"); + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + b.Property("Code") .IsRequired() .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("stop_code"); b.Property("Description") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("stop_desc"); - b.Property("Latitude") - .HasColumnType("double") - .HasColumnName("stop_lat"); - - b.Property("Longitude") - .HasColumnType("double") - .HasColumnName("stop_lon"); - b.Property("Name") .IsRequired() .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("stop_name"); + b.Property("Position") + .HasColumnType("geometry") + .HasColumnName("stop_pos"); + b.Property("Timezone") .HasMaxLength(50) - .HasColumnType("varchar(50)") + .HasColumnType("character varying(50)") .HasColumnName("stop_timezone"); b.Property("Url") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("stop_url"); b.Property("WheelchairBoarding") - .HasColumnType("int") + .HasColumnType("integer") .HasColumnName("wheelchair_boarding"); - b.HasKey("Id"); + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); - b.ToTable("stops"); + b.ToTable("gtfs_stops"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.StopTime", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => { b.Property("TripId") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("trip_id"); b.Property("StopSequence") - .HasColumnType("int") + .HasColumnType("integer") .HasColumnName("stop_sequence"); - b.Property("ArrivalTime") - .HasMaxLength(8) - .HasColumnType("varchar(8)") + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + + b.Property("Arrival") + .IsRequired() + .HasColumnType("text") .HasColumnName("arrival_time"); - b.Property("DepartureTime") - .HasMaxLength(8) - .HasColumnType("varchar(8)") + b.Property("Departure") + .IsRequired() + .HasColumnType("text") .HasColumnName("departure_time"); b.Property("ShapeDistTraveled") - .HasColumnType("double") + .HasColumnType("double precision") .HasColumnName("shape_dist_traveled"); b.Property("StopId") .IsRequired() .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("stop_id"); - b.HasKey("TripId", "StopSequence"); + b.HasKey("TripId", "StopSequence", "FeedId"); + + b.HasIndex("FeedId"); - b.HasIndex("StopId"); + b.HasIndex("StopId", "FeedId"); - b.ToTable("stop_times"); + b.HasIndex("TripId", "FeedId"); + + b.ToTable("gtfs_stop_times"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Trip", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => { - b.Property("TripId") + b.Property("Id") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("trip_id"); + b.Property("FeedId") + .HasColumnType("integer") + .HasColumnName("feed_id"); + b.Property("BlockId") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("block_id"); b.Property("DirectionId") - .HasColumnType("int") + .HasColumnType("integer") .HasColumnName("direction_id"); b.Property("RouteId") .IsRequired() .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("route_id"); b.Property("ServiceId") .IsRequired() .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("service_id"); b.Property("ShapeId") .HasMaxLength(32) - .HasColumnType("varchar(32)") + .HasColumnType("character varying(32)") .HasColumnName("shape_id"); b.Property("TripBikesAllowed") .ValueGeneratedOnAdd() - .HasColumnType("int") + .HasColumnType("integer") .HasDefaultValue(0) .HasColumnName("trip_bikes_allowed"); b.Property("TripHeadsign") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("trip_headsign"); b.Property("TripShortName") .HasMaxLength(255) - .HasColumnType("varchar(255)") + .HasColumnType("character varying(255)") .HasColumnName("trip_short_name"); b.Property("TripWheelchairAccessible") .ValueGeneratedOnAdd() - .HasColumnType("int") + .HasColumnType("integer") .HasDefaultValue(0) .HasColumnName("trip_wheelchair_accessible"); - b.HasKey("TripId"); + b.HasKey("Id", "FeedId"); + + b.HasIndex("FeedId"); + + b.HasIndex("RouteId", "FeedId"); + + b.ToTable("gtfs_trips"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.HasIndex("RouteId"); + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") + .WithMany() + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.ToTable("trips"); + b.Navigation("Feed"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Route", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => { - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Agency", "Agency") + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") .WithMany() - .HasForeignKey("AgencyId") + .HasForeignKey("FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", "Agency") + .WithMany() + .HasForeignKey("AgencyId", "FeedId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Agency"); + + b.Navigation("Feed"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.StopTime", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => { - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Stop", "Stop") + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") .WithMany() - .HasForeignKey("StopId") + .HasForeignKey("FeedId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Trip", "Trip") + b.Navigation("Feed"); + }); + + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => + { + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") .WithMany() - .HasForeignKey("TripId") + .HasForeignKey("FeedId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("Stop"); + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", "GtfsStop") + .WithMany() + .HasForeignKey("StopId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.Navigation("Trip"); + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", "GtfsTrip") + .WithMany() + .HasForeignKey("TripId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + + b.Navigation("GtfsStop"); + + b.Navigation("GtfsTrip"); }); - modelBuilder.Entity("Costasdev.Busurbano.Database.Gtfs.Trip", b => + modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => { - b.HasOne("Costasdev.Busurbano.Database.Gtfs.Route", null) + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") .WithMany() - .HasForeignKey("RouteId") + .HasForeignKey("FeedId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", "Route") + .WithMany() + .HasForeignKey("RouteId", "FeedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feed"); + + b.Navigation("Route"); }); #pragma warning restore 612, 618 } diff --git a/src/Costasdev.Busurbano.ServiceViewer/Program.cs b/src/Costasdev.Busurbano.ServiceViewer/Program.cs index 285afc2..847f9d5 100644 --- a/src/Costasdev.Busurbano.ServiceViewer/Program.cs +++ b/src/Costasdev.Busurbano.ServiceViewer/Program.cs @@ -13,7 +13,10 @@ builder.Services.AddDbContext(db => { throw new InvalidOperationException("Connection string 'Database' is not configured."); } - db.UseMySQL(connectionString); + db.UseNpgsql(connectionString, npg => + { + npg.UseNetTopologySuite(); + }); }); builder.Services.AddHttpClient(); -- cgit v1.3