- added support for calling member functions (setters/getters) from Models

those functions can be used with databases and flat files
- removed support for calling static function
- if MORM_HAS_EZC_LIBRARY macro is defined then we can call a function
  which has a first argument Ezc::FunInfo<>& object
  (only for generating flat files)
This commit is contained in:
2021-06-01 19:34:34 +02:00
parent 515e806a50
commit dd01fafa40
9 changed files with 444 additions and 108 deletions

View File

@@ -49,10 +49,53 @@
#include "modelenv.h"
#include "ft.h"
// use a macro
#ifdef MORM_HAS_EZC_LIBRARY
#include "funinfo.h"
////////////////////
#endif
#define MORM_MODEL_MEMBER_FIELD(ClassName) \
void field(const wchar_t * field_name, \
void (ClassName::*getter_method)(pt::TextStream &), \
void (ClassName::*setter_method)(const char * input_str), \
const morm::FT & field_type = morm::FT::default_type) \
{ \
field(field_name, field_name, getter_method, setter_method, field_type); \
}\
void field(const wchar_t * db_field_name, \
const wchar_t * flat_field_name, \
void (ClassName::*getter_method)(pt::TextStream &), \
void (ClassName::*setter_method)(const char * input_str), \
const morm::FT & field_type = morm::FT::default_type) \
{ \
typedef void (Model::*ModelGetterMethod)(pt::TextStream &); \
typedef void (Model::*ModelSetterMethod)(const char * input_str); \
ModelGetterMethod model_getter_method = static_cast<ModelGetterMethod>(getter_method); \
ModelSetterMethod model_setter_method = static_cast<ModelSetterMethod>(setter_method); \
field_member(db_field_name, flat_field_name, model_getter_method, model_setter_method, field_type); \
}\
using Model::field;
#ifdef MORM_HAS_EZC_LIBRARY
#define MORM_MODEL_MEMBER_FIELD_EZC(ClassName) \
template<typename FunInfoStreamType> \
void field(const wchar_t * flat_field_name, void (ClassName::*method)(Ezc::FunInfo<FunInfoStreamType> &), const morm::FT & field_type = morm::FT::default_type) \
{ \
typedef void (Model::*ModelMember)(Ezc::FunInfo<FunInfoStreamType> &); \
ModelMember model_member = static_cast<ModelMember>(method); \
field_member_ezc(flat_field_name, model_member, field_type); \
}
#endif
#ifdef MORM_HAS_EZC_LIBRARY
#define MORM_MEMBER_FIELD(ClassName) MORM_MODEL_MEMBER_FIELD(ClassName) MORM_MODEL_MEMBER_FIELD_EZC(ClassName)
#else
#define MORM_MEMBER_FIELD(ClassName) MORM_MODEL_MEMBER_FIELD(ClassName)
#endif
namespace morm
@@ -142,7 +185,7 @@ public:
ModelEnv model_env_local;
model_env = &model_env_local;
model_env->model_work_mode = MORM_MODEL_WORK_MODE_SET_FIELD_VALUE;
table(); // CHECK ME it is needed to set table name?
model_env->model = this;
FieldValueHelper field_value_helper;
field_value_helper.db_field_name = db_field_name;
@@ -173,48 +216,16 @@ public:
}
Model * get_field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name)
{
ModelEnv model_env_local;
model_env = &model_env_local;
model_env->model_work_mode = MORM_MODEL_WORK_MODE_GET_FIELD_MODEL;
model_env->flat_field_name = flat_field_name;
Model * model = nullptr;
try
{
fields();
model = model_env->model;
}
catch(...)
{
model_env = nullptr;
throw;
}
if( !model_env->model && model_connector )
{
pt::Log * plog = model_connector->get_logger();
if( plog )
{
(*plog) << pt::Log::log1 << "Morm: I cannot find such a property: ";
put_fields_to_log(*plog, db_field_name, flat_field_name);
(*plog) << pt::Log::logend;
}
}
model_env = nullptr;
return model;
}
Model * get_field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name);
void put_field_value(const wchar_t * flat_field_name, pt::TextStream & stream, bool clear_stream = true);
void put_field_value(const wchar_t * flat_field_name, ModelData * model_data, pt::TextStream & stream, bool clear_stream = true);
// put in macro
#ifdef MORM_HAS_EZC_LIBRARY
template<typename FunInfoStreamType>
void put_field_value(const wchar_t * flat_field_name, ModelData * model_data, Ezc::FunInfo<FunInfoStreamType> & fun_info, pt::TextStream & stream, bool clear_stream)
void put_field_value(const wchar_t * flat_field_name, ModelData * model_data, Ezc::FunInfo<FunInfoStreamType> & fun_info, pt::TextStream & stream, bool clear_stream = true)
{
if( clear_stream )
{
@@ -229,6 +240,7 @@ public:
model_env->model_data = model_data;
model_env->ezc_fun_info = &fun_info;
model_env->ezc_fun_info_typeinfo = &typeid(fun_info);
model_env->model = this;
if( model_connector )
{
@@ -250,7 +262,7 @@ public:
model_env = nullptr;
}
#endif
protected:
@@ -305,6 +317,13 @@ protected:
virtual bool db_query(const std::string & raw_sql);
virtual bool db_query(const pt::TextStream & raw_sql);
/////////////////////////////////
/*
* IMPLEMENT ME
@@ -425,11 +444,7 @@ protected:
field_list(field_name, field_name, field_value, list_model_null_pointer, field_type);
}
template<typename FunInfoStreamType>
void field(const wchar_t * field_name, void (*fun)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type = FT::default_type)
{
field_fun(field_name, field_name, fun, field_type);
}
/*
@@ -551,11 +566,7 @@ protected:
field_list(db_field_name, flat_field_name, field_value, list_model_null_pointer, field_type);
}
template<typename FunInfoStreamType>
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (*fun)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type = FT::default_type)
{
field_fun(db_field_name, flat_field_name, fun, field_type);
}
protected:
@@ -640,7 +651,7 @@ protected:
template<typename FieldValue>
void field_generic_generate_db_sql(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type)
void field_generic_generate_db_sql(const wchar_t * db_field_name, FieldValue & field_value, const FT & field_type)
{
DbConnector * db_connector = model_connector->get_db_connector();
@@ -657,7 +668,7 @@ protected:
template<typename FieldValue>
void field_generic_read_value_from_db_resultset(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type)
void field_generic_read_value_from_db_resultset(const wchar_t * db_field_name, FieldValue & field_value, const FT & field_type)
{
DbConnector * db_connector = model_connector->get_db_connector();
@@ -680,7 +691,7 @@ protected:
template<typename FieldValue>
void field_generic_clear_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type)
void field_generic_clear_value(FieldValue & field_value, const FT & field_type)
{
Clearer * clearer = model_connector->get_clearer();
@@ -718,47 +729,71 @@ protected:
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_DB_SQL )
{
field_generic_generate_db_sql(db_field_name, flat_field_name, field_value, field_type);
field_generic_generate_db_sql(db_field_name, field_value, field_type);
}
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET )
{
field_generic_read_value_from_db_resultset(db_field_name, flat_field_name, field_value, field_type);
field_generic_read_value_from_db_resultset(db_field_name, field_value, field_type);
}
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE )
{
field_generic_clear_value(db_field_name, flat_field_name, field_value, field_type);
field_generic_clear_value(field_value, field_type);
}
}
}
template<typename FunInfoStreamType>
void field_fun(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (*fun)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
{
if( model_connector && model_env )
{
if( field_type.is_primary_key() )
{
model_env->was_primary_key_read = true;
}
void field_member_set_field_value(
const wchar_t * db_field_name,
const wchar_t * flat_field_name,
void (Model::*setter_method)(const char * input_str));
void field_member_generate_flat_string(
const wchar_t * flat_field_name,
void (Model::*getter_method)(pt::TextStream &),
const FT & field_type);
void field_member_generate_db_sql(
const wchar_t * db_field_name,
void (Model::*getter_method)(pt::TextStream &),
const FT & field_type);
void field_member_read_value_from_db_resultset(
const wchar_t * db_field_name,
void (Model::*setter_method)(const char * input_str),
const FT & field_type);
void field_member_clear_value(
void (Model::*setter_method)(const char * input_str),
const FT & field_type);
void field_member(
const wchar_t * db_field_name,
const wchar_t * flat_field_name,
void (Model::*getter_method)(pt::TextStream &),
void (Model::*setter_method)(const char * input_str),
const FT & field_type);
#ifdef MORM_HAS_EZC_LIBRARY
template<typename FunInfoStreamType>
void field_member_ezc(const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
{
if( model_connector && model_env && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo && model_env->model )
{
if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING )
{
field_fun_generate_flat_string(flat_field_name, fun, field_type);
field_fun_generate_flat_string(flat_field_name, method, field_type);
}
// if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_DB_SQL )
// {
// field_generic_generate_db_sql(db_field_name, flat_field_name, field_value, field_type);
// }
}
}
template<typename FunInfoStreamType>
void field_fun_generate_flat_string(const wchar_t * flat_field_name, void (*fun)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
void field_fun_generate_flat_string(const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type)
{
FlatConnector * flat_connector = model_connector->get_flat_connector();
@@ -768,10 +803,12 @@ protected:
if( flat_expression && !is_empty_field(flat_field_name) )
{
flat_expression->field(flat_field_name, fun, field_type, model_env);
flat_expression->field(flat_field_name, method, field_type, model_env);
}
}
}
#endif
@@ -820,6 +857,7 @@ protected:
{
ModelEnv model_env_local;
model_env_local.copy_global_objects(*model_env);
model_env_local.model = &child_model;
child_model.model_env = &model_env_local;
child_model.model_env->has_primary_key_set = child_model.has_primary_key_set;