some work in branches/join_models

- added FinderHelper class - used as a global object for the whole model tree in Finder
  (some fields moved from ModelData)
- added CursorHelper class - used as a global object for the whole model tree in Cursor
  (some fields moved from ModelData)







git-svn-id: svn://ttmath.org/publicrep/morm/branches/join_models@1192 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2019-05-21 15:51:13 +00:00
parent b37a577713
commit 958e89fb02
13 changed files with 349 additions and 238 deletions

View File

@ -7,10 +7,11 @@ 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 modelenv.h
baseexpression.o: modeldata.h queryresult.h model.h modelconnector.h
baseexpression.o: clearer.h dbconnector.h ../../pikotools/log/log.h
baseexpression.o: ../../pikotools/log/filelog.h flatconnector.h
baseexpression.o: dbexpression.h flatexpression.h ../../pikotools/utf8/utf8.h
baseexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
baseexpression.o: model.h modelconnector.h clearer.h dbconnector.h
baseexpression.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
baseexpression.o: flatconnector.h dbexpression.h flatexpression.h
baseexpression.o: ../../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 +20,8 @@ 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 modelenv.h modeldata.h flatexpression.h
clearer.o: morm_types.h modelenv.h modeldata.h cursorhelper.h finderhelper.h
clearer.o: 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 +29,9 @@ 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 modelenv.h modeldata.h model.h
dbconnector.o: modelconnector.h clearer.h flatconnector.h flatexpression.h
dbconnector.o: baseexpression.h morm_types.h modelenv.h modeldata.h
dbconnector.o: cursorhelper.h finderhelper.h model.h modelconnector.h
dbconnector.o: 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
@ -42,7 +45,7 @@ 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 modelenv.h
dbexpression.o: modeldata.h queryresult.h
dbexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
dochtmlconnector.o: dochtmlconnector.h flatconnector.h
dochtmlconnector.o: ../../pikotools/textstream/textstream.h
dochtmlconnector.o: ../../pikotools/space/space.h
@ -52,7 +55,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 modelenv.h
dochtmlconnector.o: modeldata.h queryresult.h
dochtmlconnector.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
dochtmlexpression.o: dochtmlexpression.h flatexpression.h baseexpression.h
dochtmlexpression.o: ../../pikotools/textstream/textstream.h
dochtmlexpression.o: ../../pikotools/space/space.h
@ -61,7 +64,8 @@ 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: modelenv.h modeldata.h queryresult.h
dochtmlexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
dochtmlexpression.o: finderhelper.h
flatconnector.o: flatconnector.h ../../pikotools/textstream/textstream.h
flatconnector.o: ../../pikotools/space/space.h
flatconnector.o: ../../pikotools/textstream/types.h
@ -70,9 +74,10 @@ 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 modelenv.h modeldata.h
flatconnector.o: queryresult.h model.h modelconnector.h clearer.h
flatconnector.o: dbconnector.h ../../pikotools/log/log.h
flatconnector.o: ../../pikotools/log/filelog.h dbexpression.h
flatconnector.o: cursorhelper.h queryresult.h finderhelper.h model.h
flatconnector.o: modelconnector.h clearer.h dbconnector.h
flatconnector.o: ../../pikotools/log/log.h ../../pikotools/log/filelog.h
flatconnector.o: dbexpression.h
flatexpression.o: flatexpression.h baseexpression.h
flatexpression.o: ../../pikotools/textstream/textstream.h
flatexpression.o: ../../pikotools/space/space.h
@ -81,7 +86,7 @@ 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 modelenv.h
flatexpression.o: modeldata.h queryresult.h
flatexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
jsonconnector.o: jsonconnector.h flatconnector.h
jsonconnector.o: ../../pikotools/textstream/textstream.h
jsonconnector.o: ../../pikotools/space/space.h
@ -91,7 +96,7 @@ 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 modelenv.h
jsonconnector.o: modeldata.h queryresult.h
jsonconnector.o: modeldata.h cursorhelper.h queryresult.h finderhelper.h
jsonexpression.o: jsonexpression.h flatexpression.h baseexpression.h
jsonexpression.o: ../../pikotools/textstream/textstream.h
jsonexpression.o: ../../pikotools/space/space.h
@ -100,7 +105,7 @@ 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 modelenv.h
jsonexpression.o: modeldata.h queryresult.h
jsonexpression.o: modeldata.h cursorhelper.h queryresult.h finderhelper.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
@ -109,7 +114,7 @@ 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 modelenv.h modeldata.h
model.o: flatexpression.h
model.o: cursorhelper.h finderhelper.h 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
@ -131,8 +136,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 modelenv.h modeldata.h
postgresqlconnector.o: ../../pikotools/convert/strtoint.h
postgresqlconnector.o: morm_types.h modelenv.h modeldata.h cursorhelper.h
postgresqlconnector.o: finderhelper.h ../../pikotools/convert/strtoint.h
postgresqlconnector.o: ../../pikotools/convert/text.h
postgresqlconnector.o: ../../pikotools/convert/misc.h
postgresqlexpression.o: postgresqlexpression.h dbexpression.h
@ -144,7 +149,8 @@ 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: modelenv.h modeldata.h queryresult.h
postgresqlexpression.o: modelenv.h modeldata.h cursorhelper.h queryresult.h
postgresqlexpression.o: finderhelper.h
postgresqlqueryresult.o: postgresqlqueryresult.h queryresult.h
queryresult.o: queryresult.h ../../pikotools/utf8/utf8.h
queryresult.o: ../../pikotools/textstream/textstream.h

View File

@ -197,15 +197,13 @@ void BaseExpression::put_field_name(const wchar_t * field_name, bool add_column_
void BaseExpression::put_field_doc(Model & model, const void * field_pointer, bool insertable, bool updatable, bool is_primary_key, ModelData * model_data)
void BaseExpression::put_field_doc(Model & model, const void * field_pointer, bool insertable, bool updatable, bool is_primary_key, ModelEnv * model_env)
{
/*
model.doc_field_pointer = field_pointer;
model.model_data = model_data;
//model.doc_field_pointer = field_pointer;
model.model_env = model_env;
model.map_doc_fields();
model.model_data = nullptr;
model.doc_field_pointer = nullptr;
*/
model.model_env = nullptr;
//model.doc_field_pointer = nullptr;
}
void BaseExpression::before_field_name()

View File

@ -75,12 +75,13 @@ public:
virtual void allow_to_use_prefix(bool use_prefix);
// give me a better name
virtual void put_field_doc(Model & model, const void * field_pointer, bool insertable, bool updatable, bool is_primary_key, ModelData * model_data);
virtual void put_field_doc(Model & model, const void * field_pointer, bool insertable, bool updatable, bool is_primary_key, ModelEnv * model_env);
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, ModelData * model_data = nullptr)
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, ModelEnv * model_env = nullptr)
{
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
{
@ -100,10 +101,10 @@ public:
put_field_name(field_name, add_column_prefix);
out_stream = old_out_stream;
if( model_data )
if( model_env && model_env->finder_helper )
{
model_data->morm_foreign_keys.emplace_back();
std::string & key_str = model_data->morm_foreign_keys.back();
model_env->finder_helper->morm_foreign_keys.emplace_back();
std::string & key_str = model_env->finder_helper->morm_foreign_keys.back();
str.to_string(key_str, false);
}
}
@ -131,7 +132,7 @@ public:
void field_doc(Model & model, 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)
ModelEnv * model_env = nullptr)
{
if( out_stream )
{
@ -140,7 +141,7 @@ public:
put_field_name(field_name, add_column_prefix);
put_name_value_separator();
put_field_doc(model, reinterpret_cast<const void*>(&field_value), insertable, updatable, is_primary_key, model_data);
put_field_doc(model, reinterpret_cast<const void*>(&field_value), insertable, updatable, is_primary_key, model_env);
put_name_value_separator();
put_type(field_value, *out_stream);
@ -181,7 +182,7 @@ public:
template<typename ModelContainer>
void field_list(const wchar_t * field_name, ModelContainer & field_value, bool insertable, bool updatable, bool is_primary_key,
ModelConnector * model_connector, int model_connector_mode, ModelData * model_data)
ModelConnector * model_connector, ModelEnv * model_env)
{
if( out_stream && can_field_be_generated(insertable, updatable, is_primary_key) )
{
@ -196,7 +197,7 @@ public:
{
put_field_name(field_name);
put_name_value_separator();
put_field_value_list(field_value, model_connector, model_connector_mode, model_data);
put_field_value_list(field_value, model_connector, model_env);
}
field_after();
@ -309,44 +310,50 @@ protected:
}
}
virtual void before_field_value_list()
{
}
virtual void after_field_value_list()
{
}
virtual void field_value_list_separator()
{
(*out_stream) << ",";
}
// what about lists with a pod types? e.g. list<int>
template<typename ModelContainer>
void put_field_value_list(ModelContainer & field_value, ModelConnector * model_connector, int model_connector_mode, ModelData * model_data)
void put_field_value_list(ModelContainer & field_value, ModelConnector * model_connector, ModelEnv * model_env)
{
if( out_stream )
if( model_connector && model_env && out_stream )
{
(*out_stream) << "[";// make a virtual method
}
bool is_first = true;
before_field_value_list();
bool is_first = true;
for(auto & m : field_value)
{
if( out_stream )
for(auto & m : field_value)
{
if( !is_first )
{
if( out_stream )
(*out_stream) << ","; // make a virtual method
field_value_list_separator();
}
ModelEnv model_env_local;
ModelEnv model_env_local(*model_env);
m.model_env = &model_env_local;
//before_field_value(field_value);
m.set_connector(model_connector);
m.model_env->model_connector_mode = model_connector_mode;
m.model_env->model_data = model_data;
generate_from_model(m);
m.model_env = nullptr;
//after_field_value(field_value);
is_first = false;
}
}
if( out_stream )
{
(*out_stream) << "]";// make a virtual method
after_field_value_list();
}
}

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
@ -51,7 +51,8 @@ public:
Cursor()
{
set_default_values();
query_result = nullptr;
clear();
}
@ -59,6 +60,7 @@ public:
{
model_connector = c.model_connector;
model_data = c.model_data;
has_autogenerated_select = c.has_autogenerated_select;
query_result = c.query_result;
select_status = c.select_status;
@ -66,6 +68,9 @@ public:
{
query_result->references_count += 1;
}
// helper doesn't have to be copied
cursor_helper.clear();
}
@ -91,7 +96,13 @@ public:
delete query_result;
}
set_default_values();
model_connector = nullptr;
model_data = nullptr;
has_autogenerated_select = false;
cursor_helper.clear();
query_result = nullptr;
select_status = false;
}
@ -119,6 +130,12 @@ public:
}
virtual void set_has_autogenerated_select(bool has_autogenerated_select)
{
this->has_autogenerated_select = has_autogenerated_select;
}
virtual QueryResult * get_query_result()
{
return query_result;
@ -144,7 +161,7 @@ public:
result.set_connector(model_connector);
result.clear();
if( model_connector && query_result && query_result->has_db_result() && model_data )
if( model_connector && query_result && query_result->has_db_result() )
{
DbConnector * db_connector = model_connector->get_db_connector();
@ -152,11 +169,13 @@ public:
{
ModelEnv model_env_local;
result.model_env = &model_env_local;
result.model_env->cursor_helper = &cursor_helper;
try
{
model_data->current_column = 0;
model_data->query_result = query_result;
cursor_helper.clear();
cursor_helper.query_result = query_result;
cursor_helper.has_autogenerated_select = has_autogenerated_select;
result.model_env->model_data = model_data;
result.before_select();
@ -214,7 +233,7 @@ public:
result.clear();
}
if( model_connector && query_result && query_result->has_db_result() && model_data )
if( model_connector && query_result && query_result->has_db_result() )
{
DbConnector * db_connector = model_connector->get_db_connector();
@ -264,17 +283,12 @@ protected:
ModelConnector * model_connector;
ModelData * model_data;
bool has_autogenerated_select;
CursorHelper cursor_helper;
QueryResult * query_result;
bool select_status;
virtual void set_default_values()
{
model_connector = nullptr;
model_data = nullptr;
query_result = nullptr;
select_status = false;
}
template<typename ContainerType>
@ -289,11 +303,13 @@ protected:
ModelEnv model_env_local;
added_model.model_env = &model_env_local;
added_model.model_env->cursor_helper = &cursor_helper;
try
{
model_data->current_column = 0;
model_data->query_result = query_result;
cursor_helper.clear();
cursor_helper.query_result = query_result;
cursor_helper.has_autogenerated_select = has_autogenerated_select;
added_model.set_connector(model_connector);
added_model.clear();

76
src/cursorhelper.h Normal file
View File

@ -0,0 +1,76 @@
/*
* This file is a part of morm
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_morm_cursorhelper
#define headerfile_morm_cursorhelper
#include "queryresult.h"
namespace morm
{
class CursorHelper
{
public:
bool has_autogenerated_select;
QueryResult * query_result;
int current_column;
CursorHelper()
{
clear();
}
virtual ~CursorHelper()
{
}
virtual void clear()
{
has_autogenerated_select = false;
query_result = nullptr;
current_column = 0;
}
};
}
#endif

View File

@ -175,13 +175,7 @@ public:
was_query_error = false;
last_query_error.clear();
column_prefix.clear();
model.model_env = &model_env;
model.model_env->clear();
//model.model_data = nullptr;
// what about model_data in model here?
model.prepare_to_select();
has_autogenerated_select = false;
if( model_connector )
{
@ -189,7 +183,6 @@ public:
{
set_db_expression();
out_stream->clear();
model.set_connector(model_connector);
}
else
{
@ -203,11 +196,6 @@ public:
last_query_error = L"model connector object is required";
}
if( !model_data )
{
model_data = &model_data_generic;
}
return *this;
}
@ -254,21 +242,17 @@ public:
prepare_to_select();
}
if( !model.model_env )
{
model.model_env = &model_env;
model.model_env->clear();
}
model.set_connector(model_connector);
if( !model_data )
{
model_data = &model_data_generic;
}
finder_helper.clear();
model_env.clear();
model.model_env = &model_env;
model.model_env->model_data = model_data;
model.model_env->finder_helper = &finder_helper;
model.prepare_to_select();
model_data->prepare_to_new_select();
model_data->has_autogenerated_select = true;
has_autogenerated_select = true;
if( model_connector && out_stream )
{
@ -280,7 +264,7 @@ public:
model.table_name_for_join_as(prefix_stream);
prefix_stream.to_string(column_prefix);
model_data->add_join_table(column_prefix);
finder_helper.add_join_table(column_prefix);
}
model.generate_select_columns(*out_stream, column_prefix);
@ -294,18 +278,14 @@ public:
else
{
(*out_stream) << " AS ";
PT::TextStream str_tmp; // improve me
PT::TextStream str_tmp;
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);
finder_helper.add_join_table(str_tmp);
}
(*out_stream) << " ";
(*out_stream) << model_data->morm_finder_join_tables;
(*out_stream) << finder_helper.morm_finder_join_tables;
}
return *this;
@ -551,6 +531,7 @@ public:
{
Cursor<ModelClass> cursor;
cursor.set_model_data(model_data);
cursor.set_has_autogenerated_select(has_autogenerated_select);
if( model_connector && out_stream )
{
@ -613,13 +594,13 @@ 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;
std::string column_prefix;
ModelEnv model_env;
FinderHelper finder_helper;
ModelData * model_data;
bool has_autogenerated_select;
void set_db_expression()

98
src/finderhelper.h Normal file
View File

@ -0,0 +1,98 @@
/*
* This file is a part of morm
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2019, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef headerfile_morm_finderhelper
#define headerfile_morm_finderhelper
#include "queryresult.h"
namespace morm
{
class FinderHelper
{
public:
PT::TextStream morm_finder_join_tables;
std::map<std::string, int> morm_table_join_map;
std::list<std::string> morm_foreign_keys;
FinderHelper()
{
}
virtual ~FinderHelper()
{
}
virtual void clear()
{
morm_finder_join_tables.clear();
morm_table_join_map.clear();
morm_foreign_keys.clear();
}
virtual int add_join_table(const PT::TextStream & table_name)
{
std::string table_name_str;
table_name.to_string(table_name_str);
return add_join_table(table_name_str);
}
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;
}
};
}
#endif

View File

@ -137,6 +137,18 @@ void JSONExpression::put_name_value_separator()
}
void JSONExpression::before_field_value_list()
{
(*out_stream) << "[";
}
void JSONExpression::after_field_value_list()
{
(*out_stream) << "]";
}
void JSONExpression::esc(char val, PT::TextStream & stream)
{
switch( val )

View File

@ -64,6 +64,9 @@ protected:
void before_field_value(const PT::Date &);
void after_field_value(const PT::Date &);
void before_field_value_list();
void after_field_value_list();
template<typename FieldValue>
void print_field_name_value(const wchar_t * field_name, const FieldValue & field_value)

View File

@ -531,9 +531,12 @@ void Model::generate_doc_for_db(PT::TextStream & stream, bool clear_stream)
void Model::map_values_from_query()
{
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_READING_VALUE_FROM_DB_RESULTSET;
map_fields();
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
if( model_env )
{
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_READING_VALUE_FROM_DB_RESULTSET;
map_fields();
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
}
}

View File

@ -166,7 +166,7 @@ protected:
virtual ModelData * get_model_data();
// used by Cursor
virtual void map_values_from_query();
@ -636,7 +636,7 @@ protected:
template<typename FieldValue>
void field_generic(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, bool insertable, bool updatable, bool is_primary_key)
{
if( model_connector )
if( model_connector && model_env )
{
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING )
{
@ -649,7 +649,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, true, model_env->model_data);
flat_expression->field(flat_field_name, field_value, insertable, updatable, is_primary_key, true, model_env);
}
}
}
@ -664,12 +664,7 @@ protected:
if( db_expression && !is_empty_field(db_field_name) )
{
db_expression->field(db_field_name, field_value, insertable, updatable, is_primary_key, true, model_env->model_data);
if( model_env->model_data )
{
model_env->model_data->current_column += 1;
}
db_expression->field(db_field_name, field_value, insertable, updatable, is_primary_key, true, model_env);
}
}
}
@ -682,10 +677,10 @@ protected:
{
if( !is_empty_field(db_field_name) )
{
if( model_env->model_data && model_env->model_data->has_autogenerated_select )
if( model_env->model_data && model_env->cursor_helper && model_env->cursor_helper->has_autogenerated_select )
{
get_value_by_field_index(model_env->model_data->current_column, field_value);
model_env->model_data->current_column += 1;
get_value_by_field_index(model_env->cursor_helper->current_column, field_value);
model_env->cursor_helper->current_column += 1;
}
else
{
@ -727,14 +722,14 @@ protected:
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_env->model_data )
if( model_env->finder_helper )
{
model_env->model_data->morm_current_max_column += 1;
model_env->model_data->morm_foreign_keys.clear();
//model_env->select_helper->morm_current_max_column += 1;
model_env->finder_helper->morm_foreign_keys.clear();
model_env->model_data->morm_finder_join_tables << "LEFT JOIN ";
field_model.table_name(model_env->model_data->morm_finder_join_tables);
model_env->model_data->morm_finder_join_tables << " AS ";
model_env->finder_helper->morm_finder_join_tables << "LEFT JOIN ";
field_model.table_name(model_env->finder_helper->morm_finder_join_tables);
model_env->finder_helper->morm_finder_join_tables << " AS ";
//////////////
@ -749,14 +744,14 @@ protected:
PT::TextStream join_table_name;
field_model.table_name_for_join_as(join_table_name);
field_model.model_env->table_index = model_env->model_data->add_join_table(join_table_name);
field_model.model_env->table_index = model_env->finder_helper->add_join_table(join_table_name);
if( field_model.model_env->table_index > 1 )
join_table_name << field_model.model_env->table_index;
//////////
model_env->model_data->morm_finder_join_tables << join_table_name;
model_env->finder_helper->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();
@ -770,29 +765,29 @@ protected:
{
field_model.map_fields();
model_env->model_data->morm_finder_join_tables << " ON " << join_table_name_this << '.' << db_field_name; // escape?
model_env->model_data->morm_finder_join_tables << " = " << join_table_name << '.';
model_env->finder_helper->morm_finder_join_tables << " ON " << join_table_name_this << '.' << db_field_name; // escape?
model_env->finder_helper->morm_finder_join_tables << " = " << join_table_name << '.';
if( !model_env->model_data->morm_foreign_keys.empty() )
if( !model_env->finder_helper->morm_foreign_keys.empty() )
{
model_env->model_data->morm_finder_join_tables << model_env->model_data->morm_foreign_keys.front();
model_env->finder_helper->morm_finder_join_tables << model_env->finder_helper->morm_foreign_keys.front();
}
}
else
{
map_fields();
model_env->model_data->morm_finder_join_tables << " ON " << join_table_name_this << '.';
model_env->finder_helper->morm_finder_join_tables << " ON " << join_table_name_this << '.';
if( !model_env->model_data->morm_foreign_keys.empty() )
if( !model_env->finder_helper->morm_foreign_keys.empty() )
{
model_env->model_data->morm_finder_join_tables << model_env->model_data->morm_foreign_keys.front();
model_env->finder_helper->morm_finder_join_tables << model_env->finder_helper->morm_foreign_keys.front();
}
model_env->model_data->morm_finder_join_tables << " = " << (join_table_name) << '.' << db_field_name;
model_env->finder_helper->morm_finder_join_tables << " = " << (join_table_name) << '.' << db_field_name;
}
model_env->model_data->morm_finder_join_tables << ' ';
model_env->finder_helper->morm_finder_join_tables << ' ';
db_expression->set_work_mode(expr_work_mode);
db_expression->set_output_type(expr_output_type);
@ -860,11 +855,6 @@ protected:
}
field_model.model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
if( model_env->model_data )
{
model_env->model_data->current_column += 1;
}
}
}
}
@ -920,7 +910,7 @@ protected:
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 )
if( model_connector && model_env )
{
ModelEnv model_env_local(*model_env);
field_model.model_env = &model_env_local;
@ -959,7 +949,7 @@ protected:
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)
{
if( model_connector )
if( model_connector && model_env )
{
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING )
{
@ -974,7 +964,7 @@ 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, false, model_connector, model_env->model_connector_mode, model_env->model_data);
flat_expression->field_list(flat_field_name, field_container, insertable, updatable, false, model_connector, model_env);
}
}
}
@ -1030,9 +1020,9 @@ protected:
template<typename FieldValue>
void get_value_by_field_index(int field_index, FieldValue & field_value)
{
if( model_env->model_data && model_env->model_data->query_result )
if( model_env->cursor_helper && model_env->cursor_helper->query_result )
{
const char * val_str = model_env->model_data->query_result->get_field_string_value(field_index);
const char * val_str = model_env->cursor_helper->query_result->get_field_string_value(field_index);
if( val_str )
{
@ -1050,9 +1040,9 @@ protected:
template<typename FieldValue>
void get_value_by_field_name(const wchar_t * field_name, FieldValue & field_value)
{
if( model_env->model_data && model_env->model_data->query_result )
if( model_env->cursor_helper && model_env->cursor_helper->query_result )
{
const char * val_str = model_env->model_data->query_result->get_field_string_value(field_name);
const char * val_str = model_env->cursor_helper->query_result->get_field_string_value(field_name);
if( val_str )
{

View File

@ -35,7 +35,6 @@
#ifndef headerfile_morm_modeldata
#define headerfile_morm_modeldata
#include "queryresult.h"
namespace morm
@ -47,98 +46,12 @@ public:
ModelData()
{
morm_current_max_column = 1;
current_column = 1;
query_result = nullptr;
}
virtual ~ModelData()
{
}
bool has_autogenerated_select;
QueryResult * query_result;
// int table_index;
// can be moved to another struct?
// let ModelData be only for user stuff
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;
int current_column;
//std::vector<int> table_index;
virtual void prepare_to_new_select()
{
has_autogenerated_select = false;
query_result = nullptr;
// table_index = 1;
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 PT::TextStream & table_name)
{
std::string table_name_str;
table_name.to_string(table_name_str);
return add_join_table(table_name_str);
}
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;
// }
// virtual int get_table_index(int column)
// {
// if( column < (int)table_index.size() )
// return table_index[column];
//
// return 0;
// }
/*
* may to add:
* std::set<std::wstring> skip_columns;
* and Finder can use this
* also update and insert from Model
* (but what about the same name of columns through the whole objects-tree?
* may we can save the name of the table too?)
*
*
*/
};
}

View File

@ -36,18 +36,22 @@
#define headerfile_morm_modelenv
#include "modeldata.h"
#include "cursorhelper.h"
#include "finderhelper.h"
#include "morm_types.h"
namespace morm
{
// rename me?
class ModelEnv
{
public:
ModelData * model_data;
FinderHelper * finder_helper;
CursorHelper * cursor_helper;
int model_connector_mode;
int table_index;
const void * doc_field_pointer;
@ -67,6 +71,8 @@ public:
ModelEnv(const ModelEnv & e)
{
model_data = e.model_data;
finder_helper = e.finder_helper;
cursor_helper = e.cursor_helper;
model_connector_mode = e.model_connector_mode;
table_index = e.table_index;
doc_field_pointer = e.doc_field_pointer;
@ -76,6 +82,8 @@ public:
void clear()
{
model_data = nullptr;
finder_helper = nullptr;
cursor_helper = nullptr;
model_connector_mode = MORM_MODEL_CONNECTOR_MODE_NONE;
table_index = 0;
doc_field_pointer = nullptr;