From edcd67b3c960f4bf69160fe7ce098e70094f24a1 Mon Sep 17 00:00:00 2001 From: samuaz Date: Sun, 11 Jun 2023 02:42:56 -0300 Subject: [PATCH 1/8] wip --- .../data/sql/column/winter_data_sql_column.h | 6 + .../function/winter_data_sql_function_min.h | 20 ++-- .../sql/migration/winter_data_migration.tpp | 2 +- .../winter_data_sql_prepared_statement.h | 60 +++++----- .../winter_data_sql_repository_utils.h | 3 +- .../statement/clause/winter_data_sql_clause.h | 26 +---- .../clause/winter_data_sql_clause_and.h | 20 ++-- .../clause/winter_data_sql_clause_from.h | 17 ++- .../clause/winter_data_sql_clause_in.h | 19 ++-- .../clause/winter_data_sql_clause_in.tpp | 60 ++++++---- .../clause/winter_data_sql_clause_into.h | 15 +-- .../clause/winter_data_sql_clause_join.h | 21 ++-- .../clause/winter_data_sql_clause_not_in.h | 17 +-- .../clause/winter_data_sql_clause_not_in.tpp | 65 ++++++----- .../clause/winter_data_sql_clause_on.h | 25 +++-- .../clause/winter_data_sql_clause_or.h | 25 +++-- .../winter_data_sql_clause_parenthesis.h | 15 ++- .../clause/winter_data_sql_clause_predicate.h | 18 +-- .../clause/winter_data_sql_clause_set.h | 24 ++-- .../clause/winter_data_sql_clause_values.h | 24 ++-- .../clause/winter_data_sql_clause_where.h | 36 +++--- .../sql/statement/winter_data_sql_select.h | 7 +- .../statement/winter_data_sql_statement.tpp | 10 +- .../winter_data_sql_statement_values.h | 60 ++++++++++ .../transaction/winter_data_sql_transaction.h | 4 +- wintercpp/include/wintercpp/winter.h | 1 + .../sql/column/winter_data_sql_column.cpp | 4 + .../function/winter_data_sql_function_min.cpp | 51 ++++----- .../winter_data_sql_prepared_statement.cpp | 54 ++++----- .../clause/winter_data_sql_clause.cpp | 37 ------ .../clause/winter_data_sql_clause_and.cpp | 94 ++++++++-------- .../clause/winter_data_sql_clause_from.cpp | 71 ++++++------ .../clause/winter_data_sql_clause_into.cpp | 54 +++++---- .../clause/winter_data_sql_clause_join.cpp | 79 +++++++------ .../clause/winter_data_sql_clause_on.cpp | 93 ++++++++------- .../clause/winter_data_sql_clause_or.cpp | 80 +++++++------ .../winter_data_sql_clause_parenthesis.cpp | 56 +++++---- .../winter_data_sql_clause_predicate.cpp | 19 ++-- .../clause/winter_data_sql_clause_set.cpp | 40 ++----- .../clause/winter_data_sql_clause_values.cpp | 53 ++++----- .../clause/winter_data_sql_clause_where.cpp | 106 +++++++++--------- .../sql/statement/winter_data_sql_select.cpp | 27 +++-- .../test/winter_preparedStatement_test.cpp | 4 +- wintercpp/test/winter_sql_function_test.cpp | 4 +- .../winter_data_sql_mysql_result_row.h | 20 ++-- .../test/winter_data_sql_select_test.cpp | 1 - 46 files changed, 811 insertions(+), 736 deletions(-) create mode 100644 wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h delete mode 100644 wintercpp/src/data/sql/statement/clause/winter_data_sql_clause.cpp diff --git a/wintercpp/include/wintercpp/data/sql/column/winter_data_sql_column.h b/wintercpp/include/wintercpp/data/sql/column/winter_data_sql_column.h index 8c3c43b..550eca4 100644 --- a/wintercpp/include/wintercpp/data/sql/column/winter_data_sql_column.h +++ b/wintercpp/include/wintercpp/data/sql/column/winter_data_sql_column.h @@ -74,6 +74,12 @@ namespace winter::data::sql_impl { */ const std::string &name() const; + /** + * @brief returns the full name of the column example tableName.columnName + * @return std::string + */ + std::string FullName() const; + /** * @brief returns the datatype this column represents * @return const FieldType diff --git a/wintercpp/include/wintercpp/data/sql/function/winter_data_sql_function_min.h b/wintercpp/include/wintercpp/data/sql/function/winter_data_sql_function_min.h index 6443bc3..dd48abc 100644 --- a/wintercpp/include/wintercpp/data/sql/function/winter_data_sql_function_min.h +++ b/wintercpp/include/wintercpp/data/sql/function/winter_data_sql_function_min.h @@ -10,30 +10,36 @@ #include #include #include +#include #include #include -#include "wintercpp/data/sql/field/winter_data_sql_field_type.h" -#include "wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h" +#include +#include namespace winter::data::sql_impl { class Min : public virtual Clause { public: - explicit Min(StatementValues column); + explicit Min(const StatementValue &statement_value); virtual ~Min() = default; - PreparedStatement Prepare() override; + std::string Query() const override; + std::vector> Fields() const override; - std::string name() override; + //PreparedStatement Prepare() override; - FieldType fieldType() override; + std::string name() const; + + //FieldType fieldType() override; private: - const StatementValues column_; + const StatementValue statement_value_; const std::shared_ptr field_; const bool is_predicate_ = false; + const std::string query_template_ = "MIN($min) AS min_$columnName"; + const std::string query_param_ = "$min"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/migration/winter_data_migration.tpp b/wintercpp/include/wintercpp/data/sql/migration/winter_data_migration.tpp index f71967b..0c9ae9f 100644 --- a/wintercpp/include/wintercpp/data/sql/migration/winter_data_migration.tpp +++ b/wintercpp/include/wintercpp/data/sql/migration/winter_data_migration.tpp @@ -36,7 +36,7 @@ void DataBaseMigration::execute() { std::to_string(migration.HASH_256()))) >> transaction;*/ auto columnFound = Column(*migration_table_, "found", FieldType::kBoolean); - auto columns = std::vector {columnFound}; + auto columns = std::vector {columnFound}; auto response = Select(ss.str()) << columns >> transaction; auto resultRow = response.RequireSingleOrNullopt(); // resultRow->AddRow("name"); diff --git a/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h b/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h index 55d8e9f..1578e5e 100644 --- a/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h +++ b/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h @@ -6,28 +6,38 @@ #define WINTERCPP_DATA_SQL_PREPARED_STATEMENT_H #include +#include #include #include +#include +#include +#include #include #include #include #include #include - -#include "wintercpp/data/sql/field/winter_data_sql_field_type.h" -#include "wintercpp/exception/generic/winter_internal_exception.h" - namespace winter::data::sql_impl { - class IStatementValue { - public: - virtual std::string name() = 0; - virtual const std::string &query() const = 0; - virtual FieldType fieldType() = 0; - }; - - typedef std::variant> StatementValues; + /* class IStatementValue { + public: + virtual const std::string &query() const = 0; + virtual std::string name() { + throw exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + ("invalid call to name function on IStatementValue")); + }; + virtual FieldType fieldType() { + throw exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + ("invalid call to fieldtype function on IStatementValue")); + }; + }; */ class PreparedStatement { public: @@ -37,21 +47,21 @@ namespace winter::data::sql_impl { std::string statement_template, std::string id = winter::random::uuid()); - PreparedStatement(const StatementType &statement_type, - std::string statement_template, - std::vector columns_, - std::string id = winter::random::uuid()); + PreparedStatement(const StatementType &statement_type, + std::string statement_template, + std::vector fields, + std::string id = winter::random::uuid()); PreparedStatement( const StatementType &statement_type, std::string query, - std::vector> values, + std::vector> fields, std::string id = winter::random::uuid()); PreparedStatement( const StatementType &statement_type, std::string statement_template, - const std::shared_ptr &value, + const std::shared_ptr &field, std::string id = winter::random::uuid()); const std::string &id() const; @@ -72,7 +82,7 @@ namespace winter::data::sql_impl { template void AddAll(const T &fields) { - values_.insert(values_.end(), fields.begin(), fields.end()); + fields_.insert(fields_.end(), fields.begin(), fields.end()); } const std::string &statement_template() const; @@ -103,13 +113,13 @@ namespace winter::data::sql_impl { int SearchFieldIndex(const std::string &name); - const std::vector &columns() const; + const std::vector &statementValues() const; - void columns(std::vector columns); + void statementValues(std::vector statement_value); - PreparedStatement &AddColumn(const StatementValues &column); + PreparedStatement &AddStatementValue(const StatementValue &statement_value); - PreparedStatement &AddColumn(const std::vector &columns); + PreparedStatement &AddStatementValue(const std::vector &statement_values); virtual ~PreparedStatement() = default; @@ -118,8 +128,8 @@ namespace winter::data::sql_impl { StatementType type_ {}; // std::shared_ptr _entityId; std::string statement_template_; - std::vector columns_; - std::vector> values_; + std::vector statement_values_; + std::vector> fields_; std::vector>::iterator FindValue(const std::string &name); }; diff --git a/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h b/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h index c65a318..5b353ca 100644 --- a/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h +++ b/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h @@ -13,14 +13,13 @@ #include #include #include +#include #include #include #include #include -#include "wintercpp/data/sql/table/winter_data_sql_uuid_table.h" - namespace winter::data::sql_impl { using namespace winter::exception; diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause.h index 18e4195..75bab62 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause.h @@ -8,32 +8,16 @@ #include #include +#include namespace winter::data::sql_impl { - class Clause : public virtual IStatementValue { + class Clause { public: - Clause &operator<<(const std::string &rvalue); - - const std::string &query() const override; - - std::string param(); - - std::string statement_template(); - - virtual PreparedStatement Prepare() = 0; - - protected: - Clause &BuildQuery(); - Clause(std::string statement_template, std::string param); - void set_statement_template(const std::string &statement_template); - - private: - std::string statement_template_ {}; - const std::string param_ {}; - std::string query_ {}; + virtual std::string Query() const = 0; + virtual std::vector> Fields() const = 0; }; } // namespace winter::data::sql_impl -#endif // WINTERCPP_WINTER_DATA_SQL_CLAUSE_H +#endif // WINTERCPP_WINTER_DATA_SQL_CLAUSE_H \ No newline at end of file diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h index 25244e1..aca6542 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h @@ -13,28 +13,28 @@ #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { class And : public virtual Clause { public: explicit And(const Predicate &predicate); - explicit And(Column column); - - explicit And(Column column, Condition); + explicit And(StatementValue statement_value); - std::string name() override; + explicit And(StatementValue statement_value, Condition); - FieldType fieldType() override; + std::string Query() const override; - PreparedStatement Prepare() override; + std::vector> Fields() const override; template static Predicate MakePredicate(const Column &column, Condition condition, T value) { return Predicate(column, - std::make_shared >( + std::make_shared>( column->name(), value), condition); } @@ -45,16 +45,18 @@ namespace winter::data::sql_impl { T value, const std::string &custom_value) { return Predicate(column, - std::make_shared >( + std::make_shared>( column->name(), value, custom_value), condition); } private: - const Column column_; + const StatementValue statement_value_; const std::shared_ptr field_; const Condition condition_ {}; const bool is_predicate_ = false; + const std::string query_template_ = "AND $and"; + const std::string query_param_ = "$and"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_from.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_from.h index 8a2eb99..cff78d5 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_from.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_from.h @@ -11,22 +11,21 @@ #include #include -#include "wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" namespace winter::data::sql_impl { class From : public virtual Clause { public: - explicit From(std::vector> tables); - explicit From(const std::shared_ptr &table); - PreparedStatement Prepare() override; - std::string name() override; - FieldType fieldType() override; + explicit From(const std::vector& tables); + explicit From(const StatementValue& statement_value); + std::string Query() const override; + std::vector> Fields() const override; private: - std::vector> tables_; - std::vector columns_; - void GenerateStatement(); + std::vector statement_values_; + const std::string query_template_ = "FROM $tables"; + const std::string query_param_ = "$tables"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h index 9aed42a..2b4a6bd 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -22,17 +23,17 @@ namespace winter::data::sql_impl { template class In : public virtual Clause { public: - explicit In(std::vector values); - explicit In(const winter::data::sql_impl::Select &select); - PreparedStatement Prepare() override; - - std::string name() override; - FieldType fieldType() override; + explicit In(const std::vector &values); + explicit In(const StatementValue &statement_value); + std::string Query() const override; + std::vector> Fields() const override; private: - std::vector values_; - Select select_; - bool has_clause_ = false; + const std::vector values_; + const StatementValue statement_value_; + bool has_clause_ = false; + const std::string query_template_ = "IN ($IN_VALUE)"; + const std::string query_param_ = "$IN_VALUE"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp index 6d709d3..f4c6bc5 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp @@ -1,35 +1,49 @@ namespace winter::data::sql_impl { template - In::In(std::vector values) : - Clause("IN ($IN_VALUE)", "$IN_VALUE"), values_(std::move(values)) {} + In::In(const std::vector &values) : + values_(values) {} template - In::In(const Select &select) : - select_(select), has_clause_(true) {} + In::In(const StatementValue &statement_value) : + statement_value_(statement_value), has_clause_(true) {} template - PreparedStatement In::Prepare() { + std::vector> In::Fields() const { + std::vector> fields; + for (const auto &value : values_) { + fields.push_back( + std::make_shared>(value)); + } + return fields; + }; + + template + std::string In::Query() const { if (has_clause_) { - return Prepare( - StatementType::kClause, - winter::util::string::replace_value( - statement_template(), - param(), - select_.prepared_statement().statement_template()), - select_.prepared_statement().values()); - } else { - std::vector > fields; - for (const auto &value : values_) { - fields.push_back( - std::make_shared >(value)); + std::string subQuery; + auto &statement_value = statement_value_; + auto clause_ptr = std::get_if>(&statement_value); + if (clause_ptr) { + subQuery = clause_ptr->get()->Query(); + } else { + std::string typeName = StatementValueType(statement_value.index()); + std::stringstream ss; + ss << "invalid statement_value " << typeName << " not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + ss.str()); } - return Prepare(StatementType::kClause, - winter::util::string::replace_value( - statement_template(), - param(), - CommaSeparatedPlaceHolder(values_.size())), - fields); + return winter::util::string::replace_value( + query_template_, + query_param_, + std::move(subQuery)); } + return winter::util::string::replace_value( + query_template_, + query_param_, + CommaSeparatedPlaceHolder(values_.size())); } } // namespace winter::data::sql_impl \ No newline at end of file diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h index 6fb0b39..f65ca36 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h @@ -8,18 +8,19 @@ #include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { class Into : public virtual Clause { public: - explicit Into(std::shared_ptr
table); - PreparedStatement Prepare() override; - - std::string name() override; - FieldType fieldType() override; + explicit Into(const StatementValue& table); + std::string Query() const override; + std::vector> Fields() const override; private: - std::shared_ptr
table_; - void GenerateStatement(); + const StatementValue statement_value_; + const std::string query_template_ = "INTO $table"; + const std::string query_param_ = "$table"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h index d8afe68..4eb4efa 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h @@ -8,6 +8,8 @@ #include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { enum class JoinType : int { DEFAULT = 0, @@ -18,18 +20,17 @@ namespace winter::data::sql_impl { class Join : public virtual Clause { public: - explicit Join(std::shared_ptr
table, JoinType type); - explicit Join(std::shared_ptr
table); - PreparedStatement Prepare() override; - - std::string name() override; - FieldType fieldType() override; + explicit Join(const StatementValue&, JoinType type); + explicit Join(const StatementValue& statement_value); + std::string Query() const override; + std::vector> Fields() const override; private: - std::shared_ptr
table_; - JoinType type_; - void GenerateStatement(); - std::string GenerateType(); + const StatementValue statement_value_; + const JoinType type_; + std::string GenerateType() const; + const std::string query_template_ = "$type JOIN $table"; + const std::string query_param_ = "$table"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h index fb088c9..3f2a989 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h @@ -22,16 +22,17 @@ namespace winter::data::sql_impl { template class NotIn : public virtual Clause { public: - explicit NotIn(std::vector values); - explicit NotIn(const winter::data::sql_impl::Select &select); - PreparedStatement Prepare() override; - std::string name() override; - FieldType fieldType() override; + explicit NotIn(const std::vector &values); + explicit NotIn(const StatementValue &statement_value); + std::string Query() const override; + std::vector> Fields() const override; private: - std::vector values_; - Select select_; - bool has_clause = false; + const std::vector values_; + const StatementValue statement_value_; + bool has_clause_ = false; + const std::string query_template_ = "NOT IN ($NOT_IN_VALUE)"; + const std::string query_param_ = "$NOT_IN_VALUE"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.tpp b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.tpp index 9fd055c..292ade6 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.tpp +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.tpp @@ -1,38 +1,49 @@ namespace winter::data::sql_impl { template - NotIn::NotIn(std::vector values) : - Clause("NOT IN ($NOT_IN_VALUE)", "$NOT_IN_VALUE"), - values_(std::move(values)) {} + NotIn::NotIn(const std::vector &values) : + values_(values) {} template - NotIn::NotIn(const Select &select) : - select_(select), has_clause(true) {} + NotIn::NotIn(const StatementValue &statement_value) : + statement_value_(statement_value), has_clause_(true) {} template - PreparedStatement NotIn::Prepare() { - if (has_clause) { - return Prepare( - StatementType::kClause, - winter::util::string::replace_value( - statement_template(), - param(), - select_.prepared_statement().statement_template()), - select_.prepared_statement().values()); - } else { - std::vector > fields; - for (const auto &value : values_) { - fields.push_back( - std::make_shared >(value)); + std::vector> NotIn::Fields() const { + std::vector> fields; + for (const auto &value : values_) { + fields.push_back( + std::make_shared>(value)); + } + return fields; + }; + + template + std::string NotIn::Query() const { + if (has_clause_) { + std::string subQuery; + auto &statement_value = statement_value_; + auto clause_ptr = std::get_if>(&statement_value); + if (clause_ptr) { + subQuery = clause_ptr->get()->Query(); + } else { + std::string typeName = StatementValueType(statement_value.index()); + std::stringstream ss; + ss << "invalid statement_value " << typeName << " not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + ss.str()); } - return Prepare( - StatementType::kClause, - winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::CommaSeparatedPlaceHolder( - values_.size())), - fields); + return winter::util::string::replace_value( + query_template_, + query_param_, + std::move(subQuery)); } + return winter::util::string::replace_value( + query_template_, + query_param_, + CommaSeparatedPlaceHolder(values_.size())); } } // namespace winter::data::sql_impl \ No newline at end of file diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_on.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_on.h index 3de849e..f04a493 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_on.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_on.h @@ -10,19 +10,30 @@ #include #include +#include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { class On : public virtual Clause { public: - explicit On(const Column &l_column, - Condition condition, - const Column &r_column); - explicit On(const Column &l_column, Condition condition); - PreparedStatement Prepare() override; - std::string name() override; - FieldType fieldType() override; + explicit On(const StatementValue &l_statement_value, + Condition condition, + const StatementValue &r_statement_value); + explicit On(const StatementValue &l_statement_value, Condition condition); + std::string Query() const override; + std::vector> Fields() const override; + + private: + const StatementValue l_statement_value_; + const std::optional r_statement_value_; + const Condition condition_; + const std::string query_template_ = "ON $lcolumn $condition $rcolumn"; + const std::string query_param_l = "$lcolumn"; + const std::string query_param_r = "$rcolumn"; + const std::string query_param_condition = "$condition"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h index 70e7d21..fe5c464 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h @@ -14,26 +14,27 @@ #include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { class Or : public virtual Clause { public: explicit Or(const Predicate &predicate); - explicit Or(Column column); + explicit Or(const StatementValue &statement_value); - explicit Or(Column column, Condition); - std::string name() override; - FieldType fieldType() override; + explicit Or(const StatementValue &statement_value, Condition); - PreparedStatement Prepare() override; + std::string Query() const override; + std::vector> Fields() const override; template static Predicate MakePredicate(const Column &column, Condition condition, T value) { return Predicate(column, - std::make_shared >( + std::make_shared>( column->name(), value), condition); } @@ -44,16 +45,18 @@ namespace winter::data::sql_impl { T value, const std::string &customValue) { return Predicate(column, - std::make_shared >( + std::make_shared>( column->name(), value, customValue), condition); } private: - Column column_; - std::shared_ptr field_; - Condition condition_ {}; - bool is_predicate_ = false; + const StatementValue statement_value_; + const std::shared_ptr field_; + Condition condition_ {}; + bool is_predicate_ = false; + const std::string query_template_ = "OR $or"; + const std::string query_param_ = "$or"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_parenthesis.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_parenthesis.h index 67af194..a0cf681 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_parenthesis.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_parenthesis.h @@ -10,15 +10,20 @@ #include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { class Parenthesis : public virtual Clause { public: - explicit Parenthesis(Clause *clause); - explicit Parenthesis(const std::string &clause); - PreparedStatement Prepare() override; - std::string name() override; - FieldType fieldType() override; + explicit Parenthesis(const StatementValue &clause); + std::string Query() const override; + std::vector> Fields() const override; + + private: + const StatementValue statement_value_; + const std::string query_template_ = "$clause"; + const std::string query_param_ = "$clause"; }; template diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h index 3913b47..b228c17 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h @@ -17,18 +17,19 @@ #include #include #include +#include namespace winter::data::sql_impl { class Predicate { public: Predicate( - Column column, - std::shared_ptr< - winter::data::sql_impl::AbstractPreparedStatementField> field, - Condition conditionOperator); + const StatementValue& statement_value, + const std::shared_ptr< + winter::data::sql_impl::AbstractPreparedStatementField>& field, + Condition conditionOperator); - const Column& column() const; + const StatementValue& statementValue() const; const std::shared_ptr< winter::data::sql_impl::AbstractPreparedStatementField>& @@ -37,10 +38,9 @@ namespace winter::data::sql_impl { Condition condition() const; private: - Column column_; - std::shared_ptr - field_; - winter::data::sql_impl::Condition condition_ {}; + const StatementValue statement_value_; + const std::shared_ptr field_; + const winter::data::sql_impl::Condition condition_ {}; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h index c9ef6a7..0e220c8 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h @@ -15,30 +15,28 @@ namespace winter::data::sql_impl { class Set : public virtual Clause { public: - explicit Set( - std::vector > - fields); + explicit Set(const std::vector> &fields); - PreparedStatement Prepare() override; - std::string name() override; - FieldType fieldType() override; + std::string Query() const override; + std::vector> Fields() const override; template - static std::shared_ptr > Add( - const Column &column, T value) { - return std::make_shared >(column->name(), - value); + static std::shared_ptr> Add(const Column &column, T value) { + return std::make_shared>(column->name(), + value); } template - static std::shared_ptr > Add( + static std::shared_ptr> Add( const Column &column, T value, const std::string &custom_value_) { - return std::make_shared >( + return std::make_shared>( column->name(), value, custom_value_); } private: - std::vector > fields_; + std::vector> fields_; + const std::string query_template_ = "SET $fields"; + const std::string query_param_ = "$fields"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h index 8a88f02..cdcd114 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h @@ -16,30 +16,30 @@ namespace winter::data::sql_impl { class Values : public virtual Clause { public: - explicit Values( - std::vector > - fields); + explicit Values(const std::vector> &fields); - PreparedStatement Prepare() override; - std::string name() override; - FieldType fieldType() override; + std::string Query() const override; + std::vector> Fields() const override; template - static std::shared_ptr > Add( + static std::shared_ptr> Add( const Column &column, T value) { - return std::make_shared >(column->name(), - value); + return std::make_shared>(column->name(), + value); } template - static std::shared_ptr > Add( + static std::shared_ptr> Add( const Column &column, T value, const std::string &custom_value) { - return std::make_shared >( + return std::make_shared>( column->name(), value, custom_value); } private: - std::vector > _fields; + std::vector> fields_; + const std::string query_template_ = "($columns) VALUES ($set_values)"; + const std::string query_param_columns_ = "$columns"; + const std::string query_param_values_ = "$set_values"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h index f971030..d836d0d 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h @@ -2,8 +2,8 @@ // Created by Samuel Azcona on 21/05/2020. // -#ifndef WINTER_DATA_SQL_CLAUSE_WHERE -#define WINTER_DATA_SQL_CLAUSE_WHERE +#ifndef WINTER_DATA_SQL_CLAUSE_WHERE2 +#define WINTER_DATA_SQL_CLAUSE_WHERE2 #include #include @@ -12,28 +12,31 @@ #include #include +#include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + namespace winter::data::sql_impl { class Where : public virtual Clause { public: explicit Where(const Predicate &predicate); - explicit Where(Column column); + explicit Where(StatementValue statement_value); + + explicit Where(StatementValue statement_value, winter::data::sql_impl::Condition); - explicit Where(Column column, winter::data::sql_impl::Condition); - std::string name() override; - FieldType fieldType() override; + std::string Query() const override; - PreparedStatement Prepare() override; + std::vector> Fields() const override; template static Predicate make_predicate(const Column &column, Condition condition, T value) { return Predicate(column, - std::make_shared >( + std::make_shared>( column->name(), value), condition); } @@ -44,20 +47,19 @@ namespace winter::data::sql_impl { T value, const std::string &custom_value) { return Predicate(column, - std::make_shared >( + std::make_shared>( column->name(), value, custom_value), condition); } private: - const Column column_; - const std::shared_ptr< - winter::data::sql_impl::AbstractPreparedStatementField> - field_; - const winter::data::sql_impl::Condition condition_ {}; - const bool _is_predicate = false; + const StatementValue statement_value_; + const std::shared_ptr field_; + const winter::data::sql_impl::Condition condition_ {}; + const bool _is_predicate = false; + const std::string query_template_ = "WHERE $where"; + const std::string query_param_ = "$where"; }; - } // namespace winter::data::sql_impl -#endif /* WINTER_DATA_SQL_CLAUSE_WHERE */ +#endif /* WINTER_DATA_SQL_CLAUSE_WHERE2 */ diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_select.h b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_select.h index 433dfa1..f4b7ebc 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_select.h +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_select.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -20,11 +21,11 @@ namespace winter::data::sql_impl { public: Select(); - explicit Select(std::vector columns); + explicit Select(std::vector statement_value); explicit Select(const std::string &query); - Select &operator<<(std::vector columns); + Select &operator<<(std::vector statement_value); using Statement::operator<<; @@ -37,7 +38,7 @@ namespace winter::data::sql_impl { private: using Statement::type_; - std::vector columns_; + std::vector value_; // std::vector > tables_; void writeColumns(); diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp index d28eccd..7649d10 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp @@ -120,11 +120,11 @@ namespace winter::data::sql_impl { template template Children &Statement::AddClause(CLAUSE clause) { - auto preparedStatement = clause.Prepare(); - statement_template_.append(" ").append(preparedStatement.statement_template()); - prepared_statement_->AddAll(preparedStatement.values()); - if (prepared_statement_->columns().empty()) { - prepared_statement_->AddColumn(preparedStatement.columns()); + statement_template_.append(" ").append(clause.Query()); + prepared_statement_->AddAll(clause.Fields()); + if (prepared_statement_->statementValues().empty()) { + // FIXME + //prepared_statement_->AddStatementValue(preparedStatement.columns()); } return This(); } diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h new file mode 100644 index 0000000..c106e02 --- /dev/null +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h @@ -0,0 +1,60 @@ +// +// Created by Samuel Azcona on 14/03/2020. +// + +#ifndef WINTERCPP_WINTER_DATA_SQL_STATEMENT_VALUES +#define WINTERCPP_WINTER_DATA_SQL_STATEMENT_VALUES + +#include +#include + +#include +#include +#include + +namespace winter::data::sql_impl { + + class IStatement; + class Clause; + class Column; + class Table; + + typedef std::variant, Table, std::shared_ptr
, std::shared_ptr, std::shared_ptr> StatementValue; + + inline bool IsColumn(const StatementValue& statement_value) { + return std::holds_alternative>(statement_value) || std::holds_alternative(statement_value); + } + + inline bool IsTable(const StatementValue& statement_value) { + return std::holds_alternative>(statement_value) || std::holds_alternative
(statement_value); + } + + inline bool IsStatement(const StatementValue& statement_value) { + return std::holds_alternative>(statement_value); + } + + inline bool IsClause(const StatementValue& statement_value) { + return std::holds_alternative>(statement_value); + } + + inline std::string StatementValueType(int index) { + switch (index) { + case 0: + return "Column"; + case 1: + return "std::shared_ptr"; + case 2: + return "Table"; + case 3: + return "std::shared_ptr
"; + case 4: + return "std::shared_ptr"; + case 5: + return "std::shared_ptr operations_status_; TTransactionImpl &This(); - //void status(const ResponseStatus &status); + // void status(const ResponseStatus &status); }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/winter.h b/wintercpp/include/wintercpp/winter.h index db348b8..bf003f7 100644 --- a/wintercpp/include/wintercpp/winter.h +++ b/wintercpp/include/wintercpp/winter.h @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/wintercpp/src/data/sql/column/winter_data_sql_column.cpp b/wintercpp/src/data/sql/column/winter_data_sql_column.cpp index bb31e73..ae9914b 100644 --- a/wintercpp/src/data/sql/column/winter_data_sql_column.cpp +++ b/wintercpp/src/data/sql/column/winter_data_sql_column.cpp @@ -52,6 +52,10 @@ const std::string &Column::TableName() const { return table_.name(); } +std::string Column::FullName() const { + return table_.name() + "." + name(); +} + bool Column::operator==(const Column &column) const { return this->TableName() == column.TableName() && this->name_ == column.name_; } diff --git a/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp b/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp index 69e71d0..08e700b 100644 --- a/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp +++ b/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp @@ -3,7 +3,10 @@ // #include +#include #include +#include +#include #include #include @@ -11,51 +14,49 @@ #include "wintercpp/data/sql/column/winter_data_sql_column.h" #include "wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" using namespace winter::util::string; -winter::data::sql_impl::Min::Min(StatementValues column) : - Clause("MIN($min) AS min_$columnName", "$min"), - column_(std::move(column)) { - Prepare(); -} +winter::data::sql_impl::Min::Min(const StatementValue& statement_value) : statement_value_(statement_value) {} -std::string winter::data::sql_impl::Min::Min::name() { + std::string winter::data::sql_impl::Min::Min::name() const { std::ostringstream builder; - if (auto columnValue = std::get_if(&column_)) { + if (auto columnValue = std::get_if(&statement_value_)) { builder << columnValue->TableName() << "_" << columnValue->name(); - } else if (auto clauseValue = std::get_if>(&column_)) { - builder << clauseValue->get()->query(); + } else if (auto clauseValue = std::get_if>(&statement_value_)) { + builder << clauseValue->get()->Query(); + } else if (auto statementValue = std::get_if>(&statement_value_)) { + builder << statementValue->get()->prepared_statement().statement_template(); } std::string name = "min_$columnName"; return replace_value(name, "$columnName", builder.str()); }; -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Min::Prepare() { +std::vector> winter::data::sql_impl::Min::Fields() const { + return {}; +} + +std::string +winter::data::sql_impl::Min::Query() const { std::ostringstream builder; std::ostringstream builderAsName; - if (auto columnValue = std::get_if(&column_)) { + if (auto columnValue = std::get_if(&statement_value_)) { builder << columnValue->TableName() << Dot() << columnValue->name(); builderAsName << columnValue->TableName() << "_" << columnValue->name(); - } else if (auto clauseValue = std::get_if>(&column_)) { - builder << clauseValue->get()->query(); + } else if (auto clauseValue = std::get_if>(&statement_value_)) { + builder << clauseValue->get()->Query(); } - std::string minFunString = replace_value(statement_template(), param(), builder.str()); - BuildQuery() << replace_value(minFunString, "min_$columnName", name()); - - - return PreparedStatement{ - StatementType::KFunction, - query()}; + std::string minFunString = replace_value(query_template_, query_param_, builder.str()); + return replace_value(minFunString, "min_$columnName", name()); } -winter::data::sql_impl::FieldType winter::data::sql_impl::Min::fieldType() { - if (auto columnValue = std::get_if(&column_)) { +/* winter::data::sql_impl::FieldType winter::data::sql_impl::Min::fieldType() { + if (auto columnValue = std::get_if(&statement_value_)) { return columnValue->type(); - } else if (auto clauseValue = std::get_if>(&column_)) { + } else if (auto clauseValue = std::get_if>(&statement_value_)) { return clauseValue->get()->fieldType(); } else { throw exception::WinterInternalException::Create( @@ -64,4 +65,4 @@ winter::data::sql_impl::FieldType winter::data::sql_impl::Min::fieldType() { __LINE__, ("invalid call to fieldtype function on clause")); } -} +} */ diff --git a/wintercpp/src/data/sql/preparedstatement/winter_data_sql_prepared_statement.cpp b/wintercpp/src/data/sql/preparedstatement/winter_data_sql_prepared_statement.cpp index 385cbcb..75b6897 100644 --- a/wintercpp/src/data/sql/preparedstatement/winter_data_sql_prepared_statement.cpp +++ b/wintercpp/src/data/sql/preparedstatement/winter_data_sql_prepared_statement.cpp @@ -18,13 +18,13 @@ PreparedStatement::PreparedStatement(const StatementType &statement_type, id_(std::move(id)), type_(statement_type), statement_template_(std::move(statement_template)) {} -PreparedStatement::PreparedStatement(const StatementType &statement_type, - std::string statement_template, - std::vector columns, - std::string id) : +PreparedStatement::PreparedStatement(const StatementType &statement_type, + std::string statement_template, + std::vector columns, + std::string id) : id_(std::move(id)), type_(statement_type), statement_template_(std::move(statement_template)), - columns_(std::move(columns)) {} + statement_values_(std::move(columns)) {} PreparedStatement::PreparedStatement( const StatementType &statement_type, @@ -33,7 +33,7 @@ PreparedStatement::PreparedStatement( std::string id) : id_(std::move(id)), type_(statement_type), statement_template_(std::move(query)), - values_(std::move(values)) {} + fields_(std::move(values)) {} PreparedStatement::PreparedStatement( const StatementType &statement_type, @@ -42,7 +42,7 @@ PreparedStatement::PreparedStatement( std::string id) : id_(std::move(id)), type_(statement_type), statement_template_(std::move(statement_template)) { - values_.push_back(value); + fields_.push_back(value); } void PreparedStatement::set_id(const std::string &id) { @@ -51,13 +51,13 @@ void PreparedStatement::set_id(const std::string &id) { PreparedStatement &PreparedStatement::AddValue( AbstractPreparedStatementField *field) { - values_.push_back(std::shared_ptr(field)); + fields_.push_back(std::shared_ptr(field)); return *this; } PreparedStatement &PreparedStatement::AddValue( const std::shared_ptr &field) { - values_.push_back(field); + fields_.push_back(field); return *this; } @@ -72,12 +72,12 @@ void PreparedStatement::set_statement_template( const std::vector > &PreparedStatement::values() const { - return values_; + return fields_; } void PreparedStatement::set_values( const std::vector > &values) { - values_ = values; + fields_ = values; } const StatementType &PreparedStatement::type() const { @@ -126,8 +126,8 @@ const AbstractPreparedStatementField &Prepare::entityId() const { std::vector >::iterator PreparedStatement::FindValue(const std::string &name) { return std::find_if( - values_.begin(), - values_.end(), + fields_.begin(), + fields_.end(), [&name](const std::shared_ptr &obj) { return obj->name() == name; }); @@ -136,7 +136,7 @@ PreparedStatement::FindValue(const std::string &name) { const AbstractPreparedStatementField &PreparedStatement::FindByName( const std::string &name) { auto it = FindValue(name); - if (it != values_.end()) { return **it; } + if (it != fields_.end()) { return **it; } throw WinterInternalException::Create( __FILE__, @@ -148,7 +148,7 @@ const AbstractPreparedStatementField &PreparedStatement::FindByName( std::shared_ptr PreparedStatement::FindByField( const string &name) { auto it = FindValue(name); - if (it != values_.end()) { return *it; } + if (it != fields_.end()) { return *it; } throw WinterInternalException::Create( __FILE__, __FUNCTION__, @@ -157,14 +157,14 @@ std::shared_ptr PreparedStatement::FindByField( } bool PreparedStatement::FieldIsPresent(const std::string &name) { - return FindValue(name) != values_.end(); + return FindValue(name) != fields_.end(); } int PreparedStatement::SearchFieldIndex(const std::string &name) { auto it = FindValue(name); - if (it != values_.end()) { - auto index = std::distance(values_.begin(), it); + if (it != fields_.end()) { + auto index = std::distance(fields_.begin(), it); return index; } @@ -175,21 +175,21 @@ int PreparedStatement::SearchFieldIndex(const std::string &name) { ("preparedstatement field not found " + name)); } -const std::vector &PreparedStatement::columns() const { - return columns_; +const std::vector &PreparedStatement::statementValues() const { + return statement_values_; } -void PreparedStatement::columns(std::vector columns) { - columns_ = std::move(columns); +void PreparedStatement::statementValues(std::vector statement_values) { + statement_values_ = std::move(statement_values); } -PreparedStatement &PreparedStatement::AddColumn(const StatementValues &column) { - columns_.push_back(column); +PreparedStatement &PreparedStatement::AddStatementValue(const StatementValue &statement_value) { + statement_values_.push_back(statement_value); return *this; } -PreparedStatement &PreparedStatement::AddColumn( - const std::vector &columns) { - for (const StatementValues &col : columns) { columns_.push_back(col); } +PreparedStatement &PreparedStatement::AddStatementValue( + const std::vector &statement_values) { + for (const StatementValue &col : statement_values) { statement_values_.push_back(col); } return *this; } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause.cpp deleted file mode 100644 index 4002821..0000000 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Created by Samuel Azcona on 23/05/2020. -// - -#include - -winter::data::sql_impl::Clause::Clause(std::string statement_template, - std::string param) : - statement_template_(std::move(statement_template)), - param_(std::move(param)) {} - -const std::string &winter::data::sql_impl::Clause::query() const { - return query_; -} - -winter::data::sql_impl::Clause &winter::data::sql_impl::Clause::operator<<( - const std::string &rvalue) { - query_ += rvalue; - return *this; -} - -winter::data::sql_impl::Clause &winter::data::sql_impl::Clause::BuildQuery() { - return *this; -} - -std::string winter::data::sql_impl::Clause::param() { - return param_; -} - -std::string winter::data::sql_impl::Clause::statement_template() { - return statement_template_; -} - -void winter::data::sql_impl::Clause::set_statement_template( - const std::string &statement_template) { - statement_template_ = statement_template; -} diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp index 69f9b6e..1173338 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp @@ -4,67 +4,71 @@ #include #include +#include +#include #include +#include + +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + using namespace winter::util::string; winter::data::sql_impl::And::And(const Predicate &predicate) : - Clause("AND $and", "$and"), column_(predicate.column()), - field_(predicate.field()), condition_(predicate.condition()), + statement_value_(predicate.statementValue()), + field_(predicate.field()), + condition_(predicate.condition()), is_predicate_(true) {} -winter::data::sql_impl::And::And(Column column) : - Clause("AND $and", "$and"), column_(std::move(column)), +winter::data::sql_impl::And::And(StatementValue statement_value) : + statement_value_(std::move(statement_value)), condition_(winter::data::sql_impl::Condition::NONE) {} -winter::data::sql_impl::And::And(Column column, +winter::data::sql_impl::And::And(StatementValue statement_value, winter::data::sql_impl::Condition condition) : - Clause("AND $and", "$and"), - column_(std::move(column)), condition_(condition) {} + statement_value_(std::move(statement_value)), + condition_(condition) {} -std::string winter::data::sql_impl::And::And::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; - -winter::data::sql_impl::FieldType winter::data::sql_impl::And::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); +std::vector> winter::data::sql_impl::And::And::Fields() const { + std::vector> fields; + fields.push_back(field_); + return fields; } -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::And::Prepare() { +std::string +winter::data::sql_impl::And::Query() const { std::ostringstream builder; - if (is_predicate_) { - if (field_->IsCustomValue()) { - builder << column_->TableName() << Dot() << column_->name() - << Space() << condition(condition_) << Space() - << field_->custom_value(); - } else { - builder << column_->TableName() << Dot() << column_->name() - << Space() << condition(condition_) << Space() - << PlaceHolder(); + + if (auto columnValue = std::get_if>(&statement_value_)) { + if (is_predicate_) { + if (field_->IsCustomValue()) { + builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + << Space() << condition(condition_) << Space() + << field_->custom_value(); + } else { + builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + << Space() << condition(condition_) << Space() + << PlaceHolder(); + } + return replace_value(query_template_, query_param_, builder.str()); } - BuildQuery() << builder.str(); - return PreparedStatement( - StatementType::kClause, - replace_value(statement_template(), param(), query()), - field_); + + builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + << ((condition_ != Condition::NONE) + ? Space() + condition(condition_) + : ""); + return replace_value(query_template_, query_param_, builder.str()); + } else if (auto clauseValue = std::get_if>(&statement_value_)) { + builder << clauseValue->get()->Query(); + return replace_value(query_template_, query_param_, builder.str()); } - builder << column_->TableName() << Dot() << column_->name() - << ((condition_ != Condition::NONE) - ? Space() + condition(condition_) - : ""); + std::string typeName = StatementValueType(statement_value_.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; - BuildQuery() << builder.str(); - return PreparedStatement( - StatementType::kClause, - replace_value(statement_template(), param(), query())); + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp index cecf69b..007205f 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp @@ -6,52 +6,49 @@ #include #include +#include +#include +#include + +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" +#include "wintercpp/data/sql/table/winter_data_sql_table.h" #include "wintercpp/exception/generic/winter_internal_exception.h" using namespace winter::util::string; -winter::data::sql_impl::From::From(std::vector> tables) : - Clause("FROM $tables", "$tables"), tables_(std::move(tables)) { - Prepare(); +winter::data::sql_impl::From::From(const StatementValue &statement_value) { + statement_values_.push_back(statement_value); } -winter::data::sql_impl::From::From(const std::shared_ptr
&table) : - Clause("FROM $tables", "$tables") { - tables_.push_back(table); -} +winter::data::sql_impl::From::From(const std::vector &statement_values) : + statement_values_(statement_values) {} -std::string winter::data::sql_impl::From::From::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; - -winter::data::sql_impl::FieldType winter::data::sql_impl::From::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); +std::vector> winter::data::sql_impl::From::Fields() const { + return {}; } -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::From::Prepare() { - GenerateStatement(); - return winter::data::sql_impl::PreparedStatement( - StatementType::kClause, statement_template(), columns_); -} - -void winter::data::sql_impl::From::GenerateStatement() { +std::string winter::data::sql_impl::From::Query() const { std::vector tablesNames; - for (auto const &table : tables_) { - tablesNames.push_back(table->name()); - auto tableColumns = table->columns(); - for (const Column &col : tableColumns) { columns_.push_back(col); } + + for (auto const &statement_value : statement_values_) { + if (auto sharedTableValue = std::get_if>(&statement_value)) { + tablesNames.push_back(sharedTableValue->get()->name()); + } else if (auto tableValue = std::get_if
(&statement_value)) { + tablesNames.push_back(tableValue->name()); + } else if (auto clauseValue = std::get_if>(&statement_value)) { + tablesNames.push_back(clauseValue->get()->Query()); + } else { + std::string typeName = StatementValueType(statement_value.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); + } } - set_statement_template(winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::CommaSeparatedValue(tablesNames))); + return winter::util::string::replace_value( + query_template_, + query_param_, + winter::data::sql_impl::CommaSeparatedValue(tablesNames)); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp index 911df10..66667e0 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp @@ -4,37 +4,35 @@ #include #include +#include +#include #include -winter::data::sql_impl::Into::Into(std::shared_ptr
table) : - Clause("INTO $table", "$table"), table_(std::move(table)) {} +winter::data::sql_impl::Into::Into(const StatementValue &statement_value) : + statement_value_(statement_value) {} -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Into::Prepare() { - GenerateStatement(); - return winter::data::sql_impl::PreparedStatement(StatementType::kClause, - statement_template()); -} - -std::string winter::data::sql_impl::Into::Into::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; +std::string winter::data::sql_impl::Into::Query() const { + std::string statement_query; + if (auto sharedTableValue = std::get_if>(&statement_value_)) { + statement_query = sharedTableValue->get()->name(); + } else if (auto tableValue = std::get_if
(&statement_value_)) { + statement_query = tableValue->name(); + } else { + std::string typeName = StatementValueType(statement_value_.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); + } -winter::data::sql_impl::FieldType winter::data::sql_impl::Into::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); + return winter::util::string::replace_value( + query_template_, + query_param_, + winter::data::sql_impl::CommaSeparatedValue({statement_query})); } -void winter::data::sql_impl::Into::GenerateStatement() { - set_statement_template(winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::CommaSeparatedValue({table_->name()}))); -} \ No newline at end of file +std::vector> Fields() { + return {}; +} diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp index 1b51298..68bca72 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp @@ -4,55 +4,54 @@ #include #include +#include +#include #include -winter::data::sql_impl::Join::Join(std::shared_ptr
table, - JoinType type) : - Clause("$type JOIN $table", "$table"), - table_(std::move(table)), type_(type) { - set_statement_template(winter::util::string::replace_value( - statement_template(), "$type", GenerateType())); - set_statement_template(winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::CommaSeparatedValue({table_->name()}))); -} +#include +#include +#include -winter::data::sql_impl::Join::Join(std::shared_ptr
table) : - Clause("JOIN $table", "$table"), table_(std::move(table)), - type_(JoinType::DEFAULT) { - set_statement_template(winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::CommaSeparatedValue({table_->name()}))); +winter::data::sql_impl::Join::Join(const StatementValue& statement_value, + JoinType type) : + statement_value_(statement_value), + type_(type) { } -std::string winter::data::sql_impl::Join::Join::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; - -winter::data::sql_impl::FieldType winter::data::sql_impl::Join::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); +winter::data::sql_impl::Join::Join(const StatementValue& statement_value) : + statement_value_(statement_value), + type_(JoinType::DEFAULT) { } -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Join::Prepare() { - GenerateStatement(); - return winter::data::sql_impl::PreparedStatement(StatementType::kClause, - statement_template()); +std::string +winter::data::sql_impl::Join::Query() const { + std::string query = winter::util::string::replace_value(query_template_, "$type", GenerateType()); + + auto subQuery = [&]() -> std::string { + if (auto sharedTable = std::get_if>(&statement_value_)) { + return sharedTable->get()->name(); + } else if (auto table = std::get_if
(&statement_value_)) { + return table->name(); + } else if (auto clause = std::get_if>(&statement_value_)) { + return clause->get()->Query(); + } + + std::string typeName = StatementValueType(statement_value_.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); + }; + + return winter::util::string::replace_value( + query, + query_param_, + winter::data::sql_impl::CommaSeparatedValue({subQuery()})); } -void winter::data::sql_impl::Join::GenerateStatement() {} - -std::string winter::data::sql_impl::Join::GenerateType() { +std::string winter::data::sql_impl::Join::GenerateType() const { switch (type_) { case JoinType::INNER: return "INNER"; case JoinType::LEFT: return "LEFT"; diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp index defe34f..f4c1f26 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp @@ -4,53 +4,62 @@ #include #include +#include +#include #include -winter::data::sql_impl::On::On(const winter::data::sql_impl::Column &l_column, - winter::data::sql_impl::Condition condition, - const winter::data::sql_impl::Column &r_column) : - Clause("ON $lcolumn $condition $rcolumn", "$lcolumn $condition $rcolumn") { - set_statement_template(winter::util::string::replace_value( - statement_template(), - "$lcolumn", - l_column->TableName() + Dot() + l_column->name())); - set_statement_template(winter::util::string::replace_value( - statement_template(), "$condition", sql_impl::condition(condition))); - set_statement_template(winter::util::string::replace_value( - statement_template(), - "$rcolumn", - r_column->TableName() + Dot() + r_column->name())); -} +#include + +#include "wintercpp/data/sql/column/winter_data_sql_column.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + +winter::data::sql_impl::On::On(const StatementValue &l_statement_value, + winter::data::sql_impl::Condition condition, + const StatementValue &r_statement_value) : + l_statement_value_(l_statement_value), + r_statement_value_(r_statement_value), condition_(condition) {} + +winter::data::sql_impl::On::On(const StatementValue &l_statement_value, + winter::data::sql_impl::Condition condition) : + l_statement_value_(l_statement_value), + condition_(condition) {} -std::string winter::data::sql_impl::On::On::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); +std::vector> winter::data::sql_impl::On::Fields() const { + return {}; }; -winter::data::sql_impl::FieldType winter::data::sql_impl::On::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); -} +std::string +winter::data::sql_impl::On::Query() const { + auto getStatementValue = [](const StatementValue &statement_value) -> std::string { + if (auto sharedColumnValue = std::get_if>(&statement_value)) { + return sharedColumnValue->get()->FullName(); + } else if (auto columnValue = std::get_if(&statement_value)) { + return columnValue->FullName(); + } else if (auto clauseValue = std::get_if>(&statement_value)) { + return clauseValue->get()->Query(); + } else { + std::string typeName = StatementValueType(statement_value.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); + } + }; -winter::data::sql_impl::On::On(const winter::data::sql_impl::Column &l_column, - winter::data::sql_impl::Condition condition) : - Clause("ON $lcolumn $condition", "$lcolumn $condition") { - set_statement_template(winter::util::string::replace_value( - statement_template(), - "$lcolumn", - l_column->TableName() + Dot() + l_column->name())); - set_statement_template(winter::util::string::replace_value( - statement_template(), "$condition", sql_impl::condition(condition))); -} + std::string result = winter::util::string::replace_value( + query_template_, + query_param_l, + getStatementValue(l_statement_value_)); + + if (r_statement_value_.has_value() && r_statement_value_.value().index() != std::variant_npos) { + result = winter::util::string::replace_value( + result, + query_param_r, + getStatementValue(r_statement_value_.value())); + } -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::On::Prepare() { - return winter::data::sql_impl::PreparedStatement(StatementType::kClause, - statement_template()); + return winter::util::string::replace_value( + result, query_param_condition, sql_impl::condition(condition_)); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp index f63f744..f8e6c5c 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp @@ -4,66 +4,78 @@ #include #include +#include +#include #include +#include +#include + +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + using namespace winter::util::string; winter::data::sql_impl::Or::Or(const Predicate &predicate) : - Clause("OR $or", "$or"), column_(predicate.column()), + statement_value_(predicate.statementValue()), field_(predicate.field()), condition_(predicate.condition()), is_predicate_(true) {} -winter::data::sql_impl::Or::Or(Column column) : - Clause("OR $or", "$or"), column_(std::move(column)), +winter::data::sql_impl::Or::Or(const StatementValue &statement_value) : + statement_value_(statement_value), condition_(winter::data::sql_impl::Condition::NONE) {} -winter::data::sql_impl::Or::Or(Column column, +winter::data::sql_impl::Or::Or(const StatementValue &statement_value, winter::data::sql_impl::Condition condition) : - Clause("OR $or", "$or"), - column_(std::move(column)), condition_(condition) {} - -std::string winter::data::sql_impl::Or::Or::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; + statement_value_(statement_value), + condition_(condition) {} -winter::data::sql_impl::FieldType winter::data::sql_impl::Or::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); +std::vector> winter::data::sql_impl::Or::Or::Fields() const { + std::vector> fields; + fields.push_back(field_); + return fields; } -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Or::Prepare() { +std::string +winter::data::sql_impl::Or::Query() const { std::ostringstream builder; + + auto subqueryfn = [&]() -> std::string { + if (auto sharedColumn = std::get_if>(&statement_value_)) { + return sharedColumn->get()->FullName(); + } else if (auto column = std::get_if(&statement_value_)) { + return column->FullName(); + } else if (auto clause = std::get_if>(&statement_value_)) { + return clause->get()->Query(); + } + std::string typeName = StatementValueType(statement_value_.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); + }; + + auto subquery = subqueryfn(); + if (is_predicate_) { if (field_->IsCustomValue()) { - builder << column_->TableName() << Dot() << column_->name() + builder << subquery << Space() << condition(condition_) << Space() << field_->custom_value(); } else { - builder << column_->TableName() << Dot() << column_->name() + builder << subquery << Space() << condition(condition_) << Space() << PlaceHolder(); } - BuildQuery() << builder.str(); - return PreparedStatement( - StatementType::kClause, - replace_value(statement_template(), param(), query()), - field_); + + return replace_value(query_template_, query_param_, builder.str()); } - builder << column_->TableName() << Dot() << column_->name() + builder << subquery << ((condition_ != Condition::NONE) ? Space() + condition(condition_) : ""); - BuildQuery() << builder.str(); - return PreparedStatement( - StatementType::kClause, - replace_value(statement_template(), param(), query())); + + return replace_value(query_template_, query_param_, builder.str()); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp index 0eb3a15..24eb64a 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp @@ -3,40 +3,36 @@ // #include +#include +#include + +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" winter::data::sql_impl::Parenthesis::Parenthesis( - winter::data::sql_impl::Clause *clause) : - Clause("($clause)", "$clause") { - set_statement_template(winter::util::string::replace_value( - statement_template(), - "$clause", - clause->Prepare().statement_template())); -} + const winter::data::sql_impl::StatementValue& statement_value) : + statement_value_(statement_value) {} -std::string winter::data::sql_impl::Parenthesis::Parenthesis::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); +std::vector> winter::data::sql_impl::Parenthesis::Fields() const { + return {}; }; -winter::data::sql_impl::FieldType winter::data::sql_impl::Parenthesis::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); -} - -winter::data::sql_impl::Parenthesis::Parenthesis(const std::string &clause) : - Clause("($clause)", "$clause") { - set_statement_template(winter::util::string::replace_value( - statement_template(), "$clause", clause)); -} +std::string +winter::data::sql_impl::Parenthesis::Query() const { + auto clauseQuery = [&]() -> std::string { + if (auto clause = std::get_if>(&statement_value_)) { + return clause->get()->Query(); + } + std::string typeName = StatementValueType(statement_value_.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); + }; -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Parenthesis::Prepare() { - return winter::data::sql_impl::PreparedStatement(StatementType::kClause, - statement_template()); + return winter::util::string::replace_value( + query_template_, + query_param_, + clauseQuery()); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp index 406f0fb..b831282 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp @@ -5,19 +5,20 @@ #include #include +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" + using namespace winter::util::string; winter::data::sql_impl::Predicate::Predicate( - Column column, - std::shared_ptr - field, - winter::data::sql_impl::Condition conditionOperator) : - column_(std::move(column)), - field_(std::move(field)), condition_(conditionOperator) {} + const winter::data::sql_impl::StatementValue& statement_value, + const std::shared_ptr& field, + winter::data::sql_impl::Condition conditionOperator) : + statement_value_(statement_value), + field_(field), condition_(conditionOperator) {} -const winter::data::sql_impl::Column& -winter::data::sql_impl::Predicate::column() const { - return column_; +const winter::data::sql_impl::StatementValue& +winter::data::sql_impl::Predicate::statementValue() const { + return statement_value_; } const std::shared_ptr& diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp index 482ec21..e42e594 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp @@ -4,38 +4,20 @@ #include #include +#include +#include #include +#include #include -winter::data::sql_impl::Set::Set( - std::vector > fields) : - Clause("SET $fields", "$fields"), - fields_(std::move(fields)) {} +winter::data::sql_impl::Set::Set(const std::vector> &fields) : + fields_(fields) {} -std::string winter::data::sql_impl::Set::Set::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; - -winter::data::sql_impl::FieldType winter::data::sql_impl::Set::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); -} - -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Set::Prepare() { - set_statement_template(winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::commaSeparatedEqualValue(fields_))); - return winter::data::sql_impl::PreparedStatement( - StatementType::kClause, statement_template(), fields_); +std::string +winter::data::sql_impl::Set::Query() const { + return winter::util::string::replace_value( + query_template_, + query_param_, + winter::data::sql_impl::commaSeparatedEqualValue(fields_)); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp index 8ae094e..28ca32d 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp @@ -5,45 +5,32 @@ #include #include #include +#include +#include #include -winter::data::sql_impl::Values::Values( - std::vector > fields) : - Clause("($columns) VALUES ($set_values)", "$set_values"), - _fields(std::move(fields)) {} - -std::string winter::data::sql_impl::Values::Values::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; +#include -winter::data::sql_impl::FieldType winter::data::sql_impl::Values::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); -} +winter::data::sql_impl::Values::Values(const std::vector>& fields) : + fields_(fields) {} + +std::vector> winter::data::sql_impl::Values::Fields() const { + return fields_; +}; -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Values::Prepare() { +std::string +winter::data::sql_impl::Values::Query() const { std::vector columns; - for (const auto &field : _fields) { columns.push_back(field->name()); } - set_statement_template(winter::util::string::replace_value( - statement_template(), - "$columns", - winter::data::sql_impl::CommaSeparatedValue(columns))); + for (const auto& field : fields_) { columns.push_back(field->name()); } - set_statement_template(winter::util::string::replace_value( - statement_template(), - param(), - winter::data::sql_impl::CommaSeparatedStatement(_fields))); + std::string query = winter::util::string::replace_value( + query_template_, + query_param_values_, + winter::data::sql_impl::CommaSeparatedValue(columns)); - return winter::data::sql_impl::PreparedStatement( - StatementType::kClause, statement_template(), _fields); + return winter::util::string::replace_value( + query, + query_param_values_, + winter::data::sql_impl::CommaSeparatedStatement(fields_)); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp index 2b2b020..4418bf6 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp @@ -1,69 +1,69 @@ -// -// Created by Samuel Azcona on 21/05/2020. -// - #include #include +#include +#include #include +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause.h" + using namespace winter::util::string; +using namespace winter::data::sql_impl; -winter::data::sql_impl::Where::Where(const Predicate &predicate) : - Clause("WHERE $where", "$where"), column_(predicate.column()), - field_(predicate.field()), condition_(predicate.condition()), +Where::Where(const Predicate& predicate) : + statement_value_(predicate.statementValue()), + field_(predicate.field()), + condition_(predicate.condition()), _is_predicate(true) {} -winter::data::sql_impl::Where::Where(Column column) : - Clause("WHERE $where", "$where"), column_(std::move(column)), - condition_(winter::data::sql_impl::Condition::NONE) {} +Where::Where(StatementValue statement_value) : + statement_value_(std::move(statement_value)), + condition_(Condition::NONE) {} -winter::data::sql_impl::Where::Where( - Column column, winter::data::sql_impl::Condition condition) : - Clause("WHERE $where", "$where"), - column_(std::move(column)), condition_(condition) {} - -std::string winter::data::sql_impl::Where::Where::name() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to name function on clause")); -}; +Where::Where( + StatementValue statement_value, Condition condition) : + statement_value_(std::move(statement_value)), + condition_(condition) {} -winter::data::sql_impl::FieldType winter::data::sql_impl::Where::fieldType() { - throw exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ("invalid call to fieldtype function on clause")); +std::vector> Where::Fields() const { + std::vector> fields; + fields.push_back(field_); + return fields; } -winter::data::sql_impl::PreparedStatement -winter::data::sql_impl::Where::Prepare() { +std::string +Where::Query() const { std::ostringstream builder; - if (_is_predicate) { - if (field_->IsCustomValue()) { - builder << column_->TableName() << Dot() << column_->name() - << Space() << condition(condition_) << Space() - << field_->custom_value(); - } else { - builder << column_->TableName() << Dot() << column_->name() - << Space() << condition(condition_) << Space() - << PlaceHolder(); + if (auto columnValue = std::get_if>(&statement_value_)) { + if (_is_predicate) { + if (field_->IsCustomValue()) { + builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + << Space() << condition(condition_) << Space() + << field_->custom_value(); + } else { + builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + << Space() << condition(condition_) << Space() + << PlaceHolder(); + } + + return replace_value(query_template_, query_param_, builder.str()); } - BuildQuery() << builder.str(); - return PreparedStatement( - StatementType::kClause, - replace_value(statement_template(), param(), query()), - field_); + + builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + << ((condition_ != Condition::NONE) + ? Space() + condition(condition_) + : ""); + return replace_value(query_template_, query_param_, builder.str()); + } else if (auto clauseValue = std::get_if>(&statement_value_)) { + builder << clauseValue->get()->Query(); + return replace_value(query_template_, query_param_, builder.str()); } - builder << column_->TableName() << Dot() << column_->name() - << ((condition_ != Condition::NONE) - ? Space() + condition(condition_) - : ""); - BuildQuery() << builder.str(); - return PreparedStatement( - StatementType::kClause, - replace_value(statement_template(), param(), query())); -} + std::string typeName = StatementValueType(statement_value_.index()); + std::string error = "invalid statement_value " + typeName + "not supported"; + + throw ::winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + (error)); +} \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/winter_data_sql_select.cpp b/wintercpp/src/data/sql/statement/winter_data_sql_select.cpp index 450cf30..70cccf7 100644 --- a/wintercpp/src/data/sql/statement/winter_data_sql_select.cpp +++ b/wintercpp/src/data/sql/statement/winter_data_sql_select.cpp @@ -10,6 +10,7 @@ #include #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement.h" using namespace winter::data::sql_impl; @@ -19,31 +20,33 @@ Select::Select(const std::string &query) : Select::Select() : Statement
(&statement_value)) { + return table->name(); + } else if (auto sharedTable = std::get_if>(&statement_value)) { + return sharedTable->get()->name(); + } else if (auto clause = std::get_if>(&statement_value)) { + return clause->get()->Query(); + } else if (auto statement = std::get_if>(&statement_value)) { + return statement->get()->prepared_statement().statement_template(); + } + throw winter::exception::WinterInternalException("invalid statementvalue or not implemented"); + }; + + inline std::string GetStatementValue(const std::optional& opt_statement_value) { + if (opt_statement_value.has_value()) { + return GetStatementValue(opt_statement_value.value()); + } + return ""; + }; + +} // namespace winter::data::sql_impl +#endif diff --git a/wintercpp/include/wintercpp/winter.h b/wintercpp/include/wintercpp/winter.h index bf003f7..bfd86dc 100644 --- a/wintercpp/include/wintercpp/winter.h +++ b/wintercpp/include/wintercpp/winter.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp b/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp index 08e700b..34015f9 100644 --- a/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp +++ b/wintercpp/src/data/sql/function/winter_data_sql_function_min.cpp @@ -18,9 +18,10 @@ using namespace winter::util::string; -winter::data::sql_impl::Min::Min(const StatementValue& statement_value) : statement_value_(statement_value) {} +winter::data::sql_impl::Min::Min(const StatementValue& statement_value) : + statement_value_(statement_value) {} - std::string winter::data::sql_impl::Min::Min::name() const { +std::string winter::data::sql_impl::Min::Min::name() const { std::ostringstream builder; if (auto columnValue = std::get_if(&statement_value_)) { builder << columnValue->TableName() << "_" << columnValue->name(); diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp index 1173338..c5a3349 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp @@ -3,67 +3,107 @@ // #include +#include #include +#include #include #include #include #include -#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_parenthesis.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" using namespace winter::util::string; +using namespace winter::data::sql_impl; -winter::data::sql_impl::And::And(const Predicate &predicate) : - statement_value_(predicate.statementValue()), - field_(predicate.field()), - condition_(predicate.condition()), - is_predicate_(true) {} +And::And(const Predicate &predicate) : + predicate_(predicate) {} -winter::data::sql_impl::And::And(StatementValue statement_value) : - statement_value_(std::move(statement_value)), +/* winter::data::sql_impl::And::And(const StatementValue &statement_value) : + l_statement_value_(statement_value), condition_(winter::data::sql_impl::Condition::NONE) {} -winter::data::sql_impl::And::And(StatementValue statement_value, +winter::data::sql_impl::And::And(const StatementValue &statement_value, winter::data::sql_impl::Condition condition) : - statement_value_(std::move(statement_value)), + l_statement_value_(statement_value), condition_(condition) {} -std::vector> winter::data::sql_impl::And::And::Fields() const { +winter::data::sql_impl::And::And(const StatementValue &l_statement_value, + winter::data::sql_impl::Condition condition, + const StatementValue &r_statement_value) : + l_statement_value_(l_statement_value), + r_statement_value_(r_statement_value), + condition_(condition) {} */ + +std::vector> And::And::Fields() const { std::vector> fields; - fields.push_back(field_); + fields.push_back(predicate_.field()); return fields; } std::string -winter::data::sql_impl::And::Query() const { +And::Query() const { std::ostringstream builder; + auto field = predicate_.field(); + auto lstatement = predicate_.lstatementStr(); + auto rstatement = predicate_.rstatementStr(); + auto condition = predicate_.conditionStr(); + + if (predicate_.has_field()) { + if (field->IsCustomValue()) { + builder << lstatement + << Space() << condition << Space() + << field->custom_value(); + } else { + builder << lstatement + << Space() << condition << Space() + << PlaceHolder(); + } + return replace_value(query_template_, query_param_, builder.str()); + } - if (auto columnValue = std::get_if>(&statement_value_)) { + if (predicate_.has_rstatement()) { + builder << lstatement + << Space() << condition << Space() + << rstatement; + return replace_value(query_template_, query_param_, builder.str()); + } + + builder << lstatement + << Space() << condition; + return replace_value(query_template_, query_param_, builder.str()); +} + +/* if (auto columnValue = std::get_if>(&l_statement_value_)) { if (is_predicate_) { if (field_->IsCustomValue()) { - builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + builder << columnValue->get()->FullName() << Space() << condition(condition_) << Space() << field_->custom_value(); } else { - builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + builder << columnValue->get()->FullName() << Space() << condition(condition_) << Space() << PlaceHolder(); } return replace_value(query_template_, query_param_, builder.str()); } - builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() + builder << columnValue->get()->FullName() << ((condition_ != Condition::NONE) ? Space() + condition(condition_) : ""); return replace_value(query_template_, query_param_, builder.str()); - } else if (auto clauseValue = std::get_if>(&statement_value_)) { + } else if (auto clauseValue = std::get_if>(&l_statement_value_)) { builder << clauseValue->get()->Query(); return replace_value(query_template_, query_param_, builder.str()); + } else if (auto statement = std::get_if>(&l_statement_value_)) { + builder << statement->get()->prepared_statement().statement_template() << Space() << condition(condition_) << Space(); + return replace_value(query_template_, query_param_, builder.str()); } - std::string typeName = StatementValueType(statement_value_.index()); + std::string typeName = StatementValueType(l_statement_value_.index()); std::string error = "invalid statement_value " + typeName + "not supported"; throw ::winter::exception::WinterInternalException::Create( @@ -72,3 +112,4 @@ winter::data::sql_impl::And::Query() const { __LINE__, (error)); } + */ \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp index 007205f..f0575b3 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp @@ -10,18 +10,27 @@ #include #include -#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" -#include "wintercpp/data/sql/table/winter_data_sql_table.h" -#include "wintercpp/exception/generic/winter_internal_exception.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" using namespace winter::util::string; +using namespace winter::data::sql_impl; -winter::data::sql_impl::From::From(const StatementValue &statement_value) { - statement_values_.push_back(statement_value); +From::From(const Predicate &predicate) { + predicate_.push_back(predicate); } -winter::data::sql_impl::From::From(const std::vector &statement_values) : - statement_values_(statement_values) {} +From::From(const std::vector &predicates) : + predicate_(predicates) {} + +From::From(const StatementValue &statement_value) { + predicate_.push_back(Predicate(statement_value)); +} + +From::From(const std::vector &statement_value) { + for (auto const &statement_value : statement_value) { + predicate_.push_back(Predicate(statement_value)); + } +} std::vector> winter::data::sql_impl::From::Fields() const { return {}; @@ -30,22 +39,8 @@ std::vector tablesNames; - for (auto const &statement_value : statement_values_) { - if (auto sharedTableValue = std::get_if>(&statement_value)) { - tablesNames.push_back(sharedTableValue->get()->name()); - } else if (auto tableValue = std::get_if
(&statement_value)) { - tablesNames.push_back(tableValue->name()); - } else if (auto clauseValue = std::get_if>(&statement_value)) { - tablesNames.push_back(clauseValue->get()->Query()); - } else { - std::string typeName = StatementValueType(statement_value.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); - } + for (auto const &predicate : predicate_) { + tablesNames.push_back(predicate.lstatementStr()); } return winter::util::string::replace_value( query_template_, diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_operator.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_operator.cpp index 91d6d1b..f795da8 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_operator.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_operator.cpp @@ -77,13 +77,13 @@ std::string GetCondition::Get() { std::string winter::data::sql_impl::condition(enum Condition condition) { switch (condition) { + case Condition::NONE: return GetCondition::Get(); case Condition::EQ: return GetCondition::Get(); case Condition::NOT_EQ: return GetCondition::Get(); case Condition::LESS: return GetCondition::Get(); case Condition::LESS_EQ: return GetCondition::Get(); case Condition::GREATER: return GetCondition::Get(); - case Condition::GREATER_EQ: - return GetCondition::Get(); + case Condition::GREATER_EQ: return GetCondition::Get(); case Condition::IN: return GetCondition::Get(); case Condition::NOT: return GetCondition::Get(); case Condition::NOT_IN: return GetCondition::Get(); @@ -91,15 +91,11 @@ std::string winter::data::sql_impl::condition(enum Condition condition) { case Condition::IS: return GetCondition::Get(); case Condition::LIKE: return GetCondition::Get(); case Condition::EXISTS: return GetCondition::Get(); - case Condition::NONE: return GetCondition::Get(); - case Condition::NOT_NULL: - return GetCondition::Get(); + case Condition::NOT_NULL: return GetCondition::Get(); case Condition::IS_NULL: return GetCondition::Get(); - case Condition::IS_NOT_NULL: - return GetCondition::Get(); + case Condition::IS_NOT_NULL: return GetCondition::Get(); default: { - std::string message = "no value for condition index, please fix me" - + std::to_string(static_cast(condition)); + std::string message = "no value for condition index, please fix me" + std::to_string(static_cast(condition)); throw winter::exception::WinterInternalException::Create( __FILE__, __FUNCTION__, __LINE__, message); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp index f8e6c5c..b2ba81e 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp @@ -16,7 +16,7 @@ using namespace winter::util::string; winter::data::sql_impl::Or::Or(const Predicate &predicate) : - statement_value_(predicate.statementValue()), + statement_value_(predicate.lstatementValue()), field_(predicate.field()), condition_(predicate.condition()), is_predicate_(true) {} diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp index b831282..429707d 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp @@ -5,28 +5,94 @@ #include #include +#include + +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_operator.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values_utils.h" using namespace winter::util::string; +using namespace winter::data::sql_impl; + +Predicate::Predicate(const StatementValue& statement_value) : + l_statement_value_(statement_value), + condition_(Condition::NONE) {} + +Predicate::Predicate( + const StatementValue& statement_value, + Condition conditionOperator) : + l_statement_value_(statement_value), + condition_(conditionOperator) {} + +Predicate::Predicate( + const StatementValue& statement_value, + const std::shared_ptr& field) : + l_statement_value_(statement_value), + condition_(Condition::NONE), + field_(field) {} -winter::data::sql_impl::Predicate::Predicate( +Predicate::Predicate( const winter::data::sql_impl::StatementValue& statement_value, - const std::shared_ptr& field, - winter::data::sql_impl::Condition conditionOperator) : - statement_value_(statement_value), - field_(field), condition_(conditionOperator) {} + winter::data::sql_impl::Condition conditionOperator, + const std::shared_ptr& field) : + l_statement_value_(statement_value), + condition_(conditionOperator), + field_(field) {} + +Predicate::Predicate( + const StatementValue& l_statement_value, + Condition conditionOperator, + const StatementValue& r_statement_value) : + l_statement_value_(l_statement_value), + condition_(conditionOperator), r_statement_value_(r_statement_value) {} const winter::data::sql_impl::StatementValue& -winter::data::sql_impl::Predicate::statementValue() const { - return statement_value_; +Predicate::lstatementValue() const { + return l_statement_value_; +} + +const std::optional& +Predicate::rstatementValue() const { + return r_statement_value_; } const std::shared_ptr& -winter::data::sql_impl::Predicate::field() const { +Predicate::field() const { return field_; } -winter::data::sql_impl::Condition winter::data::sql_impl::Predicate::condition() - const { +winter::data::sql_impl::Condition Predicate::condition() const { return condition_; -} \ No newline at end of file +} + +std::string Predicate::lstatementStr() const { + bool isClause = IsClause(l_statement_value_) || IsStatement(l_statement_value_); + std::string clauseValue = GetStatementValue(l_statement_value_); + return ((isClause) ? "(" + clauseValue + ")" : clauseValue); +} + +std::string Predicate::rstatementStr() const { + if (r_statement_value_) { + auto value = r_statement_value_.value(); + bool isClause = IsClause(value) || IsStatement(value); + std::string clauseValue = GetStatementValue(value); + return ((isClause) ? "(" + clauseValue + ")" : clauseValue); + } + return GetStatementValue(r_statement_value_); +}; + +std::string Predicate::conditionStr() const { + return ::condition(condition_); +}; + +bool Predicate::has_rstatement() const { + return r_statement_value_.has_value(); +}; + +bool Predicate::has_condition() const { + return condition_ != Condition::NONE; +}; + +bool Predicate::has_field() const { + return field_ != nullptr; +}; diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp index 4418bf6..6626fc1 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp @@ -10,7 +10,7 @@ using namespace winter::util::string; using namespace winter::data::sql_impl; Where::Where(const Predicate& predicate) : - statement_value_(predicate.statementValue()), + statement_value_(predicate.lstatementValue()), field_(predicate.field()), condition_(predicate.condition()), _is_predicate(true) {} diff --git a/wintercpp/test/winter_clause_and_test.cpp b/wintercpp/test/winter_clause_and_test.cpp new file mode 100644 index 0000000..14a1ecf --- /dev/null +++ b/wintercpp/test/winter_clause_and_test.cpp @@ -0,0 +1,79 @@ +// +// Created by samuaz on 3/10/21. +// + +#include + +#include +#include +#include + +#include "gtest/gtest.h" +#include "wintercpp/data/sql/column/winter_data_sql_column.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_from.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_operator.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" +#include "wintercpp/data/sql/statement/winter_data_sql_select.h" + +// AND (SELECT columna4 FROM tabla2 WHERE columna5 = 'bar') < (SELECT columna6 FROM tabla3 WHERE columna7 = 'baz') +// AND (SELECT columna4 FROM tabla2 WHERE columna5 = 'bar') < 10 +// AND table.column < 10 +// AND table.column NOT NULL +// AND LOWER(lastName) LIKE 'a%' + +using namespace winter::data::sql_impl; + +struct QueryTestTableMin : public UUIDTable { + QueryTestTableMin() : + UUIDTable("QueryTestTableMin", true, DatabaseType::kGeneric) {} + const Column col1 = String("col1"); + const Column col2 = String("col2"); + const Column col3 = String("col3"); + const Column col4 = String("col4"); + const Column col5 = String("col5"); +}; + +TEST(winteAndClause, canCreateSubClause) { + std::shared_ptr testTable = std::make_shared(); + Select *select = new Select({testTable->col1}); + select->AddClause(From(testTable)); + auto selectShared = std::shared_ptr(select); + Predicate predicate = Predicate::MakePredicate(selectShared, Condition::LESS_EQ, 10); + auto andClause = And(predicate); + ASSERT_EQ(andClause.Query(), "AND (SELECT QueryTestTableMin.col1 FROM QueryTestTableMin) <= ?"); +} + +TEST(winteAndClause, canCreateSubColumnAndValue) { + std::shared_ptr testTable = std::make_shared(); + Predicate predicate = Predicate::MakePredicate(testTable->col1, Condition::LESS_EQ, 10); + auto andClause = And(predicate); + ASSERT_EQ(andClause.Query(), "AND QueryTestTableMin.col1 <= ?"); +} + +TEST(winteAndClause, canCreateSubColumnAndCondition) { + std::shared_ptr testTable = std::make_shared(); + Predicate predicate = Predicate::MakePredicate(testTable->col1, Condition::IS_NOT_NULL); + auto andClause = And(predicate); + ASSERT_EQ(andClause.Query(), "AND QueryTestTableMin.col1 IS NOT NULL"); +} + +TEST(winteAndClause, canCreateSubClauseAndCondition) { + std::shared_ptr testTable = std::make_shared(); + Select *select = new Select({testTable->col1}); + select->AddClause(From(testTable)); + auto selectShared = std::shared_ptr(new Select({testTable->col1})); + auto fromClause = From(selectShared); + ASSERT_EQ(fromClause.Query(), "FROM (SELECT QueryTestTableMin.col1)"); +} diff --git a/wintercpp/test/winter_field_test.cpp b/wintercpp/test/winter_field_test.cpp deleted file mode 100644 index 2fdbf7c..0000000 --- a/wintercpp/test/winter_field_test.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by samuaz on 3/10/21. -// - -#include - -#include -#include - -#include "gtest/gtest.h" - -TEST(winterResultSet, dashedUUID) { -} \ No newline at end of file diff --git a/wintercpp_grpc/CMakeLists.txt b/wintercpp_grpc/CMakeLists.txt index 8ecbae3..381a215 100644 --- a/wintercpp_grpc/CMakeLists.txt +++ b/wintercpp_grpc/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(${CMAKE_BINARY_DIR}/generated) diff --git a/wintercpp_mariadb/CMakeLists.txt b/wintercpp_mariadb/CMakeLists.txt index 3e74353..d933583 100644 --- a/wintercpp_mariadb/CMakeLists.txt +++ b/wintercpp_mariadb/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(${CMAKE_BINARY_DIR}/generated) diff --git a/wintercpp_mysql/CMakeLists.txt b/wintercpp_mysql/CMakeLists.txt index 0cb8248..9618540 100644 --- a/wintercpp_mysql/CMakeLists.txt +++ b/wintercpp_mysql/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(${CMAKE_BINARY_DIR}/generated) diff --git a/wintercpp_mysql_core/CMakeLists.txt b/wintercpp_mysql_core/CMakeLists.txt index 52ebd6c..ef952ae 100644 --- a/wintercpp_mysql_core/CMakeLists.txt +++ b/wintercpp_mysql_core/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(${CMAKE_BINARY_DIR}/generated) diff --git a/wintercpp_redis/CMakeLists.txt b/wintercpp_redis/CMakeLists.txt index 4115be1..dd27bb5 100644 --- a/wintercpp_redis/CMakeLists.txt +++ b/wintercpp_redis/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(${CMAKE_BINARY_DIR}/generated) diff --git a/wintercpp_test/CMakeLists.txt b/wintercpp_test/CMakeLists.txt index e80e9b8..cf46bfd 100644 --- a/wintercpp_test/CMakeLists.txt +++ b/wintercpp_test/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(${CMAKE_BINARY_DIR}/generated) From e1d075998f1eb7bc3fbe1851acff41db41947404 Mon Sep 17 00:00:00 2001 From: samuaz Date: Wed, 14 Jun 2023 03:24:17 -0300 Subject: [PATCH 3/8] update predicate and clausules --- .../winter_data_sql_repository_utils.h | 6 +- .../clause/winter_data_sql_clause_and.h | 2 - .../clause/winter_data_sql_clause_in.h | 24 +++--- .../clause/winter_data_sql_clause_in.tpp | 49 ------------- .../clause/winter_data_sql_clause_into.h | 10 ++- .../clause/winter_data_sql_clause_join.h | 15 ++-- .../clause/winter_data_sql_clause_or.h | 31 +------- .../clause/winter_data_sql_clause_predicate.h | 39 ++++++++-- .../clause/winter_data_sql_clause_where.h | 43 +++-------- .../winter_data_sql_statement_util.h | 2 + .../winter_data_sql_statement_values.h | 7 ++ .../winter_data_sql_statement_values_utils.h | 6 +- .../clause/winter_data_sql_clause_and.cpp | 73 +++---------------- .../clause/winter_data_sql_clause_from.cpp | 12 ++- .../clause/winter_data_sql_clause_in.cpp | 29 ++++++++ .../clause/winter_data_sql_clause_into.cpp | 33 ++++----- .../clause/winter_data_sql_clause_join.cpp | 42 ++++------- .../clause/winter_data_sql_clause_or.cpp | 52 ++++--------- .../winter_data_sql_clause_predicate.cpp | 72 ++++++++++++------ .../clause/winter_data_sql_clause_where.cpp | 66 ++++++----------- .../winter_data_sql_statement_util.cpp | 4 + wintercpp/test/winter_clause_in_test.cpp | 38 ++++++++++ wintercpp/test/winter_clause_into_test.cpp | 32 ++++++++ wintercpp/test/winter_clause_join_test.cpp | 57 +++++++++++++++ 24 files changed, 384 insertions(+), 360 deletions(-) delete mode 100644 wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp create mode 100644 wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_in.cpp create mode 100644 wintercpp/test/winter_clause_in_test.cpp create mode 100644 wintercpp/test/winter_clause_into_test.cpp create mode 100644 wintercpp/test/winter_clause_join_test.cpp diff --git a/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h b/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h index 5b353ca..4ed237c 100644 --- a/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h +++ b/wintercpp/include/wintercpp/data/sql/repository/winter_data_sql_repository_utils.h @@ -20,6 +20,8 @@ #include #include +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" + namespace winter::data::sql_impl { using namespace winter::exception; @@ -108,10 +110,10 @@ namespace winter::data::sql_impl { auto uuidTable = std::dynamic_pointer_cast< winter::data::sql_impl::UUIDTable>(table); if (uuidTable->binary()) { - select << Where(Where::make_predicate( + select << Where(Predicate::MakePredicate( uuidTable->id(), Condition::EQ, id, "unhex(?)")); } else { - select << Where(Where::make_predicate( + select << Where(Predicate::MakePredicate( uuidTable->id(), Condition::EQ, id)); } break; diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h index cd65e09..b0a9254 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h @@ -13,8 +13,6 @@ #include -#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" - namespace winter::data::sql_impl { class And : public virtual Clause { diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h index 2b4a6bd..a57a33d 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h @@ -7,37 +7,39 @@ #include #include -#include #include #include #include #include #include +#include #include #include #include +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" + namespace winter::data::sql_impl { - template class In : public virtual Clause { public: - explicit In(const std::vector &values); - explicit In(const StatementValue &statement_value); + explicit In(const StatementValue& statement_value); + explicit In(const Predicate& predicate); std::string Query() const override; std::vector> Fields() const override; + template + static In Values(const std::vector& values_) { + return In(Predicate::MakePredicate(values_)); + } + private: - const std::vector values_; - const StatementValue statement_value_; - bool has_clause_ = false; - const std::string query_template_ = "IN ($IN_VALUE)"; - const std::string query_param_ = "$IN_VALUE"; + const Predicate predicate_; + const std::string query_template_ = "IN $IN_VALUE"; + const std::string query_param_ = "$IN_VALUE"; }; } // namespace winter::data::sql_impl -#include "winter_data_sql_clause_in.tpp" - #endif // WINTERCPP_WINTER_DATA_SQL_CLAUSE_IN_H \ No newline at end of file diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp deleted file mode 100644 index f4c6bc5..0000000 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.tpp +++ /dev/null @@ -1,49 +0,0 @@ -namespace winter::data::sql_impl { - - template - In::In(const std::vector &values) : - values_(values) {} - - template - In::In(const StatementValue &statement_value) : - statement_value_(statement_value), has_clause_(true) {} - - template - std::vector> In::Fields() const { - std::vector> fields; - for (const auto &value : values_) { - fields.push_back( - std::make_shared>(value)); - } - return fields; - }; - - template - std::string In::Query() const { - if (has_clause_) { - std::string subQuery; - auto &statement_value = statement_value_; - auto clause_ptr = std::get_if>(&statement_value); - if (clause_ptr) { - subQuery = clause_ptr->get()->Query(); - } else { - std::string typeName = StatementValueType(statement_value.index()); - std::stringstream ss; - ss << "invalid statement_value " << typeName << " not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - ss.str()); - } - return winter::util::string::replace_value( - query_template_, - query_param_, - std::move(subQuery)); - } - return winter::util::string::replace_value( - query_template_, - query_param_, - CommaSeparatedPlaceHolder(values_.size())); - } -} // namespace winter::data::sql_impl \ No newline at end of file diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h index f65ca36..0f11d83 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_into.h @@ -8,19 +8,21 @@ #include #include +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" namespace winter::data::sql_impl { class Into : public virtual Clause { public: - explicit Into(const StatementValue& table); + explicit Into(const Predicate& predicate); + explicit Into(const StatementValue& predicate); std::string Query() const override; std::vector> Fields() const override; private: - const StatementValue statement_value_; - const std::string query_template_ = "INTO $table"; - const std::string query_param_ = "$table"; + const Predicate predicate_; + const std::string query_template_ = "INTO $table"; + const std::string query_param_ = "$table"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h index 4eb4efa..860416a 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_join.h @@ -8,6 +8,7 @@ #include #include +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" namespace winter::data::sql_impl { @@ -16,7 +17,9 @@ namespace winter::data::sql_impl { INNER, LEFT, RIGHT, - CROSS }; + CROSS, + FULL_JOIN + }; class Join : public virtual Clause { public: @@ -26,11 +29,11 @@ namespace winter::data::sql_impl { std::vector> Fields() const override; private: - const StatementValue statement_value_; - const JoinType type_; - std::string GenerateType() const; - const std::string query_template_ = "$type JOIN $table"; - const std::string query_param_ = "$table"; + const Predicate predicate_; + const JoinType type_; + std::string GenerateType() const; + const std::string query_template_ = "$type JOIN $table"; + const std::string query_param_ = "$table"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h index fe5c464..6af7e9c 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_or.h @@ -29,34 +29,11 @@ namespace winter::data::sql_impl { std::string Query() const override; std::vector> Fields() const override; - template - static Predicate MakePredicate(const Column &column, - Condition condition, - T value) { - return Predicate(column, - std::make_shared>( - column->name(), value), - condition); - } - - template - static Predicate MakePredicate(const Column &column, - Condition condition, - T value, - const std::string &customValue) { - return Predicate(column, - std::make_shared>( - column->name(), value, customValue), - condition); - } - private: - const StatementValue statement_value_; - const std::shared_ptr field_; - Condition condition_ {}; - bool is_predicate_ = false; - const std::string query_template_ = "OR $or"; - const std::string query_param_ = "$or"; + const Predicate predicate_; + bool is_predicate_ = false; + const std::string query_template_ = "OR $or"; + const std::string query_param_ = "$or"; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h index 5a65f88..8049be0 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h @@ -20,6 +20,7 @@ #include #include +#include #include namespace winter::data::sql_impl { @@ -28,6 +29,10 @@ namespace winter::data::sql_impl { public: explicit Predicate(const StatementValue& statement_value); + explicit Predicate(const std::shared_ptr& field); + + explicit Predicate(const std::vector>& fields); + Predicate( const StatementValue& statement_value, const std::shared_ptr& field); @@ -77,6 +82,21 @@ namespace winter::data::sql_impl { std::make_shared>(value)); } + template + static Predicate MakePredicate(T value) { + return Predicate(std::make_shared>(value)); + } + + template + static Predicate MakePredicate(const std::vector& values) { + std::vector> fields; + fields.reserve(values.size()); + for (const auto& value : values) { + fields.push_back(std::make_shared>(value)); + } + return Predicate(fields); + } + static Predicate MakePredicate(const StatementValue& statement_value, Condition condition) { return Predicate(statement_value, @@ -94,7 +114,9 @@ namespace winter::data::sql_impl { return Predicate(lclause, condition, rclause); } - const StatementValue& lstatementValue() const; + const std::optional& lstatementValue() const; + + const std::optional& rstatementValue() const; std::string lstatementStr() const; @@ -102,23 +124,26 @@ namespace winter::data::sql_impl { std::string conditionStr() const; + bool has_lstatement() const; + bool has_rstatement() const; bool has_condition() const; - bool has_field() const; + bool has_fields() const; - const std::optional& rstatementValue() const; + const std::vector>& fields() const; const std::shared_ptr& field() const; Condition condition() const; private: - const StatementValue l_statement_value_; - const winter::data::sql_impl::Condition condition_; - const std::optional r_statement_value_; - const std::shared_ptr field_; + std::string statementStr(std::optional statement_value) const; + const std::optional l_statement_value_; + const winter::data::sql_impl::Condition condition_; + const std::optional r_statement_value_; + const std::vector> fields_ {}; }; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h index d836d0d..4d879f7 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_where.h @@ -2,8 +2,8 @@ // Created by Samuel Azcona on 21/05/2020. // -#ifndef WINTER_DATA_SQL_CLAUSE_WHERE2 -#define WINTER_DATA_SQL_CLAUSE_WHERE2 +#ifndef WINTER_DATA_SQL_CLAUSE_WHERE +#define WINTER_DATA_SQL_CLAUSE_WHERE #include #include @@ -21,45 +21,22 @@ namespace winter::data::sql_impl { class Where : public virtual Clause { public: - explicit Where(const Predicate &predicate); + explicit Where(const Predicate& predicate); - explicit Where(StatementValue statement_value); + explicit Where(const StatementValue& statement_value); - explicit Where(StatementValue statement_value, winter::data::sql_impl::Condition); + explicit Where(const StatementValue& statement_value, winter::data::sql_impl::Condition); std::string Query() const override; std::vector> Fields() const override; - template - static Predicate make_predicate(const Column &column, - Condition condition, - T value) { - return Predicate(column, - std::make_shared>( - column->name(), value), - condition); - } - - template - static Predicate make_predicate(const Column &column, - Condition condition, - T value, - const std::string &custom_value) { - return Predicate(column, - std::make_shared>( - column->name(), value, custom_value), - condition); - } - private: - const StatementValue statement_value_; - const std::shared_ptr field_; - const winter::data::sql_impl::Condition condition_ {}; - const bool _is_predicate = false; - const std::string query_template_ = "WHERE $where"; - const std::string query_param_ = "$where"; + const Predicate predicate_; + const bool _is_predicate = false; + const std::string query_template_ = "WHERE $where"; + const std::string query_param_ = "$where"; }; } // namespace winter::data::sql_impl -#endif /* WINTER_DATA_SQL_CLAUSE_WHERE2 */ +#endif /* WINTER_DATA_SQL_CLAUSE_WHERE */ diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_util.h b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_util.h index 94a06a7..50b1662 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_util.h +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_util.h @@ -23,6 +23,8 @@ namespace winter::data::sql_impl { std::string CommaSeparatedPlaceHolder(size_t size); + std::string CommaSeparatedParenthesesPlaceHolder(size_t size); + std::string CommaSeparatedEqualValue( const std::vector &elements); diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h index 367adbc..bf589ae 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values.h @@ -37,6 +37,13 @@ namespace winter::data::sql_impl { return std::holds_alternative>(statement_value); } + inline bool IsClause(const std::optional& statement_value) { + if (statement_value.has_value()) { + return std::holds_alternative>(statement_value.value()); + } + return false; + } + inline std::string StatementValueType(int index) { switch (index) { case 0: diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values_utils.h b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values_utils.h index 8c10718..6ce897d 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values_utils.h +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement_values_utils.h @@ -31,7 +31,11 @@ namespace winter::data::sql_impl { } else if (auto statement = std::get_if>(&statement_value)) { return statement->get()->prepared_statement().statement_template(); } - throw winter::exception::WinterInternalException("invalid statementvalue or not implemented"); + throw winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + "invalid statementvalue or not implemented"); }; inline std::string GetStatementValue(const std::optional& opt_statement_value) { diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp index c5a3349..da581c3 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp @@ -10,9 +10,10 @@ #include #include +#include #include -#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_parenthesis.h" +#include "wintercpp/data/sql/preparedstatement/winter_data_sql_abstract_prepared_statement_field.h" #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" using namespace winter::util::string; @@ -21,37 +22,19 @@ using namespace winter::data::sql_impl; And::And(const Predicate &predicate) : predicate_(predicate) {} -/* winter::data::sql_impl::And::And(const StatementValue &statement_value) : - l_statement_value_(statement_value), - condition_(winter::data::sql_impl::Condition::NONE) {} - -winter::data::sql_impl::And::And(const StatementValue &statement_value, - winter::data::sql_impl::Condition condition) : - l_statement_value_(statement_value), - condition_(condition) {} - -winter::data::sql_impl::And::And(const StatementValue &l_statement_value, - winter::data::sql_impl::Condition condition, - const StatementValue &r_statement_value) : - l_statement_value_(l_statement_value), - r_statement_value_(r_statement_value), - condition_(condition) {} */ - std::vector> And::And::Fields() const { - std::vector> fields; - fields.push_back(predicate_.field()); - return fields; + return predicate_.fields(); } std::string And::Query() const { std::ostringstream builder; - auto field = predicate_.field(); - auto lstatement = predicate_.lstatementStr(); - auto rstatement = predicate_.rstatementStr(); - auto condition = predicate_.conditionStr(); + std::string lstatement = predicate_.lstatementStr(); + std::string rstatement = predicate_.rstatementStr(); + std::string condition = predicate_.conditionStr(); - if (predicate_.has_field()) { + if (predicate_.has_fields()) { + std::shared_ptr field = predicate_.fields().front(); if (field->IsCustomValue()) { builder << lstatement << Space() << condition << Space() @@ -74,42 +57,4 @@ And::Query() const { builder << lstatement << Space() << condition; return replace_value(query_template_, query_param_, builder.str()); -} - -/* if (auto columnValue = std::get_if>(&l_statement_value_)) { - if (is_predicate_) { - if (field_->IsCustomValue()) { - builder << columnValue->get()->FullName() - << Space() << condition(condition_) << Space() - << field_->custom_value(); - } else { - builder << columnValue->get()->FullName() - << Space() << condition(condition_) << Space() - << PlaceHolder(); - } - return replace_value(query_template_, query_param_, builder.str()); - } - - builder << columnValue->get()->FullName() - << ((condition_ != Condition::NONE) - ? Space() + condition(condition_) - : ""); - return replace_value(query_template_, query_param_, builder.str()); - } else if (auto clauseValue = std::get_if>(&l_statement_value_)) { - builder << clauseValue->get()->Query(); - return replace_value(query_template_, query_param_, builder.str()); - } else if (auto statement = std::get_if>(&l_statement_value_)) { - builder << statement->get()->prepared_statement().statement_template() << Space() << condition(condition_) << Space(); - return replace_value(query_template_, query_param_, builder.str()); - } - - std::string typeName = StatementValueType(l_statement_value_.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); -} - */ \ No newline at end of file +} \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp index f0575b3..b8a6c11 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_from.cpp @@ -33,13 +33,19 @@ From::From(const std::vector &statement_value) { } std::vector> winter::data::sql_impl::From::Fields() const { - return {}; + std::vector> fields; + fields.reserve(predicate_.size()); + for (const auto &predicate : predicate_) { + auto predicateFields = predicate.fields(); + fields.insert(fields.end(), predicateFields.begin(), predicateFields.end()); + } + return fields; } std::string winter::data::sql_impl::From::Query() const { std::vector tablesNames; - - for (auto const &predicate : predicate_) { + tablesNames.reserve(predicate_.size()); + for (const auto &predicate : predicate_) { tablesNames.push_back(predicate.lstatementStr()); } return winter::util::string::replace_value( diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_in.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_in.cpp new file mode 100644 index 0000000..e7bed42 --- /dev/null +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_in.cpp @@ -0,0 +1,29 @@ +// +// Created by Samuel Azcona on 23/05/2020. +// +#include + +using namespace winter::data::sql_impl; + +In::In(const StatementValue& statement_value) : + predicate_(statement_value) {} + +In::In(const Predicate& predicate) : + predicate_(predicate) {} + +std::vector> In::Fields() const { + return predicate_.fields(); +}; + +std::string In::Query() const { + if (predicate_.has_fields()) { + return winter::util::string::replace_value( + query_template_, + query_param_, + CommaSeparatedParenthesesPlaceHolder(predicate_.fields().size())); + } + return winter::util::string::replace_value( + query_template_, + query_param_, + predicate_.lstatementStr()); +} \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp index 66667e0..6d11639 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_into.cpp @@ -8,31 +8,24 @@ #include #include -winter::data::sql_impl::Into::Into(const StatementValue &statement_value) : - statement_value_(statement_value) {} +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" -std::string winter::data::sql_impl::Into::Query() const { - std::string statement_query; - if (auto sharedTableValue = std::get_if>(&statement_value_)) { - statement_query = sharedTableValue->get()->name(); - } else if (auto tableValue = std::get_if
(&statement_value_)) { - statement_query = tableValue->name(); - } else { - std::string typeName = StatementValueType(statement_value_.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); - } +using namespace winter::data::sql_impl; +Into::Into(const Predicate &predicate) : + predicate_(predicate) {} + +Into::Into(const StatementValue &statementValue) : + predicate_(statementValue) {} + +std::string Into::Query() const { return winter::util::string::replace_value( query_template_, query_param_, - winter::data::sql_impl::CommaSeparatedValue({statement_query})); + predicate_.lstatementStr()); } -std::vector> Fields() { - return {}; +std::vector> Into::Fields() const { + return predicate_.fields(); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp index 68bca72..fe46b46 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_join.cpp @@ -12,52 +12,40 @@ #include #include -winter::data::sql_impl::Join::Join(const StatementValue& statement_value, - JoinType type) : - statement_value_(statement_value), +using namespace winter::data::sql_impl; + +Join::Join(const StatementValue& statement_value, + JoinType type) : + predicate_(statement_value), type_(type) { } -winter::data::sql_impl::Join::Join(const StatementValue& statement_value) : - statement_value_(statement_value), +Join::Join(const StatementValue& statement_value) : + predicate_(statement_value), type_(JoinType::DEFAULT) { } +std::vector> Join::Fields() const { + return predicate_.fields(); +} + std::string -winter::data::sql_impl::Join::Query() const { +Join::Query() const { std::string query = winter::util::string::replace_value(query_template_, "$type", GenerateType()); - - auto subQuery = [&]() -> std::string { - if (auto sharedTable = std::get_if>(&statement_value_)) { - return sharedTable->get()->name(); - } else if (auto table = std::get_if
(&statement_value_)) { - return table->name(); - } else if (auto clause = std::get_if>(&statement_value_)) { - return clause->get()->Query(); - } - - std::string typeName = StatementValueType(statement_value_.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); - }; - return winter::util::string::replace_value( query, query_param_, - winter::data::sql_impl::CommaSeparatedValue({subQuery()})); + predicate_.lstatementStr()); } -std::string winter::data::sql_impl::Join::GenerateType() const { +std::string Join::GenerateType() const { switch (type_) { case JoinType::INNER: return "INNER"; case JoinType::LEFT: return "LEFT"; case JoinType::RIGHT: return "RIGHT"; case JoinType::CROSS: return "CROSS"; case JoinType::DEFAULT: return "INNER"; + case JoinType::FULL_JOIN: return "FULL"; } return std::string(); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp index b2ba81e..ea7cec7 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp @@ -11,71 +11,47 @@ #include #include +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" using namespace winter::util::string; winter::data::sql_impl::Or::Or(const Predicate &predicate) : - statement_value_(predicate.lstatementValue()), - field_(predicate.field()), condition_(predicate.condition()), + predicate_(predicate), is_predicate_(true) {} winter::data::sql_impl::Or::Or(const StatementValue &statement_value) : - statement_value_(statement_value), - condition_(winter::data::sql_impl::Condition::NONE) {} + predicate_(statement_value) {} winter::data::sql_impl::Or::Or(const StatementValue &statement_value, winter::data::sql_impl::Condition condition) : - statement_value_(statement_value), - condition_(condition) {} + predicate_(statement_value, condition) {} std::vector> winter::data::sql_impl::Or::Or::Fields() const { - std::vector> fields; - fields.push_back(field_); - return fields; + return predicate_.fields(); } std::string winter::data::sql_impl::Or::Query() const { std::ostringstream builder; - auto subqueryfn = [&]() -> std::string { - if (auto sharedColumn = std::get_if>(&statement_value_)) { - return sharedColumn->get()->FullName(); - } else if (auto column = std::get_if(&statement_value_)) { - return column->FullName(); - } else if (auto clause = std::get_if>(&statement_value_)) { - return clause->get()->Query(); - } - std::string typeName = StatementValueType(statement_value_.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); - }; - - auto subquery = subqueryfn(); - if (is_predicate_) { - if (field_->IsCustomValue()) { - builder << subquery - << Space() << condition(condition_) << Space() - << field_->custom_value(); + const auto &field = predicate_.field(); + if (field->IsCustomValue()) { + builder << predicate_.lstatementStr() + << Space() << predicate_.conditionStr() << Space() + << field->custom_value(); } else { - builder << subquery - << Space() << condition(condition_) << Space() + builder << predicate_.lstatementStr() + << Space() << predicate_.conditionStr() << Space() << PlaceHolder(); } return replace_value(query_template_, query_param_, builder.str()); } - builder << subquery - << ((condition_ != Condition::NONE) - ? Space() + condition(condition_) - : ""); + builder << predicate_.lstatementStr() + << predicate_.conditionStr(); return replace_value(query_template_, query_param_, builder.str()); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp index 429707d..37fe9f2 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_predicate.cpp @@ -10,6 +10,7 @@ #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_operator.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values_utils.h" +#include "wintercpp/exception/generic/winter_internal_exception.h" using namespace winter::util::string; using namespace winter::data::sql_impl; @@ -18,6 +19,12 @@ Predicate::Predicate(const StatementValue& statement_value) : l_statement_value_(statement_value), condition_(Condition::NONE) {} +Predicate::Predicate(const std::shared_ptr& field) : + condition_(Condition::NONE), fields_(std::vector {field}) {} + +Predicate::Predicate(const std::vector>& fields) : + condition_(Condition::NONE), fields_(fields) {} + Predicate::Predicate( const StatementValue& statement_value, Condition conditionOperator) : @@ -25,19 +32,20 @@ Predicate::Predicate( condition_(conditionOperator) {} Predicate::Predicate( - const StatementValue& statement_value, - const std::shared_ptr& field) : + const StatementValue& statement_value, + const std::shared_ptr& field) : l_statement_value_(statement_value), condition_(Condition::NONE), - field_(field) {} + fields_(std::vector {field}) { +} Predicate::Predicate( - const winter::data::sql_impl::StatementValue& statement_value, - winter::data::sql_impl::Condition conditionOperator, - const std::shared_ptr& field) : + const StatementValue& statement_value, + Condition conditionOperator, + const std::shared_ptr& field) : l_statement_value_(statement_value), condition_(conditionOperator), - field_(field) {} + fields_(std::vector {field}) {} Predicate::Predicate( const StatementValue& l_statement_value, @@ -46,45 +54,65 @@ Predicate::Predicate( l_statement_value_(l_statement_value), condition_(conditionOperator), r_statement_value_(r_statement_value) {} -const winter::data::sql_impl::StatementValue& +const std::optional& Predicate::lstatementValue() const { return l_statement_value_; } -const std::optional& +const std::optional& Predicate::rstatementValue() const { return r_statement_value_; } -const std::shared_ptr& -Predicate::field() const { - return field_; +const std::vector>& +Predicate::fields() const { + return fields_; +} + +const std::shared_ptr& Predicate::field() const { + if (has_fields()) { + const std::shared_ptr& front = fields().front(); + if (front.get() != nullptr) { + return front; + } + } + throw winter::exception::WinterInternalException::Create( + __FILE__, + __FUNCTION__, + __LINE__, + "Predicate Fields empty"); } -winter::data::sql_impl::Condition Predicate::condition() const { +::Condition Predicate::condition() const { return condition_; } std::string Predicate::lstatementStr() const { - bool isClause = IsClause(l_statement_value_) || IsStatement(l_statement_value_); - std::string clauseValue = GetStatementValue(l_statement_value_); - return ((isClause) ? "(" + clauseValue + ")" : clauseValue); + return statementStr(l_statement_value_); } std::string Predicate::rstatementStr() const { - if (r_statement_value_) { - auto value = r_statement_value_.value(); + return statementStr(r_statement_value_); +}; + +std::string Predicate::statementStr(std::optional statement_value) const { + if (statement_value) { + auto value = statement_value.value(); bool isClause = IsClause(value) || IsStatement(value); std::string clauseValue = GetStatementValue(value); return ((isClause) ? "(" + clauseValue + ")" : clauseValue); } - return GetStatementValue(r_statement_value_); -}; + return GetStatementValue(statement_value); +} std::string Predicate::conditionStr() const { return ::condition(condition_); }; +bool Predicate::has_lstatement() const { + return l_statement_value_.has_value(); +}; + bool Predicate::has_rstatement() const { return r_statement_value_.has_value(); }; @@ -93,6 +121,6 @@ bool Predicate::has_condition() const { return condition_ != Condition::NONE; }; -bool Predicate::has_field() const { - return field_ != nullptr; +bool Predicate::has_fields() const { + return ! fields_.empty(); }; diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp index 6626fc1..9125a88 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp @@ -5,65 +5,43 @@ #include #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" +#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" using namespace winter::util::string; using namespace winter::data::sql_impl; Where::Where(const Predicate& predicate) : - statement_value_(predicate.lstatementValue()), - field_(predicate.field()), - condition_(predicate.condition()), + predicate_(predicate), _is_predicate(true) {} -Where::Where(StatementValue statement_value) : - statement_value_(std::move(statement_value)), - condition_(Condition::NONE) {} +Where::Where(const StatementValue& statement_value) : + predicate_(statement_value) {} Where::Where( - StatementValue statement_value, Condition condition) : - statement_value_(std::move(statement_value)), - condition_(condition) {} + const StatementValue& statement_value, Condition condition) : + predicate_(statement_value, condition) {} std::vector> Where::Fields() const { - std::vector> fields; - fields.push_back(field_); - return fields; + return predicate_.fields(); } std::string Where::Query() const { std::ostringstream builder; - if (auto columnValue = std::get_if>(&statement_value_)) { - if (_is_predicate) { - if (field_->IsCustomValue()) { - builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() - << Space() << condition(condition_) << Space() - << field_->custom_value(); - } else { - builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() - << Space() << condition(condition_) << Space() - << PlaceHolder(); - } - - return replace_value(query_template_, query_param_, builder.str()); - } - - builder << columnValue->get()->TableName() << Dot() << columnValue->get()->name() - << ((condition_ != Condition::NONE) - ? Space() + condition(condition_) - : ""); - return replace_value(query_template_, query_param_, builder.str()); - } else if (auto clauseValue = std::get_if>(&statement_value_)) { - builder << clauseValue->get()->Query(); - return replace_value(query_template_, query_param_, builder.str()); + bool isColumn = IsClause(predicate_.lstatementValue()); + + if (isColumn && predicate_.has_fields()) { + const auto& field = predicate_.field(); + const std::string value_str = field->IsCustomValue() ? field->custom_value() : PlaceHolder(); + builder << predicate_.lstatementStr() + << predicate_.conditionStr() + << value_str; + } else if (isColumn) { + builder << predicate_.lstatementStr() + << predicate_.conditionStr(); + } else { + builder << predicate_.lstatementStr(); } - - std::string typeName = StatementValueType(statement_value_.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); + return replace_value(query_template_, query_param_, builder.str()); } \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp b/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp index db20339..cadcf1a 100644 --- a/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp +++ b/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp @@ -91,6 +91,10 @@ std::string winter::data::sql_impl::CommaSeparatedPlaceHolder(size_t size) { return values; } +std::string winter::data::sql_impl::CommaSeparatedParenthesesPlaceHolder(size_t size) { + return "(" + CommaSeparatedPlaceHolder(size) + ")"; +} + std::string winter::data::sql_impl::Dot() { return "."; } diff --git a/wintercpp/test/winter_clause_in_test.cpp b/wintercpp/test/winter_clause_in_test.cpp new file mode 100644 index 0000000..56b96cf --- /dev/null +++ b/wintercpp/test/winter_clause_in_test.cpp @@ -0,0 +1,38 @@ +// +// Created by samuaz on 3/10/21. +// + +#include + +#include +#include +#include + +#include "gtest/gtest.h" +#include "wintercpp/data/sql/column/winter_data_sql_column.h" +#include "wintercpp/data/sql/statement/winter_data_sql_select.h" + +using namespace winter::data::sql_impl; + +struct QueryTestTableMin : public UUIDTable { + QueryTestTableMin() : + UUIDTable("QueryTestTableMin", true, DatabaseType::kGeneric) {} + const Column col1 = String("col1"); + const Column col2 = String("col2"); + const Column col3 = String("col3"); + const Column col4 = String("col4"); + const Column col5 = String("col5"); +}; + +TEST(winteInClause, canCreateInWithValues) { + std::vector values {1,2,3}; + auto inClause = In::Values(values); + ASSERT_EQ(inClause.Query(), "IN (?,?,?)"); +} + +TEST(winteInClause, canCreateInWithSubClause) { + std::shared_ptr testTable = std::make_shared(); + auto selectShared = std::shared_ptr
"; - case 4: - return "std::shared_ptr"; - case 5: - return "std::shared_ptr #include +#include #include #include #include namespace winter::data::sql_impl { + inline std::string StatementValueType(size_t index) { + switch (index) { + case 0: + return "Column"; + case 1: + return "std::shared_ptr"; + case 2: + return "Table"; + case 3: + return "std::shared_ptr
"; + case 4: + return "std::shared_ptr"; + case 5: + return "std::shared_ptr>(&statement_value)) { return sharedColumn->get()->FullName(); diff --git a/wintercpp/include/wintercpp/util/winter_string_util.h b/wintercpp/include/wintercpp/util/winter_string_util.h index aaed140..1d6168f 100644 --- a/wintercpp/include/wintercpp/util/winter_string_util.h +++ b/wintercpp/include/wintercpp/util/winter_string_util.h @@ -19,6 +19,8 @@ namespace winter::util::string { void strip_unicode(std::string &str); + void trim_string(std::string &str); + } // namespace winter::util::string #endif // WINTERCPP_WINTER_STRING_UTIL_H diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp index da581c3..d508835 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_and.cpp @@ -19,42 +19,40 @@ using namespace winter::util::string; using namespace winter::data::sql_impl; -And::And(const Predicate &predicate) : +And::And(const Predicate& predicate) : predicate_(predicate) {} std::vector> And::And::Fields() const { return predicate_.fields(); } -std::string -And::Query() const { +std::string And::Query() const { std::ostringstream builder; std::string lstatement = predicate_.lstatementStr(); std::string rstatement = predicate_.rstatementStr(); std::string condition = predicate_.conditionStr(); + std::string result; if (predicate_.has_fields()) { - std::shared_ptr field = predicate_.fields().front(); - if (field->IsCustomValue()) { - builder << lstatement - << Space() << condition << Space() - << field->custom_value(); - } else { - builder << lstatement - << Space() << condition << Space() - << PlaceHolder(); + for (auto& field : predicate_.fields()) { + if (field->IsCustomValue()) { + builder << lstatement + << Space() << condition << Space() + << field->custom_value().value(); + } else { + builder << lstatement + << Space() << condition << Space() + << PlaceHolder(); + } } - return replace_value(query_template_, query_param_, builder.str()); - } - - if (predicate_.has_rstatement()) { + } else if (predicate_.has_rstatement()) { builder << lstatement << Space() << condition << Space() << rstatement; - return replace_value(query_template_, query_param_, builder.str()); + } else { + builder << lstatement + << Space() << condition; } - builder << lstatement - << Space() << condition; return replace_value(query_template_, query_param_, builder.str()); } \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_not_in.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_not_in.cpp new file mode 100644 index 0000000..925dd97 --- /dev/null +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_not_in.cpp @@ -0,0 +1,29 @@ +// +// Created by Samuel Azcona on 23/05/2020. +// +#include + +using namespace winter::data::sql_impl; + +NotIn::NotIn(const StatementValue& statement_value) : + predicate_(statement_value) {} + +NotIn::NotIn(const Predicate& predicate) : + predicate_(predicate) {} + +std::vector> NotIn::Fields() const { + return predicate_.fields(); +}; + +std::string NotIn::Query() const { + if (predicate_.has_fields()) { + return winter::util::string::replace_value( + query_template_, + query_param_, + CommaSeparatedParenthesesPlaceHolder(predicate_.fields().size())); + } + return winter::util::string::replace_value( + query_template_, + query_param_, + predicate_.lstatementStr()); +} \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp index f4c1f26..df939e7 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_on.cpp @@ -10,56 +10,38 @@ #include -#include "wintercpp/data/sql/column/winter_data_sql_column.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" -winter::data::sql_impl::On::On(const StatementValue &l_statement_value, - winter::data::sql_impl::Condition condition, - const StatementValue &r_statement_value) : - l_statement_value_(l_statement_value), - r_statement_value_(r_statement_value), condition_(condition) {} +using namespace winter::data::sql_impl; +using namespace winter::util::string; -winter::data::sql_impl::On::On(const StatementValue &l_statement_value, - winter::data::sql_impl::Condition condition) : - l_statement_value_(l_statement_value), - condition_(condition) {} +On::On(const StatementValue &l_statement_value, + Condition condition, + const StatementValue &r_statement_value) : + predicate_(l_statement_value, condition, r_statement_value) {} -std::vector> winter::data::sql_impl::On::Fields() const { - return {}; +On::On(const StatementValue &l_statement_value, + Condition condition) : + predicate_(l_statement_value, condition) {} + +std::vector> On::Fields() const { + return predicate_.fields(); }; std::string -winter::data::sql_impl::On::Query() const { - auto getStatementValue = [](const StatementValue &statement_value) -> std::string { - if (auto sharedColumnValue = std::get_if>(&statement_value)) { - return sharedColumnValue->get()->FullName(); - } else if (auto columnValue = std::get_if(&statement_value)) { - return columnValue->FullName(); - } else if (auto clauseValue = std::get_if>(&statement_value)) { - return clauseValue->get()->Query(); - } else { - std::string typeName = StatementValueType(statement_value.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); - } - }; - +On::Query() const { std::string result = winter::util::string::replace_value( query_template_, query_param_l, - getStatementValue(l_statement_value_)); + predicate_.lstatementStr()); - if (r_statement_value_.has_value() && r_statement_value_.value().index() != std::variant_npos) { - result = winter::util::string::replace_value( - result, - query_param_r, - getStatementValue(r_statement_value_.value())); - } + result = winter::util::string::replace_value( + result, + query_param_r, + predicate_.rstatementStr()); - return winter::util::string::replace_value( - result, query_param_condition, sql_impl::condition(condition_)); + std::string query = replace_value(result, query_param_condition, predicate_.conditionStr()); + trim_string(query); + return query; } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp index ea7cec7..709c134 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_or.cpp @@ -17,8 +17,7 @@ using namespace winter::util::string; winter::data::sql_impl::Or::Or(const Predicate &predicate) : - predicate_(predicate), - is_predicate_(true) {} + predicate_(predicate) {} winter::data::sql_impl::Or::Or(const StatementValue &statement_value) : predicate_(statement_value) {} @@ -34,24 +33,31 @@ std::vectorIsCustomValue()) { - builder << predicate_.lstatementStr() - << Space() << predicate_.conditionStr() << Space() - << field->custom_value(); - } else { - builder << predicate_.lstatementStr() - << Space() << predicate_.conditionStr() << Space() - << PlaceHolder(); + std::string lstatement = predicate_.lstatementStr(); + std::string rstatement = predicate_.rstatementStr(); + std::string condition = predicate_.conditionStr(); + + std::string result; + if (predicate_.has_fields()) { + for (auto &field : predicate_.fields()) { + if (field->IsCustomValue()) { + builder << lstatement + << Space() << condition << Space() + << field->custom_value().value(); + } else { + builder << lstatement + << Space() << condition << Space() + << PlaceHolder(); + } } - - return replace_value(query_template_, query_param_, builder.str()); + } else if (predicate_.has_rstatement()) { + builder << lstatement + << Space() << condition << Space() + << rstatement; + } else { + builder << lstatement + << Space() << condition; } - builder << predicate_.lstatementStr() - << predicate_.conditionStr(); - return replace_value(query_template_, query_param_, builder.str()); -} +} \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp index 24eb64a..699590b 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_parenthesis.cpp @@ -3,36 +3,25 @@ // #include +#include +#include #include #include -#include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" winter::data::sql_impl::Parenthesis::Parenthesis( const winter::data::sql_impl::StatementValue& statement_value) : - statement_value_(statement_value) {} + predicate_(statement_value) {} std::vector> winter::data::sql_impl::Parenthesis::Fields() const { - return {}; + return predicate_.fields(); }; std::string winter::data::sql_impl::Parenthesis::Query() const { - auto clauseQuery = [&]() -> std::string { - if (auto clause = std::get_if>(&statement_value_)) { - return clause->get()->Query(); - } - std::string typeName = StatementValueType(statement_value_.index()); - std::string error = "invalid statement_value " + typeName + "not supported"; - throw ::winter::exception::WinterInternalException::Create( - __FILE__, - __FUNCTION__, - __LINE__, - (error)); - }; - return winter::util::string::replace_value( query_template_, query_param_, - clauseQuery()); + predicate_.lstatementStr()); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp index e42e594..86ab2d7 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_set.cpp @@ -11,13 +11,28 @@ #include #include -winter::data::sql_impl::Set::Set(const std::vector> &fields) : - fields_(fields) {} - -std::string -winter::data::sql_impl::Set::Query() const { - return winter::util::string::replace_value( - query_template_, - query_param_, - winter::data::sql_impl::commaSeparatedEqualValue(fields_)); -} +#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" + +namespace winter::data::sql_impl { + + Set::Set(const std::vector> &fields) : + predicate_(fields) {} + + Set::Set(const std::shared_ptr &field) : + predicate_(field) {} + + Set::Set(const Predicate &predicate) : + predicate_(predicate) {} + + std::vector> Set::Fields() const { + return predicate_.fields(); + } + + std::string + Set::Query() const { + return winter::util::string::replace_value( + query_template_, + query_param_, + commaSeparatedEqualValue(predicate_.fields())); + } +} // namespace winter::data::sql_impl \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp index 28ca32d..51139eb 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_values.cpp @@ -12,25 +12,26 @@ #include winter::data::sql_impl::Values::Values(const std::vector>& fields) : - fields_(fields) {} + predicate_(fields) {} std::vector> winter::data::sql_impl::Values::Fields() const { - return fields_; + return predicate_.fields(); }; std::string winter::data::sql_impl::Values::Query() const { std::vector columns; + auto fields = predicate_.fields(); - for (const auto& field : fields_) { columns.push_back(field->name()); } + for (const auto& field : fields) { columns.push_back(field->name()); } std::string query = winter::util::string::replace_value( query_template_, - query_param_values_, + query_param_columns_, winter::data::sql_impl::CommaSeparatedValue(columns)); return winter::util::string::replace_value( query, query_param_values_, - winter::data::sql_impl::CommaSeparatedStatement(fields_)); + winter::data::sql_impl::CommaSeparatedStatement(fields)); } diff --git a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp index 9125a88..40ae2b7 100644 --- a/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp +++ b/wintercpp/src/data/sql/statement/clause/winter_data_sql_clause_where.cpp @@ -4,7 +4,6 @@ #include #include -#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause.h" #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" @@ -12,8 +11,7 @@ using namespace winter::util::string; using namespace winter::data::sql_impl; Where::Where(const Predicate& predicate) : - predicate_(predicate), - _is_predicate(true) {} + predicate_(predicate) {} Where::Where(const StatementValue& statement_value) : predicate_(statement_value) {} @@ -29,19 +27,31 @@ std::vectorIsCustomValue() ? field->custom_value() : PlaceHolder(); + const std::string value_str = field->IsCustomValue() ? field->custom_value().value() : PlaceHolder(); builder << predicate_.lstatementStr() + << Space() << predicate_.conditionStr() + << Space() << value_str; - } else if (isColumn) { + } else if (isColumn && ! haveRStatement) { builder << predicate_.lstatementStr() + << Space() << predicate_.conditionStr(); + } else if (haveRStatement) { + builder << predicate_.lstatementStr() + << Space() + << predicate_.conditionStr() + << Space() + << predicate_.rstatementStr(); } else { - builder << predicate_.lstatementStr(); + builder << predicate_.lstatementStr() + << Space() + << predicate_.conditionStr(); } return replace_value(query_template_, query_param_, builder.str()); } \ No newline at end of file diff --git a/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp b/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp index cadcf1a..84469aa 100644 --- a/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp +++ b/wintercpp/src/data/sql/statement/winter_data_sql_statement_util.cpp @@ -40,7 +40,7 @@ std::string winter::data::sql_impl::commaSeparatedEqualValue( for (unsigned long i = 0; i < size; i++) { auto row = columns[i]; if (row->IsCustomValue()) { - values += row->name() + Equal() += row->custom_value() + values += row->name() + Equal() += row->custom_value().value() + std::string(i == size - 1 ? Nothing() : Comma()); } else { values += row->name() + Equal() += PlaceHolder() += std::string(i == size - 1 ? Nothing() : Comma()); @@ -57,7 +57,7 @@ std::string winter::data::sql_impl::CommaSeparatedStatement( for (unsigned long i = 0; i < size; i++) { auto row = columns[i]; if (row->IsCustomValue()) { - values += Space() += row->custom_value() + values += Space() += row->custom_value().value() + std::string(i == size - 1 ? Nothing() : Comma()); } else { values += PlaceHolder() += std::string(i == size - 1 ? Nothing() : Comma()); @@ -74,7 +74,7 @@ std::string winter::data::sql_impl::CommaSeparatedStatement( for (unsigned long i = 0; i < size; i++) { auto row = columns[i]; if (row->IsCustomValue()) { - values += Space() += row->custom_value() + values += Space() += row->custom_value().value() + std::string(i == size - 1 ? Nothing() : Comma()); } else { values += PlaceHolder() += std::string(i == size - 1 ? Nothing() : Comma()); diff --git a/wintercpp/src/util/winter_string_util.cpp b/wintercpp/src/util/winter_string_util.cpp index 4b174b6..7bdbddc 100644 --- a/wintercpp/src/util/winter_string_util.cpp +++ b/wintercpp/src/util/winter_string_util.cpp @@ -7,38 +7,102 @@ #include #include -std::string winter::util::string::replace(std::string &str, - const std::string &from, - const std::string &to) { - size_t start_pos = str.find(from); - if (start_pos != std::string::npos) { - str.replace(start_pos, from.length(), to); +namespace winter::util::string { + + /** + * @brief Replaces all occurrences of a substring in a string. + * + * This function returns a new string where every occurrence of the specified substring is replaced + * with another string. The original string IS MODIFIED. + * + * @param str The input string to search for substrings. + * @param from The substring to replace. + * @param to The string to replace `from` with. + * @return A new string where all occurrences of `from` have been replaced with `to`. + */ + std::string replace(std::string& str, const std::string& from, const std::string& to) { + str = replace_value(str, from, to); + return str; + } + + /** + * @brief Replaces all occurrences of a substring in a string. + * + * This function returns a new string where every occurrence of the specified substring is replaced + * with another string. The original string is not modified. + * + * @param str The input string to search for substrings. + * @param from The substring to replace. + * @param to The string to replace `from` with. + * @return A new string where all occurrences of `from` have been replaced with `to`. + */ + + std::string replace_value(std::string str, const std::string& from, const std::string& to) { + size_t start_pos = 0; + const size_t from_len = from.length(); + const size_t to_len = to.length(); + + // Use a loop and std::string::find() to find all occurrences of the substring. + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + // When we find a match, use std::string::replace() to replace it with the new string. + str.replace(start_pos, from_len, to); + // Increment start_pos to avoid replacing the same substring again. + start_pos += to_len; + } + + // Return the modified string. + return str; } - return str; -} - -std::string winter::util::string::replace_value(std::string str, - const std::string &from, - const std::string &to) { - size_t start_pos = str.find(from); - if (start_pos != std::string::npos) { - str.replace(start_pos, from.length(), to); + + /** + * @brief Removes non-ASCII characters and whitespace from a string. + * + * This function modifies the input string by removing any characters that are outside + * the ASCII range (with a value greater than 127) or are considered whitespace according + * to the classic C locale. The resulting string will only contain ASCII characters that + * are not whitespace. + * + * @param str The string to modify. + */ + void strip_unicode(std::string& str) { + // Use the erase-remove idiom to remove non-ASCII characters and whitespace. + // This works by calling std::remove_if to move all unwanted characters to the end + // of the string, then erasing them with the corresponding call to str.erase(). + str.erase(std::remove_if(str.begin(), str.end(), [](char c) { + // Check if the character is outside of the ASCII range or is whitespace. + // We use static_cast to convert the char to an unsigned char for comparison. + // We also use std::isspace() to check if it's a whitespace character. + return static_cast(c) > 127 || std::isspace(c, std::locale::classic()); + }), + str.end()); + } + + /** + * @brief Removes leading and trailing whitespace from a string. + * + * This function modifies the input string to remove any whitespace characters (e.g. spaces, tabs, + * newlines) that appear at the beginning or end of the string. + * + * @param str The string to modify. + */ + void trim_string(std::string& str) { + // Find the first non-whitespace character. + const size_t start = str.find_first_not_of(" \t\n\v\f\r"); + if (start == std::string::npos) { + // If the string is empty or contains only whitespace, clear it. + str.clear(); + return; + } + + // Trim leading whitespace by erasing it from the string. + str.erase(0, start); + + // Find the last non-whitespace character. + const size_t end = str.find_last_not_of(" \t\n\v\f\r"); + + // Trim trailing whitespace by erasing it from the string. + if (end != std::string::npos && end != str.length() - 1) { + str.erase(end + 1); + } } - return str; -} - -void winter::util::string::strip_unicode(std::string &str) { - str.erase(remove_if(str.begin(), - str.end(), - [](char c) -> bool { - return ! (c >= 0 && c < 128); - }), - str.end()); - - str.erase(std::remove_if(str.begin(), - str.end(), - [l = std::locale {}](auto x) { - return std::isspace(x, l); - }), - str.end()); -} +} // namespace winter::util::string \ No newline at end of file diff --git a/wintercpp/test/winter_clause_and_test.cpp b/wintercpp/test/winter_clause_and_test.cpp index 14a1ecf..409726e 100644 --- a/wintercpp/test/winter_clause_and_test.cpp +++ b/wintercpp/test/winter_clause_and_test.cpp @@ -49,21 +49,21 @@ TEST(winteAndClause, canCreateSubClauseAndValue) { Select *select = new Select({testTable->col1}); select->AddClause(From(testTable)); auto selectShared = std::shared_ptr(select); - Predicate predicate = Predicate::MakePredicate(selectShared, Condition::IS_NOT_NULL); + Predicate predicate = Predicate::Make(selectShared, Condition::IS_NOT_NULL); auto andClause = And(predicate); ASSERT_EQ(andClause.Query(), "AND (SELECT QueryTestTableMin.col1 FROM QueryTestTableMin) IS NOT NULL"); } \ No newline at end of file diff --git a/wintercpp/test/winter_clause_not_in_test.cpp b/wintercpp/test/winter_clause_not_in_test.cpp new file mode 100644 index 0000000..eeeb734 --- /dev/null +++ b/wintercpp/test/winter_clause_not_in_test.cpp @@ -0,0 +1,36 @@ +// +// Created by samuaz on 3/10/21. +// + +#include + +#include +#include +#include + +#include "gtest/gtest.h" + +using namespace winter::data::sql_impl; + +struct QueryTestTableMin : public UUIDTable { + QueryTestTableMin() : + UUIDTable("QueryTestTableMin", true, DatabaseType::kGeneric) {} + const Column col1 = String("col1"); + const Column col2 = String("col2"); + const Column col3 = String("col3"); + const Column col4 = String("col4"); + const Column col5 = String("col5"); +}; + +TEST(winteNotInClause, canCreatenNotInWithValues) { + std::vector values {1,2,3}; + auto notInClause = NotIn::Values(values); + ASSERT_EQ(notInClause.Query(), "NOT IN (?,?,?)"); +} + +TEST(winteNotInClause, canCreateNotInWithSubClause) { + std::shared_ptr testTable = std::make_shared(); + auto selectShared = std::shared_ptr(new Select({testTable->col1})); + auto on = On(selectShared, Condition::EQ, selectShared); + ASSERT_EQ(on.Query(), "ON (SELECT QueryTestTableMin.col1) = (SELECT QueryTestTableMin.col1)"); +} + +TEST(winteOnClause, canCreateOnWithClauseConditionColumn) { + std::shared_ptr testTable = std::make_shared(); + auto selectShared = std::shared_ptr(new Select({testTable->col1})); + auto on = On(selectShared, Condition::IS_NOT_NULL); + ASSERT_EQ(on.Query(), "ON (SELECT QueryTestTableMin.col1) IS NOT NULL"); +} \ No newline at end of file diff --git a/wintercpp/test/winter_clause_or_test.cpp b/wintercpp/test/winter_clause_or_test.cpp new file mode 100644 index 0000000..a928294 --- /dev/null +++ b/wintercpp/test/winter_clause_or_test.cpp @@ -0,0 +1,67 @@ +// +// Created by samuaz on 3/10/21. +// + +#include + +#include +#include +#include + +#include "gtest/gtest.h" + +using namespace winter::data::sql_impl; + +struct QueryTestTableMin : public UUIDTable { + QueryTestTableMin() : + UUIDTable("QueryTestTableMin", true, DatabaseType::kGeneric) {} + const Column col1 = String("col1"); + const Column col2 = String("col2"); + const Column col3 = String("col3"); + const Column col4 = String("col4"); + const Column col5 = String("col5"); +}; + +TEST(winteOrClause, canCreateSubClause) { + std::shared_ptr testTable = std::make_shared(); + Select *select = new Select({testTable->col1}); + select->AddClause(From(testTable)); + auto selectShared = std::shared_ptr(select); + Predicate predicate = Predicate::Make(selectShared, Condition::LESS_EQ, 10); + auto orClause = Or(predicate); + ASSERT_EQ(orClause.Query(), "OR (SELECT QueryTestTableMin.col1 FROM QueryTestTableMin) <= ?"); +} + +TEST(winteOrClause, canCreateSubColumnAndValue) { + std::shared_ptr testTable = std::make_shared(); + Predicate predicate = Predicate::Make(testTable->col1, Condition::LESS_EQ, 10); + auto orClause = Or(predicate); + ASSERT_EQ(orClause.Query(), "OR QueryTestTableMin.col1 <= ?"); +} + +TEST(winteOrClause, canCreateSubColumnAndCondition) { + std::shared_ptr testTable = std::make_shared(); + Predicate predicate = Predicate::Make(testTable->col1, Condition::IS_NOT_NULL); + auto orClause = Or(predicate); + ASSERT_EQ(orClause.Query(), "OR QueryTestTableMin.col1 IS NOT NULL"); +} + +TEST(winteOrClause, canCreateSubClauseAndCondition) { + std::shared_ptr testTable = std::make_shared(); + Select *select = new Select({testTable->col1}); + select->AddClause(From(testTable)); + auto selectShared = std::shared_ptr(new Select({testTable->col1})); + auto whereClause = Where(Predicate::Make(selectShared, Condition::IS_NOT_NULL)); + ASSERT_EQ(whereClause.Query(), "WHERE (SELECT QueryTestTableMin.col1) IS NOT NULL"); +} + From d012d531cff25b0ba56d32e6521773c3618eee1f Mon Sep 17 00:00:00 2001 From: samuaz Date: Thu, 27 Jul 2023 01:51:41 -0300 Subject: [PATCH 5/8] fix fieldtype with std::variant --- .../data/sql/field/winter_data_sql_field.h | 37 +++++++------- .../data/sql/field/winter_data_sql_field.tpp | 25 ---------- .../sql/field/winter_data_sql_field_type.h | 41 +++++++++++++++ ...winter_data_sql_prepared_statement_field.h | 26 +++++----- .../clause/winter_data_sql_clause_in.h | 4 +- .../clause/winter_data_sql_clause_not_in.h | 7 +-- .../clause/winter_data_sql_clause_predicate.h | 49 ++++++++---------- .../clause/winter_data_sql_clause_set.h | 9 ++-- .../clause/winter_data_sql_clause_values.h | 17 +++---- .../sql/statement/winter_data_sql_statement.h | 11 ++-- .../statement/winter_data_sql_statement.tpp | 16 +++--- .../data/sql/field/winter_data_sql_field.cpp | 22 ++++++++ wintercpp/test/winter_clause_and_test.cpp | 6 --- wintercpp/test/winter_clause_in_test.cpp | 3 +- wintercpp/test/winter_clause_not_in_test.cpp | 3 +- wintercpp/test/winter_clause_values_test.cpp | 8 +-- wintercpp/test/winter_clause_where_test.cpp | 3 +- .../test/winter_preparedStatement_test.cpp | 50 +++++++++---------- 18 files changed, 182 insertions(+), 155 deletions(-) delete mode 100644 wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.tpp create mode 100644 wintercpp/src/data/sql/field/winter_data_sql_field.cpp diff --git a/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.h b/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.h index f9110c7..9f86484 100644 --- a/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.h +++ b/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.h @@ -10,40 +10,43 @@ namespace winter::data::sql_impl { - template + class Field : public virtual AbstractField { public: - explicit Field(T value) : - value_(std::move(value)), type_(TypeField::Get()) {} + explicit Field(const DataType& value) : + value_(value) { + using T = std::decay_t; + type_ = GetFieldType(); + } - Field(std::string name, T value) : - name_(std::move(name)), value_(std::move(value)), - type_(TypeField::Get()) {} + Field(const std::string& name, const DataType& value) : + name_(name), value_(value) { + using T = std::decay_t; + type_ = GetFieldType(); + } - Field(const Field &field) : - value_(field.value_), type_(field.type_), name_(field.name_) {} + Field(const Field& field) : + name_(field.name_), value_(field.value_), type_(field.type_) {} - explicit Field(const Field *field) : - value_(field->value_), type_(field->type_), name_(field->name_) {} + explicit Field(const Field* field) : + name_(field->name_), value_(field->value_), type_(field->type_) {} - const T &value() const; + const DataType& value() const; - const FieldType &type() const override; + const FieldType& type() const override; - const std::string &name() const override; + const std::string& name() const override; - void value(T value); + void value(DataType value); ~Field() override = default; protected: std::string name_; - T value_; + DataType value_; FieldType type_; }; } // namespace winter::data::sql_impl -#include "winter_data_sql_field.tpp" - #endif /* WINTER_DATA_SQL_FIELD */ diff --git a/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.tpp b/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.tpp deleted file mode 100644 index b34bf43..0000000 --- a/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field.tpp +++ /dev/null @@ -1,25 +0,0 @@ -//#include "winter_data_sql_abstract_field.h" - -namespace winter::data::sql_impl { - - template - const T& Field::value() const { - return value_; - } - - template - const FieldType& Field::type() const { - return type_; - } - - template - const std::string& Field::name() const { - return name_; - } - - template - void Field::value(T value) { - value_ = value; - } - -} // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field_type.h b/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field_type.h index 8783961..fede555 100644 --- a/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field_type.h +++ b/wintercpp/include/wintercpp/data/sql/field/winter_data_sql_field_type.h @@ -141,6 +141,47 @@ namespace winter::data::sql_impl { static FieldType Get(); }; + template + FieldType GetFieldType() { + if constexpr (std::is_same_v) { + return FieldType::kUchar; + } else if constexpr (std::is_same_v) { + return FieldType::kUshort; + } else if constexpr (std::is_same_v) { + return FieldType::KUint; + } else if constexpr (std::is_same_v) { + return FieldType::kBigInt; + } else if constexpr (std::is_same_v) { + return FieldType::kSchar; + } else if constexpr (std::is_same_v) { + return FieldType::KShort; + } else if constexpr (std::is_same_v) { + return FieldType::kInt; + } else if constexpr (std::is_same_v) { + return FieldType::kLong; + } else if constexpr (std::is_same_v) { + return FieldType::kChar; + } else if constexpr (std::is_same_v) { + return FieldType::KShort; + } else if constexpr (std::is_same_v) { + return FieldType::kLong; + } else if constexpr (std::is_same_v) { + return FieldType::KDecimal; + } else if constexpr (std::is_same_v) { + return FieldType::kDouble; + } else if constexpr (std::is_same_v) { + return FieldType::kFloat; + } else if constexpr (std::is_same_v) { + return FieldType::kBoolean; + } else if constexpr (std::is_same_v) { + return FieldType::kString; + } else if constexpr (std::is_same_v) { + return FieldType::kBlob; + } else { + return FieldType::kNull; // Valor por defecto en caso de no coincidir con ninguno + } + } + } // namespace winter::data::sql_impl #endif /* WINTER_DATA_SQL_FIELD_TYPE */ diff --git a/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement_field.h b/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement_field.h index 82c5f01..89b3111 100644 --- a/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement_field.h +++ b/wintercpp/include/wintercpp/data/sql/preparedstatement/winter_data_sql_prepared_statement_field.h @@ -11,29 +11,29 @@ #include "../field/winter_data_sql_field.h" #include "winter_data_sql_abstract_prepared_statement_field.h" +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" namespace winter::data::sql_impl { - template class PreparedStatementField : - public virtual Field, + public virtual Field, public virtual AbstractPreparedStatementField { public: - explicit PreparedStatementField(const T &value) : - Field(value) {} + explicit PreparedStatementField(const DataType &value) : + Field(value) {} - PreparedStatementField(const std::string &name, const T &value) : - Field(name, value), custom_value_(std::nullopt) {} + PreparedStatementField(const std::string &name, const DataType &value) : + Field(name, value), custom_value_(std::nullopt) {} - PreparedStatementField(const std::string &name, const T &value, const std::optional &custom_value) : - Field(name, value), + PreparedStatementField(const std::string &name, const DataType &value, const std::optional &custom_value) : + Field(name, value), custom_value_(custom_value) {} - PreparedStatementField(const PreparedStatementField &field) : - Field(field), custom_value_(field.custom_value_) {} + PreparedStatementField(const PreparedStatementField &field) : + Field(field), custom_value_(field.custom_value_) {} - explicit PreparedStatementField(const PreparedStatementField *field) : - Field(field), + explicit PreparedStatementField(const PreparedStatementField *field) : + Field(field), custom_value_(field->custom_value_) {} const std::optional &custom_value() const override { @@ -53,7 +53,7 @@ namespace winter::data::sql_impl { }; template - using QUERY_FIELD = std::shared_ptr >; + using QUERY_FIELD = std::shared_ptr; } // namespace winter::data::sql_impl diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h index 4440041..5b415ec 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_in.h @@ -18,6 +18,7 @@ #include #include +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" namespace winter::data::sql_impl { @@ -29,8 +30,7 @@ namespace winter::data::sql_impl { std::string Query() const override; std::vector> Fields() const override; - template - static In Values(const std::vector& values_) { + static In Values(const std::vector& values_) { return In(Predicate::Make(values_)); } diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h index 787805f..8664a91 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_not_in.h @@ -17,6 +17,8 @@ #include #include +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" + namespace winter::data::sql_impl { class NotIn : public virtual Clause { @@ -26,9 +28,8 @@ namespace winter::data::sql_impl { std::string Query() const override; std::vector> Fields() const override; - template - static NotIn Values(const std::vector& values_) { - return NotIn(Predicate::Make(values_)); + static NotIn Values(const std::vector& values) { + return NotIn(Predicate::Make(values)); } private: diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h index 8b04ceb..118c379 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h @@ -23,6 +23,7 @@ #include #include +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement.h" namespace winter::data::sql_impl { @@ -53,63 +54,55 @@ namespace winter::data::sql_impl { Condition conditionOperator, const StatementValue& r_statement_value); - template - static Predicate Make(const Column& column, - T value) { - return Predicate(column, std::make_shared>(column->FullName(), value)); + static Predicate Make(const Column& column, + const DataType& value) { + return Predicate(column, std::make_shared(column->FullName(), value)); } - template - static Predicate Make(const Column& column, - Condition condition, - T value) { - return Predicate(column, condition, std::make_shared>(column->FullName(), value)); + static Predicate Make(const Column& column, + Condition condition, + const DataType& value) { + return Predicate(column, condition, std::make_shared(column->FullName(), value)); } - template static Predicate Make(const Column& column, Condition condition, - T value, + const DataType& value, const std::string& custom_value) { return Predicate(column, condition, - std::make_shared>(column->FullName(), value, custom_value)); + std::make_shared(column->FullName(), value, custom_value)); } - template static Predicate Make( - const Column& column, - T value, + const Column& column, + const DataType value, const std::string& custom_value) { - return Predicate(std::make_shared>(column->FullName(), value, custom_value)); + return Predicate(std::make_shared(column->FullName(), value, custom_value)); } - template static Predicate Make(const std::string& valueName, - T value) { - return Predicate(std::make_shared>(valueName, value)); + const DataType& value) { + return Predicate(std::make_shared(valueName, value)); } - template static Predicate Make(const StatementValue& statement_value, Condition condition, - T value) { + const DataType& value) { return Predicate(statement_value, condition, - std::make_shared>(value)); + std::make_shared(value)); } - template - static Predicate Make(T value) { - return Predicate(std::make_shared>(value)); + static Predicate Make(const DataType& value) { + return Predicate(std::make_shared(value)); } - template - static Predicate Make(const std::vector& values) { + static Predicate Make(const std::vector& values) { std::vector> fields; fields.reserve(values.size()); for (const auto& value : values) { - fields.push_back(std::make_shared>(value)); + fields.push_back(std::make_shared(value)); } return Predicate(fields); } diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h index cfe9300..cd38ea5 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_set.h @@ -12,6 +12,7 @@ #include #include +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h" #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" @@ -26,14 +27,12 @@ namespace winter::data::sql_impl { std::string Query() const override; std::vector> Fields() const override; - template - static std::shared_ptr> Add(const Column &column, T value, const std::optional &custom_value_ = nullopt) { + static std::shared_ptr Add(const Column &column, const DataType &value, const std::optional &custom_value_ = nullopt) { return Set::Add(column.FullName(), value, custom_value_); } - template - static std::shared_ptr> Add(const std::string &name, T value, const std::optional &custom_value_ = nullopt) { - return std::make_shared>(name, value, custom_value_); + static std::shared_ptr Add(const std::string &name, const DataType &value, const std::optional &custom_value_ = nullopt) { + return std::make_shared(name, value, custom_value_); } private: diff --git a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h index 4bbed31..f0b704d 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h +++ b/wintercpp/include/wintercpp/data/sql/statement/clause/winter_data_sql_clause_values.h @@ -12,6 +12,7 @@ #include #include +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" #include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" namespace winter::data::sql_impl { @@ -23,17 +24,15 @@ namespace winter::data::sql_impl { std::string Query() const override; std::vector> Fields() const override; - template - static std::shared_ptr> Add( - const Column &column, T value) { - return std::make_shared>(column->FullName(), - value); + static std::shared_ptr Add( + const Column &column, const DataType &value) { + return std::make_shared(column->FullName(), + value); } - template - static std::shared_ptr> Add( - const Column &column, T value, const std::string &custom_value) { - return std::make_shared>( + static std::shared_ptr Add( + const Column &column, const DataType &value, const std::string &custom_value) { + return std::make_shared( column->FullName(), value, custom_value); } diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.h b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.h index 9028f05..86549e7 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.h +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.h @@ -11,6 +11,8 @@ #include #include +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" + namespace winter::data::sql_impl { class IStatement { @@ -39,15 +41,12 @@ namespace winter::data::sql_impl { Children &set_statement_template(const std::string &statement_template); */ - template - Children &Value(const T value); + Children &Value(const DataType &value); - template - Children &Value(const Column &row, const T value); + Children &Value(const Column &row, const DataType &value); - template Children &Value(const Column &row, - const T value, + const DataType &value, const std::string &custom_value); const PreparedStatement &prepared_statement() override; diff --git a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp index 57d296b..48a3ee9 100644 --- a/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp +++ b/wintercpp/include/wintercpp/data/sql/statement/winter_data_sql_statement.tpp @@ -3,6 +3,7 @@ // //#include "wintercpp/data/sql/statement/winter_data_sql_statement.h" +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" namespace winter::data::sql_impl { template @@ -49,27 +50,24 @@ namespace winter::data::sql_impl { }; */ template - template - Children &Statement::Value(const T value) { - prepared_statement_->AddValue(new PreparedStatementField(value)); + Children &Statement::Value(const DataType &value) { + prepared_statement_->AddValue(new PreparedStatementField(value)); return This(); }; template - template - Children &Statement::Value(const Column &row, const T value) { + Children &Statement::Value(const Column &row, const DataType &value) { prepared_statement_->AddValue( - new PreparedStatementField(row->name(), value)); + new PreparedStatementField(row->name(), value)); return This(); }; template - template Children &Statement::Value(const Column &row, - const T value, + const DataType &value, const std::string &custom_value) { prepared_statement_->AddValue( - new PreparedStatementField(row->name(), value, custom_value)); + new PreparedStatementField(row->name(), value, custom_value)); return This(); }; diff --git a/wintercpp/src/data/sql/field/winter_data_sql_field.cpp b/wintercpp/src/data/sql/field/winter_data_sql_field.cpp new file mode 100644 index 0000000..82dfb86 --- /dev/null +++ b/wintercpp/src/data/sql/field/winter_data_sql_field.cpp @@ -0,0 +1,22 @@ + +#include + +namespace winter::data::sql_impl { + + const DataType& Field::value() const { + return value_; + } + + const FieldType& Field::type() const { + return type_; + } + + const std::string& Field::name() const { + return name_; + } + + void Field::value(DataType value) { + value_ = value; + } + +} // namespace winter::data::sql_impl diff --git a/wintercpp/test/winter_clause_and_test.cpp b/wintercpp/test/winter_clause_and_test.cpp index 409726e..11d54df 100644 --- a/wintercpp/test/winter_clause_and_test.cpp +++ b/wintercpp/test/winter_clause_and_test.cpp @@ -9,12 +9,6 @@ #include #include "gtest/gtest.h" -#include "wintercpp/data/sql/column/winter_data_sql_column.h" -#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_and.h" -#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_from.h" -#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_operator.h" -#include "wintercpp/data/sql/statement/clause/winter_data_sql_clause_predicate.h" -#include "wintercpp/data/sql/statement/winter_data_sql_select.h" // AND (SELECT columna4 FROM tabla2 WHERE columna5 = 'bar') < (SELECT columna6 FROM tabla3 WHERE columna7 = 'baz') // AND (SELECT columna4 FROM tabla2 WHERE columna5 = 'bar') < 10 diff --git a/wintercpp/test/winter_clause_in_test.cpp b/wintercpp/test/winter_clause_in_test.cpp index 56b96cf..92d3770 100644 --- a/wintercpp/test/winter_clause_in_test.cpp +++ b/wintercpp/test/winter_clause_in_test.cpp @@ -10,6 +10,7 @@ #include "gtest/gtest.h" #include "wintercpp/data/sql/column/winter_data_sql_column.h" +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" #include "wintercpp/data/sql/statement/winter_data_sql_select.h" using namespace winter::data::sql_impl; @@ -25,7 +26,7 @@ struct QueryTestTableMin : public UUIDTable { }; TEST(winteInClause, canCreateInWithValues) { - std::vector values {1,2,3}; + std::vector values {1, 2, 3}; auto inClause = In::Values(values); ASSERT_EQ(inClause.Query(), "IN (?,?,?)"); } diff --git a/wintercpp/test/winter_clause_not_in_test.cpp b/wintercpp/test/winter_clause_not_in_test.cpp index eeeb734..0d38bd9 100644 --- a/wintercpp/test/winter_clause_not_in_test.cpp +++ b/wintercpp/test/winter_clause_not_in_test.cpp @@ -9,6 +9,7 @@ #include #include "gtest/gtest.h" +#include "wintercpp/data/sql/field/winter_data_sql_data_type.h" using namespace winter::data::sql_impl; @@ -23,7 +24,7 @@ struct QueryTestTableMin : public UUIDTable { }; TEST(winteNotInClause, canCreatenNotInWithValues) { - std::vector values {1,2,3}; + std::vector values {1,2,3}; auto notInClause = NotIn::Values(values); ASSERT_EQ(notInClause.Query(), "NOT IN (?,?,?)"); } diff --git a/wintercpp/test/winter_clause_values_test.cpp b/wintercpp/test/winter_clause_values_test.cpp index eeed502..b205861 100644 --- a/wintercpp/test/winter_clause_values_test.cpp +++ b/wintercpp/test/winter_clause_values_test.cpp @@ -17,8 +17,8 @@ struct QueryTestTableMin : public UUIDTable { QueryTestTableMin() : UUIDTable("QueryTestTableMin", true, DatabaseType::kGeneric) {} const Column col1 = String("col1"); - const Column col2 = String("col2"); - const Column col3 = String("col3"); + const Column col2 = Int("col2"); + const Column col3 = Boolean("col3"); const Column col4 = String("col4"); const Column col5 = String("col5"); }; @@ -33,8 +33,8 @@ TEST(winteValuesClause, canCreateValuesClauseMultipleValue) { std::shared_ptr testTable = std::make_shared(); auto valuesClause = Values({ Values::Add(testTable->col1, "hola"), - Values::Add(testTable->col2, "hola"), - Values::Add(testTable->col3, "hola") + Values::Add(testTable->col2, 10), + Values::Add(testTable->col3, true) }); ASSERT_EQ(valuesClause.Query(), "(QueryTestTableMin.col1, QueryTestTableMin.col2, QueryTestTableMin.col3) VALUES (?,?,?)"); } \ No newline at end of file diff --git a/wintercpp/test/winter_clause_where_test.cpp b/wintercpp/test/winter_clause_where_test.cpp index 2448131..628c15f 100644 --- a/wintercpp/test/winter_clause_where_test.cpp +++ b/wintercpp/test/winter_clause_where_test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "gtest/gtest.h" #include "wintercpp/data/sql/statement/winter_data_sql_statement_values.h" @@ -63,7 +64,7 @@ TEST(winteSelectClause, canCreateSelectClauseTwoWithStatement) { TEST(winteSelectClause, canCreateSelectClauseWithStatement) { std::shared_ptr testTable = std::make_shared(); - auto selectShared = std::shared_ptr::prepared_statement_; using Statement(query, StatementType::kSelect) {} + Statement("SELECT $columns", StatementType::kSelect) {} -Select::Select(std::vector values) : - Statement("SELECT $columns", StatementType::kSelect), - value_(std::move(values)) {} +Select::Select(const std::vector &values) : + Statement