From 958e89fb022b735b63b58c1747728558a6031b19 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 21 May 2019 15:51:13 +0000 Subject: [PATCH] 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 --- src/Makefile.dep | 46 +++++++++++--------- src/baseexpression.cpp | 12 +++--- src/baseexpression.h | 63 +++++++++++++++------------ src/cursor.h | 48 ++++++++++++++------- src/cursorhelper.h | 76 ++++++++++++++++++++++++++++++++ src/finder.h | 51 +++++++--------------- src/finderhelper.h | 98 ++++++++++++++++++++++++++++++++++++++++++ src/jsonexpression.cpp | 12 ++++++ src/jsonexpression.h | 3 ++ src/model.cpp | 9 ++-- src/model.h | 72 +++++++++++++------------------ src/modeldata.h | 87 ------------------------------------- src/modelenv.h | 10 ++++- 13 files changed, 349 insertions(+), 238 deletions(-) create mode 100644 src/cursorhelper.h create mode 100644 src/finderhelper.h diff --git a/src/Makefile.dep b/src/Makefile.dep index e372200..4a4f46e 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -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 diff --git a/src/baseexpression.cpp b/src/baseexpression.cpp index 554837f..6f826ae 100644 --- a/src/baseexpression.cpp +++ b/src/baseexpression.cpp @@ -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() diff --git a/src/baseexpression.h b/src/baseexpression.h index a80ce74..58edf80 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -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 - 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(&field_value), insertable, updatable, is_primary_key, model_data); + put_field_doc(model, reinterpret_cast(&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 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 template - 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(); } } diff --git a/src/cursor.h b/src/cursor.h index 6b42474..17c1052 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -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 @@ -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(); diff --git a/src/cursorhelper.h b/src/cursorhelper.h new file mode 100644 index 0000000..2b469f2 --- /dev/null +++ b/src/cursorhelper.h @@ -0,0 +1,76 @@ +/* + * This file is a part of morm + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * 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 diff --git a/src/finder.h b/src/finder.h index 6b767fb..7b7d76e 100644 --- a/src/finder.h +++ b/src/finder.h @@ -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 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() diff --git a/src/finderhelper.h b/src/finderhelper.h new file mode 100644 index 0000000..180eddb --- /dev/null +++ b/src/finderhelper.h @@ -0,0 +1,98 @@ +/* + * This file is a part of morm + * and is distributed under the 2-Clause BSD licence. + * Author: Tomasz Sowa + */ + +/* + * 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 morm_table_join_map; + std::list 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 diff --git a/src/jsonexpression.cpp b/src/jsonexpression.cpp index 6987460..1212c3f 100644 --- a/src/jsonexpression.cpp +++ b/src/jsonexpression.cpp @@ -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 ) diff --git a/src/jsonexpression.h b/src/jsonexpression.h index abbdb24..4a7e5e5 100644 --- a/src/jsonexpression.h +++ b/src/jsonexpression.h @@ -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 void print_field_name_value(const wchar_t * field_name, const FieldValue & field_value) diff --git a/src/model.cpp b/src/model.cpp index 5e51fc0..a36452b 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -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; + } } diff --git a/src/model.h b/src/model.h index 3cdce56..5be9e6d 100644 --- a/src/model.h +++ b/src/model.h @@ -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 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 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 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 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 ) { diff --git a/src/modeldata.h b/src/modeldata.h index 8781181..472bf69 100644 --- a/src/modeldata.h +++ b/src/modeldata.h @@ -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 morm_foreign_keys; - int morm_current_max_column; - std::map morm_table_join_map; - - int current_column; - //std::vector 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 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?) - * - * - */ }; } diff --git a/src/modelenv.h b/src/modelenv.h index 5c34e14..6042d80 100644 --- a/src/modelenv.h +++ b/src/modelenv.h @@ -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;