reported by clang with -fsanitize=undefined
main.cpp:55:63: runtime error: member access within address 0x614000000040 which does not point to an object of type 'Krolik'
0x614000000040: note: object is of type 'Item'
02 00 00 73 00 4e 75 00 00 00 00 00 a0 b9 ff ff ff 7f 00 00 c0 80 ff ff ff 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'Item'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.cpp:55:63 in
main.cpp:55:97: runtime error: member access within address 0x614000000040 which does not point to an object of type 'Krolik'
0x614000000040: note: object is of type 'Item'
02 00 00 73 00 4e 75 00 00 00 00 00 a0 b9 ff ff ff 7f 00 00 c0 80 ff ff ff 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'Item'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.cpp:55:97 in
- pikotools is in src subdirectory now
- map_fields() -> fields()
- prepare_table() -> table()
- instead of pt::MainSpaceParser we have pt::MainOptionsParser now
- changed in Model::field_list_generic(...): message "you should set FT::is_foreign_key or FT::is_foreign_key_in_child flag" print only
for work mode MORM_MODEL_WORK_MODE_SET_PARENT_ID or MORM_MODEL_WORK_MODE_ITERATE_THROUGH_CHILDS_WITHOUT_FOREIGN_KEY
- pt::TextStream::to_string(...) is now pt::TextStream::to_str(...)
- in Model::get_raw_value() for ezc 'pt::TextStream & stream' changed to 'pt::Stream & stream' (a base class of pt::TextStream)
similar in field(...) methods which take getters: void (Model::*getter_method)(pt::TextStream &) -> void (Model::*getter_method)(pt::Stream &)
added to Model:
- method field() which can take a pointer to a member which returns bool:
void field(const wchar_t * field_name, bool (ClassName::*method)(), const morm::FT & field_type = morm::FT::default_type)
- method field() which can take a pointer to a member which can set morm::ModelWrapper object
void field(const wchar_t * field_name, void (ClassName::*method)(morm::ModelWrapper **), const morm::FT & field_type = morm::FT::default_type)
- methods: bool Model::convert_to_bool(...) - they are used for creating a result for ezc from local fields
- removed MORM_WORK_MODE_GET_SPECIFIC_FIELD_VALUE from expression work mode
- removed: void BaseExpression::field(const wchar_t * field_name, void (Model::*getter_method)(pt::TextStream &), const FT & field_type, ModelEnv * model_env)
- removed from BaseExpression: template<typename FunInfoStreamType> void field(const wchar_t * field_name, void (Model::*fun)(Ezc::FunInfo<FunInfoStreamType> &), const FT & field_type, ModelEnv * model_env)
- removed: void FlatConnector::to_text(const wchar_t * flat_field_name, pt::TextStream & stream, Model & model)
- renamed/changed: Model::put_field_value(...) -> Model::get_raw_value()
added classes:
class ModelWrapper - base wrapper class for a model or a model container
class ModelWrapperModel : public ModelWrapper - wrapper for a model
template<typename VectorType> class ModelWrapperVector : public ModelWrapper - wrapper for vector of models
template<typename ListType> class ModelWrapperList : public ModelWrapper - wrapper for list of models
ModelWrapper... classes are used by ezc library for iterating through child models and for iterating in [for...] statements
added to Model:
Model * get_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool put_log_if_not_found = true);
ModelWrapper * get_model_wrapper(const wchar_t * db_field_name, const wchar_t * flat_field_name, bool put_log_if_not_found = true);
those functions can be used with databases and flat files
- removed support for calling static function
- if MORM_HAS_EZC_LIBRARY macro is defined then we can call a function
which has a first argument Ezc::FunInfo<>& object
(only for generating flat files)
now method put_field_name() is not making a test whether field_name is in long format
and only puts the field name (without table name),
this allows us to have a dot in the column name (field_name)
methods before_field_value_string() and after_field_value_string() moved
from DbExpression and JsonExpression to BaseExpression and made virtual
and now methods before_field_value(const std::wstring &) and after_field_value(const std::wstring &)
(and the rest of them with string arguments) can be removed from DbExpression, PostgreSqlExpression and JsonExpression
FT class has following types:
enum FieldType
{
default_type = 0,
primary_key = 1,
foreign_key = 2,
foreign_key_in_child = 4,
no_insertable = 8,
no_updatable = 16,
no_fetchable = 32, /* not supported yet */
};
an object of FT class are now used in Model::field() methods instead of insertable/updatable/is_primary_key/... boolean flags
changed the semantic of has_foreign_key (which was a bool) flag in child Models:
now on Models and list/vector of Models you should use either FT::foreign_key or FT::foreign_key_in_child
1. FT::foreign_key means that field with this flag is a foreign key and is pointing to the child object
(it was the case when has_foreign_key was equal to true beforehand)
2. FT::foreign_key_in child means that the foreign key is in the child object and is pointing to the parent object
Now we know whether the primary key is defined or not
and we do not allow to make update/remove if the key is not defined.
And when doing insert/update we can put NULL if child models don't have
the primary key set (fields with has_foreign_key set to true).
Now in after_select() we should also set has_primary_key_set flag
or just call get_last_sequence_for_primary_key instead of get_last_sequence.
fixed: added prefix +00 when serializing PT::Date to PostgreSQL (time zone)
(for a column with a time zone there was a wrong value saved)
methods removed:
virtual void before_field_name();
virtual void after_field_name();
methods added:
virtual void before_short_field_name();
virtual void after_short_field_name();
they are used for escaping column names in a case when using short form - just only column_name
e.g.: [before_short_field_name]column_name[after_short_field_name]
methods added:
virtual void before_first_part_long_field_name();
virtual void after_first_part_long_field_name();
virtual void before_second_part_long_field_name();
virtual void after_second_part_long_field_name();
they are used for escaping column names in a case when using long form: table_name.column_name
e.g.: [before_first_part_long_field_name]table_name[after_first_part_long_field_name].[before_second_part_long_field_name]column_name[after_second_part_long_field_name]
methods added:
virtual void esc(wchar_t val, PT::TextStream & stream);