From cff4c1518ebb37a3e11a2b5e876cb3f88584038b Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 24 Sep 2019 11:09:11 +0000 Subject: [PATCH] added support for UPDATE, INSERT and REMOVE for lists childs (need some testing) git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1214 e52654a7-88a9-db11-a3e9-0013d4bc506e --- samples/person.h | 12 ++++- samples/sample01.h | 15 ++++++ src/model.h | 126 +++++++++++++++++++++++++++++---------------- 3 files changed, 108 insertions(+), 45 deletions(-) diff --git a/samples/person.h b/samples/person.h index 6261791..f289db3 100644 --- a/samples/person.h +++ b/samples/person.h @@ -69,8 +69,10 @@ public: std::wstring email; Language language; + std::list attachments; Attachment attachment; + void map_fields() { field(L"id", id, false, false, true); @@ -81,7 +83,9 @@ public: field(L"email", email); field(L"language_id", L"language", language); - field(L"person_id", L"attachment", attachment, true, true, false); + field(L"person_id", L"attachments", attachments); + + //field(L"person_id", L"attachment", attachment, true, true, false); //field(L"person_id", attachment, f::insertable | f::updatable | f::foreign_key); //field(L"person_id", attachment, f::insertable, f::updatable, f::foreign_key); } @@ -92,6 +96,12 @@ public: stream << "public.person"; } + void after_select() + { + morm::Finder finder(model_connector); + attachments = finder.select().where().eq(L"person_id", id).get_list(); + } + void after_insert() { get_last_sequence(L"public.person_id_seq", id); diff --git a/samples/sample01.h b/samples/sample01.h index 93a3fd8..bf4594c 100644 --- a/samples/sample01.h +++ b/samples/sample01.h @@ -65,6 +65,8 @@ void make() morm::Finder finder(model_connector); + //std::list plist = finder.use_table_prefix(false).select().where().eq(L"id", 120).get_list(); + Person p = finder.use_table_prefix(false).select().where().eq(L"id", 120).get(); // Person p = finder.prepare_to_select().use_table_prefix(true).raw("select person.id as \"person.id\", person.first_name as \"person.first_name\", person.last_name as \"person.last_name\", person.email as \"person.email\", " @@ -77,8 +79,21 @@ void make() // "LEFT JOIN public.language AS language2 ON attachment.language_id = language2.id " // "where person.id=120").get(); + std::cout << "--------------------------------" << std::endl; + p.remove(); + std::cout << "--------------------------------" << std::endl; + std::string str; + //str += "--------\n"; + p.to_text(str, true, true); + +// for(Person & person : plist) +// { +// person.to_text(str, false, true); +// str += "\n--------\n"; +// } + std::cout << str << std::endl; } diff --git a/src/model.h b/src/model.h index 67078af..a62d62d 100644 --- a/src/model.h +++ b/src/model.h @@ -607,6 +607,11 @@ protected: } + /* + * IMPROVE ME there can be more rows in the result set when there are more items on the left hand side of the join + * this is only in a case when has_foreign_key is false, may it can be ignored? we can use unique index in such a case + * + */ void field_model_left_join(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, bool insertable, bool updatable, bool has_foreign_key, DbExpression * db_expression) { if( model_env && field_model.model_env && model_env->finder_helper ) @@ -960,61 +965,94 @@ protected: } + template + void field_list_iterate_through_childs(const wchar_t * db_field_name, ModelContainer & field_container, ModelContainerType * model_container_type) + { + if( !is_empty_field(db_field_name) ) + { + for(ModelContainerType & child_model : field_container) + { + ModelEnv model_env_local; + model_env_local.copy_global_objects(*model_env); + + child_model.model_env = &model_env_local; + child_model.set_connector(model_connector); + + if( model_env->model_work_submode == MORM_MODEL_WORK_SUBMODE_INSERT ) + { + child_model.insert_tree(true); + } + + if( model_env->model_work_submode == MORM_MODEL_WORK_SUBMODE_UPDATE ) + { + child_model.update_tree(true); + } + + if( model_env->model_work_submode == MORM_MODEL_WORK_SUBMODE_REMOVE ) + { + child_model.remove_tree(true); + } + + if( model_env->model_work_submode == MORM_MODEL_WORK_SUBMODE_SAVE ) + { + child_model.save_tree(true); + } + + child_model.model_env = nullptr; + } + } + + } + + + template + void field_list_generate_flat_string(const wchar_t * flat_field_name, ModelContainer & field_container, bool insertable, bool updatable) + { + 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) ) + { + // insertable and updatable will be ignored there + flat_expression->field_list(flat_field_name, field_container, insertable, updatable, false, model_connector, model_env); + } + } + } + + + template + void field_list_clearing_values(ModelContainer & field_container) + { + Clearer * clearer = model_connector->get_clearer(); + + if( clearer ) + { + clearer->clear_container(field_container); + } + } + + template void field_list(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelContainer & field_container, ModelContainerType * model_container_type, bool insertable, bool updatable) { if( model_connector && model_env ) { + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY ) + { + field_list_iterate_through_childs(db_field_name, field_container, model_container_type); + } + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING ) { - 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) ) - { - // IMPROVE ME - // what about model_data and save_mode? - // may it should be placed inside some structure? - flat_expression->field_list(flat_field_name, field_container, insertable, updatable, false, model_connector, model_env); - } - } + field_list_generate_flat_string(flat_field_name, field_container, insertable, updatable); } - if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_DB_SQL ) - { - 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) && - db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES && - db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_INSERT && - db_expression->get_output_type() != MORM_OUTPUT_TYPE_DB_UPDATE ) - { - // another select will be used (from another Finder) - // we need only columns name - // but columns are defined in the other model - - // FIX ME - // UPDATE, INSERT, REMOVE for lists - } - } - } - - if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) { - Clearer * clearer = model_connector->get_clearer(); - - if( clearer ) - { - clearer->clear_container(field_container); - } + field_list_clearing_values(field_container); } } }