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:
Tomasz Sowa 2023-02-26 18:28:16 +01:00
parent d1c86c84cf
commit 0fbd988eda
Signed by: tomasz.sowa
GPG Key ID: 662CC1438638588B
7 changed files with 114 additions and 42 deletions

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2023, Tomasz Sowa
* All rights reserved.
*
* 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)
{
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;
generate_from_model(model);
generate_from_model(model, field_type);
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 )
{
before_generate_from_model();
dump_additional_info(model);
model.fields();
add_additional_columns(model);
after_generate_from_model();
if( should_field_model_be_generated_as_null(model.get_has_primary_key_set(), field_type) )
{
put_null_value();
}
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()
{
if( !is_first_field )

View File

@ -75,6 +75,7 @@ public:
virtual void clear();
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();
@ -232,7 +233,7 @@ public:
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
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
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
@ -240,7 +241,7 @@ public:
(*out_stream) << '\n';
put_field_name_and_table_if_needed(field_name, field_type, model_env);
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();
/*
* IMPROVEME currently only used in XML serializer so we put / directly here
@ -267,7 +268,7 @@ public:
template<typename ModelClass>
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();
@ -278,14 +279,14 @@ public:
else
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
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
generate_from_model(field_model);
generate_from_model(field_model, field_type);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
@ -293,7 +294,7 @@ public:
(*out_stream) << '\n';
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
generate_from_model(field_model);
generate_from_model(field_model, field_type);
put_name_value_separator();
/*
* 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;
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 after_generate_from_model();
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_after();
@ -527,18 +532,18 @@ protected:
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
ModelEnv * model_env, IsContainerByValueRenameMe * foo)
void put_field_value_list(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
{
if constexpr (std::is_base_of<Model, ModelContainerType>())
{
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
{
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
@ -549,8 +554,8 @@ protected:
template<typename ModelContainer, typename ModelContainerType>
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
ModelEnv * model_env)
void put_field_value_list_model_by_value(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
ModelConnector * model_connector, ModelEnv * model_env)
{
if( model_connector && model_env && out_stream )
{
@ -559,13 +564,16 @@ protected:
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);
is_first = false;
put_field_value_list_model(child_model_item, model_connector, model_env);
is_first = false;
}
}
after_field_value_list();
@ -574,8 +582,8 @@ protected:
template<typename ModelContainer, typename ModelContainerType>
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, ModelConnector * model_connector,
ModelEnv * model_env)
void put_field_value_list_model_by_pointer(ModelContainer & field_value, ModelContainerType * model_container_type, const FT & field_type,
ModelConnector * model_connector, ModelEnv * model_env)
{
if( model_connector && model_env && out_stream )
{
@ -584,13 +592,16 @@ protected:
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);
is_first = false;
put_field_value_list_model(*child_model_item, model_connector, model_env);
is_first = false;
}
}
after_field_value_list();
@ -607,7 +618,8 @@ protected:
child_model.model_env->model = &child_model;
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;
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -39,6 +39,18 @@
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();
}
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -46,6 +46,10 @@ class FlatExpression : public BaseExpression
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);
};

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2021-2022, Tomasz Sowa
* Copyright (c) 2021-2023, Tomasz Sowa
* All rights reserved.
*
* 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 */
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 */
/*
* 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);
}
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);
}
};
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2023, Tomasz Sowa
* All rights reserved.
*
* 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;
}
@ -1448,7 +1448,7 @@ void Model::field_model_generate_flat_string(const wchar_t * flat_field_name, Mo
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;
flat_expression->field_model(flat_field_name, field_model, field_type, model_env);

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2018-2022, Tomasz Sowa
* Copyright (c) 2018-2023, Tomasz Sowa
* All rights reserved.
*
* 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_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_remove();