From a1d18735b0334ff3ee1c552b7c024836d0a74aa4 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 21 May 2019 17:24:12 +0000 Subject: [PATCH] - removed prefix() method from Finder (this was for a custom prefix) - removed column_prefix and column_prefix_index from BaseExpression now we have a pointer to ModelEnv passed in field() method - to ModelEnv: added table_name, table_name_simple and table_index git-svn-id: svn://ttmath.org/publicrep/morm/branches/join_models@1193 e52654a7-88a9-db11-a3e9-0013d4bc506e --- src/baseexpression.cpp | 44 +++++++++++-------------- src/baseexpression.h | 32 +++++++----------- src/dbconnector.cpp | 3 +- src/dbconnector.h | 2 +- src/finder.h | 62 ++++++++++++----------------------- src/finderhelper.h | 1 + src/model.cpp | 4 +-- src/model.h | 73 ++++++++++++------------------------------ src/modelenv.h | 21 ++++++++++-- 9 files changed, 94 insertions(+), 148 deletions(-) diff --git a/src/baseexpression.cpp b/src/baseexpression.cpp index 6f826ae..e7d1cc3 100644 --- a/src/baseexpression.cpp +++ b/src/baseexpression.cpp @@ -68,8 +68,6 @@ int BaseExpression::get_work_mode() void BaseExpression::prepare_to_new_expression() { - column_prefix.clear(); - column_prefix_index = 1; out_stream = nullptr; is_first_field = false; work_mode = 0; @@ -89,25 +87,9 @@ void BaseExpression::allow_to_use_prefix(bool use_prefix) } -void BaseExpression::set_column_prefix(const std::string & prefix) +bool BaseExpression::get_allow_to_use_prefix() { - column_prefix = prefix; -} - -void BaseExpression::set_column_prefix(const std::string & prefix, int index) -{ - column_prefix = prefix; - column_prefix_index = index; -} - -std::string BaseExpression::get_column_prefix() -{ - return column_prefix; -} - -int BaseExpression::get_column_prefix_index() -{ - return column_prefix_index; + return use_prefix; } @@ -177,16 +159,18 @@ void BaseExpression::field_after() -void BaseExpression::put_field_name(const wchar_t * field_name, bool add_column_prefix) +void BaseExpression::put_field_name(const wchar_t * field_name, bool add_column_prefix, ModelEnv * model_env) { before_field_name(); - if( use_prefix && add_column_prefix && !column_prefix.empty() ) + if( use_prefix && model_env && add_column_prefix ) { - esc(column_prefix, *out_stream); + esc(model_env->table_name_simple, *out_stream); - if( column_prefix_index > 1 ) - (*out_stream) << column_prefix_index; + if( model_env->table_index > 1 ) + { + (*out_stream) << model_env->table_index; + } (*out_stream) << '.'; } @@ -415,6 +399,16 @@ void BaseExpression::esc(const PT::Date & date, PT::TextStream & stream) stream << date; } +void BaseExpression::esc(const PT::TextStream & val, PT::TextStream & stream) +{ + PT::TextStream::const_iterator i = val.begin(); + + for(; i != val.end() ; ++i) + { + esc(*i, stream); + } +} + void BaseExpression::put_type(char val, PT::TextStream & stream) { diff --git a/src/baseexpression.h b/src/baseexpression.h index 58edf80..fd2f56c 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -61,11 +61,6 @@ public: virtual int get_work_mode(); virtual void prepare_to_new_expression(); - virtual void set_column_prefix(const std::string & prefix); - virtual void set_column_prefix(const std::string & prefix, int index); - - virtual std::string get_column_prefix(); - virtual int get_column_prefix_index(); virtual void generate_from_model(PT::TextStream & stream, Model & model); @@ -73,6 +68,7 @@ public: // rename me virtual void allow_to_use_prefix(bool use_prefix); + virtual bool get_allow_to_use_prefix(); // give me a better name virtual void put_field_doc(Model & model, const void * field_pointer, bool insertable, bool updatable, bool is_primary_key, ModelEnv * model_env); @@ -89,7 +85,7 @@ public: if( work_mode == MORM_WORK_MODE_MODEL_FIELDS ) { - put_field_name(field_name, add_column_prefix); + put_field_name(field_name, add_column_prefix, model_env); } else if( work_mode == MORM_WORK_MODE_MODEL_SAVE_FIELDS ) @@ -98,7 +94,7 @@ public: PT::TextStream * old_out_stream = out_stream; out_stream = &str; - put_field_name(field_name, add_column_prefix); + put_field_name(field_name, add_column_prefix, model_env); out_stream = old_out_stream; if( model_env && model_env->finder_helper ) @@ -116,7 +112,7 @@ public: else if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES ) { - put_field_name(field_name); + put_field_name(field_name, add_column_prefix, model_env); put_name_value_separator(); put_field_value(field_value); } @@ -138,7 +134,7 @@ public: { field_before(); - put_field_name(field_name, add_column_prefix); + put_field_name(field_name, add_column_prefix, model_env); put_name_value_separator(); put_field_doc(model, reinterpret_cast(&field_value), insertable, updatable, is_primary_key, model_env); @@ -195,7 +191,7 @@ public: // else if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES ) { - put_field_name(field_name); + put_field_name(field_name); // what about model_env? put it here? put_name_value_separator(); put_field_value_list(field_value, model_connector, model_env); } @@ -233,10 +229,11 @@ public: } template - void field_to_stream(PT::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false) + void field_to_stream(PT::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false, + bool add_column_prefix = true, ModelEnv * model_env = nullptr) { this->out_stream = &stream; - field(field_name, field_value, insertable, updatable, is_primary_key); + field(field_name, field_value, insertable, updatable, is_primary_key, add_column_prefix, model_env); this->out_stream = nullptr; } @@ -266,6 +263,7 @@ public: //virtual void esc(void* val, PT::TextStream & stream); virtual void esc(const PT::Date & date, PT::TextStream & stream); + virtual void esc(const PT::TextStream & val,PT::TextStream & stream); @@ -275,16 +273,8 @@ protected: int work_mode; /* what to do: generating fields list, values list or fields-values list */ bool is_first_field; - // niech Stream bedzie jakims interfejsem z operatorami << dla standardowych typow - // albo w pikotoolsach dodać klase bazowa (intefejs) dla streamow - // i dodatkowo dodac loger ktory dziedziczy po niej i dodaje loglevel i endline - // jako metode bazowa dodac format("string", parametry,...) - // przyda sie do formatowania doubli PT::TextStream * out_stream; - - std::string column_prefix; - int column_prefix_index; bool use_prefix; virtual void generate_from_model(Model & model); @@ -297,7 +287,7 @@ protected: //void field(const wchar_t * field_name, Model & field, bool insertable = true, bool updatable = true); - virtual void put_field_name(const wchar_t * field_name, bool add_column_prefix = true); + virtual void put_field_name(const wchar_t * field_name, bool add_column_prefix = true, ModelEnv * model_env = nullptr); template void put_field_value(const FieldValue & field_value) diff --git a/src/dbconnector.cpp b/src/dbconnector.cpp index 35ba785..d74d1d2 100644 --- a/src/dbconnector.cpp +++ b/src/dbconnector.cpp @@ -151,7 +151,7 @@ DbExpression * DbConnector::get_expression() } -void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model, const std::string & column_prefix) +void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model) { allocate_default_expression_if_needed(); @@ -160,7 +160,6 @@ void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model db_expression->prepare_to_new_expression(); db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS); db_expression->set_output_type(MORM_OUTPUT_TYPE_SELECT_COLUMNS); - db_expression->set_column_prefix(column_prefix); db_expression->generate_from_model(stream, model); } } diff --git a/src/dbconnector.h b/src/dbconnector.h index 6d37ad6..e2f58e1 100644 --- a/src/dbconnector.h +++ b/src/dbconnector.h @@ -61,7 +61,7 @@ public: //virtual void clear_last_query_result(); - virtual void generate_select_columns(PT::TextStream & stream, Model & model, const std::string & column_prefix); + virtual void generate_select_columns(PT::TextStream & stream, Model & model); virtual void generate_insert_query(PT::TextStream & stream, Model & model); virtual void generate_update_query(PT::TextStream & stream, Model & model); virtual void generate_remove_query(PT::TextStream & stream, Model & model); diff --git a/src/finder.h b/src/finder.h index 7b7d76e..cf645f5 100644 --- a/src/finder.h +++ b/src/finder.h @@ -157,24 +157,17 @@ public: return was_query_error; } + std::wstring get_error_msg() { return last_query_error; } - Finder & prefix(const wchar_t * prefix) - { - PT::WideToUTF8(prefix, column_prefix); - return *this; - } - - Finder & prepare_to_select() { was_query_error = false; last_query_error.clear(); - column_prefix.clear(); has_autogenerated_select = false; if( model_connector ) @@ -256,34 +249,14 @@ public: if( model_connector && out_stream ) { + model.table_name(model.model_env->table_name); + model.table_name_for_join_as(model.model_env->table_name_simple); + model.model_env->table_index = finder_helper.add_join_table(model.model_env->table_name_simple); + (*out_stream) << "SELECT "; - - if( column_prefix.empty() ) - { - PT::TextStream prefix_stream; - model.table_name_for_join_as(prefix_stream); - - prefix_stream.to_string(column_prefix); - finder_helper.add_join_table(column_prefix); - } - - model.generate_select_columns(*out_stream, column_prefix); - (*out_stream) << " FROM "; - model.table_name(*out_stream); - - if( !column_prefix.empty() ) - { - (*out_stream) << " AS " << column_prefix; // what about escaping? - } - else - { - (*out_stream) << " AS "; - PT::TextStream str_tmp; - model.table_name_for_join_as(str_tmp); - (*out_stream) << str_tmp; - finder_helper.add_join_table(str_tmp); - } - + model.generate_select_columns(*out_stream); + (*out_stream) << " FROM " << model.model_env->table_name << " AS "; + (*out_stream) << model.model_env->table_name_simple; (*out_stream) << " "; (*out_stream) << finder_helper.morm_finder_join_tables; } @@ -369,7 +342,14 @@ public: if( db_expression ) { db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_EQ); - db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false); + + bool put_table_prefix = true; + + // IMPROVE ME + // add check if there is a dot char in field_name? + // or add a second eq() method with an additional parameter -- table name? + + db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, put_table_prefix, &model_env); } return *this; @@ -382,7 +362,7 @@ public: if( db_expression ) { db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LT); - db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false); + db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, true, &model_env); } return *this; @@ -395,7 +375,7 @@ public: if( db_expression ) { db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GT); - db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false); + db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, true, &model_env); } return *this; @@ -408,7 +388,7 @@ public: if( db_expression ) { db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LE); - db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false); + db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, true, &model_env); } return *this; @@ -421,7 +401,7 @@ public: if( db_expression ) { db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GE); - db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false); + db_expression->field_to_stream(*out_stream, field_name, field_value, false, false, false, true, &model_env); } return *this; @@ -596,7 +576,6 @@ private: ModelClass model; bool was_query_error; std::wstring last_query_error; - std::string column_prefix; ModelEnv model_env; FinderHelper finder_helper; ModelData * model_data; @@ -613,7 +592,6 @@ private: { db_expression = db_connector->get_expression(); db_expression->allow_to_use_prefix(true); - // set prefix maybe there to an empty string? } } } diff --git a/src/finderhelper.h b/src/finderhelper.h index 180eddb..ba1e3a8 100644 --- a/src/finderhelper.h +++ b/src/finderhelper.h @@ -51,6 +51,7 @@ public: std::list morm_foreign_keys; + FinderHelper() { } diff --git a/src/model.cpp b/src/model.cpp index a36452b..8770457 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -467,7 +467,7 @@ bool Model::save(ModelData & model_data) } -void Model::generate_select_columns(PT::TextStream & stream, const std::string & column_prefix) +void Model::generate_select_columns(PT::TextStream & stream) { if( model_connector && model_env ) { @@ -476,7 +476,7 @@ void Model::generate_select_columns(PT::TextStream & stream, const std::string & if( db_connector ) { - db_connector->generate_select_columns(stream, *this, column_prefix); + db_connector->generate_select_columns(stream, *this); } } } diff --git a/src/model.h b/src/model.h index 5be9e6d..7eec1cd 100644 --- a/src/model.h +++ b/src/model.h @@ -123,7 +123,7 @@ public: virtual bool save(ModelData * model_data = nullptr); virtual bool save(ModelData & model_data); - virtual void generate_select_columns(PT::TextStream & stream, const std::string & column_prefix); + virtual void generate_select_columns(PT::TextStream & stream); virtual void generate_doc_for_flat(PT::TextStream & stream, bool clear_stream = true); virtual void generate_doc_for_db(PT::TextStream & stream, bool clear_stream = true); @@ -722,53 +722,33 @@ protected: 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->finder_helper ) + if( model_env && field_model.model_env && model_env->finder_helper ) { - //model_env->select_helper->morm_current_max_column += 1; model_env->finder_helper->morm_foreign_keys.clear(); + field_model.model_env->table_index = model_env->finder_helper->add_join_table(field_model.model_env->table_name_simple); - model_env->finder_helper->morm_finder_join_tables << "LEFT JOIN "; - field_model.table_name(model_env->finder_helper->morm_finder_join_tables); - model_env->finder_helper->morm_finder_join_tables << " AS "; - - - ////////////// - PT::TextStream join_table_name_this; - table_name_for_join_as(join_table_name_this); - - if( model_env->table_index > 1 ) - join_table_name_this << model_env->table_index; - - /////////// - - PT::TextStream join_table_name; - field_model.table_name_for_join_as(join_table_name); - - field_model.model_env->table_index = model_env->finder_helper->add_join_table(join_table_name); + model_env->finder_helper->morm_finder_join_tables << "LEFT JOIN " << field_model.model_env->table_name + << " AS " << field_model.model_env->table_name_simple; if( field_model.model_env->table_index > 1 ) - join_table_name << field_model.model_env->table_index; - ////////// - - - model_env->finder_helper->morm_finder_join_tables << join_table_name; + model_env->finder_helper->morm_finder_join_tables << field_model.model_env->table_index; int expr_work_mode = db_expression->get_work_mode(); int expr_output_type = db_expression->get_output_type(); + bool expr_allow_prefix = db_expression->get_allow_to_use_prefix(); db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS); db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES); - db_expression->allow_to_use_prefix(false); if( has_foreign_key ) { field_model.map_fields(); - model_env->finder_helper->morm_finder_join_tables << " ON " << join_table_name_this << '.' << db_field_name; // escape? - model_env->finder_helper->morm_finder_join_tables << " = " << join_table_name << '.'; + model_env->finder_helper->morm_finder_join_tables << " ON " << model_env->table_name_simple << '.' + << db_field_name << " = " << field_model.model_env->table_name_simple << '.'; - if( !model_env->finder_helper->morm_foreign_keys.empty() ) + if( model_env->finder_helper->morm_foreign_keys.size() == 1 ) { model_env->finder_helper->morm_finder_join_tables << model_env->finder_helper->morm_foreign_keys.front(); } @@ -777,23 +757,21 @@ protected: { map_fields(); - model_env->finder_helper->morm_finder_join_tables << " ON " << join_table_name_this << '.'; + model_env->finder_helper->morm_finder_join_tables << " ON " << model_env->table_name_simple << '.'; - if( !model_env->finder_helper->morm_foreign_keys.empty() ) + if( model_env->finder_helper->morm_foreign_keys.size() == 1 ) { model_env->finder_helper->morm_finder_join_tables << model_env->finder_helper->morm_foreign_keys.front(); } - model_env->finder_helper->morm_finder_join_tables << " = " << (join_table_name) << '.' << db_field_name; + model_env->finder_helper->morm_finder_join_tables << " = " << field_model.model_env->table_name_simple << '.' << db_field_name; } model_env->finder_helper->morm_finder_join_tables << ' '; db_expression->set_work_mode(expr_work_mode); db_expression->set_output_type(expr_output_type); - - db_expression->allow_to_use_prefix(true); - + db_expression->allow_to_use_prefix(expr_allow_prefix); } } @@ -828,6 +806,9 @@ protected: { field_model.model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL; + field_model.table_name(field_model.model_env->table_name); + field_model.table_name_for_join_as(field_model.model_env->table_name_simple); + if( db_expression->get_output_type() == MORM_OUTPUT_TYPE_SELECT_COLUMNS ) { field_model_left_join(db_field_name, flat_field_name, field_model, insertable, updatable, has_foreign_key, db_expression); @@ -835,23 +816,7 @@ protected: if( db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES ) { - // they dont have to be copied out, this is the same as current table name and table_index - std::string current_prefix = db_expression->get_column_prefix(); - int current_table_index = db_expression->get_column_prefix_index(); - - /////////// - PT::TextStream join_table_name; - field_model.table_name_for_join_as(join_table_name); // RENAME this method - - std::string sss; // improve me - join_table_name.to_string(sss); - - // now we dont need set_column_prefix()?, we can pass ModelEnv there somewhat? - db_expression->set_column_prefix(sss, field_model.model_env->table_index); - field_model.map_fields(); - - db_expression->set_column_prefix(current_prefix, current_table_index); } field_model.model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE; @@ -912,7 +877,9 @@ protected: { if( model_connector && model_env ) { - ModelEnv model_env_local(*model_env); + ModelEnv model_env_local; + model_env_local.copy_global_objects(*model_env); + field_model.model_env = &model_env_local; field_model.set_connector(model_connector); diff --git a/src/modelenv.h b/src/modelenv.h index 6042d80..f6eb01d 100644 --- a/src/modelenv.h +++ b/src/modelenv.h @@ -53,9 +53,13 @@ public: CursorHelper * cursor_helper; int model_connector_mode; - int table_index; const void * doc_field_pointer; + PT::TextStream table_name; + PT::TextStream table_name_simple; + int table_index; + + ModelEnv() { @@ -79,14 +83,27 @@ public: } + void copy_global_objects(const ModelEnv & e) + { + model_data = e.model_data; + finder_helper = e.finder_helper; + cursor_helper = e.cursor_helper; + + model_connector_mode = e.model_connector_mode; + + // what about doc_field_pointer? + } + void clear() { model_data = nullptr; finder_helper = nullptr; cursor_helper = nullptr; model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE; - table_index = 0; doc_field_pointer = nullptr; + table_name.clear(); + table_name_simple.clear(); + table_index = 0; }