296 lines
7.1 KiB
C++
296 lines
7.1 KiB
C++
/*
|
|
* This file is a part of morm
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2018, Tomasz Sowa
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#ifndef headerfile_morm_expression
|
|
#define headerfile_morm_expression
|
|
|
|
#include "textstream/textstream.h"
|
|
#include "morm_types.h"
|
|
#include "baseescaper.h"
|
|
|
|
|
|
|
|
namespace morm
|
|
{
|
|
class Model;
|
|
class ModelConnector;
|
|
|
|
|
|
class Expression
|
|
{
|
|
public:
|
|
|
|
Expression();
|
|
virtual ~Expression();
|
|
|
|
virtual void set_json_escaper(BaseEscaper & json_escaper);
|
|
virtual void set_db_escaper(BaseEscaper & db_escaper);
|
|
|
|
virtual void to_json(PT::TextStream & stream, Model & model);
|
|
virtual void insert(PT::TextStream & stream, Model & model, int db_type);
|
|
virtual void update(PT::TextStream & stream, Model & model, int db_type);
|
|
|
|
|
|
Expression & eq(const wchar_t * field_name, const std::wstring & field_value)
|
|
{
|
|
//put_field_name(field_name);
|
|
return *this;
|
|
}
|
|
|
|
Expression & eq(const wchar_t * field_name, const std::string & field_value)
|
|
{
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<typename FieldValue>
|
|
Expression & eq(const wchar_t * field_name, const FieldValue & field_value)
|
|
{
|
|
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
protected:
|
|
|
|
|
|
int work_mode; /* what to do: generating fields list, values list or fields-values list */
|
|
int output_type; /* what the output string is: for json, for database */
|
|
int db_type; /* what type of database we are using if generating a string for a database */
|
|
|
|
bool is_first_field;
|
|
|
|
// niech Stream bedzie jakims interfejsem z operatorami << dla standardowych typow
|
|
PT::TextStream * out_stream;
|
|
Model * model;
|
|
|
|
BaseEscaper * json_escaper;
|
|
BaseEscaper * db_escaper;
|
|
|
|
|
|
/*
|
|
ostream& operator<< (bool val);
|
|
ostream& operator<< (short val);
|
|
ostream& operator<< (unsigned short val);
|
|
ostream& operator<< (int val);
|
|
ostream& operator<< (unsigned int val);
|
|
ostream& operator<< (long val);
|
|
ostream& operator<< (unsigned long val);
|
|
ostream& operator<< (long long val);
|
|
ostream& operator<< (unsigned long long val);
|
|
ostream& operator<< (float val);
|
|
ostream& operator<< (double val);
|
|
ostream& operator<< (long double val);
|
|
ostream& operator<< (void* val);
|
|
*/
|
|
|
|
// virtual void map_fields(Model * model)
|
|
// {
|
|
// work_mode = model->work_mode;
|
|
// out_stream = model->out_stream;
|
|
// is_insert = model->is_insert;
|
|
// is_update = model->is_update;
|
|
//
|
|
// generate_from_model();
|
|
// }
|
|
|
|
|
|
virtual void generate_from_model();
|
|
virtual void before_generate_from_model();
|
|
virtual void after_generate_from_model();
|
|
virtual bool can_field_be_generated(bool insertable, bool updatable, bool is_primary_key);
|
|
virtual void field_before();
|
|
virtual void field_after();
|
|
|
|
template<typename FieldValue>
|
|
void field(const wchar_t * field_name, const FieldValue & field_value, bool insertable = true, bool updatable = true, bool is_primary_key = false)
|
|
{
|
|
if( can_field_be_generated(insertable, updatable, is_primary_key) )
|
|
{
|
|
field_before();
|
|
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS )
|
|
{
|
|
put_field_name(field_name);
|
|
}
|
|
else
|
|
if( work_mode == MORM_WORK_MODE_MODEL_VALUES )
|
|
{
|
|
put_field_value(field_value);
|
|
}
|
|
else
|
|
if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES )
|
|
{
|
|
print_field_name_value(field_name, field_value);
|
|
}
|
|
|
|
field_after();
|
|
}
|
|
}
|
|
|
|
//void field(const wchar_t * field_name, Model & field, bool insertable = true, bool updatable = true);
|
|
|
|
virtual void put_field_name(const wchar_t * field_name);
|
|
|
|
template<typename FieldValue>
|
|
void put_field_value(const FieldValue & field_value)
|
|
{
|
|
before_field_value(field_value);
|
|
field_value_raw(field_value);
|
|
after_field_value(field_value);
|
|
}
|
|
|
|
|
|
virtual void before_field_name();
|
|
virtual void after_field_name();
|
|
|
|
virtual void before_field_value_string();
|
|
virtual void after_field_value_string();
|
|
|
|
virtual void before_field_value(const std::wstring &);
|
|
virtual void after_field_value(const std::wstring &);
|
|
|
|
virtual void before_field_value(const std::string &);
|
|
virtual void after_field_value(const std::string &);
|
|
|
|
template<typename FieldValue>
|
|
void before_field_value(const FieldValue &)
|
|
{
|
|
}
|
|
|
|
template<typename FieldValue>
|
|
void after_field_value(const FieldValue &)
|
|
{
|
|
}
|
|
|
|
virtual void field_name_raw(const wchar_t * field_name);
|
|
virtual void field_value_raw(const std::wstring & field_value);
|
|
virtual void field_value_raw(long field_value);
|
|
|
|
virtual void field_value_raw(int field_value);
|
|
|
|
template<typename FieldValue>
|
|
void print_field_name_value(const wchar_t * field_name, const FieldValue & field_value)
|
|
{
|
|
put_field_name(field_name);
|
|
|
|
if( output_type == MORM_OUTPUT_TYPE_JSON )
|
|
{
|
|
(*out_stream) << ":";
|
|
}
|
|
else
|
|
if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
|
|
{
|
|
(*out_stream) << " = ";
|
|
}
|
|
|
|
put_field_value(field_value);
|
|
}
|
|
|
|
|
|
/*
|
|
template<typename Container>
|
|
virtual void field_container(const wchar_t * field_name, Container container, bool insertable = true, bool updatable = true)
|
|
{
|
|
typename Container::value Value; // czy tu jest Container::value? sprawdzic
|
|
|
|
if( !is_first_field )
|
|
(*out_stream) << ",";
|
|
|
|
if( work_mode == ORM_STREAM_MODE_CREATING_JSON )
|
|
{
|
|
(*out_stream) << "[";
|
|
boolean is_first = true;
|
|
|
|
for(Value v : container)
|
|
{
|
|
if( !is_first )
|
|
(*out_stream) << ",";
|
|
|
|
v.map_fields(this);
|
|
is_first = false;
|
|
}
|
|
|
|
(*out_stream) << "]";
|
|
}
|
|
// a co z bazą danych?
|
|
|
|
|
|
is_first_field = false;
|
|
}
|
|
*/
|
|
|
|
|
|
template<typename Field>
|
|
void esc(const Field & val, PT::TextStream & stream)
|
|
{
|
|
if( output_type == MORM_OUTPUT_TYPE_JSON )
|
|
{
|
|
if( json_escaper )
|
|
{
|
|
json_escaper->esc(val, stream);
|
|
}
|
|
}
|
|
else
|
|
if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ||
|
|
output_type == MORM_OUTPUT_TYPE_DB_UPDATE ||
|
|
output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY )
|
|
{
|
|
if( db_escaper )
|
|
{
|
|
db_escaper->esc(val, stream);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
friend ModelConnector;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
#endif
|