From 56cbebad4f71140ff45afe2874b8087e457428fe Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 16 May 2022 13:42:51 +0200 Subject: [PATCH] add FT::numeric to be applied on string types --- src/Makefile.dep | 10 +++--- src/baseexpression.cpp | 16 +++++++--- src/baseexpression.h | 44 ++++++++++++++++++++++++++ src/clearer.cpp | 60 ++++++++++++++++++++++-------------- src/clearer.h | 45 ++++++++++++++------------- src/ft.h | 6 ++++ src/model.cpp | 6 ++-- src/model.h | 10 +++--- src/postgresqlexpression.cpp | 5 +++ 9 files changed, 140 insertions(+), 62 deletions(-) diff --git a/src/Makefile.dep b/src/Makefile.dep index a63305e..8ea5025 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -6,9 +6,9 @@ baseexpression.o: fieldvaluehelper.h wrapper.h spacewrapper.h baseexpression.o: baseobjectwrapper.h modelcontainerwrapper.h ft.h model.h baseexpression.o: modelconnector.h clearer.h dbconnector.h flatconnector.h baseexpression.o: dbexpression.h flatexpression.h -clearer.o: clearer.h model.h modelconnector.h dbconnector.h queryresult.h -clearer.o: ft.h flatconnector.h dbexpression.h baseexpression.h morm_types.h -clearer.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h +clearer.o: clearer.h ft.h model.h modelconnector.h dbconnector.h +clearer.o: queryresult.h flatconnector.h dbexpression.h baseexpression.h +clearer.o: morm_types.h modelenv.h modeldata.h cursorhelper.h finderhelper.h clearer.o: fieldvaluehelper.h wrapper.h spacewrapper.h baseobjectwrapper.h clearer.o: modelcontainerwrapper.h flatexpression.h dbconnector.o: dbconnector.h queryresult.h ft.h dbexpression.h @@ -41,12 +41,12 @@ jsonexpression.o: morm_types.h modelenv.h modeldata.h cursorhelper.h jsonexpression.o: queryresult.h finderhelper.h fieldvaluehelper.h wrapper.h jsonexpression.o: spacewrapper.h baseobjectwrapper.h modelcontainerwrapper.h jsonexpression.o: ft.h -model.o: model.h modelconnector.h clearer.h dbconnector.h queryresult.h ft.h +model.o: model.h modelconnector.h clearer.h ft.h dbconnector.h queryresult.h model.o: flatconnector.h dbexpression.h baseexpression.h morm_types.h model.o: modelenv.h modeldata.h cursorhelper.h finderhelper.h model.o: fieldvaluehelper.h wrapper.h spacewrapper.h baseobjectwrapper.h model.o: modelcontainerwrapper.h flatexpression.h -modelconnector.o: modelconnector.h clearer.h dbconnector.h queryresult.h ft.h +modelconnector.o: modelconnector.h clearer.h ft.h dbconnector.h queryresult.h modelconnector.o: flatconnector.h postgresqlconnector.o: postgresqlconnector.h dbconnector.h queryresult.h ft.h postgresqlconnector.o: postgresqlqueryresult.h postgresqlexpression.h diff --git a/src/baseexpression.cpp b/src/baseexpression.cpp index dacfbae..d6a64d3 100644 --- a/src/baseexpression.cpp +++ b/src/baseexpression.cpp @@ -467,18 +467,26 @@ void BaseExpression::esc(wchar_t val, pt::TextStream & stream, const FT & field_ void BaseExpression::esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type) { - for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i) + if( field_type.is_numeric() ) { - esc(val[i], stream, field_type); + esc_numeric_string(val, has_known_length, len, stream, field_type); + } + else + { + esc_normal_string(val, has_known_length, len, stream, field_type); } } void BaseExpression::esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type) { - for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i) + if( field_type.is_numeric() ) { - esc(val[i], stream, field_type); + esc_numeric_string(val, has_known_length, len, stream, field_type); + } + else + { + esc_normal_string(val, has_known_length, len, stream, field_type); } } diff --git a/src/baseexpression.h b/src/baseexpression.h index fe119d3..91cc328 100644 --- a/src/baseexpression.h +++ b/src/baseexpression.h @@ -37,6 +37,7 @@ #include #include +#include #include "textstream/textstream.h" #include "date/date.h" #include "morm_types.h" @@ -635,6 +636,49 @@ protected: void esc(const char * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type); bool is_empty_field(const wchar_t * value); + + + + template + void esc_normal_string(CharType * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type) + { + for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i) + { + esc(val[i], stream, field_type); + } + } + + + template + void esc_numeric_string(CharType * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type) + { + bool was_comma = false; + bool was_something_printed = false; + + for(size_t i = 0 ; has_known_length ? (i < len) : val[i] != 0 ; ++i) + { + typename std::remove_const::type c = val[i]; + + if( c == ',' ) + c = '.'; + + if( (c=='.' && !was_comma) || (c>='0' && c<='9') ) + { + esc(c, stream, field_type); + was_something_printed = true; + + if( c == '.' ) + was_comma = true; + } + } + + if( !was_something_printed ) + { + esc(static_cast('0'), stream, field_type); + } + } + + }; } diff --git a/src/clearer.cpp b/src/clearer.cpp index 97a2270..3c13e35 100644 --- a/src/clearer.cpp +++ b/src/clearer.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2018-2021, Tomasz Sowa + * Copyright (c) 2018-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,105 +50,119 @@ Clearer::~Clearer() } -void Clearer::clear_value(char & field_value) +void Clearer::clear_value(char & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(unsigned char & field_value) +void Clearer::clear_value(unsigned char & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(wchar_t & field_value) +void Clearer::clear_value(wchar_t & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(std::wstring & field_value) +void Clearer::clear_value(std::wstring & field_value, const FT & field_type) { - field_value.clear(); + if( field_type.is_numeric() ) + { + field_value = L"0"; + } + else + { + field_value.clear(); + } } -void Clearer::clear_value(std::string & field_value) +void Clearer::clear_value(std::string & field_value, const FT & field_type) { - field_value.clear(); + if( field_type.is_numeric() ) + { + field_value = "0"; + } + else + { + field_value.clear(); + } } -void Clearer::clear_value(bool & field_value) +void Clearer::clear_value(bool & field_value, const FT & field_type) { field_value = false; } -void Clearer::clear_value(short & field_value) +void Clearer::clear_value(short & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(unsigned short & field_value) +void Clearer::clear_value(unsigned short & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(int & field_value) +void Clearer::clear_value(int & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(unsigned int & field_value) +void Clearer::clear_value(unsigned int & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(long & field_value) +void Clearer::clear_value(long & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(unsigned long & field_value) +void Clearer::clear_value(unsigned long & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(long long & field_value) +void Clearer::clear_value(long long & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(unsigned long long & field_value) +void Clearer::clear_value(unsigned long long & field_value, const FT & field_type) { field_value = 0; } -void Clearer::clear_value(float & field_value) +void Clearer::clear_value(float & field_value, const FT & field_type) { field_value = 0.0f; } -void Clearer::clear_value(double & field_value) +void Clearer::clear_value(double & field_value, const FT & field_type) { field_value = 0.0; } -void Clearer::clear_value(long double & field_value) +void Clearer::clear_value(long double & field_value, const FT & field_type) { field_value = 0.0; } -void Clearer::clear_value(pt::Date & field_value) +void Clearer::clear_value(pt::Date & field_value, const FT & field_type) { field_value.Clear(); } -void Clearer::clear_value(pt::Space & field_value) +void Clearer::clear_value(pt::Space & field_value, const FT & field_type) { field_value.clear(); } -void Clearer::clear_model(Model & field_value) +void Clearer::clear_model(Model & field_value, const FT & field_type) { field_value.clear(); } diff --git a/src/clearer.h b/src/clearer.h index a1957ac..d907a05 100644 --- a/src/clearer.h +++ b/src/clearer.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2018-2021, Tomasz Sowa + * Copyright (c) 2018-2022, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ #include #include "date/date.h" #include "space/space.h" +#include "ft.h" namespace morm @@ -52,30 +53,30 @@ public: Clearer(); virtual ~Clearer(); - virtual void clear_value(char & field_value); - virtual void clear_value(unsigned char & field_value); - virtual void clear_value(wchar_t & field_value); - virtual void clear_value(std::wstring & field_value); - virtual void clear_value(std::string & field_value); - virtual void clear_value(bool & field_value); - virtual void clear_value(short & field_value); - virtual void clear_value(unsigned short & field_value); - virtual void clear_value(int & field_value); - virtual void clear_value(unsigned int & field_value); - virtual void clear_value(long & field_value); - virtual void clear_value(unsigned long & field_value); - virtual void clear_value(long long & field_value); - virtual void clear_value(unsigned long long & field_value); - virtual void clear_value(float & field_value); - virtual void clear_value(double & field_value); - virtual void clear_value(long double & field_value); - virtual void clear_value(pt::Date & field_value); - virtual void clear_value(pt::Space & field_value); + virtual void clear_value(char & field_value, const FT & field_type); + virtual void clear_value(unsigned char & field_value, const FT & field_type); + virtual void clear_value(wchar_t & field_value, const FT & field_type); + virtual void clear_value(std::wstring & field_value, const FT & field_type); + virtual void clear_value(std::string & field_value, const FT & field_type); + virtual void clear_value(bool & field_value, const FT & field_type); + virtual void clear_value(short & field_value, const FT & field_type); + virtual void clear_value(unsigned short & field_value, const FT & field_type); + virtual void clear_value(int & field_value, const FT & field_type); + virtual void clear_value(unsigned int & field_value, const FT & field_type); + virtual void clear_value(long & field_value, const FT & field_type); + virtual void clear_value(unsigned long & field_value, const FT & field_type); + virtual void clear_value(long long & field_value, const FT & field_type); + virtual void clear_value(unsigned long long & field_value, const FT & field_type); + virtual void clear_value(float & field_value, const FT & field_type); + virtual void clear_value(double & field_value, const FT & field_type); + virtual void clear_value(long double & field_value, const FT & field_type); + virtual void clear_value(pt::Date & field_value, const FT & field_type); + virtual void clear_value(pt::Space & field_value, const FT & field_type); - virtual void clear_model(Model & field_value); + virtual void clear_model(Model & field_value, const FT & field_type); template - void clear_container(ModelContainer & container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo) + void clear_container(ModelContainer & container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type) { if constexpr (std::is_base_of()) { diff --git a/src/ft.h b/src/ft.h index 4afa38d..f1d5309 100644 --- a/src/ft.h +++ b/src/ft.h @@ -64,6 +64,7 @@ public: json = 2048, space = 4096, pretty_print = 8192, + numeric = 16384, }; /* @@ -176,6 +177,11 @@ public: return is_flag_set(pretty_print); } + bool is_numeric() const + { + return is_flag_set(numeric); + } + }; } diff --git a/src/model.cpp b/src/model.cpp index 9caf383..7b570d4 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -1486,13 +1486,13 @@ void Model::field_model_generate_db_sql(const wchar_t * db_field_name, Model & f } -void Model::field_model_clear_values(Model & field_model) +void Model::field_model_clear_values(Model & field_model, const FT & field_type) { Clearer * clearer = model_connector->get_clearer(); if( clearer ) { - clearer->clear_model(field_model); + clearer->clear_model(field_model, field_type); } } @@ -1571,7 +1571,7 @@ void Model::field_model(const wchar_t * db_field_name, const wchar_t * flat_fiel if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) { - field_model_clear_values(field_model); + field_model_clear_values(field_model, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_GET_FIELD_MODEL ) diff --git a/src/model.h b/src/model.h index 15ce0a9..b11caee 100644 --- a/src/model.h +++ b/src/model.h @@ -754,7 +754,7 @@ protected: if( clearer ) { - clearer->clear_value(field_value); + clearer->clear_value(field_value, field_type); } } @@ -1050,7 +1050,7 @@ protected: void field_model_iterate_through_childs(Model & field_model, const FT & field_type); void field_model_generate_flat_string(const wchar_t * flat_field_name, Model & field_model, const FT & field_type); void field_model_generate_db_sql(const wchar_t * db_field_name, Model & field_model, const FT & field_type); - void field_model_clear_values(Model & field_model); + void field_model_clear_values(Model & field_model, const FT & field_type); void field_model_read_values_from_queryresult(const wchar_t * db_field_name, Model & field_model, const FT & field_type); void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, const FT & field_type); void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model * field_model, const FT & field_type); @@ -1180,13 +1180,13 @@ protected: template - void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo) + void field_list_clearing_values(ModelContainer & field_container, ModelContainerType * model_container_type, IsContainerByValueRenameMe * foo, const FT & field_type) { Clearer * clearer = model_connector->get_clearer(); if( clearer ) { - clearer->clear_container(field_container, model_container_type, foo); + clearer->clear_container(field_container, model_container_type, foo, field_type); } } @@ -1412,7 +1412,7 @@ protected: if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_CLEARING_VALUE ) { - field_list_clearing_values(field_container, model_container_type, foo); + field_list_clearing_values(field_container, model_container_type, foo, field_type); } if( model_env->model_work_mode == MORM_MODEL_WORK_MODE_PROPAGATE_SAVE_STATUS ) diff --git a/src/postgresqlexpression.cpp b/src/postgresqlexpression.cpp index 5167b9c..bfe9a98 100644 --- a/src/postgresqlexpression.cpp +++ b/src/postgresqlexpression.cpp @@ -52,6 +52,11 @@ void PostgreSQLExpression::before_field_value_string(const FT & field_type) (*out_stream) << "'"; } else + if( field_type.is_numeric() ) + { + (*out_stream) << "'"; + } + else { (*out_stream) << "E'"; }