#ifndef QUERY_QUERY_RESULT_IMPL_HPP #define QUERY_QUERY_RESULT_IMPL_HPP #include "matador/utils/access.hpp" #include "matador/utils/field_attributes.hpp" #include "matador/utils/foreign_attributes.hpp" #include "matador/sql/any_type.hpp" #include "matador/sql/query_result_reader.hpp" #include "matador/sql/column_definition.hpp" #include "matador/sql/data_type_traits.hpp" #include #include namespace matador::sql { namespace detail { class pk_reader { public: explicit pk_reader(query_result_reader &reader); template void read(Type &obj, size_t column_index) { column_index_ = column_index; utils::access::process(*this, obj); } template void on_primary_key(const char *id, ValueType &value, typename std::enable_if::value && !std::is_same::value>::type* = 0); void on_primary_key(const char *id, std::string &value, size_t size); void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {} 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*/, const utils::foreign_attributes &/*attr*/) {} template < class Pointer > void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {} template void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {} template void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {} private: size_t column_index_{}; query_result_reader &reader_; }; } class query_result_impl { public: query_result_impl(std::unique_ptr &&reader, std::vector prototype); template void on_primary_key(const char *id, ValueType &value, typename std::enable_if::value && !std::is_same::value>::type* = 0) { 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); template < class Type > void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes) { 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); 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, any_type &value, data_type_t type, 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*/) { if (!x.get()) { x.reset(new typename Pointer::value_type); } pk_reader_.read(*x, column_index_++); } template < class Pointer > void on_has_one(const char * /*id*/, Pointer &x, const utils::foreign_attributes &/*attr*/) { if (!x.get()) { x.reset(new typename Pointer::value_type); } pk_reader_.read(*x, column_index_++); } template void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {} template void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {} template void bind(const Type &) {} template bool fetch(Type &obj) { column_index_ = 0; if (!reader_->fetch()) { return false; } matador::utils::access::process(*this, obj); return true; } [[nodiscard]] const std::vector& prototype() const; protected: size_t column_index_ = 0; std::vector prototype_; std::unique_ptr reader_; detail::pk_reader pk_reader_; }; namespace detail { template void detail::pk_reader::on_primary_key(const char *id, ValueType &value, typename std::enable_if::value && !std::is_same::value>::type *) { data_type_traits::read_value(reader_, id, column_index_++, value); } } } #endif //QUERY_QUERY_RESULT_IMPL_HPP