From 476e5de29230237a6d977e5b9f18813eb797ba2f Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 18 Apr 2018 17:52:09 +0000 Subject: [PATCH] added support for 'in()' statement in 'select' git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1086 e52654a7-88a9-db11-a3e9-0013d4bc506e --- src/baseexpression.h | 64 +++++++++++++++++++++++++++++++++++++++++--- src/dbconnector.cpp | 2 +- src/dbexpression.cpp | 8 +++++- src/finder.h | 49 +++++++++++++++++++++++++++++++++ src/model.cpp | 13 ++++++--- src/model.h | 4 +-- src/modelconnector.h | 2 +- src/morm_types.h | 1 + 8 files changed, 131 insertions(+), 12 deletions(-) diff --git a/src/baseexpression.h b/src/baseexpression.h index db193bf..52a9d8d 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -36,6 +36,7 @@ #define headerfile_morm_baseexpression #include +#include #include "textstream/textstream.h" #include "morm_types.h" #include "date/date.h" @@ -86,6 +87,24 @@ public: } + template + void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::set & container) + { + field_in_generic>(stream, field_name, container); + } + + template + void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::list & container) + { + field_in_generic>(stream, field_name, container); + } + + template + void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::vector & container) + { + field_in_generic>(stream, field_name, container); + } + template void field_list(const wchar_t * field_name, const std::list & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false) { @@ -114,6 +133,7 @@ public: } } + template void field(PT::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false) { @@ -187,11 +207,15 @@ protected: template void put_field_value(const FieldValue & field_value) { - before_field_value(field_value); - esc(field_value, *out_stream); - after_field_value(field_value); + if( out_stream ) + { + before_field_value(field_value); + esc(field_value, *out_stream); + after_field_value(field_value); + } } + template void put_field_value_list(const std::list & field_value) { @@ -225,6 +249,40 @@ protected: } } + + // used in 'in()' statements, may should be renamed? + template + void field_in_generic(PT::TextStream & stream, const wchar_t * field_name, const Container & container) + { + // IMPROVE ME + // what about if container is empty? + // only 'in()' statement would be generated + this->out_stream = &stream; + + field_before(); + put_field_name(field_name); + put_name_value_separator(); + + bool is_first = true; + (*out_stream) << "("; + + for(const FieldValue & v : container) + { + if( !is_first ) + { + (*out_stream) << ","; + } + + put_field_value(v); + is_first = false; + } + + (*out_stream) << ") "; + field_after(); + this->out_stream = nullptr; + } + + virtual void before_field_name(); virtual void after_field_name(); diff --git a/src/dbconnector.cpp b/src/dbconnector.cpp index 5360c24..2f8b95d 100644 --- a/src/dbconnector.cpp +++ b/src/dbconnector.cpp @@ -460,7 +460,7 @@ void DbConnector::get_value(const char * value_str, long double & field_value) void DbConnector::get_value(const char * value_str, PT::Date & field_value) { // IMPROVE ME give some log if parsing failed - bool res = field_value.Parse(value_str); + field_value.Parse(value_str); } diff --git a/src/dbexpression.cpp b/src/dbexpression.cpp index e62a199..4f4e67d 100644 --- a/src/dbexpression.cpp +++ b/src/dbexpression.cpp @@ -102,7 +102,8 @@ void DbExpression::field_before() output_type == MORM_OUTPUT_TYPE_WHERE_GE || output_type == MORM_OUTPUT_TYPE_WHERE_GT || output_type == MORM_OUTPUT_TYPE_WHERE_LE || - output_type == MORM_OUTPUT_TYPE_WHERE_LT ) + output_type == MORM_OUTPUT_TYPE_WHERE_LT || + output_type == MORM_OUTPUT_TYPE_WHERE_IN ) { int conjunction = MORM_CONJUNCTION_AND; @@ -152,6 +153,11 @@ void DbExpression::put_name_value_separator() { (*out_stream) << " >= "; } + else + if( output_type == MORM_OUTPUT_TYPE_WHERE_IN ) + { + (*out_stream) << " in "; + } } diff --git a/src/finder.h b/src/finder.h index 0c4f03e..4ed4d19 100644 --- a/src/finder.h +++ b/src/finder.h @@ -37,6 +37,7 @@ #include #include +#include #include "model.h" #include "textstream/textstream.h" #include "dbconnector.h" @@ -263,6 +264,54 @@ public: } + + template + Finder & in(const wchar_t * field_name, const std::set & container) + { + if( db_expression ) + { + db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN); + db_expression->field_in(*out_stream, field_name, container); + } + + return *this; + } + + template + Finder & in(const wchar_t * field_name, const std::list & container) + { + if( db_expression ) + { + db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN); + db_expression->field_in(*out_stream, field_name, container); + } + + return *this; + } + + template + Finder & in(const wchar_t * field_name, const std::vector & container) + { + if( db_expression ) + { + db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_IN); + db_expression->field_in(*out_stream, field_name, container); + } + + return *this; + } + + Finder & raw_sql(const char * sql) + { + if( out_stream ) + { + (*out_stream) << " " << sql << " "; + } + + return *this; + } + + bool get(ModelClass & result) { bool res = false; diff --git a/src/model.cpp b/src/model.cpp index 4351a98..3e04bf2 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -76,8 +76,13 @@ bool Model::found() -void Model::to_text(PT::TextStream & stream) +void Model::to_text(PT::TextStream & stream, bool clear_stream) { + if( clear_stream ) + { + stream.clear(); + } + if( model_connector ) { model_connector->to_text(stream, *this); @@ -85,12 +90,12 @@ void Model::to_text(PT::TextStream & stream) } -void Model::to_text(std::string & str) +void Model::to_text(std::string & str, bool clear_string) { PT::TextStream stream; - to_text(stream); - stream.to_string(str); + to_text(stream, false); + stream.to_string(str, clear_string); } diff --git a/src/model.h b/src/model.h index d37fdb1..7281e5d 100644 --- a/src/model.h +++ b/src/model.h @@ -70,8 +70,8 @@ public: virtual void table_name(PT::TextStream & stream); - virtual void to_text(PT::TextStream & stream); - virtual void to_text(std::string & str); + virtual void to_text(PT::TextStream & stream, bool clear_stream = true); + virtual void to_text(std::string & str, bool clear_string = true); virtual std::string to_text(); virtual std::string to_string(); diff --git a/src/modelconnector.h b/src/modelconnector.h index 8b2218c..13e0d35 100644 --- a/src/modelconnector.h +++ b/src/modelconnector.h @@ -163,7 +163,7 @@ protected: template void field_list(const wchar_t * field_name, std::list & field_list, bool insertable = true, bool updatable = true, bool is_primary_key = false) { - if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_EXPRESSION && flat_connector && out_stream ) + if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_EXPRESSION && flat_connector ) { FlatExpression * flat_expression = flat_connector->get_expression(); diff --git a/src/morm_types.h b/src/morm_types.h index 14e4ee6..9434a5d 100644 --- a/src/morm_types.h +++ b/src/morm_types.h @@ -68,6 +68,7 @@ #define MORM_OUTPUT_TYPE_WHERE_GT 9 #define MORM_OUTPUT_TYPE_WHERE_LE 10 #define MORM_OUTPUT_TYPE_WHERE_GE 11 +#define MORM_OUTPUT_TYPE_WHERE_IN 12 #define MORM_CONJUNCTION_AND 1