added support for 'in()' statement in 'select'

git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1086 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2018-04-18 17:52:09 +00:00
parent ffb7ac85a6
commit 476e5de292
8 changed files with 131 additions and 12 deletions

View File

@@ -36,6 +36,7 @@
#define headerfile_morm_baseexpression #define headerfile_morm_baseexpression
#include <list> #include <list>
#include <set>
#include "textstream/textstream.h" #include "textstream/textstream.h"
#include "morm_types.h" #include "morm_types.h"
#include "date/date.h" #include "date/date.h"
@@ -86,6 +87,24 @@ public:
} }
template<typename FieldValue>
void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::set<FieldValue> & container)
{
field_in_generic<FieldValue, std::set<FieldValue>>(stream, field_name, container);
}
template<typename FieldValue>
void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::list<FieldValue> & container)
{
field_in_generic<FieldValue, std::list<FieldValue>>(stream, field_name, container);
}
template<typename FieldValue>
void field_in(PT::TextStream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container)
{
field_in_generic<FieldValue, std::vector<FieldValue>>(stream, field_name, container);
}
template<typename ModelClass> template<typename ModelClass>
void field_list(const wchar_t * field_name, const std::list<ModelClass> & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false) void field_list(const wchar_t * field_name, const std::list<ModelClass> & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
{ {
@@ -114,6 +133,7 @@ public:
} }
} }
template<typename FieldValue> template<typename FieldValue>
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) 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<typename FieldValue> template<typename FieldValue>
void put_field_value(const FieldValue & field_value) void put_field_value(const FieldValue & field_value)
{ {
before_field_value(field_value); if( out_stream )
esc(field_value, *out_stream); {
after_field_value(field_value); before_field_value(field_value);
esc(field_value, *out_stream);
after_field_value(field_value);
}
} }
template<typename ModelClass> template<typename ModelClass>
void put_field_value_list(const std::list<ModelClass> & field_value) void put_field_value_list(const std::list<ModelClass> & field_value)
{ {
@@ -225,6 +249,40 @@ protected:
} }
} }
// used in 'in()' statements, may should be renamed?
template<typename FieldValue, typename Container>
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 before_field_name();
virtual void after_field_name(); virtual void after_field_name();

View File

@@ -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) void DbConnector::get_value(const char * value_str, PT::Date & field_value)
{ {
// IMPROVE ME give some log if parsing failed // IMPROVE ME give some log if parsing failed
bool res = field_value.Parse(value_str); field_value.Parse(value_str);
} }

View File

@@ -102,7 +102,8 @@ void DbExpression::field_before()
output_type == MORM_OUTPUT_TYPE_WHERE_GE || output_type == MORM_OUTPUT_TYPE_WHERE_GE ||
output_type == MORM_OUTPUT_TYPE_WHERE_GT || output_type == MORM_OUTPUT_TYPE_WHERE_GT ||
output_type == MORM_OUTPUT_TYPE_WHERE_LE || 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; int conjunction = MORM_CONJUNCTION_AND;
@@ -152,6 +153,11 @@ void DbExpression::put_name_value_separator()
{ {
(*out_stream) << " >= "; (*out_stream) << " >= ";
} }
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_IN )
{
(*out_stream) << " in ";
}
} }

View File

@@ -37,6 +37,7 @@
#include <vector> #include <vector>
#include <list> #include <list>
#include <set>
#include "model.h" #include "model.h"
#include "textstream/textstream.h" #include "textstream/textstream.h"
#include "dbconnector.h" #include "dbconnector.h"
@@ -263,6 +264,54 @@ public:
} }
template<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * field_name, const std::set<FieldValue> & 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<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * field_name, const std::list<FieldValue> & 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<typename FieldValue>
Finder<ModelClass> & in(const wchar_t * field_name, const std::vector<FieldValue> & 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<ModelClass> & raw_sql(const char * sql)
{
if( out_stream )
{
(*out_stream) << " " << sql << " ";
}
return *this;
}
bool get(ModelClass & result) bool get(ModelClass & result)
{ {
bool res = false; bool res = false;

View File

@@ -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 ) if( model_connector )
{ {
model_connector->to_text(stream, *this); 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; PT::TextStream stream;
to_text(stream); to_text(stream, false);
stream.to_string(str); stream.to_string(str, clear_string);
} }

View File

@@ -70,8 +70,8 @@ public:
virtual void table_name(PT::TextStream & stream); virtual void table_name(PT::TextStream & stream);
virtual void to_text(PT::TextStream & stream); virtual void to_text(PT::TextStream & stream, bool clear_stream = true);
virtual void to_text(std::string & str); virtual void to_text(std::string & str, bool clear_string = true);
virtual std::string to_text(); virtual std::string to_text();
virtual std::string to_string(); virtual std::string to_string();

View File

@@ -163,7 +163,7 @@ protected:
template<typename ModelClass> template<typename ModelClass>
void field_list(const wchar_t * field_name, std::list<ModelClass> & field_list, bool insertable = true, bool updatable = true, bool is_primary_key = false) void field_list(const wchar_t * field_name, std::list<ModelClass> & 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(); FlatExpression * flat_expression = flat_connector->get_expression();

View File

@@ -68,6 +68,7 @@
#define MORM_OUTPUT_TYPE_WHERE_GT 9 #define MORM_OUTPUT_TYPE_WHERE_GT 9
#define MORM_OUTPUT_TYPE_WHERE_LE 10 #define MORM_OUTPUT_TYPE_WHERE_LE 10
#define MORM_OUTPUT_TYPE_WHERE_GE 11 #define MORM_OUTPUT_TYPE_WHERE_GE 11
#define MORM_OUTPUT_TYPE_WHERE_IN 12
#define MORM_CONJUNCTION_AND 1 #define MORM_CONJUNCTION_AND 1