2018-03-13 23:22:17 +01:00
|
|
|
/*
|
|
|
|
* This file is a part of morm
|
|
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2021-02-24 01:15:17 +01:00
|
|
|
* Copyright (c) 2018-2021, Tomasz Sowa
|
2018-03-13 23:22:17 +01:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-03-23 20:26:57 +01:00
|
|
|
#ifndef headerfile_morm_baseexpression
|
|
|
|
#define headerfile_morm_baseexpression
|
|
|
|
|
2018-04-17 00:46:25 +02:00
|
|
|
#include <list>
|
2018-04-18 19:52:09 +02:00
|
|
|
#include <set>
|
2018-03-13 23:22:17 +01:00
|
|
|
#include "textstream/textstream.h"
|
2018-04-12 18:05:14 +02:00
|
|
|
#include "date/date.h"
|
2019-03-26 19:34:07 +01:00
|
|
|
#include "morm_types.h"
|
2019-05-13 19:59:28 +02:00
|
|
|
#include "modelenv.h"
|
2021-03-10 16:20:11 +01:00
|
|
|
#include "ft.h"
|
2021-05-31 18:40:28 +02:00
|
|
|
#include "convert/text.h"
|
|
|
|
|
2021-06-01 19:34:34 +02:00
|
|
|
#ifdef MORM_HAS_EZC_LIBRARY
|
2021-09-08 15:34:40 +02:00
|
|
|
#include "env.h"
|
2021-06-01 19:34:34 +02:00
|
|
|
#endif
|
2018-03-13 23:22:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
namespace morm
|
|
|
|
{
|
|
|
|
class Model;
|
|
|
|
class ModelConnector;
|
|
|
|
|
|
|
|
|
2018-03-23 20:26:57 +01:00
|
|
|
class BaseExpression
|
2018-03-13 23:22:17 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2018-03-23 20:26:57 +01:00
|
|
|
BaseExpression();
|
|
|
|
virtual ~BaseExpression();
|
2018-03-13 23:22:17 +01:00
|
|
|
|
2018-03-23 20:26:57 +01:00
|
|
|
virtual void set_work_mode(int work_mode);
|
2019-03-26 19:34:07 +01:00
|
|
|
virtual int get_work_mode();
|
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual pt::TextStream * get_text_stream();
|
|
|
|
virtual void set_text_stream(pt::TextStream * out_stream);
|
2021-05-12 00:27:35 +02:00
|
|
|
|
2019-05-31 20:28:09 +02:00
|
|
|
virtual void clear();
|
2018-05-02 01:22:32 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void generate_from_model(pt::TextStream & stream, Model & model);
|
2018-03-13 23:22:17 +01:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual pt::TextStream * get_current_stream();
|
2018-07-16 00:36:04 +02:00
|
|
|
|
2019-03-31 22:21:12 +02:00
|
|
|
// rename me
|
|
|
|
virtual void allow_to_use_prefix(bool use_prefix);
|
2019-05-21 19:24:12 +02:00
|
|
|
virtual bool get_allow_to_use_prefix();
|
2018-07-16 00:36:04 +02:00
|
|
|
|
|
|
|
|
2018-03-30 21:34:45 +02:00
|
|
|
template<typename FieldValue>
|
2021-05-12 04:53:23 +02:00
|
|
|
void field(const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
2021-06-20 17:49:54 +02:00
|
|
|
{
|
|
|
|
field_generic(field_name, field_value, nullptr, field_type, model_env);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual void field(const wchar_t * field_name, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
|
|
|
{
|
|
|
|
int tmp_object = 0;
|
|
|
|
field_generic(field_name, tmp_object, getter_method, field_type, model_env);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename FieldValue>
|
|
|
|
void field_generic(const wchar_t * field_name, const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
2018-03-30 21:34:45 +02:00
|
|
|
{
|
2021-03-10 16:20:11 +01:00
|
|
|
if( out_stream && can_field_be_generated(field_type) )
|
2018-03-30 21:34:45 +02:00
|
|
|
{
|
|
|
|
field_before();
|
|
|
|
|
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
|
|
|
|
{
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
2019-03-26 19:34:07 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_SAVE_FIELDS )
|
|
|
|
{
|
2021-04-12 18:53:55 +02:00
|
|
|
save_foreign_key(field_name, field_type, model_env);
|
2018-03-30 21:34:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
|
|
|
{
|
2021-06-20 17:49:54 +02:00
|
|
|
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
2018-03-30 21:34:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
|
|
|
{
|
2019-09-04 18:02:18 +02:00
|
|
|
if( model_env && model_env->set_field_name_helper )
|
|
|
|
{
|
|
|
|
if( (size_t)model_env->field_index < model_env->set_field_name_helper->size() )
|
|
|
|
{
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed((*model_env->set_field_name_helper)[model_env->field_index], field_type, model_env);
|
2019-09-04 18:02:18 +02:00
|
|
|
put_name_value_separator();
|
2021-06-20 17:49:54 +02:00
|
|
|
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
2019-09-04 18:02:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
model_env->field_index += 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
2019-09-04 18:02:18 +02:00
|
|
|
put_name_value_separator();
|
2021-06-20 17:49:54 +02:00
|
|
|
put_field_value_or_null(field_value, getter_method, field_type, model_env);
|
2019-09-04 18:02:18 +02:00
|
|
|
}
|
2018-03-30 21:34:45 +02:00
|
|
|
}
|
2021-05-31 18:40:28 +02:00
|
|
|
|
|
|
|
field_after();
|
|
|
|
}
|
|
|
|
}
|
2021-04-30 01:23:22 +02:00
|
|
|
|
|
|
|
|
2021-03-09 18:10:34 +01:00
|
|
|
template<typename FieldValue>
|
2021-06-20 17:49:54 +02:00
|
|
|
void put_field_value_or_null(const FieldValue & field_value, void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
2021-03-09 18:10:34 +01:00
|
|
|
{
|
2021-06-20 17:49:54 +02:00
|
|
|
if( getter_method )
|
2021-03-09 18:10:34 +01:00
|
|
|
{
|
2021-06-20 17:49:54 +02:00
|
|
|
put_field_value(getter_method, field_type, model_env);
|
2021-03-09 18:10:34 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-06-20 17:49:54 +02:00
|
|
|
if( field_type.is_primary_key() )
|
|
|
|
{
|
|
|
|
if( model_env && model_env->has_primary_key_set )
|
|
|
|
put_field_value(field_value, field_type);
|
|
|
|
else
|
|
|
|
put_null_value();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
put_field_value(field_value, field_type);
|
|
|
|
}
|
2021-03-09 18:10:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-31 18:40:28 +02:00
|
|
|
|
2018-04-22 23:04:50 +02:00
|
|
|
template<typename FieldValue>
|
2021-05-20 16:25:01 +02:00
|
|
|
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::set<FieldValue> & container, ModelEnv * model_env)
|
2018-04-22 23:04:50 +02:00
|
|
|
{
|
2019-05-31 20:28:09 +02:00
|
|
|
field_in_generic<FieldValue, std::set<FieldValue>>(stream, field_name, container, model_env);
|
2018-04-22 23:04:50 +02:00
|
|
|
}
|
2018-03-30 21:34:45 +02:00
|
|
|
|
2018-04-18 19:52:09 +02:00
|
|
|
|
|
|
|
template<typename FieldValue>
|
2021-05-20 16:25:01 +02:00
|
|
|
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::list<FieldValue> & container, ModelEnv * model_env)
|
2018-04-18 19:52:09 +02:00
|
|
|
{
|
2019-05-31 20:28:09 +02:00
|
|
|
field_in_generic<FieldValue, std::list<FieldValue>>(stream, field_name, container, model_env);
|
2018-04-18 19:52:09 +02:00
|
|
|
}
|
|
|
|
|
2019-05-31 20:28:09 +02:00
|
|
|
|
2018-04-18 19:52:09 +02:00
|
|
|
template<typename FieldValue>
|
2021-05-20 16:25:01 +02:00
|
|
|
void field_in(pt::TextStream & stream, const wchar_t * field_name, const std::vector<FieldValue> & container, ModelEnv * model_env)
|
2018-04-18 19:52:09 +02:00
|
|
|
{
|
2019-05-31 20:28:09 +02:00
|
|
|
field_in_generic<FieldValue, std::vector<FieldValue>>(stream, field_name, container, model_env);
|
2018-04-18 19:52:09 +02:00
|
|
|
}
|
|
|
|
|
2019-05-31 20:28:09 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
template<typename ModelContainer, typename ModelContainerType, typename IsContainerByValueRenameMe>
|
|
|
|
void field_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)
|
2018-04-17 00:46:25 +02:00
|
|
|
{
|
2021-03-10 16:20:11 +01:00
|
|
|
if( out_stream && can_field_be_generated(field_type) )
|
2018-04-17 00:46:25 +02:00
|
|
|
{
|
|
|
|
field_before();
|
|
|
|
|
2019-03-26 19:34:07 +01:00
|
|
|
// if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
|
|
|
|
// {
|
2021-05-13 00:19:22 +02:00
|
|
|
// put_field_name_and_table_if_needed(field_name);
|
2019-03-26 19:34:07 +01:00
|
|
|
// }
|
|
|
|
// else
|
2018-04-17 00:46:25 +02:00
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
|
|
|
{
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
2018-04-17 00:46:25 +02:00
|
|
|
put_name_value_separator();
|
2021-06-17 21:31:58 +02:00
|
|
|
put_field_value_list(field_value, model_container_type, model_connector, model_env, foo);
|
2018-04-17 00:46:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
field_after();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-26 20:58:31 +02:00
|
|
|
template<typename ModelClass>
|
2021-05-12 04:53:23 +02:00
|
|
|
void field_model(const wchar_t * field_name, ModelClass & field_model, const FT & field_type, ModelEnv * model_env)
|
2018-04-26 20:58:31 +02:00
|
|
|
{
|
2021-03-10 16:20:11 +01:00
|
|
|
if( out_stream && can_field_be_generated(field_type) )
|
2018-04-26 20:58:31 +02:00
|
|
|
{
|
|
|
|
field_before();
|
|
|
|
|
2018-07-05 13:15:16 +02:00
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
|
|
|
|
{
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
2018-07-05 13:15:16 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
|
|
|
{
|
|
|
|
generate_from_model(field_model); // is it ok as a value?
|
|
|
|
}
|
|
|
|
else
|
2018-04-26 20:58:31 +02:00
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
|
|
|
{
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed(field_name, field_type, model_env);
|
2018-04-26 20:58:31 +02:00
|
|
|
put_name_value_separator();
|
|
|
|
generate_from_model(field_model);
|
|
|
|
}
|
|
|
|
|
|
|
|
field_after();
|
|
|
|
}
|
|
|
|
}
|
2018-04-18 19:52:09 +02:00
|
|
|
|
2018-04-16 01:00:17 +02:00
|
|
|
template<typename FieldValue>
|
2021-05-20 16:25:01 +02:00
|
|
|
void field_to_stream(pt::TextStream & stream, const wchar_t * field_name, const FieldValue & field_value, const FT & field_type, ModelEnv * model_env)
|
2018-04-16 01:00:17 +02:00
|
|
|
{
|
|
|
|
this->out_stream = &stream;
|
2021-03-10 16:20:11 +01:00
|
|
|
field(field_name, field_value, field_type, model_env);
|
2018-04-16 01:00:17 +02:00
|
|
|
this->out_stream = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-12 00:27:35 +02:00
|
|
|
virtual void put_schema_table(const wchar_t * schema_name, const wchar_t * table_name);
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void put_schema_table(const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
|
2021-05-12 00:27:35 +02:00
|
|
|
virtual void put_table(const wchar_t * table_name);
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void put_table(const pt::WTextStream & table_name);
|
2021-05-12 00:27:35 +02:00
|
|
|
virtual void put_table_with_index(const wchar_t * table_name, int index);
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void put_table_with_index(const pt::WTextStream & table_name, int index);
|
2021-05-12 00:27:35 +02:00
|
|
|
virtual void put_table_with_index_and_field(const wchar_t * table_name, int index, const wchar_t * field_name, const FT & field_type);
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void put_table_with_index_and_field(const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
|
2021-05-13 00:19:22 +02:00
|
|
|
virtual void put_table_and_field(const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void put_table_and_field(const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
|
2021-04-30 01:23:22 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void schema_table_to_stream(pt::TextStream & stream, const wchar_t * schema_name, const wchar_t * table_name);
|
|
|
|
virtual void schema_table_to_stream(pt::TextStream & stream, const pt::WTextStream & schema_name, const pt::WTextStream & table_name);
|
|
|
|
virtual void table_to_stream(pt::TextStream & stream, const wchar_t * table_name);
|
|
|
|
virtual void table_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name);
|
|
|
|
virtual void table_with_index_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index);
|
|
|
|
virtual void table_with_index_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index);
|
|
|
|
virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, int index, const wchar_t * field_name, const FT & field_type);
|
|
|
|
virtual void table_with_index_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, int index, const wchar_t * field_name, const FT & field_type);
|
|
|
|
virtual void table_and_field_to_stream(pt::TextStream & stream, const wchar_t * table_name, const wchar_t * field_name, const FT & field_type);
|
|
|
|
virtual void table_and_field_to_stream(pt::TextStream & stream, const pt::WTextStream & table_name, const wchar_t * field_name, const FT & field_type);
|
2021-04-30 01:23:22 +02:00
|
|
|
|
|
|
|
|
2019-09-25 19:21:12 +02:00
|
|
|
/*
|
|
|
|
* IMPLEMENT ME
|
|
|
|
* esc for: signed char, wchar_t, char16_t, char32_t
|
|
|
|
*
|
|
|
|
*/
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void esc(char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(unsigned char val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
2021-05-12 04:53:23 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void esc(wchar_t val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
2021-05-12 04:53:23 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void esc(const std::wstring & val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(const wchar_t * val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
2021-05-12 04:53:23 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void esc(const std::string & val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(const char * val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
2021-05-12 04:53:23 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void esc(bool val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(unsigned short val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(unsigned int val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(unsigned long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(unsigned long long val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(float val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(long double val, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
//virtual void esc(void* val, pt::TextStream & stream);
|
2018-04-16 01:00:17 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void esc(const pt::Date & date, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(const pt::TextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(const pt::WTextStream & val,pt::TextStream & stream, const FT & field_type = FT::default_type);
|
|
|
|
virtual void esc(const pt::Space & space, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
2018-03-30 21:34:45 +02:00
|
|
|
|
2019-05-31 20:28:09 +02:00
|
|
|
|
2018-07-03 18:55:06 +02:00
|
|
|
|
2018-03-13 23:22:17 +01:00
|
|
|
protected:
|
|
|
|
|
|
|
|
int work_mode; /* what to do: generating fields list, values list or fields-values list */
|
|
|
|
bool is_first_field;
|
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
pt::TextStream * out_stream;
|
2018-03-13 23:22:17 +01:00
|
|
|
|
2019-03-31 22:21:12 +02:00
|
|
|
bool use_prefix;
|
2018-05-02 01:22:32 +02:00
|
|
|
|
2018-04-17 00:46:25 +02:00
|
|
|
virtual void generate_from_model(Model & model);
|
|
|
|
|
2018-03-13 23:22:17 +01:00
|
|
|
virtual void before_generate_from_model();
|
|
|
|
virtual void after_generate_from_model();
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual bool can_field_be_generated(const FT &);
|
2018-03-13 23:22:17 +01:00
|
|
|
virtual void field_before();
|
|
|
|
virtual void field_after();
|
|
|
|
|
2021-05-13 00:19:22 +02:00
|
|
|
virtual void put_field_name_and_table_if_needed(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void put_field_name(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
2021-05-12 00:27:35 +02:00
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void save_foreign_key(const wchar_t * field_name, const FT & field_type, ModelEnv * model_env);
|
2019-09-13 20:17:02 +02:00
|
|
|
virtual void dump_additional_info(Model & model);
|
2018-03-13 23:22:17 +01:00
|
|
|
|
|
|
|
template<typename FieldValue>
|
2021-05-12 04:53:23 +02:00
|
|
|
void put_field_value(const FieldValue & field_value, const FT & field_type)
|
2018-03-13 23:22:17 +01:00
|
|
|
{
|
2018-04-18 19:52:09 +02:00
|
|
|
if( out_stream )
|
|
|
|
{
|
2021-05-11 22:11:31 +02:00
|
|
|
before_field_value(field_value, field_type);
|
|
|
|
esc(field_value, *out_stream, field_type);
|
|
|
|
after_field_value(field_value, field_type);
|
2018-04-18 19:52:09 +02:00
|
|
|
}
|
2018-03-13 23:22:17 +01:00
|
|
|
}
|
|
|
|
|
2021-06-20 17:49:54 +02:00
|
|
|
void put_field_value(void (Model::*getter_method)(pt::Stream &), const FT & field_type, ModelEnv * model_env)
|
|
|
|
{
|
|
|
|
if( out_stream && model_env && model_env->model && getter_method )
|
|
|
|
{
|
|
|
|
before_field_value_string(field_type);
|
|
|
|
(model_env->model->*getter_method)(*out_stream);
|
|
|
|
after_field_value_string(field_type);
|
|
|
|
}
|
|
|
|
}
|
2019-05-21 17:51:13 +02:00
|
|
|
|
2021-03-09 18:10:34 +01:00
|
|
|
virtual void put_null_value()
|
|
|
|
{
|
|
|
|
(*out_stream) << "null";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-21 17:51:13 +02:00
|
|
|
virtual void before_field_value_list()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual void after_field_value_list()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual void field_value_list_separator()
|
|
|
|
{
|
|
|
|
(*out_stream) << ",";
|
|
|
|
}
|
|
|
|
|
2019-05-31 20:28:09 +02:00
|
|
|
virtual void put_statement_in_starts()
|
|
|
|
{
|
|
|
|
(*out_stream) << "(";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void put_statement_in_ends()
|
|
|
|
{
|
|
|
|
(*out_stream) << ") ";
|
|
|
|
}
|
2019-05-21 17:51:13 +02:00
|
|
|
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
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)
|
2019-08-20 17:49:37 +02:00
|
|
|
{
|
2021-06-17 21:31:58 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
put_field_value_list_model_by_pointer(field_value, model_container_type, model_connector, model_env);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
put_field_value_list_non_model(field_value, model_connector);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
if( model_connector && model_env && out_stream )
|
2019-08-20 17:49:37 +02:00
|
|
|
{
|
|
|
|
bool is_first = true;
|
|
|
|
before_field_value_list();
|
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
for(auto & child_model_item : field_value)
|
2019-08-20 17:49:37 +02:00
|
|
|
{
|
|
|
|
if( !is_first )
|
|
|
|
{
|
|
|
|
field_value_list_separator();
|
|
|
|
}
|
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
put_field_value_list_model(child_model_item, model_connector, model_env);
|
2019-08-20 17:49:37 +02:00
|
|
|
is_first = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
after_field_value_list();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
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)
|
2018-04-17 00:46:25 +02:00
|
|
|
{
|
2019-05-21 17:51:13 +02:00
|
|
|
if( model_connector && model_env && out_stream )
|
2018-04-17 00:46:25 +02:00
|
|
|
{
|
2019-05-21 17:51:13 +02:00
|
|
|
bool is_first = true;
|
|
|
|
before_field_value_list();
|
2018-04-17 00:46:25 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
for(auto * child_model_item : field_value)
|
2018-04-17 00:46:25 +02:00
|
|
|
{
|
|
|
|
if( !is_first )
|
|
|
|
{
|
2019-05-21 17:51:13 +02:00
|
|
|
field_value_list_separator();
|
2018-04-17 00:46:25 +02:00
|
|
|
}
|
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
put_field_value_list_model(*child_model_item, model_connector, model_env);
|
2018-04-17 00:46:25 +02:00
|
|
|
is_first = false;
|
|
|
|
}
|
|
|
|
|
2019-05-21 17:51:13 +02:00
|
|
|
after_field_value_list();
|
2018-04-17 00:46:25 +02:00
|
|
|
}
|
|
|
|
}
|
2018-03-13 23:22:17 +01:00
|
|
|
|
2018-04-18 19:52:09 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
template<typename ModelContainerType>
|
|
|
|
void put_field_value_list_model(ModelContainerType & child_model, ModelConnector * model_connector, ModelEnv * model_env)
|
2019-08-20 17:49:37 +02:00
|
|
|
{
|
2021-06-17 21:31:58 +02:00
|
|
|
ModelEnv model_env_local(*model_env);
|
|
|
|
child_model.model_env = &model_env_local;
|
|
|
|
child_model.model_env->has_primary_key_set = child_model.get_has_primary_key_set();
|
2021-07-01 22:39:50 +02:00
|
|
|
child_model.model_env->model = &child_model;
|
2021-06-17 21:31:58 +02:00
|
|
|
child_model.set_connector(model_connector);
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
generate_from_model(child_model);
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
child_model.model_env = nullptr;
|
2019-08-20 17:49:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
template<typename ModelContainer>
|
|
|
|
void put_field_value_list_non_model(ModelContainer & field_value, ModelConnector * model_connector)
|
2019-08-20 17:49:37 +02:00
|
|
|
{
|
2021-06-17 21:31:58 +02:00
|
|
|
if( model_connector && out_stream )
|
|
|
|
{
|
|
|
|
bool is_first = true;
|
|
|
|
before_field_value_list();
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
for(const auto & m : field_value)
|
|
|
|
{
|
|
|
|
if( !is_first )
|
|
|
|
{
|
|
|
|
field_value_list_separator();
|
|
|
|
}
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
put_field_value(m, FT::default_type);
|
|
|
|
is_first = false;
|
|
|
|
}
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-06-17 21:31:58 +02:00
|
|
|
after_field_value_list();
|
|
|
|
}
|
2019-08-20 17:49:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-18 19:52:09 +02:00
|
|
|
// used in 'in()' statements, may should be renamed?
|
|
|
|
template<typename FieldValue, typename Container>
|
2021-05-20 16:25:01 +02:00
|
|
|
void field_in_generic(pt::TextStream & stream, const wchar_t * field_name, const Container & container, ModelEnv * model_env)
|
2018-04-18 19:52:09 +02:00
|
|
|
{
|
|
|
|
// IMPROVE ME
|
|
|
|
// what about if container is empty?
|
|
|
|
// only 'in()' statement would be generated
|
|
|
|
this->out_stream = &stream;
|
|
|
|
|
|
|
|
field_before();
|
2021-05-13 00:19:22 +02:00
|
|
|
put_field_name_and_table_if_needed(field_name, FT::default_type, model_env);
|
2018-04-18 19:52:09 +02:00
|
|
|
put_name_value_separator();
|
|
|
|
|
|
|
|
bool is_first = true;
|
2019-05-31 20:28:09 +02:00
|
|
|
put_statement_in_starts();
|
2018-04-18 19:52:09 +02:00
|
|
|
|
|
|
|
for(const FieldValue & v : container)
|
|
|
|
{
|
|
|
|
if( !is_first )
|
|
|
|
{
|
2019-05-31 20:28:09 +02:00
|
|
|
field_value_list_separator();
|
2018-04-18 19:52:09 +02:00
|
|
|
}
|
|
|
|
|
2021-05-11 22:11:31 +02:00
|
|
|
put_field_value(v, FT::default_type);
|
2018-04-18 19:52:09 +02:00
|
|
|
is_first = false;
|
|
|
|
}
|
|
|
|
|
2019-05-31 20:28:09 +02:00
|
|
|
put_statement_in_ends();
|
2018-04-18 19:52:09 +02:00
|
|
|
field_after();
|
|
|
|
this->out_stream = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-13 02:32:03 +02:00
|
|
|
virtual void schema_table_separator();
|
|
|
|
virtual void table_field_separator();
|
|
|
|
|
|
|
|
virtual void before_schema_name();
|
|
|
|
virtual void after_schema_name();
|
|
|
|
|
|
|
|
virtual void before_table_name();
|
|
|
|
virtual void after_table_name();
|
|
|
|
|
|
|
|
virtual void before_field_name();
|
|
|
|
virtual void after_field_name();
|
2021-02-24 01:15:17 +01:00
|
|
|
|
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value(const std::wstring &, const FT & field_type);
|
|
|
|
virtual void after_field_value(const std::wstring &, const FT & field_type);
|
2018-03-13 23:22:17 +01:00
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value(const std::string &, const FT & field_type);
|
|
|
|
virtual void after_field_value(const std::string &, const FT & field_type);
|
2018-03-13 23:22:17 +01:00
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value(const wchar_t *, const FT & field_type);
|
|
|
|
virtual void after_field_value(const wchar_t *, const FT & field_type);
|
2018-03-30 21:34:45 +02:00
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value(const char *, const FT & field_type);
|
|
|
|
virtual void after_field_value(const char *, const FT & field_type);
|
2018-03-30 21:34:45 +02:00
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value(wchar_t, const FT & field_type);
|
|
|
|
virtual void after_field_value(wchar_t, const FT & field_type);
|
2018-04-17 00:46:25 +02:00
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value(char, const FT & field_type);
|
|
|
|
virtual void after_field_value(char, const FT & field_type);
|
2021-05-11 22:11:31 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void before_field_value(const pt::Date &, const FT & field_type);
|
|
|
|
virtual void after_field_value(const pt::Date &, const FT & field_type);
|
2021-05-11 22:11:31 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
virtual void before_field_value(const pt::Space &, const FT & field_type);
|
|
|
|
virtual void after_field_value(const pt::Space &, const FT & field_type);
|
2018-03-30 21:34:45 +02:00
|
|
|
|
2018-03-13 23:22:17 +01:00
|
|
|
template<typename FieldValue>
|
2021-05-12 04:53:23 +02:00
|
|
|
void before_field_value(const FieldValue &, const FT & field_type)
|
2018-03-13 23:22:17 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename FieldValue>
|
2021-05-12 04:53:23 +02:00
|
|
|
void after_field_value(const FieldValue &, const FT & field_type)
|
2018-03-13 23:22:17 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-03-23 20:26:57 +01:00
|
|
|
virtual void put_name_value_separator();
|
2018-03-13 23:22:17 +01:00
|
|
|
|
|
|
|
|
2019-09-25 19:21:12 +02:00
|
|
|
/*
|
|
|
|
* IMPLEMENT ME
|
|
|
|
* put_type for: signed char, wchar_t, char16_t, char32_t
|
|
|
|
*
|
|
|
|
*/
|
2021-05-20 16:25:01 +02:00
|
|
|
// virtual void put_type(char val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(unsigned char val, pt::TextStream & stream);
|
2021-03-11 18:40:32 +01:00
|
|
|
//
|
2021-05-20 16:25:01 +02:00
|
|
|
// virtual void put_type(const std::wstring & val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(const wchar_t * val, pt::TextStream & stream);
|
2021-03-11 18:40:32 +01:00
|
|
|
//
|
2021-05-20 16:25:01 +02:00
|
|
|
// virtual void put_type(const std::string & val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(const char * val, pt::TextStream & stream);
|
2021-03-11 18:40:32 +01:00
|
|
|
//
|
2021-05-20 16:25:01 +02:00
|
|
|
// virtual void put_type(bool val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(short val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(unsigned short val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(int val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(unsigned int val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(long val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(unsigned long val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(long long val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(unsigned long long val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(float val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(double val, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(long double val, pt::TextStream & stream);
|
|
|
|
//virtual void put_type(void* val, pt::TextStream & stream);
|
|
|
|
|
|
|
|
// virtual void put_type(const pt::Date & date, pt::TextStream & stream);
|
|
|
|
// virtual void put_type(const Model & model, pt::TextStream & stream);
|
2021-03-11 18:40:32 +01:00
|
|
|
//
|
|
|
|
// template<typename ListType>
|
2021-05-20 16:25:01 +02:00
|
|
|
// void put_type(const std::list<ListType> & model, pt::TextStream & stream)
|
2021-03-11 18:40:32 +01:00
|
|
|
// {
|
|
|
|
// stream << "table"; // may just use std::list?
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// template<typename ListType>
|
2021-05-20 16:25:01 +02:00
|
|
|
// void put_type(const std::vector<ListType> & model, pt::TextStream & stream)
|
2021-03-11 18:40:32 +01:00
|
|
|
// {
|
|
|
|
// stream << "table"; // may just just std::vector?
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-12 04:53:23 +02:00
|
|
|
virtual void before_field_value_string(const FT & field_type);
|
|
|
|
virtual void after_field_value_string(const FT & field_type);
|
2018-07-16 00:36:04 +02:00
|
|
|
|
2021-05-11 22:11:31 +02:00
|
|
|
char char_to_hex_part(char c);
|
2021-05-20 16:25:01 +02:00
|
|
|
void char_to_hex(char c, pt::TextStream & stream);
|
2019-08-20 17:49:37 +02:00
|
|
|
|
2021-05-20 16:25:01 +02:00
|
|
|
void esc(const wchar_t * val, bool has_known_length, size_t len, pt::TextStream & stream, const FT & field_type = FT::default_type);
|
2018-03-23 20:26:57 +01:00
|
|
|
|
2021-05-13 02:32:03 +02:00
|
|
|
bool is_empty_field(const wchar_t * value);
|
2018-03-13 23:22:17 +01:00
|
|
|
};
|
|
|
|
|
2018-03-23 20:26:57 +01:00
|
|
|
}
|
2018-03-13 23:22:17 +01:00
|
|
|
|
|
|
|
#endif
|