some work in morm (select statement)

git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1079 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2018-04-15 23:00:17 +00:00
parent b1af7b8d25
commit 09f31b2803
11 changed files with 405 additions and 195 deletions

View File

@ -67,6 +67,8 @@ void BaseExpression::generate_from_model(PT::TextStream & stream, Model & model)
before_generate_from_model();
model.map_fields();
after_generate_from_model();
this->out_stream = nullptr;
}

View File

@ -60,7 +60,7 @@ public:
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) )
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
{
field_before();
@ -86,6 +86,40 @@ public:
}
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)
{
this->out_stream = &stream;
field(field_name, field_value, insertable, updatable, is_primary_key);
this->out_stream = nullptr;
}
virtual void esc(char val, PT::TextStream & stream);
virtual void esc(unsigned char val, PT::TextStream & stream);
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);
virtual void esc(bool val, PT::TextStream & stream);
virtual void esc(short val, PT::TextStream & stream);
virtual void esc(unsigned short val, PT::TextStream & stream);
virtual void esc(int val, PT::TextStream & stream);
virtual void esc(unsigned int val, PT::TextStream & stream);
virtual void esc(long val, PT::TextStream & stream);
virtual void esc(unsigned long val, PT::TextStream & stream);
virtual void esc(long long val, PT::TextStream & stream);
virtual void esc(unsigned long long val, PT::TextStream & stream);
virtual void esc(float val, PT::TextStream & stream);
virtual void esc(double val, PT::TextStream & stream);
virtual void esc(long double val, PT::TextStream & stream);
virtual void esc(void* val, PT::TextStream & stream);
virtual void esc(const PT::Date & date, PT::TextStream & stream);
protected:
@ -226,31 +260,6 @@ protected:
*/
virtual void esc(char val, PT::TextStream & stream);
virtual void esc(unsigned char val, PT::TextStream & stream);
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);
virtual void esc(bool val, PT::TextStream & stream);
virtual void esc(short val, PT::TextStream & stream);
virtual void esc(unsigned short val, PT::TextStream & stream);
virtual void esc(int val, PT::TextStream & stream);
virtual void esc(unsigned int val, PT::TextStream & stream);
virtual void esc(long val, PT::TextStream & stream);
virtual void esc(unsigned long val, PT::TextStream & stream);
virtual void esc(long long val, PT::TextStream & stream);
virtual void esc(unsigned long long val, PT::TextStream & stream);
virtual void esc(float val, PT::TextStream & stream);
virtual void esc(double val, PT::TextStream & stream);
virtual void esc(long double val, PT::TextStream & stream);
virtual void esc(void* val, PT::TextStream & stream);
virtual void esc(const PT::Date & date, PT::TextStream & stream);
};
}

View File

@ -53,31 +53,31 @@ DbConnector::~DbConnector()
bool DbConnector::query(PT::TextStream & stream)
bool DbConnector::query(const PT::TextStream & stream)
{
return false;
}
bool DbConnector::query(const std::wstring & query)
//bool DbConnector::query(const std::wstring & query)
//{
// return false;
//}
bool DbConnector::query(const std::string & query_str)
{
return false;
}
bool DbConnector::query(const std::string & query)
{
return false;
}
//bool DbConnector::query(const wchar_t * query)
//{
// return false;
//}
bool DbConnector::query(const wchar_t * query)
{
return false;
}
bool DbConnector::query(const char * query)
bool DbConnector::query(const char * query_str)
{
// do query
return false;
@ -85,6 +85,27 @@ bool DbConnector::query(const char * query)
bool DbConnector::query_select(const PT::TextStream & stream)
{
return false;
}
bool DbConnector::query_update(const PT::TextStream & stream)
{
return false;
}
bool DbConnector::query_insert(const PT::TextStream & stream)
{
return false;
}
virtual void DbConnector::map_values_from_query(Model & model)
{
model.clear();
}
DbExpression * DbConnector::get_expression()
{

View File

@ -61,11 +61,17 @@ public:
virtual void insert(PT::TextStream & stream, Model & model);
virtual void update(PT::TextStream & stream, Model & model);
virtual bool query(PT::TextStream & stream);
virtual bool query(const std::wstring & query);
virtual bool query(const std::string & query);
virtual bool query(const wchar_t * query);
virtual bool query(const char * query);
virtual bool query(const PT::TextStream & stream);
//virtual bool query(const std::wstring & query);
virtual bool query(const std::string & query_str);
//virtual bool query(const wchar_t * query);
virtual bool query(const char * query_str);
virtual bool query_select(const PT::TextStream & stream);
virtual bool query_update(const PT::TextStream & stream);
virtual bool query_insert(const PT::TextStream & stream);
virtual void map_values_from_query(Model & model);
protected:

View File

@ -227,28 +227,34 @@ void DbExpression::prepare_to_where_clause()
}
DbExpression & DbExpression::group_or()
DbExpression & DbExpression::group_or(PT::TextStream & stream)
{
out_stream = &stream;
field_before();
(*out_stream) << "(";
is_first_field = true;
conjunctions.push_back(MORM_CONJUNCTION_OR);
out_stream = nullptr;
return *this;
}
DbExpression & DbExpression::group_and()
DbExpression & DbExpression::group_and(PT::TextStream & stream)
{
out_stream = &stream;
field_before();
(*out_stream) << "(";
is_first_field = true;
conjunctions.push_back(MORM_CONJUNCTION_AND);
out_stream = nullptr;
return *this;
}
DbExpression & DbExpression::group_end()
DbExpression & DbExpression::group_end(PT::TextStream & stream)
{
out_stream = &stream;
if( !conjunctions.empty() )
{
conjunctions.pop_back();
@ -256,6 +262,7 @@ DbExpression & DbExpression::group_end()
field_after();
}
out_stream = nullptr;
return *this;
}

View File

@ -55,10 +55,9 @@ public:
virtual void prepare_to_where_clause();
// may better names?
virtual DbExpression & group_or();
virtual DbExpression & group_and();
virtual DbExpression & group_end();
virtual DbExpression & group_or(PT::TextStream & stream);
virtual DbExpression & group_and(PT::TextStream & stream);
virtual DbExpression & group_end(PT::TextStream & stream);

View File

@ -36,6 +36,7 @@
#define headerfile_morm_finder
#include <vector>
#include <list>
#include "model.h"
#include "textstream/textstream.h"
#include "dbconnector.h"
@ -70,8 +71,8 @@ public:
Finder(PT::TextStream & out_stream, ModelConnector & model_connector)
{
this->model_connector = &model_connector;
this->out_stream = &out_stream;
this->model_connector = &model_connector;
db_expression = nullptr;
}
@ -91,29 +92,34 @@ public:
}
Finder<ModelClass> & find()
{
if( model_connector )
{
if( out_stream )
{
model_connector->set_stream(*out_stream);
}
else
if( !out_stream )
{
out_stream = model_connector->get_stream();
}
set_db_expression();
if( out_stream )
{
set_db_expression();
out_stream->clear();
model.set_connector(*model_connector);
model.clear();
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);
(*out_stream) << "SELECT ";
model_connector->generate_select_columns(*out_stream, model);
(*out_stream) << " FROM ";
model.table_name(*out_stream);
}
}
return *this;
@ -159,9 +165,9 @@ public:
// may better names?
Finder<ModelClass> & group_or()
{
if( db_expression )
if( db_expression && out_stream )
{
db_expression->group_or();
db_expression->group_or(*out_stream);
}
return *this;
@ -170,9 +176,9 @@ public:
Finder<ModelClass> & group_and()
{
if( db_expression )
if( db_expression && out_stream )
{
db_expression->group_and();
db_expression->group_and(*out_stream);
}
return *this;
@ -181,9 +187,9 @@ public:
Finder<ModelClass> & group_end()
{
if( db_expression )
if( db_expression && out_stream )
{
db_expression->group_end();
db_expression->group_end(*out_stream);
}
return *this;
@ -198,7 +204,7 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_EQ);
db_expression->field(field_name, field_value, false, false, false);
db_expression->field(*out_stream, field_name, field_value, false, false, false);
}
return *this;
@ -211,7 +217,7 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LT);
db_expression->field(field_name, field_value, false, false, false);
db_expression->field(*out_stream, field_name, field_value, false, false, false);
}
return *this;
@ -224,7 +230,7 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GT);
db_expression->field(field_name, field_value, false, false, false);
db_expression->field(*out_stream, field_name, field_value, false, false, false);
}
return *this;
@ -237,7 +243,7 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_LE);
db_expression->field(field_name, field_value, false, false, false);
db_expression->field(*out_stream, field_name, field_value, false, false, false);
}
return *this;
@ -250,13 +256,55 @@ public:
if( db_expression )
{
db_expression->set_output_type(MORM_OUTPUT_TYPE_WHERE_GE);
db_expression->field(field_name, field_value, false, false, false);
db_expression->field(*out_stream, field_name, field_value, false, false, false);
}
return *this;
}
void get_list(std::list<ModelClass> & result, bool clear_list = true)
{
if( clear_list )
{
result.clear();
}
if( model_connector && out_stream )
{
DbConnector * db_connector = model_connector->get_db_connector();
if( db_connector )
{
bool res = db_connector->query_select(*out_stream);
if( res )
{
//ModelClass model;
//db_connector->map_values_from_query(model);
}
if( !res )
{
// put some log here?
}
}
}
}
std::list<ModelClass> get_list()
{
std::list<ModelClass> result;
get_list(result);
return result;
}
private:

View File

@ -40,6 +40,9 @@
#define MORM_WORK_MODE_MODEL_VALUES 2
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES 3
// IMPROVE ME give me a better name
#define MORM_WORK_MODE_MODEL_SELECT_FROM_DB 3
//#define MORM_OUTPUT_TYPE_JSON 1
#define MORM_OUTPUT_TYPE_DB_INSERT 2
#define MORM_OUTPUT_TYPE_DB_UPDATE 3

View File

@ -32,6 +32,9 @@
*
*/
// for sleep()
#include <unistd.h>
#include "postgresqlconnector.h"
#include "utf8/utf8.h"
#include "postgresqlexpression.h"
@ -73,14 +76,14 @@ bool PostgreSQLConnector::query(const char * query_str)
// if( log_queries )
// log << log1 << "Db: executing query: " << q << logend;
last_status = PGRES_EMPTY_QUERY;
last_status = PGRES_EMPTY_QUERY; // or something else?
last_result = PQexec(pg_conn, query_str);
if( !last_result )
{
if( PQstatus(pg_conn) != CONNECTION_OK )
{
//AssertConnection();
assert_connection();
last_result = PQexec(pg_conn, query_str);
}
}
@ -99,6 +102,19 @@ return last_result != nullptr;
}
bool PostgreSQLConnector::query(const PT::TextStream & stream)
{
stream.to_string(query_str);
return query(query_str.c_str());
}
bool PostgreSQLConnector::query(const std::string & query_str)
{
return query(query_str.c_str());
}
bool PostgreSQLConnector::query_select(const char * query_str)
{
return (query(query_str) && last_status == PGRES_TUPLES_OK);
@ -115,6 +131,27 @@ bool PostgreSQLConnector::query_insert(const char * query_str)
}
bool PostgreSQLConnector::query_select(const PT::TextStream & stream)
{
stream.to_string(query_str);
return query_select(query_str.c_str());
}
bool PostgreSQLConnector::query_update(const PT::TextStream & stream)
{
stream.to_string(query_str);
return query_update(query_str.c_str());
}
bool PostgreSQLConnector::query_insert(const PT::TextStream & stream)
{
stream.to_string(query_str);
return query_insert(query_str.c_str());
}
//Error PostgreSQLConnector::DoCommand(const char * command)
//{
// PGresult * r = 0;
@ -137,7 +174,6 @@ bool PostgreSQLConnector::query_insert(const char * query_str)
bool PostgreSQLConnector::is_last_result(ExecStatusType t)
{
return (last_result && PQresultStatus(last_result) == t);
@ -145,6 +181,28 @@ bool PostgreSQLConnector::is_last_result(ExecStatusType t)
void PostgreSQLConnector::map_values_from_query(Model & model)
{
if( db_expression )
{
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SELECT_FROM_DB);
//db_expression->set_output_type()
}
}
int PostgreSQLConnector::get_column_index(const char * column_name)
{
int c = PQfnumber(last_result, column_name);
@ -580,120 +638,160 @@ size_t i = 0;
//void PostgreSQLConnector::SetConnParam(const std::wstring & database_name, const std::wstring & user, const std::wstring & pass)
//{
// db_database = database_name;
// db_user = user;
// db_pass = pass;
//}
void PostgreSQLConnector::set_conn_param(const std::wstring & database_name, const std::wstring & user, const std::wstring & pass)
{
db_database = database_name;
db_user = user;
db_pass = pass;
}
void PostgreSQLConnector::overwrite(PT::TextStream & stream)
{
PT::TextStream::iterator i = stream.begin();
for( ; i != stream.end() ; ++i)
{
*i = 0;
}
stream.clear();
}
void PostgreSQLConnector::connect()
{
close();
stream.clear();
stream << "dbname='";
db_expression->esc(db_database, stream);
stream << "' user='";
db_expression->esc(db_user, stream);
stream << "' password='";
db_expression->esc(db_pass, stream);
stream << "'";
std::string str;
stream.to_string(str);
pg_conn = PQconnectdb(str.c_str());
overwrite(stream);
// warning! pg_conn can be not null but there cannnot be a connection established
// use PQstatus(pg_conn) to check whether the connection works fine
}
//
//
//
//void PostgreSQLConnector::Connect()
//{
// Close();
//
// conn_info.Clear();
// conn_info.SetExtented(false);
//
// conn_info << R("dbname=") << db_database
// << R(" user=") << db_user
// << R(" password=") << db_pass;
//
// pg_conn = PQconnectdb(conn_info.CStr());
//
// // warning! pg_conn can be not null but there cannnot be a connection established
// // use PQstatus(pg_conn) to check whether the connection works fine
//}
//
//
//
//void PostgreSQLConnector::LogConnectionSocket()
//{
// log << log2 << "Db: connection to the database works fine" << logend;
// log << log3 << "Db: connection socket: " << PQsocket(pg_conn) << logend;
//}
//
//
//
//void PostgreSQLConnector::WaitForConnection()
//{
// if( !pg_conn || PQstatus(pg_conn) != CONNECTION_OK )
// {
// log << log3 << "Db: waiting for the db to be ready...." << logend << logsave;
//
// while( !AssertConnection(false, false) )
// sleep(5);
//
// LogConnectionSocket();
// }
//}
//
//
//
//void PostgreSQLConnector::Close()
//{
// if( pg_conn )
// {
// PQfinish(pg_conn);
// pg_conn = 0;
// }
//}
//
//
//
//bool PostgreSQLConnector::AssertConnection(bool put_log, bool throw_if_no_connection)
//{
//bool was_connection = true;
//
//
// if( !pg_conn )
// {
// was_connection = false;
// Connect();
// }
// else
// if( PQstatus(pg_conn) != CONNECTION_OK )
// {
// if( put_log )
// log << log2 << "Db: connection to the database is lost, trying to recover" << logend;
//
// was_connection = false;
// PQreset(pg_conn);
// }
//
//
// if( pg_conn && PQstatus(pg_conn) == CONNECTION_OK )
// {
// if( !was_connection )
// {
void PostgreSQLConnector::log_connection_socket()
{
//log << log2 << "Db: connection to the database works fine" << logend;
//log << log3 << "Db: connection socket: " << PQsocket(pg_conn) << logend;
if( pg_conn )
{
std::cout << "Db: connection to the database works fine" << std::endl;
std::cout << "Db: connection socket: " << PQsocket(pg_conn) << std::endl;
}
}
void PostgreSQLConnector::wait_for_connection()
{
if( !pg_conn || PQstatus(pg_conn) != CONNECTION_OK )
{
//log << log3 << "Db: waiting for the db to be ready...." << logend << logsave;
std::cout << "Db: waiting for the db to be ready...." << std::endl;
while( !assert_connection(false, false) )
{
sleep(5);
}
//LogConnectionSocket();
}
}
void PostgreSQLConnector::close()
{
if( pg_conn )
{
PQfinish(pg_conn);
pg_conn = nullptr;
}
}
bool PostgreSQLConnector::assert_connection(bool put_log, bool throw_if_no_connection)
{
bool was_connection = true;
if( !pg_conn )
{
was_connection = false;
connect();
}
else
if( PQstatus(pg_conn) != CONNECTION_OK )
{
if( put_log )
{
//log << log2 << "Db: connection to the database is lost, trying to recover" << logend;
std::cout << "Db: connection to the database is lost, trying to recover" << std::endl;
}
was_connection = false;
PQreset(pg_conn);
}
if( pg_conn && PQstatus(pg_conn) == CONNECTION_OK )
{
if( !was_connection )
{
// if( put_log )
// LogConnectionSocket();
//
// SetDbParameters();
// }
//
// return true;
// }
// else
// {
// if( put_log )
// log << log1 << "Db: connection to db server cannot be established" << logend;
//
// if( throw_if_no_connection )
// throw Error(WINIX_ERR_DB_FATAL_ERROR_DURING_CONNECTING);
//
// return false;
// }
//}
//
//
//
//void PostgreSQLConnector::SetDbParameters()
//{
// if( PQsetClientEncoding(pg_conn, "UTF8") == -1 )
// log << log1 << "Db: Can't set the proper client encoding" << logend;
//}
set_db_parameters();
}
return true;
}
else
{
if( put_log )
{
//log << log1 << "Db: connection to db server cannot be established" << logend;
std::cout << "Db: connection to db server cannot be established" << std::endl;
}
if( throw_if_no_connection )
{
//throw Error(WINIX_ERR_DB_FATAL_ERROR_DURING_CONNECTING);
throw int(10);
}
return false;
}
}
void PostgreSQLConnector::set_db_parameters()
{
if( PQsetClientEncoding(pg_conn, "UTF8") == -1 )
{
//log << log1 << "Db: Can't set the proper client encoding" << logend;
std::cout << "Db: Can't set the proper client encoding" << std::endl;
}
}
}

View File

@ -52,11 +52,21 @@ public:
void set_log_queries(bool log_queries);
bool query(const PT::TextStream & stream);
bool query(const char * query_str);
bool query(const std::string & query_str);
bool query_select(const char * query_str);
bool query_update(const char * query_str);
bool query_insert(const char * query_str);
bool query_select(const PT::TextStream & stream);
bool query_update(const PT::TextStream & stream);
bool query_insert(const PT::TextStream & stream);
void map_values_from_query(Model & model);
bool is_last_result(ExecStatusType t);
/*
@ -81,12 +91,14 @@ public:
void clear_result();
//void SetConnParam(const std::wstring & database, const std::wstring & user, const std::wstring & pass);
//void Connect();
//void WaitForConnection();
//void Close();
//bool AssertConnection(bool put_log = true, bool throw_if_no_connection = true);
//void SetDbParameters();
void set_conn_param(const std::wstring & database, const std::wstring & user, const std::wstring & pass);
void connect();
void wait_for_connection();
void close();
bool assert_connection(bool put_log = true, bool throw_if_no_connection = true);
void set_db_parameters();
void log_connection_socket();
//PGconn * GetPgConn();
@ -96,6 +108,8 @@ protected:
PGresult * last_result; // can be null
ExecStatusType last_status;
bool log_queries;
PT::TextStream stream;
std::string query_str;
std::wstring db_database;
std::wstring db_user;
@ -104,6 +118,7 @@ protected:
void allocate_default_expression();
void overwrite(PT::TextStream & stream);
};
}

View File

@ -43,6 +43,9 @@ namespace morm
class PostgreSQLExpression : public DbExpression
{
public:
void esc(char val, PT::TextStream & stream);
protected:
@ -65,7 +68,6 @@ private:
void after_field_value_string();
void esc(char val, PT::TextStream & stream);
};