added: support for generating LEFT JOIN statement in Finder

(the primary key should consist of only one column at the moment)



git-svn-id: svn://ttmath.org/publicrep/morm/branches/join_models@1186 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2019-03-26 18:34:07 +00:00
parent 440f56e376
commit 9c7a0f3d7e
10 changed files with 266 additions and 70 deletions

View File

@ -6,11 +6,11 @@ baseexpression.o: ../../pikotools/textstream/types.h
baseexpression.o: ../../pikotools/date/date.h
baseexpression.o: ../../pikotools/convert/inttostr.h
baseexpression.o: ../../pikotools/membuffer/membuffer.h
baseexpression.o: ../../pikotools/textstream/types.h morm_types.h model.h
baseexpression.o: modelconnector.h clearer.h dbconnector.h
baseexpression.o: ../../pikotools/textstream/types.h morm_types.h modeldata.h
baseexpression.o: model.h modelconnector.h clearer.h dbconnector.h
baseexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
baseexpression.o: queryresult.h flatconnector.h dbexpression.h
baseexpression.o: flatexpression.h modeldata.h ../../pikotools/utf8/utf8.h
baseexpression.o: flatexpression.h ../../pikotools/utf8/utf8.h
clearer.o: clearer.h ../../pikotools/date/date.h
clearer.o: ../../pikotools/convert/inttostr.h model.h
clearer.o: ../../pikotools/textstream/textstream.h
@ -19,7 +19,7 @@ clearer.o: ../../pikotools/membuffer/membuffer.h
clearer.o: ../../pikotools/textstream/types.h modelconnector.h dbconnector.h
clearer.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
clearer.o: queryresult.h flatconnector.h dbexpression.h baseexpression.h
clearer.o: morm_types.h flatexpression.h modeldata.h
clearer.o: morm_types.h modeldata.h flatexpression.h
dbconnector.o: dbconnector.h ../../pikotools/textstream/textstream.h
dbconnector.o: ../../pikotools/space/space.h
dbconnector.o: ../../pikotools/textstream/types.h ../../pikotools/date/date.h
@ -27,8 +27,8 @@ dbconnector.o: ../../pikotools/convert/inttostr.h
dbconnector.o: ../../pikotools/membuffer/membuffer.h
dbconnector.o: ../../pikotools/textstream/types.h ../../pikotools/log/log.h
dbconnector.o: ../../pikotools/log/filelog.h queryresult.h dbexpression.h
dbconnector.o: baseexpression.h morm_types.h model.h modelconnector.h
dbconnector.o: clearer.h flatconnector.h flatexpression.h modeldata.h
dbconnector.o: baseexpression.h morm_types.h modeldata.h model.h
dbconnector.o: modelconnector.h clearer.h flatconnector.h flatexpression.h
dbconnector.o: ../../pikotools/utf8/utf8.h ../../pikotools/convert/convert.h
dbconnector.o: ../../pikotools/convert/inttostr.h
dbconnector.o: ../../pikotools/convert/patternreplacer.h
@ -41,7 +41,7 @@ dbexpression.o: ../../pikotools/textstream/types.h
dbexpression.o: ../../pikotools/date/date.h
dbexpression.o: ../../pikotools/convert/inttostr.h
dbexpression.o: ../../pikotools/membuffer/membuffer.h
dbexpression.o: ../../pikotools/textstream/types.h morm_types.h
dbexpression.o: ../../pikotools/textstream/types.h morm_types.h modeldata.h
dochtmlconnector.o: dochtmlconnector.h flatconnector.h
dochtmlconnector.o: ../../pikotools/textstream/textstream.h
dochtmlconnector.o: ../../pikotools/space/space.h
@ -51,6 +51,7 @@ dochtmlconnector.o: ../../pikotools/convert/inttostr.h
dochtmlconnector.o: ../../pikotools/membuffer/membuffer.h
dochtmlconnector.o: ../../pikotools/textstream/types.h dochtmlexpression.h
dochtmlconnector.o: flatexpression.h baseexpression.h morm_types.h
dochtmlconnector.o: modeldata.h
dochtmlexpression.o: dochtmlexpression.h flatexpression.h baseexpression.h
dochtmlexpression.o: ../../pikotools/textstream/textstream.h
dochtmlexpression.o: ../../pikotools/space/space.h
@ -59,6 +60,7 @@ dochtmlexpression.o: ../../pikotools/date/date.h
dochtmlexpression.o: ../../pikotools/convert/inttostr.h
dochtmlexpression.o: ../../pikotools/membuffer/membuffer.h
dochtmlexpression.o: ../../pikotools/textstream/types.h morm_types.h
dochtmlexpression.o: modeldata.h
flatconnector.o: flatconnector.h ../../pikotools/textstream/textstream.h
flatconnector.o: ../../pikotools/space/space.h
flatconnector.o: ../../pikotools/textstream/types.h
@ -66,10 +68,10 @@ flatconnector.o: ../../pikotools/date/date.h
flatconnector.o: ../../pikotools/convert/inttostr.h
flatconnector.o: ../../pikotools/membuffer/membuffer.h
flatconnector.o: ../../pikotools/textstream/types.h flatexpression.h
flatconnector.o: baseexpression.h morm_types.h model.h modelconnector.h
flatconnector.o: clearer.h dbconnector.h ../../pikotools/log/log.h
flatconnector.o: ../../pikotools/log/filelog.h queryresult.h dbexpression.h
flatconnector.o: modeldata.h
flatconnector.o: baseexpression.h morm_types.h modeldata.h model.h
flatconnector.o: modelconnector.h clearer.h dbconnector.h
flatconnector.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
flatconnector.o: queryresult.h dbexpression.h
flatexpression.o: flatexpression.h baseexpression.h
flatexpression.o: ../../pikotools/textstream/textstream.h
flatexpression.o: ../../pikotools/space/space.h
@ -77,7 +79,7 @@ flatexpression.o: ../../pikotools/textstream/types.h
flatexpression.o: ../../pikotools/date/date.h
flatexpression.o: ../../pikotools/convert/inttostr.h
flatexpression.o: ../../pikotools/membuffer/membuffer.h
flatexpression.o: ../../pikotools/textstream/types.h morm_types.h
flatexpression.o: ../../pikotools/textstream/types.h morm_types.h modeldata.h
jsonconnector.o: jsonconnector.h flatconnector.h
jsonconnector.o: ../../pikotools/textstream/textstream.h
jsonconnector.o: ../../pikotools/space/space.h
@ -86,7 +88,7 @@ jsonconnector.o: ../../pikotools/date/date.h
jsonconnector.o: ../../pikotools/convert/inttostr.h
jsonconnector.o: ../../pikotools/membuffer/membuffer.h
jsonconnector.o: ../../pikotools/textstream/types.h jsonexpression.h
jsonconnector.o: flatexpression.h baseexpression.h morm_types.h
jsonconnector.o: flatexpression.h baseexpression.h morm_types.h modeldata.h
jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.h
jsonexpression.o: ../../pikotools/textstream/textstream.h
jsonexpression.o: ../../pikotools/space/space.h
@ -94,7 +96,7 @@ jsonexpression.o: ../../pikotools/textstream/types.h
jsonexpression.o: ../../pikotools/date/date.h
jsonexpression.o: ../../pikotools/convert/inttostr.h
jsonexpression.o: ../../pikotools/membuffer/membuffer.h
jsonexpression.o: ../../pikotools/textstream/types.h morm_types.h
jsonexpression.o: ../../pikotools/textstream/types.h morm_types.h modeldata.h
model.o: model.h ../../pikotools/textstream/textstream.h
model.o: ../../pikotools/space/space.h ../../pikotools/textstream/types.h
model.o: ../../pikotools/date/date.h ../../pikotools/convert/inttostr.h
@ -102,8 +104,8 @@ model.o: ../../pikotools/membuffer/membuffer.h
model.o: ../../pikotools/textstream/types.h modelconnector.h clearer.h
model.o: dbconnector.h ../../pikotools/log/log.h
model.o: ../../pikotools/log/filelog.h queryresult.h flatconnector.h
model.o: dbexpression.h baseexpression.h morm_types.h flatexpression.h
model.o: modeldata.h
model.o: dbexpression.h baseexpression.h morm_types.h modeldata.h
model.o: flatexpression.h
modelconnector.o: modelconnector.h clearer.h ../../pikotools/date/date.h
modelconnector.o: ../../pikotools/convert/inttostr.h dbconnector.h
modelconnector.o: ../../pikotools/textstream/textstream.h
@ -125,7 +127,8 @@ postgresqlconnector.o: ../../pikotools/log/log.h
postgresqlconnector.o: ../../pikotools/log/filelog.h queryresult.h
postgresqlconnector.o: postgresqlqueryresult.h ../../pikotools/utf8/utf8.h
postgresqlconnector.o: postgresqlexpression.h dbexpression.h baseexpression.h
postgresqlconnector.o: morm_types.h ../../pikotools/convert/strtoint.h
postgresqlconnector.o: morm_types.h modeldata.h
postgresqlconnector.o: ../../pikotools/convert/strtoint.h
postgresqlconnector.o: ../../pikotools/convert/text.h
postgresqlconnector.o: ../../pikotools/convert/misc.h
postgresqlexpression.o: postgresqlexpression.h dbexpression.h
@ -137,6 +140,7 @@ postgresqlexpression.o: ../../pikotools/date/date.h
postgresqlexpression.o: ../../pikotools/convert/inttostr.h
postgresqlexpression.o: ../../pikotools/membuffer/membuffer.h
postgresqlexpression.o: ../../pikotools/textstream/types.h morm_types.h
postgresqlexpression.o: modeldata.h
postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h
queryresult.o: queryresult.h ../../pikotools/utf8/utf8.h
queryresult.o: ../../pikotools/textstream/textstream.h

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -60,6 +60,12 @@ void BaseExpression::set_work_mode(int work_mode)
}
int BaseExpression::get_work_mode()
{
return work_mode;
}
void BaseExpression::prepare_to_new_expression()
{
column_prefix.clear();
@ -144,10 +150,16 @@ void BaseExpression::field_after()
}
void BaseExpression::put_field_name(const wchar_t * field_name, bool add_column_prefix)
void BaseExpression::put_field_name(int table_index, const wchar_t * field_name, bool add_column_prefix)
{
before_field_name();
if( table_index >= 0 )
{
(*out_stream) << 't' << table_index << '.';
}
if( add_column_prefix && !column_prefix.empty() )
{
esc(column_prefix, *out_stream);
@ -159,6 +171,11 @@ void BaseExpression::put_field_name(const wchar_t * field_name, bool add_column_
}
void BaseExpression::put_field_name(const wchar_t * field_name, bool add_column_prefix)
{
put_field_name(-1, field_name, add_column_prefix);
}
void BaseExpression::put_field_doc(Model & model, const void * field_pointer, bool insertable, bool updatable, bool is_primary_key, ModelData * model_data)

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,14 +38,15 @@
#include <list>
#include <set>
#include "textstream/textstream.h"
#include "morm_types.h"
#include "date/date.h"
#include "morm_types.h"
#include "modeldata.h"
namespace morm
{
class Model;
class ModelData;
class ModelConnector;
@ -57,6 +58,8 @@ public:
virtual ~BaseExpression();
virtual void set_work_mode(int work_mode);
virtual int get_work_mode();
virtual void prepare_to_new_expression();
virtual void set_column_prefix(const std::wstring & prefix);
@ -71,7 +74,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, bool add_column_prefix = true)
void field(int table_index, const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false, bool add_column_prefix = true, ModelData * model_data = nullptr)
{
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
{
@ -79,7 +82,24 @@ public:
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
{
put_field_name(field_name, add_column_prefix);
put_field_name(table_index, field_name, add_column_prefix);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_SAVE_FIELDS )
{
PT::TextStream str;
PT::TextStream * old_out_stream = out_stream;
out_stream = &str;
put_field_name(table_index, field_name, add_column_prefix);
out_stream = old_out_stream;
if( model_data )
{
model_data->morm_foreign_keys.emplace_back();
std::string & key_str = model_data->morm_foreign_keys.back();
str.to_string(key_str, false);
}
}
else
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
@ -89,15 +109,18 @@ public:
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name(field_name);
put_field_name(table_index, field_name);
put_name_value_separator();
put_field_value(field_value);
}
field_after();
}
}
template<typename FieldValue>
void field_doc(Model & model, const wchar_t * field_name, const FieldValue & field_value,
bool insertable = true, bool updatable = true,
@ -158,6 +181,11 @@ public:
{
field_before();
// if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
// {
// put_field_name(field_name);
// }
// else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name(field_name);
@ -201,7 +229,7 @@ public:
void field_to_stream(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);
field(-1, field_name, field_value, insertable, updatable, is_primary_key);
this->out_stream = nullptr;
}
@ -260,6 +288,7 @@ protected:
//void field(const wchar_t * field_name, Model & field, bool insertable = true, bool updatable = true);
virtual void put_field_name(int table_index, const wchar_t * field_name, bool add_column_prefix = true);
virtual void put_field_name(const wchar_t * field_name, bool add_column_prefix = true);
template<typename FieldValue>

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -56,6 +56,12 @@ void DbExpression::set_output_type(int output_type)
}
int DbExpression::get_output_type()
{
return output_type;
}
bool DbExpression::can_field_be_generated(bool insertable, bool updatable, bool is_primary_key)
{
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT )
@ -68,7 +74,7 @@ bool DbExpression::can_field_be_generated(bool insertable, bool updatable, bool
return updatable;
}
else
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY || output_type == MORM_OUTPUT_TYPE_JOIN_TABLES )
{
return is_primary_key;
}

View File

@ -51,6 +51,7 @@ public:
virtual ~DbExpression();
virtual void set_output_type(int output_type);
virtual int get_output_type();
virtual void prepare_to_where_clause();
@ -61,7 +62,6 @@ public:
virtual DbExpression & page(PT::TextStream & stream, size_t page_number, size_t page_size);
template<typename FieldValue>
void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, FieldValue & field_value)
{
@ -71,7 +71,7 @@ public:
column_expression += L" as ";
column_expression += new_column_name;
field(column_expression.c_str(), field_value, false, false, false, false);
field(-1, column_expression.c_str(), field_value, false, false, false, false);
}

View File

@ -175,6 +175,7 @@ public:
last_query_error.clear();
model_data = nullptr;
column_prefix.clear();
model.clear_table_index(); // will be changed
if( model_connector )
{
@ -242,17 +243,32 @@ public:
prepare_to_select();
}
if( !model_data )
{
model_data = &model_data_generic;
}
model_data->morm_current_max_column = 0;
if( model_connector && out_stream )
{
(*out_stream) << "SELECT ";
model.generate_select_columns(*out_stream, column_prefix);
model.generate_select_columns(*out_stream, column_prefix, model_data);
(*out_stream) << " FROM ";
model.table_name(*out_stream);
if( !column_prefix.empty() )
{
(*out_stream) << " AS " << column_prefix; // what about escaping?
}
else
{
(*out_stream) << " AS t0";
}
(*out_stream) << " ";
(*out_stream) << model_data->morm_finder_join_tables;
}
return *this;
@ -557,6 +573,7 @@ private:
ModelConnector * model_connector;
DbExpression * db_expression;
ModelClass model;
ModelData model_data_generic;
bool was_query_error;
std::wstring last_query_error;
ModelData * model_data;

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -426,10 +426,11 @@ bool Model::save(ModelData & model_data)
}
void Model::generate_select_columns(PT::TextStream & stream, const std::wstring & column_prefix)
void Model::generate_select_columns(PT::TextStream & stream, const std::wstring & column_prefix, ModelData * model_data)
{
if( model_connector )
{
this->model_data = model_data;
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL;
DbConnector * db_connector = model_connector->get_db_connector();
@ -439,6 +440,7 @@ void Model::generate_select_columns(PT::TextStream & stream, const std::wstring
}
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
this->model_data = nullptr;
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -97,33 +97,33 @@ public:
*/
virtual void table_name(PT::TextStream & stream);
virtual void to_text(PT::TextStream & stream, ModelData * model_data = nullptr, 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);
virtual void to_text(PT::TextStream & stream, bool clear_stream = true);
virtual void to_text(std::string & str, ModelData * model_data = nullptr, bool clear_string = true);
virtual void to_text(std::string & str, ModelData & model_data, bool clear_string = true);
virtual void to_text(std::string & str, ModelData * model_data, bool clear_string = true);
virtual void to_text(std::string & str, ModelData & model_data, bool clear_string = true);
virtual void to_text(std::string & str, bool clear_string = true);
virtual std::string to_text();
virtual std::string to_string();
virtual void generate_insert_query(PT::TextStream & stream);
virtual void generate_insert_query(PT::TextStream & stream); // FIX ME needed model_data
virtual bool insert(ModelData * model_data = nullptr);
virtual bool insert(ModelData & model_data);
virtual void generate_update_query(PT::TextStream & stream);
virtual void generate_update_query(PT::TextStream & stream); // FIX ME needed model_data
virtual bool update(ModelData * model_data = nullptr);
virtual bool update(ModelData & model_data);
virtual void generate_remove_query(PT::TextStream & stream);
virtual void generate_remove_query(PT::TextStream & stream); // FIX ME needed model_data
virtual bool remove(ModelData * model_data = nullptr);
virtual bool remove(ModelData & model_data);
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);
virtual void generate_select_columns(PT::TextStream & stream, const std::wstring & 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);
@ -132,6 +132,12 @@ public:
virtual void clear();
// will be changed
void clear_table_index()
{
table_index = 0;
}
protected:
ModelConnector * model_connector;
@ -140,6 +146,7 @@ protected:
const void * doc_field_pointer;
int model_connector_mode;
QueryResult * query_result;
int table_index;
Model();
@ -269,15 +276,16 @@ protected:
field_generic(field_name, field_name, field_value, insertable, updatable, is_primary_key);
}
void field(const wchar_t * field_name, Model & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
void field(const wchar_t * field_name, Model & field_value, bool insertable = true, bool updatable = true)
{
field_model(field_name, field_name, field_value, insertable, updatable, is_primary_key);
field_model(field_name, field_name, field_value, insertable, updatable, true);
}
template<typename ModelClass>
void field(const wchar_t * field_name, std::list<ModelClass> & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
void field(const wchar_t * field_name, std::list<ModelClass> & field_value, bool insertable = true, bool updatable = true)
{
field_list(field_name, field_name, field_value, insertable, updatable, is_primary_key);
ModelClass * list_model_null_pointer = nullptr;
field_list(field_name, field_name, field_value, list_model_null_pointer, insertable, updatable);
}
@ -384,15 +392,16 @@ protected:
}
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_value, bool insertable = true, bool updatable = true)
{
field_model(db_field_name, flat_field_name, field_value, insertable, updatable, is_primary_key);
field_model(db_field_name, flat_field_name, field_value, insertable, updatable, true);
}
template<typename ModelClass>
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list<ModelClass> & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list<ModelClass> & field_value, bool insertable = true, bool updatable = true)
{
field_list(db_field_name, flat_field_name, field_value, insertable, updatable, is_primary_key);
ModelClass * list_model_null_pointer = nullptr;
field_list(db_field_name, flat_field_name, field_value, list_model_null_pointer, insertable, updatable);
}
//////////////////////
@ -644,7 +653,7 @@ protected:
if( flat_expression && !is_empty_field(flat_field_name) )
{
// insertable, updatable and is_primary_key are ignored here
flat_expression->field(flat_field_name, field_value, insertable, updatable, is_primary_key);
flat_expression->field(-1, flat_field_name, field_value, insertable, updatable, is_primary_key, true, model_data);
}
}
}
@ -659,7 +668,7 @@ protected:
if( db_expression && !is_empty_field(db_field_name) )
{
db_expression->field(db_field_name, field_value, insertable, updatable, is_primary_key);
db_expression->field(table_index, db_field_name, field_value, insertable, updatable, is_primary_key, true, model_data);
}
}
}
@ -705,14 +714,64 @@ protected:
}
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, bool insertable, bool updatable, bool is_primary_key)
void field_model_left_join(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, bool insertable, bool updatable, bool has_foreign_key, DbExpression * db_expression)
{
if( model_data )
{
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);
int expr_work_mode = db_expression->get_work_mode();
int expr_output_type = db_expression->get_output_type();
db_expression->set_work_mode(MORM_WORK_MODE_MODEL_SAVE_FIELDS);
db_expression->set_output_type(MORM_OUTPUT_TYPE_JOIN_TABLES);
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 << " = ";
if( !model_data->morm_foreign_keys.empty() )
{
model_data->morm_finder_join_tables << model_data->morm_foreign_keys.front();
}
}
else
{
map_fields();
model_data->morm_finder_join_tables << " ON ";
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 << ' ';
db_expression->set_work_mode(expr_work_mode);
db_expression->set_output_type(expr_output_type);
}
}
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, bool insertable, bool updatable, bool has_foreign_key)
{
if( model_connector )
{
field_model.set_connector(model_connector);
field_model.model_data = model_data;
// IMPLEMENTME what about db?
if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING )
{
FlatConnector * flat_connector = model_connector->get_flat_connector();
@ -724,7 +783,36 @@ protected:
if( flat_expression && !is_empty_field(flat_field_name) )
{
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING;
flat_expression->field_model(flat_field_name, field_model, insertable, updatable, is_primary_key);
flat_expression->field_model(flat_field_name, field_model, insertable, updatable, false);
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
}
}
}
if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL )
{
DbConnector * db_connector = model_connector->get_db_connector();
if( db_connector )
{
DbExpression * db_expression = db_connector->get_expression();
if( db_expression && !is_empty_field(db_field_name) )
{
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL;
if( db_expression->get_output_type() == MORM_OUTPUT_TYPE_SELECT_COLUMNS )
{
field_model_left_join(db_field_name, flat_field_name, field_model, insertable, updatable, has_foreign_key, db_expression);
}
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.map_fields();
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
}
field_model.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
}
}
@ -752,7 +840,7 @@ protected:
if( doc_expression && !is_empty_field(flat_field_name) )
{
// insertable, updatable and is_primary_key are ignored here
doc_expression->field_doc(*this, flat_field_name, field_model, insertable, updatable, is_primary_key);
doc_expression->field_doc(*this, flat_field_name, field_model, insertable, updatable, false);
}
}
}
@ -762,10 +850,9 @@ protected:
}
template<typename ModelContainer>
void field_list(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelContainer & field_container, bool insertable, bool updatable, bool is_primary_key)
template<typename ModelContainer, typename ModelContainerType>
void field_list(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelContainer & field_container, ModelContainerType * model_container_type, bool insertable, bool updatable)
{
// IMPLEMENTME what about db?
if( model_connector )
{
if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING )
@ -781,11 +868,31 @@ protected:
// IMPROVE ME
// what about model_data and save_mode?
// may it should be placed inside some structure?
flat_expression->field_list(flat_field_name, field_container, insertable, updatable, is_primary_key, model_connector, model_connector_mode, model_data);
flat_expression->field_list(flat_field_name, field_container, insertable, updatable, false, model_connector, model_connector_mode, model_data);
}
}
}
if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL )
{
DbConnector * db_connector = model_connector->get_db_connector();
if( db_connector )
{
DbExpression * db_expression = db_connector->get_expression();
if( db_expression && !is_empty_field(db_field_name) && db_expression->get_output_type() != MORM_OUTPUT_TYPE_JOIN_TABLES )
{
ModelContainerType model_type;
model_type.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_GENERATING_DB_SQL;
field_model(db_field_name, flat_field_name, model_type, insertable, updatable, false);
model_type.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
}
}
}
if( model_connector_mode == MORM_MODEL_CONNECTOR_MODE_CLEARING_VALUE )
{
Clearer * clearer = model_connector->get_clearer();
@ -808,7 +915,7 @@ protected:
if( doc_expression && !is_empty_field(flat_field_name) )
{
// insertable, updatable and is_primary_key are ignored here
doc_expression->field_doc(*this, flat_field_name, field_container, insertable, updatable, is_primary_key, model_data);
doc_expression->field_doc(*this, flat_field_name, field_container, insertable, updatable, false, model_data);
}
}
}

View File

@ -43,8 +43,19 @@ class ModelData
{
public:
ModelData() {}
virtual ~ModelData() {}
ModelData()
{
morm_current_max_column = 0;
}
virtual ~ModelData()
{
}
PT::TextStream morm_finder_join_tables;
std::list<std::string> morm_foreign_keys;
int morm_current_max_column;
/*
* may to add:

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* Copyright (c) 2018-2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -53,6 +53,7 @@
#define MORM_WORK_MODE_MODEL_VALUES 2
#define MORM_WORK_MODE_MODEL_FIELDS_VALUES 3
#define MORM_WORK_MODE_MODEL_SAVE_FIELDS 4
// IMPROVE ME give me a better name
@ -68,12 +69,14 @@
//#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_OUTPUT_TYPE_WHERE_IN 12
#define MORM_OUTPUT_TYPE_JOIN_TABLES 7
#define MORM_OUTPUT_TYPE_WHERE_EQ 10
#define MORM_OUTPUT_TYPE_WHERE_LT 11
#define MORM_OUTPUT_TYPE_WHERE_GT 12
#define MORM_OUTPUT_TYPE_WHERE_LE 13
#define MORM_OUTPUT_TYPE_WHERE_GE 14
#define MORM_OUTPUT_TYPE_WHERE_IN 15
#define MORM_CONJUNCTION_AND 1