From dd01fafa40ba2c9f804e9e47889752d3811273a9 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 1 Jun 2021 19:34:34 +0200 Subject: [PATCH] - 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) --- src/baseexpression.cpp | 68 +++++++++++ src/baseexpression.h | 30 +++-- src/cursor.h | 2 + src/dbconnector.cpp | 6 + src/dbconnector.h | 1 + src/finder.h | 1 + src/model.cpp | 251 +++++++++++++++++++++++++++++++++++++---- src/model.h | 190 ++++++++++++++++++------------- src/modelenv.h | 3 + 9 files changed, 444 insertions(+), 108 deletions(-) diff --git a/src/baseexpression.cpp b/src/baseexpression.cpp index ede7e5c..8b8ac84 100644 --- a/src/baseexpression.cpp +++ b/src/baseexpression.cpp @@ -206,6 +206,74 @@ void BaseExpression::put_field_name(const wchar_t * field_name, const FT & field } +void BaseExpression::field(const wchar_t * field_name, void (Model::*getter_method)(pt::TextStream &), const FT & field_type, ModelEnv * model_env) +{ + if( out_stream && can_field_be_generated(field_type) ) + { + field_before(); + + if( work_mode == MORM_WORK_MODE_MODEL_FIELDS ) + { + put_field_name_and_table_if_needed(field_name, field_type, model_env); + } + else + if( work_mode == MORM_WORK_MODE_MODEL_VALUES ) + { + put_field_value(getter_method, field_type, model_env); + } + else + if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES ) + { + if( model_env && model_env->set_field_name_helper ) + { + if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() ) + { + put_field_name_and_table_if_needed((*model_env->set_field_name_helper)[model_env->field_index], field_type, model_env); + put_name_value_separator(); + put_field_value(getter_method, field_type, model_env); + } + + model_env->field_index += 1; + } + else + { + put_field_name_and_table_if_needed(field_name, field_type, model_env); + put_name_value_separator(); + put_field_value(getter_method, field_type, model_env); + } + } + else + if( work_mode == MORM_WORK_MODE_GET_SPECIFIC_FIELD_VALUE ) + { + if( model_env && model_env->flat_field_name && pt::is_equal(model_env->flat_field_name, field_name) ) + { + put_field_value(getter_method, field_type, model_env); + } + } + + field_after(); + } +} + + +void BaseExpression::put_field_value(void (Model::*getter_method)(pt::TextStream &), const FT & field_type, ModelEnv * model_env) +{ + if( model_env && model_env->model && out_stream ) + { + // IMPROVEME + // if field_type is something like raw_value then don't call before_field_value_string() and after...() + // and don't do escaping + + before_field_value_string(field_type); + + // FIXME add escaping, we need to create a tmp buffer pt::TextStream and this buffer put to getter_method + (model_env->model->*getter_method)(*out_stream); + after_field_value_string(field_type); + } +} + + + void BaseExpression::save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env) { pt::TextStream str; diff --git a/src/baseexpression.h b/src/baseexpression.h index 18d4323..8bbb01b 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -44,8 +44,9 @@ #include "ft.h" #include "convert/text.h" -// put some macro +#ifdef MORM_HAS_EZC_LIBRARY #include "funinfo.h" +#endif namespace morm @@ -135,8 +136,14 @@ public: } + + virtual void field(const wchar_t * field_name, void (Model::*getter_method)(pt::TextStream &), const FT & field_type, ModelEnv * model_env); + + + +#ifdef MORM_HAS_EZC_LIBRARY template - void field(const wchar_t * field_name, void (*fun)(Ezc::FunInfo &), const FT & field_type, ModelEnv * model_env) + void field(const wchar_t * field_name, void (Model::*fun)(Ezc::FunInfo &), const FT & field_type, ModelEnv * model_env) { if( out_stream && can_field_be_generated(field_type) ) { @@ -184,6 +191,7 @@ public: field_after(); } } +#endif @@ -204,20 +212,26 @@ public: } - // not finished yet + void put_field_value(void (Model::*getter_method)(pt::TextStream &), const FT & field_type, ModelEnv * model_env); + + + +#ifdef MORM_HAS_EZC_LIBRARY template - void put_field_value(void (*fun)(Ezc::FunInfo&), const FT & field_type, ModelEnv * model_env) + void put_field_value(void (Model::*getter_method)(Ezc::FunInfo &), const FT & field_type, ModelEnv * model_env) { - if( model_env && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo ) + if( model_env && model_env->model && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo ) { if( typeid(Ezc::FunInfo) == *model_env->ezc_fun_info_typeinfo ) { - fun(*reinterpret_cast*>(model_env->ezc_fun_info)); + before_field_value_string(field_type); + (model_env->model->*getter_method)(*reinterpret_cast*>(model_env->ezc_fun_info)); + after_field_value_string(field_type); } - - //put_field_value(info.out, field_type); } } +#endif + template diff --git a/src/cursor.h b/src/cursor.h index b3ec707..54ad872 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -181,6 +181,7 @@ public: result.model_env = &model_env_local; result.model_env->cursor_helper = &cursor_helper; result.model_env->finder_helper = &finder_helper; + result.model_env->model = &result; try { @@ -366,6 +367,7 @@ protected: added_model.model_env->cursor_helper = &cursor_helper; added_model.model_env->finder_helper = &finder_helper; added_model.model_env->model_data = model_data; + added_model.model_env->model = &added_model; if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values ) { diff --git a/src/dbconnector.cpp b/src/dbconnector.cpp index 86a292c..24f13dc 100644 --- a/src/dbconnector.cpp +++ b/src/dbconnector.cpp @@ -616,6 +616,12 @@ void DbConnector::get_value(const char * value_str, std::string & field_value, c } +void DbConnector::get_value(const char * value_str, std::string_view & field_value, const FT & field_type) +{ + field_value = value_str; +} + + void DbConnector::get_value(const char * value_str, bool & field_value, const FT & field_type) { // IMPROVE ME diff --git a/src/dbconnector.h b/src/dbconnector.h index e4f76e5..e4ffffd 100644 --- a/src/dbconnector.h +++ b/src/dbconnector.h @@ -96,6 +96,7 @@ public: virtual void get_value(const char * value_str, wchar_t & field_value, const FT & field_type = FT::default_type); virtual void get_value(const char * value_str, std::wstring & field_value, const FT & field_type = FT::default_type); virtual void get_value(const char * value_str, std::string & field_value, const FT & field_type = FT::default_type); + virtual void get_value(const char * value_str, std::string_view & field_value, const FT & field_type = FT::default_type); virtual void get_value(const char * value_str, bool & field_value, const FT & field_type = FT::default_type); virtual void get_value(const char * value_str, short & field_value, const FT & field_type = FT::default_type); virtual void get_value(const char * value_str, unsigned short & field_value, const FT & field_type = FT::default_type); diff --git a/src/finder.h b/src/finder.h index e37ebb9..5b1dfd2 100644 --- a/src/finder.h +++ b/src/finder.h @@ -181,6 +181,7 @@ public: model.model_env = &model_env; model.model_env->model_data = model_data; model.model_env->finder_helper = &finder_helper; + model.model_env->model = &model; model.table(); model.model_env->add_table_name_to_finder_helper(); diff --git a/src/model.cpp b/src/model.cpp index 9993799..5f75430 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -240,6 +240,43 @@ void Model::get_table_name(std::string & str, bool with_schema_name, ModelData * } +Model * 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_env->model = this; + Model * model = nullptr; + + try + { + fields(); + model = model_env->child_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; +} + + void Model::put_field_value(const wchar_t * flat_field_name, pt::TextStream & stream, bool clear_stream) { put_field_value(flat_field_name, nullptr, stream, clear_stream); @@ -255,10 +292,10 @@ void Model::put_field_value(const wchar_t * flat_field_name, ModelData * model_d ModelEnv model_env_local; model_env = &model_env_local; - model_env->has_primary_key_set = has_primary_key_set; model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING; model_env->model_data = model_data; + model_env->model = this; if( model_connector ) { @@ -295,11 +332,11 @@ void Model::to_text(pt::TextStream & stream, ModelData * model_data, bool clear_ ModelEnv model_env_local; model_env = &model_env_local; - model_env->has_primary_key_set = has_primary_key_set; model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING; model_env->dump_mode = dump_mode; model_env->model_data = model_data; + model_env->model = this; if( model_connector ) { @@ -389,6 +426,7 @@ void Model::generate_insert_query(pt::TextStream & stream, ModelData * model_dat model_env->has_primary_key_set = has_primary_key_set; model_env->model_data = model_data; model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL; + model_env->model = this; if( model_connector ) { @@ -429,8 +467,8 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree) { ModelEnv model_env_local; model_env = &model_env_local; - model_env->model_data = model_data; + model_env->model = this; bool status = false; try @@ -522,6 +560,7 @@ void Model::generate_update_query(pt::TextStream & stream, ModelData * model_dat model_env->has_primary_key_set = has_primary_key_set; model_env->model_data = model_data; model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL; + model_env->model = this; if( model_connector ) { @@ -555,8 +594,8 @@ bool Model::update(ModelData * model_data, bool update_whole_tree) { ModelEnv model_env_local; model_env = &model_env_local; - model_env->model_data = model_data; + model_env->model = this; bool status = false; try @@ -633,6 +672,7 @@ void Model::generate_remove_query(pt::TextStream & stream, ModelData * model_dat model_env->has_primary_key_set = has_primary_key_set; model_env->model_data = model_data; model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL; + model_env->model = this; if( model_connector ) { @@ -667,8 +707,8 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree) { ModelEnv model_env_local; model_env = &model_env_local; - model_env->model_data = model_data; + model_env->model = this; bool status = false; try @@ -763,8 +803,8 @@ bool Model::save(ModelData * model_data, bool save_whole_tree) { ModelEnv model_env_local; model_env = &model_env_local; - model_env->model_data = model_data; + model_env->model = this; bool status = false; try @@ -885,8 +925,8 @@ void Model::clear() { ModelEnv model_env_local; model_env = &model_env_local; - model_env->model_work_mode = MORM_MODEL_WORK_MODE_CLEARING_VALUE; + model_env->model = this; try { @@ -1002,20 +1042,7 @@ bool Model::is_the_same_field(const wchar_t * field1, const wchar_t * field2) if( is_empty_field(field1) || is_empty_field(field2) ) return false; - bool the_same = false; - - while( *field1 && *field2 ) - { - field1 += 1; - field2 += 1; - } - - if( *field1 == 0 && *field2 == 0 ) - { - the_same = true; - } - - return the_same; + return pt::is_equal(field1, field2); } @@ -1243,9 +1270,10 @@ void Model::field_model_set_parent_key_in_child(const wchar_t * db_field_name, M model_env_local.model_work_mode = MORM_MODEL_WORK_MODE_SET_FIELD_VALUE; model_env_local.field_value_helper_tab = &helper_tab; model_env_local.field_index = 0; + model_env_local.model = &field_model; + field_model.model_env = &model_env_local; field_model.table(); - field_model.fields(); if( (size_t)field_model.model_env->field_index != helper_tab.size() && log ) @@ -1477,6 +1505,7 @@ void Model::field_model(const wchar_t * db_field_name, const wchar_t * flat_fiel { ModelEnv model_env_local; model_env_local.copy_global_objects(*model_env); + model_env_local.model = &field_model; field_model.model_env = &model_env_local; field_model.model_env->has_primary_key_set = field_model.has_primary_key_set; @@ -1519,10 +1548,9 @@ void Model::field_model(const wchar_t * db_field_name, const wchar_t * flat_fiel if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_FIELD_MODEL ) { - //if( pt::is_equal(db_field_name, model_env->db_field_model) && pt::is_equal(flat_field_name, model_env->flat_field_name) ) if( flat_field_name && model_env->flat_field_name && pt::is_equal(flat_field_name, model_env->flat_field_name) ) - model_env->model = &field_model; + model_env->child_model = &field_model; } field_model.model_env = nullptr; @@ -1623,5 +1651,180 @@ bool Model::db_query(const pt::TextStream & raw_sql) + +void Model::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)) +{ + if( model_env->field_value_helper_tab ) + { + if( model_env->field_index >= 0 && (size_t)model_env->field_index < model_env->field_value_helper_tab->size() ) + { + FieldValueHelper & helper = (*model_env->field_value_helper_tab)[model_env->field_index]; + pt::Log * log = model_connector->get_logger(); + + if( (!helper.compare_db_field_name || is_the_same_field(db_field_name, helper.db_field_name)) && + (!helper.compare_flat_field_name || is_the_same_field(flat_field_name, helper.flat_field_name)) ) + { + if( helper.value_object && helper.value_type_info ) + { + const char * p_const_char_type; + + if( typeid(p_const_char_type) == *helper.value_type_info ) + { + const char * const * p_str = reinterpret_cast(helper.value_object); + (model_env->model->*setter_method)(*p_str); + } + else + { + if( log ) + { + (*log) << pt::Log::log1 << "Morm: incorrect type of a field in "; + log_table_name(); + (*log) << ", "; + put_fields_to_log(*log, db_field_name, flat_field_name); + (*log) << ", type expected " << typeid(p_const_char_type).name() + << " got " << helper.value_type_info->name() << pt::Log::logend; + } + } + } + + helper.found = true; + model_env->field_index += 1; + } + } + } +} + + +void Model::field_member_generate_flat_string( + const wchar_t * flat_field_name, + void (Model::*getter_method)(pt::TextStream &), + const FT & field_type) +{ + FlatConnector * flat_connector = model_connector->get_flat_connector(); + + if( flat_connector ) + { + FlatExpression * flat_expression = flat_connector->get_expression(); + + if( flat_expression && !is_empty_field(flat_field_name) ) + { + flat_expression->field(flat_field_name, getter_method, field_type, model_env); + } + } +} + + +void Model::field_member_generate_db_sql( + const wchar_t * db_field_name, + void (Model::*getter_method)(pt::TextStream &), + const FT & field_type) +{ + DbConnector * db_connector = model_connector->get_db_connector(); + + if( db_connector ) + { + DbExpression * db_expression = db_connector->get_expression(); + + if( db_expression && !is_empty_field(db_field_name) ) + { + // dodac do FT raw_value + // jest raw_value jest zdefiniowane to nie wykonujemy eskejpowania + // (jesli nie zdefiniowane to zrobic tymczasowy strumien ktory zostanie dostarczony + // do getter_method i pozniej z tego strumienia wykopiowac z eskejpowaniem i wstawic do normalnego strumienia) + + db_expression->field(db_field_name, getter_method, field_type, model_env); + } + } +} + + +void Model::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) +{ + if( model_env && model_env->model ) + { + if( field_type.is_binary() || field_type.is_hexadecimal() ) + { + std::string db_value; + field_generic_read_value_from_db_resultset(db_field_name, db_value, field_type); + (model_env->model->*setter_method)(db_value.c_str()); + } + else + { + std::string_view db_value; + field_generic_read_value_from_db_resultset(db_field_name, db_value, field_type); + + if( db_value.data() != nullptr ) + { + // the string is already null terminated (by the database) + (model_env->model->*setter_method)(db_value.data()); + } + } + } +} + + +void Model::field_member_clear_value( + void (Model::*setter_method)(const char * input_str), + const FT & field_type) +{ + char buffer[1] = {0}; + (model_env->model->*setter_method)(buffer); +} + + +void Model::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) +{ + if( model_connector && model_env && model_env->model ) + { + if( field_type.is_primary_key() ) + { + pt::Log * plog = model_connector->get_logger(); + + if( plog ) + { + (*plog) << pt::Log::log1 << "Morm:: getters and setters cannot be used as a primary key" << pt::Log::logend; + } + } + + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_SET_FIELD_VALUE ) + { + field_member_set_field_value(db_field_name, flat_field_name, setter_method); + } + + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING ) + { + field_member_generate_flat_string(flat_field_name, getter_method, field_type); + } + + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_DB_SQL ) + { + field_member_generate_db_sql(db_field_name, getter_method, field_type); + } + + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET ) + { + field_member_read_value_from_db_resultset(db_field_name, setter_method, field_type); + } + + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) + { + field_member_clear_value(setter_method, field_type); + } + } +} + + + } // namespace diff --git a/src/model.h b/src/model.h index eb68a3b..2b77b5d 100644 --- a/src/model.h +++ b/src/model.h @@ -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(getter_method); \ + ModelSetterMethod model_setter_method = static_cast(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 \ + void field(const wchar_t * flat_field_name, void (ClassName::*method)(Ezc::FunInfo &), const morm::FT & field_type = morm::FT::default_type) \ + { \ + typedef void (Model::*ModelMember)(Ezc::FunInfo &); \ + ModelMember model_member = static_cast(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 - void put_field_value(const wchar_t * flat_field_name, ModelData * model_data, Ezc::FunInfo & fun_info, pt::TextStream & stream, bool clear_stream) + void put_field_value(const wchar_t * flat_field_name, ModelData * model_data, Ezc::FunInfo & 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 - void field(const wchar_t * field_name, void (*fun)(Ezc::FunInfo &), 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 - void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (*fun)(Ezc::FunInfo &), 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 - 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 - 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 - 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 - void field_fun(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (*fun)(Ezc::FunInfo &), 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 + void field_member_ezc(const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo &), 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 - void field_fun_generate_flat_string(const wchar_t * flat_field_name, void (*fun)(Ezc::FunInfo &), const FT & field_type) + void field_fun_generate_flat_string(const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo &), 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; diff --git a/src/modelenv.h b/src/modelenv.h index 038c1cc..2908077 100644 --- a/src/modelenv.h +++ b/src/modelenv.h @@ -93,6 +93,7 @@ public: void * ezc_fun_info; const std::type_info * ezc_fun_info_typeinfo; + Model * child_model; ModelEnv() { @@ -119,6 +120,7 @@ public: model = e.model; ezc_fun_info = e.ezc_fun_info; ezc_fun_info_typeinfo = e.ezc_fun_info_typeinfo; + child_model = e.child_model; // schema_name and table_name don't have to be copied table2_name = nullptr; @@ -159,6 +161,7 @@ public: model = nullptr; ezc_fun_info = nullptr; ezc_fun_info_typeinfo = nullptr; + child_model = nullptr; }