Skip to content

Commit

Permalink
Model & mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
k-nero committed Feb 26, 2024
1 parent 30e2a00 commit 872a218
Show file tree
Hide file tree
Showing 23 changed files with 355 additions and 98 deletions.
5 changes: 5 additions & 0 deletions Application/Application.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,11 @@
<ClInclude Include="ITodoItemCommand.h" />
<ClInclude Include="ITodoItemQuery.h" />
<ClInclude Include="ITodoListQuery.h" />
<ClInclude Include="Mapper.h" />
<ClInclude Include="PaginationObject.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="TodoItemCommand.h" />
<ClInclude Include="TodoItemModel.h" />
<ClInclude Include="TodoItemService.h" />
<ClInclude Include="TodoListCommand.h" />
</ItemGroup>
Expand All @@ -260,9 +262,12 @@
<ClCompile Include="CommandBuilder.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClInclude Include="TodoItemQuery.h" />
<ClCompile Include="TodoItemModel.cpp" />
<ClCompile Include="TodoItemQuery.cpp" />
<ClCompile Include="TodoItemService.cpp" />
<ClCompile Include="TodoListModel.cpp" />
<ClCompile Include="TodoListService.cpp" />
<ClInclude Include="TodoListModel.h" />
<ClInclude Include="TodoListService.h" />
<ClInclude Include="ITodoListCommand.h" />
<ClCompile Include="PaginationObject.cpp" />
Expand Down
28 changes: 20 additions & 8 deletions Application/Application.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,6 @@
<Filter Include="Source Files\Services">
<UniqueIdentifier>{1161eb53-88cc-4bac-9847-8821d7fc4f0f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Services\Interface">
<UniqueIdentifier>{0e29a219-c1b7-4076-8f11-29efe88f4348}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Services\Base">
<UniqueIdentifier>{fa33e1ed-b085-40fe-ba3c-0c36111484fe}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Common">
<UniqueIdentifier>{9149844f-55c9-4af4-ba05-a8fe88616cc9}</UniqueIdentifier>
</Filter>
Expand All @@ -76,8 +70,11 @@
<Filter Include="Source Files\CQRS\TodoItem">
<UniqueIdentifier>{04f1a55d-d43c-42e5-8d18-be5044852521}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\CQRS\Base">
<UniqueIdentifier>{838272c3-dfea-49bf-82b7-30f427193de5}</UniqueIdentifier>
<Filter Include="Header Files\Model">
<UniqueIdentifier>{ed85d578-47ba-4d32-a470-3f570e30e713}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Model">
<UniqueIdentifier>{50cef1b3-460a-48a0-b20b-4b1e19b45997}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
Expand Down Expand Up @@ -156,6 +153,15 @@
<ClInclude Include="TodoItemService.h">
<Filter>Header Files\Services</Filter>
</ClInclude>
<ClInclude Include="Mapper.h">
<Filter>Header Files\Common</Filter>
</ClInclude>
<ClInclude Include="TodoListModel.h">
<Filter>Header Files\Model</Filter>
</ClInclude>
<ClInclude Include="TodoItemModel.h">
<Filter>Header Files\Model</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
Expand Down Expand Up @@ -200,5 +206,11 @@
<ClCompile Include="TodoItemService.cpp">
<Filter>Source Files\Services</Filter>
</ClCompile>
<ClCompile Include="TodoListModel.cpp">
<Filter>Source Files\Model</Filter>
</ClCompile>
<ClCompile Include="TodoItemModel.cpp">
<Filter>Source Files\Model</Filter>
</ClCompile>
</ItemGroup>
</Project>
6 changes: 3 additions & 3 deletions Application/ApplicationUserServices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ std::vector<std::shared_ptr<ApplicationUser>> ApplicationUserService::GetAllAppl
return query.GetAll();
}

std::string ApplicationUserService::CreateApplicationUser(ApplicationUser* applicationUser) noexcept(false)
std::string ApplicationUserService::CreateApplicationUser(ApplicationUser& applicationUser) noexcept(false)
{
std::string id = CoreHelper::CreateUUID();
applicationUser->SetId(id);
applicationUser.SetId(id);
ApplicationUserCommand cmd;
cmd.Create(applicationUser);
return id;
}

int ApplicationUserService::UpdateApplicationUser(ApplicationUser* applicationUser, const std::string& Id) noexcept(false)
int ApplicationUserService::UpdateApplicationUser(ApplicationUser& applicationUser, const std::string& Id) noexcept(false)
{
ApplicationUserCommand cmd;
return cmd.Update(applicationUser, EQ(Id));
Expand Down
4 changes: 2 additions & 2 deletions Application/ApplicationUserServices.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class APPLICATION_API ApplicationUserService
std::shared_ptr<ApplicationUser> GetApplicationUserById(const std::string& id);
std::shared_ptr<ApplicationUser> GetApplicationUserByUserName(std::string& userName);
std::vector<std::shared_ptr<ApplicationUser>>GetAllApplicationUsers();
std::string CreateApplicationUser(ApplicationUser* applicationUser);
int UpdateApplicationUser(ApplicationUser* applicationUser, const std::string& id);
std::string CreateApplicationUser(ApplicationUser& applicationUser);
int UpdateApplicationUser(ApplicationUser& applicationUser, const std::string& id);
int DeleteApplicationUser(const std::string& id);
~ApplicationUserService();
private:
Expand Down
57 changes: 27 additions & 30 deletions Application/BaseCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@ class APPLICATION_API BaseCommand : public IBaseCommand<T>
}
}
explicit BaseCommand(DbContext* db) { this->db = std::make_unique<DbContext>(db); }
virtual int Create(T* item) noexcept(false) override
virtual int Create(T& item) noexcept(false) override
{
auto con = db->GetConnection();
try
{
if (item == nullptr)
{
throw std::exception("Internal error! Item is null");
}

if (con == nullptr || !con->isConnected())
{
throw std::exception("Internal error! Database connection is null or failed");
Expand All @@ -46,7 +43,7 @@ class APPLICATION_API BaseCommand : public IBaseCommand<T>
{
std::string field = D.name;

if (D.name != "ModifiedDate" && is_primitive_type((item->*(D).pointer)))
if (D.name != "ModifiedDate" && is_primitive_type((item.*(D).pointer)))
{
query += field + ", ";
if (D.name == "CreatedDate")
Expand All @@ -70,33 +67,33 @@ class APPLICATION_API BaseCommand : public IBaseCommand<T>
{
if (D.name == f)
{
auto value = (item->*(D).pointer);
auto value = (item.*(D).pointer);
auto void_pointer = (void*)&value;
if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, int>::value )
if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, int>::value )
{
cmd.Param(D.name).setAsLong() = *(int*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, long>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, long>::value )
{
cmd.Param(D.name).setAsLong() = *(long*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, bool>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, bool>::value )
{
cmd.Param(D.name).setAsBool() = *(bool*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, double>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, float>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, double>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, float>::value )
{
cmd.Param(D.name).setAsDouble() = *(double*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::string>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::wstring>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::string_view>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::wstring_view>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::string>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::wstring>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::string_view>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::wstring_view>::value )
{
cmd.Param(_TSA(D.name)).setAsString() = (*(std::string*)void_pointer).c_str();
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::tm>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::tm>::value )
{
cmd.Param(_TSA(D.name)).setAsDateTime() = SADateTime(*(tm*)void_pointer);
}
Expand All @@ -121,7 +118,7 @@ class APPLICATION_API BaseCommand : public IBaseCommand<T>
return 0;
}

virtual int Update(T* item, const std::string& query) noexcept(false) override
virtual int Update(T& item, const std::string& query) noexcept(false) override
{
auto con = db->GetConnection();
try
Expand All @@ -135,7 +132,7 @@ class APPLICATION_API BaseCommand : public IBaseCommand<T>
boost::mp11::mp_for_each<D>([&](auto D)
{
std::string field = D.name;
if (field != "Id" && field != "CreatedDate" && is_primitive_type((item->*(D).pointer)))
if (field != "Id" && field != "CreatedDate" && is_primitive_type((item.*(D).pointer)))
{
if (field == "ModifiedDate")
{
Expand All @@ -156,33 +153,33 @@ class APPLICATION_API BaseCommand : public IBaseCommand<T>
{
if (D.name == f)
{
auto value = (item->*(D).pointer);
auto value = (item.*(D).pointer);
auto void_pointer = (void*)&value;
if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, int>::value )
if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, int>::value )
{
cmd.Param(D.name).setAsLong() = *(int*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, long>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, long>::value )
{
cmd.Param(D.name).setAsLong() = *(long*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, bool>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, bool>::value )
{
cmd.Param(D.name).setAsBool() = *(bool*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, double>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, float>::value)
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, double>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, float>::value)
{
cmd.Param(D.name).setAsDouble() = *(double*)void_pointer;
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::string>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::wstring>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::string_view>::value
|| std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::wstring_view>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::string>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::wstring>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::string_view>::value
|| std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::wstring_view>::value )
{
cmd.Param(_TSA(D.name)).setAsString() = (*(std::string*)void_pointer).c_str();
}
else if (std::is_same<std::remove_reference_t<decltype(item->*(D).pointer)>, std::tm>::value )
else if (std::is_same<std::remove_reference_t<decltype(item.*(D).pointer)>, std::tm>::value )
{
cmd.Param(_TSA(D.name)).setAsDateTime() = SADateTime(*(tm*)void_pointer);
}
Expand Down
1 change: 0 additions & 1 deletion Application/BaseQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ class APPLICATION_API BaseQuery
}
else
{
//TODO: Join table
}
});
return std::shared_ptr<T>(item);
Expand Down
37 changes: 20 additions & 17 deletions Application/CommandBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,34 @@
#include <type_traits>
#include <functional>

/*template<typename T, typename Z = std::is_base_of<BaseEntity, T>::type >
class CommandBuilder
{
public:
CommandBuilder();
~CommandBuilder();
private:
std::string _command;
}*/;

namespace CommandBuilder
{
class Where
template<typename T>
class DbSet
{
public:
Where();
~Where();

DbSet();
~DbSet();
DbSet& Where(std::string where)
{
_where = where;
return this;
}

template<typename F>
DbSet& Include(F f)
{
_includes.push_back(typeid(f()).name());
return this;
}


private:
std::string _command;
std::string _where;
std::string _table;
std::vector<std::string> _includes;

};
}

4 changes: 2 additions & 2 deletions Application/IBaseCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
template<typename T>
class APPLICATION_API IBaseCommand
{
virtual int Create(T* item) = 0;
virtual int Update(T* item, const std::string& id) = 0;
virtual int Create(T& item) = 0;
virtual int Update(T& item, const std::string& id) = 0;
virtual int Delete(const std::string& id ) = 0;
};
78 changes: 78 additions & 0 deletions Application/Mapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#pragma once
#include <string>
#include <unordered_map>
#include <boost/describe.hpp>
#include <memory>
#include "ApplicationApi.h"

enum APPLICATION_API MemberOption
{
Ignore,
Override,
OvverideIfNull
};

class APPLICATION_API Mapper
{
public:
Mapper() = default;
~Mapper() = default;

template<typename Source, typename Destination>
static Destination Map(Source& source)
{
Destination destination{};
boost::mp11::mp_for_each< boost::describe::describe_members<Destination, boost::describe::mod_any_access | boost::describe::mod_inherited>>([&](auto destination_memeber)
{
boost::mp11::mp_for_each< boost::describe::describe_members<Source, boost::describe::mod_any_access | boost::describe::mod_inherited>>([&](auto source_member)
{

void* source_pointer = &(source.*(source_member.pointer));
using des_type = std::remove_reference_t<decltype(destination.*(destination_memeber.pointer))>;
if (source_member.name == destination_memeber.name && typeid(source.*(source_member.pointer)) == typeid(destination.*(destination_memeber.pointer)) )
{
destination.*(destination_memeber.pointer) = *((des_type*)source_pointer);
}
});
});
return destination;
}

template<typename Source, typename Destination>
class MapProfile
{
public:
MapProfile() = default;
~MapProfile() = default;

using SourceType = Source;
using DestinationType = Destination;

template <typename Source, typename Destination>
static MapProfile& CreateMap()
{
return new MapProfile<Source, Destination>();
}

MapProfile& ForMember( std::string memeber_name, MemberOption opt )
{
_memberOptions[memeber_name] = opt;
return *this;
}

MapProfile& ReverseMap()
{
_reverseMap = true;
return *this;
}



private:
std::unordered_map<std::string, MemberOption> _memberOptions;
bool _reverseMap = false;
};



};
Loading

0 comments on commit 872a218

Please sign in to comment.