- 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:
parent
515e806a50
commit
dd01fafa40
|
@ -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;
|
||||
|
|
|
@ -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<typename FunInfoStreamType>
|
||||
void field(const wchar_t * field_name, void (*fun)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type, ModelEnv * model_env)
|
||||
void field(const wchar_t * field_name, void (Model::*fun)(Ezc::FunInfo<FunInfoStreamType> &), 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<typename FunInfoStreamType>
|
||||
void put_field_value(void (*fun)(Ezc::FunInfo<FunInfoStreamType>&), const FT & field_type, ModelEnv * model_env)
|
||||
void put_field_value(void (Model::*getter_method)(Ezc::FunInfo<FunInfoStreamType> &), 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<FunInfoStreamType>) == *model_env->ezc_fun_info_typeinfo )
|
||||
{
|
||||
fun(*reinterpret_cast<Ezc::FunInfo<FunInfoStreamType>*>(model_env->ezc_fun_info));
|
||||
before_field_value_string(field_type);
|
||||
(model_env->model->*getter_method)(*reinterpret_cast<Ezc::FunInfo<FunInfoStreamType>*>(model_env->ezc_fun_info));
|
||||
after_field_value_string(field_type);
|
||||
}
|
||||
|
||||
//put_field_value(info.out, field_type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
template<typename FieldValue>
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
251
src/model.cpp
251
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<const char * const *>(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
|
||||
|
||||
|
|
190
src/model.h
190
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<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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue