/* * This file is a part of morm * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2018-2021, 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. * */ #include "baseexpression.h" #include "morm_types.h" #include "model.h" #include "utf8/utf8.h" namespace morm { BaseExpression::BaseExpression() { clear(); } BaseExpression::~BaseExpression() { } void BaseExpression::clear() { out_stream = nullptr; is_first_field = false; work_mode = 0; use_prefix = false; } void BaseExpression::set_work_mode(int work_mode) { this->work_mode = work_mode; } int BaseExpression::get_work_mode() { return work_mode; } PT::TextStream * BaseExpression::get_current_stream() { return out_stream; } void BaseExpression::allow_to_use_prefix(bool use_prefix) { this->use_prefix = use_prefix; } bool BaseExpression::get_allow_to_use_prefix() { return use_prefix; } void BaseExpression::generate_from_model(PT::TextStream & stream, Model & model) { this->out_stream = &stream; generate_from_model(model); this->out_stream = nullptr; } void BaseExpression::generate_from_model(Model & model) { if( out_stream ) { before_generate_from_model(); dump_additional_info(model); model.map_fields(); after_generate_from_model(); } } void BaseExpression::dump_additional_info(Model & model) { if( model.model_env && model.model_env->dump_mode ) { field(L"model_save_mode", model.save_mode, false, false, false, model.model_env); field(L"has_primary_key_set", model.has_primary_key_set, false, false, false, model.model_env); } } void BaseExpression::before_generate_from_model() { is_first_field = true; } void BaseExpression::after_generate_from_model() { } bool BaseExpression::can_field_be_generated(bool insertable, bool updatable, bool is_primary_key) { return true; } void BaseExpression::field_before() { if( !is_first_field ) { // put a separator between fields } } void BaseExpression::field_after() { is_first_field = false; } bool BaseExpression::is_long_field_name(const wchar_t * field_name) { bool is_long = false; while( *field_name != 0 ) { if( *field_name == '.' ) { is_long = true; break; } field_name += 1; } return is_long; } bool BaseExpression::is_long_field_name(const PT::TextStream & field_name) { PT::TextStream::const_iterator i = field_name.begin(); bool is_long = false; while( i != field_name.end() ) { if( *i == '.' ) { is_long = true; break; } ++i; } return is_long; } bool BaseExpression::is_long_table_name(const wchar_t * table_name) { return is_long_field_name(table_name); } bool BaseExpression::is_long_table_name(const PT::TextStream & table_name) { return is_long_field_name(table_name); } void BaseExpression::put_field_name(const wchar_t * field_name, ModelEnv * model_env) { if( is_long_field_name(field_name) ) put_long_field_name(field_name); else put_short_field_name(field_name, model_env); } const wchar_t * BaseExpression::put_long_part_field_name(const wchar_t * field_name) { while( *field_name != 0 && *field_name != '.' ) { esc(*field_name, *out_stream); field_name += 1; } return field_name; } void BaseExpression::put_long_field_name(const wchar_t * field_name) { before_first_part_long_field_name(); field_name = put_long_part_field_name(field_name); after_first_part_long_field_name(); if( *field_name == '.' ) { field_name += 1; (*out_stream) << '.'; before_second_part_long_field_name(); field_name = put_long_part_field_name(field_name); after_second_part_long_field_name(); } } void BaseExpression::put_short_field_name(const wchar_t * field_name, ModelEnv * model_env) { if( use_prefix && model_env ) { before_first_part_long_field_name(); esc(model_env->table_name_short, *out_stream); if( model_env->table_index > 1 ) { (*out_stream) << model_env->table_index; } after_first_part_long_field_name(); (*out_stream) << '.'; before_second_part_long_field_name(); esc(field_name, *out_stream); after_second_part_long_field_name(); } else { before_short_field_name(); esc(field_name, *out_stream); after_short_field_name(); } } void BaseExpression::save_foreign_key(const wchar_t * field_name, ModelEnv * model_env) { PT::TextStream str; PT::TextStream * old_out_stream = out_stream; out_stream = &str; put_field_name(field_name, model_env); out_stream = old_out_stream; if( model_env && model_env->finder_helper ) { model_env->finder_helper->foreign_keys.emplace_back(); std::string & key_str = model_env->finder_helper->foreign_keys.back(); str.to_string(key_str, false); } } void BaseExpression::before_short_field_name() { } void BaseExpression::after_short_field_name() { } void BaseExpression::before_first_part_long_field_name() { } void BaseExpression::after_first_part_long_field_name() { } void BaseExpression::before_second_part_long_field_name() { } void BaseExpression::after_second_part_long_field_name() { } void BaseExpression::before_field_value(const std::wstring &) { } void BaseExpression::before_field_value(const std::string &) { } void BaseExpression::after_field_value(const std::wstring &) { } void BaseExpression::after_field_value(const std::string &) { } void BaseExpression::before_field_value(const wchar_t *) { } void BaseExpression::after_field_value(const wchar_t *) { } void BaseExpression::before_field_value(const char *) { } void BaseExpression::after_field_value(const char *) { } void BaseExpression::before_field_value(const PT::Date &) { } void BaseExpression::after_field_value(const PT::Date &) { } void BaseExpression::put_name_value_separator() { (*out_stream) << ','; } void BaseExpression::esc(char val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(unsigned char val, PT::TextStream & stream) { esc(static_cast(val), stream); } void BaseExpression::esc(wchar_t val, PT::TextStream & stream) { char utf8_buf[10]; size_t utf8_len = PT::IntToUTF8((int)val, utf8_buf, sizeof(utf8_buf)); for(size_t a = 0 ; a < utf8_len ; ++a) { esc(utf8_buf[a], stream); } } void BaseExpression::esc(const std::wstring & val, PT::TextStream & stream) { char utf8_buf[10]; for(size_t i = 0 ; i < val.size() ; ++i) { size_t utf8_len = PT::IntToUTF8((int)val[i], utf8_buf, sizeof(utf8_buf)); for(size_t a = 0 ; a < utf8_len ; ++a) { esc(utf8_buf[a], stream); } } } void BaseExpression::esc(const wchar_t * val, PT::TextStream & stream) { char utf8_buf[10]; for(size_t i = 0 ; val[i] != 0 ; ++i) { size_t utf8_len = PT::IntToUTF8((int)val[i], utf8_buf, sizeof(utf8_buf)); for(size_t a = 0 ; a < utf8_len ; ++a) { esc(utf8_buf[a], stream); } } } void BaseExpression::esc(const std::string & val, PT::TextStream & stream) { for(size_t i = 0 ; i < val.size() ; ++i) { esc(val[i], stream); } } void BaseExpression::esc(const char * val, PT::TextStream & stream) { for(size_t i = 0 ; val[i] != 0 ; ++i) { esc(val[i], stream); } } void BaseExpression::esc(bool val, PT::TextStream & stream) { if( val ) stream << "true"; else stream << "false"; } void BaseExpression::esc(short val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(unsigned short val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(int val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(unsigned int val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(long val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(unsigned long val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(long long val, PT::TextStream & stream) { // not implemented in PT::TextStream yet //stream << val; } void BaseExpression::esc(unsigned long long val, PT::TextStream & stream) { //stream << val; } void BaseExpression::esc(float val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(double val, PT::TextStream & stream) { stream << val; } void BaseExpression::esc(long double val, PT::TextStream & stream) { // IMPLEMENT ME in PT::TextStream //stream << val; } void BaseExpression::esc(const PT::Date & date, PT::TextStream & stream) { stream << date; } void BaseExpression::esc(const PT::TextStream & val, PT::TextStream & stream) { PT::TextStream::const_iterator i = val.begin(); for(; i != val.end() ; ++i) { esc(*i, stream); } } void BaseExpression::put_type(char val, PT::TextStream & stream) { stream << "char"; } void BaseExpression::put_type(unsigned char val, PT::TextStream & stream) { stream << "unsigned char"; } void BaseExpression::put_type(const std::wstring & val, PT::TextStream & stream) { stream << "text"; } void BaseExpression::put_type(const wchar_t * val, PT::TextStream & stream) { stream << "text"; } void BaseExpression::put_type(const std::string & val, PT::TextStream & stream) { stream << "text"; } void BaseExpression::put_type(const char * val, PT::TextStream & stream) { stream << "text"; } void BaseExpression::put_type(bool val, PT::TextStream & stream) { stream << "boolean"; } void BaseExpression::put_type(short val, PT::TextStream & stream) { stream << "short integer"; } void BaseExpression::put_type(unsigned short val, PT::TextStream & stream) { stream << "unsigned short integer"; } void BaseExpression::put_type(int val, PT::TextStream & stream) { stream << "integer"; } void BaseExpression::put_type(unsigned int val, PT::TextStream & stream) { stream << "unsigned integer"; } void BaseExpression::put_type(long val, PT::TextStream & stream) { stream << "long integer"; } void BaseExpression::put_type(unsigned long val, PT::TextStream & stream) { stream << "unsigned long integer"; } void BaseExpression::put_type(long long val, PT::TextStream & stream) { stream << "very long integer"; } void BaseExpression::put_type(unsigned long long val, PT::TextStream & stream) { stream << "unsigned very long integer"; } void BaseExpression::put_type(float val, PT::TextStream & stream) { stream << "float"; } void BaseExpression::put_type(double val, PT::TextStream & stream) { stream << "double"; } void BaseExpression::put_type(long double val, PT::TextStream & stream) { stream << "long double"; } //void BaseExpression::put_type(void* val, PT::TextStream & stream) //{ //} void BaseExpression::put_type(const PT::Date & date, PT::TextStream & stream) { stream << "date"; } void BaseExpression::put_type(const Model & model, PT::TextStream & stream) { stream << "object"; } }