improve the xml serializer

while here:
- do some refactoring in BaseExpression
This commit is contained in:
2023-02-26 22:19:46 +01:00
parent 0fbd988eda
commit cf377204a9
8 changed files with 324 additions and 199 deletions

View File

@@ -122,48 +122,12 @@ public:
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
{
if( model_env && model_env->set_field_name_helper )
{
if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() )
{
put_field_name_and_table_if_needed((*model_env->set_field_name_helper)[model_env->field_index], field_type, model_env);
put_name_value_separator();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
}
model_env->field_index += 1;
}
else
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
}
put_field_name_and_value(field_name, field_value, getter_method, field_type, model_env);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
{
(*out_stream) << '\n';
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
put_name_value_separator();
/*
* IMPROVEME currently only used in XML serializer so we put / directly here
* we need some virtual methods for it
*/
before_field_name(); // here should be a different method such as before_closing_field_name()
if( out_stream )
{
(*out_stream) << '/';
}
esc(field_name, *out_stream, FT::default_type, nullptr); /* do not use provided field_type here - it would use e.g. binary mode if it was set, similar don't use model_env */
after_field_name(); // here too, e.g. after_closing_field_name()
/*
*
*/
put_field_name_and_value_and_closing_name(field_name, field_value, getter_method, field_type, model_env);
}
field_after();
@@ -171,30 +135,6 @@ public:
}
template<typename FieldValue>
void put_field_value_or_null(const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
{
if( getter_method )
{
put_field_value(getter_method, field_type, model_env);
}
else
{
if( field_type.is_primary_key() )
{
if( model_env && model_env->has_primary_key_set )
put_field_value(field_value, field_type, model_env);
else
put_null_value();
}
else
{
put_field_value(field_value, field_type, model_env);
}
}
}
template<typename FieldValue>
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
{
@@ -231,34 +171,12 @@ public:
// 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();
put_field_value_list(field_value, model_container_type, field_type, model_connector, model_env, foo);
put_field_name_and_value_list(field_name, field_value, model_container_type, field_type, model_connector, model_env, foo);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
{
(*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, field_type, model_connector, model_env, foo);
put_name_value_separator();
/*
* IMPROVEME currently only used in XML serializer so we put / directly here
* we need some virtual methods for it
*/
before_field_name(); // here should be a different method such as before_closing_field_name()
if( out_stream )
{
(*out_stream) << '/';
}
esc(field_name, *out_stream, FT::default_type, nullptr); /* do not use provided field_type here - it would use e.g. binary mode if it was set, similar don't use model_env */
after_field_name(); // here too, e.g. after_closing_field_name()
/*
*
*/
put_field_name_and_value_list_and_closing_name(field_name, field_value, model_container_type, field_type, model_connector, model_env, foo);
}
field_after();
@@ -284,41 +202,19 @@ public:
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, field_type);
put_field_name_and_value_model(field_name, field_model, field_type, model_env);
}
else
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES_FIELDS )
{
(*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, field_type);
put_name_value_separator();
/*
* IMPROVEME currently only used in XML serializer so we put / directly here
* we need some virtual methods for it
*/
before_field_name(); // here should be a different method such as before_closing_field_name()
if( out_stream )
{
(*out_stream) << '/';
}
esc(field_name, *out_stream, FT::default_type, nullptr); /* do not use provided field_type here - it would use e.g. binary mode if it was set, similar don't use model_env */
after_field_name(); // here too, e.g. after_closing_field_name()
(*out_stream) << '\n';
/*
*
*/
put_field_name_and_value_model_and_closing_name(field_name, field_model, field_type, model_env);
}
field_after();
}
}
template<typename FieldValue>
void field_to_stream(pt::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
{
@@ -465,6 +361,9 @@ protected:
virtual void put_field_name_and_table_if_needed(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void put_field_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void put_field_closing_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void put_value_list_opening_index(size_t index, const FT & field_type);
virtual void put_value_list_closing_index(size_t index, const FT & field_type);
virtual void save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
virtual void dump_additional_info(Model & model);
@@ -548,7 +447,7 @@ protected:
}
else
{
put_field_value_list_non_model(field_value, model_connector);
put_field_value_list_non_model(field_value, model_connector, field_type);
}
}
@@ -559,20 +458,22 @@ protected:
{
if( model_connector && model_env && out_stream )
{
bool is_first = true;
before_field_value_list();
size_t index = 0;
for(auto & child_model_item : field_value)
{
if( can_field_model_be_generated(child_model_item.get_has_primary_key_set(), field_type) )
{
if( !is_first )
if( index > 0 )
{
field_value_list_separator();
}
put_value_list_opening_index(index, field_type);
put_field_value_list_model(child_model_item, model_connector, model_env);
is_first = false;
put_value_list_closing_index(index, field_type);
index += 1;
}
}
@@ -587,20 +488,22 @@ protected:
{
if( model_connector && model_env && out_stream )
{
bool is_first = true;
before_field_value_list();
size_t index = 0;
for(auto * child_model_item : field_value)
{
if( can_field_model_be_generated(child_model_item->get_has_primary_key_set(), field_type) )
{
if( !is_first )
if( index > 0 )
{
field_value_list_separator();
}
put_value_list_opening_index(index, field_type);
put_field_value_list_model(*child_model_item, model_connector, model_env);
is_first = false;
put_value_list_closing_index(index, field_type);
index += 1;
}
}
@@ -626,22 +529,24 @@ protected:
template<typename ModelContainer>
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector)
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector, const FT & field_type)
{
if( model_connector && out_stream )
{
bool is_first = true;
before_field_value_list();
size_t index = 0;
for(const auto & m : field_value)
{
if( !is_first )
if( index > 0 )
{
field_value_list_separator();
}
put_value_list_opening_index(index, field_type);
put_field_value(m, FT::default_type);
is_first = false;
put_value_list_closing_index(index, field_type);
index += 1;
}
after_field_value_list();
@@ -846,6 +751,106 @@ protected:
}
template<typename FieldValue>
void put_field_value_or_null(const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
{
if( getter_method )
{
put_field_value(getter_method, field_type, model_env);
}
else
{
if( field_type.is_primary_key() )
{
if( model_env && model_env->has_primary_key_set )
put_field_value(field_value, field_type, model_env);
else
put_null_value();
}
else
{
put_field_value(field_value, field_type, model_env);
}
}
}
template<typename FieldValue>
void put_field_name_and_value(const wchar_t * field_name, const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
{
if( model_env && model_env->set_field_name_helper )
{
if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() )
{
put_field_name_and_table_if_needed((*model_env->set_field_name_helper)[model_env->field_index], field_type, model_env);
put_name_value_separator();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
}
model_env->field_index += 1;
}
else
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
}
}
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
void put_field_name_and_value_list(const wchar_t * field_name, ModelContainer & field_value, ModelContainerType * model_container_type,
const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
{
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, field_type, model_connector, model_env, foo);
}
template<typename ModelClass>
void put_field_name_and_value_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
generate_from_model(field_model, field_type);
}
template<typename FieldValue>
void put_field_name_and_value_and_closing_name(const wchar_t * field_name, const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
put_field_value_or_null(field_value, getter_method, field_type, model_env);
put_name_value_separator();
put_field_closing_name(field_name, field_type, model_env);
}
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
void put_field_name_and_value_list_and_closing_name(const wchar_t * field_name, ModelContainer & field_value, ModelContainerType * model_container_type,
const FT & field_type, ModelConnector * model_connector, ModelEnv * model_env, IsContainerByValueRenameMe * foo)
{
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, field_type, model_connector, model_env, foo);
put_name_value_separator();
put_field_closing_name(field_name, field_type, model_env);
}
template<typename ModelClass>
void put_field_name_and_value_model_and_closing_name(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
{
put_field_name_and_table_if_needed(field_name, field_type, model_env);
put_name_value_separator();
generate_from_model(field_model, field_type);
put_name_value_separator();
put_field_closing_name(field_name, field_type, model_env);
}
};
}