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;
|
||||
}
|
||||
|
||||
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() )
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
26
src/finder.h
26
src/finder.h
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
73
src/model.h
73
src/model.h
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue