This commit is contained in:
parent
41accac4f7
commit
f999e96b6f
|
@ -4,25 +4,32 @@ using System.Text;
|
||||||
|
|
||||||
namespace BlueWest.Data
|
namespace BlueWest.Data
|
||||||
{
|
{
|
||||||
class DataQueryResult { }
|
public sealed class DataQueryResult<T>
|
||||||
|
|
||||||
internal sealed class PositiveResult<T> : DataQueryResult
|
|
||||||
{
|
{
|
||||||
public readonly T Value;
|
public readonly T Value;
|
||||||
|
public bool HasValue;
|
||||||
|
public string Message;
|
||||||
|
|
||||||
public PositiveResult(T value)
|
public DataQueryResult(T value, bool success = true, string message = "")
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
|
HasValue = success;
|
||||||
|
Message = message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal sealed class DataQueryResult
|
||||||
|
|
||||||
internal sealed class NegativeResult : DataQueryResult
|
|
||||||
{
|
{
|
||||||
public readonly string UserMessage;
|
public readonly object Value;
|
||||||
public NegativeResult(string userMessage)
|
public bool HasValue;
|
||||||
|
public string Message;
|
||||||
|
|
||||||
|
public DataQueryResult(object value, bool success = true, string message = "")
|
||||||
{
|
{
|
||||||
UserMessage = userMessage;
|
Value = value;
|
||||||
|
HasValue = success;
|
||||||
|
Message = message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,9 @@ namespace BlueWest.Data
|
||||||
[Key(6)] public double BTCAmount { get; set; }
|
[Key(6)] public double BTCAmount { get; set; }
|
||||||
[Key(7)] public double LTCAmount { get; set; }
|
[Key(7)] public double LTCAmount { get; set; }
|
||||||
|
|
||||||
[Key(8)] public FastDictionary<FinanceTransaction> FinanceTransactions { get; set; }
|
[Key(8)] public FastDictionary<int, FinanceTransaction> FinanceTransactions { get; }
|
||||||
|
|
||||||
public User(int id, string name, string address, string btcAddress, string ltcAddress, double btcAmount, double ltcAmount, FastList<FinanceTransaction> financeTransactions)
|
public User(int id, string name, string address, string btcAddress, string ltcAddress, double btcAmount, double ltcAmount, FastDictionary<int, FinanceTransaction> financeTransactions)
|
||||||
{
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
@ -41,11 +41,11 @@ namespace BlueWest.Data
|
||||||
|
|
||||||
public void AddTransaction(FinanceTransaction financeTransaction)
|
public void AddTransaction(FinanceTransaction financeTransaction)
|
||||||
{
|
{
|
||||||
FinanceTransactions.Add(financeTransaction);
|
FinanceTransactions.Add(FinanceTransactions.Count + 1, financeTransaction);
|
||||||
}
|
}
|
||||||
public void AddTransaction(FinanceTransactionInsertDto financeTransaction)
|
public void AddTransaction(FinanceTransactionInsertDto financeTransaction)
|
||||||
{
|
{
|
||||||
FinanceTransactions.Add(new FinanceTransaction(financeTransaction));
|
FinanceTransactions.Add(FinanceTransactions.Count + 1, new FinanceTransaction(financeTransaction, FinanceTransactions.Count + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool HasTransaction(int transactionId)
|
internal bool HasTransaction(int transactionId)
|
||||||
|
@ -53,9 +53,9 @@ namespace BlueWest.Data
|
||||||
return FinanceTransactions.Contains(transactionId);
|
return FinanceTransactions.Contains(transactionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Transaction GetTransactionById(int transactionId)
|
internal FinanceTransaction GetTransactionById(int transactionId)
|
||||||
{
|
{
|
||||||
return FinanceTransactions(transactionId);
|
return FinanceTransactions[transactionId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace BlueWest.Data
|
||||||
{
|
{
|
||||||
[Key(9)] public readonly FastDictionary<int, User> Users;
|
[Key(9)] public readonly FastDictionary<int, User> Users;
|
||||||
|
|
||||||
public int Length = 0;
|
[IgnoreMember] public int Length = 0;
|
||||||
|
|
||||||
public UserList(FastDictionary<int, User> users)
|
public UserList(FastDictionary<int, User> users)
|
||||||
{
|
{
|
||||||
|
@ -30,13 +30,13 @@ namespace BlueWest.Data
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DataQueryResult GetUserById(int id)
|
public DataQueryResult<User> GetUserById(int id)
|
||||||
{
|
{
|
||||||
if (Users.ContainsKey(id)) return new PositiveResult<User>(Users[id]);
|
if (Users.ContainsKey(id)) return new DataQueryResult<User>(Users[id], true);
|
||||||
return new NegativeResult("Can't find a user with the provided id.");
|
return new DataQueryResult<User>(null, false, "Can't find a user with the provided id.");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool RemoveUser(int userId)
|
public bool RemoveUser(int userId)
|
||||||
{
|
{
|
||||||
if (Users.ContainsKey(userId))
|
if (Users.ContainsKey(userId))
|
||||||
{
|
{
|
||||||
|
@ -52,25 +52,30 @@ namespace BlueWest.Data
|
||||||
return Users.Contains(userId);
|
return Users.Contains(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DataQueryResult UpdateUser(int userId, UserUpdateDto userUpdate)
|
public DataQueryResult<User> UpdateUser(int userId, UserUpdateDto userUpdate)
|
||||||
{
|
{
|
||||||
Users[userId].Update(userUpdate);
|
if (Users.ContainsKey(userId))
|
||||||
return Users[userId];
|
{
|
||||||
|
Users[userId].Update(userUpdate);
|
||||||
|
return new DataQueryResult<User>(Users[userId], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DataQueryResult<User>(null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal bool UserHasTransaction(int userId, int transactionId) => HasUser(userId) && Users[userId].FinanceTransactions.Contains(transactionId);
|
internal bool UserHasTransaction(int userId, int transactionId) => HasUser(userId) && Users[userId].FinanceTransactions.Contains(transactionId);
|
||||||
|
|
||||||
internal DataQueryResult GetTransactionById(int userId, int transactionId)
|
public DataQueryResult<FinanceTransaction> GetTransactionById(int userId, int transactionId)
|
||||||
{
|
{
|
||||||
if(!HasUser(userId)) return new NegativeResult("Can't find a user with the provided id.");
|
if(!HasUser(userId)) return new DataQueryResult<FinanceTransaction>(new FinanceTransaction(), false, "Can't find a user with the provided id.");
|
||||||
|
|
||||||
if (UserHasTransaction(userId, transactionId)) return new PositiveResult<Transaction>(Users[userId].FinanceTransactions[transactionId]);
|
if (UserHasTransaction(userId, transactionId)) return new DataQueryResult<FinanceTransaction>(Users[userId].FinanceTransactions[transactionId]);
|
||||||
|
|
||||||
return new NegativeResult("No transaction was found with the specified id");
|
return new DataQueryResult<FinanceTransaction>(new FinanceTransaction(), false, "Can't find a transaction with the provided id.");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal User AddUser(int userId, UserUpdateDto userUpdateDto)
|
public User AddUser(int userId, UserUpdateDto userUpdateDto)
|
||||||
{
|
{
|
||||||
if (Users.ContainsKey(userId))
|
if (Users.ContainsKey(userId))
|
||||||
{
|
{
|
||||||
|
@ -80,7 +85,7 @@ namespace BlueWest.Data
|
||||||
|
|
||||||
var id = userId != -1 ? userId : Length + 1;
|
var id = userId != -1 ? userId : Length + 1;
|
||||||
|
|
||||||
var newUser = new User(userUpdateDto, id, new FastList<FinanceTransaction>());
|
var newUser = new User(userUpdateDto);
|
||||||
|
|
||||||
Users.Add(Length, newUser);
|
Users.Add(Length, newUser);
|
||||||
|
|
||||||
|
@ -91,28 +96,28 @@ namespace BlueWest.Data
|
||||||
|
|
||||||
const string NoIdError = "No transaction was found with the specified id";
|
const string NoIdError = "No transaction was found with the specified id";
|
||||||
|
|
||||||
static NegativeResult NoIdResult = new NegativeResult(NoIdError);
|
public DataQueryResult<FinanceTransaction> AddFinanceTransaction(int userId, FinanceTransactionInsertDto financeTransactionDto)
|
||||||
internal DataQueryResult AddFinanceTransaction(int userId, FinanceTransactionInsertDto financeTransactionDto)
|
|
||||||
{
|
{
|
||||||
if (Users.ContainsKey(userId))
|
if (Users.ContainsKey(userId))
|
||||||
{
|
{
|
||||||
var financeTransaction = new FinanceTransaction(financeTransactionDto);
|
var financeTransaction = new FinanceTransaction(financeTransactionDto, Users[userId].FinanceTransactions.Count + 1);
|
||||||
Users[userId].AddTransaction(financeTransaction);
|
Users[userId].AddTransaction(financeTransaction);
|
||||||
return new PositiveResult<BlueWest.Data.FinanceTransaction>(financeTransaction);
|
return new DataQueryResult<FinanceTransaction>(financeTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NoIdResult;
|
return new DataQueryResult<FinanceTransaction>(new FinanceTransaction(), false,
|
||||||
|
"no transaction with the provided id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal FastList<FinanceTransaction> GetUserTransactions(int userId)
|
public ImmutableArray<FinanceTransaction> GetUserTransactions(int userId)
|
||||||
{
|
{
|
||||||
if (Users.ContainsKey(userId))
|
if (Users.ContainsKey(userId))
|
||||||
{
|
{
|
||||||
return Users[userId].FinanceTransactions;
|
return Users[userId].FinanceTransactions.Values.ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FastList<FinanceTransaction>();
|
return new ImmutableArray<FinanceTransaction>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net5.0-windows</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<LangVersion>10</LangVersion>
|
<LangVersion>10</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using BlueWest.Core.Tests;
|
using System.Collections.Immutable;
|
||||||
|
using BlueWest.Collections;
|
||||||
using BlueWest.Data;
|
using BlueWest.Data;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
@ -18,7 +19,7 @@ namespace BlueWest.WebApi.Controllers
|
||||||
{
|
{
|
||||||
if (_userList != null)
|
if (_userList != null)
|
||||||
{
|
{
|
||||||
return Ok(_userList);
|
return Ok(_userList.Users.Values.ToImmutableArray());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +32,9 @@ namespace BlueWest.WebApi.Controllers
|
||||||
[HttpGet("{userId}", Name = nameof(GetUserById))]
|
[HttpGet("{userId}", Name = nameof(GetUserById))]
|
||||||
public ActionResult GetUserById(int userId)
|
public ActionResult GetUserById(int userId)
|
||||||
{
|
{
|
||||||
User? user = MemoryData.GetUserById(userId);
|
DataQueryResult<User> user = MemoryData.GetUserById(userId);
|
||||||
|
|
||||||
if (user != null)
|
if (user.HasValue)
|
||||||
{
|
{
|
||||||
return Ok(user.Value);
|
return Ok(user.Value);
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ namespace BlueWest.WebApi.Controllers
|
||||||
public ActionResult GetTransactions(int userId)
|
public ActionResult GetTransactions(int userId)
|
||||||
{
|
{
|
||||||
var transactions = MemoryData.GetUserTransactions(userId);
|
var transactions = MemoryData.GetUserTransactions(userId);
|
||||||
return OK(transactions.ToDictionary());
|
return Ok(transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,9 +61,11 @@ namespace BlueWest.WebApi.Controllers
|
||||||
{
|
{
|
||||||
var user = MemoryData.UserList.GetUserById(userId);
|
var user = MemoryData.UserList.GetUserById(userId);
|
||||||
|
|
||||||
var transactions = user?.FinanceTransactions;
|
if(!user.HasValue) return new NotFoundResult();
|
||||||
|
|
||||||
FinanceTransaction? transaction = transactions?.FirstOrNull(t => t.Id == transactionId);
|
var transactions = user?.Value.FinanceTransactions;
|
||||||
|
|
||||||
|
FinanceTransaction? transaction = transactions?.Values.ToImmutableArray().FirstOrNull(t => t.Id == transactionId);
|
||||||
|
|
||||||
if (transaction != null)
|
if (transaction != null)
|
||||||
{
|
{
|
||||||
|
@ -113,9 +116,9 @@ namespace BlueWest.WebApi.Controllers
|
||||||
[HttpPost("{userId}/transactions")]
|
[HttpPost("{userId}/transactions")]
|
||||||
public ActionResult PostTransaction(int userId, FinanceTransactionInsertDto financeTransaction)
|
public ActionResult PostTransaction(int userId, FinanceTransactionInsertDto financeTransaction)
|
||||||
{
|
{
|
||||||
FinanceTransaction? result = MemoryData.UserList.AddFinanceTransaction(userId, financeTransaction);
|
DataQueryResult<FinanceTransaction> result = MemoryData.UserList.AddFinanceTransaction(userId, financeTransaction);
|
||||||
|
|
||||||
if(result != null) return Ok(result);
|
if(result.HasValue) return Ok(result.Value);
|
||||||
|
|
||||||
return new BadRequestResult();
|
return new BadRequestResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>disable</ImplicitUsings>
|
<ImplicitUsings>disable</ImplicitUsings>
|
||||||
<RootNamespace>PerformanceSolution</RootNamespace>
|
<RootNamespace>PerformanceSolution</RootNamespace>
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using BlueWest.Core.Tests;
|
|
||||||
using BlueWest.DataAgent;
|
using BlueWest.DataAgent;
|
||||||
|
|
||||||
namespace BlueWest.Core
|
namespace BlueWest.Core
|
||||||
|
|
|
@ -1,44 +1 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace BlueWest.Core.Tests
|
|
||||||
{
|
|
||||||
public static class PocoToDictionary
|
|
||||||
{
|
|
||||||
private static readonly MethodInfo AddToDicitonaryMethod = typeof(IDictionary<string, object>).GetMethod("Add");
|
|
||||||
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<int, object> ToDictionary(this object obj) => obj == null ? null : Converters.GetOrAdd(obj.GetType(), o =>
|
|
||||||
{
|
|
||||||
var outputType = typeof(IDictionary<int, object>);
|
|
||||||
var inputType = obj.GetType();
|
|
||||||
var inputExpression = Expression.Parameter(typeof(object), "input");
|
|
||||||
var typedInputExpression = Expression.Convert(inputExpression, inputType);
|
|
||||||
var outputVariable = Expression.Variable(outputType, "output");
|
|
||||||
var returnTarget = Expression.Label(outputType);
|
|
||||||
var body = new List<Expression>
|
|
||||||
{
|
|
||||||
Expression.Assign(outputVariable, Expression.New(DictionaryConstructor))
|
|
||||||
};
|
|
||||||
body.AddRange(
|
|
||||||
from prop in inputType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)
|
|
||||||
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<int, object>>>(
|
|
||||||
Expression.Block(new[] { outputVariable }, body),
|
|
||||||
inputExpression);
|
|
||||||
|
|
||||||
return lambdaExpression.Compile();
|
|
||||||
})(obj);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Transactions;
|
using System.Transactions;
|
||||||
using BlueWest.Collections;
|
using BlueWest.Collections;
|
||||||
using BlueWest.Data;
|
using BlueWest.Data;
|
||||||
|
@ -20,16 +21,16 @@ namespace PerformanceSolution.Data
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
{
|
{
|
||||||
UserList = GenerateMockData();
|
UserList = GenerateMockData();
|
||||||
SaveUserList();
|
//SaveUserList();
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadUsers();
|
//LoadUsers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveUserList(UserList userList)
|
public static void SaveUserList(UserList userList)
|
||||||
{
|
{
|
||||||
UserList = userList;
|
//UserList = userList;
|
||||||
SaveLoadManager.Save(UserList, SavePathName);
|
//SaveLoadManager.Save(UserList, SavePathName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadUsers()
|
public static void LoadUsers()
|
||||||
|
@ -38,7 +39,7 @@ namespace PerformanceSolution.Data
|
||||||
UserList ??= new UserList(new FastDictionary<int, User>());
|
UserList ??= new UserList(new FastDictionary<int, User>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Transaction GetTransactionById(int userId, int transactionId) => UserList.GetTransactionById(userId, transactionId);
|
public static DataQueryResult<FinanceTransaction> GetTransactionById(int userId, int transactionId) => UserList.GetTransactionById(userId, transactionId);
|
||||||
|
|
||||||
|
|
||||||
private static void SaveUserList() => SaveUserList(UserList);
|
private static void SaveUserList() => SaveUserList(UserList);
|
||||||
|
@ -53,10 +54,10 @@ namespace PerformanceSolution.Data
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
var transactions = new FastList<FinanceTransaction>();
|
var transactions = new FastDictionary<int, FinanceTransaction>();
|
||||||
var financeTransaction = new FinanceTransaction(0, 1, FinanceTransactionType.Buy, FinanceSymbol.BTC_EUR, 0,
|
var financeTransaction = new FinanceTransaction(0, 1, FinanceTransactionType.Buy, FinanceSymbol.BTC_EUR, 0,
|
||||||
0, 0.1, DateTime.Now);
|
0, 0.1, DateTime.Now);
|
||||||
transactions.Add(financeTransaction);
|
transactions.Add(1, financeTransaction);
|
||||||
|
|
||||||
var u = new User(1, "Rui Sousa", "Sagres", "NOADD", "NOADD", 0, 0, transactions);
|
var u = new User(1, "Rui Sousa", "Sagres", "NOADD", "NOADD", 0, 0, transactions);
|
||||||
var list = new FastDictionary<int, User>(10);
|
var list = new FastDictionary<int, User>(10);
|
||||||
|
@ -65,12 +66,12 @@ namespace PerformanceSolution.Data
|
||||||
return new UserList(list);
|
return new UserList(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static User? GetUserById(int userId)
|
public static DataQueryResult<User> GetUserById(int userId)
|
||||||
{
|
{
|
||||||
return UserList.GetUserById(userId);
|
return UserList.GetUserById(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FastList<FinanceTransaction> GetUserTransactions(int userId)
|
public static ImmutableArray<FinanceTransaction> GetUserTransactions(int userId)
|
||||||
{
|
{
|
||||||
return UserList.GetUserTransactions(userId);
|
return UserList.GetUserTransactions(userId);
|
||||||
}
|
}
|
||||||
|
|
2
MapTo
2
MapTo
|
@ -1 +1 @@
|
||||||
Subproject commit 9470afb737d873f2fbbc631813eadf10032c5c6b
|
Subproject commit ffc3dc7729c97190849441d73edb2dfc5fe63ecd
|
Loading…
Reference in New Issue