some work: we need a different way of naming tables for joins

git-svn-id: svn://ttmath.org/publicrep/morm/branches/join_models@1187 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2019-03-26 20:35:05 +00:00
parent 9c7a0f3d7e
commit ab54a3fc3e
8 changed files with 181 additions and 22 deletions

View File

@ -81,11 +81,16 @@ PT::TextStream * BaseExpression::get_current_stream()
}
void BaseExpression::set_column_prefix(const std::wstring & prefix)
void BaseExpression::set_column_prefix(const std::string & prefix)
{
column_prefix = prefix;
}
std::string BaseExpression::get_column_prefix()
{
return column_prefix;
}
void BaseExpression::generate_from_model(PT::TextStream & stream, Model & model)
{
this->out_stream = &stream;
@ -155,10 +160,16 @@ void BaseExpression::put_field_name(int table_index, const wchar_t * field_name,
{
before_field_name();
if( table_index >= 0 )
{
(*out_stream) << 't' << table_index << '.';
}
// if( !add_column_prefix )
// {
//
//
// }
//
// if( table_index >= 0 )
// {
// (*out_stream) << 't' << table_index << '.';
// }
if( add_column_prefix && !column_prefix.empty() )
{

View File

@ -61,7 +61,8 @@ public:
virtual int get_work_mode();
virtual void prepare_to_new_expression();
virtual void set_column_prefix(const std::wstring & prefix);
virtual void set_column_prefix(const std::string & prefix);
virtual std::string get_column_prefix();
virtual void generate_from_model(PT::TextStream & stream, Model & model);
@ -91,7 +92,7 @@ public:
PT::TextStream * old_out_stream = out_stream;
out_stream = &str;
put_field_name(table_index, field_name, add_column_prefix);
put_field_name(-1, field_name, add_column_prefix);
out_stream = old_out_stream;
if( model_data )
@ -276,7 +277,7 @@ protected:
PT::TextStream * out_stream;
std::wstring column_prefix;
std::string column_prefix;
virtual void generate_from_model(Model & model);

View File

@ -151,7 +151,7 @@ DbExpression * DbConnector::get_expression()
}
void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model, const std::wstring & column_prefix)
void DbConnector::generate_select_columns(PT::TextStream & stream, Model & model, const std::string & column_prefix)
{
allocate_default_expression_if_needed();

View File

@ -61,7 +61,7 @@ public:
//virtual void clear_last_query_result();
virtual void generate_select_columns(PT::TextStream & stream, Model & model, const std::wstring & column_prefix);
virtual void generate_select_columns(PT::TextStream & stream, Model & model, const std::string & column_prefix);
virtual void generate_insert_query(PT::TextStream & stream, Model & model);
virtual void generate_update_query(PT::TextStream & stream, Model & model);
virtual void generate_remove_query(PT::TextStream & stream, Model & model);

View File

@ -39,6 +39,7 @@
#include <list>
#include <set>
#include "model.h"
#include "utf8/utf8.h"
#include "textstream/textstream.h"
#include "dbconnector.h"
#include "modelconnector.h"
@ -164,7 +165,7 @@ public:
Finder<ModelClass> & prefix(const wchar_t * prefix)
{
column_prefix = prefix;
PT::WideToUTF8(prefix, column_prefix);
return *this;
}
@ -248,11 +249,21 @@ public:
model_data = &model_data_generic;
}
model_data->morm_current_max_column = 0;
model_data->prepare_to_new_select();
if( model_connector && out_stream )
{
(*out_stream) << "SELECT ";
if( column_prefix.empty() )
{
PT::TextStream prefix_stream;
model.table_name_for_join_as(prefix_stream);
prefix_stream.to_string(column_prefix);
model_data->add_join_table(column_prefix);
}
model.generate_select_columns(*out_stream, column_prefix, model_data);
(*out_stream) << " FROM ";
model.table_name(*out_stream);
@ -263,7 +274,14 @@ public:
}
else
{
(*out_stream) << " AS t0";
(*out_stream) << " AS ";
PT::TextStream str_tmp; // improve me
model.table_name_for_join_as(str_tmp);
(*out_stream) << str_tmp;
std::string str;
str_tmp.to_string(str);
model_data->add_join_table(str);
}
(*out_stream) << " ";
@ -577,7 +595,7 @@ private:
bool was_query_error;
std::wstring last_query_error;
ModelData * model_data;
std::wstring column_prefix;
std::string column_prefix;

View File

@ -105,6 +105,40 @@ void Model::table_name(PT::TextStream & stream)
}
// the body can be moved to dbexpression
// the algorithm can be different depending on the database used
void Model::table_name_for_join_as(PT::TextStream & stream)
{
PT::TextStream str_temp;
table_name(str_temp);
// temporarily
std::string str;
str_temp.to_string(str);
size_t i = str.size();
while( i-- > 0 )
{
if( str[i] == '.' )
{
break;
}
}
if( str[i] == '.' )
{
i += 1;
}
for( ; i < str.size() ; ++i)
{
stream << str[i];
}
}
void Model::set_connector(ModelConnector & connector)
{
set_connector(&connector);
@ -426,7 +460,7 @@ bool Model::save(ModelData & model_data)
}
void Model::generate_select_columns(PT::TextStream & stream, const std::wstring & column_prefix, ModelData * model_data)
void Model::generate_select_columns(PT::TextStream & stream, const std::string & column_prefix, ModelData * model_data)
{
if( model_connector )
{

View File

@ -96,6 +96,7 @@ public:
*
*/
virtual void table_name(PT::TextStream & stream);
virtual void table_name_for_join_as(PT::TextStream & stream);
virtual void to_text(PT::TextStream & stream, ModelData * model_data, bool clear_stream = true);
virtual void to_text(PT::TextStream & stream, ModelData & model_data, bool clear_stream = true);
@ -123,7 +124,7 @@ public:
virtual bool save(ModelData * model_data = nullptr);
virtual bool save(ModelData & model_data);
virtual void generate_select_columns(PT::TextStream & stream, const std::wstring & column_prefix, ModelData * model_data);
virtual void generate_select_columns(PT::TextStream & stream, const std::string & column_prefix, ModelData * model_data);
virtual void generate_doc_for_flat(PT::TextStream & stream, bool clear_stream = true);
virtual void generate_doc_for_db(PT::TextStream & stream, bool clear_stream = true);
@ -720,24 +721,61 @@ protected:
{
model_data->morm_current_max_column += 1;
model_data->morm_foreign_keys.clear();
field_model.table_index = model_data->morm_current_max_column;
model_data->morm_finder_join_tables << "LEFT JOIN ";
field_model.table_name(model_data->morm_finder_join_tables);
model_data->morm_finder_join_tables << " AS t" << (model_data->morm_current_max_column);
model_data->morm_finder_join_tables << " AS ";
//////////////
PT::TextStream join_table_name_this;
table_name_for_join_as(join_table_name_this);
std::string sss1; // improve me
join_table_name_this.to_string(sss1);
int this_index = model_data->find_join_table_index(sss1);
if( this_index > 1 )
join_table_name_this << this_index;
///////////
PT::TextStream join_table_name;
field_model.table_name_for_join_as(join_table_name);
std::string sss; // improve me
join_table_name.to_string(sss);
int table_index = model_data->add_join_table(sss);
if( table_index > 1 )
join_table_name << table_index;
//////////
model_data->morm_finder_join_tables << join_table_name;
int expr_work_mode = db_expression->get_work_mode();
int expr_output_type = db_expression->get_output_type();
std::string old_prefix = db_expression->get_column_prefix();
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS);
db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
std::string empty;
db_expression->set_column_prefix(empty);
if( has_foreign_key )
{
field_model.map_fields();
model_data->morm_finder_join_tables << " ON t" << table_index << '.' << db_field_name;
model_data->morm_finder_join_tables << " = ";
model_data->morm_finder_join_tables << " ON " << join_table_name_this << '.' << db_field_name; // escape?
model_data->morm_finder_join_tables << " = " << join_table_name << '.';
if( !model_data->morm_foreign_keys.empty() )
{
@ -748,19 +786,20 @@ protected:
{
map_fields();
model_data->morm_finder_join_tables << " ON ";
model_data->morm_finder_join_tables << " ON " << join_table_name_this << '.';
if( !model_data->morm_foreign_keys.empty() )
{
model_data->morm_finder_join_tables << model_data->morm_foreign_keys.front();
}
model_data->morm_finder_join_tables << " = t" << (model_data->morm_current_max_column) << '.' << db_field_name;
model_data->morm_finder_join_tables << " = " << (join_table_name) << '.' << db_field_name;
}
model_data->morm_finder_join_tables << ' ';
db_expression->set_work_mode(expr_work_mode);
db_expression->set_output_type(expr_output_type);
db_expression->set_column_prefix(old_prefix);
}
}
@ -809,7 +848,29 @@ protected:
if( db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES )
{
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL;
std::string current_prefix = db_expression->get_column_prefix();
///////////
PT::TextStream join_table_name;
field_model.table_name_for_join_as(join_table_name);
std::string sss; // improve me
join_table_name.to_string(sss);
int table_index = model_data->add_join_table(sss);
if( table_index > 1 )
{
join_table_name << table_index;
join_table_name.to_string(sss);
}
//////////
db_expression->set_column_prefix(sss);
field_model.map_fields();
db_expression->set_column_prefix(current_prefix);
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
}

View File

@ -45,7 +45,7 @@ public:
ModelData()
{
morm_current_max_column = 0;
morm_current_max_column = 1;
}
virtual ~ModelData()
@ -55,8 +55,42 @@ public:
PT::TextStream morm_finder_join_tables;
std::list<std::string> morm_foreign_keys;
int morm_current_max_column;
std::map<std::string, int> morm_table_join_map;
virtual void prepare_to_new_select()
{
morm_current_max_column = 1;
morm_finder_join_tables.clear();
morm_table_join_map.clear();
morm_foreign_keys.clear();
}
virtual int add_join_table(const std::string & table_name)
{
auto res = morm_table_join_map.insert(std::make_pair(table_name, 1));
if( !res.second )
{
res.first->second += 1;
}
return res.first->second;
}
virtual int find_join_table_index(const std::string & table_name)
{
auto iter = morm_table_join_map.find(table_name);
if( iter != morm_table_join_map.end() )
{
return iter->second;
}
return 0;
}
/*
* may to add:
* std::set<std::wstring> skip_columns;