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:
parent
9c7a0f3d7e
commit
ab54a3fc3e
|
@ -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;
|
column_prefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string BaseExpression::get_column_prefix()
|
||||||
|
{
|
||||||
|
return column_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseExpression::generate_from_model(PT::TextStream & stream, Model & model)
|
void BaseExpression::generate_from_model(PT::TextStream & stream, Model & model)
|
||||||
{
|
{
|
||||||
this->out_stream = &stream;
|
this->out_stream = &stream;
|
||||||
|
@ -155,10 +160,16 @@ void BaseExpression::put_field_name(int table_index, const wchar_t * field_name,
|
||||||
{
|
{
|
||||||
before_field_name();
|
before_field_name();
|
||||||
|
|
||||||
if( table_index >= 0 )
|
// if( !add_column_prefix )
|
||||||
{
|
// {
|
||||||
(*out_stream) << 't' << table_index << '.';
|
//
|
||||||
}
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if( table_index >= 0 )
|
||||||
|
// {
|
||||||
|
// (*out_stream) << 't' << table_index << '.';
|
||||||
|
// }
|
||||||
|
|
||||||
if( add_column_prefix && !column_prefix.empty() )
|
if( add_column_prefix && !column_prefix.empty() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,7 +61,8 @@ public:
|
||||||
virtual int get_work_mode();
|
virtual int get_work_mode();
|
||||||
|
|
||||||
virtual void prepare_to_new_expression();
|
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);
|
virtual void generate_from_model(PT::TextStream & stream, Model & model);
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ public:
|
||||||
PT::TextStream * old_out_stream = out_stream;
|
PT::TextStream * old_out_stream = out_stream;
|
||||||
|
|
||||||
out_stream = &str;
|
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;
|
out_stream = old_out_stream;
|
||||||
|
|
||||||
if( model_data )
|
if( model_data )
|
||||||
|
@ -276,7 +277,7 @@ protected:
|
||||||
PT::TextStream * out_stream;
|
PT::TextStream * out_stream;
|
||||||
|
|
||||||
|
|
||||||
std::wstring column_prefix;
|
std::string column_prefix;
|
||||||
|
|
||||||
virtual void generate_from_model(Model & model);
|
virtual void generate_from_model(Model & model);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
allocate_default_expression_if_needed();
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
//virtual void clear_last_query_result();
|
//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_insert_query(PT::TextStream & stream, Model & model);
|
||||||
virtual void generate_update_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);
|
virtual void generate_remove_query(PT::TextStream & stream, Model & model);
|
||||||
|
|
26
src/finder.h
26
src/finder.h
|
@ -39,6 +39,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "utf8/utf8.h"
|
||||||
#include "textstream/textstream.h"
|
#include "textstream/textstream.h"
|
||||||
#include "dbconnector.h"
|
#include "dbconnector.h"
|
||||||
#include "modelconnector.h"
|
#include "modelconnector.h"
|
||||||
|
@ -164,7 +165,7 @@ public:
|
||||||
|
|
||||||
Finder<ModelClass> & prefix(const wchar_t * prefix)
|
Finder<ModelClass> & prefix(const wchar_t * prefix)
|
||||||
{
|
{
|
||||||
column_prefix = prefix;
|
PT::WideToUTF8(prefix, column_prefix);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,11 +249,21 @@ public:
|
||||||
model_data = &model_data_generic;
|
model_data = &model_data_generic;
|
||||||
}
|
}
|
||||||
|
|
||||||
model_data->morm_current_max_column = 0;
|
model_data->prepare_to_new_select();
|
||||||
|
|
||||||
if( model_connector && out_stream )
|
if( model_connector && out_stream )
|
||||||
{
|
{
|
||||||
(*out_stream) << "SELECT ";
|
(*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);
|
model.generate_select_columns(*out_stream, column_prefix, model_data);
|
||||||
(*out_stream) << " FROM ";
|
(*out_stream) << " FROM ";
|
||||||
model.table_name(*out_stream);
|
model.table_name(*out_stream);
|
||||||
|
@ -263,7 +274,14 @@ public:
|
||||||
}
|
}
|
||||||
else
|
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) << " ";
|
(*out_stream) << " ";
|
||||||
|
@ -577,7 +595,7 @@ private:
|
||||||
bool was_query_error;
|
bool was_query_error;
|
||||||
std::wstring last_query_error;
|
std::wstring last_query_error;
|
||||||
ModelData * model_data;
|
ModelData * model_data;
|
||||||
std::wstring column_prefix;
|
std::string column_prefix;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
void Model::set_connector(ModelConnector & connector)
|
||||||
{
|
{
|
||||||
set_connector(&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 )
|
if( model_connector )
|
||||||
{
|
{
|
||||||
|
|
73
src/model.h
73
src/model.h
|
@ -96,6 +96,7 @@ public:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual void table_name(PT::TextStream & stream);
|
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);
|
||||||
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 = nullptr);
|
||||||
virtual bool save(ModelData & model_data);
|
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_flat(PT::TextStream & stream, bool clear_stream = true);
|
||||||
virtual void generate_doc_for_db(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_current_max_column += 1;
|
||||||
model_data->morm_foreign_keys.clear();
|
model_data->morm_foreign_keys.clear();
|
||||||
|
|
||||||
field_model.table_index = model_data->morm_current_max_column;
|
field_model.table_index = model_data->morm_current_max_column;
|
||||||
|
|
||||||
model_data->morm_finder_join_tables << "LEFT JOIN ";
|
model_data->morm_finder_join_tables << "LEFT JOIN ";
|
||||||
field_model.table_name(model_data->morm_finder_join_tables);
|
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_work_mode = db_expression->get_work_mode();
|
||||||
int expr_output_type = db_expression->get_output_type();
|
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_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS);
|
||||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
|
db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
|
||||||
|
|
||||||
|
std::string empty;
|
||||||
|
db_expression->set_column_prefix(empty);
|
||||||
|
|
||||||
if( has_foreign_key )
|
if( has_foreign_key )
|
||||||
{
|
{
|
||||||
field_model.map_fields();
|
field_model.map_fields();
|
||||||
|
|
||||||
model_data->morm_finder_join_tables << " ON t" << table_index << '.' << db_field_name;
|
model_data->morm_finder_join_tables << " ON " << join_table_name_this << '.' << db_field_name; // escape?
|
||||||
model_data->morm_finder_join_tables << " = ";
|
model_data->morm_finder_join_tables << " = " << join_table_name << '.';
|
||||||
|
|
||||||
if( !model_data->morm_foreign_keys.empty() )
|
if( !model_data->morm_foreign_keys.empty() )
|
||||||
{
|
{
|
||||||
|
@ -748,19 +786,20 @@ protected:
|
||||||
{
|
{
|
||||||
map_fields();
|
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() )
|
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 << 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 << ' ';
|
model_data->morm_finder_join_tables << ' ';
|
||||||
db_expression->set_work_mode(expr_work_mode);
|
db_expression->set_work_mode(expr_work_mode);
|
||||||
db_expression->set_output_type(expr_output_type);
|
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 )
|
if( db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES )
|
||||||
{
|
{
|
||||||
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL;
|
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();
|
field_model.map_fields();
|
||||||
|
db_expression->set_column_prefix(current_prefix);
|
||||||
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
|
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
|
|
||||||
ModelData()
|
ModelData()
|
||||||
{
|
{
|
||||||
morm_current_max_column = 0;
|
morm_current_max_column = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~ModelData()
|
virtual ~ModelData()
|
||||||
|
@ -55,8 +55,42 @@ public:
|
||||||
PT::TextStream morm_finder_join_tables;
|
PT::TextStream morm_finder_join_tables;
|
||||||
std::list<std::string> morm_foreign_keys;
|
std::list<std::string> morm_foreign_keys;
|
||||||
int morm_current_max_column;
|
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:
|
* may to add:
|
||||||
* std::set<std::wstring> skip_columns;
|
* std::set<std::wstring> skip_columns;
|
||||||
|
|
Loading…
Reference in New Issue