This commit is contained in:
Rui Sousa 2021-12-10 00:04:48 +00:00
parent 6437336228
commit 1469b03c16
28 changed files with 425 additions and 230 deletions

View File

@ -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

View File

@ -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
{

View File

@ -0,0 +1 @@


View File

@ -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>

View File

@ -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; }
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -22,6 +22,7 @@ namespace BlueWest.Data
}
[MessagePackObject]
[MapFrom(typeof(FinanceTransactionInsertDto))]
public partial struct FinanceTransaction
{
[Key(1)] public int Id { get; set; }

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

119
BlueWest.Data/UserList.cs Normal file
View File

@ -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>();
}
}
}

View File

@ -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>

View File

@ -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!");
}
}
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}

View File

@ -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>

View File

@ -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);

View File

@ -0,0 +1,13 @@
syntax = "proto3";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}

View File

@ -0,0 +1,11 @@
using Microsoft.Extensions.Logging;
namespace BlueWest.WebApi.Service
{
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
}

View File

@ -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>();
});
}
}

View File

@ -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

View File

@ -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;
}
}*/
}
}

View File

@ -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);

View File

@ -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

@ -1 +1 @@
Subproject commit 63b2bcb3593440fb332917bed7d6c78827195dbe
Subproject commit 9470afb737d873f2fbbc631813eadf10032c5c6b