From 6619f3ecb53661090313f399b85c4bc39f030edb Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sat, 15 Jul 2023 03:08:02 +0200 Subject: [PATCH] fix: correctly use a table name when using Finder::use_table_prefix(true) We cannot use aliases in the form of "tablename"."fieldname" - now it was changed to "tablename.fieldname". Sample how to get the id field, assuming the table name is 'mymodel'. mymodel = finder2. select(morm::Select::no_auto_generated_columns). use_table_prefix(true). raw("SELECT id AS \"mymodel.id\""). raw("FROM mymodel"). raw("WHERE id = 25"). get(); In addition, there was an error that the table name was not correctly set for the first object in the hierarchy - it was empty, e.g. ""."field_name" --- src/baseexpression.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++ src/baseexpression.h | 7 +++++ src/cursor.h | 2 ++ src/dbexpression.cpp | 19 ++++++++++++ src/dbexpression.h | 4 +++ src/model.cpp | 2 +- src/model.h | 15 ++++++---- 7 files changed, 111 insertions(+), 6 deletions(-) diff --git a/src/baseexpression.cpp b/src/baseexpression.cpp index 4992532..b0a9275 100644 --- a/src/baseexpression.cpp +++ b/src/baseexpression.cpp @@ -307,6 +307,10 @@ void BaseExpression::table_field_separator() } +void BaseExpression::alias_names_separator() +{ +} + void BaseExpression::before_schema_name() { @@ -338,6 +342,16 @@ void BaseExpression::after_field_name() } +void BaseExpression::before_alias_name() +{ +} + + +void BaseExpression::after_alias_name() +{ +} + + void BaseExpression::before_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env) { before_field_value_string(field_type, model_env); @@ -988,6 +1002,7 @@ void BaseExpression::put_table_and_field(const wchar_t * table_name, const wchar } } + void BaseExpression::put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type) { if( out_stream ) @@ -999,6 +1014,42 @@ void BaseExpression::put_table_and_field(const pt::WTextStream & table_name, con } +void BaseExpression::put_alias(const pt::WTextStream & alias_name, int index) +{ + if( out_stream ) + { + before_alias_name(); + esc(alias_name, *out_stream); + + if( index > 1 ) + { + (*out_stream) << index; + } + + after_alias_name(); + } +} + + +void BaseExpression::put_alias(const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix) +{ + if( out_stream ) + { + before_alias_name(); + esc(alias_name_prefix, *out_stream); + + if( index > 1 ) + { + (*out_stream) << index; + } + + alias_names_separator(); + esc(alias_name_postfix, *out_stream); + after_alias_name(); + } +} + + void BaseExpression::put_string(const char * str, const FT & field_type, bool add_quotes) { @@ -1117,6 +1168,23 @@ void BaseExpression::table_and_field_to_stream(pt::TextStream & stream, const pt } +void BaseExpression::alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name, int index) +{ + this->out_stream = &stream; + put_alias(alias_name, index); + this->out_stream = nullptr; +} + + +void BaseExpression::alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix) +{ + this->out_stream = &stream; + put_alias(alias_name_prefix, index, alias_name_postfix); + this->out_stream = nullptr; +} + + + void BaseExpression::string_to_stream(pt::TextStream & stream, const char * str, const FT & field_type, bool add_quotes) { diff --git a/src/baseexpression.h b/src/baseexpression.h index 6f8e343..24af73c 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -241,6 +241,8 @@ public: virtual void put_table_with_index_and_field(const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type); virtual void put_table_and_field(const wchar_t * table_name, const wchar_t * field_name, const FT & field_type); virtual void put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type); + virtual void put_alias(const pt::WTextStream & alias_name, int index); + virtual void put_alias(const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix); virtual void put_string(const char * str, const FT & field_type, bool add_quotes = false); virtual void put_string(const wchar_t * str, const FT & field_type, bool add_quotes = false); @@ -259,6 +261,8 @@ public: virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type); virtual void table_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, const wchar_t * field_name, const FT & field_type); virtual void table_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type); + virtual void alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name, int index); + virtual void alias_to_stream(pt::TextStream & stream, const pt::WTextStream & alias_name_prefix, int index, const wchar_t * alias_name_postfix); virtual void string_to_stream(pt::TextStream & stream, const char * str, const FT & field_type, bool add_quotes = false); virtual void string_to_stream(pt::TextStream & stream, const wchar_t * str, const FT & field_type, bool add_quotes = false); @@ -599,6 +603,7 @@ protected: virtual void schema_table_separator(); virtual void table_field_separator(); + virtual void alias_names_separator(); virtual void before_schema_name(); virtual void after_schema_name(); @@ -609,6 +614,8 @@ protected: virtual void before_field_name(); virtual void after_field_name(); + virtual void before_alias_name(); + virtual void after_alias_name(); virtual void before_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env); virtual void after_field_value(const std::wstring &, const FT & field_type, ModelEnv * model_env); diff --git a/src/cursor.h b/src/cursor.h index 3ca4f06..a9ae900 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -229,6 +229,7 @@ public: if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values ) { + result.table(); result.model_env->add_table_name_to_finder_helper(); } @@ -417,6 +418,7 @@ protected: if( !cursor_helper.has_autogenerated_select && cursor_helper.use_table_prefix_for_fetching_values ) { + added_model.table(); added_model.model_env->add_table_name_to_finder_helper(); } diff --git a/src/dbexpression.cpp b/src/dbexpression.cpp index 8aa08a7..4e2b0ed 100644 --- a/src/dbexpression.cpp +++ b/src/dbexpression.cpp @@ -208,6 +208,12 @@ void DbExpression::table_field_separator() } +void DbExpression::alias_names_separator() +{ + (*out_stream) << '.'; +} + + void DbExpression::before_schema_name() { (*out_stream) << '"'; @@ -244,6 +250,19 @@ void DbExpression::after_field_name() } +void DbExpression::before_alias_name() +{ + (*out_stream) << '"'; +} + + +void DbExpression::after_alias_name() +{ + (*out_stream) << '"'; +} + + + void DbExpression::before_field_value_string(const FT & field_type, ModelEnv * model_env) { diff --git a/src/dbexpression.h b/src/dbexpression.h index bbe8f9f..3990020 100644 --- a/src/dbexpression.h +++ b/src/dbexpression.h @@ -90,6 +90,7 @@ protected: void schema_table_separator(); void table_field_separator(); + void alias_names_separator(); void before_schema_name(); void after_schema_name(); @@ -100,6 +101,9 @@ protected: void before_field_name(); void after_field_name(); + void before_alias_name(); + void after_alias_name(); + void add_additional_columns(Model & model); void before_field_value_string(const FT & field_type, ModelEnv * model_env); diff --git a/src/model.cpp b/src/model.cpp index 396b49c..1d3f9ee 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -1261,7 +1261,7 @@ void Model::field_model_left_join(const wchar_t * db_field_name, Model & field_m db_expression->schema_table_to_stream(join_tables_str, field_model.model_env->schema_name, field_model.model_env->table_name); join_tables_str << " AS "; - db_expression->table_with_index_to_stream(join_tables_str, field_model.model_env->table_name, field_model.model_env->table_index); + db_expression->alias_to_stream(join_tables_str, field_model.model_env->table_name, field_model.model_env->table_index); db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS); db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES); diff --git a/src/model.h b/src/model.h index d9fcd3c..6a15b03 100644 --- a/src/model.h +++ b/src/model.h @@ -1477,13 +1477,18 @@ protected: if( db_expression ) { - std::wstring table_field_name; pt::TextStream table_field_name_str; + db_expression->alias_to_stream(table_field_name_str, model_env->table_name, model_env->table_index, field_name); - // 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_str(table_field_name); - column_index = model_env->cursor_helper->query_result->get_column_index(table_field_name.c_str()); + if( table_field_name_str.size() < 256 ) + { + wchar_t alias_name[256]; + + if( table_field_name_str.to_str(alias_name, sizeof(alias_name) / sizeof(wchar_t)) ) + { + column_index = model_env->cursor_helper->query_result->get_column_index(alias_name); + } + } } } else