diff --git a/src/FlightRecorder.Api/Controllers/ReportsController.cs b/src/FlightRecorder.Api/Controllers/ReportsController.cs index 6f9deda..ebc0ccb 100644 --- a/src/FlightRecorder.Api/Controllers/ReportsController.cs +++ b/src/FlightRecorder.Api/Controllers/ReportsController.cs @@ -1,13 +1,9 @@ -using FlightRecorder.BusinessLogic.Factory; +using FlightRecorder.Api.Entities; +using FlightRecorder.BusinessLogic.Factory; using FlightRecorder.Entities.Db; using FlightRecorder.Entities.Reporting; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; using System.Web; namespace FlightRecorder.Api.Controllers @@ -27,6 +23,34 @@ public ReportsController(FlightRecorderFactory factory) _factory = factory; } + /// + /// Generate the sighting statistics report + /// + /// + [HttpGet] + [Route("sightings")] + public async Task> GetSightingStatistics() + { + var aircraft = await _factory.Aircraft.CountAsync(); + var manufacturers = await _factory.Manufacturers.CountAsync(); + var models = await _factory.Models.CountAsync(); + var airlines = await _factory.Airlines.CountAsync(); + var flights = await _factory.Flights.CountAsync(); + var sightings = await _factory.Sightings.CountAsync(); + var locations = await _factory.Locations.CountAsync(); + + return new SightingStatisticsReport + ( + aircraft, + manufacturers, + models, + airlines, + flights, + sightings, + locations + ); + } + /// /// Generate the airline statistics report /// diff --git a/src/FlightRecorder.Api/Entities/SightingStatisticsReport.cs b/src/FlightRecorder.Api/Entities/SightingStatisticsReport.cs new file mode 100644 index 0000000..89696b1 --- /dev/null +++ b/src/FlightRecorder.Api/Entities/SightingStatisticsReport.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.CodeAnalysis; + +namespace FlightRecorder.Api.Entities +{ + [ExcludeFromCodeCoverage] + public record SightingStatisticsReport + ( + int Aircraft, + int Manufacturers, + int Models, + int Airlines, + int Flights, + int Sightings, + int Locations + ); +} diff --git a/src/FlightRecorder.Api/FlightRecorder.Api.csproj b/src/FlightRecorder.Api/FlightRecorder.Api.csproj index 86e2044..9e4610b 100644 --- a/src/FlightRecorder.Api/FlightRecorder.Api.csproj +++ b/src/FlightRecorder.Api/FlightRecorder.Api.csproj @@ -2,9 +2,9 @@ net8.0 - 1.10.0.0 - 1.10.0.0 - 1.10.0 + 1.11.0.0 + 1.11.0.0 + 1.11.0 enable false diff --git a/src/FlightRecorder.BusinessLogic/Database/AircraftManager.cs b/src/FlightRecorder.BusinessLogic/Database/AircraftManager.cs index 7c24834..cb881b7 100644 --- a/src/FlightRecorder.BusinessLogic/Database/AircraftManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/AircraftManager.cs @@ -67,6 +67,13 @@ public IAsyncEnumerable ListAsync(Expression> pre return aircraft; } + /// + /// Return the number of aircraft in the database + /// + /// + public async Task CountAsync() + => await _factory.Context.Aircraft.CountAsync(); + /// /// Get the aircraft of a specified model /// diff --git a/src/FlightRecorder.BusinessLogic/Database/AirlineManager.cs b/src/FlightRecorder.BusinessLogic/Database/AirlineManager.cs index 2d9c7a9..2b363eb 100644 --- a/src/FlightRecorder.BusinessLogic/Database/AirlineManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/AirlineManager.cs @@ -56,6 +56,13 @@ public IAsyncEnumerable ListAsync(Expression> predi return results; } + /// + /// Return the number of airlines in the database + /// + /// + public async Task CountAsync() + => await _context.Airlines.CountAsync(); + /// /// Add a named airline, if it doesn't already exist /// diff --git a/src/FlightRecorder.BusinessLogic/Database/FlightManager.cs b/src/FlightRecorder.BusinessLogic/Database/FlightManager.cs index 16fd66a..217ffc9 100644 --- a/src/FlightRecorder.BusinessLogic/Database/FlightManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/FlightManager.cs @@ -63,6 +63,13 @@ public IAsyncEnumerable ListAsync(Expression> predica return flights; } + /// + /// Return the number of flights in the database + /// + /// + public async Task CountAsync() + => await _factory.Context.Flights.CountAsync(); + /// /// Get the flights for a named airline /// diff --git a/src/FlightRecorder.BusinessLogic/Database/LocationManager.cs b/src/FlightRecorder.BusinessLogic/Database/LocationManager.cs index 22f5e62..26aaae5 100644 --- a/src/FlightRecorder.BusinessLogic/Database/LocationManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/LocationManager.cs @@ -60,6 +60,13 @@ public virtual IAsyncEnumerable ListAsync(Expression + /// Return the number of locations in the database + /// + /// + public async Task CountAsync() + => await _context.Locations.CountAsync(); + /// /// Add a named location, if it doesn't already exist /// diff --git a/src/FlightRecorder.BusinessLogic/Database/ManufacturerManager.cs b/src/FlightRecorder.BusinessLogic/Database/ManufacturerManager.cs index a7a1e58..aca6929 100644 --- a/src/FlightRecorder.BusinessLogic/Database/ManufacturerManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/ManufacturerManager.cs @@ -60,6 +60,13 @@ public IAsyncEnumerable ListAsync(Expression + /// Return the number of manufacturers in the database + /// + /// + public async Task CountAsync() + => await _context.Manufacturers.CountAsync(); + /// /// Add a named manufacturer, if it doesn't already exist /// diff --git a/src/FlightRecorder.BusinessLogic/Database/ModelManager.cs b/src/FlightRecorder.BusinessLogic/Database/ModelManager.cs index 662cd84..e83a0a8 100644 --- a/src/FlightRecorder.BusinessLogic/Database/ModelManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/ModelManager.cs @@ -63,6 +63,13 @@ public IAsyncEnumerable ListAsync(Expression> predicate return models; } + /// + /// Return the number of aircraft models in the database + /// + /// + public async Task CountAsync() + => await _factory.Context.Models.CountAsync(); + /// /// Get the models for a named manufacturer /// diff --git a/src/FlightRecorder.BusinessLogic/Database/SightingManager.cs b/src/FlightRecorder.BusinessLogic/Database/SightingManager.cs index 56c64d5..47760be 100644 --- a/src/FlightRecorder.BusinessLogic/Database/SightingManager.cs +++ b/src/FlightRecorder.BusinessLogic/Database/SightingManager.cs @@ -76,6 +76,13 @@ public IAsyncEnumerable ListAsync(Expression> pre return sightings; } + /// + /// Return the number of sightings in the database + /// + /// + public async Task CountAsync() + => await _factory.Context.Sightings.CountAsync(); + /// /// Add a new sighting /// diff --git a/src/FlightRecorder.Entities/Interfaces/IAircraftManager.cs b/src/FlightRecorder.Entities/Interfaces/IAircraftManager.cs index f0772eb..513d51f 100644 --- a/src/FlightRecorder.Entities/Interfaces/IAircraftManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/IAircraftManager.cs @@ -11,6 +11,7 @@ public interface IAircraftManager Task AddAsync(string registration, string serialNumber, long? yearOfManufacture, string modelName, string manufacturerName); Task GetAsync(Expression> predicate); IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); Task> ListByModelAsync(string modelName, int pageNumber, int pageSize); Task> ListByManufacturerAsync(string manufacturerName, int pageNumber, int pageSize); } diff --git a/src/FlightRecorder.Entities/Interfaces/IAirlineManager.cs b/src/FlightRecorder.Entities/Interfaces/IAirlineManager.cs index 27e9c99..68bd0b2 100644 --- a/src/FlightRecorder.Entities/Interfaces/IAirlineManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/IAirlineManager.cs @@ -10,6 +10,7 @@ public interface IAirlineManager { Task AddAsync(string name); Task GetAsync(Expression> predicate); - IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); } } \ No newline at end of file diff --git a/src/FlightRecorder.Entities/Interfaces/IFlightManager.cs b/src/FlightRecorder.Entities/Interfaces/IFlightManager.cs index d5b3206..e8166b3 100644 --- a/src/FlightRecorder.Entities/Interfaces/IFlightManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/IFlightManager.cs @@ -11,6 +11,7 @@ public interface IFlightManager Task AddAsync(string number, string embarkation, string destination, string airlineName); Task GetAsync(Expression> predicate); IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); Task> ListByAirlineAsync(string airlineName, int pageNumber, int pageSize); } } \ No newline at end of file diff --git a/src/FlightRecorder.Entities/Interfaces/ILocationManager.cs b/src/FlightRecorder.Entities/Interfaces/ILocationManager.cs index 59a4e7b..25e273d 100644 --- a/src/FlightRecorder.Entities/Interfaces/ILocationManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/ILocationManager.cs @@ -10,6 +10,7 @@ public interface ILocationManager { Task AddAsync(string name); Task GetAsync(Expression> predicate); - IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); } } \ No newline at end of file diff --git a/src/FlightRecorder.Entities/Interfaces/IManufacturerManager.cs b/src/FlightRecorder.Entities/Interfaces/IManufacturerManager.cs index 993196a..19144a7 100644 --- a/src/FlightRecorder.Entities/Interfaces/IManufacturerManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/IManufacturerManager.cs @@ -10,6 +10,7 @@ public interface IManufacturerManager { Task AddAsync(string name); Task GetAsync(Expression> predicate); - IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); } } \ No newline at end of file diff --git a/src/FlightRecorder.Entities/Interfaces/IModelManager.cs b/src/FlightRecorder.Entities/Interfaces/IModelManager.cs index 4e53151..71558aa 100644 --- a/src/FlightRecorder.Entities/Interfaces/IModelManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/IModelManager.cs @@ -11,6 +11,7 @@ public interface IModelManager Task AddAsync(string name, string manufacturerName); Task GetAsync(Expression> predicate); IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); IAsyncEnumerable ListByManufacturerAsync(string manufacturerName, int pageNumber, int pageSize); } } \ No newline at end of file diff --git a/src/FlightRecorder.Entities/Interfaces/ISightingManager.cs b/src/FlightRecorder.Entities/Interfaces/ISightingManager.cs index 0330fc7..a6e36ee 100644 --- a/src/FlightRecorder.Entities/Interfaces/ISightingManager.cs +++ b/src/FlightRecorder.Entities/Interfaces/ISightingManager.cs @@ -13,6 +13,7 @@ public interface ISightingManager Task AddAsync(FlattenedSighting flattened); Task GetAsync(Expression> predicate); IAsyncEnumerable ListAsync(Expression> predicate, int pageNumber, int pageSize); + Task CountAsync(); Task> ListByAircraftAsync(string registration, int pageNumber, int pageSize); Task> ListByRouteAsync(string embarkation, string destination, int pageNumber, int pageSize); Task> ListByAirlineAsync(string airlineName, int pageNumber, int pageSize); diff --git a/src/FlightRecorder.Mvc/FlightRecorder.Mvc.csproj b/src/FlightRecorder.Mvc/FlightRecorder.Mvc.csproj index ee6f047..2d897f2 100644 --- a/src/FlightRecorder.Mvc/FlightRecorder.Mvc.csproj +++ b/src/FlightRecorder.Mvc/FlightRecorder.Mvc.csproj @@ -2,9 +2,9 @@ net8.0 - 1.10.0.0 - 1.10.0.0 - 1.10.0 + 1.11.0.0 + 1.11.0.0 + 1.11.0 enable false diff --git a/src/FlightRecorder.Mvc/Views/Shared/_Layout.cshtml b/src/FlightRecorder.Mvc/Views/Shared/_Layout.cshtml index 5db3aeb..13d01a8 100644 --- a/src/FlightRecorder.Mvc/Views/Shared/_Layout.cshtml +++ b/src/FlightRecorder.Mvc/Views/Shared/_Layout.cshtml @@ -109,7 +109,7 @@
- © 2020, 2021, 2022, 2023, 2024 - Flight Recorder + © 2020, 2021, 2022, 2023, 2024 - David Walker