I hope it will be clear what I want to do.
I want to fetch data from database based on properties of provided object and then fill those properties with the retrieved data. So, if for example a user defines a class
class Person
{
public:
int Id;
string Name;
};
and then when he calls MyDatabase.Instance.ExecQuery<Person>()
it should return Person
object filled with information.
What I did is: a user should define the class as following:
class Person : public DBEntity
{
ENTITIY_PROP(Person , int, Id)
ENTITIY_PROP(Person , string, Name)
};
The defined macros ensure to add the name and type of the properties to _propsMeta
. Now, how do I set object's property based on it's name (see ExecQuery
)?
MY INITIAL SOLUTION
I though to add map
that maps property to a function that sets the property but I cannot have a map
of references to functions with different signatures. Any ideas? If you think I need to change my design to accomplish what I need - let me know.
template <typename T>
void ExecQuery()
{
static_assert(std::is_base_of<DBEntity, T>(), "a Class should inherit from DBEntity");
const auto& props = entity->GetPropsMeta();
auto row = GetData(props);
T entity = new T();
for (const auto& colName : row.Columns)
{
string val = row[colName];
// TODO: SET ENTITY'S PROPERTY colName with val
}
}
#define ENTITIY_PROP(Class, Type, Name) \
private: \
int _##Name; \
public: \
class Property_##Name { \
public: \
Property_##Name(Class* parent) : _parent(parent) \
{ \
_parent->SetPropMeta(#Name, #Type); \
} \
Type operator = (Type value) \
{ \
_parent->Set##Name(value); \
return _parent->Get##Name(); \
} \
operator Type() const \
{ \
return static_cast<const Class*>(_parent)->Get##Name(); \
} \
Property_##Name& operator =(const Property_##Name& other) \
{ \
operator=(other._parent->Get##Name()); return *this; \
}; \
Property_##Name(const Property_##Name& other) = delete; \
private: \
Class* _parent; \
} Name { this }; \
\
Type Get##Name() const { return _##Name; } \
void Set##Name(int value) { _##Name = value; } \
class DBEntity
{
private:
std::unordered_map<std::string, std::string> _propsMeta;
public:
const std::unordered_map<std::string, std::string>& GetPropsMeta() { return _propsMeta; }
};
Aucun commentaire:
Enregistrer un commentaire