2018-03-13 23:22:17 +01:00
/*
* This file is a part of morm
* and is distributed under the 2 - Clause BSD licence .
* Author : Tomasz Sowa < t . sowa @ ttmath . org >
*/
/*
2021-02-23 16:58:45 +01:00
* Copyright ( c ) 2018 - 2021 , Tomasz Sowa
2018-03-13 23:22:17 +01:00
* 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_model
# define headerfile_morm_model
# include <string>
2019-08-20 17:49:37 +02:00
# include <list>
# include <vector>
2019-09-11 20:16:22 +02:00
# include <typeinfo>
2019-09-25 18:20:37 +02:00
# include <type_traits>
2018-03-13 23:22:17 +01:00
# include "textstream/textstream.h"
# include "modelconnector.h"
2018-07-05 11:51:26 +02:00
# include "dbexpression.h"
# include "flatexpression.h"
2019-05-13 19:59:28 +02:00
# include "modelenv.h"
2021-03-10 16:20:11 +01:00
# include "ft.h"
2018-03-13 23:22:17 +01:00
namespace morm
{
class Model
{
public :
2018-04-22 03:26:46 +02:00
enum SaveMode
{
2019-09-13 20:17:02 +02:00
DO_INSERT_ON_SAVE = 0 ,
2018-04-22 03:26:46 +02:00
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 ( ) ;
2021-03-09 18:10:34 +01:00
virtual void set_has_primary_key_set ( bool has_primary_key ) ;
virtual bool get_has_primary_key_set ( ) ;
2018-04-22 03:26:46 +02:00
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 ( ) ;
2018-03-13 23:22:17 +01:00
void set_connector ( ModelConnector & connector ) ;
2018-04-22 03:26:46 +02:00
void set_connector ( ModelConnector * connector ) ;
2021-02-23 16:58:45 +01:00
ModelConnector * get_connector ( ) ;
2018-03-13 23:22:17 +01:00
/*
* map fields to names
*
2021-03-11 12:22:37 +01:00
* IMPROVEME rename me to fields ( ) and make protected
2018-03-13 23:22:17 +01:00
*/
virtual void map_fields ( ) = 0 ;
2018-07-16 00:36:04 +02:00
2018-03-13 23:22:17 +01:00
/*
2021-03-11 12:22:37 +01:00
* IMPROVEME make me protected
2018-03-13 23:22:17 +01:00
*/
2021-03-11 12:22:37 +01:00
virtual void prepare_table ( ) ;
virtual void table ( const wchar_t * table_name ) ;
virtual void table ( const wchar_t * schema_name , const wchar_t * table_name ) ;
2018-03-13 23:22:17 +01:00
2019-09-13 20:17:02 +02:00
virtual void to_text ( PT : : TextStream & stream , ModelData * model_data , bool clear_stream = true , bool dump_mode = false ) ;
virtual void to_text ( PT : : TextStream & stream , ModelData & model_data , bool clear_stream = true , bool dump_mode = false ) ;
virtual void to_text ( PT : : TextStream & stream , bool clear_stream = true , bool dump_mode = false ) ;
2019-03-07 19:02:29 +01:00
2019-09-13 20:17:02 +02:00
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 ) ;
2019-03-07 19:02:29 +01:00
2018-03-23 20:26:57 +01:00
virtual std : : string to_text ( ) ;
virtual std : : string to_string ( ) ;
2018-03-13 23:22:17 +01:00
2019-08-20 17:49:37 +02:00
virtual void generate_insert_query ( PT : : TextStream & stream , ModelData * model_data = nullptr ) ;
2019-09-25 18:20:37 +02:00
virtual bool insert ( ModelData * model_data , bool insert_whole_tree = true ) ;
2019-08-21 19:42:50 +02:00
virtual bool insert ( ModelData & model_data , bool insert_whole_tree = true ) ;
2019-09-25 18:20:37 +02:00
virtual bool insert ( bool insert_whole_tree = true ) ;
2018-03-13 23:22:17 +01:00
2019-08-20 17:49:37 +02:00
virtual void generate_update_query ( PT : : TextStream & stream , ModelData * model_data = nullptr ) ;
2019-09-25 18:20:37 +02:00
virtual bool update ( ModelData * model_data , bool update_whole_tree = true ) ;
2019-09-04 18:02:18 +02:00
virtual bool update ( ModelData & model_data , bool update_whole_tree = true ) ;
2019-09-25 18:20:37 +02:00
virtual bool update ( bool update_whole_tree = true ) ;
2018-03-13 23:22:17 +01:00
2019-08-20 17:49:37 +02:00
virtual void generate_remove_query ( PT : : TextStream & stream , ModelData * model_data = nullptr ) ;
2019-09-25 18:20:37 +02:00
virtual bool remove ( ModelData * model_data , bool remove_whole_tree = true ) ;
2019-09-05 18:32:35 +02:00
virtual bool remove ( ModelData & model_data , bool remove_whole_tree = true ) ;
2019-09-25 18:20:37 +02:00
virtual bool remove ( bool remove_whole_tree = true ) ;
2018-04-22 03:26:46 +02:00
2019-09-25 18:20:37 +02:00
virtual bool save ( ModelData * model_data , bool save_whole_tree = true ) ;
2019-09-04 18:02:18 +02:00
virtual bool save ( ModelData & model_data , bool save_whole_tree = true ) ;
2019-09-25 18:20:37 +02:00
virtual bool save ( bool save_whole_tree = true ) ;
2018-03-13 23:22:17 +01:00
2019-05-21 19:24:12 +02:00
virtual void generate_select_columns ( PT : : TextStream & stream ) ;
2018-03-30 21:34:45 +02:00
// set object to default values
virtual void clear ( ) ;
2018-03-13 23:22:17 +01:00
2019-08-22 20:33:35 +02:00
// IMPROVE ME this will be protected
// add set_field_value() functions for each POD type
template < typename FieldValue >
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 ;
2019-09-18 17:28:06 +02:00
model_env - > model_work_mode = MORM_MODEL_WORK_MODE_SET_FIELD_VALUE ;
2019-08-22 20:33:35 +02:00
model_env - > field_index = 0 ;
2021-03-11 12:22:37 +01:00
prepare_table ( ) ; // CHECK ME it is needed to set table name?
2019-08-22 20:33:35 +02:00
2019-09-11 20:16:22 +02:00
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 ) ;
2019-08-22 20:33:35 +02:00
2019-09-11 20:16:22 +02:00
std : : vector < FieldValueHelper > helper_tab ;
helper_tab . push_back ( field_value_helper ) ;
model_env - > field_value_helper_tab = & helper_tab ;
2019-08-22 20:33:35 +02:00
map_fields ( ) ;
2019-09-24 19:08:45 +02:00
if ( ! helper_tab . back ( ) . found & & model_connector )
{
PT : : Log * plog = model_connector - > get_logger ( ) ;
if ( plog )
{
2021-03-11 12:22:37 +01:00
( * plog ) < < PT : : Log : : log1 < < " Morm: I cannot find such a property: " ;
2019-09-24 19:08:45 +02:00
put_fields_to_log ( * plog , db_field_name , flat_field_name ) ;
( * plog ) < < PT : : Log : : logend ;
}
}
2019-08-22 20:33:35 +02:00
// what if an exception was thrown?
model_env = nullptr ;
}
2018-04-17 00:46:25 +02:00
2019-03-26 19:34:07 +01:00
2018-03-13 23:22:17 +01:00
protected :
ModelConnector * model_connector ;
2019-05-13 19:59:28 +02:00
ModelEnv * model_env ;
2021-03-09 18:10:34 +01:00
SaveMode save_mode ;
bool has_primary_key_set ;
2019-05-13 19:59:28 +02:00
2018-11-14 18:14:26 +01:00
2018-03-13 23:22:17 +01:00
Model ( ) ;
2018-11-14 18:14:26 +01:00
Model ( const Model & m ) ;
2018-03-13 23:22:17 +01:00
virtual ~ Model ( ) ;
2018-04-17 00:46:25 +02:00
virtual void before_select ( ) ;
virtual void before_insert ( ) ;
virtual void before_update ( ) ;
2018-04-22 03:26:46 +02:00
virtual void before_remove ( ) ;
2018-04-17 00:46:25 +02:00
virtual void after_select ( ) ;
virtual void after_insert ( ) ;
virtual void after_update ( ) ;
2018-04-22 03:26:46 +02:00
virtual void after_remove ( ) ;
virtual void after_select_failure ( ) ;
virtual void after_insert_failure ( ) ;
virtual void after_update_failure ( ) ;
virtual void after_remove_failure ( ) ;
2018-03-13 23:22:17 +01:00
2019-09-18 17:28:06 +02:00
virtual int get_work_mode ( ) ;
2018-04-19 17:21:51 +02:00
2019-05-13 19:59:28 +02:00
virtual ModelData * get_model_data ( ) ;
2019-08-21 19:42:50 +02:00
virtual bool insert_tree ( bool insert_whole_tree ) ;
2019-09-04 18:02:18 +02:00
virtual bool update_tree ( bool update_whole_tree ) ;
2019-09-05 18:32:35 +02:00
virtual bool remove_tree ( bool remove_whole_tree ) ;
2019-09-04 18:02:18 +02:00
virtual bool save_tree ( bool save_whole_tree ) ;
2019-05-21 17:51:13 +02:00
2019-05-13 19:59:28 +02:00
virtual void map_values_from_query ( ) ;
2018-07-04 13:34:49 +02:00
2018-07-03 18:55:06 +02:00
/////////////////////////////////
2019-09-25 19:21:12 +02:00
/*
* IMPLEMENT ME
* field methods for such field_values : signed char , wchar_t , char16_t , char32_t , std : : u16string , std : : u32string
*
*/
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , char & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , unsigned char & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , std : : wstring & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , std : : string & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , bool & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , short & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , unsigned short & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , int & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , unsigned int & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , unsigned long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , long long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , unsigned long long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , float & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , double & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , long double & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , PT : : Date & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( field_name , field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , Model & field_value , FT field_type = FT : : default_type )
2018-04-26 20:58:31 +02:00
{
2021-03-10 16:20:11 +01:00
// has_foreign_key was here
field_model ( field_name , field_name , field_value , field_type ) ;
2018-04-26 20:58:31 +02:00
}
2018-07-03 18:55:06 +02:00
template < typename ModelClass >
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , std : : list < ModelClass > & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2019-03-26 19:34:07 +01:00
ModelClass * list_model_null_pointer = nullptr ;
2021-03-10 16:20:11 +01:00
field_list ( field_name , field_name , field_value , list_model_null_pointer , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2018-04-26 20:58:31 +02:00
2019-08-20 17:49:37 +02:00
template < typename ModelClass >
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * field_name , std : : vector < ModelClass > & field_value , FT field_type = FT : : default_type )
2019-08-20 17:49:37 +02:00
{
ModelClass * list_model_null_pointer = nullptr ;
2021-03-10 16:20:11 +01:00
field_list ( field_name , field_name , field_value , list_model_null_pointer , field_type ) ;
2019-08-20 17:49:37 +02:00
}
2018-04-26 20:58:31 +02:00
2021-03-10 16:20:11 +01:00
/*
* 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 , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , unsigned char & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , std : : wstring & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , std : : string & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , bool & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , short & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , unsigned short & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , int & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , unsigned int & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , unsigned long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , long long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , unsigned long long & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , float & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , double & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , long double & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , PT : : Date & field_value , FT field_type = FT : : default_type )
2018-07-03 18:55:06 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-03 18:55:06 +02:00
}
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , Model & field_value , FT field_type = FT : : default_type )
2018-03-13 23:22:17 +01:00
{
2021-03-10 16:20:11 +01:00
// has_foreign_key was here
field_model ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-04-22 23:04:50 +02:00
}
2018-07-03 18:55:06 +02:00
template < typename ModelClass >
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , std : : list < ModelClass > & field_value , FT field_type = FT : : default_type )
2018-04-22 23:04:50 +02:00
{
2019-03-26 19:34:07 +01:00
ModelClass * list_model_null_pointer = nullptr ;
2021-03-10 16:20:11 +01:00
field_list ( db_field_name , flat_field_name , field_value , list_model_null_pointer , field_type ) ;
2018-04-22 23:04:50 +02:00
}
2019-08-20 17:49:37 +02:00
template < typename ModelClass >
2021-03-10 16:20:11 +01:00
void field ( const wchar_t * db_field_name , const wchar_t * flat_field_name , std : : vector < ModelClass > & field_value , FT field_type = FT : : default_type )
2019-08-20 17:49:37 +02:00
{
ModelClass * list_model_null_pointer = nullptr ;
2021-03-10 16:20:11 +01:00
field_list ( db_field_name , flat_field_name , field_value , list_model_null_pointer , field_type ) ;
2019-08-20 17:49:37 +02:00
}
2018-07-03 18:55:06 +02:00
protected :
2018-07-04 13:34:49 +02:00
2018-04-22 23:04:50 +02:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic_set_field_value ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value )
2018-04-22 23:04:50 +02:00
{
2019-09-18 16:36:13 +02:00
if ( model_env - > field_value_helper_tab )
2018-04-22 23:04:50 +02:00
{
2019-09-18 16:36:13 +02:00
if ( model_env - > field_index > = 0 & & ( size_t ) model_env - > field_index < model_env - > field_value_helper_tab - > size ( ) )
2019-08-22 20:33:35 +02:00
{
2019-09-18 16:36:13 +02:00
FieldValueHelper & helper = ( * model_env - > field_value_helper_tab ) [ model_env - > field_index ] ;
PT : : Log * log = model_connector - > get_logger ( ) ;
2019-09-24 19:08:45 +02:00
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 ) ) )
2019-08-22 20:33:35 +02:00
{
2019-09-18 16:36:13 +02:00
if ( helper . value_object & & helper . value_type_info )
2019-08-22 20:33:35 +02:00
{
2019-09-18 16:36:13 +02:00
if ( typeid ( field_value ) = = * helper . value_type_info )
2019-08-22 20:33:35 +02:00
{
2019-09-18 16:36:13 +02:00
field_value = * ( FieldValue * ) helper . value_object ;
}
else
{
2021-02-24 01:15:17 +01:00
if ( log )
{
2021-03-11 12:22:37 +01:00
( * log ) < < PT : : Log : : log1 < < " Morm: incorrect type of a field in " < < get_table_name ( ) < < " , " ;
2021-02-24 01:15:17 +01:00
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 ;
}
2019-08-22 20:33:35 +02:00
}
}
2019-09-18 16:36:13 +02:00
2019-09-24 19:08:45 +02:00
helper . found = true ;
2019-09-18 16:36:13 +02:00
model_env - > field_index + = 1 ;
2019-08-22 20:33:35 +02:00
}
}
2019-09-18 16:36:13 +02:00
}
}
2019-08-22 20:33:35 +02:00
2019-09-18 16:36:13 +02:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic_iterate_primary_key_values ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value , FT field_type )
2019-09-18 16:36:13 +02:00
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_primary_key ( ) )
2019-09-18 16:36:13 +02:00
{
if ( model_env - > field_value_helper_tab )
2019-08-22 20:33:35 +02:00
{
2019-09-18 16:36:13 +02:00
if ( model_env - > field_index > = 0 & & ( size_t ) model_env - > field_index < model_env - > field_value_helper_tab - > size ( ) )
2019-08-22 20:33:35 +02:00
{
2019-09-18 16:36:13 +02:00
FieldValueHelper & helper = ( * model_env - > field_value_helper_tab ) [ model_env - > field_index ] ;
helper . value_object = & field_value ;
helper . value_type_info = & typeid ( field_value ) ;
2019-08-22 20:33:35 +02:00
}
2019-09-18 16:36:13 +02:00
}
2019-08-22 20:33:35 +02:00
2019-09-18 16:36:13 +02:00
model_env - > field_index + = 1 ;
}
}
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic_generate_flat_string ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value , FT field_type )
2019-09-18 16:36:13 +02:00
{
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 ) )
{
2021-03-10 16:20:11 +01:00
flat_expression - > field ( flat_field_name , field_value , field_type , model_env ) ;
2019-08-22 20:33:35 +02:00
}
2019-09-18 16:36:13 +02:00
}
}
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic_generate_db_sql ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value , FT field_type )
2019-09-18 16:36:13 +02:00
{
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
2019-08-22 20:33:35 +02:00
2019-09-18 16:36:13 +02:00
if ( db_connector )
{
DbExpression * db_expression = db_connector - > get_expression ( ) ;
2019-08-22 20:33:35 +02:00
2019-09-18 16:36:13 +02:00
if ( db_expression & & ! is_empty_field ( db_field_name ) )
2018-07-04 13:34:49 +02:00
{
2021-03-10 16:20:11 +01:00
db_expression - > field ( db_field_name , field_value , field_type , model_env ) ;
2019-09-18 16:36:13 +02:00
}
}
}
2018-07-04 13:34:49 +02:00
2019-09-18 16:36:13 +02:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic_read_value_from_db_resultset ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value , FT field_type )
2019-09-18 16:36:13 +02:00
{
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
2018-07-04 13:34:49 +02:00
2019-09-18 16:36:13 +02:00
if ( db_connector )
{
if ( ! is_empty_field ( db_field_name ) )
{
if ( model_env - > cursor_helper & & model_env - > cursor_helper - > has_autogenerated_select )
{
2021-03-10 16:20:11 +01:00
get_value_by_field_index ( model_env - > cursor_helper - > current_column , field_value , field_type ) ;
2019-09-18 16:36:13 +02:00
model_env - > cursor_helper - > current_column + = 1 ;
}
else
{
2021-03-10 16:20:11 +01:00
get_value_by_field_name ( db_field_name , field_value , field_type ) ;
2018-07-04 13:34:49 +02:00
}
}
2019-09-18 16:36:13 +02:00
}
}
2018-07-04 13:34:49 +02:00
2019-09-18 16:36:13 +02:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic_clear_value ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value , FT field_type )
2019-09-18 16:36:13 +02:00
{
Clearer * clearer = model_connector - > get_clearer ( ) ;
2018-07-04 13:34:49 +02:00
2019-09-18 16:36:13 +02:00
if ( clearer )
{
clearer - > clear_value ( field_value ) ;
}
}
2018-07-04 13:34:49 +02:00
2019-09-18 16:36:13 +02:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void field_generic ( const wchar_t * db_field_name , const wchar_t * flat_field_name , FieldValue & field_value , FT field_type )
2019-09-18 16:36:13 +02:00
{
if ( model_connector & & model_env )
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_primary_key ( ) )
2021-03-09 18:10:34 +01:00
{
model_env - > was_primary_key_read = true ;
}
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_SET_FIELD_VALUE )
2018-07-04 13:34:49 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic_set_field_value ( db_field_name , flat_field_name , field_value ) ;
2019-09-18 16:36:13 +02:00
}
2018-07-04 13:34:49 +02:00
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_ITERATE_PRIMARY_KEY_VALUES )
2019-09-18 16:36:13 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic_iterate_primary_key_values ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-04 13:34:49 +02:00
}
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING )
2018-07-04 13:34:49 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic_generate_flat_string ( db_field_name , flat_field_name , field_value , field_type ) ;
2019-09-18 16:36:13 +02:00
}
2018-07-04 13:34:49 +02:00
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL )
2019-09-18 16:36:13 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic_generate_db_sql ( db_field_name , flat_field_name , field_value , field_type ) ;
2018-07-04 13:34:49 +02:00
}
2018-07-16 00:36:04 +02:00
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET )
2018-07-16 00:36:04 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic_read_value_from_db_resultset ( db_field_name , flat_field_name , field_value , field_type ) ;
2019-09-18 16:36:13 +02:00
}
2018-07-16 00:36:04 +02:00
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_CLEARING_VALUE )
2019-09-18 16:36:13 +02:00
{
2021-03-10 16:20:11 +01:00
field_generic_clear_value ( db_field_name , flat_field_name , field_value , field_type ) ;
2019-09-18 16:36:13 +02:00
}
2018-04-22 23:04:50 +02:00
}
}
2018-07-04 13:34:49 +02:00
2019-09-24 13:09:11 +02:00
/*
* IMPROVE ME there can be more rows in the result set when there are more items on the left hand side of the join
* this is only in a case when has_foreign_key is false , may it can be ignored ? we can use unique index in such a case
*
*/
2021-03-10 16:20:11 +01:00
void field_model_left_join ( const wchar_t * db_field_name , Model & field_model , FT field_type , DbExpression * db_expression )
2019-03-26 19:34:07 +01:00
{
2019-05-21 19:24:12 +02:00
if ( model_env & & field_model . model_env & & model_env - > finder_helper )
2019-03-26 19:34:07 +01:00
{
2019-05-31 20:28:09 +02:00
model_env - > finder_helper - > foreign_keys . clear ( ) ;
2019-09-18 14:29:20 +02:00
PT : : TextStream & join_tables_str = model_env - > finder_helper - > join_tables_str ;
2021-03-11 12:22:37 +01:00
field_model . model_env - > add_table_name_to_finder_helper ( ) ;
2019-03-26 21:35:05 +01:00
2019-09-18 14:29:20 +02:00
join_tables_str < < " LEFT JOIN " < < field_model . model_env - > table_name < < " AS " ;
field_model . put_table_name_with_index ( join_tables_str ) ;
2019-03-26 19:34:07 +01:00
int expr_work_mode = db_expression - > get_work_mode ( ) ;
int expr_output_type = db_expression - > get_output_type ( ) ;
2019-05-21 19:24:12 +02:00
bool expr_allow_prefix = db_expression - > get_allow_to_use_prefix ( ) ;
2019-03-26 19:34:07 +01:00
db_expression - > set_work_mode ( MORM_WORK_MODE_MODEL_SAVE_FIELDS ) ;
db_expression - > set_output_type ( MORM_OUTPUT_TYPE_JOIN_TABLES ) ;
2019-03-31 22:21:12 +02:00
db_expression - > allow_to_use_prefix ( false ) ;
2019-03-26 21:35:05 +01:00
2021-03-10 16:20:11 +01:00
if ( field_type . is_foreign_key ( ) )
2019-03-26 19:34:07 +01:00
{
field_model . map_fields ( ) ;
2019-09-18 14:29:20 +02:00
join_tables_str < < " ON " ;
put_table_name_with_index ( join_tables_str ) ;
join_tables_str < < ' . ' < < db_field_name < < " = " ;
field_model . put_table_name_with_index ( join_tables_str ) ;
join_tables_str < < ' . ' ;
2019-03-26 19:34:07 +01:00
2019-09-18 14:29:20 +02:00
// IMPROVE ME at the moment support only for foreign keys consisting of only one column
2019-05-31 20:28:09 +02:00
if ( model_env - > finder_helper - > foreign_keys . size ( ) = = 1 )
2019-03-26 19:34:07 +01:00
{
2019-09-18 14:29:20 +02:00
join_tables_str < < model_env - > finder_helper - > foreign_keys . front ( ) ;
2019-03-26 19:34:07 +01:00
}
}
else
{
2019-09-13 20:17:02 +02:00
ModelEnv * old_model_env = field_model . model_env ;
map_fields ( ) ; // map_fields() will set field_model.model_env to null
field_model . model_env = old_model_env ;
2019-03-26 19:34:07 +01:00
2019-09-18 14:29:20 +02:00
join_tables_str < < " ON " ;
put_table_name_with_index ( join_tables_str ) ;
join_tables_str < < ' . ' ;
2019-03-26 19:34:07 +01:00
2019-09-18 14:29:20 +02:00
// IMPROVE ME at the moment support only for foreign keys consisting of only one column
2019-05-31 20:28:09 +02:00
if ( model_env - > finder_helper - > foreign_keys . size ( ) = = 1 )
2019-03-26 19:34:07 +01:00
{
2019-09-18 14:29:20 +02:00
join_tables_str < < model_env - > finder_helper - > foreign_keys . front ( ) ;
2019-03-26 19:34:07 +01:00
}
2019-09-18 14:29:20 +02:00
join_tables_str < < " = " ;
field_model . put_table_name_with_index ( join_tables_str ) ;
join_tables_str < < ' . ' < < db_field_name ;
2019-03-26 19:34:07 +01:00
}
2019-09-18 14:29:20 +02:00
join_tables_str < < ' ' ;
2019-03-31 22:21:12 +02:00
2019-03-26 19:34:07 +01:00
db_expression - > set_work_mode ( expr_work_mode ) ;
db_expression - > set_output_type ( expr_output_type ) ;
2019-05-21 19:24:12 +02:00
db_expression - > allow_to_use_prefix ( expr_allow_prefix ) ;
2019-03-26 19:34:07 +01:00
}
}
2019-09-24 19:08:45 +02:00
/*
* first we iterate through fields and save primary key values to helper_tab
*/
void field_model_save_key ( const wchar_t * db_field_name )
2019-09-18 16:36:13 +02:00
{
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
2019-09-24 19:08:45 +02:00
PT : : Log * plog = model_connector - > get_logger ( ) ;
2019-09-18 16:36:13 +02:00
if ( db_connector )
{
DbExpression * db_expression = db_connector - > get_expression ( ) ;
2019-09-24 19:08:45 +02:00
if ( db_expression & & ! is_empty_field ( db_field_name ) & & model_env - > field_value_helper_tab )
2019-09-18 16:36:13 +02:00
{
2019-09-18 17:28:06 +02:00
int old_work_mode = model_env - > model_work_mode ;
model_env - > model_work_mode = MORM_MODEL_WORK_MODE_ITERATE_PRIMARY_KEY_VALUES ;
2019-09-24 19:08:45 +02:00
model_env - > field_index = 0 ;
map_fields ( ) ;
model_env - > model_work_mode = old_work_mode ;
2019-09-18 16:36:13 +02:00
2019-09-24 19:08:45 +02:00
if ( model_env - > field_value_helper_tab - > empty ( ) & & plog )
{
2021-03-11 12:22:37 +01:00
( * plog ) < < PT : : Log : : log1 < < " Morm: I cannot find a primary key in " < < get_table_name ( ) < < PT : : Log : : logend ;
2019-09-24 19:08:45 +02:00
}
}
}
}
2019-09-18 16:36:13 +02:00
2019-09-24 19:08:45 +02:00
/*
* now we iterate through fields in field_model and save primary key values from * this object to the specified fields in field_model
*/
void field_model_set_parent_key_in_child ( const wchar_t * db_field_name , Model & field_model )
{
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
PT : : Log * log = model_connector - > get_logger ( ) ;
2019-09-18 16:36:13 +02:00
2019-09-24 19:08:45 +02:00
if ( db_connector )
{
DbExpression * db_expression = db_connector - > get_expression ( ) ;
if ( db_expression & & ! is_empty_field ( db_field_name ) & & model_env - > field_value_helper_tab )
{
std : : vector < FieldValueHelper > & helper_tab = * model_env - > field_value_helper_tab ;
2019-09-18 16:36:13 +02:00
if ( ( size_t ) model_env - > field_index = = helper_tab . size ( ) )
{
ModelEnv model_env_local ;
model_env_local . copy_global_objects ( * model_env ) ;
2021-03-09 18:10:34 +01:00
model_env_local . has_primary_key_set = field_model . has_primary_key_set ;
2019-09-18 17:28:06 +02:00
model_env_local . model_work_mode = MORM_MODEL_WORK_MODE_SET_FIELD_VALUE ;
2019-09-18 16:36:13 +02:00
model_env_local . field_value_helper_tab = & helper_tab ;
model_env_local . field_index = 0 ;
field_model . model_env = & model_env_local ;
2021-03-11 12:22:37 +01:00
field_model . prepare_table ( ) ;
2019-09-18 16:36:13 +02:00
field_model . map_fields ( ) ;
if ( ( size_t ) field_model . model_env - > field_index ! = helper_tab . size ( ) & & log )
{
2021-03-10 16:20:11 +01:00
if ( field_model . model_env - > field_index = = 0 )
{
2021-03-11 12:22:37 +01:00
( * log ) < < PT : : Log : : log1 < < " Morm: there is no a foreign key in " < < field_model . get_table_name ( )
< < " called " < < db_field_name < < " pointing to " < < get_table_name ( ) < < PT : : Log : : logend ;
2021-03-10 16:20:11 +01:00
}
else
{
2021-03-11 12:22:37 +01:00
( * log ) < < PT : : Log : : log1 < < " Morm: primary key in " < < get_table_name ( ) < < " consists of " < < model_env - > field_index < < " column(s) "
< < " but foreign key in " < < field_model . get_table_name ( ) < < " consists of "
2021-03-10 16:20:11 +01:00
< < field_model . model_env - > field_index < < " column(s) " < < PT : : Log : : logend ;
}
2019-09-18 16:36:13 +02:00
}
field_model . model_env = nullptr ;
}
else
if ( log )
{
2021-03-11 12:22:37 +01:00
( * log ) < < PT : : Log : : log1 < < " Morm: primary key in " < < get_table_name ( ) < < " consists of incorrect number of columns "
2019-09-18 16:36:13 +02:00
< < " , expected " < < helper_tab . size ( ) < < " column(s) but got " < < model_env - > field_index < < PT : : Log : : logend ;
}
}
}
}
2019-09-24 19:08:45 +02:00
void field_model_set_parent_key ( const wchar_t * db_field_name , Model & field_model )
{
FieldValueHelper helper ;
helper . db_field_name = db_field_name ;
helper . flat_field_name = nullptr ;
helper . compare_flat_field_name = false ;
std : : vector < FieldValueHelper > 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 ) ;
field_model_set_parent_key_in_child ( db_field_name , field_model ) ;
model_env - > field_value_helper_tab = nullptr ;
}
2019-09-18 16:36:13 +02:00
void field_model_iterate_through_childs ( const wchar_t * db_field_name , Model & field_model )
{
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_INSERT )
2019-09-18 16:36:13 +02:00
{
2021-03-10 16:20:11 +01:00
field_model . insert_tree ( true ) ;
}
2019-09-18 16:36:13 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_UPDATE )
{
field_model . update_tree ( true ) ;
}
2019-09-18 16:36:13 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_REMOVE )
{
field_model . remove_tree ( true ) ;
}
2019-09-18 16:36:13 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_SAVE )
{
field_model . save_tree ( true ) ;
2019-09-18 16:36:13 +02:00
}
}
2019-05-13 19:59:28 +02:00
2021-03-10 16:20:11 +01:00
void field_model_generate_flat_string ( const wchar_t * flat_field_name , Model & field_model , FT field_type )
2018-04-22 23:04:50 +02:00
{
2019-05-13 19:59:28 +02:00
FlatConnector * flat_connector = model_connector - > get_flat_connector ( ) ;
if ( flat_connector )
2018-04-22 23:04:50 +02:00
{
2019-05-13 19:59:28 +02:00
FlatExpression * flat_expression = flat_connector - > get_expression ( ) ;
2018-07-05 13:15:16 +02:00
2021-03-10 16:20:11 +01:00
if ( flat_expression )
2018-07-04 13:34:49 +02:00
{
2019-09-13 20:17:02 +02:00
if ( model_env - > dump_mode | | field_model . save_mode = = DO_INSERT_ON_SAVE | | field_model . save_mode = = DO_UPDATE_ON_SAVE )
{
2019-09-18 17:28:06 +02:00
field_model . model_env - > model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING ;
2021-03-10 16:20:11 +01:00
flat_expression - > field_model ( flat_field_name , field_model , field_type , model_env ) ;
2019-09-13 20:17:02 +02:00
}
2019-05-13 19:59:28 +02:00
}
}
}
2018-03-13 23:22:17 +01:00
2019-05-13 19:59:28 +02:00
2021-03-10 16:20:11 +01:00
void field_model_generate_db_sql ( const wchar_t * db_field_name , Model & field_model , FT field_type )
2019-05-13 19:59:28 +02:00
{
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 ) )
{
2019-09-18 17:28:06 +02:00
field_model . model_env - > model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL ;
2019-05-13 19:59:28 +02:00
if ( db_expression - > get_output_type ( ) = = MORM_OUTPUT_TYPE_SELECT_COLUMNS )
2018-07-04 13:34:49 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_left_join ( db_field_name , field_model , field_type , db_expression ) ;
2019-05-13 19:59:28 +02:00
}
2018-07-03 18:55:06 +02:00
2021-03-10 16:20:11 +01:00
if ( field_type . is_foreign_key ( ) )
2019-08-21 19:42:50 +02:00
{
2019-09-04 18:02:18 +02:00
if ( db_expression - > get_work_mode ( ) = = MORM_WORK_MODE_MODEL_FIELDS & & db_expression - > get_output_type ( ) = = MORM_OUTPUT_TYPE_DB_INSERT )
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_insertable ( ) )
2021-03-09 18:10:34 +01:00
{
int not_used_object = 0 ;
2021-03-10 16:20:11 +01:00
db_expression - > field ( db_field_name , not_used_object , field_type , model_env ) ;
2021-03-09 18:10:34 +01:00
}
2019-09-04 18:02:18 +02:00
}
2019-08-21 19:42:50 +02:00
2019-09-04 18:02:18 +02:00
if ( db_expression - > get_work_mode ( ) = = MORM_WORK_MODE_MODEL_VALUES & & db_expression - > get_output_type ( ) = = MORM_OUTPUT_TYPE_DB_INSERT )
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_insertable ( ) )
2021-03-09 18:10:34 +01:00
{
db_expression - > set_output_type ( MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY ) ;
field_model . map_fields ( ) ;
db_expression - > set_output_type ( MORM_OUTPUT_TYPE_DB_INSERT ) ;
}
2019-09-04 18:02:18 +02:00
}
if ( db_expression - > get_work_mode ( ) = = MORM_WORK_MODE_MODEL_FIELDS_VALUES & & db_expression - > get_output_type ( ) = = MORM_OUTPUT_TYPE_DB_UPDATE )
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_updatable ( ) )
2021-03-09 18:10:34 +01:00
{
std : : vector < const wchar_t * > key_fields ;
key_fields . push_back ( db_field_name ) ; // at the moment only one key
2019-09-04 18:02:18 +02:00
2021-03-09 18:10:34 +01:00
db_expression - > set_output_type ( MORM_OUTPUT_TYPE_DB_UPDATE_PRIMARY_KEY ) ;
field_model . model_env - > field_index = 0 ;
field_model . model_env - > set_field_name_helper = & key_fields ;
field_model . map_fields ( ) ;
db_expression - > set_output_type ( MORM_OUTPUT_TYPE_DB_UPDATE ) ;
2019-09-04 18:02:18 +02:00
2021-03-09 18:10:34 +01:00
if ( ( size_t ) field_model . model_env - > field_index ! = key_fields . size ( ) )
{
// IMPROVEME
// number of keys are different
// put error log here
}
2019-09-04 18:02:18 +02:00
}
}
2019-08-21 19:42:50 +02:00
}
2019-08-21 14:15:55 +02:00
if ( db_expression - > get_output_type ( ) ! = MORM_OUTPUT_TYPE_JOIN_TABLES & &
2019-09-04 18:02:18 +02:00
db_expression - > get_output_type ( ) ! = MORM_OUTPUT_TYPE_DB_PRIMARY_KEY & &
2019-08-21 14:15:55 +02:00
db_expression - > get_output_type ( ) ! = MORM_OUTPUT_TYPE_DB_INSERT & &
db_expression - > get_output_type ( ) ! = MORM_OUTPUT_TYPE_DB_UPDATE )
2019-05-13 19:59:28 +02:00
{
field_model . map_fields ( ) ;
2019-03-26 19:34:07 +01:00
}
2019-09-18 17:28:06 +02:00
field_model . model_env - > model_work_mode = MORM_MODEL_WORK_MODE_NONE ;
2019-05-13 19:59:28 +02:00
}
}
}
2019-03-26 19:34:07 +01:00
2021-03-10 16:20:11 +01:00
void field_model_clear_values ( Model & field_model )
2019-05-13 19:59:28 +02:00
{
Clearer * clearer = model_connector - > get_clearer ( ) ;
2019-03-26 19:34:07 +01:00
2019-05-13 19:59:28 +02:00
if ( clearer )
{
clearer - > clear_model ( field_model ) ;
}
}
2019-03-31 22:21:12 +02:00
2019-03-26 21:35:05 +01:00
2021-03-10 16:20:11 +01:00
void field_model_read_values_from_queryresult ( const wchar_t * db_field_name , Model & field_model , FT field_type )
2019-05-13 19:59:28 +02:00
{
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
2019-03-26 19:34:07 +01:00
2019-05-13 19:59:28 +02:00
if ( db_connector )
{
2021-03-10 16:20:11 +01:00
DbExpression * db_expression = db_connector - > get_expression ( ) ;
2019-03-31 22:21:12 +02:00
2021-03-10 16:20:11 +01:00
if ( db_expression )
{
if ( model_env - > cursor_helper & &
! model_env - > cursor_helper - > has_autogenerated_select & &
model_env - > cursor_helper - > use_table_prefix_for_fetching_values )
2019-09-17 19:55:39 +02:00
{
2021-03-11 12:22:37 +01:00
field_model . model_env - > add_table_name_to_finder_helper ( ) ;
2021-03-10 16:20:11 +01:00
}
2019-09-17 19:55:39 +02:00
2021-03-10 16:20:11 +01:00
field_model . before_select ( ) ;
field_model . map_values_from_query ( ) ;
2019-09-18 14:29:20 +02:00
2021-03-10 16:20:11 +01:00
if ( field_model . found ( ) )
{
field_model . after_select ( ) ;
2019-09-17 19:55:39 +02:00
}
2018-07-04 13:34:49 +02:00
}
2019-05-13 19:59:28 +02:00
}
}
2021-03-10 16:20:11 +01:00
void field_model ( const wchar_t * db_field_name , const wchar_t * flat_field_name , Model & field_model , FT field_type )
2019-05-13 19:59:28 +02:00
{
2019-05-21 17:51:13 +02:00
if ( model_connector & & model_env )
2019-05-13 19:59:28 +02:00
{
2019-05-21 19:24:12 +02:00
ModelEnv model_env_local ;
model_env_local . copy_global_objects ( * model_env ) ;
2019-05-13 19:59:28 +02:00
field_model . model_env = & model_env_local ;
2021-03-09 18:10:34 +01:00
field_model . model_env - > has_primary_key_set = field_model . has_primary_key_set ;
2019-05-13 19:59:28 +02:00
field_model . set_connector ( model_connector ) ;
2021-03-11 12:22:37 +01:00
field_model . prepare_table ( ) ;
2018-07-03 18:55:06 +02:00
2021-03-10 16:20:11 +01:00
if ( ! is_empty_field ( db_field_name ) )
2019-08-21 19:42:50 +02:00
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_foreign_key ( ) | | field_type . is_foreign_key_in_child ( ) )
2019-08-22 20:33:35 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_for_db ( db_field_name , field_model , field_type ) ;
2019-09-05 18:32:35 +02:00
}
2021-03-10 16:20:11 +01:00
else
2019-09-04 18:02:18 +02:00
{
2021-03-10 16:20:11 +01:00
PT : : Log * plog = model_connector - > get_logger ( ) ;
if ( plog )
{
2021-03-11 12:22:37 +01:00
( * plog ) < < PT : : Log : : log1 < < " Morm: error in " < < get_table_name_with_field ( db_field_name )
2021-03-10 16:20:11 +01:00
< < " field, you should set FT::is_foreign_key or FT::is_foreign_key_in_child flag for a model child object " < < PT : : Log : : logend ;
}
2019-09-04 18:02:18 +02:00
}
2019-09-18 16:36:13 +02:00
}
2019-09-04 18:02:18 +02:00
2021-03-10 16:20:11 +01:00
if ( ! is_empty_field ( flat_field_name ) )
2019-09-18 16:36:13 +02:00
{
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING )
2019-09-04 18:02:18 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_generate_flat_string ( flat_field_name , field_model , field_type ) ;
2019-09-04 18:02:18 +02:00
}
2019-08-21 19:42:50 +02:00
}
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_CLEARING_VALUE )
2018-07-04 13:34:49 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_clear_values ( field_model ) ;
2019-05-13 19:59:28 +02:00
}
2018-07-05 13:15:16 +02:00
2021-03-10 16:20:11 +01:00
field_model . model_env = nullptr ;
}
}
void field_model_for_db ( const wchar_t * db_field_name , Model & field_model , FT field_type )
{
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_SET_PARENT_ID )
{
if ( field_type . is_foreign_key_in_child ( ) )
2019-05-13 19:59:28 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_set_parent_key ( db_field_name , field_model ) ;
2018-07-04 13:34:49 +02:00
}
2021-03-10 16:20:11 +01:00
}
2018-07-16 00:36:04 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITH_FOREIGN_KEY )
{
if ( field_type . is_foreign_key ( ) )
2018-07-16 00:36:04 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_iterate_through_childs ( db_field_name , field_model ) ;
2019-05-13 19:59:28 +02:00
}
2021-03-10 16:20:11 +01:00
}
2018-07-16 00:36:04 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY )
{
if ( field_type . is_foreign_key_in_child ( ) )
2019-05-13 19:59:28 +02:00
{
2021-03-10 16:20:11 +01:00
field_model_iterate_through_childs ( db_field_name , field_model ) ;
2018-07-16 00:36:04 +02:00
}
2021-03-10 16:20:11 +01:00
}
2019-03-07 19:02:29 +01:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL )
{
field_model_generate_db_sql ( db_field_name , field_model , field_type ) ;
}
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET )
{
field_model_read_values_from_queryresult ( db_field_name , field_model , field_type ) ;
2018-04-17 00:46:25 +02:00
}
}
2018-03-13 23:22:17 +01:00
2018-07-04 15:52:40 +02:00
2019-09-24 19:08:45 +02:00
template < typename ModelContainer , typename ModelContainerType >
void field_list_set_parent_key ( const wchar_t * db_field_name , ModelContainer & field_container , ModelContainerType * model_container_type )
{
FieldValueHelper helper ;
helper . db_field_name = db_field_name ;
helper . flat_field_name = nullptr ;
helper . compare_flat_field_name = false ;
std : : vector < FieldValueHelper > 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 ) ;
for ( ModelContainerType & child_model : field_container )
{
child_model . set_connector ( model_connector ) ;
field_model_set_parent_key_in_child ( db_field_name , child_model ) ;
}
model_env - > field_value_helper_tab = nullptr ;
}
2019-03-26 19:34:07 +01:00
template < typename ModelContainer , typename ModelContainerType >
2019-09-24 13:09:11 +02:00
void field_list_iterate_through_childs ( const wchar_t * db_field_name , ModelContainer & field_container , ModelContainerType * model_container_type )
2018-04-26 20:58:31 +02:00
{
2021-03-10 16:20:11 +01:00
for ( ModelContainerType & child_model : field_container )
2018-04-26 20:58:31 +02:00
{
2021-03-10 16:20:11 +01:00
ModelEnv model_env_local ;
model_env_local . copy_global_objects ( * model_env ) ;
2018-07-04 13:34:49 +02:00
2021-03-10 16:20:11 +01:00
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 ) ;
2021-03-11 12:22:37 +01:00
child_model . prepare_table ( ) ;
2018-07-04 13:34:49 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_INSERT )
{
child_model . insert_tree ( true ) ;
}
2019-09-24 13:09:11 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_UPDATE )
{
child_model . update_tree ( true ) ;
}
2019-09-24 13:09:11 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_REMOVE )
{
child_model . remove_tree ( true ) ;
}
2019-09-24 13:09:11 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_submode = = MORM_MODEL_WORK_SUBMODE_SAVE )
{
child_model . save_tree ( true ) ;
2018-07-04 13:34:49 +02:00
}
2021-03-10 16:20:11 +01:00
child_model . model_env = nullptr ;
}
2019-09-24 13:09:11 +02:00
}
template < typename ModelContainer >
2021-03-10 16:20:11 +01:00
void field_list_generate_flat_string ( const wchar_t * flat_field_name , ModelContainer & field_container , FT field_type )
2019-09-24 13:09:11 +02:00
{
FlatConnector * flat_connector = model_connector - > get_flat_connector ( ) ;
if ( flat_connector )
{
FlatExpression * flat_expression = flat_connector - > get_expression ( ) ;
2021-03-10 16:20:11 +01:00
if ( flat_expression )
2019-03-26 19:34:07 +01:00
{
2021-03-10 16:20:11 +01:00
flat_expression - > field_list ( flat_field_name , field_container , field_type , model_connector , model_env ) ;
2019-09-24 13:09:11 +02:00
}
}
}
2019-03-26 19:34:07 +01:00
2019-09-24 13:09:11 +02:00
template < typename ModelContainer >
void field_list_clearing_values ( ModelContainer & field_container )
{
Clearer * clearer = model_connector - > get_clearer ( ) ;
2019-08-20 17:49:37 +02:00
2019-09-24 13:09:11 +02:00
if ( clearer )
{
clearer - > clear_container ( field_container ) ;
}
}
template < typename ModelContainer , typename ModelContainerType >
2021-03-10 16:20:11 +01:00
void field_list ( const wchar_t * db_field_name , const wchar_t * flat_field_name , ModelContainer & field_container , ModelContainerType * model_container_type , FT field_type )
2019-09-24 13:09:11 +02:00
{
if ( model_connector & & model_env )
{
2021-03-10 16:20:11 +01:00
PT : : Log * plog = model_connector - > get_logger ( ) ;
2019-09-25 18:20:37 +02:00
if ( ! is_empty_field ( db_field_name ) )
2019-09-24 19:08:45 +02:00
{
2021-03-10 16:20:11 +01:00
/*
* 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 ( ) )
2019-09-25 18:20:37 +02:00
{
2021-03-10 16:20:11 +01:00
if ( plog )
2019-09-25 18:20:37 +02:00
{
2021-03-11 12:22:37 +01:00
( * plog ) < < PT : : Log : : log1 < < " Morm: error: FT::is_foreign_key is not implemented for a list/vector yet " < < PT : : Log : : logend ;
2021-03-10 16:20:11 +01:00
return ;
2019-09-25 18:20:37 +02:00
}
2021-03-10 16:20:11 +01:00
}
if ( field_type . is_foreign_key ( ) | | field_type . is_foreign_key_in_child ( ) )
{
if constexpr ( std : : is_base_of < Model , ModelContainerType > ( ) )
{
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_SET_PARENT_ID )
{
field_list_set_parent_key ( db_field_name , field_container , model_container_type ) ;
}
2019-09-24 19:08:45 +02:00
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY )
{
field_list_iterate_through_childs ( db_field_name , field_container , model_container_type ) ;
}
}
else
2019-09-25 18:20:37 +02:00
{
2021-03-10 16:20:11 +01:00
if ( plog )
{
2021-03-11 12:22:37 +01:00
( * plog ) < < PT : : Log : : log1 < < " Morm: ignoring " < < get_table_name_with_field ( db_field_name ) < < " as this is not a container with Model objects " < < PT : : Log : : logend ;
2021-03-10 16:20:11 +01:00
}
2019-09-25 18:20:37 +02:00
}
}
else
{
if ( plog )
{
2021-03-11 12:22:37 +01:00
( * plog ) < < PT : : Log : : log1 < < " Morm: error in " < < get_table_name_with_field ( db_field_name )
2021-03-10 16:20:11 +01:00
< < " 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 ;
2019-09-25 18:20:37 +02:00
}
}
2019-03-26 19:34:07 +01:00
}
2021-03-10 16:20:11 +01:00
if ( ! is_empty_field ( flat_field_name ) )
2019-09-24 13:09:11 +02:00
{
2021-03-10 16:20:11 +01:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING )
{
field_list_generate_flat_string ( flat_field_name , field_container , field_type ) ;
}
2019-09-24 13:09:11 +02:00
}
2019-03-26 19:34:07 +01:00
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_CLEARING_VALUE )
2018-07-04 13:34:49 +02:00
{
2019-09-24 13:09:11 +02:00
field_list_clearing_values ( field_container ) ;
2018-07-04 13:34:49 +02:00
}
2018-07-16 00:36:04 +02:00
}
}
2018-11-14 18:14:26 +01:00
2019-05-13 05:12:31 +02:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void get_value_by_field_index ( int field_index , FieldValue & field_value , FT field_type )
2019-05-13 05:12:31 +02:00
{
2019-09-18 14:29:20 +02:00
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
2019-05-13 05:12:31 +02:00
2019-09-18 14:29:20 +02:00
if ( db_connector & & model_env - > cursor_helper & & model_env - > cursor_helper - > query_result )
{
if ( ! model_env - > cursor_helper - > query_result - > is_null ( field_index ) )
2019-05-13 05:12:31 +02:00
{
2019-09-18 14:29:20 +02:00
const char * val_str = model_env - > cursor_helper - > query_result - > get_field_string_value ( field_index ) ;
2019-05-13 05:12:31 +02:00
2019-09-18 14:29:20 +02:00
if ( val_str )
2019-05-13 05:12:31 +02:00
{
db_connector - > get_value ( val_str , field_value ) ;
}
}
2021-03-09 18:10:34 +01:00
else
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_primary_key ( ) )
2021-03-09 18:10:34 +01:00
{
model_env - > has_primary_key_set = false ;
}
}
2019-05-13 05:12:31 +02:00
}
}
2018-11-14 18:14:26 +01:00
template < typename FieldValue >
2021-03-10 16:20:11 +01:00
void get_value_by_field_name ( const wchar_t * field_name , FieldValue & field_value , FT field_type )
2018-11-14 18:14:26 +01:00
{
2019-09-17 19:55:39 +02:00
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
if ( db_connector & & model_env - > cursor_helper & & model_env - > cursor_helper - > query_result )
2018-11-14 18:14:26 +01:00
{
2019-09-18 14:29:20 +02:00
int column_index = - 1 ;
2019-09-13 20:17:02 +02:00
2019-09-17 19:55:39 +02:00
if ( model_env - > cursor_helper - > use_table_prefix_for_fetching_values & & model_env - > finder_helper )
{
// CHECK what about escaping field names here?
2019-09-13 20:17:02 +02:00
2019-09-17 19:55:39 +02:00
std : : wstring table_field_name ;
PT : : TextStream table_field_name_str ;
2019-09-13 20:17:02 +02:00
2019-09-18 14:29:20 +02:00
put_table_name_with_index ( table_field_name_str ) ;
2019-09-17 19:55:39 +02:00
table_field_name_str < < ' . ' ;
table_field_name_str < < field_name ;
table_field_name_str . to_string ( table_field_name ) ;
2019-09-18 14:29:20 +02:00
column_index = model_env - > cursor_helper - > query_result - > get_column_index ( table_field_name . c_str ( ) ) ;
2019-09-17 19:55:39 +02:00
}
else
{
2019-09-18 14:29:20 +02:00
column_index = model_env - > cursor_helper - > query_result - > get_column_index ( field_name ) ;
2019-09-17 19:55:39 +02:00
}
2019-09-18 14:29:20 +02:00
if ( column_index ! = - 1 & & ! model_env - > cursor_helper - > query_result - > is_null ( column_index ) )
2019-09-17 19:55:39 +02:00
{
2019-09-18 14:29:20 +02:00
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 ) ;
}
2018-11-14 18:14:26 +01:00
}
2021-03-09 18:10:34 +01:00
else
{
2021-03-10 16:20:11 +01:00
if ( field_type . is_primary_key ( ) )
2021-03-09 18:10:34 +01:00
{
model_env - > has_primary_key_set = false ;
}
}
2018-11-14 18:14:26 +01:00
}
}
2019-08-22 20:33:35 +02:00
virtual void set_parent_key_in_childs ( )
{
if ( model_env )
{
2019-09-18 17:28:06 +02:00
model_env - > model_work_mode = MORM_MODEL_WORK_MODE_SET_PARENT_ID ;
2019-08-22 20:33:35 +02:00
map_fields ( ) ;
}
}
2018-07-04 13:34:49 +02:00
public :
2018-04-26 20:58:31 +02:00
2018-04-17 00:46:25 +02:00
template < typename FieldValue >
2021-03-09 18:10:34 +01:00
bool get_last_sequence ( const wchar_t * sequence_table_name , FieldValue & field_value )
2018-04-17 00:46:25 +02:00
{
if ( model_connector )
{
2018-07-04 13:34:49 +02:00
DbConnector * db_connector = model_connector - > get_db_connector ( ) ;
if ( db_connector & & ! is_empty_field ( sequence_table_name ) )
{
2021-03-09 18:10:34 +01:00
return db_connector - > get_last_sequence ( sequence_table_name , field_value ) ;
2018-07-04 13:34:49 +02:00
}
2018-04-17 00:46:25 +02:00
}
2021-03-09 18:10:34 +01:00
return false ;
}
template < typename FieldValue >
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 ;
2018-04-17 00:46:25 +02:00
}
2018-04-22 23:04:50 +02:00
template < typename FieldValue >
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 )
{
2019-09-18 17:28:06 +02:00
if ( model_connector & & model_env )
2018-04-22 23:04:50 +02:00
{
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_DB_SQL )
2018-04-22 23:04:50 +02:00
{
2018-07-04 13:34:49 +02:00
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 ) ;
}
}
2018-04-22 23:04:50 +02:00
}
else
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING )
2018-04-22 23:04:50 +02:00
{
2018-07-04 13:34:49 +02:00
field_generic ( L " " , flat_field_name , field_value , false , false , false ) ;
2018-04-22 23:04:50 +02:00
}
else
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_READING_VALUE_FROM_DB_RESULTSET )
2018-04-22 23:04:50 +02:00
{
2018-07-04 13:34:49 +02:00
field_generic ( new_column_name , L " " , field_value , false , false , false ) ;
2018-04-22 23:04:50 +02:00
}
else
2019-09-18 17:28:06 +02:00
if ( model_env - > model_work_mode = = MORM_MODEL_WORK_MODE_CLEARING_VALUE )
2018-04-22 23:04:50 +02:00
{
2018-07-04 13:34:49 +02:00
field_generic ( L " " , L " " , field_value , false , false , false ) ; // the names don't matter here
2018-04-22 23:04:50 +02:00
}
}
}
2019-09-25 18:20:37 +02:00
// RENAME ME to something like select_field() or field_select()
2018-04-22 23:04:50 +02:00
template < typename FieldValue >
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 ) ;
}
2018-03-13 23:22:17 +01:00
2018-04-22 23:04:50 +02:00
2018-07-04 13:34:49 +02:00
protected :
virtual bool is_empty_field ( const wchar_t * value ) ;
2019-08-22 20:33:35 +02:00
virtual bool is_the_same_field ( const wchar_t * field1 , const wchar_t * field2 ) ;
2021-03-11 12:22:37 +01:00
2019-09-18 14:29:20 +02:00
virtual void put_table_name_with_index ( PT : : TextStream & str ) ;
2018-07-04 13:34:49 +02:00
2021-03-09 18:10:34 +01:00
virtual void put_to_log ( const wchar_t * str ) ;
2019-09-24 19:08:45 +02:00
virtual void put_fields_to_log ( PT : : Log & log , const wchar_t * db_field_name , const wchar_t * flat_field_name ) ;
2021-03-11 12:22:37 +01:00
virtual PT : : WTextStream get_table_name ( bool put_schema_name = true ) ;
virtual PT : : WTextStream get_table_name_with_field ( const wchar_t * db_field_name = nullptr , bool put_schema_name = true ) ;
2021-03-10 16:20:11 +01:00
2019-05-13 19:59:28 +02:00
template < typename ModelClass > friend class Finder ;
2018-11-14 18:14:26 +01:00
template < typename ModelClass > friend class Cursor ;
2018-07-03 18:55:06 +02:00
friend class BaseExpression ;
2021-03-11 12:22:37 +01:00
friend class DbConnector ;
2018-07-03 18:55:06 +02:00
2018-03-13 23:22:17 +01:00
} ;
} // namespace
# endif