diff --git a/samples/language.h b/samples/language.h index f1a962f..4fa2088 100644 --- a/samples/language.h +++ b/samples/language.h @@ -84,6 +84,10 @@ public: stream << "public.language"; } + void after_insert() + { + get_last_sequence(L"public.language_id_seq", id); + } }; diff --git a/samples/person.h b/samples/person.h index c0496aa..7e4f1fb 100644 --- a/samples/person.h +++ b/samples/person.h @@ -83,6 +83,10 @@ public: stream << "public.person"; } + void after_insert() + { + get_last_sequence(L"public.person_id_seq", id); + } }; diff --git a/src/dbconnector.cpp b/src/dbconnector.cpp index 5ec5569..c1ac2cb 100644 --- a/src/dbconnector.cpp +++ b/src/dbconnector.cpp @@ -187,7 +187,7 @@ void DbConnector::generate_insert_query(PT::TextStream & stream, Model & model) stream << " ("; db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS); - db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_UPDATE); + db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT); db_expression->generate_from_model(stream, model); stream << ") values ("; diff --git a/src/dbexpression.cpp b/src/dbexpression.cpp index c489b7f..fb8ba48 100644 --- a/src/dbexpression.cpp +++ b/src/dbexpression.cpp @@ -74,7 +74,9 @@ bool DbExpression::can_field_be_generated(bool insertable, bool updatable, bool return updatable; } else - if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY || output_type == MORM_OUTPUT_TYPE_JOIN_TABLES ) + if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY || + output_type == MORM_OUTPUT_TYPE_JOIN_TABLES || + output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ) { return is_primary_key; } @@ -104,6 +106,11 @@ void DbExpression::field_before() (*out_stream) << " AND "; } else + if( output_type == MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ) + { + (*out_stream) << ", "; + } + else if( output_type == MORM_OUTPUT_TYPE_WHERE_EQ || output_type == MORM_OUTPUT_TYPE_WHERE_GE || output_type == MORM_OUTPUT_TYPE_WHERE_GT || diff --git a/src/model.cpp b/src/model.cpp index b670279..e8ce949 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -232,17 +232,29 @@ void Model::generate_insert_query(PT::TextStream & stream, ModelData * model_dat } +bool Model::insert(ModelData * model_data, bool insert_whole_tree) +{ + ModelEnv model_env_local; + model_env = &model_env_local; -bool Model::insert(ModelData * model_data) + model_env->model_data = model_data; + return insert_tree(insert_whole_tree); +} + + +// has ModelEnv set +bool Model::insert_tree(bool insert_whole_tree) { bool result = false; + if( insert_whole_tree ) + { + model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_INSERT; + map_fields(); + } + if( model_connector ) { - ModelEnv model_env_local; - model_env = &model_env_local; - - model_env->model_data = model_data; model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL; DbConnector * db_connector = model_connector->get_db_connector(); @@ -251,6 +263,7 @@ bool Model::insert(ModelData * model_data) if( db_connector && out_stream ) { + before_insert(); out_stream->clear(); result = db_connector->insert(*out_stream, *this); @@ -275,9 +288,9 @@ bool Model::insert(ModelData * model_data) -bool Model::insert(ModelData & model_data) +bool Model::insert(ModelData & model_data, bool insert_whole_tree) { - return insert(&model_data); + return insert(&model_data, insert_whole_tree); } diff --git a/src/model.h b/src/model.h index a5d7442..e0a99bd 100644 --- a/src/model.h +++ b/src/model.h @@ -110,8 +110,8 @@ public: virtual std::string to_string(); virtual void generate_insert_query(PT::TextStream & stream, ModelData * model_data = nullptr); - virtual bool insert(ModelData * model_data = nullptr); - virtual bool insert(ModelData & model_data); + virtual bool insert(ModelData * model_data = nullptr, bool insert_whole_tree = true); + virtual bool insert(ModelData & model_data, bool insert_whole_tree = true); virtual void generate_update_query(PT::TextStream & stream, ModelData * model_data = nullptr); virtual bool update(ModelData * model_data = nullptr); @@ -165,6 +165,7 @@ protected: virtual ModelData * get_model_data(); + virtual bool insert_tree(bool insert_whole_tree); virtual void map_values_from_query(); @@ -826,6 +827,19 @@ protected: field_model_left_join(db_field_name, flat_field_name, field_model, insertable, updatable, has_foreign_key, db_expression); } + if( db_expression->get_work_mode() == MORM_WORK_MODE_MODEL_FIELDS && db_expression->get_output_type() == MORM_OUTPUT_TYPE_DB_INSERT ) + { + int not_used_object = 0; + db_expression->field(db_field_name, not_used_object, insertable, updatable, false, model_env); + } + + if( db_expression->get_work_mode() == MORM_WORK_MODE_MODEL_VALUES && db_expression->get_output_type() == MORM_OUTPUT_TYPE_DB_INSERT ) + { + db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY); + field_model.map_fields(); + db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT); + } + if( 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 ) @@ -899,6 +913,27 @@ protected: field_model.model_env = &model_env_local; field_model.set_connector(model_connector); + if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_INSERT ) + { + // IMPROVE ME what about if db_field_name is empty? not iterate in such a case? + field_model.map_fields(); + field_model.insert_tree(true); + } + + if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_UPDATE ) + { + // IMPROVE ME what about if db_field_name is empty? not iterate in such a case? + //field_model.map_fields(); + //field_model.update_tree(true); + } + + if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_SAVE ) + { + // IMPROVE ME what about if db_field_name is empty? not iterate in such a case? + //field_model.map_fields(); + //field_model.save_tree(true); + } + if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING ) { field_model_generate_flat_string(db_field_name, flat_field_name, field_model, insertable, updatable); diff --git a/src/morm_types.h b/src/morm_types.h index d1a2c61..2fc65da 100644 --- a/src/morm_types.h +++ b/src/morm_types.h @@ -47,6 +47,9 @@ #define MORM_MODEL_CONNECTOR_MODE_READING_VALUE_FROM_DB_RESULTSET 6 #define MORM_MODEL_CONNECTOR_MODE_CLEARING_VALUE 7 +#define MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_INSERT 8 +#define MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_UPDATE 9 +#define MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_SAVE 10 #define MORM_WORK_MODE_MODEL_FIELDS 1 @@ -66,10 +69,13 @@ // change to something like MORM_OUTPUT_TYPE_DB_WHERE_PRIMARY_KEY #define MORM_OUTPUT_TYPE_DB_PRIMARY_KEY 4 -//#define MORM_OUTPUT_TYPE_WHERE_CUSTOM 5 -#define MORM_OUTPUT_TYPE_SELECT_COLUMNS 6 +#define MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY 5 -#define MORM_OUTPUT_TYPE_JOIN_TABLES 7 + +//#define MORM_OUTPUT_TYPE_WHERE_CUSTOM 6 +#define MORM_OUTPUT_TYPE_SELECT_COLUMNS 7 + +#define MORM_OUTPUT_TYPE_JOIN_TABLES 8 #define MORM_OUTPUT_TYPE_WHERE_EQ 10 #define MORM_OUTPUT_TYPE_WHERE_LT 11