diff --git a/BlueWest.Api/Controllers/UserController.cs b/BlueWest.Api/Controllers/UserController.cs index a980d57..7ad3c8c 100644 --- a/BlueWest.Api/Controllers/UserController.cs +++ b/BlueWest.Api/Controllers/UserController.cs @@ -1,10 +1,12 @@ using System; +using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using BlueWest.Collections; using BlueWest.Data; +using BlueWest.WebApi.MySQL; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using PerformanceSolution.Data; namespace BlueWest.WebApi.Controllers { @@ -12,33 +14,37 @@ namespace BlueWest.WebApi.Controllers [Route("[controller]")] public class UserController : ControllerBase { - private UserList _userList => MemoryData.UserList; + private readonly MysqlDbContext _dbContext; + + public UserController(MysqlDbContext dbContext) + { + _dbContext = dbContext; + } + [ProducesResponseType(StatusCodes.Status200OK)] [HttpGet] public ActionResult Get() { - if (_userList != null) - { - return Ok(_userList.Users.Values.ToImmutableArray()); - } + var users = _dbContext.Users.ToImmutableArray(); + + return Ok(users); - return new NotFoundResult(); } [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [HttpGet("{userId}", Name = nameof(GetUserById))] - public ActionResult GetUserById(int userId) + public ActionResult GetUserById(TimeSpan userId) { - var user = MemoryData.GetUserById(userId); - - if (user.Id != TimeSpan.Zero) + var user = _dbContext.Users.FirstOrDefault(x => x.Id == userId); + + if (user != null) { return Ok(user); } - + return new NotFoundResult(); } @@ -48,8 +54,7 @@ namespace BlueWest.WebApi.Controllers [HttpGet("{userId}/transactions")] public ActionResult GetTransactions(int userId) { - var transactions = MemoryData.GetUserTransactions(userId); - return Ok(transactions); + return Ok(); } @@ -58,28 +63,17 @@ namespace BlueWest.WebApi.Controllers [HttpGet("{userId}/transactions/{transactionId}")] public ActionResult GetTransactionsById(int userId, TimeSpan transactionId) { - var user = MemoryData.UserList.GetUserById(userId); - - if(user.Id == TimeSpan.Zero) return new NotFoundResult(); - - var transactions = user.FinanceTransactions; - - FinanceTransaction? transaction = transactions?.Values.ToImmutableArray().FirstOrNull(t => t.CreationDate == transactionId); - - if (transaction != null) - { - return Ok(transaction); - } - return new NotFoundResult(); } [ProducesResponseType(StatusCodes.Status201Created)] [HttpPost] - public ActionResult AddOrModifyUser(UserUpdateDto userUpdateDto) + public ActionResult AddUser(UserUpdateDto userUpdateDto) { - var user = MemoryData.AddOrModifyUser(userUpdateDto); + var user = new User(userUpdateDto, DateTime.Now.TimeOfDay, new List()); + _dbContext.Users.Add(user); + _dbContext.SaveChanges(); return CreatedAtRoute(nameof(GetUserById), new {userId = user.Id}, user); } @@ -88,26 +82,23 @@ namespace BlueWest.WebApi.Controllers [HttpPut("{userId}")] public ActionResult UpdateUser(int userId, UserUpdateDto userUpdate) { - var result = MemoryData.UserList.UpdateUser(userId, userUpdate); - - if (result != null) return Ok(result); - - return BadRequest(); + + return new NotFoundResult(); } [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [HttpDelete("{id}")] - public ActionResult DeleteUser(int id) + public ActionResult DeleteUser(TimeSpan id) { - bool result = MemoryData.UserList.RemoveUser(id); - - if (result) + var user = _dbContext.Users.FirstOrDefault(u => u.Id == id); + if (user == null) { - return NoContent(); + return new NotFoundResult(); } - - return new BadRequestResult(); + _dbContext.Users.Remove(user); + _dbContext.SaveChanges(); + return Ok(); } [ProducesResponseType(StatusCodes.Status200OK)] @@ -115,10 +106,6 @@ namespace BlueWest.WebApi.Controllers [HttpPost("{userId}/transactions")] public ActionResult PostTransaction(int userId, FinanceTransactionInsertDto financeTransaction) { - FinanceTransaction result = MemoryData.UserList.AddFinanceTransaction(userId, financeTransaction); - - if(result.UserId != TimeSpan.Zero) return Ok(result); - return new BadRequestResult(); } diff --git a/BlueWest.Api/MySQL/MysqlDbContext.cs b/BlueWest.Api/MySQL/MysqlDbContext.cs new file mode 100644 index 0000000..d6a9a34 --- /dev/null +++ b/BlueWest.Api/MySQL/MysqlDbContext.cs @@ -0,0 +1,45 @@ +using System; +using BlueWest.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; + +namespace BlueWest.WebApi.MySQL; + +public sealed class MysqlDbContext : DbContext +{ + public DbSet Users { get; set; } + public DbSet Transactions { get; set; } + public IConfiguration Configuration; + + + public MysqlDbContext(DbContextOptions options) : base(options) + { + Database.EnsureCreated(); + + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + /*optionsBuilder.UseMySql( + Configuration.GetConnectionString("LocalMySQL"), + new MySqlServerVersion(new Version(8, 0, 11)) + );*/ + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity(builder => + { + builder.HasKey(x => x.Id); + }); + + modelBuilder.Entity(builder => + { + builder.HasOne() + .WithMany(x => x.FinanceTransactions) + .HasForeignKey(x => x.UserId); + }); + + } +} \ No newline at end of file diff --git a/BlueWest.Api/Startup.cs b/BlueWest.Api/Startup.cs index 099f167..cbcfbb5 100644 --- a/BlueWest.Api/Startup.cs +++ b/BlueWest.Api/Startup.cs @@ -10,8 +10,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using BlueWest.WebApi.MySQL; using BlueWest.WebApi.Service; using BlueWest.WebApi.Tools; +using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -57,7 +59,8 @@ namespace BlueWest.WebApi Version = "v1" }); }); - + services.AddDbContextPool(options => + options.UseMySql(Configuration.GetConnectionString("LocalMySQL"), new MySqlServerVersion(new Version(8, 0, 11)))); services.AddGrpc(); } diff --git a/BlueWest.Api/WeatherForecast.cs b/BlueWest.Api/WeatherForecast.cs deleted file mode 100644 index 28d7564..0000000 --- a/BlueWest.Api/WeatherForecast.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace BlueWest.WebApi -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string Summary { get; set; } - } -} diff --git a/BlueWest.Api/appsettings.json b/BlueWest.Api/appsettings.json index d9d9a9b..cadbc89 100644 --- a/BlueWest.Api/appsettings.json +++ b/BlueWest.Api/appsettings.json @@ -6,5 +6,8 @@ "Microsoft.Hosting.Lifetime": "Information" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "ConnectionStrings": { + "LocalMySQL": "server=127.0.0.1;user=blueuser;password=JwuWxhWxhh$X1;database=bluedb;" + } } diff --git a/BlueWest.Collections/IEnumerableExtensions.cs b/BlueWest.Collections/IEnumerableExtensions.cs index 6ebf99f..268776a 100644 --- a/BlueWest.Collections/IEnumerableExtensions.cs +++ b/BlueWest.Collections/IEnumerableExtensions.cs @@ -23,10 +23,13 @@ namespace BlueWest.Collections return null; } - public static TSource? FirstOrNull(this IEnumerable source, Func predicate) where TSource : struct => - source.TryGetFirst(predicate); + public static TSource FirstOrNullRef(this IEnumerable source, Func predicate) where TSource : class => + source.TryGetFirstClass(predicate); - private static TSource? TryGetFirst(this IEnumerable source, Func predicate) where TSource : struct + public static TSource? FirstOrNullStruct(this IEnumerable source, Func predicate) where TSource : struct => + source.TryGetFirstStruct(predicate); + + private static TSource? TryGetFirstStruct(this IEnumerable source, Func predicate) where TSource : struct { foreach (TSource obj in source) { @@ -37,7 +40,18 @@ namespace BlueWest.Collections } return null; } - + private static TSource TryGetFirstClass(this IEnumerable source, Func predicate) where TSource : class + { + foreach (TSource obj in source) + { + if (predicate(obj)) + { + return obj; + } + } + return null; + } + } } \ No newline at end of file diff --git a/BlueWest.Data/BlueWest.Data.csproj b/BlueWest.Data/BlueWest.Data.csproj index 89effba..86cdb70 100644 --- a/BlueWest.Data/BlueWest.Data.csproj +++ b/BlueWest.Data/BlueWest.Data.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net6.0 true BlueWest.Data preview @@ -9,7 +9,6 @@ - diff --git a/BlueWest.Data/Core/DataObject.cs b/BlueWest.Data/Core/DataObject.cs deleted file mode 100644 index b21262d..0000000 --- a/BlueWest.Data/Core/DataObject.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Newtonsoft.Json; - -namespace BlueWest.Data -{ - public class DataObject - { - public override string ToString() - { - return JsonConvert.SerializeObject(this, Formatting.Indented); - } - } -} \ No newline at end of file diff --git a/BlueWest.Data/Finance/FinanceTransaction.cs b/BlueWest.Data/Finance/FinanceTransaction.cs index c8222ae..dcb2740 100644 --- a/BlueWest.Data/Finance/FinanceTransaction.cs +++ b/BlueWest.Data/Finance/FinanceTransaction.cs @@ -1,24 +1,27 @@ using System; +using System.ComponentModel.DataAnnotations; using MapTo; -using MessagePack; namespace BlueWest.Data { - [MessagePackObject] [MapFrom(typeof(FinanceTransactionInsertDto))] - public partial struct FinanceTransaction + public partial class FinanceTransaction { - [Key(1)] public TimeSpan CreationDate { get; set; } - [Key(2)] public TimeSpan UserId { get; set; } + [Key] public TimeSpan CreationDate { get; set; } + public TimeSpan UserId { get; set; } - [Key(4)] public string Currency { get; } - [Key(5)] public double Amount { get; } // To Buy - [Key(6)] public double Quantity { get; } // Bought - [Key(7)] public double Fee { get; } - [Key(8)] public TimeSpan UploadedDate { get; } - [Key(9)] public TimeSpan TransactionDate { get; } + public string Currency { get; } + public double Amount { get; } // To Buy + public double Quantity { get; } // Bought + public double Fee { get; } + public TimeSpan UploadedDate { get; } + public TimeSpan TransactionDate { get; } + public FinanceTransaction() + { + + } public FinanceTransaction(TimeSpan creationDate, TimeSpan userId, string currency, double amount, double quantity, double fee, TimeSpan uploadedDate, TimeSpan transactionDate) diff --git a/BlueWest.Data/Finance/FinanceTransactionInsertDto.cs b/BlueWest.Data/Finance/FinanceTransactionInsertDto.cs index d8a83cf..88e2357 100644 --- a/BlueWest.Data/Finance/FinanceTransactionInsertDto.cs +++ b/BlueWest.Data/Finance/FinanceTransactionInsertDto.cs @@ -7,7 +7,7 @@ namespace BlueWest.Data { [MapFrom(typeof(FinanceTransaction))] - public partial struct FinanceTransactionInsertDto + public partial class FinanceTransactionInsertDto { public string Currency { get; } public double Amount { get; } // To Buy diff --git a/BlueWest.Data/Finance/FinanceTransactionReadDto.cs b/BlueWest.Data/Finance/FinanceTransactionReadDto.cs index b292f8b..23c3e5a 100644 --- a/BlueWest.Data/Finance/FinanceTransactionReadDto.cs +++ b/BlueWest.Data/Finance/FinanceTransactionReadDto.cs @@ -7,7 +7,7 @@ namespace BlueWest.Data { [MapFrom(typeof(FinanceTransaction))] - public partial struct FinanceTransactionReadDto + public partial class FinanceTransactionReadDto { public TimeSpan CreationDate { get; set; } public TimeSpan UserId { get; set; } diff --git a/BlueWest.Data/User/User.cs b/BlueWest.Data/User/User.cs index f9366bd..e8030df 100644 --- a/BlueWest.Data/User/User.cs +++ b/BlueWest.Data/User/User.cs @@ -4,54 +4,31 @@ using System.Collections.Generic; using System.Transactions; using BlueWest.Collections; using MapTo; -using MessagePack; -using Newtonsoft.Json; using BlueWest.Collections; namespace BlueWest.Data { - [MessagePackObject] [UseUpdate] [MapFrom(typeof(UserUpdateDto))] public partial class User { - [Key(1)] public TimeSpan Id { get; } = TimeSpan.Zero; - [Key(2)] public string Name { get; set; } + public TimeSpan Id { get; } = TimeSpan.Zero; + public string Name { get; set; } + public List FinanceTransactions { get; } - [Key(8)] public FastDictionary FinanceTransactions { get; } - - public User(TimeSpan id, string name, FastDictionary financeTransactions) + + public User(TimeSpan id, string name) { Id = id; Name = name; - FinanceTransactions = financeTransactions; } public User() { } - - public void AddTransaction(FinanceTransaction financeTransaction) - { - FinanceTransactions.Add(FinanceTransactions.Count + 1, financeTransaction); - } - public void AddTransaction(FinanceTransactionInsertDto financeTransaction) - { - FinanceTransactions.Add(FinanceTransactions.Count + 1, - new FinanceTransaction(financeTransaction, TimeSpan.FromTicks(DateTime.Now.Ticks), Id)); - } - - internal bool HasTransaction(int transactionId) - { - return FinanceTransactions.Contains(transactionId); - } - - internal FinanceTransaction GetTransactionById(int transactionId) - { - return FinanceTransactions[transactionId]; - } + } } diff --git a/BlueWest.Data/UserExtensions.cs b/BlueWest.Data/UserExtensions.cs index 186c7a8..0c8b953 100644 --- a/BlueWest.Data/UserExtensions.cs +++ b/BlueWest.Data/UserExtensions.cs @@ -6,9 +6,6 @@ namespace BlueWest.Data { public static class UserExtensions { - public static bool UserHasTransaction(this User user, int transactionId) - { - return user.FinanceTransactions.Contains(transactionId); - } + } } diff --git a/BlueWest.Data/UserList.cs b/BlueWest.Data/UserList.cs index 7050ae4..5f28270 100644 --- a/BlueWest.Data/UserList.cs +++ b/BlueWest.Data/UserList.cs @@ -1,125 +1 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Transactions; -using BlueWest.Collections; -using MessagePack; - -namespace BlueWest.Data -{ - [MessagePackObject] - public class UserList: DataObject - { - [Key(9)] public readonly FastDictionary Users; - - [IgnoreMember] public int Length = 0; - - public UserList(FastDictionary users) - { - Users = users; - } - - private int GetIndexById(int userId) - { - var keys = Users.Keys; - - foreach (var key in keys) - { - if (key == userId) return key; - } - - return -1; - } - - public User GetUserById(int id) - { - if (Users.ContainsKey(id)) return Users[id]; - return new User(); - } - - public bool RemoveUser(int userId) - { - if (Users.ContainsKey(userId)) - { - Users.Remove(userId); - return true; - } - - return false; - } - - internal bool HasUser(int userId) - { - return Users.Contains(userId); - } - - public User UpdateUser(int userId, UserUpdateDto userUpdate) - { - if (Users.ContainsKey(userId)) - { - Users[userId].Update(userUpdate); - return Users[userId]; - } - - return new User(); - } - - - internal bool UserHasTransaction(int userId, int transactionId) => HasUser(userId) && Users[userId].FinanceTransactions.Contains(transactionId); - - public FinanceTransaction GetTransactionById(int userId, int transactionId) - { - if(!HasUser(userId)) return new FinanceTransaction(); - - if (UserHasTransaction(userId, transactionId)) return Users[userId].FinanceTransactions[transactionId]; - - return new FinanceTransaction(); - } - - public User AddUser(int userId, UserUpdateDto userUpdateDto) - { - if (Users.ContainsKey(userId)) - { - Users[userId].Update(userUpdateDto); - return Users[userId]; - } - - var id = userId != -1 ? userId : Length + 1; - - var newUser = new User(userUpdateDto, DateTime.Now.TimeOfDay, new FastDictionary()); - - Users.Add(Length, newUser); - - Length++; - - return newUser; - } - - const string NoIdError = "No transaction was found with the specified id"; - - public FinanceTransaction AddFinanceTransaction(int userId, FinanceTransactionInsertDto financeTransactionDto) - { - if (Users.ContainsKey(userId)) - { - var now = TimeSpan.FromTicks(DateTime.Now.Ticks); - var financeTransaction = new FinanceTransaction(financeTransactionDto, now, Users[userId].Id); - Users[userId].AddTransaction(financeTransaction); - return financeTransaction; - } - - return new FinanceTransaction(); - } - - - public ImmutableArray GetUserTransactions(int userId) - { - if (Users.ContainsKey(userId)) - { - return Users[userId].FinanceTransactions.Values.ToImmutableArray(); - } - - return new ImmutableArray(); - } - - } -} \ No newline at end of file + \ No newline at end of file diff --git a/BlueWest.sln b/BlueWest.sln index c1a3a48..9de9c6e 100644 --- a/BlueWest.sln +++ b/BlueWest.sln @@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlueWest.Api", "BlueWest.Ap EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlueWest.Collections", "BlueWest.Collections\BlueWest.Collections.csproj", "{F55019A2-E2A8-4AF1-8FBC-FA99476A1B1C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlueWest.GrpcClient", "BlueWest.GrpcClient\BlueWest.GrpcClient.csproj", "{65A6A17A-EFFB-4750-8B80-3B0690CCA59F}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlueWest.MapTo", "include\MapTo\src\BlueWest.MapTo\BlueWest.MapTo.csproj", "{72B37540-A12F-466E-A58F-7BA2B247CB74}" EndProject Global @@ -37,10 +35,6 @@ Global {F55019A2-E2A8-4AF1-8FBC-FA99476A1B1C}.Debug|Any CPU.Build.0 = Debug|Any CPU {F55019A2-E2A8-4AF1-8FBC-FA99476A1B1C}.Release|Any CPU.ActiveCfg = Release|Any CPU {F55019A2-E2A8-4AF1-8FBC-FA99476A1B1C}.Release|Any CPU.Build.0 = Release|Any CPU - {65A6A17A-EFFB-4750-8B80-3B0690CCA59F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {65A6A17A-EFFB-4750-8B80-3B0690CCA59F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {65A6A17A-EFFB-4750-8B80-3B0690CCA59F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {65A6A17A-EFFB-4750-8B80-3B0690CCA59F}.Release|Any CPU.Build.0 = Release|Any CPU {72B37540-A12F-466E-A58F-7BA2B247CB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {72B37540-A12F-466E-A58F-7BA2B247CB74}.Debug|Any CPU.Build.0 = Debug|Any CPU {72B37540-A12F-466E-A58F-7BA2B247CB74}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/BlueWest/Artefacts/AccountArtefact.cs b/BlueWest/Artefacts/AccountArtefact.cs index 6e18bc9..1b0ab59 100644 --- a/BlueWest/Artefacts/AccountArtefact.cs +++ b/BlueWest/Artefacts/AccountArtefact.cs @@ -1,7 +1,6 @@ using System; using BlueWest.Core.ComponentSystem; using BlueWest.Tools; -using PerformanceSolution.Data; namespace PerformanceSolution.Artefacts { @@ -38,22 +37,22 @@ namespace PerformanceSolution.Artefacts private void GetAllUsersInConsole() { - var data = MemoryData.UserList; + /*var data = MemoryData.UserList; if (data != null) { Console.WriteLine(MemoryData.UserList.ToString()); - } + }*/ } private void GetUserByIdInConsole(int id) { - var user = MemoryData.GetUserById(id); + /*var user = MemoryData.GetUserById(id); if (user != null) { Console.WriteLine(user.ToString()); - } + }*/ } public void OnEvent(CommandRequestEvent commandRequestEvent) diff --git a/BlueWest/Data/MemoryData.cs b/BlueWest/Data/MemoryData.cs index fd1790f..5f28270 100644 --- a/BlueWest/Data/MemoryData.cs +++ b/BlueWest/Data/MemoryData.cs @@ -1,78 +1 @@ -using System; -using System.Collections.Immutable; -using BlueWest.Collections; -using BlueWest.Data; -using PerformanceSolution.Tools; - -namespace PerformanceSolution.Data -{ - public static class MemoryData - { - public static UserList UserList = new UserList(new FastDictionary()); - - private const string SavePathName = "userData"; - - public static TimeSpan DateKey = new TimeSpan(2386, 0,0,0,0 ); - - private static bool DEBUG = true; - - static MemoryData() - { - if (DEBUG) - { - UserList = GenerateMockData(); - //SaveUserList(); - } - - //LoadUsers(); - } - - public static void SaveUserList(UserList userList) - { - //UserList = userList; - //SaveLoadManager.Save(UserList, SavePathName); - } - - public static void LoadUsers() - { - UserList = SaveLoadManager.Load(SavePathName); - UserList ??= new UserList(new FastDictionary()); - } - - public static FinanceTransaction GetTransactionById(int userId, int transactionId) => UserList.GetTransactionById(userId, transactionId); - - private static void SaveUserList() => SaveUserList(UserList); - - public static User AddOrModifyUser(UserUpdateDto userUpdateDto, int userId = -1) - { - return UserList.AddUser(userId, userUpdateDto); - } - - private static UserList GenerateMockData() - { - - - var transactions = new FastDictionary(); - - var u = new User(DateTime.Now.TimeOfDay, "Benny", transactions); - var list = new FastDictionary(10); - var financeTransaction = new FinanceTransaction(TimeSpan.FromTicks(DateTime.Now.Ticks), u.Id, "", 0.00, 0.00, 0.00, - TimeSpan.FromTicks(DateTime.Now.Ticks), TimeSpan.FromTicks(DateTime.Now.Ticks)); - transactions.Add(1, financeTransaction); - - list.Add(0, u); - - return new UserList(list); - } - - public static User GetUserById(int userId) - { - return UserList.GetUserById(userId); - } - - public static ImmutableArray GetUserTransactions(int userId) - { - return UserList.GetUserTransactions(userId); - } - } -} \ No newline at end of file + \ No newline at end of file