/* * This file is a part of morm * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2018-2023, 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_src_model #define headerfile_morm_src_model #include #include #include #include #include #include "textstream/textstream.h" #include "space/space.h" #include "modelconnector.h" #include "dbexpression.h" #include "flatexpression.h" #include "modelenv.h" #include "ft.h" #include "wrapper.h" #ifdef MORM_HAS_EZC_LIBRARY #include "funinfo.h" #endif #define MORM_MODEL_MEMBER_FIELD(ClassName) \ void field(const wchar_t * field_name, \ void (ClassName::*getter_method)(pt::Stream &), \ void (ClassName::*setter_method)(const char * input_str), \ const morm::FT & field_type = morm::FT::default_type) \ { \ field(field_name, field_name, getter_method, setter_method, field_type); \ }\ void field(const wchar_t * db_field_name, \ const wchar_t * flat_field_name, \ void (ClassName::*getter_method)(pt::Stream &), \ void (ClassName::*setter_method)(const char * input_str), \ const morm::FT & field_type = morm::FT::default_type) \ { \ typedef void (Model::*ModelGetterMethod)(pt::Stream &); \ typedef void (Model::*ModelSetterMethod)(const char * input_str); \ ModelGetterMethod model_getter_method = static_cast(getter_method); \ ModelSetterMethod model_setter_method = static_cast(setter_method); \ field_member(db_field_name, flat_field_name, model_getter_method, model_setter_method, field_type); \ }\ using Model::field; #ifdef MORM_HAS_EZC_LIBRARY #define MORM_MODEL_MEMBER_FIELD_EZC(ClassName) \ template \ void field(const wchar_t * field_name, void (ClassName::*method)(Ezc::FunInfo &), const morm::FT & field_type = morm::FT::default_type) \ { \ field(field_name, field_name, method, field_type); \ } \ template \ void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (ClassName::*method)(Ezc::FunInfo &), const morm::FT & field_type = morm::FT::default_type) \ { \ typedef void (Model::*ModelMember)(Ezc::FunInfo &); \ ModelMember model_member = static_cast(method); \ field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \ } \ void field(const wchar_t * field_name, bool (ClassName::*method)(), const morm::FT & field_type = morm::FT::default_type) \ { \ field(field_name, field_name, method, field_type); \ } \ void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool (ClassName::*method)(), const morm::FT & field_type = morm::FT::default_type) \ { \ typedef bool (Model::*ModelMember)(); \ ModelMember model_member = static_cast(method); \ field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \ } \ void field(const wchar_t * field_name, bool (ClassName::*method)() const, const morm::FT & field_type = morm::FT::default_type) \ { \ field(field_name, field_name, method, field_type); \ } \ void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool (ClassName::*method)() const, const morm::FT & field_type = morm::FT::default_type) \ { \ typedef bool (Model::*ModelMember)() const; \ ModelMember model_member = static_cast(method); \ field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \ } \ void field(const wchar_t * field_name, void (ClassName::*method)(morm::Wrapper &), const morm::FT & field_type = morm::FT::default_type) \ { \ field(field_name, field_name, method, field_type); \ } \ void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (ClassName::*method)(morm::Wrapper &), const morm::FT & field_type = morm::FT::default_type) \ { \ typedef void (Model::*ModelMember)(morm::Wrapper &); \ ModelMember model_member = static_cast(method); \ field_member_ezc(db_field_name, flat_field_name, model_member, field_type); \ } #endif #ifdef MORM_HAS_EZC_LIBRARY #define MORM_MEMBER_FIELD(ClassName) MORM_MODEL_MEMBER_FIELD(ClassName) MORM_MODEL_MEMBER_FIELD_EZC(ClassName) #else #define MORM_MEMBER_FIELD(ClassName) MORM_MODEL_MEMBER_FIELD(ClassName) #endif namespace morm { class Model { public: enum SaveMode { DO_INSERT_ON_SAVE = 0, DO_UPDATE_ON_SAVE, DO_DELETE_ON_SAVE, DO_NOTHING_ON_SAVE, }; virtual void set_save_mode(SaveMode save_mode); virtual SaveMode get_save_mode(); // set_save_mode() will be changed to set_save_mode2() in the future virtual void set_save_mode2(SaveMode save_mode, bool update_whole_tree = true); virtual void set_has_primary_key_set(bool has_primary_key); virtual bool get_has_primary_key_set() const; virtual void mark_to_delete(); virtual void mark_to_remove(); virtual void mark_to_insert(); virtual void mark_to_update(); virtual bool object_exists(); virtual bool found(); void set_connector(ModelConnector & connector); void set_connector(ModelConnector * connector); ModelConnector * get_connector(); virtual void get_table_name(pt::WTextStream & stream, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_stream = true); virtual void get_table_name(std::wstring & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true); virtual void get_table_name(std::string & str, bool with_schema_name = true, ModelData * model_data = nullptr, bool clear_string = true); virtual void to_text(pt::TextStream & stream, ModelData * model_data, Export exp = Export::default_type); virtual void to_text(pt::TextStream & stream, ModelData & model_data, Export exp = Export::default_type); virtual void to_text(pt::TextStream & stream, Export exp = Export::default_type); virtual void to_text(pt::TextStream & stream, ModelData * model_data, bool clear_stream, bool dump_mode); virtual void to_text(pt::TextStream & stream, ModelData & model_data, bool clear_stream, bool dump_mode); virtual void to_text(pt::TextStream & stream, bool clear_stream, bool dump_mode); virtual void to_text(std::string & str, ModelData * model_data, bool clear_string = true, bool dump_mode = false); virtual void to_text(std::string & str, ModelData & model_data, bool clear_string = true, bool dump_mode = false); virtual void to_text(std::string & str, bool clear_string = true, bool dump_mode = false); virtual std::string to_text(); virtual std::string to_string(); virtual void generate_insert_query(pt::TextStream & stream, ModelData * model_data = nullptr); virtual bool insert(ModelData * model_data, bool insert_whole_tree = true); virtual bool insert(ModelData & model_data, bool insert_whole_tree = true); virtual bool insert(bool insert_whole_tree = true); virtual void generate_update_query(pt::TextStream & stream, ModelData * model_data = nullptr); virtual bool update(ModelData * model_data, bool update_whole_tree = true); virtual bool update(ModelData & model_data, bool update_whole_tree = true); virtual bool update(bool update_whole_tree = true); virtual void generate_remove_query(pt::TextStream & stream, ModelData * model_data = nullptr); virtual bool remove(ModelData * model_data, bool remove_whole_tree = true); virtual bool remove(ModelData & model_data, bool remove_whole_tree = true); virtual bool remove(bool remove_whole_tree = true); virtual bool save(ModelData * model_data, bool save_whole_tree = true); virtual bool save(ModelData & model_data, bool save_whole_tree = true); virtual bool save(bool save_whole_tree = true); virtual void generate_select_columns(pt::TextStream & stream); // set object to default values virtual void clear(); virtual bool do_migration(int & current_table_version); // IMPROVE ME this will be protected // add set_field_value() functions for each POD type template void set_field_value_generic(const wchar_t * db_field_name, const wchar_t * flat_field_name, const FieldValue & field_value) { ModelEnv model_env_local; model_env = &model_env_local; model_env->model_work_mode = MORM_MODEL_WORK_MODE_SET_FIELD_VALUE; model_env->model = this; FieldValueHelper field_value_helper; field_value_helper.db_field_name = db_field_name; field_value_helper.flat_field_name = flat_field_name; field_value_helper.value_object = &field_value; field_value_helper.value_type_info = &typeid(field_value); std::vector helper_tab; helper_tab.push_back(field_value_helper); model_env->field_value_helper_tab = &helper_tab; fields(); if( !helper_tab.back().found && model_connector ) { pt::Log * plog = model_connector->get_logger(); if( plog ) { (*plog) << pt::Log::log1 << "Morm: I cannot find such a property: "; put_fields_to_log(*plog, db_field_name, flat_field_name); (*plog) << pt::Log::logend; } } // what if an exception was thrown? model_env = nullptr; } Model * get_model(const wchar_t * db_field_name, const wchar_t * flat_field_name); Wrapper get_wrapper(const wchar_t * db_field_name, const wchar_t * flat_field_name); bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Stream & stream, bool clear_stream = true); bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, pt::Stream & stream, bool clear_stream = true); #ifdef MORM_HAS_EZC_LIBRARY template bool get_raw_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelData * model_data, Ezc::FunInfo & fun_info, pt::Stream & stream, bool clear_stream = true) { if( clear_stream ) { stream.clear(); } ModelEnv model_env_local; model_env = &model_env_local; model_env->has_primary_key_set = has_primary_key_set; model_env->model_work_mode = MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM; model_env->db_field_name = db_field_name; model_env->flat_field_name = flat_field_name; model_env->model_data = model_data; model_env->stream = &stream; model_env->ezc_fun_info = &fun_info; model_env->ezc_fun_info_typeinfo = &typeid(fun_info); model_env->model = this; try { fields(); fun_info.res = model_env->ezc_fun_result; } catch(...) { model_env = nullptr; throw; } model_env = nullptr; return model_env_local.was_field_found; } #endif protected: ModelConnector * model_connector; ModelEnv * model_env; SaveMode save_mode; bool has_primary_key_set; Model(); Model(const Model & m); virtual ~Model(); /* * the main method of mapping between fields and database resultsets */ virtual void fields() = 0; virtual void table(); virtual void table_name(const wchar_t * table_name); virtual void table_name(const wchar_t * schema_name, const wchar_t * table_name); virtual void before_select(); virtual void before_insert(); virtual void before_update(); virtual void before_remove(); virtual void after_select(); virtual void after_insert(); virtual void after_update(); virtual void after_remove(); virtual void after_select_failure(); virtual void after_insert_failure(); virtual void after_update_failure(); virtual void after_remove_failure(); virtual int get_work_mode(); virtual ModelData * get_model_data(); virtual void insert_tree(bool insert_whole_tree); virtual void update_tree(bool update_whole_tree); virtual void remove_tree(bool remove_whole_tree); virtual void save_tree(bool save_whole_tree); virtual void map_values_from_query(); virtual void map_additional_columns_from_query(); virtual void map_rows_counter_from_query(); virtual bool db_query(const char * raw_sql); virtual bool db_query(const std::string & raw_sql); virtual bool db_query(const pt::TextStream & raw_sql); virtual bool db_query(const char ** raw_sql, size_t len); ///////////////////////////////// /* * IMPLEMENT ME * field methods for such field_values: signed char, char16_t, char32_t, std::u16string, std::u32string * */ void field(const wchar_t * field_name, char & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, unsigned char & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, wchar_t & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, std::wstring & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, std::string & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, bool & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, short & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, unsigned short & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, int & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, unsigned int & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, long & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, unsigned long & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, long long & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, unsigned long long & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, float & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, double & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, long double & field_value, const FT & field_type = FT::default_type) { field_generic(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, pt::Date & field_value, const FT & field_type = FT::default_type) { field_date(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, pt::Space & field_value, const FT & field_type = FT::default_type) { field_space(field_name, field_name, field_value, field_type); } void field(const wchar_t * field_name, Model & field_value, const FT & field_type = FT::default_type) { field_model(field_name, field_name, field_value, field_type); } template void field(const wchar_t * field_name, std::list & field_value, const FT & field_type = FT::default_type) { field_list(field_name, field_name, field_value, field_type); } template void field(const wchar_t * field_name, std::vector & field_value, const FT & field_type = FT::default_type) { field_vector(field_name, field_name, field_value, field_type); } template void field(const wchar_t * field_name, std::list & field_value, const FT & field_type = FT::default_type) { field_list(field_name, field_name, field_value, field_type); } template void field(const wchar_t * field_name, std::vector & field_value, const FT & field_type = FT::default_type) { field_vector(field_name, field_name, field_value, field_type); } /* * field methods which take two names: db_field_name and flat_field_name */ void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, char & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, unsigned char & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, wchar_t & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::wstring & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::string & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, short & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, unsigned short & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, int & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, unsigned int & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, long & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, unsigned long & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, long long & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, unsigned long long & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, float & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, double & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, long double & field_value, const FT & field_type = FT::default_type) { field_generic(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Date & field_value, const FT & field_type = FT::default_type) { field_date(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Space & field_value, const FT & field_type = FT::default_type) { field_space(db_field_name, flat_field_name, field_value, field_type); } void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_value, const FT & field_type = FT::default_type) { field_model(db_field_name, flat_field_name, field_value, field_type); } template void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list & field_value, const FT & field_type = FT::default_type) { field_list(db_field_name, flat_field_name, field_value, field_type); } template void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::vector & field_value, const FT & field_type = FT::default_type) { field_vector(db_field_name, flat_field_name, field_value, field_type); } // FIXME we need to correct handle such pointerns, cctor, dtor etc. template void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list & field_value, const FT & field_type = FT::default_type) { field_list(db_field_name, flat_field_name, field_value, field_type); } // FIXME we need to correct handle such pointerns, cctor, dtor etc. template void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::vector & field_value, const FT & field_type = FT::default_type) { field_vector(db_field_name, flat_field_name, field_value, field_type); } protected: template void field_generic_set_field_value(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value) { if( model_env->field_value_helper_tab ) { if( model_env->field_index >= 0 && (size_t)model_env->field_index < model_env->field_value_helper_tab->size() ) { FieldValueHelper & helper = (*model_env->field_value_helper_tab)[model_env->field_index]; pt::Log * log = model_connector->get_logger(); if( (!helper.compare_db_field_name || is_the_same_field(db_field_name, helper.db_field_name)) && (!helper.compare_flat_field_name || is_the_same_field(flat_field_name, helper.flat_field_name)) ) { if( helper.value_object && helper.value_type_info ) { if( typeid(field_value) == *helper.value_type_info ) { field_value = *(FieldValue*)helper.value_object; } else { if( log ) { (*log) << pt::Log::log1 << "Morm: incorrect type of a field in "; log_table_name(); (*log) << ", "; put_fields_to_log(*log, db_field_name, flat_field_name); (*log) << ", type expected " << typeid(field_value).name() << " got " << helper.value_type_info->name() << pt::Log::logend; } } } helper.found = true; model_env->field_index += 1; } } } } template void field_generic_iterate_primary_key_values(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type) { if( field_type.is_primary_key() ) { if( model_env->field_value_helper_tab ) { if( model_env->field_index >= 0 && (size_t)model_env->field_index < model_env->field_value_helper_tab->size() ) { FieldValueHelper & helper = (*model_env->field_value_helper_tab)[model_env->field_index]; helper.value_object = &field_value; helper.value_type_info = &typeid(field_value); } } model_env->field_index += 1; } } template void field_generic_generate_flat_string(const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type) { FlatConnector * flat_connector = model_connector->get_flat_connector(); if( flat_connector ) { FlatExpression * flat_expression = flat_connector->get_expression(); if( flat_expression && !is_empty_field(flat_field_name) ) { flat_expression->field(flat_field_name, field_value, field_type, model_env); } } } template void field_generic_generate_db_sql(const wchar_t * db_field_name, FieldValue & field_value, const FT & field_type) { 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->field(db_field_name, field_value, field_type, model_env); } } } template void field_generic_read_value_from_db_resultset(const wchar_t * db_field_name, FieldValue & field_value, const FT & field_type) { DbConnector * db_connector = model_connector->get_db_connector(); if( db_connector ) { if( !is_empty_field(db_field_name) ) { if( model_env->cursor_helper && model_env->cursor_helper->has_autogenerated_select ) { get_value_by_field_index(model_env->cursor_helper->current_column, field_value, field_type); model_env->cursor_helper->current_column += 1; } else { get_value_by_field_name(db_field_name, field_value, field_type); } } } } template void field_generic_clear_value(FieldValue & field_value, const FT & field_type) { Clearer * clearer = model_connector->get_clearer(); if( clearer ) { clearer->clear_value(field_value, field_type); } } template void field_generic_put_raw_value_to_stream(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) ) { model_env->was_field_found = true; if( model_env->stream ) { (*model_env->stream) << field_value; } #ifdef MORM_HAS_EZC_LIBRARY model_env->ezc_fun_result = convert_to_bool(field_value); #endif } } template void field_generic(const wchar_t * db_field_name, const wchar_t * flat_field_name, FieldValue & field_value, const FT & field_type) { if( model_connector && model_env ) { if( field_type.is_primary_key() ) { model_env->was_primary_key_read = true; } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_SET_FIELD_VALUE ) { field_generic_set_field_value(db_field_name, flat_field_name, field_value); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_ITERATE_PRIMARY_KEY_VALUES ) { field_generic_iterate_primary_key_values(db_field_name, flat_field_name, field_value, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING ) { field_generic_generate_flat_string(flat_field_name, field_value, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_DB_SQL ) { field_generic_generate_db_sql(db_field_name, field_value, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET ) { field_generic_read_value_from_db_resultset(db_field_name, field_value, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) { field_generic_clear_value(field_value, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM ) { field_generic_put_raw_value_to_stream(db_field_name, flat_field_name, field_value, field_type); } } } void field_date(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Date & field_value, const FT & field_type) { if( model_connector && model_env ) { if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) && !model_env->wrapper.date ) { model_env->wrapper.date = &field_value; } } else { field_generic(db_field_name, flat_field_name, field_value, field_type); } } } void field_space(const wchar_t * db_field_name, const wchar_t * flat_field_name, pt::Space & field_value, const FT & field_type) { if( model_connector && model_env ) { if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) && !model_env->wrapper.space_wrapper ) { model_env->wrapper.space_wrapper = new SpaceWrapper(&field_value); } } else { field_generic(db_field_name, flat_field_name, field_value, field_type); } } } void field_member_set_field_value( const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*setter_method)(const char * input_str)); void field_member_generate_flat_string( const wchar_t * flat_field_name, void (Model::*getter_method)(pt::Stream &), const FT & field_type); void field_member_generate_db_sql( const wchar_t * db_field_name, void (Model::*getter_method)(pt::Stream &), const FT & field_type); void field_member_read_value_from_db_resultset( const wchar_t * db_field_name, void (Model::*setter_method)(const char * input_str), const FT & field_type); void field_member_put_field_raw_value_to_stream( const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*getter_method)(pt::Stream &), const FT & field_type); void field_member_clear_value( void (Model::*setter_method)(const char * input_str), const FT & field_type); void field_member( const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*getter_method)(pt::Stream &), void (Model::*setter_method)(const char * input_str), const FT & field_type); #ifdef MORM_HAS_EZC_LIBRARY template void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo &), const FT & field_type) { if( model_connector && model_env && model_env->ezc_fun_info && model_env->ezc_fun_info_typeinfo && model_env->model ) { if( field_type.is_primary_key() ) { pt::Log * plog = model_connector->get_logger(); if( plog ) { (*plog) << pt::Log::log1 << "Morm:: an ezc method cannot be used as a primary key" << pt::Log::logend; } } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM ) { field_member_ezc_put_field_value_to_stream(db_field_name, flat_field_name, method, field_type); } } } template void field_member_ezc_put_field_value_to_stream(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Ezc::FunInfo &), const FT & field_type) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) ) { model_env->was_field_found = true; if( typeid(Ezc::FunInfo) == *model_env->ezc_fun_info_typeinfo ) { Ezc::FunInfo * ezc_fun_info = reinterpret_cast*>(model_env->ezc_fun_info); (model_env->model->*method)(*ezc_fun_info); model_env->ezc_fun_result = ezc_fun_info->res; // ezc_fun_info->res is overwritten in get_raw_value() after fields() method call so we have to remember it in model_env } else { pt::Log * plog = model_connector->get_logger(); if( plog ) { (*plog) << pt::Log::log2 << "Morm: incorrect method type for field: " << flat_field_name << pt::Log::logend; } } } } void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool (Model::*method)(), const FT & field_type) { if( model_connector && model_env && model_env->model ) { if( field_type.is_primary_key() ) { pt::Log * plog = model_connector->get_logger(); if( plog ) { (*plog) << pt::Log::log1 << "Morm:: an ezc method cannot be used as a primary key" << pt::Log::logend; } } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM ) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) ) { model_env->was_field_found = true; model_env->ezc_fun_result = (model_env->model->*method)(); } } } } void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool (Model::*method)() const, const FT & field_type) { if( model_connector && model_env && model_env->model ) { if( field_type.is_primary_key() ) { pt::Log * plog = model_connector->get_logger(); if( plog ) { (*plog) << pt::Log::log1 << "Morm:: an ezc method cannot be used as a primary key" << pt::Log::logend; } } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PUT_FIELD_RAW_VALUE_TO_STREAM ) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) ) { model_env->was_field_found = true; model_env->ezc_fun_result = (model_env->model->*method)(); } } } } void field_member_ezc(const wchar_t * db_field_name, const wchar_t * flat_field_name, void (Model::*method)(Wrapper & wrapper), const FT & field_type) { if( model_connector && model_env && model_env->model ) { if( field_type.is_primary_key() ) { pt::Log * plog = model_connector->get_logger(); if( plog ) { (*plog) << pt::Log::log1 << "Morm:: an ezc method cannot be used as a primary key" << pt::Log::logend; } } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) ) { (model_env->model->*method)(model_env->wrapper); } } } } #endif void field_model_left_join(const wchar_t * db_field_name, Model & field_model, const FT & field_type, DbExpression * db_expression); void field_model_save_key(const wchar_t * db_field_name); void field_model_set_parent_key_in_child(const wchar_t * db_field_name, Model & field_model); void field_model_set_parent_key(const wchar_t * db_field_name, Model & field_model); void field_model_iterate_through_childs(Model & field_model, const FT & field_type); void field_model_generate_flat_string(const wchar_t * flat_field_name, Model & field_model, const FT & field_type); void field_model_generate_db_sql(const wchar_t * db_field_name, Model & field_model, const FT & field_type); void field_model_clear_values(Model & field_model, const FT & field_type); void field_model_read_values_from_queryresult(const wchar_t * db_field_name, Model & field_model, const FT & field_type); void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, const FT & field_type); void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model * field_model, const FT & field_type); void field_model_for_db(const wchar_t * db_field_name, Model & field_model, const FT & field_type); template void field_list_set_parent_key(const wchar_t * db_field_name, ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo) { FieldValueHelper helper; helper.db_field_name = db_field_name; helper.flat_field_name = nullptr; helper.compare_flat_field_name = false; std::vector helper_tab; helper_tab.push_back(helper); // only one column at the moment, in the future we can have a primary key from more than one column model_env->field_value_helper_tab = &helper_tab; field_model_save_key(db_field_name); if constexpr (std::is_base_of()) { field_list_set_parent_key_by_value(db_field_name, field_container); } else { field_list_set_parent_key_by_pointer(db_field_name, field_container); } model_env->field_value_helper_tab = nullptr; } template void field_list_set_parent_key_by_value(const wchar_t * db_field_name, ModelContainer & field_container) { for(ModelContainerType & child_model : field_container) { child_model.set_connector(model_connector); field_model_set_parent_key_in_child(db_field_name, child_model); } } template void field_list_set_parent_key_by_pointer(const wchar_t * db_field_name, ModelContainer & field_container) { for(ModelContainerType * child_model : field_container) { child_model->set_connector(model_connector); field_model_set_parent_key_in_child(db_field_name, *child_model); } } template void field_list_iterate_through_childs(ModelContainer & field_container, ModelContainerType * model_container_type, const FT & field_type, IsContainerByValueRenameMe * foo) { if constexpr (std::is_base_of()) { field_list_iterate_through_childs_by_value(field_container, model_container_type, field_type); } else { field_list_iterate_through_childs_by_pointer(field_container, model_container_type, field_type); } } template void field_list_iterate_through_childs_by_value(ModelContainer & field_container, ModelContainerType * model_container_type, const FT & field_type) { for(ModelContainerType & child_model : field_container) { field_list_iterate_through_childs(child_model, field_type); } } template void field_list_iterate_through_childs_by_pointer(ModelContainer & field_container, ModelContainerType * model_container_type, const FT & field_type) { for(ModelContainerType * child_model : field_container) { field_list_iterate_through_childs(*child_model, field_type); } } template void field_list_iterate_through_childs(ModelContainerType & child_model, const FT & field_type) { if( model_env->status ) { ModelEnv model_env_local; model_env_local.copy_global_objects(*model_env); model_env_local.model = &child_model; child_model.model_env = &model_env_local; child_model.model_env->has_primary_key_set = child_model.has_primary_key_set; child_model.set_connector(model_connector); child_model.table(); field_model_iterate_through_childs(child_model, field_type); if( !model_env_local.status ) model_env->status = false; child_model.model_env = nullptr; } } template void field_list_generate_flat_string(const wchar_t * flat_field_name, ModelContainer & field_container, ModelContainerType * model_container_type, const FT & field_type, IsContainerByValueRenameMe * foo) { FlatConnector * flat_connector = model_connector->get_flat_connector(); if( flat_connector ) { FlatExpression * flat_expression = flat_connector->get_expression(); if( flat_expression ) { flat_expression->field_list(flat_field_name, field_container, model_container_type, field_type, model_connector, model_env, foo); } } } template void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type) { Clearer * clearer = model_connector->get_clearer(); if( clearer ) { clearer->clear_container(field_container, model_container_type, foo, field_type); } } template void field_list_propagate_save_status(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo) { if constexpr (std::is_base_of()) { if constexpr (std::is_base_of()) { field_list_propagate_save_status_in_container_by_value(field_container, model_container_type); } else { field_list_propagate_save_status_in_container_by_pointer(field_container, model_container_type); } } } template void field_list_propagate_save_status_in_container_by_value(ModelContainer & field_container, ModelContainerType * model_container_type) { for(ModelContainerType & item : field_container) { item.set_connector(model_connector); item.set_save_mode2(save_mode, true); } } template void field_list_propagate_save_status_in_container_by_pointer(ModelContainer & field_container, ModelContainerType * model_container_type) { for(ModelContainerType * item : field_container) { item->set_connector(model_connector); item->set_save_mode2(save_mode, true); } } template void field_vector(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::vector & field_value, const FT & field_type) { ContainerItemType * item_type_null_pointer = nullptr; if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if constexpr (std::is_base_of()) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) && !model_env->wrapper.model_container_wrapper ) { model_env->wrapper.model_container_wrapper = new ModelWrapperVector(&field_value); } } } else { ContainerItemType * pointer = nullptr; field_list_generic(db_field_name, flat_field_name, field_value, item_type_null_pointer, field_type, pointer); } } template void field_list(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list & field_value, const FT & field_type) { ContainerItemType * item_type_null_pointer = nullptr; if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if constexpr (std::is_base_of()) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) && !model_env->wrapper.model_container_wrapper ) { model_env->wrapper.model_container_wrapper = new ModelWrapperList(&field_value); } } } else { ContainerItemType * pointer = nullptr; field_list_generic(db_field_name, flat_field_name, field_value, item_type_null_pointer, field_type, pointer); } } template void field_vector(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::vector & field_value, const FT & field_type) { ContainerItemType * item_type_null_pointer = nullptr; if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if constexpr (std::is_base_of()) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) && !model_env->wrapper.model_container_wrapper ) { model_env->wrapper.model_container_wrapper = new ModelWrapperVectorPointer(&field_value); } } } else { void * pointer = nullptr; field_list_generic(db_field_name, flat_field_name, field_value, item_type_null_pointer, field_type, pointer); } } template void field_list(const wchar_t * db_field_name, const wchar_t * flat_field_name, std::list & field_value, const FT & field_type) { ContainerItemType * item_type_null_pointer = nullptr; if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_MODEL_WRAPPER ) { if constexpr (std::is_base_of()) { if( (is_empty_field(model_env->db_field_name) || is_the_same_field(db_field_name, model_env->db_field_name)) && (is_empty_field(model_env->flat_field_name) || is_the_same_field(flat_field_name, model_env->flat_field_name)) && !model_env->wrapper.model_container_wrapper ) { model_env->wrapper.model_container_wrapper = new ModelWrapperListPointer(&field_value); } } } else { void * pointer = nullptr; field_list_generic(db_field_name, flat_field_name, field_value, item_type_null_pointer, field_type, pointer); } } template void field_list_generic(const wchar_t * db_field_name, const wchar_t * flat_field_name, ModelContainer & field_container, ModelContainerType * model_container_type, const FT & field_type, IsContainerByValueRenameMe * foo) { if( model_connector && model_env ) { pt::Log * plog = model_connector->get_logger(); if( !is_empty_field(db_field_name) ) { /* * IMPROVEME * field_type.is_foreign_key() is not implemented for lists yet * (in such a case parent will point only to one object (or none) so the list will consists of only one object (or none)) */ if( field_type.is_foreign_key() ) { if( plog ) { (*plog) << pt::Log::log1 << "Morm: error: FT::is_foreign_key is not implemented for a list/vector yet" << pt::Log::logend; return; } } if constexpr (std::is_base_of()) { bool print_need_foreign_key_option = false; if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_SET_PARENT_ID ) { if( field_type.is_foreign_key() || field_type.is_foreign_key_in_child() ) { field_list_set_parent_key(db_field_name, field_container, model_container_type, foo); } else { print_need_foreign_key_option = true; } } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY ) { if( field_type.is_foreign_key() || field_type.is_foreign_key_in_child() ) { // IMPROVEME it would be good to make some optimisation before going through all items // such as: if UPDATE is called then we check if field_type allows to make update field_list_iterate_through_childs(field_container, model_container_type, field_type, foo); } else { print_need_foreign_key_option = true; } } if( print_need_foreign_key_option && plog ) { (*plog) << pt::Log::log1 << "Morm: error in "; log_table_name_with_field(db_field_name); (*plog) << " field, you should set FT::is_foreign_key or FT::is_foreign_key_in_child flag for a list of child objects" << pt::Log::logend; } } else { if( plog ) { (*plog) << pt::Log::log1 << "Morm: ignoring "; log_table_name_with_field(db_field_name); (*plog) << " as this is not a container with Model objects" << pt::Log::logend; } } } if( !is_empty_field(flat_field_name) ) { if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING ) { field_list_generate_flat_string(flat_field_name, field_container, model_container_type, field_type, foo); } } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) { field_list_clearing_values(field_container, model_container_type, foo, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS ) { field_list_propagate_save_status(field_container, model_container_type, foo); } } } template void get_value_by_field_index(int field_index, FieldValue & field_value, const FT & field_type) { DbConnector * db_connector = model_connector->get_db_connector(); if( db_connector && model_env->cursor_helper && model_env->cursor_helper->query_result ) { if( !model_env->cursor_helper->query_result->is_null(field_index) ) { const char * val_str = model_env->cursor_helper->query_result->get_field_string_value(field_index); if( val_str ) { db_connector->get_value(val_str, field_value, field_type); } } else { if( field_type.is_primary_key() ) { model_env->has_primary_key_set = false; } } } } template void get_value_by_field_name(const wchar_t * field_name, FieldValue & field_value, const FT & field_type) { DbConnector * db_connector = model_connector->get_db_connector(); if( db_connector && model_env->cursor_helper && model_env->cursor_helper->query_result ) { int column_index = -1; if( model_env->cursor_helper->use_table_prefix_for_fetching_values && model_env->finder_helper ) { DbExpression * db_expression = db_connector->get_expression(); if( db_expression ) { pt::TextStream table_field_name_str; db_expression->alias_to_stream(table_field_name_str, model_env->table_name, model_env->table_index, field_name); if( table_field_name_str.size() < 256 ) { wchar_t alias_name[256]; if( table_field_name_str.to_str(alias_name, sizeof(alias_name) / sizeof(wchar_t)) ) { column_index = model_env->cursor_helper->query_result->get_column_index(alias_name); } } } } else { column_index = model_env->cursor_helper->query_result->get_column_index(field_name); } if( column_index != -1 && !model_env->cursor_helper->query_result->is_null(column_index) ) { const char * val_str = model_env->cursor_helper->query_result->get_field_string_value(column_index); if( val_str ) { db_connector->get_value(val_str, field_value, field_type); } } else { if( field_type.is_primary_key() ) { model_env->has_primary_key_set = false; } } } } virtual void set_parent_key_in_childs(); public: template bool get_last_sequence(const wchar_t * sequence_table_name, FieldValue & field_value) { if( model_connector ) { DbConnector * db_connector = model_connector->get_db_connector(); if( db_connector && !is_empty_field(sequence_table_name) ) { return db_connector->get_last_sequence(sequence_table_name, field_value); } } return false; } template bool get_last_sequence_for_primary_key(const wchar_t * sequence_table_name, FieldValue & field_value) { has_primary_key_set = get_last_sequence(sequence_table_name, field_value); return has_primary_key_set; } template void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, const wchar_t * flat_field_name, FieldValue & field_value) { FT field_type = FT::no_insertable | FT::no_updatable | FT::raw_field_name; if( model_connector && model_env ) { if( model_env->model_work_mode == MORM_MODEL_WORK_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(new_column_expression) ) { db_expression->add_field_for_select(new_column_expression, new_column_name, field_value, field_type, model_env); } } } else if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING ) { field_generic(L"", flat_field_name, field_value, field_type); } else if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET ) { field_generic(new_column_name, L"", field_value, field_type); } else if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) { field_generic(L"", L"", field_value, field_type); // the names don't matter here } } } // RENAME ME to something like select_field() or field_select() template void add_field_for_select(const wchar_t * new_column_expression, const wchar_t * new_column_name, FieldValue & field_value) { add_field_for_select(new_column_expression, new_column_name, new_column_name, field_value); } protected: virtual bool is_empty_field(const wchar_t * value); virtual bool is_the_same_field(const wchar_t * field1, const wchar_t * field2); virtual pt::Log * get_logger(); virtual void put_to_log(const wchar_t * str); virtual void put_fields_to_log(pt::Log & log, const wchar_t * db_field_name, const wchar_t * flat_field_name); virtual void log_table_name(bool put_schema_name = true); virtual void log_table_name_with_field(const wchar_t * db_field_name = nullptr, bool put_schema_name = true); template bool do_migration(int & current_table_version, int destination_table_version, ModelObject * model_object, bool (ModelObject::*migration_function)()) { bool status = true; if( current_table_version < destination_table_version ) { if( (model_object->*migration_function)() ) { current_table_version = destination_table_version; } else { status = false; } } return status; } // those methods are used when converting fields to bool for Ezc library virtual bool convert_to_bool(char v); virtual bool convert_to_bool(unsigned char v); virtual bool convert_to_bool(wchar_t v); virtual bool convert_to_bool(const std::wstring & str); virtual bool convert_to_bool(const wchar_t * str); virtual bool convert_to_bool(const std::string & str); virtual bool convert_to_bool(const char * str); virtual bool convert_to_bool(bool v); virtual bool convert_to_bool(short v); virtual bool convert_to_bool(unsigned short v); virtual bool convert_to_bool(int v); virtual bool convert_to_bool(unsigned int v); virtual bool convert_to_bool(long v); virtual bool convert_to_bool(unsigned long v); virtual bool convert_to_bool(long long v); virtual bool convert_to_bool(unsigned long long v); virtual bool convert_to_bool(float v); virtual bool convert_to_bool(double v); virtual bool convert_to_bool(long double v); virtual bool convert_to_bool(const pt::Date & date); virtual bool convert_to_bool(const pt::TextStream & val); virtual bool convert_to_bool(const pt::WTextStream & val); virtual bool convert_to_bool(const pt::Space & space); template friend class Finder; template friend class Cursor; friend class BaseExpression; friend class DbExpression; friend class DbConnector; friend class FlatConnector; }; } // namespace #endif