From a8fe798279df5b104754e546d028e96e6493ccc8 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sun, 20 Jun 2021 17:49:54 +0200 Subject: [PATCH] fixed: getters method (Model::*getter_method)(pt::Stream &) produced boolean value when serializing to flat string - changed in Model::field_list_generic(...): message "you should set FT::is_foreign_key or FT::is_foreign_key_in_child flag" print only for work mode MORM_MODEL_WORK_MODE_SET_PARENT_ID or MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY - pt::TextStream::to_string(...) is now pt::TextStream::to_str(...) - in Model::get_raw_value() for ezc 'pt::TextStream & stream' changed to 'pt::Stream & stream' (a base class of pt::TextStream) similar in field(...) methods which take getters: void (Model::*getter_method)(pt::TextStream &) -> void (Model::*getter_method)(pt::Stream &) --- src/baseexpression.cpp | 4 ++- src/baseexpression.h | 51 +++++++++++++++++++++++++------- src/dbconnector.cpp | 2 +- src/finderhelper.h | 4 +-- src/model.cpp | 16 +++++----- src/model.h | 59 ++++++++++++++++++++++--------------- src/modelenv.h | 2 +- src/postgresqlconnector.cpp | 12 ++++---- 8 files changed, 96 insertions(+), 54 deletions(-) diff --git a/src/baseexpression.cpp b/src/baseexpression.cpp index ee522f2..30260aa 100644 --- a/src/baseexpression.cpp +++ b/src/baseexpression.cpp @@ -220,7 +220,7 @@ void BaseExpression::save_foreign_key(const wchar_t * field_name, const FT & fie { model_env->finder_helper->foreign_keys.emplace_back(); std::string & key_str = model_env->finder_helper->foreign_keys.back(); - str.to_string(key_str, false); + str.to_str(key_str, false); } } @@ -408,6 +408,7 @@ void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_ { char utf8_buf[10]; + // FIXME surrogate pairs are not used size_t utf8_len = pt::int_to_utf8((int)val, utf8_buf, sizeof(utf8_buf)); for(size_t a = 0 ; a < utf8_len ; ++a) @@ -430,6 +431,7 @@ void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i) { + // FIXME surrogate pairs are not used size_t utf8_len = pt::int_to_utf8((int)val[i], utf8_buf, sizeof(utf8_buf)); for(size_t a = 0 ; a < utf8_len ; ++a) diff --git a/src/baseexpression.h b/src/baseexpression.h index db10ee2..273274e 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -79,9 +79,22 @@ public: virtual bool get_allow_to_use_prefix(); - template void field(const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env) + { + field_generic(field_name, field_value, nullptr, field_type, model_env); + } + + + virtual void field(const wchar_t * field_name, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env) + { + int tmp_object = 0; + field_generic(field_name, tmp_object, getter_method, field_type, model_env); + } + + + template + void field_generic(const wchar_t * field_name, const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env) { if( out_stream && can_field_be_generated(field_type) ) { @@ -99,7 +112,7 @@ public: else if( work_mode == MORM_WORK_MODE_MODEL_VALUES ) { - put_field_value_or_null(field_value, field_type, model_env); + put_field_value_or_null(field_value, getter_method, field_type, model_env); } else if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES ) @@ -110,7 +123,7 @@ public: { 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_or_null(field_value, field_type, model_env); + put_field_value_or_null(field_value, getter_method, field_type, model_env); } model_env->field_index += 1; @@ -119,7 +132,7 @@ public: { put_field_name_and_table_if_needed(field_name, field_type, model_env); put_name_value_separator(); - put_field_value_or_null(field_value, field_type, model_env); + put_field_value_or_null(field_value, getter_method, field_type, model_env); } } @@ -129,18 +142,25 @@ public: template - void put_field_value_or_null(const FieldValue & field_value, const FT & field_type, ModelEnv * model_env) + void put_field_value_or_null(const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env) { - if( field_type.is_primary_key() ) + if( getter_method ) { - if( model_env && model_env->has_primary_key_set ) - put_field_value(field_value, field_type); - else - put_null_value(); + put_field_value(getter_method, field_type, model_env); } else { - put_field_value(field_value, field_type); + if( field_type.is_primary_key() ) + { + if( model_env && model_env->has_primary_key_set ) + put_field_value(field_value, field_type); + else + put_null_value(); + } + else + { + put_field_value(field_value, field_type); + } } } @@ -321,6 +341,15 @@ protected: } } + void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env) + { + if( out_stream && model_env && model_env->model && getter_method ) + { + before_field_value_string(field_type); + (model_env->model->*getter_method)(*out_stream); + after_field_value_string(field_type); + } + } virtual void put_null_value() { diff --git a/src/dbconnector.cpp b/src/dbconnector.cpp index 24f13dc..ae312a3 100644 --- a/src/dbconnector.cpp +++ b/src/dbconnector.cpp @@ -110,7 +110,7 @@ bool DbConnector::query(const char * query_str) bool DbConnector::query(const pt::TextStream & stream, QueryResult & query_result) { std::string query_str; - stream.to_string(query_str); + stream.to_str(query_str); return query(query_str, query_result); } diff --git a/src/finderhelper.h b/src/finderhelper.h index b0adf7b..e90a59c 100644 --- a/src/finderhelper.h +++ b/src/finderhelper.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2019, Tomasz Sowa + * Copyright (c) 2019-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ public: virtual int add_join_table(const pt::WTextStream & table_name) { std::wstring table_name_str; - table_name.to_string(table_name_str); + table_name.to_str(table_name_str); return add_join_table(table_name_str); } diff --git a/src/model.cpp b/src/model.cpp index ac0e95f..326a9c9 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -227,7 +227,7 @@ void Model::get_table_name(std::wstring & str, bool with_schema_name, ModelData str.clear(); get_table_name(stream, with_schema_name, model_data, false); - stream.to_string(str); + stream.to_str(str); } @@ -317,13 +317,13 @@ ModelWrapper * Model::get_model_wrapper(const wchar_t * db_field_name, const wch -bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::TextStream & stream, bool clear_stream, bool put_log_if_not_found) +bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream, bool put_log_if_not_found) { return get_raw_value(db_field_name, flat_field_name, nullptr, stream, clear_stream, put_log_if_not_found); } -bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::TextStream & stream, bool clear_stream, bool put_log_if_not_found) +bool Model::get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::Stream & stream, bool clear_stream, bool put_log_if_not_found) { if( clear_stream ) { @@ -432,7 +432,7 @@ void Model::to_text(std::string & str, ModelData * model_data, bool clear_string if( out_stream ) { to_text(*out_stream, model_data, true, dump_mode); - out_stream->to_string(str, clear_string); + out_stream->to_str(str, clear_string); } } } @@ -1762,7 +1762,7 @@ void Model::field_member_set_field_value( void Model::field_member_generate_flat_string( const wchar_t * flat_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), const FT & field_type) { FlatConnector * flat_connector = model_connector->get_flat_connector(); @@ -1781,7 +1781,7 @@ void Model::field_member_generate_flat_string( void Model::field_member_generate_db_sql( const wchar_t * db_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), const FT & field_type) { DbConnector * db_connector = model_connector->get_db_connector(); @@ -1834,7 +1834,7 @@ void Model::field_member_read_value_from_db_resultset( void Model::field_member_put_field_raw_value_to_stream( const wchar_t * db_field_name, const wchar_t * flat_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), const FT & field_type) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && @@ -1862,7 +1862,7 @@ void Model::field_member_clear_value( void Model::field_member( const wchar_t * db_field_name, const wchar_t * flat_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), void (Model::*setter_method)(const char * input_str), const FT & field_type) { diff --git a/src/model.h b/src/model.h index d637369..f0ec914 100644 --- a/src/model.h +++ b/src/model.h @@ -58,7 +58,7 @@ #define MORM_MODEL_MEMBER_FIELD(ClassName) \ void field(const wchar_t * field_name, \ - void (ClassName::*getter_method)(pt::TextStream &), \ + void (ClassName::*getter_method)(pt::Stream &), \ void (ClassName::*setter_method)(const char * input_str), \ const morm::FT & field_type = morm::FT::default_type) \ { \ @@ -66,11 +66,11 @@ }\ void field(const wchar_t * db_field_name, \ const wchar_t * flat_field_name, \ - void (ClassName::*getter_method)(pt::TextStream &), \ + void (ClassName::*getter_method)(pt::Stream &), \ 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::*ModelGetterMethod)(pt::Stream &); \ typedef void (Model::*ModelSetterMethod)(const char * input_str); \ ModelGetterMethod model_getter_method = static_cast(getter_method); \ ModelSetterMethod model_setter_method = static_cast(setter_method); \ @@ -255,15 +255,15 @@ public: Model * get_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool put_log_if_not_found = true); ModelWrapper * get_model_wrapper(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool put_log_if_not_found = true); - bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::TextStream & stream, bool clear_stream = true, bool put_log_if_not_found = true); - bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::TextStream & stream, bool clear_stream = true, bool put_log_if_not_found = true); + bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream = true, bool put_log_if_not_found = true); + bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::Stream & stream, bool clear_stream = true, bool put_log_if_not_found = true); #ifdef MORM_HAS_EZC_LIBRARY template bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, - Ezc::FunInfo & fun_info, pt::TextStream & stream, bool clear_stream = true) + Ezc::FunInfo & fun_info, pt::Stream & stream, bool clear_stream = true) { if( clear_stream ) { @@ -831,12 +831,12 @@ protected: void field_member_generate_flat_string( const wchar_t * flat_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), const FT & field_type); void field_member_generate_db_sql( const wchar_t * db_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), const FT & field_type); void field_member_read_value_from_db_resultset( @@ -847,7 +847,7 @@ protected: void field_member_put_field_raw_value_to_stream( const wchar_t * db_field_name, const wchar_t * flat_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), const FT & field_type); void field_member_clear_value( @@ -857,7 +857,7 @@ protected: void field_member( const wchar_t * db_field_name, const wchar_t * flat_field_name, - void (Model::*getter_method)(pt::TextStream &), + void (Model::*getter_method)(pt::Stream &), void (Model::*setter_method)(const char * input_str), const FT & field_type); @@ -1270,39 +1270,50 @@ protected: } } - if( field_type.is_foreign_key() || field_type.is_foreign_key_in_child() ) + if constexpr (std::is_base_of()) { - if constexpr (std::is_base_of()) + bool print_need_foreign_key_option = false; + + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_SET_PARENT_ID ) { - if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_SET_PARENT_ID ) + if( field_type.is_foreign_key() || field_type.is_foreign_key_in_child() ) { field_list_set_parent_key(db_field_name, field_container, model_container_type, foo); } + else + { + print_need_foreign_key_option = true; + } + } - if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY ) + if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY ) + { + if( field_type.is_foreign_key() || field_type.is_foreign_key_in_child() ) { // IMPROVEME it would be good to make some optimisation before going through all items // such as: if UPDATE is called then we check if field_type allows to make update field_list_iterate_through_childs(field_container, model_container_type, field_type, foo); } - } - else - { - if( plog ) + else { - (*plog) << pt::Log::log1 << "Morm: ignoring "; - log_table_name_with_field(db_field_name); - (*plog) << " as this is not a container with Model objects" << pt::Log::logend; + print_need_foreign_key_option = true; } } + + if( print_need_foreign_key_option && plog ) + { + (*plog) << pt::Log::log1 << "Morm: error in "; + log_table_name_with_field(db_field_name); + (*plog) << " field, you should set FT::is_foreign_key or FT::is_foreign_key_in_child flag for a list of child objects" << pt::Log::logend; + } } else { if( plog ) { - (*plog) << pt::Log::log1 << "Morm: error in "; + (*plog) << pt::Log::log1 << "Morm: ignoring "; log_table_name_with_field(db_field_name); - (*plog) << " field, you should set FT::is_foreign_key or FT::is_foreign_key_in_child flag for a list of child objects" << pt::Log::logend; + (*plog) << " as this is not a container with Model objects" << pt::Log::logend; } } } @@ -1370,7 +1381,7 @@ protected: // CHECK ME not tested yet after changing to db_expression->table_with_index_and_field_to_stream() db_expression->table_with_index_and_field_to_stream(table_field_name_str, model_env->table_name, model_env->table_index, field_name, field_type); - table_field_name_str.to_string(table_field_name); + table_field_name_str.to_str(table_field_name); column_index = model_env->cursor_helper->query_result->get_column_index(table_field_name.c_str()); } } diff --git a/src/modelenv.h b/src/modelenv.h index 1a796f7..6124832 100644 --- a/src/modelenv.h +++ b/src/modelenv.h @@ -93,7 +93,7 @@ public: Model * model; Model * child_model; ModelWrapper * model_wrapper; - pt::TextStream * stream; + pt::Stream * stream; bool was_field_found; // used only in MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM diff --git a/src/postgresqlconnector.cpp b/src/postgresqlconnector.cpp index a9fec7d..1a6422b 100644 --- a/src/postgresqlconnector.cpp +++ b/src/postgresqlconnector.cpp @@ -193,7 +193,7 @@ const char * PostgreSQLConnector::query_last_sequence(const wchar_t * sequence_t bool PostgreSQLConnector::query(const pt::TextStream & stream, QueryResult & query_result) { - stream.to_string(query_str); + stream.to_str(query_str); return query(query_str.c_str(), query_result); } @@ -266,25 +266,25 @@ bool PostgreSQLConnector::query_remove(const char * query_str, QueryResult & que bool PostgreSQLConnector::query_select(const pt::TextStream & stream, QueryResult & query_result) { - stream.to_string(query_str); + stream.to_str(query_str); return query_select(query_str.c_str(), query_result); } bool PostgreSQLConnector::query_update(const pt::TextStream & stream, QueryResult & query_result) { - stream.to_string(query_str); + stream.to_str(query_str); return query_update(query_str.c_str(), query_result); } bool PostgreSQLConnector::query_insert(const pt::TextStream & stream, QueryResult & query_result) { - stream.to_string(query_str); + stream.to_str(query_str); return query_insert(query_str.c_str(), query_result); } bool PostgreSQLConnector::query_remove(const pt::TextStream & stream, QueryResult & query_result) { - stream.to_string(query_str); + stream.to_str(query_str); return query_remove(query_str.c_str(), query_result); } @@ -438,7 +438,7 @@ void PostgreSQLConnector::connect() stream << "'"; std::string str; - stream.to_string(str); + stream.to_str(str); pg_conn = PQconnectdb(str.c_str()); overwrite(stream);