/* * This file is a part of morm * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * 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. * */ #include "expression.h" #include "model.h" namespace morm { Expression::Expression() { out_stream = nullptr; model = nullptr; json_escaper = nullptr; db_escaper = nullptr; } Expression::~Expression() { } void Expression::set_json_escaper(BaseEscaper & json_escaper) { this->json_escaper = &json_escaper; } void Expression::set_db_escaper(BaseEscaper & db_escaper) { this->db_escaper = &db_escaper; } void Expression::generate_from_model() { before_generate_from_model(); model->map_fields(); after_generate_from_model(); } void Expression::before_generate_from_model() { is_first_field = true; if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES ) { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_stream) << "{"; } } } void Expression::after_generate_from_model() { if( work_mode == MORM_WORK_MODE_MODEL_FIELDS_VALUES ) { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_stream) << "}"; } } } bool Expression::can_field_be_generated(bool insertable, bool updatable, bool is_primary_key) { if( output_type == MORM_OUTPUT_TYPE_DB_INSERT ) { return insertable; } else if( output_type == MORM_OUTPUT_TYPE_DB_UPDATE ) { return updatable; } else if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY ) { return is_primary_key; } else { return true; } } void Expression::field_before() { if( !is_first_field ) { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_stream) << ","; } else if( output_type == MORM_OUTPUT_TYPE_DB_INSERT || output_type == MORM_OUTPUT_TYPE_DB_UPDATE ) { (*out_stream) << ","; } else if( output_type == MORM_OUTPUT_TYPE_DB_PRIMARY_KEY ) { (*out_stream) << " AND "; } } } void Expression::field_after() { is_first_field = false; } //void Expression::field(const wchar_t * field_name, Model & field, bool insertable = true, bool updatable = true) //{ // // IMPLEMENT ME //} void Expression::put_field_name(const wchar_t * field_name) { before_field_name(); field_name_raw(field_name); after_field_name(); } void Expression::before_field_name() { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_stream) << "\""; } } void Expression::after_field_name() { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_stream) << "\""; } } void Expression::before_field_value_string() { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_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_type == MORM_DB_TYPE_POSTGRESQL ) { (*out_stream) << "E'"; } } } void Expression::after_field_value_string() { if( output_type == MORM_OUTPUT_TYPE_JSON ) { (*out_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_type == MORM_DB_TYPE_POSTGRESQL ) { (*out_stream) << "'"; } } } void Expression::before_field_value(const std::wstring &) { before_field_value_string(); } void Expression::before_field_value(const std::string &) { before_field_value_string(); } void Expression::after_field_value(const std::wstring &) { after_field_value_string(); } void Expression::after_field_value(const std::string &) { after_field_value_string(); } void Expression::field_name_raw(const wchar_t * field_name) { // IMPROVE ME // provide esc_field and esc_value methods esc(field_name, *out_stream); } void Expression::field_value_raw(const std::wstring & field_value) { // IMPROVE ME // provide esc_field and esc_value methods esc(field_value, *out_stream); } void Expression::field_value_raw(long field_value) { // may it should be moved to escaper? (*out_stream) << field_value; } void Expression::field_value_raw(int field_value) { // may it should be moved to escaper? (*out_stream) << field_value; } void Expression::to_json(PT::TextStream & stream, Model & model) { work_mode = MORM_WORK_MODE_MODEL_FIELDS_VALUES; output_type = MORM_OUTPUT_TYPE_JSON; out_stream = &stream; this->model = &model; generate_from_model(); } void Expression::insert(PT::TextStream & stream, Model & model, int db_type) { out_stream = &stream; output_type = MORM_OUTPUT_TYPE_DB_INSERT; this->db_type = db_type; this->model = &model; stream << "insert into "; this->model->table_name(stream); stream << " ("; work_mode = MORM_WORK_MODE_MODEL_FIELDS; generate_from_model(); stream << ") values ("; work_mode = MORM_WORK_MODE_MODEL_VALUES; generate_from_model(); stream << ")"; } void Expression::update(PT::TextStream & stream, Model & model, int db_type) { out_stream = &stream; this->db_type = db_type; this->model = &model; stream << "update "; this->model->table_name(stream); stream << " set ("; work_mode = MORM_WORK_MODE_MODEL_FIELDS; output_type = MORM_OUTPUT_TYPE_DB_UPDATE; generate_from_model(); stream << ") values ("; work_mode = MORM_WORK_MODE_MODEL_VALUES; output_type = MORM_OUTPUT_TYPE_DB_UPDATE; generate_from_model(); stream << ") where "; work_mode = MORM_WORK_MODE_MODEL_FIELDS_VALUES; output_type = MORM_OUTPUT_TYPE_DB_PRIMARY_KEY; generate_from_model(); } /* template 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; } */ } // namespace