some work for SELECT statement

git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1077 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2018-03-30 19:34:45 +00:00
parent d84ca900c3
commit fceec43d07
16 changed files with 605 additions and 105 deletions

View File

@ -33,7 +33,15 @@ dbexpression.o: ../../pikotools/convert/strtoint.h
dbexpression.o: ../../pikotools/convert/text.h ../../pikotools/convert/misc.h
dbexpression.o: ../../pikotools/membuffer/membuffer.h
dbexpression.o: ../../pikotools/textstream/types.h morm_types.h
finder.o: finder.h
finder.o: finder.h model.h ../../pikotools/textstream/textstream.h
finder.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
finder.o: ../../pikotools/date/date.h ../../pikotools/convert/convert.h
finder.o: ../../pikotools/convert/inttostr.h
finder.o: ../../pikotools/convert/strtoint.h ../../pikotools/convert/text.h
finder.o: ../../pikotools/convert/misc.h
finder.o: ../../pikotools/membuffer/membuffer.h
finder.o: ../../pikotools/textstream/types.h modelconnector.h
finder.o: baseexpression.h morm_types.h dbconnector.h dbexpression.h
flatconnector.o: flatconnector.h flatexpression.h baseexpression.h
flatconnector.o: ../../pikotools/textstream/textstream.h
flatconnector.o: ../../pikotools/space/space.h

View File

@ -140,6 +140,27 @@ void BaseExpression::after_field_value(const std::string &)
}
void BaseExpression::before_field_value(const wchar_t *)
{
}
void BaseExpression::after_field_value(const wchar_t *)
{
}
void BaseExpression::before_field_value(const char *)
{
}
void BaseExpression::after_field_value(const char *)
{
}
void BaseExpression::put_name_value_separator()
{
(*out_stream) << ',';

View File

@ -53,10 +53,39 @@ public:
BaseExpression();
virtual ~BaseExpression();
virtual void set_work_mode(int work_mode);
virtual void generate_from_model(PT::TextStream & stream, Model & model);
template<typename FieldValue>
void field(const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
{
if( can_field_be_generated(insertable, updatable, is_primary_key) )
{
field_before();
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
{
put_field_name(field_name);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
{
put_field_value(field_value);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name(field_name);
put_name_value_separator();
put_field_value(field_value);
}
field_after();
}
}
protected:
@ -86,32 +115,6 @@ protected:
virtual void field_before();
virtual void field_after();
template<typename FieldValue>
void field(const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
{
if( can_field_be_generated(insertable, updatable, is_primary_key) )
{
field_before();
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
{
put_field_name(field_name);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
{
put_field_value(field_value);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
print_field_name_value(field_name, field_value);
}
field_after();
}
}
//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);
@ -134,6 +137,13 @@ protected:
virtual void before_field_value(const std::string &);
virtual void after_field_value(const std::string &);
virtual void before_field_value(const wchar_t *);
virtual void after_field_value(const wchar_t *);
virtual void before_field_value(const char *);
virtual void after_field_value(const char *);
template<typename FieldValue>
void before_field_value(const FieldValue &)
{
@ -181,14 +191,6 @@ protected:
*/
template<typename FieldValue>
void print_field_name_value(const wchar_t * field_name, const FieldValue & field_value)
{
put_field_name(field_name);
put_name_value_separator();
put_field_value(field_value);
}
/*
template<typename Container>
@ -228,6 +230,7 @@ protected:
virtual void esc(const std::wstring & val, PT::TextStream & stream);
virtual void esc(const wchar_t * val, PT::TextStream & stream);
virtual void esc(const std::string & val, PT::TextStream & stream);
virtual void esc(const char * val, PT::TextStream & stream);
@ -245,7 +248,6 @@ protected:
virtual void esc(long double val, PT::TextStream & stream);
virtual void esc(void* val, PT::TextStream & stream);
friend ModelConnector;
};

View File

@ -93,6 +93,18 @@ DbExpression * DbConnector::get_expression()
}
void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model)
{
allocate_default_expression_if_needed();
if( db_expression )
{
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_FIELDS);
db_expression->set_output_type(MORM_OUTPUT_TYPE_SELECT_COLUMNS);
db_expression->generate_from_model(stream, model);
}
}
void DbConnector::generate_insert_query(PT::TextStream & stream, Model & model)
{
@ -181,4 +193,7 @@ void DbConnector::allocate_default_expression_if_needed()
}
}
}

View File

@ -53,6 +53,8 @@ public:
virtual ~DbConnector();
DbExpression * get_expression();
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);
@ -65,6 +67,7 @@ public:
virtual bool query(const wchar_t * query);
virtual bool query(const char * query);
protected:
DbExpression * db_expression;

View File

@ -87,7 +87,8 @@ void DbExpression::field_before()
if( !is_first_field )
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE )
output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
output_type == MORM_OUTPUT_TYPE_SELECT_COLUMNS )
{
(*out_stream) << ",";
}
@ -96,15 +97,70 @@ void DbExpression::field_before()
{
(*out_stream) << " AND ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_EQ ||
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 )
{
int conjunction = MORM_CONJUNCTION_AND;
if( !conjunctions.empty() )
{
conjunction = conjunctions.back();
}
if( conjunction == MORM_CONJUNCTION_AND )
{
(*out_stream) << " AND ";
}
else
if( conjunction == MORM_CONJUNCTION_OR )
{
(*out_stream) << " OR ";
}
}
}
}
void DbExpression::put_name_value_separator()
{
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY ||
output_type == MORM_OUTPUT_TYPE_WHERE_EQ )
{
(*out_stream) << " = ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_LT )
{
(*out_stream) << " < ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_GT )
{
(*out_stream) << " > ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_LE )
{
(*out_stream) << " <= ";
}
else
if( output_type == MORM_OUTPUT_TYPE_WHERE_GE )
{
(*out_stream) << " >= ";
}
}
void DbExpression::before_field_value_string()
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
// if( output_type == MORM_OUTPUT_TYPE_SELECT_COLUMNS ||
// output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << "'";
}
@ -112,9 +168,10 @@ void DbExpression::before_field_value_string()
void DbExpression::after_field_value_string()
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
// if( output_type == MORM_OUTPUT_TYPE_SELECT_COLUMNS ||
// output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << "'";
}
@ -126,22 +183,81 @@ void DbExpression::before_field_value(const std::wstring &)
before_field_value_string();
}
void DbExpression::before_field_value(const std::string &)
{
before_field_value_string();
}
void DbExpression::after_field_value(const std::wstring &)
{
after_field_value_string();
}
void DbExpression::before_field_value(const std::string &)
{
before_field_value_string();
}
void DbExpression::after_field_value(const std::string &)
{
after_field_value_string();
}
void DbExpression::before_field_value(const wchar_t *)
{
before_field_value_string();
}
void DbExpression::after_field_value(const wchar_t *)
{
after_field_value_string();
}
void DbExpression::before_field_value(const char *)
{
before_field_value_string();
}
void DbExpression::after_field_value(const char *)
{
after_field_value_string();
}
void DbExpression::prepare_to_where_clause()
{
work_mode = MORM_WORK_MODE_MODEL_FIELDS_VALUES;
conjunctions.clear();
is_first_field = true;
}
DbExpression & DbExpression::group_or()
{
field_before();
(*out_stream) << "(";
is_first_field = true;
conjunctions.push_back(MORM_CONJUNCTION_OR);
return *this;
}
DbExpression & DbExpression::group_and()
{
field_before();
(*out_stream) << "(";
is_first_field = true;
conjunctions.push_back(MORM_CONJUNCTION_AND);
return *this;
}
DbExpression & DbExpression::group_end()
{
if( !conjunctions.empty() )
{
conjunctions.pop_back();
(*out_stream) << ")";
field_after();
}
return *this;
}
}

View File

@ -35,6 +35,7 @@
#ifndef headerfile_morm_dbexpression
#define headerfile_morm_dbexpression
#include <vector>
#include "baseexpression.h"
#include "morm_types.h"
@ -52,35 +53,39 @@ public:
virtual void set_output_type(int output_type);
virtual void prepare_to_where_clause();
// may better names?
virtual DbExpression & group_or();
virtual DbExpression & group_and();
virtual DbExpression & group_end();
protected:
int output_type;
std::vector<int> conjunctions;
bool can_field_be_generated(bool insertable, bool updatable, bool is_primary_key);
void field_before();
void before_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::string &);
void before_field_value(const wchar_t *);
void after_field_value(const wchar_t *);
void before_field_value(const char *);
void after_field_value(const char *);
template<typename FieldValue>
void print_field_name_value(const wchar_t * field_name, const FieldValue & field_value)
{
put_field_name(field_name);
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << " = ";
}
put_field_value(field_value);
}
void put_name_value_separator();
private:
@ -89,30 +94,6 @@ private:
void after_field_value_string();
// DbExpression & eq(const wchar_t * field_name, const std::wstring & field_value)
// {
// //put_field_name(field_name);
// return *this;
// }
//
// DbExpression & eq(const wchar_t * field_name, const std::string & field_value)
// {
//
// return *this;
// }
//
// template<typename FieldValue>
// DbExpression & eq(const wchar_t * field_name, const FieldValue & field_value)
// {
// return *this;
// }
};
}

View File

@ -35,23 +35,252 @@
#ifndef headerfile_morm_finder
#define headerfile_morm_finder
#include <vector>
#include "model.h"
#include "textstream/textstream.h"
#include "dbconnector.h"
#include "modelconnector.h"
namespace morm
{
template<typename ModelClass>
class Finder
{
public:
Finder()
{
model_connector = nullptr;
out_stream = nullptr;
db_expression = nullptr;
}
Finder(ModelConnector & model_connector)
{
this->model_connector = &model_connector;
out_stream = nullptr;
db_expression = nullptr;
}
Finder(PT::TextStream & out_stream, ModelConnector & model_connector)
{
this->model_connector = &model_connector;
this->out_stream = &out_stream;
db_expression = nullptr;
}
Finder<ModelClass> & find(ModelConnector & model_connector)
{
this->model_connector = &model_connector;
return find();
}
Finder<ModelClass> & find(PT::TextStream & out_stream, ModelConnector & model_connector)
{
this->out_stream = &out_stream;
this->model_connector = &model_connector;
return find();
}
Finder<ModelClass> & find()
{
if( model_connector )
{
if( out_stream )
{
model_connector->set_stream(*out_stream);
}
else
{
out_stream = model_connector->get_stream();
}
set_db_expression();
out_stream->clear();
model.set_connector(*model_connector);
model.clear();
(*out_stream) << "SELECT ";
model_connector->generate_select_columns(*out_stream, model);
(*out_stream) << " FROM ";
model.table_name(*out_stream);
}
return *this;
}
ModelClass find_one()
{
//model.set_object_exists(true);
// at the end
db_expression = nullptr;
return model;
}
std::vector<ModelClass> find_many()
{
std::vector<ModelClass> res;
// at the end
db_expression = nullptr;
return res;
}
Finder<ModelClass> & where()
{
if( out_stream && db_expression )
{
(*out_stream) << " WHERE ";
db_expression->prepare_to_where_clause();
}
return *this;
}
// may better names?
Finder<ModelClass> & group_or()
{
if( db_expression )
{
db_expression->group_or();
}
return *this;
}
Finder<ModelClass> & group_and()
{
if( db_expression )
{
db_expression->group_and();
}
return *this;
}
Finder<ModelClass> & group_end()
{
if( db_expression )
{
db_expression->group_end();
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & eq(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_EQ);
db_expression->field(field_name, field_value, false, false, false);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & lt(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LT);
db_expression->field(field_name, field_value, false, false, false);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & gt(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GT);
db_expression->field(field_name, field_value, false, false, false);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & le(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LE);
db_expression->field(field_name, field_value, false, false, false);
}
return *this;
}
template<typename FieldValue>
Finder<ModelClass> & ge(const wchar_t * field_name, const FieldValue & field_value)
{
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GE);
db_expression->field(field_name, field_value, false, false, false);
}
return *this;
}
private:
PT::TextStream * out_stream;
ModelConnector * model_connector;
DbExpression * db_expression;
ModelClass model;
void set_db_expression()
{
if( model_connector )
{
DbConnector * db_connector = model_connector->get_db_connector();
if( db_connector )
{
db_expression = db_connector->get_expression();
}
}
}
};
} // namespace

View File

@ -41,6 +41,7 @@ namespace morm
Model::Model()
{
model_connector = nullptr;
morm_object_exists = false;
}
Model::~Model()
@ -57,6 +58,23 @@ void Model::set_connector(ModelConnector & connector)
model_connector = &connector;
}
void Model::set_object_exists(bool object_exists)
{
this->morm_object_exists = object_exists;
}
bool Model::object_exists()
{
return morm_object_exists;
}
bool Model::found()
{
return morm_object_exists;
}
void Model::to_text(PT::TextStream & stream)
{
@ -126,5 +144,10 @@ void Model::update()
}
void Model::clear()
{
morm_object_exists = false;
}
} // namespace

View File

@ -81,12 +81,18 @@ public:
virtual void generate_update_query(PT::TextStream & stream);
virtual void update();
virtual void set_object_exists(bool object_exists);
virtual bool object_exists();
virtual bool found();
// set object to default values
virtual void clear();
protected:
ModelConnector * model_connector;
bool morm_object_exists;
Model();
virtual ~Model();
@ -95,7 +101,7 @@ protected:
template<typename FieldValue>
void field(const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
{
if( model_connector)
if( model_connector )
{
model_connector->field(field_name, field_value, insertable, updatable, is_primary_key);
}

View File

@ -57,6 +57,23 @@ ModelConnector::~ModelConnector()
}
void ModelConnector::set_db_expression_output_type(int output_type)
{
if( db_connector )
{
DbExpression * db_expression = db_connector->get_expression();
if( db_expression )
{
db_expression->set_output_type(output_type);
}
}
}
void ModelConnector::deallocate_stream()
{
if( out_stream_allocated )
@ -95,6 +112,7 @@ void ModelConnector::set_stream(PT::TextStream & stream)
PT::TextStream * ModelConnector::get_stream()
{
allocate_default_stream_if_needed();
return out_stream;
}
@ -112,6 +130,12 @@ void ModelConnector::set_db_connector(DbConnector & db_connector)
}
DbConnector * ModelConnector::get_db_connector()
{
return db_connector;
}
void ModelConnector::to_text(PT::TextStream & stream, Model & model)
{
if( flat_connector )
@ -128,6 +152,22 @@ void ModelConnector::to_text(PT::TextStream & stream, Model & model)
}
void ModelConnector::generate_select_columns(PT::TextStream & stream, Model & model)
{
if( db_connector )
{
expression_callback = db_connector->get_expression();
if( expression_callback )
{
db_connector->generate_select_columns(stream, model);
}
expression_callback = nullptr;
}
}
void ModelConnector::generate_insert_query(PT::TextStream & stream, Model & model)
{

View File

@ -36,6 +36,7 @@
#define headerfile_morm_modelconnector
#include "baseexpression.h"
//#include "finder.h"
namespace morm
@ -44,6 +45,9 @@ class Model;
class FlatConnector;
class DbConnector;
template<typename ModelClass>
class Finder;
class ModelConnector
{
@ -60,10 +64,17 @@ public:
virtual PT::TextStream * get_stream();
virtual void set_flat_connector(FlatConnector & flat_connector);
virtual void set_db_connector(DbConnector & db_connector);
virtual DbConnector * get_db_connector();
virtual void set_db_expression_output_type(int output_type);
virtual void to_text(PT::TextStream & stream, Model & model);
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);
@ -71,6 +82,12 @@ public:
virtual void update(Model & model);
// template<typename ModelClass>
// Finder<ModelClass> & find()
// {
// allocate_default_stream_if_needed();
// return Finder<ModelClass>(this);
// }
protected:
@ -100,7 +117,9 @@ protected:
/*
* Model is using field() method
*/
friend Model;
friend class Model;
template<typename ModelClass> friend class Finder;
};
}

View File

@ -44,6 +44,7 @@
#include "jsonexpression.h"
#include "postgresqlexpression.h"
#include "modelconnector.h"
#include "finder.h"
namespace morm

View File

@ -43,8 +43,23 @@
//#define MORM_OUTPUT_TYPE_JSON 1
#define MORM_OUTPUT_TYPE_DB_INSERT 2
#define MORM_OUTPUT_TYPE_DB_UPDATE 3
// change to something like MORM_OUTPUT_TYPE_DB_WHERE_PRIMARY_KEY
#define MORM_OUTPUT_TYPE_DB_PRIMARY_KEY 4
//#define MORM_OUTPUT_TYPE_WHERE_CUSTOM 5
#define MORM_OUTPUT_TYPE_SELECT_COLUMNS 6
#define MORM_OUTPUT_TYPE_WHERE_EQ 7
#define MORM_OUTPUT_TYPE_WHERE_LT 8
#define MORM_OUTPUT_TYPE_WHERE_GT 9
#define MORM_OUTPUT_TYPE_WHERE_LE 10
#define MORM_OUTPUT_TYPE_WHERE_GE 11
#define MORM_CONJUNCTION_AND 1
#define MORM_CONJUNCTION_OR 2
//#define MORM_DB_TYPE_POSTGRESQL 1

View File

@ -41,9 +41,9 @@ namespace morm
void PostgreSQLExpression::before_field_value_string()
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
// if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << "E'";
}
@ -51,9 +51,9 @@ void PostgreSQLExpression::before_field_value_string()
void PostgreSQLExpression::after_field_value_string()
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
// if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
// output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
// output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
{
(*out_stream) << "'";
}
@ -65,24 +65,39 @@ void PostgreSQLExpression::before_field_value(const std::wstring &)
before_field_value_string();
}
void PostgreSQLExpression::before_field_value(const std::string &)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const std::wstring &)
{
after_field_value_string();
}
void PostgreSQLExpression::before_field_value(const std::string &)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const std::string &)
{
after_field_value_string();
}
void PostgreSQLExpression::put_name_value_separator()
void PostgreSQLExpression::before_field_value(const wchar_t *)
{
(*out_stream) << '=';
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const wchar_t *)
{
after_field_value_string();
}
void PostgreSQLExpression::before_field_value(const char *)
{
before_field_value_string();
}
void PostgreSQLExpression::after_field_value(const char *)
{
after_field_value_string();
}

View File

@ -48,10 +48,16 @@ class PostgreSQLExpression : public DbExpression
protected:
void before_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::wstring &);
void before_field_value(const std::string &);
void after_field_value(const std::string &);
void put_name_value_separator();
void before_field_value(const wchar_t *);
void after_field_value(const wchar_t *);
void before_field_value(const char *);
void after_field_value(const char *);
private: