diff --git a/database/mistox.sql b/database/mistox.sql index 59032b3..2d08131 100755 --- a/database/mistox.sql +++ b/database/mistox.sql @@ -206,10 +206,7 @@ FIELDS TERMINATED BY '\t' ENCLOSED BY '"' LINES TERMINATED BY '\n'; -CREATE INDEX idx_country_code ON PostalCodes(CountryCode); -CREATE INDEX idx_postal_code ON PostalCodes(PostalCode); -CREATE INDEX idx_latitude ON PostalCodes(Latitude); -CREATE INDEX idx_longitude ON PostalCodes(Longitude); +CREATE INDEX idx_postal_country ON PostalCodes (City, PostalCode, CountryCode, Latitude, Longitude); -- Application Section diff --git a/src/Server/Controllers/LocationController.cs b/src/Server/Controllers/LocationController.cs new file mode 100644 index 0000000..e855975 --- /dev/null +++ b/src/Server/Controllers/LocationController.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc; +using BoredCareers.Services.DatabaseService; +using BoredCareers.Entities; +using BoredCareers.Services; + +namespace BoredCareers.Controllers { + [ApiController] + [Route("api/location")] + public class LocationController : MistoxControllerBase { + + public LocationController(DatabaseService db, EmailService emailContext) : base(db) {} + + [HttpGet] + public async Task GetCompany(string PostalCode, string CountryCode, float MaxDistanceKm) { + if (isLoggedIn()) { + + Location? MyZIP = await _databaseService.GetLocation(PostalCode, CountryCode); + if (MyZIP != null) { + Location[] places = await _databaseService.GetNearbyLocations(MyZIP.Latitude, MyZIP.Longitude, MyZIP.CountryCode, MaxDistanceKm); + return Ok(places.ToArray()); + } + return NotFound("Postal + CountryCode not found"); + } + return NotFound("Not logged in"); + } + + } +} diff --git a/src/Server/Entities/Location.cs b/src/Server/Entities/Location.cs new file mode 100644 index 0000000..0fa6711 --- /dev/null +++ b/src/Server/Entities/Location.cs @@ -0,0 +1,10 @@ +namespace BoredCareers.Entities { + public class Location { + public string City { get; set; } = ""; + public string PostalCode { get; set; } = ""; + public string CountryCode { get; set; } = ""; + public float Latitude { get; set; } + public float Longitude { get; set; } + public float DistanceKM { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/Services/DatabaseService/Location.cs b/src/Server/Services/DatabaseService/Location.cs new file mode 100644 index 0000000..467d00b --- /dev/null +++ b/src/Server/Services/DatabaseService/Location.cs @@ -0,0 +1,95 @@ +using BoredCareers.Entities; +using MySql.Data.MySqlClient; +using System.Data; +using System.Data.Common; +using System.Text; + +namespace BoredCareers.Services.DatabaseService { + public partial class DatabaseService { + + public async Task GetLocation(string PostalCode, string CountryCode) { + using (MySqlConnection connection = GetConnection()) { + await connection.OpenAsync(); + string command = @" + SELECT PostalCode, CountryCode, Latitude, Longitude, City + FROM PostalCodes + WHERE PostalCode = @PostalCode + AND CountryCode = @CountryCode; + "; + + MySqlCommand cmd = new MySqlCommand(command, connection); + cmd.Parameters.AddWithValue("@PostalCode", PostalCode); + cmd.Parameters.AddWithValue("@CountryCode", CountryCode); + + using (DbDataReader reader = await cmd.ExecuteReaderAsync()) { + while (await reader.ReadAsync()) { + string _city = reader.GetString("City"); + string _postalCode = reader.GetString("PostalCode"); + string _countryCode = reader.GetString("CountryCode"); + float _latitude = reader.GetFloat("Latitude"); + float _longitude = reader.GetFloat("Longitude"); + + return new Location() { + City = _city, + PostalCode = _postalCode, + CountryCode = _countryCode, + Latitude = _latitude, + Longitude = _longitude + }; + } + } + } + return null; + } + + public async Task GetNearbyLocations(float Latitude, float Longitude, string CountryCode, float MaxDistanceKm) { + List closePostalCodes = new List(); + using (MySqlConnection connection = GetConnection()) { + await connection.OpenAsync(); + string command = @" + SELECT PostalCode, CountryCode, Latitude, Longitude, City, ( + 6371 * acos( + cos(radians(@Latitude)) * + cos(radians(Latitude)) * + cos(radians(Longitude) - radians(@Longitude)) + + sin(radians(@Latitude)) * + sin(radians(Latitude)) + ) + ) AS distance_km + FROM PostalCodes + WHERE countrycode = @CountryCode + HAVING distance_km <= @MaxDistanceKm + ORDER BY distance_km; + "; + + MySqlCommand cmd = new MySqlCommand(command, connection); + cmd.Parameters.AddWithValue("@Latitude", Latitude); + cmd.Parameters.AddWithValue("@Longitude", Longitude); + cmd.Parameters.AddWithValue("@CountryCode", CountryCode); + cmd.Parameters.AddWithValue("@MaxDistanceKm", MaxDistanceKm); + + using (DbDataReader reader = await cmd.ExecuteReaderAsync()) { + while (await reader.ReadAsync()) { + string _city = reader.GetString("City"); + string _postalCode = reader.GetString("PostalCode"); + string _countryCode = reader.GetString("CountryCode"); + float _latitude = reader.GetFloat("Latitude"); + float _longitude = reader.GetFloat("Longitude"); + float _distanceKm = reader.GetFloat("distance_km"); + + closePostalCodes.Add(new Location() { + City = _city, + PostalCode = _postalCode, + CountryCode = _countryCode, + Latitude = _latitude, + Longitude = _longitude, + DistanceKM = _distanceKm + }); + } + } + } + return closePostalCodes.ToArray(); + } + + } +}