diff --git a/backends/postgres/src/postgres_connection.cpp b/backends/postgres/src/postgres_connection.cpp index ed7f39d..777832f 100644 --- a/backends/postgres/src/postgres_connection.cpp +++ b/backends/postgres/src/postgres_connection.cpp @@ -94,7 +94,11 @@ size_t postgres_connection::execute(const std::string &stmt) throw_postgres_error(res, conn_, "postgres", stmt); - return sql::to_long_long(PQcmdTuples(res)); + const auto affected_rows = sql::to_long_long(PQcmdTuples(res)); + + PQclear(res); + + return affected_rows; } sql::data_type_t string2type(const char *type) diff --git a/backends/sqlite/src/sqlite_result_reader.cpp b/backends/sqlite/src/sqlite_result_reader.cpp index e9e761f..b62fe52 100644 --- a/backends/sqlite/src/sqlite_result_reader.cpp +++ b/backends/sqlite/src/sqlite_result_reader.cpp @@ -1,7 +1,5 @@ #include "sqlite_result_reader.hpp" -#include "matador/sql/to_value.hpp" - #include namespace matador::backends::sqlite { diff --git a/include/matador/sql/connection_pool.hpp b/include/matador/sql/connection_pool.hpp index 0aab972..dbd8094 100644 --- a/include/matador/sql/connection_pool.hpp +++ b/include/matador/sql/connection_pool.hpp @@ -1,6 +1,8 @@ #ifndef QUERY_CONNECTION_POOL_HPP #define QUERY_CONNECTION_POOL_HPP +#include "matador/sql/connection_info.hpp" + #include #include #include diff --git a/include/matador/sql/object_binder.hpp b/include/matador/sql/object_binder.hpp index db3bd51..55a9c6e 100644 --- a/include/matador/sql/object_binder.hpp +++ b/include/matador/sql/object_binder.hpp @@ -1,6 +1,8 @@ #ifndef QUERY_OBJECT_BINDER_HPP #define QUERY_OBJECT_BINDER_HPP +#include "matador/sql/parameter_binder.hpp" + #include "matador/utils/cascade_type.hpp" #include "matador/utils/field_attributes.hpp" @@ -8,8 +10,6 @@ namespace matador::sql { -class parameter_binder; - class object_binder { public: diff --git a/include/matador/sql/query_result_impl.hpp b/include/matador/sql/query_result_impl.hpp index cbbe6fe..9f110a7 100644 --- a/include/matador/sql/query_result_impl.hpp +++ b/include/matador/sql/query_result_impl.hpp @@ -35,9 +35,9 @@ public: template < class Type > void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {} template < class Pointer > - void on_belongs_to(const char *id, Pointer &x, utils::cascade_type) {} + void on_belongs_to(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {} template < class Pointer > - void on_has_one(const char *id, Pointer &x, utils::cascade_type) {} + void on_has_one(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {} template void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {} @@ -59,7 +59,7 @@ public: template void on_primary_key(const char *id, ValueType &value, typename std::enable_if::value && !std::is_same::value>::type* = 0) { - reader_->read_value(id, column_index_++, value); + data_type_traits::read_value(*reader_, id, column_index_++, value); } void on_primary_key(const char *id, std::string &value, size_t size); void on_revision(const char *id, unsigned long long &rev); @@ -67,7 +67,7 @@ public: template < class Type > void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes) { - reader_->read_value(id, column_index_++, x); + data_type_traits::read_value(*reader_, id, column_index_++, x); } 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); diff --git a/include/matador/sql/types.hpp b/include/matador/sql/types.hpp index ad3d6c1..922c155 100644 --- a/include/matador/sql/types.hpp +++ b/include/matador/sql/types.hpp @@ -6,6 +6,8 @@ namespace matador::sql { +class query_result_reader; + /** * @brief Enumeration type of all supported builtin data types */ @@ -71,136 +73,152 @@ enum class sql_function_t { * provide the correct size information * for a data type */ -template < class T > +template < class Type, class Enable = void > struct data_type_traits; /// @cond MATADOR_DEV -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; } - inline static unsigned long size() { return sizeof(char); } - inline static const char* name() { return "char"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, char &value); +// inline static unsigned long size() { return sizeof(char); } +// inline static const char* name() { return "char"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_short; } - inline static unsigned long size() { return sizeof(short); } - inline static const char* name() { return "short"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, short &value); +// inline static unsigned long size() { return sizeof(short); } +// inline static const char* name() { return "short"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_int; } - inline static unsigned long size() { return sizeof(int); } - inline static const char* name() { return "int"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, int &value); +// inline static unsigned long size() { return sizeof(int); } +// inline static const char* name() { return "int"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_long; } - inline static unsigned long size() { return sizeof(long); } - inline static const char* name() { return "long"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, long &value); +// inline static unsigned long size() { return sizeof(long); } +// inline static const char* name() { return "long"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_long_long; } - inline static unsigned long size() { return sizeof(long long); } - inline static const char* name() { return "long long"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, long long &value); +// inline static unsigned long size() { return sizeof(long long); } +// inline static const char* name() { return "long long"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_char; } - inline static unsigned long size() { return sizeof(unsigned char); } - inline static const char* name() { return "unsigned char"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned char &value); +// inline static unsigned long size() { return sizeof(unsigned char); } +// inline static const char* name() { return "unsigned char"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_short; } - inline static unsigned long size() { return sizeof(unsigned short); } - inline static const char* name() { return "unsigned short"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned short &value); +// inline static unsigned long size() { return sizeof(unsigned short); } +// inline static const char* name() { return "unsigned short"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_int; } - inline static unsigned long size() { return sizeof(unsigned int); } - inline static const char* name() { return "unsigned int"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned int &value); +// inline static unsigned long size() { return sizeof(unsigned int); } +// inline static const char* name() { return "unsigned int"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/ = 0) { return database_type_t::type_bigint; } +// inline static database_type_t type(std::size_t /*size*/ = 0) { return database_type_t::type_bigint; } inline static data_type_t builtin_type(std::size_t /*size*/ = 0) { return data_type_t::type_unsigned_long; } - inline static unsigned long size() { return sizeof(unsigned long); } - inline static const char* name() { return "unsigned long"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long &value); +// inline static unsigned long size() { return sizeof(unsigned long); } +// inline static const char* name() { return "unsigned long"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_long_long; } - inline static unsigned long size() { return sizeof(unsigned long long); } - inline static const char* name() { return "unsigned long long"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long long &value); +// inline static unsigned long size() { return sizeof(unsigned long long); } +// inline static const char* name() { return "unsigned long long"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bool; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bool; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_bool; } - inline static unsigned long size() { return sizeof(bool); } - inline static const char* name() { return "bool"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, bool &value); +// inline static unsigned long size() { return sizeof(bool); } +// inline static const char* name() { return "bool"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_float; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_float; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_float; } - inline static unsigned long size() { return sizeof(float); } - inline static const char* name() { return "float"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, float &value); +// inline static unsigned long size() { return sizeof(float); } +// inline static const char* name() { return "float"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_double; } +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_double; } inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_double; } - inline static unsigned long size() { return sizeof(double); } - inline static const char* name() { return "double"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, double &value); +// inline static unsigned long size() { return sizeof(double); } +// inline static const char* name() { return "double"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; } +// inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; } inline static data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_char_pointer; } - inline static unsigned long size() { return sizeof(const char*); } - inline static const char* name() { return "const char*"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, const char* value, size_t size); +// inline static unsigned long size() { return sizeof(const char*); } +// inline static const char* name() { return "const char*"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; } +// inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; } inline static data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_varchar; } - inline static unsigned long size() { return sizeof(char*); } - inline static const char* name() { return "char*"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, char *value, size_t size); +// inline static unsigned long size() { return sizeof(char*); } +// inline static const char* name() { return "char*"; } }; -template <> struct data_type_traits +template <> struct data_type_traits { - inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; } +// inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; } inline static data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_varchar; } - inline static unsigned long size() { return 1023; } - inline static const char* name() { return "std::string"; } + static void read_value(query_result_reader &reader, const char *id, size_t index, std::string &value, size_t size); +// inline static unsigned long size() { return 1023; } +// inline static const char* name() { return "std::string"; } }; //template <> struct data_type_traits @@ -219,6 +237,18 @@ template <> struct data_type_traits // inline static const char* name() { return "matador::time"; } //}; +template < typename EnumType > +struct data_type_traits::value>::type> +{ +// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; } + inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_int; } + static void read_value(query_result_reader &reader, const char *id, size_t index, EnumType &value) + { + data_type_traits::read_value(reader, id, index, reinterpret_cast(value)); + } +// inline static unsigned long size() { return sizeof(int); } +// inline static const char* name() { return "int"; } +}; /// @endcond } diff --git a/include/matador/sql/value_extractor.hpp b/include/matador/sql/value_extractor.hpp index 0b17817..3efe1cc 100644 --- a/include/matador/sql/value_extractor.hpp +++ b/include/matador/sql/value_extractor.hpp @@ -56,10 +56,15 @@ public: private: template - void append(Type &value) + void append(Type &value, typename std::enable_if::value>::type* = 0) { values_.emplace_back(value); } + template + void append(Type &value, typename std::enable_if::value>::type* = 0) + { + values_.emplace_back((int)value); + } private: detail::fk_value_extractor fk_value_extractor_; diff --git a/include/matador/utils/access.hpp b/include/matador/utils/access.hpp index 6adbaab..e77a901 100644 --- a/include/matador/utils/access.hpp +++ b/include/matador/utils/access.hpp @@ -13,6 +13,7 @@ class container; class field_attributes; namespace access { + template void process(Operator &op, Type &object) { object.process(op); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dac3f4f..2a79995 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ set(SQL_SOURCES sql/dialect_builder.cpp sql/object_binder.cpp sql/placeholder_generator.cpp + sql/types.cpp ) set(SQL_HEADER diff --git a/src/sql/query_result_impl.cpp b/src/sql/query_result_impl.cpp index aa6635c..2a86023 100644 --- a/src/sql/query_result_impl.cpp +++ b/src/sql/query_result_impl.cpp @@ -18,22 +18,23 @@ query_result_impl::query_result_impl(std::unique_ptr &&read void query_result_impl::on_primary_key(const char *id, std::string &value, size_t size) { - reader_->read_value(id, column_index_++, value, size); + data_type_traits::read_value(*reader_, id, column_index_++, value, size); } void query_result_impl::on_revision(const char *id, unsigned long long int &rev) { + data_type_traits::read_value(*reader_, id, column_index_++, rev); reader_->read_value(id, column_index_++, rev); } void query_result_impl::on_attribute(const char *id, char *value, const utils::field_attributes &attr) { - reader_->read_value(id, column_index_++, value, attr.size()); + data_type_traits::read_value(*reader_, id, column_index_++, value, attr.size()); } void query_result_impl::on_attribute(const char *id, std::string &value, const utils::field_attributes &attr) { - reader_->read_value(id, column_index_++, value, attr.size()); + data_type_traits::read_value(*reader_, id, column_index_++, value, attr.size()); } void diff --git a/src/sql/types.cpp b/src/sql/types.cpp new file mode 100644 index 0000000..1f4246b --- /dev/null +++ b/src/sql/types.cpp @@ -0,0 +1,85 @@ +#include "matador/sql/types.hpp" + +#include "matador/sql/query_result_reader.hpp" + +namespace matador::sql { + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, char &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, short &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, int &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, long &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, long long &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, unsigned char &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, unsigned short &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, unsigned int &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, unsigned long &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, unsigned long long &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, bool &value) +{ + reader.read_value(id, index, value); +} +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, float &value) +{ + reader.read_value(id, index, value); +} +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, double &value) +{ + reader.read_value(id, index, value); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, const char* value, size_t size) +{ + reader.read_value(id, index, const_cast(value), size); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, char* value, size_t size) +{ + reader.read_value(id, index, value, size); +} + +void data_type_traits::read_value(query_result_reader &reader, const char *id, size_t index, std::string &value, size_t size) +{ + reader.read_value(id, index, value, size); +} + +} \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e1b6c60..0740046 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,7 +27,11 @@ add_executable(tests QueryBuilderTest.cpp ColumnTest.cpp SessionRecordTest.cpp StatementCacheTest.cpp - StatementTest.cpp) + StatementTest.cpp + models/coordinate.hpp + models/location.hpp + TypeTraitsTest.cpp + Databases.hpp) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain matador diff --git a/test/Databases.hpp b/test/Databases.hpp new file mode 100644 index 0000000..0f47626 --- /dev/null +++ b/test/Databases.hpp @@ -0,0 +1,15 @@ +#ifndef QUERY_DATABASES_HPP +#define QUERY_DATABASES_HPP + +struct Postgres +{ +// constexpr static const char *dns{"postgres://test:test123@127.0.0.1:15432/test"}; + constexpr static const char *dns{"postgres://test:test123@127.0.0.1:5432/matador_test"}; +}; + +struct Sqlite +{ + constexpr static const char *dns{"sqlite://sqlite.db"}; +}; + +#endif //QUERY_DATABASES_HPP diff --git a/test/StatementTest.cpp b/test/StatementTest.cpp index 34c06ab..572f05a 100644 --- a/test/StatementTest.cpp +++ b/test/StatementTest.cpp @@ -7,22 +7,13 @@ #include "matador/sql/connection_pool.hpp" #include "matador/sql/session.hpp" +#include "Databases.hpp" + #include "models/airplane.hpp" using namespace matador::sql; using namespace matador::test; -struct Postgres -{ -// constexpr static const char *dns{"postgres://test:test123@127.0.0.1:15432/test"}; - constexpr static const char *dns{"postgres://test:test123@127.0.0.1:5432/matador_test"}; -}; - -struct Sqlite -{ - constexpr static const char *dns{"sqlite://sqlite.db"}; -}; - template class StatementTestFixture { diff --git a/test/TypeTraitsTest.cpp b/test/TypeTraitsTest.cpp new file mode 100644 index 0000000..24b8113 --- /dev/null +++ b/test/TypeTraitsTest.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include "matador/sql/connection_pool.hpp" +#include "matador/sql/session.hpp" + +#include "Databases.hpp" + +#include "models/location.hpp" + +using namespace matador::sql; +using namespace matador::test; + +using namespace matador::sql; +using namespace matador::test; + +template +class TypeTraitsTestFixture +{ +public: + TypeTraitsTestFixture() + : pool_(Type::dns, 4), session_(pool_) + { + auto res = session_.create() + .table("location") + .execute(); + REQUIRE(res.first == 0); + REQUIRE(res.second == R"(CREATE TABLE "location" ("id" BIGINT, "name" VARCHAR(255), "coordinate_x" INTEGER, "coordinate_y" INTEGER, "coordinate_z" INTEGER, "color" INTEGER, CONSTRAINT PK_location PRIMARY KEY (id)))"); + } + + ~TypeTraitsTestFixture() + { + session_.drop().table("location").execute(); + } + + matador::sql::session &session() + { return session_; } + +private: + matador::sql::connection_pool pool_; + matador::sql::session session_; +}; + +TEMPLATE_TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]", Sqlite, Postgres) +{ + auto &s = TypeTraitsTestFixture::session(); + + location loc{1, "center", {1, 2, 3}, Color::Black}; + + auto res = s.insert().template into("location").values(loc).execute(); + REQUIRE(res.first == 1); + + auto result = s.template select().from("location").template fetch_all(); + + for (const auto &l : result) { + REQUIRE(l.name == "center"); + } + +} \ No newline at end of file diff --git a/test/models/coordinate.hpp b/test/models/coordinate.hpp new file mode 100644 index 0000000..f6d63da --- /dev/null +++ b/test/models/coordinate.hpp @@ -0,0 +1,26 @@ +#ifndef QUERY_COORDINATE_HPP +#define QUERY_COORDINATE_HPP + +#include "matador/utils/access.hpp" + +namespace matador::test { +struct coordinate +{ + int x; + int y; + int z; +}; + +} + +namespace matador::utils::access { + +template +void attribute(Operator &op, const char *id, test::coordinate &value, const field_attributes &attr = null_attributes) { + attribute(op, (std::string(id) + "_x").c_str(), value.x, attr); + attribute(op, (std::string(id) + "_y").c_str(), value.y, attr); + attribute(op, (std::string(id) + "_z").c_str(), value.z, attr); +} + +} +#endif //QUERY_COORDINATE_HPP diff --git a/test/models/location.hpp b/test/models/location.hpp new file mode 100644 index 0000000..3755aaa --- /dev/null +++ b/test/models/location.hpp @@ -0,0 +1,34 @@ +#ifndef QUERY_LOCATION_HPP +#define QUERY_LOCATION_HPP + +#include "matador/utils/access.hpp" + +#include "coordinate.hpp" + +namespace matador::test { + +enum class Color : uint8_t { + Green, Red, Blue, Yellow, Black, White, Brown +}; + +struct location +{ + unsigned long id; + std::string name; + coordinate coord; + Color color; + + template < class Operator > + void process(Operator &op) + { + namespace field = matador::utils::access; + field::primary_key(op, "id", id); + field::attribute(op, "name", name, 255); + field::attribute(op, "coordinate", coord); + field::attribute(op, "color", color); + } +}; + +} + +#endif //QUERY_LOCATION_HPP