diff --git a/src/model.cpp b/src/model.cpp index 7b570d4..956a77f 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -494,12 +494,11 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree) model_env = &model_env_local; model_env->model_data = model_data; model_env->model = this; - bool status = false; try { table(); - status = insert_tree(insert_whole_tree); + insert_tree(insert_whole_tree); } catch(...) { @@ -508,30 +507,27 @@ bool Model::insert(ModelData * model_data, bool insert_whole_tree) } model_env = nullptr; - return status; + return model_env_local.status; } -// has ModelEnv set -// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent -bool Model::insert_tree(bool insert_whole_tree) +void Model::insert_tree(bool insert_whole_tree) { - bool result = false; model_env->has_primary_key_set = has_primary_key_set; - if( insert_whole_tree ) + if( model_env->status && insert_whole_tree ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY; model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_INSERT; fields(); } - if( model_connector ) + if( model_env->status && model_connector ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL; DbConnector * db_connector = model_connector->get_db_connector(); - // CHECK ME what if the stream is being used by something other? + // CHECK ME what if the stream is being used by someone else? pt::TextStream * out_stream = model_connector->get_stream(); if( db_connector && out_stream ) @@ -539,9 +535,9 @@ bool Model::insert_tree(bool insert_whole_tree) before_insert(); out_stream->clear(); - result = db_connector->insert(*out_stream, *this); + model_env->status = db_connector->insert(*out_stream, *this); - if( result ) + if( model_env->status ) { /* * after_insert() should read the new primary key and set has_primary_key_set flag if the key was read correctly @@ -564,16 +560,22 @@ bool Model::insert_tree(bool insert_whole_tree) after_insert_failure(); } } + else + { + model_env->status = false; + } + } + else + { + model_env->status = false; } - if( insert_whole_tree ) + if( model_env->status && insert_whole_tree ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY; model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_INSERT; fields(); } - - return result; } @@ -621,12 +623,11 @@ bool Model::update(ModelData * model_data, bool update_whole_tree) model_env = &model_env_local; model_env->model_data = model_data; model_env->model = this; - bool status = false; try { table(); - status = update_tree(update_whole_tree); + update_tree(update_whole_tree); } catch(...) { @@ -635,30 +636,28 @@ bool Model::update(ModelData * model_data, bool update_whole_tree) } model_env = nullptr; - return status; + return model_env_local.status; } -// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent -bool Model::update_tree(bool update_whole_tree) +void Model::update_tree(bool update_whole_tree) { - bool result = false; model_env->has_primary_key_set = has_primary_key_set; if( !has_primary_key_set ) { put_to_log(L"Morm: call update but model doesn't have a primary key set"); - return result; + model_env->status = false; } - if( update_whole_tree ) + if( model_env->status && update_whole_tree ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY; model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_UPDATE; fields(); } - if( model_connector ) + if( model_env->status && model_connector ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL; DbConnector * db_connector = model_connector->get_db_connector(); @@ -670,23 +669,29 @@ bool Model::update_tree(bool update_whole_tree) { before_update(); out_stream->clear(); - result = db_connector->update(*out_stream, *this); + model_env->status = db_connector->update(*out_stream, *this); - if( result ) + if( model_env->status ) after_update(); else after_update_failure(); } + else + { + model_env->status = false; + } + } + else + { + model_env->status = false; } - if( update_whole_tree ) + if( model_env->status && update_whole_tree ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY; model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_UPDATE; fields(); } - - return result; } @@ -734,12 +739,11 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree) model_env = &model_env_local; model_env->model_data = model_data; model_env->model = this; - bool status = false; try { table(); - status = remove_tree(remove_whole_tree); + remove_tree(remove_whole_tree); } catch(...) { @@ -748,44 +752,42 @@ bool Model::remove(ModelData * model_data, bool remove_whole_tree) } model_env = nullptr; - return status; + return model_env_local.status; } -// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent -bool Model::remove_tree(bool remove_whole_tree) +void Model::remove_tree(bool remove_whole_tree) { - bool result = false; model_env->has_primary_key_set = has_primary_key_set; if( !has_primary_key_set ) { put_to_log(L"Morm: call remove but model doesn't have a primary key set"); - return result; + model_env->status = false; } - if( remove_whole_tree ) + if( model_env->status && remove_whole_tree ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY; model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_REMOVE; fields(); } - if( model_connector ) + if( model_env->status && model_connector ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL; DbConnector * db_connector = model_connector->get_db_connector(); - // CHECK ME what if the stream is being used by something other? + // CHECK ME what if the stream is being used by someone else? pt::TextStream * out_stream = model_connector->get_stream(); if( db_connector && out_stream ) { before_remove(); out_stream->clear(); - result = db_connector->remove(*out_stream, *this); + model_env->status = db_connector->remove(*out_stream, *this); - if( result ) + if( model_env->status ) { save_mode = DO_NOTHING_ON_SAVE; has_primary_key_set = false; @@ -797,16 +799,22 @@ bool Model::remove_tree(bool remove_whole_tree) after_remove_failure(); } } + else + { + model_env->status = false; + } + } + else + { + model_env->status = false; } - if( remove_whole_tree ) + if( model_env->status && remove_whole_tree ) { model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY; model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_REMOVE; fields(); } - - return result; } @@ -830,12 +838,11 @@ bool Model::save(ModelData * model_data, bool save_whole_tree) model_env = &model_env_local; model_env->model_data = model_data; model_env->model = this; - bool status = false; try { table(); - status = save_tree(save_whole_tree); + save_tree(save_whole_tree); } catch(...) { @@ -844,17 +851,15 @@ bool Model::save(ModelData * model_data, bool save_whole_tree) } model_env = nullptr; - return status; + return model_env_local.status; } -// FIX ME we need to propagage the status from the whole tree, if there is an error somewhere then we should return error from the parent -bool Model::save_tree(bool save_whole_tree) +void Model::save_tree(bool save_whole_tree) { - bool result = false; model_env->has_primary_key_set = has_primary_key_set; - if( save_whole_tree ) + if( model_env->status && save_whole_tree ) { if( save_mode == DO_DELETE_ON_SAVE ) model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY; @@ -865,30 +870,32 @@ bool Model::save_tree(bool save_whole_tree) fields(); } - ModelEnv * old_model_env = model_env; // remove, insert or update will set model_env to nullptr - - switch( save_mode ) + if( model_env->status ) { - case DO_DELETE_ON_SAVE: - result = remove_tree(false); - break; + ModelEnv * old_model_env = model_env; // remove, insert or update will set model_env to nullptr - case DO_INSERT_ON_SAVE: - result = insert_tree(false); - break; + switch( save_mode ) + { + case DO_DELETE_ON_SAVE: + remove_tree(false); + break; - case DO_UPDATE_ON_SAVE: - result = update_tree(false); - break; + case DO_INSERT_ON_SAVE: + insert_tree(false); + break; - case DO_NOTHING_ON_SAVE: - result = true; - break; + case DO_UPDATE_ON_SAVE: + update_tree(false); + break; + + case DO_NOTHING_ON_SAVE: + break; + } + + model_env = old_model_env; } - model_env = old_model_env; - - if( save_whole_tree ) + if( model_env->status && save_whole_tree ) { if( save_mode == DO_DELETE_ON_SAVE ) model_env->model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY; @@ -898,8 +905,6 @@ bool Model::save_tree(bool save_whole_tree) model_env->model_work_submode = MORM_MODEL_WORK_SUBMODE_SAVE; fields(); } - - return result; } @@ -1599,6 +1604,9 @@ void Model::field_model(const wchar_t * db_field_name, const wchar_t * flat_fiel } field_model.model_env = nullptr; + + if( !model_env_local.status ) + model_env->status = false; } } diff --git a/src/model.h b/src/model.h index b11caee..bef780e 100644 --- a/src/model.h +++ b/src/model.h @@ -344,10 +344,10 @@ protected: virtual ModelData * get_model_data(); - virtual bool insert_tree(bool insert_whole_tree); - virtual bool update_tree(bool update_whole_tree); - virtual bool remove_tree(bool remove_whole_tree); - virtual bool save_tree(bool save_whole_tree); + virtual void insert_tree(bool insert_whole_tree); + virtual void update_tree(bool update_whole_tree); + virtual void remove_tree(bool remove_whole_tree); + virtual void save_tree(bool save_whole_tree); virtual void map_values_from_query(); @@ -1146,18 +1146,24 @@ protected: template void field_list_iterate_through_childs(ModelContainerType & child_model, const FT & field_type) { - ModelEnv model_env_local; - model_env_local.copy_global_objects(*model_env); - model_env_local.model = &child_model; + if( model_env->status ) + { + 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; - child_model.set_connector(model_connector); - child_model.table(); + child_model.model_env = &model_env_local; + child_model.model_env->has_primary_key_set = child_model.has_primary_key_set; + child_model.set_connector(model_connector); + child_model.table(); - field_model_iterate_through_childs(child_model, field_type); + field_model_iterate_through_childs(child_model, field_type); - child_model.model_env = nullptr; + if( !model_env_local.status ) + model_env->status = false; + + child_model.model_env = nullptr; + } } diff --git a/src/modelenv.h b/src/modelenv.h index a4f35c6..a4ca60e 100644 --- a/src/modelenv.h +++ b/src/modelenv.h @@ -105,6 +105,9 @@ public: const std::type_info * ezc_fun_info_typeinfo; #endif + bool status; + + ModelEnv() { clear(); @@ -138,6 +141,7 @@ public: stream = e.stream; was_field_found = e.was_field_found; wrapper = e.wrapper; + status = e.status; #ifdef MORM_HAS_EZC_LIBRARY ezc_fun_info = e.ezc_fun_info; @@ -189,6 +193,7 @@ public: stream = nullptr; was_field_found = false; wrapper.clear(); + status = true; #ifdef MORM_HAS_EZC_LIBRARY ezc_fun_info = nullptr;