diff --git a/backends/sqlite/include/sqlite_prepared_result_reader.hpp b/backends/sqlite/include/sqlite_prepared_result_reader.hpp index 9b55404..c90eff6 100644 --- a/backends/sqlite/include/sqlite_prepared_result_reader.hpp +++ b/backends/sqlite/include/sqlite_prepared_result_reader.hpp @@ -32,7 +32,7 @@ public: void read_value(const char *id, size_t index, char *value, size_t s) override; void read_value(const char *id, size_t index, std::string &value) override; void read_value(const char *id, size_t index, std::string &value, size_t s) override; - void read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size) override; + void read_value(const char *id, size_t index, sql::value &val, size_t size) override; private: sqlite3 *db_{nullptr}; diff --git a/backends/sqlite/src/sqlite_prepared_result_reader.cpp b/backends/sqlite/src/sqlite_prepared_result_reader.cpp index 3097d52..ba6d528 100644 --- a/backends/sqlite/src/sqlite_prepared_result_reader.cpp +++ b/backends/sqlite/src/sqlite_prepared_result_reader.cpp @@ -107,8 +107,8 @@ void sqlite_prepared_result_reader::read_value(const char *id, size_t index, std query_result_reader::read_value(id, index, value, s); } -void sqlite_prepared_result_reader::read_value(const char *id, size_t index, sql::any_type &value, sql::data_type_t type, size_t size) +void sqlite_prepared_result_reader::read_value(const char *id, size_t index, sql::value &val, size_t size) { - query_result_reader::read_value(id, index, value, type, size); + query_result_reader::read_value(id, index, val, size); } } \ No newline at end of file diff --git a/backends/tests/SessionTest.cpp b/backends/tests/SessionTest.cpp index 5a92a98..ceccf68 100644 --- a/backends/tests/SessionTest.cpp +++ b/backends/tests/SessionTest.cpp @@ -45,7 +45,7 @@ TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]") REQUIRE(true); } -TEST_CASE_METHOD(SessionFixture, "Find object with id", "[session][find]") { +TEST_CASE_METHOD(SessionFixture, "Use session to find object with id", "[session][find]") { using namespace matador::test; ses.attach("airplane"); ses.create_schema(); diff --git a/include/matador/sql/data_type_traits.hpp b/include/matador/sql/data_type_traits.hpp index 0c9f432..ef23b14 100644 --- a/include/matador/sql/data_type_traits.hpp +++ b/include/matador/sql/data_type_traits.hpp @@ -53,6 +53,15 @@ template < class Type, class Enable = void > struct data_type_traits; /// @cond MATADOR_DEV +template <> struct data_type_traits +{ + inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_null; } + static void read_value(query_result_reader &reader, const char *id, size_t index, nullptr_t &/*value*/); + static void bind_value(parameter_binder &binder, size_t index, nullptr_t &/*value*/); + static void bind_result_value(result_parameter_binder &binder, size_t index, nullptr_t &/*value*/); + inline static any_type create_value(char &value) { return value; } +}; + template <> struct data_type_traits { inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; } @@ -199,7 +208,7 @@ template <> struct data_type_traits template <> struct data_type_traits { - inline static data_type_t builtin_type(std::size_t size) { return data_type_t::type_blob; } + inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_blob; } static void read_value(query_result_reader &reader, const char *id, size_t index, utils::blob &value); static void bind_value(parameter_binder &binder, size_t index, utils::blob &value); static void bind_result_value(result_parameter_binder &binder, size_t index, utils::blob &value); diff --git a/include/matador/sql/entity_query_builder.hpp b/include/matador/sql/entity_query_builder.hpp index 31cb661..f6a1c29 100644 --- a/include/matador/sql/entity_query_builder.hpp +++ b/include/matador/sql/entity_query_builder.hpp @@ -6,6 +6,7 @@ #include "matador/sql/query_context.hpp" #include "matador/sql/query.hpp" #include "matador/sql/query_intermediates.hpp" +#include "matador/sql/value.hpp" #include @@ -24,20 +25,19 @@ struct entity_query_data { std::unique_ptr where_clause; }; -template < typename PrimaryKeyType > class entity_query_builder { public: - explicit entity_query_builder(const PrimaryKeyType &pk, const schema &scm) - : pk_(pk) - , schema_(scm) {} + explicit entity_query_builder(const schema &scm) + : schema_(scm) {} - template - std::optional build() { + template + std::optional build(const PrimaryKeyType &pk) { const auto info = schema_.info(); if (!info) { return std::nullopt; } + pk_ = pk; table_info_stack_.push(info.value()); entity_query_data_ = { info->name }; EntityType obj; @@ -50,24 +50,13 @@ public: void on_primary_key(const char *id, V &, typename std::enable_if::value && !std::is_same::value>::type* = 0) { push(id); - if (is_root_entity() && std::is_integral_v) { - entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == pk_); + if (is_root_entity() && pk_.is_integer()) { + entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == *pk_.as()); } } - void on_primary_key(const char *id, std::string &, size_t) - { - push(id); - if (!is_root_entity()) { - auto b = std::is_same_v; - std::cout << "is matching primary key: " << std::boolalpha << b << "\n"; - } - } - - void on_revision(const char *id, unsigned long long &/*rev*/) - { - push(id); - } + void on_primary_key(const char *id, std::string &, size_t); + void on_revision(const char *id, unsigned long long &/*rev*/); template void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) @@ -174,26 +163,12 @@ public: void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &/*attr*/) {} private: - void push(const std::string &column_name) - { - char str[4]; - snprintf(str, 4, "c%02d", ++column_index); - entity_query_data_.columns.emplace_back(table_info_stack_.top().name, column_name, str); - } + void push(const std::string &column_name); + [[nodiscard]] bool is_root_entity() const; + void append_join(const column &left, const column &right); - [[nodiscard]] bool is_root_entity() const { - return table_info_stack_.size() == 1; - } - - void append_join(const column &left, const column &right) - { - entity_query_data_.joins.push_back({ - { left.table }, - make_condition(left == right) - }); - } private: - PrimaryKeyType pk_; + value pk_; std::stack table_info_stack_; const schema &schema_; entity_query_data entity_query_data_; diff --git a/include/matador/sql/field.hpp b/include/matador/sql/field.hpp index 0dcefdc..a749397 100644 --- a/include/matador/sql/field.hpp +++ b/include/matador/sql/field.hpp @@ -1,11 +1,7 @@ #ifndef QUERY_FIELD_HPP #define QUERY_FIELD_HPP -#include "matador/sql/any_type.hpp" -#include "matador/sql/any_type_to_visitor.hpp" -#include "matador/sql/data_type_traits.hpp" - -#include "matador/utils/types.hpp" +#include "matador/sql/value.hpp" #include #include @@ -19,10 +15,8 @@ public: template field(std::string name, Type value, size_t size = 0, int index = -1) : name_(std::move(name)) - , size_(size) , index_(index) - , value_(value) - , type_(data_type_traits::builtin_type(size)) {} + , value_(value, size) {} field(std::string name, data_type_t data_type, size_t size = 0, int index = -1); field(const field &x) = default; field& operator=(const field &x) = default; @@ -32,7 +26,7 @@ public: template field& operator=(Type value) { value_ = std::move(value); - type_ = data_type_traits::builtin_type(-1); + return *this; } @@ -43,9 +37,7 @@ public: template std::optional as() const { - any_type_to_visitor visitor; - std::visit(visitor, const_cast(value_)); - return visitor.result; + return value_.as(); } [[nodiscard]] std::string str() const; @@ -65,7 +57,7 @@ private: template void process(Operator &op) { - op.on_attribute(name_.c_str(), value_, type_, size_); + op.on_attribute(name_.c_str(), value_, value_.size()); } private: @@ -73,9 +65,8 @@ private: std::string name_; int index_{-1}; - any_type value_; - size_t size_{}; - data_type_t type_; + + value value_; }; } diff --git a/include/matador/sql/query_result_impl.hpp b/include/matador/sql/query_result_impl.hpp index 334128e..581bdff 100644 --- a/include/matador/sql/query_result_impl.hpp +++ b/include/matador/sql/query_result_impl.hpp @@ -15,6 +15,8 @@ namespace matador::sql { +class value; + namespace detail { class pk_reader { @@ -74,7 +76,7 @@ public: } void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes); void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes); - void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes); + void on_attribute(const char *id, value &val, const utils::field_attributes &attr = utils::null_attributes); template < class Pointer > void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr) diff --git a/include/matador/sql/query_result_reader.hpp b/include/matador/sql/query_result_reader.hpp index 915bfde..a18bf26 100644 --- a/include/matador/sql/query_result_reader.hpp +++ b/include/matador/sql/query_result_reader.hpp @@ -6,6 +6,8 @@ namespace matador::sql { +class value; + class query_result_reader { public: @@ -34,7 +36,7 @@ public: virtual void read_value(const char *id, size_t index, std::string &value); virtual void read_value(const char *id, size_t index, std::string &value, size_t s); virtual void read_value(const char *id, size_t index, utils::blob &value); - virtual void read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size); + virtual void read_value(const char *id, size_t index, value &val, size_t size); }; } diff --git a/include/matador/sql/session.hpp b/include/matador/sql/session.hpp index eb6e629..8c41639 100644 --- a/include/matador/sql/session.hpp +++ b/include/matador/sql/session.hpp @@ -43,8 +43,8 @@ public: return {}; } - entity_query_builder eqb(pk, *schema_); - auto data = eqb.template build(); + entity_query_builder eqb(*schema_); + auto data = eqb.build(pk); auto q = c->query(*schema_) .select(data->columns) diff --git a/include/matador/sql/value.hpp b/include/matador/sql/value.hpp new file mode 100644 index 0000000..c3ff003 --- /dev/null +++ b/include/matador/sql/value.hpp @@ -0,0 +1,81 @@ +#ifndef QUERY_VALUE_HPP +#define QUERY_VALUE_HPP + +#include "matador/sql/any_type.hpp" +#include "matador/sql/any_type_to_visitor.hpp" +#include "matador/sql/data_type_traits.hpp" + +#include "matador/utils/types.hpp" + +#include + +namespace matador::sql { + +namespace detail { +template +size_t determine_size(const Type &/*val*/) +{ + return 0; +} +size_t determine_size(const std::string &val); +size_t determine_size(const char *val); +size_t determine_size(const utils::blob &val); + +} +class value +{ +public: + value() = default; + template + explicit value(Type value, size_t size = 0) + : size_(size) + , value_(value) + , type_(data_type_traits::builtin_type(size)) {} + explicit value(data_type_t data_type, size_t size = 0); + value(const value &x) = default; + value& operator=(const value &x) = default; + template + value& operator=(Type val) + { + value_ = val; + size_ = detail::determine_size(val); + type_ = data_type_traits::builtin_type(size_); + return *this; + } + value(value &&x) noexcept; + value& operator=(value &&x) noexcept; + + template + std::optional as() const + { + if (std::holds_alternative(value_)) { + return std::get(value_); + } else { + any_type_to_visitor visitor; + std::visit(visitor, const_cast(value_)); + return visitor.result; + } + } + [[nodiscard]] std::string str() const; + + [[nodiscard]] size_t size() const; + [[nodiscard]] data_type_t type() const; + + [[nodiscard]] bool is_integer() const; + [[nodiscard]] bool is_floating_point() const; + [[nodiscard]] bool is_bool() const; + [[nodiscard]] bool is_string() const; + [[nodiscard]] bool is_varchar() const; + [[nodiscard]] bool is_blob() const; + [[nodiscard]] bool is_null() const; + [[nodiscard]] bool is_unknown() const; + +private: + any_type value_; + size_t size_{}; + data_type_t type_{data_type_t::type_unknown}; + +}; + +} +#endif //QUERY_VALUE_HPP diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8d730de..59839af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -37,6 +37,8 @@ set(SQL_SOURCES sql/any_type_to_string_visitor.cpp sql/field.cpp sql/table_definition.cpp + sql/value.cpp + sql/entity_query_builder.cpp ) set(SQL_HEADER @@ -92,6 +94,7 @@ set(SQL_HEADER ../include/matador/sql/entity_query_builder.hpp ../include/matador/sql/table_definition.hpp ../include/matador/sql/has_many_to_many_relation.hpp + ../include/matador/sql/value.hpp ) set(UTILS_HEADER diff --git a/src/sql/column_definition.cpp b/src/sql/column_definition.cpp index 4291d8f..97ad391 100644 --- a/src/sql/column_definition.cpp +++ b/src/sql/column_definition.cpp @@ -110,6 +110,10 @@ void column_definition::type(data_type_t type) std::string column_definition::str() const { + if (std::holds_alternative(value_)) { + return std::get(value_); + } + any_type_to_visitor visitor; std::visit(visitor, const_cast(value_)); return visitor.result; diff --git a/src/sql/data_type_traits.cpp b/src/sql/data_type_traits.cpp index 69f134f..5fedc18 100644 --- a/src/sql/data_type_traits.cpp +++ b/src/sql/data_type_traits.cpp @@ -6,6 +6,21 @@ namespace matador::sql { +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, nullptr_t &/*value*/) +{ +// reader.read_value(id, index, value); +} + +void data_type_traits::bind_value(parameter_binder &binder, size_t index, nullptr_t &/*value*/) +{ +// binder.bind(index, value); +} + +void data_type_traits::bind_result_value(result_parameter_binder &binder, size_t index, nullptr_t &/*value*/) +{ +// binder.bind_result_value(index, value); +} + void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, char &value) { reader.read_value(id, index, value); diff --git a/src/sql/dialect.cpp b/src/sql/dialect.cpp index e11c4b9..07433b0 100644 --- a/src/sql/dialect.cpp +++ b/src/sql/dialect.cpp @@ -37,7 +37,7 @@ std::string dialect::prepare_identifier_string(const std::string &col) const for (auto &part : parts) { escape_quotes_in_identifier(part); -// quote_identifier(part); + quote_identifier(part); } return utils::join(parts, "."); } diff --git a/src/sql/entity_query_builder.cpp b/src/sql/entity_query_builder.cpp new file mode 100644 index 0000000..6d96555 --- /dev/null +++ b/src/sql/entity_query_builder.cpp @@ -0,0 +1,38 @@ +#include "matador/sql/entity_query_builder.hpp" + +namespace matador::sql { + +void entity_query_builder::on_primary_key(const char *id, std::string &, size_t) +{ + push(id); + if (!is_root_entity()) { + auto b = pk_.is_varchar(); + std::cout << "is matching primary key: " << std::boolalpha << b << "\n"; + } +} + +void entity_query_builder::on_revision(const char *id, unsigned long long &/*rev*/) +{ + push(id); +} + +void entity_query_builder::push(const std::string &column_name) +{ + char str[4]; + snprintf(str, 4, "c%02d", ++column_index); + entity_query_data_.columns.emplace_back(table_info_stack_.top().name, column_name, str); +} + +[[nodiscard]] bool entity_query_builder::is_root_entity() const { + return table_info_stack_.size() == 1; +} + +void entity_query_builder::append_join(const column &left, const column &right) +{ + entity_query_data_.joins.push_back({ + { left.table }, + make_condition(left == right) + }); +} + +} \ No newline at end of file diff --git a/src/sql/field.cpp b/src/sql/field.cpp index 229b9c1..c3364a0 100644 --- a/src/sql/field.cpp +++ b/src/sql/field.cpp @@ -7,24 +7,20 @@ namespace matador::sql { field::field(std::string name) : name_(std::move(name)) , value_(nullptr) - , type_(data_type_t::type_unknown) {} field::field(std::string name, data_type_t data_type, size_t size, int index) : name_(std::move(name)) - , size_(size) , index_(index) - , type_(data_type) {} + , value_(data_type, size) {} field::field(field &&x) noexcept : name_(std::move(x.name_)) , index_(x.index_) , value_(std::move(x.value_)) - , type_(x.type_) { x.value_ = nullptr; x.index_ = -1; - x.type_ = data_type_t::type_unknown; } field &field::operator=(field &&x) noexcept @@ -32,10 +28,8 @@ field &field::operator=(field &&x) noexcept name_ = std::move(x.name_); index_ = x.index_; value_ = std::move(x.value_); - type_ = x.type_; x.index_ = -1; x.value_ = nullptr; - x.type_ = data_type_t::type_unknown; return *this; } @@ -47,7 +41,7 @@ const std::string &field::name() const size_t field::size() const { - return size_; + return value_.size(); } int field::index() const @@ -68,42 +62,42 @@ std::string field::str() const bool field::is_integer() const { - return type_ >= data_type_t::type_char && type_ <= data_type_t::type_unsigned_long_long; + return value_.is_integer(); } bool field::is_floating_point() const { - return type_ == data_type_t::type_float || type_ == data_type_t::type_double; + return value_.is_floating_point(); } bool field::is_bool() const { - return type_ == data_type_t::type_bool; + return value_.is_bool(); } bool field::is_string() const { - return type_ == data_type_t::type_text; + return value_.is_string(); } bool field::is_varchar() const { - return type_ == data_type_t::type_varchar; + return value_.is_varchar(); } bool field::is_blob() const { - return type_ == data_type_t::type_blob; + return value_.is_blob(); } bool field::is_null() const { - return type_ == data_type_t::type_null; + return value_.is_null(); } bool field::is_unknown() const { - return type_ == data_type_t::type_unknown; + return value_.is_unknown(); } } \ No newline at end of file diff --git a/src/sql/query_result_impl.cpp b/src/sql/query_result_impl.cpp index 76e2de4..a21ede0 100644 --- a/src/sql/query_result_impl.cpp +++ b/src/sql/query_result_impl.cpp @@ -1,5 +1,6 @@ #include "matador/sql/query_result_impl.hpp" #include "matador/sql/query_result_reader.hpp" +#include "matador/sql/value.hpp" namespace matador::sql { @@ -39,9 +40,9 @@ void query_result_impl::on_attribute(const char *id, std::string &value, const u } void -query_result_impl::on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr) +query_result_impl::on_attribute(const char *id, value &val, const utils::field_attributes &attr) { - reader_->read_value(id, column_index_++, value, type, attr.size()); + reader_->read_value(id, column_index_++, val, attr.size()); } const std::vector& query_result_impl::prototype() const diff --git a/src/sql/query_result_reader.cpp b/src/sql/query_result_reader.cpp index cf27589..79e7328 100644 --- a/src/sql/query_result_reader.cpp +++ b/src/sql/query_result_reader.cpp @@ -1,5 +1,6 @@ #include "matador/sql/query_result_reader.hpp" #include "matador/sql/to_value.hpp" +#include "matador/sql/value.hpp" namespace matador::sql { @@ -104,82 +105,82 @@ void query_result_reader::read_value(const char *id, size_t index, utils::blob & } template < typename Type > -void convert(const char *valstr, sql::any_type &value) +void convert(const char *valstr, value &val) { - Type val{}; - sql::to_value(val, valstr); - value = val; + Type local_val{}; + sql::to_value(local_val, valstr); + val = local_val; } -void query_result_reader::read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size) +void query_result_reader::read_value(const char *id, size_t index, value &val, size_t size) { - switch (type) { + switch (val.type()) { case sql::data_type_t::type_char: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_short: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_int: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_long: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_long_long: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_unsigned_char: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_unsigned_short: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_unsigned_int: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_unsigned_long: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_unsigned_long_long: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_float: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_double: - convert(column(index), value); + convert(column(index), val); break; case sql::data_type_t::type_bool: { - int val{}; - sql::to_value(val, column(index)); - value = val > 0; + int local_val{}; + sql::to_value(local_val, column(index)); + val = local_val > 0; break; } case sql::data_type_t::type_text: case sql::data_type_t::type_varchar: { - value = std::string{column(index)}; + val = std::string{column(index)}; break; } case sql::data_type_t::type_char_pointer: { - value = column(index); + val = column(index); break; } case sql::data_type_t::type_time: case sql::data_type_t::type_date: { - value = std::string{column(index)}; + val = std::string{column(index)}; break; } case sql::data_type_t::type_null: { - value = nullptr_t{}; + val = nullptr_t{}; break; } case sql::data_type_t::type_blob: { - value = utils::blob{}; + val = utils::blob{}; break; } case sql::data_type_t::type_unknown: { - value = std::string(column(index)); + val = std::string(column(index)); break; } } diff --git a/src/sql/value.cpp b/src/sql/value.cpp new file mode 100644 index 0000000..cedc26b --- /dev/null +++ b/src/sql/value.cpp @@ -0,0 +1,99 @@ +#include "matador/sql/value.hpp" + +namespace matador::sql { +namespace detail { + +size_t determine_size(const std::string &val) +{ + return val.size(); +} + +size_t determine_size(const char *val) +{ + return strlen(val); +} + +size_t determine_size(const utils::blob &val) +{ + return val.size(); +} + +} +value::value(data_type_t data_type, size_t size) +: size_(size) +, type_(data_type) {} + +value::value(value &&x) noexcept + : value_(std::move(x.value_)) + , type_(x.type_) +{ + x.value_ = nullptr; + x.type_ = data_type_t::type_unknown; +} + +value &value::operator=(value &&x) noexcept +{ + value_ = std::move(x.value_); + type_ = x.type_; + x.value_ = nullptr; + x.type_ = data_type_t::type_unknown; + + return *this; +} + +std::string value::str() const +{ + return as().value(); +} + +size_t value::size() const +{ + return size_; +} + +data_type_t value::type() const +{ + return type_; +} + +bool value::is_integer() const +{ + return type_ >= data_type_t::type_char && type_ <= data_type_t::type_unsigned_long_long; +} + +bool value::is_floating_point() const +{ + return type_ == data_type_t::type_float || type_ == data_type_t::type_double; +} + +bool value::is_bool() const +{ + return type_ == data_type_t::type_bool; +} + +bool value::is_string() const +{ + return type_ == data_type_t::type_text; +} + +bool value::is_varchar() const +{ + return type_ == data_type_t::type_varchar || type_ == data_type_t::type_char_pointer; +} + +bool value::is_blob() const +{ + return type_ == data_type_t::type_blob; +} + +bool value::is_null() const +{ + return type_ == data_type_t::type_null; +} + +bool value::is_unknown() const +{ + return type_ == data_type_t::type_unknown; +} + +} \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4f9cec2..7d3608e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -40,7 +40,8 @@ add_executable(tests models/author.hpp models/book.hpp FieldTest.cpp - models/recipe.hpp) + models/recipe.hpp + ValueTest.cpp) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain diff --git a/test/ColumnDefinitionGeneratorTest.cpp b/test/ColumnDefinitionGeneratorTest.cpp index 77aa88d..d8fd9f3 100644 --- a/test/ColumnDefinitionGeneratorTest.cpp +++ b/test/ColumnDefinitionGeneratorTest.cpp @@ -9,7 +9,7 @@ using namespace matador::sql; using namespace matador::utils; -TEST_CASE("Generate columns from object", "[column generator]") { +TEST_CASE("Generate column definitions from object", "[column][definition][generator]") { schema repo("main"); auto columns = column_definition_generator::generate(repo); diff --git a/test/EntityQueryBuilderTest.cpp b/test/EntityQueryBuilderTest.cpp index eedde0c..de1998d 100644 --- a/test/EntityQueryBuilderTest.cpp +++ b/test/EntityQueryBuilderTest.cpp @@ -17,9 +17,9 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent scm.attach("authors"); scm.attach("books"); - entity_query_builder eqb(17, scm); + entity_query_builder eqb(scm); - auto data = eqb.build(); + auto data = eqb.build(17); REQUIRE(data.has_value()); REQUIRE(data->root_table_name == "books"); @@ -41,7 +41,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent } std::vector> expected_join_data { - { "books", "books.author_id = authors.id"} + { "books", R"("books"."author_id" = "authors"."id")"} }; query_context qc; @@ -54,7 +54,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent REQUIRE(data->where_clause); auto cond = data->where_clause->evaluate(db.dialect(), qc); - REQUIRE(cond == "books.id = 17"); + REQUIRE(cond == R"("books"."id" = 17)"); auto q = db.query(scm) .select(data->columns) @@ -77,9 +77,9 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q scm.attach("order_details"); scm.attach("orders"); - entity_query_builder eqb(17, scm); + entity_query_builder eqb(scm); - auto data = eqb.build(); + auto data = eqb.build(17); REQUIRE(data.has_value()); REQUIRE(data->root_table_name == "orders"); @@ -107,7 +107,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q } std::vector> expected_join_data { - { "orders", "orders.order_id = order_details.order_id"} + { "orders", R"("orders"."order_id" = "order_details"."order_id")"} }; query_context qc; @@ -120,7 +120,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q REQUIRE(data->where_clause); auto cond = data->where_clause->evaluate(db.dialect(), qc); - REQUIRE(cond == "orders.order_id = 17"); + REQUIRE(cond == R"("orders"."order_id" = 17)"); } TEST_CASE("Create sql query data for entity with eager many to many", "[query][entity][builder]") { @@ -131,9 +131,9 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e scm.attach("ingredients"); scm.attach("recipe_ingredients"); - entity_query_builder eqb(17, scm); + entity_query_builder eqb(scm); - auto data = eqb.build(); + auto data = eqb.build(17); REQUIRE(data.has_value()); REQUIRE(data->root_table_name == "ingredients"); @@ -150,8 +150,8 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e } std::vector> expected_join_data { - { "ingredients", "ingredients.id = recipe_ingredients.ingredient_id"}, - { "recipes", "recipes.id = recipe_ingredients.recipe_id"} + { "ingredients", R"("ingredients"."id" = "recipe_ingredients"."ingredient_id")"}, + { "recipes", R"("recipes"."id" = "recipe_ingredients"."recipe_id")"} }; query_context qc; @@ -164,5 +164,5 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e REQUIRE(data->where_clause); auto cond = data->where_clause->evaluate(db.dialect(), qc); - REQUIRE(cond == "ingredients.id = 17"); + REQUIRE(cond == R"("ingredients"."id" = 17)"); } \ No newline at end of file diff --git a/test/FieldTest.cpp b/test/FieldTest.cpp index b645d53..bb0b4bb 100644 --- a/test/FieldTest.cpp +++ b/test/FieldTest.cpp @@ -9,8 +9,8 @@ TEST_CASE("Field test", "[field]") { REQUIRE(f.name() == "name"); REQUIRE(f.index() == -1); - REQUIRE(f.is_unknown()); - REQUIRE(!f.is_null()); + REQUIRE(!f.is_unknown()); + REQUIRE(f.is_null()); REQUIRE(!f.is_integer()); REQUIRE(!f.is_floating_point()); REQUIRE(!f.is_blob()); diff --git a/test/ValueTest.cpp b/test/ValueTest.cpp new file mode 100644 index 0000000..48da82f --- /dev/null +++ b/test/ValueTest.cpp @@ -0,0 +1,70 @@ +#include + +#include "matador/sql/value.hpp" +#include "matador/utils/types.hpp" + +using namespace matador::sql; + +TEST_CASE("Test value class", "[value]") { + value v; + + REQUIRE(v.is_unknown()); + REQUIRE(v.type() == data_type_t::type_unknown); + REQUIRE(v.size() == 0); + + v = 7; + + REQUIRE(v.is_integer()); + REQUIRE(v.type() == data_type_t::type_int); + REQUIRE(v.size() == 0); + REQUIRE(v.as() == 7); + REQUIRE(v.as() == 7); + + v = "test"; + + REQUIRE(v.is_varchar()); + REQUIRE(v.type() == data_type_t::type_char_pointer); + REQUIRE(v.size() == 4); + + v = std::string{"hello"}; + + REQUIRE(v.is_varchar()); + REQUIRE(v.type() == data_type_t::type_varchar); + REQUIRE(v.size() == 5); + + v = 4.5; + + REQUIRE(v.is_floating_point()); + REQUIRE(v.type() == data_type_t::type_double); + REQUIRE(v.size() == 0); + + v = 6.7f; + + REQUIRE(v.is_floating_point()); + REQUIRE(v.type() == data_type_t::type_float); + REQUIRE(v.size() == 0); + + v = std::string(); + + REQUIRE(v.is_string()); + REQUIRE(v.type() == data_type_t::type_text); + REQUIRE(v.size() == 0); + + v = true; + + REQUIRE(v.is_bool()); + REQUIRE(v.type() == data_type_t::type_bool); + REQUIRE(v.size() == 0); + + v = nullptr; + + REQUIRE(v.is_null()); + REQUIRE(v.type() == data_type_t::type_null); + REQUIRE(v.size() == 0); + + v = matador::utils::blob{ 1, 2, 3, 4 }; + + REQUIRE(v.is_blob()); + REQUIRE(v.type() == data_type_t::type_blob); + REQUIRE(v.size() == 4); +} \ No newline at end of file