serialize a model to flat string even when a DO_NOTHING_ON_SAVE flag is set
while here: - add FT::serialize_to_null_if_null and FT::do_not_serialize_if_null flags
This commit is contained in:
parent
d1c86c84cf
commit
0fbd988eda
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -112,22 +112,36 @@ bool BaseExpression::get_allow_to_use_prefix()
|
||||||
|
|
||||||
|
|
||||||
void BaseExpression::generate_from_model(pt::TextStream & stream, Model & model)
|
void BaseExpression::generate_from_model(pt::TextStream & stream, Model & model)
|
||||||
|
{
|
||||||
|
FT field_type = FT::default_type;
|
||||||
|
generate_from_model(stream, model, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseExpression::generate_from_model(pt::TextStream & stream, Model & model, const FT & field_type)
|
||||||
{
|
{
|
||||||
this->out_stream = &stream;
|
this->out_stream = &stream;
|
||||||
generate_from_model(model);
|
generate_from_model(model, field_type);
|
||||||
this->out_stream = nullptr;
|
this->out_stream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BaseExpression::generate_from_model(Model & model)
|
void BaseExpression::generate_from_model(Model & model, const FT & field_type)
|
||||||
{
|
{
|
||||||
if( out_stream )
|
if( out_stream )
|
||||||
{
|
{
|
||||||
before_generate_from_model();
|
if( should_field_model_be_generated_as_null(model.get_has_primary_key_set(), field_type) )
|
||||||
dump_additional_info(model);
|
{
|
||||||
model.fields();
|
put_null_value();
|
||||||
add_additional_columns(model);
|
}
|
||||||
after_generate_from_model();
|
else
|
||||||
|
{
|
||||||
|
before_generate_from_model();
|
||||||
|
dump_additional_info(model);
|
||||||
|
model.fields();
|
||||||
|
add_additional_columns(model);
|
||||||
|
after_generate_from_model();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +178,17 @@ bool BaseExpression::can_field_be_generated(const FT &)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseExpression::can_field_model_be_generated(bool has_model_primary_key, const FT & field_type)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BaseExpression::should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseExpression::field_before()
|
void BaseExpression::field_before()
|
||||||
{
|
{
|
||||||
if( !is_first_field )
|
if( !is_first_field )
|
||||||
|
|
|
@ -75,6 +75,7 @@ public:
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
virtual void generate_from_model(pt::TextStream & stream, Model & model);
|
virtual void generate_from_model(pt::TextStream & stream, Model & model);
|
||||||
|
virtual void generate_from_model(pt::TextStream & stream, Model & model, const FT & field_type);
|
||||||
|
|
||||||
virtual pt::TextStream * get_current_stream();
|
virtual pt::TextStream * get_current_stream();
|
||||||
|
|
||||||
|
@ -232,7 +233,7 @@ public:
|
||||||
{
|
{
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
put_name_value_separator();
|
put_name_value_separator();
|
||||||
put_field_value_list(field_value, model_container_type, model_connector, model_env, foo);
|
put_field_value_list(field_value, model_container_type, field_type, model_connector, model_env, foo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
||||||
|
@ -240,7 +241,7 @@ public:
|
||||||
(*out_stream) << '\n';
|
(*out_stream) << '\n';
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
put_name_value_separator();
|
put_name_value_separator();
|
||||||
put_field_value_list(field_value, model_container_type, model_connector, model_env, foo);
|
put_field_value_list(field_value, model_container_type, field_type, model_connector, model_env, foo);
|
||||||
put_name_value_separator();
|
put_name_value_separator();
|
||||||
/*
|
/*
|
||||||
* IMPROVEME currently only used in XML serializer so we put / directly here
|
* IMPROVEME currently only used in XML serializer so we put / directly here
|
||||||
|
@ -267,7 +268,7 @@ public:
|
||||||
template<typename ModelClass>
|
template<typename ModelClass>
|
||||||
void field_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
void field_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( out_stream && can_field_be_generated(field_type) )
|
if( out_stream && can_field_be_generated(field_type) && can_field_model_be_generated(field_model.get_has_primary_key_set(), field_type) )
|
||||||
{
|
{
|
||||||
field_before();
|
field_before();
|
||||||
|
|
||||||
|
@ -278,14 +279,14 @@ public:
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
||||||
{
|
{
|
||||||
generate_from_model(field_model); // is it ok as a value?
|
generate_from_model(field_model, field_type); // is it ok as a value?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
||||||
{
|
{
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
put_name_value_separator();
|
put_name_value_separator();
|
||||||
generate_from_model(field_model);
|
generate_from_model(field_model, field_type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
|
||||||
|
@ -293,7 +294,7 @@ public:
|
||||||
(*out_stream) << '\n';
|
(*out_stream) << '\n';
|
||||||
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
||||||
put_name_value_separator();
|
put_name_value_separator();
|
||||||
generate_from_model(field_model);
|
generate_from_model(field_model, field_type);
|
||||||
put_name_value_separator();
|
put_name_value_separator();
|
||||||
/*
|
/*
|
||||||
* IMPROVEME currently only used in XML serializer so we put / directly here
|
* IMPROVEME currently only used in XML serializer so we put / directly here
|
||||||
|
@ -450,11 +451,15 @@ protected:
|
||||||
pt::TextStream scratch_buffer_local;
|
pt::TextStream scratch_buffer_local;
|
||||||
pt::TextStream * scratch_buffer;
|
pt::TextStream * scratch_buffer;
|
||||||
|
|
||||||
virtual void generate_from_model(Model & model);
|
virtual void generate_from_model(Model & model, const FT & field_type);
|
||||||
|
|
||||||
virtual void before_generate_from_model();
|
virtual void before_generate_from_model();
|
||||||
virtual void after_generate_from_model();
|
virtual void after_generate_from_model();
|
||||||
|
|
||||||
virtual bool can_field_be_generated(const FT &);
|
virtual bool can_field_be_generated(const FT &);
|
||||||
|
virtual bool can_field_model_be_generated(bool has_model_primary_key, const FT & field_type);
|
||||||
|
virtual bool should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type);
|
||||||
|
|
||||||
virtual void field_before();
|
virtual void field_before();
|
||||||
virtual void field_after();
|
virtual void field_after();
|
||||||
|
|
||||||
|
@ -527,18 +532,18 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
||||||
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
|
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
|
||||||
ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
if constexpr (std::is_base_of<Model, ModelContainerType>())
|
||||||
{
|
{
|
||||||
if constexpr (std::is_base_of<Model, IsContainerByValueRenameMe>())
|
if constexpr (std::is_base_of<Model, IsContainerByValueRenameMe>())
|
||||||
{
|
{
|
||||||
put_field_value_list_model_by_value(field_value, model_container_type, model_connector, model_env);
|
put_field_value_list_model_by_value(field_value, model_container_type, field_type, model_connector, model_env);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
put_field_value_list_model_by_pointer(field_value, model_container_type, model_connector, model_env);
|
put_field_value_list_model_by_pointer(field_value, model_container_type, field_type, model_connector, model_env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -549,8 +554,8 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType>
|
template<typename ModelContainer, typename ModelContainerType>
|
||||||
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
|
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
|
||||||
ModelEnv * model_env)
|
ModelConnector * model_connector, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( model_connector && model_env && out_stream )
|
if( model_connector && model_env && out_stream )
|
||||||
{
|
{
|
||||||
|
@ -559,13 +564,16 @@ protected:
|
||||||
|
|
||||||
for(auto & child_model_item : field_value)
|
for(auto & child_model_item : field_value)
|
||||||
{
|
{
|
||||||
if( !is_first )
|
if( can_field_model_be_generated(child_model_item.get_has_primary_key_set(), field_type) )
|
||||||
{
|
{
|
||||||
field_value_list_separator();
|
if( !is_first )
|
||||||
}
|
{
|
||||||
|
field_value_list_separator();
|
||||||
|
}
|
||||||
|
|
||||||
put_field_value_list_model(child_model_item, model_connector, model_env);
|
put_field_value_list_model(child_model_item, model_connector, model_env);
|
||||||
is_first = false;
|
is_first = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
after_field_value_list();
|
after_field_value_list();
|
||||||
|
@ -574,8 +582,8 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
template<typename ModelContainer, typename ModelContainerType>
|
template<typename ModelContainer, typename ModelContainerType>
|
||||||
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
|
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
|
||||||
ModelEnv * model_env)
|
ModelConnector * model_connector, ModelEnv * model_env)
|
||||||
{
|
{
|
||||||
if( model_connector && model_env && out_stream )
|
if( model_connector && model_env && out_stream )
|
||||||
{
|
{
|
||||||
|
@ -584,13 +592,16 @@ protected:
|
||||||
|
|
||||||
for(auto * child_model_item : field_value)
|
for(auto * child_model_item : field_value)
|
||||||
{
|
{
|
||||||
if( !is_first )
|
if( can_field_model_be_generated(child_model_item->get_has_primary_key_set(), field_type) )
|
||||||
{
|
{
|
||||||
field_value_list_separator();
|
if( !is_first )
|
||||||
}
|
{
|
||||||
|
field_value_list_separator();
|
||||||
|
}
|
||||||
|
|
||||||
put_field_value_list_model(*child_model_item, model_connector, model_env);
|
put_field_value_list_model(*child_model_item, model_connector, model_env);
|
||||||
is_first = false;
|
is_first = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
after_field_value_list();
|
after_field_value_list();
|
||||||
|
@ -607,7 +618,8 @@ protected:
|
||||||
child_model.model_env->model = &child_model;
|
child_model.model_env->model = &child_model;
|
||||||
child_model.set_connector(model_connector);
|
child_model.set_connector(model_connector);
|
||||||
|
|
||||||
generate_from_model(child_model);
|
FT field_type = FT::default_type;
|
||||||
|
generate_from_model(child_model, field_type);
|
||||||
|
|
||||||
child_model.model_env = nullptr;
|
child_model.model_env = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -39,6 +39,18 @@
|
||||||
namespace morm
|
namespace morm
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool FlatExpression::should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type)
|
||||||
|
{
|
||||||
|
return !has_model_primary_key && field_type.is_serialize_to_null_if_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool FlatExpression::can_field_model_be_generated(bool has_model_primary_key, const FT & field_type)
|
||||||
|
{
|
||||||
|
return has_model_primary_key || !field_type.is_do_not_serialize_if_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -46,6 +46,10 @@ class FlatExpression : public BaseExpression
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool should_field_model_be_generated_as_null(bool has_model_primary_key, const FT & field_type);
|
||||||
|
bool can_field_model_be_generated(bool has_model_primary_key, const FT & field_type);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
21
src/ft.h
21
src/ft.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022, Tomasz Sowa
|
* Copyright (c) 2021-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -68,6 +68,15 @@ public:
|
||||||
date_only = 32768, /* use only year, month and day from pt::Date, no_time_zone flag is not used here */
|
date_only = 32768, /* use only year, month and day from pt::Date, no_time_zone flag is not used here */
|
||||||
time_only = 65536, /* use only hour, min, sec from pt::Date, no_time_zone flag is not used here */
|
time_only = 65536, /* use only hour, min, sec from pt::Date, no_time_zone flag is not used here */
|
||||||
no_time_zone = 131072, /* no time zone, used only with pt::Date */
|
no_time_zone = 131072, /* no time zone, used only with pt::Date */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if this flag is set and a model does not have a primary key set
|
||||||
|
* then we print only 'null'
|
||||||
|
* (this is used only with flat strings)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
serialize_to_null_if_null = 262144,
|
||||||
|
do_not_serialize_if_null = 524288, /* null objects are completely skipped when serializing to a flat string (test only for Model objects, not lists/vectors with childs models */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -212,6 +221,16 @@ public:
|
||||||
return is_flag_set(no_time_zone);
|
return is_flag_set(no_time_zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_serialize_to_null_if_null() const
|
||||||
|
{
|
||||||
|
return is_flag_set(serialize_to_null_if_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_do_not_serialize_if_null() const
|
||||||
|
{
|
||||||
|
return is_flag_set(do_not_serialize_if_null);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -95,7 +95,7 @@ void Model::set_has_primary_key_set(bool has_primary_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Model::get_has_primary_key_set()
|
bool Model::get_has_primary_key_set() const
|
||||||
{
|
{
|
||||||
return this->has_primary_key_set;
|
return this->has_primary_key_set;
|
||||||
}
|
}
|
||||||
|
@ -1448,7 +1448,7 @@ void Model::field_model_generate_flat_string(const wchar_t * flat_field_name, Mo
|
||||||
|
|
||||||
if( flat_expression )
|
if( flat_expression )
|
||||||
{
|
{
|
||||||
if( model_env->dump_mode || field_model.save_mode == DO_INSERT_ON_SAVE || field_model.save_mode == DO_UPDATE_ON_SAVE )
|
if( model_env->dump_mode || field_model.save_mode != DO_DELETE_ON_SAVE )
|
||||||
{
|
{
|
||||||
field_model.model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
|
field_model.model_env->model_work_mode = MORM_MODEL_WORK_MODE_GENERATING_FLAT_STRING;
|
||||||
flat_expression->field_model(flat_field_name, field_model, field_type, model_env);
|
flat_expression->field_model(flat_field_name, field_model, field_type, model_env);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2022, Tomasz Sowa
|
* Copyright (c) 2018-2023, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -157,7 +157,7 @@ public:
|
||||||
virtual void set_save_mode2(SaveMode save_mode, bool update_whole_tree = true);
|
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 void set_has_primary_key_set(bool has_primary_key);
|
||||||
virtual bool get_has_primary_key_set();
|
virtual bool get_has_primary_key_set() const;
|
||||||
|
|
||||||
virtual void mark_to_delete();
|
virtual void mark_to_delete();
|
||||||
virtual void mark_to_remove();
|
virtual void mark_to_remove();
|
||||||
|
|
Loading…
Reference in New Issue