This commit is contained in:
parent
6437336228
commit
1469b03c16
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace BlueWest.Collections
|
||||
{
|
||||
|
@ -131,6 +132,15 @@ namespace BlueWest.Collections
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts To a generic List
|
||||
/// </summary>
|
||||
/// <param name="item">Item.</param>
|
||||
public System.Collections.Immutable.ImmutableArray<T> ToList()
|
||||
{
|
||||
return Buffer.ToImmutableArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// if the buffer is at its max more space will be allocated to fit additionalItemCount
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BlueWest.WebApi.Tools
|
||||
namespace BlueWest.Collections
|
||||
{
|
||||
public static class IEnumerableExtensions
|
||||
{
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MapTo" Version="0.9.1" />
|
||||
<PackageReference Include="MapTo" Version="0.9.3" />
|
||||
<PackageReference Include="MessagePack" Version="2.3.85" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="6.0.4" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace BlueWest.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies that the annotated class can be mapped from the provided <see cref="SourceType"/>.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
|
||||
public sealed class AAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MapFromAttribute"/> class with the specified <paramref name="sourceType"/>.
|
||||
/// </summary>
|
||||
/// <param name="sourceType">The type of to map from.</param>
|
||||
public AAttribute(Type sourceType)
|
||||
{
|
||||
SourceType = sourceType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type to map from.
|
||||
/// </summary>
|
||||
public Type SourceType { get; }
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using BlueWest.Collections;
|
||||
using MapTo;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BlueWest.Data
|
||||
{
|
||||
[MessagePackObject]
|
||||
[MapFrom(typeof(UserUpdateDto))]
|
||||
public partial struct User
|
||||
{
|
||||
[Key(1)]public int Id { get; }
|
||||
[Key(2)]public string Name { get; set; }
|
||||
[Key(3)]public string Address { get; set; }
|
||||
|
||||
[Key(4)]public string BTCAddress { get; set; }
|
||||
[Key(5)]public string LTCAddress { get; set; }
|
||||
|
||||
[Key(6)]public double BTCAmount { get; set; }
|
||||
[Key(7)]public double LTCAmount { get; set; }
|
||||
|
||||
[Key(8)] public List<FinanceTransaction> FinanceTransactions { get; set; }
|
||||
|
||||
public User(int id, string name, string address, string btcAddress, string ltcAddress, double btcAmount, double ltcAmount, List<FinanceTransaction> financeTransactions)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
Address = address;
|
||||
BTCAddress = btcAddress;
|
||||
LTCAddress = ltcAddress;
|
||||
BTCAmount = btcAmount;
|
||||
LTCAmount = ltcAmount;
|
||||
FinanceTransactions = financeTransactions;
|
||||
}
|
||||
|
||||
public void AddTransaction(FinanceTransaction financeTransaction)
|
||||
{
|
||||
FinanceTransactions.Add(financeTransaction);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using BlueWest.Collections;
|
||||
using MessagePack;
|
||||
|
||||
namespace BlueWest.Data
|
||||
{
|
||||
[MessagePackObject]
|
||||
public class UserList: DataObject
|
||||
{
|
||||
[Key(9)] public List<User> Users;
|
||||
|
||||
public UserList(List<User> users)
|
||||
{
|
||||
Users = users;
|
||||
}
|
||||
|
||||
[IgnoreMember]
|
||||
public int Length => Users.Count;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BlueWest.Data
|
||||
{
|
||||
class DataQueryResult { }
|
||||
|
||||
internal sealed class PositiveResult<T> : DataQueryResult
|
||||
{
|
||||
public readonly T Value;
|
||||
|
||||
public PositiveResult(T value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal sealed class NegativeResult : DataQueryResult
|
||||
{
|
||||
public readonly string UserMessage;
|
||||
public NegativeResult(string userMessage)
|
||||
{
|
||||
UserMessage = userMessage;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ namespace BlueWest.Data
|
|||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[MapFrom(typeof(FinanceTransactionInsertDto))]
|
||||
public partial struct FinanceTransaction
|
||||
{
|
||||
[Key(1)] public int Id { get; set; }
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using MapTo;
|
||||
|
||||
namespace BlueWest.Data
|
||||
{
|
||||
[MapFrom(typeof(FinanceTransaction))]
|
||||
|
||||
public partial struct FinanceTransactionInsertDto
|
||||
{
|
||||
public int UserId { get; }
|
||||
public FinanceTransactionType FinanceTransactionType { get; }
|
||||
public FinanceSymbol FinanceSymbol { get; }
|
||||
public double Amount { get; } // To Buy
|
||||
public double Quantity { get; } // Bought
|
||||
public double Fee { get; }
|
||||
public DateTime DateTime { get; }
|
||||
|
||||
public FinanceTransactionInsertDto(
|
||||
int userId,
|
||||
FinanceTransactionType financeTransactionType,
|
||||
FinanceSymbol financeSymbol,
|
||||
double amount ,
|
||||
double quantity,
|
||||
double fee,
|
||||
DateTime dateTime)
|
||||
{
|
||||
UserId = userId;
|
||||
FinanceTransactionType = financeTransactionType;
|
||||
FinanceSymbol = financeSymbol;
|
||||
Amount = amount;
|
||||
Quantity = quantity;
|
||||
Fee = fee;
|
||||
DateTime = dateTime;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
using System;
|
||||
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 int Id { get; }
|
||||
[Key(2)] public string Name { get; set; }
|
||||
[Key(3)] public string Address { get; set; }
|
||||
|
||||
[Key(4)] public string BTCAddress { get; set; }
|
||||
[Key(5)] public string LTCAddress { get; set; }
|
||||
|
||||
[Key(6)] public double BTCAmount { get; set; }
|
||||
[Key(7)] public double LTCAmount { get; set; }
|
||||
|
||||
[Key(8)] public FastDictionary<FinanceTransaction> FinanceTransactions { get; set; }
|
||||
|
||||
public User(int id, string name, string address, string btcAddress, string ltcAddress, double btcAmount, double ltcAmount, FastList<FinanceTransaction> financeTransactions)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
Address = address;
|
||||
BTCAddress = btcAddress;
|
||||
LTCAddress = ltcAddress;
|
||||
BTCAmount = btcAmount;
|
||||
LTCAmount = ltcAmount;
|
||||
FinanceTransactions = financeTransactions;
|
||||
}
|
||||
|
||||
public void AddTransaction(FinanceTransaction financeTransaction)
|
||||
{
|
||||
FinanceTransactions.Add(financeTransaction);
|
||||
}
|
||||
public void AddTransaction(FinanceTransactionInsertDto financeTransaction)
|
||||
{
|
||||
FinanceTransactions.Add(new FinanceTransaction(financeTransaction));
|
||||
}
|
||||
|
||||
internal bool HasTransaction(int transactionId)
|
||||
{
|
||||
return FinanceTransactions.Contains(transactionId);
|
||||
}
|
||||
|
||||
internal Transaction GetTransactionById(int transactionId)
|
||||
{
|
||||
return FinanceTransactions(transactionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace BlueWest.Data
|
||||
{
|
||||
public static class UserExtensions
|
||||
{
|
||||
public static bool UserHasTransaction(this User user, int transactionId)
|
||||
{
|
||||
return user.FinanceTransactions.Contains(transactionId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
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<int, User> Users;
|
||||
|
||||
public int Length = 0;
|
||||
|
||||
public UserList(FastDictionary<int, User> users)
|
||||
{
|
||||
Users = users;
|
||||
}
|
||||
|
||||
private int GetIndexById(int userId)
|
||||
{
|
||||
var keys = Users.Keys;
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
if (key == userId) return key;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal DataQueryResult GetUserById(int id)
|
||||
{
|
||||
if (Users.ContainsKey(id)) return new PositiveResult<User>(Users[id]);
|
||||
return new NegativeResult("Can't find a user with the provided id.");
|
||||
}
|
||||
|
||||
internal bool RemoveUser(int userId)
|
||||
{
|
||||
if (Users.ContainsKey(userId))
|
||||
{
|
||||
Users.Remove(userId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool HasUser(int userId)
|
||||
{
|
||||
return Users.Contains(userId);
|
||||
}
|
||||
|
||||
internal DataQueryResult UpdateUser(int userId, UserUpdateDto userUpdate)
|
||||
{
|
||||
Users[userId].Update(userUpdate);
|
||||
return Users[userId];
|
||||
}
|
||||
|
||||
|
||||
internal bool UserHasTransaction(int userId, int transactionId) => HasUser(userId) && Users[userId].FinanceTransactions.Contains(transactionId);
|
||||
|
||||
internal DataQueryResult GetTransactionById(int userId, int transactionId)
|
||||
{
|
||||
if(!HasUser(userId)) return new NegativeResult("Can't find a user with the provided id.");
|
||||
|
||||
if (UserHasTransaction(userId, transactionId)) return new PositiveResult<Transaction>(Users[userId].FinanceTransactions[transactionId]);
|
||||
|
||||
return new NegativeResult("No transaction was found with the specified id");
|
||||
}
|
||||
|
||||
internal 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, id, new FastList<FinanceTransaction>());
|
||||
|
||||
Users.Add(Length, newUser);
|
||||
|
||||
Length++;
|
||||
|
||||
return newUser;
|
||||
}
|
||||
|
||||
const string NoIdError = "No transaction was found with the specified id";
|
||||
|
||||
static NegativeResult NoIdResult = new NegativeResult(NoIdError);
|
||||
internal DataQueryResult AddFinanceTransaction(int userId, FinanceTransactionInsertDto financeTransactionDto)
|
||||
{
|
||||
if (Users.ContainsKey(userId))
|
||||
{
|
||||
var financeTransaction = new FinanceTransaction(financeTransactionDto);
|
||||
Users[userId].AddTransaction(financeTransaction);
|
||||
return new PositiveResult<BlueWest.Data.FinanceTransaction>(financeTransaction);
|
||||
}
|
||||
|
||||
return NoIdResult;
|
||||
}
|
||||
|
||||
|
||||
internal FastList<FinanceTransaction> GetUserTransactions(int userId)
|
||||
{
|
||||
if (Users.ContainsKey(userId))
|
||||
{
|
||||
return Users[userId].FinanceTransactions;
|
||||
}
|
||||
|
||||
return new FastList<FinanceTransaction>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.Net.Client" Version="2.41.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="Protos\greet.proto">
|
||||
<GrpcServices>Both</GrpcServices>
|
||||
<Access>Public</Access>
|
||||
<ProtoCompile>True</ProtoCompile>
|
||||
<CompileOutputs>True</CompileOutputs>
|
||||
<OutputDir>obj\Release\net5.0-windows\</OutputDir>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Protobuf>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using Grpc.Net.Client;
|
||||
|
||||
namespace BlueWest.GrpcClient
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
var channel = GrpcChannel.ForAddress("https://localhost:5001");
|
||||
//var client = new Greet.GreeterClient(channel);
|
||||
Console.WriteLine("Hello, World!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
syntax = "proto3";
|
||||
|
||||
service Greeter {
|
||||
rpc SayHello (HelloRequest) returns (HelloReply);
|
||||
}
|
||||
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message HelloReply {
|
||||
string message = 1;
|
||||
}
|
|
@ -1,18 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>9</LangVersion>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0" />
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="2.41.0" />
|
||||
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.41.0" />
|
||||
<PackageReference Include="Grpc.AspNetCore.Web" Version="2.41.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.12" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BlueWest\BlueWest.csproj" />
|
||||
<Protobuf Include="Protos\greet.proto" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using BlueWest.Data;
|
||||
using BlueWest.WebApi.Tools;
|
||||
using BlueWest.Core.Tests;
|
||||
using BlueWest.Data;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PerformanceSolution.Data;
|
||||
|
@ -10,14 +10,15 @@ namespace BlueWest.WebApi.Controllers
|
|||
[Route("[controller]")]
|
||||
public class UserController : ControllerBase
|
||||
{
|
||||
private UserList _userList => MemoryData.UserList;
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[HttpGet]
|
||||
public ActionResult Get()
|
||||
{
|
||||
if (MemoryData.UserList != null)
|
||||
if (_userList != null)
|
||||
{
|
||||
return Ok(MemoryData.UserList);
|
||||
return Ok(_userList);
|
||||
|
||||
}
|
||||
|
||||
|
@ -30,11 +31,11 @@ namespace BlueWest.WebApi.Controllers
|
|||
[HttpGet("{userId}", Name = nameof(GetUserById))]
|
||||
public ActionResult GetUserById(int userId)
|
||||
{
|
||||
User user = MemoryData.GetUserById(userId);
|
||||
User? user = MemoryData.GetUserById(userId);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
return Ok(user);
|
||||
return Ok(user.Value);
|
||||
|
||||
}
|
||||
|
||||
|
@ -47,14 +48,8 @@ namespace BlueWest.WebApi.Controllers
|
|||
[HttpGet("{userId}/transactions")]
|
||||
public ActionResult GetTransactions(int userId)
|
||||
{
|
||||
var user = MemoryData.GetUserById(userId);
|
||||
var transactions = user.FinanceTransactions;
|
||||
if (transactions != null)
|
||||
{
|
||||
return Ok(transactions);
|
||||
|
||||
}
|
||||
return new NotFoundResult();
|
||||
var transactions = MemoryData.GetUserTransactions(userId);
|
||||
return OK(transactions.ToDictionary());
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +58,7 @@ namespace BlueWest.WebApi.Controllers
|
|||
[HttpGet("{userId}/transactions/{transactionId}")]
|
||||
public ActionResult GetTransactionsById(int userId, int transactionId)
|
||||
{
|
||||
var user = MemoryData.GetUserById(userId);
|
||||
var user = MemoryData.UserList.GetUserById(userId);
|
||||
|
||||
var transactions = user?.FinanceTransactions;
|
||||
|
||||
|
@ -91,7 +86,7 @@ namespace BlueWest.WebApi.Controllers
|
|||
[HttpPut("{userId}")]
|
||||
public ActionResult UpdateUser(int userId, UserUpdateDto userUpdate)
|
||||
{
|
||||
var result = MemoryData.UpdateUser(userId, userUpdate);
|
||||
var result = MemoryData.UserList.UpdateUser(userId, userUpdate);
|
||||
|
||||
if (result != null) return Ok(result);
|
||||
|
||||
|
@ -103,8 +98,7 @@ namespace BlueWest.WebApi.Controllers
|
|||
[HttpDelete("{id}")]
|
||||
public ActionResult DeleteUser(int id)
|
||||
{
|
||||
|
||||
bool result = MemoryData.RemoveUser(id);
|
||||
bool result = MemoryData.UserList.RemoveUser(id);
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
@ -117,9 +111,9 @@ namespace BlueWest.WebApi.Controllers
|
|||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[HttpPost("{userId}/transactions")]
|
||||
public ActionResult PostTransaction(int userId, FinanceTransaction financeTransaction)
|
||||
public ActionResult PostTransaction(int userId, FinanceTransactionInsertDto financeTransaction)
|
||||
{
|
||||
FinanceTransaction? result = MemoryData.AddFinanceTransaction(userId, financeTransaction);
|
||||
FinanceTransaction? result = MemoryData.UserList.AddFinanceTransaction(userId, financeTransaction);
|
||||
|
||||
if(result != null) return Ok(result);
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
syntax = "proto3";
|
||||
|
||||
service Greeter {
|
||||
rpc SayHello (HelloRequest) returns (HelloReply);
|
||||
}
|
||||
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message HelloReply {
|
||||
string message = 1;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BlueWest.WebApi.Service
|
||||
{
|
||||
public class GreeterService : Greeter.GreeterBase
|
||||
{
|
||||
public GreeterService(ILogger<GreeterService> logger)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BlueWest.WebApi.Service;
|
||||
using BlueWest.WebApi.Tools;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -56,6 +57,8 @@ namespace BlueWest.WebApi
|
|||
Version = "v1"
|
||||
});
|
||||
});
|
||||
|
||||
services.AddGrpc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -79,6 +82,8 @@ namespace BlueWest.WebApi
|
|||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapGrpcService<GreeterService>();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlueWest.WebApi", "BlueWest
|
|||
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
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -33,6 +35,10 @@ 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
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -37,13 +37,16 @@ namespace BlueWest.Core
|
|||
return eoDynamic;
|
||||
}
|
||||
|
||||
/*
|
||||
private static T DictionaryToObject<T>(IDictionary<String, Object> dictionary) where T : class
|
||||
{
|
||||
var dicToObj = DictionaryToObject(dictionary);
|
||||
return dicToObj as T;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
public static T ToDto<T>(this object obj) where T: class
|
||||
{
|
||||
var objDic = obj.ToDictionary();
|
||||
|
@ -61,6 +64,6 @@ namespace BlueWest.Core
|
|||
}
|
||||
|
||||
return dataInstance;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
|
@ -13,9 +13,9 @@ namespace BlueWest.Core.Tests
|
|||
private static readonly ConcurrentDictionary<Type, Func<object, IDictionary<string, object>>> Converters = new ConcurrentDictionary<Type, Func<object, IDictionary<string, object>>>();
|
||||
private static readonly ConstructorInfo DictionaryConstructor = typeof(Dictionary<string, object>).GetConstructors().FirstOrDefault(c => c.IsPublic && !c.GetParameters().Any());
|
||||
|
||||
public static IDictionary<string, object> ToDictionary(this object obj) => obj == null ? null : Converters.GetOrAdd(obj.GetType(), o =>
|
||||
public static IDictionary<int, object> ToDictionary(this object obj) => obj == null ? null : Converters.GetOrAdd(obj.GetType(), o =>
|
||||
{
|
||||
var outputType = typeof(IDictionary<string, object>);
|
||||
var outputType = typeof(IDictionary<int, object>);
|
||||
var inputType = obj.GetType();
|
||||
var inputExpression = Expression.Parameter(typeof(object), "input");
|
||||
var typedInputExpression = Expression.Convert(inputExpression, inputType);
|
||||
|
@ -27,14 +27,14 @@ namespace BlueWest.Core.Tests
|
|||
};
|
||||
body.AddRange(
|
||||
from prop in inputType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)
|
||||
where prop.CanRead && (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string))
|
||||
where prop.CanRead && (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(int))
|
||||
let getExpression = Expression.Property(typedInputExpression, prop.GetMethod)
|
||||
let convertExpression = Expression.Convert(getExpression, typeof(object))
|
||||
select Expression.Call(outputVariable, AddToDicitonaryMethod, Expression.Constant(prop.Name), convertExpression));
|
||||
body.Add(Expression.Return(returnTarget, outputVariable));
|
||||
body.Add(Expression.Label(returnTarget, Expression.Constant(null, outputType)));
|
||||
|
||||
var lambdaExpression = Expression.Lambda<Func<object, IDictionary<string, object>>>(
|
||||
var lambdaExpression = Expression.Lambda<Func<object, IDictionary<int, object>>>(
|
||||
Expression.Block(new[] { outputVariable }, body),
|
||||
inputExpression);
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
using BlueWest.Collections;
|
||||
using BlueWest.Core;
|
||||
using BlueWest.Data;
|
||||
using PerformanceSolution.Tools;
|
||||
|
||||
|
@ -11,7 +9,7 @@ namespace PerformanceSolution.Data
|
|||
{
|
||||
public static class MemoryData
|
||||
{
|
||||
public static UserList UserList = new UserList(new List<User>());
|
||||
public static UserList UserList = new UserList(new FastDictionary<int, User>());
|
||||
|
||||
private const string SavePathName = "userData";
|
||||
|
||||
|
@ -37,119 +35,44 @@ namespace PerformanceSolution.Data
|
|||
public static void LoadUsers()
|
||||
{
|
||||
UserList = SaveLoadManager.Load<UserList>(SavePathName);
|
||||
UserList ??= new UserList(new List<User>());
|
||||
UserList ??= new UserList(new FastDictionary<int, User>());
|
||||
}
|
||||
|
||||
public static User? GetUserById(int id)
|
||||
{
|
||||
var user = UserList.Users.FirstOrDefault(user => user.Id == id);
|
||||
//var d = new UserUpdateDto(user);
|
||||
return user;
|
||||
}
|
||||
public static Transaction GetTransactionById(int userId, int transactionId) => UserList.GetTransactionById(userId, transactionId);
|
||||
|
||||
public static bool RemoveUser(int userId)
|
||||
{
|
||||
int index = GetIndexById(userId);
|
||||
if (index == -1) return false;
|
||||
UserList.Users.RemoveAt(index);
|
||||
SaveUserList();
|
||||
return true;
|
||||
}
|
||||
public static async Task AddUserAsync(User user) => await Task.Run(() => { AddOrModifyUser(user); });
|
||||
|
||||
private static int GetIndexById(int userId) => UserList.Users.FindIndex(row => row.Id == userId);
|
||||
|
||||
private static void SaveUserList() => SaveUserList(UserList);
|
||||
|
||||
public static void AddOrModifyUser(User user)
|
||||
public static User AddOrModifyUser(UserUpdateDto userUpdateDto, int userId = -1)
|
||||
{
|
||||
var index = GetIndexById(user.Id);
|
||||
if (index != -1)
|
||||
{
|
||||
UserList.Users[index] = user;
|
||||
SaveUserList();
|
||||
}
|
||||
else
|
||||
{
|
||||
UserList.Users.Add(user);
|
||||
SaveUserList();
|
||||
}
|
||||
}
|
||||
|
||||
public static User? AddOrModifyUser(UserUpdateDto userUpdateDto, int userId = -1)
|
||||
{
|
||||
var id = userId != -1 ? userId : UserList.Length + 1;
|
||||
|
||||
var index = GetIndexById(userId);
|
||||
|
||||
User? user;
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
user = GetUserById(id);
|
||||
|
||||
if (user == null) return user;
|
||||
|
||||
UserList.Users[index] = user;
|
||||
|
||||
SaveUserList();
|
||||
}
|
||||
else
|
||||
{
|
||||
user = new User(userUpdateDto);
|
||||
|
||||
UserList.Users.Add(user);
|
||||
SaveUserList();
|
||||
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
public static User? UpdateUser(int userId, UserUpdateDto userUpdate)
|
||||
{
|
||||
var index = GetIndexById(userId);
|
||||
|
||||
if (index == -1) return null;
|
||||
|
||||
var actualUser = GetUserById(userId);
|
||||
|
||||
if (actualUser == null) return null;
|
||||
|
||||
actualUser.Update(userUpdate);
|
||||
|
||||
UserList.Users[index] = actualUser;
|
||||
|
||||
SaveUserList();
|
||||
|
||||
return actualUser;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static FinanceTransaction? AddFinanceTransaction(int userId, FinanceTransaction financeTransaction)
|
||||
{
|
||||
var user = GetUserById(userId);
|
||||
|
||||
if (user == null) return null;
|
||||
|
||||
user.AddTransaction(financeTransaction);
|
||||
|
||||
SaveUserList();
|
||||
|
||||
return financeTransaction;
|
||||
return UserList.AddUser(userId, userUpdateDto);
|
||||
|
||||
}
|
||||
|
||||
private static UserList GenerateMockData()
|
||||
{
|
||||
var u = new User(1, "Rui Sousa", "Sagres", "NOADD", "NOADD", 0 , 0, new List<FinanceTransaction>()
|
||||
{
|
||||
new FinanceTransaction(0, 1, FinanceTransactionType.Buy, FinanceSymbol.BTC_EUR, 0, 0, 0.1, DateTime.Now)
|
||||
});
|
||||
var list = new List<User>(10);
|
||||
list.Add(u);
|
||||
|
||||
|
||||
var transactions = new FastList<FinanceTransaction>();
|
||||
var financeTransaction = new FinanceTransaction(0, 1, FinanceTransactionType.Buy, FinanceSymbol.BTC_EUR, 0,
|
||||
0, 0.1, DateTime.Now);
|
||||
transactions.Add(financeTransaction);
|
||||
|
||||
var u = new User(1, "Rui Sousa", "Sagres", "NOADD", "NOADD", 0, 0, transactions);
|
||||
var list = new FastDictionary<int, User>(10);
|
||||
list.Add(0, u);
|
||||
|
||||
return new UserList(list);
|
||||
}
|
||||
|
||||
public static User? GetUserById(int userId)
|
||||
{
|
||||
return UserList.GetUserById(userId);
|
||||
}
|
||||
|
||||
public static FastList<FinanceTransaction> GetUserTransactions(int userId)
|
||||
{
|
||||
return UserList.GetUserTransactions(userId);
|
||||
}
|
||||
}
|
||||
}
|
2
MapTo
2
MapTo
|
@ -1 +1 @@
|
|||
Subproject commit 63b2bcb3593440fb332917bed7d6c78827195dbe
|
||||
Subproject commit 9470afb737d873f2fbbc631813eadf10032c5c6b
|
Loading…
Reference in New Issue