diff --git a/include/matador/query/query_collection_resolver.hpp b/include/matador/query/query_collection_resolver.hpp index d879933..cf18f09 100644 --- a/include/matador/query/query_collection_resolver.hpp +++ b/include/matador/query/query_collection_resolver.hpp @@ -2,6 +2,7 @@ #define MATADOR_QUERY_CONTAINER_RESOLVER_HPP #include "matador/object/collection_resolver.hpp" +#include "matador/object/object_resolver.hpp" #include "matador/sql/internal/identifier_statement_binder.hpp" #include "matador/sql/statement.hpp" @@ -25,6 +26,38 @@ protected: std::type_index index{typeid(Type)}; }; +struct value_to_identifier{ + void operator()(const int8_t &x) { assign(x); } + void operator()(const int16_t &x) { assign(x); } + void operator()(const int32_t &x) { assign(x); } + void operator()(const int64_t &x) { assign(x); } + void operator()(const uint8_t &x) { assign(x); } + void operator()(const uint16_t &x) { assign(x); } + void operator()(const uint32_t &x) { assign(x); } + void operator()(const uint64_t &x) { assign(x); } + void operator()(const bool &x) {} + void operator()(const float &x) {} + void operator()(const double &x) { /* assign(x);*/ } + void operator()(const char *x) {} + void operator()(const std::string &x) { assign(x); } + void operator()(const utils::date_type_t &x) {} + void operator()(const utils::time_type_t &x) {} + void operator()(const utils::timestamp_type_t &x) {} + void operator()(const utils::blob_type_t &x) {} + + template + void assign(const Type &x) { id_ = x; } + + utils::identifier id_; +}; + +struct identifier_creator { + value_to_identifier visitor; + void on_attribute(const char*, const utils::value &val, const utils::field_attributes &/*attr*/) { + std::visit(visitor, val.raw_value()); + } +}; + template std::vector query_collection_resolver::resolve(const utils::identifier &id) { sql::identifier_statement_binder binder(stmt_); @@ -35,10 +68,16 @@ std::vector query_collection_resolver::resolve(const utils::identifi return {}; } std::vector out; - for (const auto &i: *result) { + for (auto &r : *result) { // Todo: convert the first value of record into an utils::identifier // then create a object_proxy(resolver, identifier) - // out.emplace_back(resolver, identifier); + if (r.size() != 1) { + continue; + } + identifier_creator creator; + r.at(0).process(creator); + const auto op = std::make_shared>(std::shared_ptr>{}, creator.visitor.id_); + out.emplace_back(op); } return out; } diff --git a/include/matador/sql/field.hpp b/include/matador/sql/field.hpp index 428b369..6a54329 100644 --- a/include/matador/sql/field.hpp +++ b/include/matador/sql/field.hpp @@ -64,7 +64,6 @@ public: friend std::ostream& operator<<(std::ostream &out, const field &col); -private: template void process(Operator &op) { op.on_attribute(name_.c_str(), value_, { value_.size(), type_ } ); diff --git a/include/matador/sql/internal/query_result_impl.hpp b/include/matador/sql/internal/query_result_impl.hpp index a4190ab..c616dcf 100644 --- a/include/matador/sql/internal/query_result_impl.hpp +++ b/include/matador/sql/internal/query_result_impl.hpp @@ -128,8 +128,8 @@ public: template void on_has_many(const char * /*id*/, CollectionType &cont, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t::value> * = nullptr) { using value_type = typename CollectionType::value_type::value_type; - auto resolver = resolver_->collection_resolver(result_type_, join_column); auto object_resolver = resolver_->object_resolver(); + auto resolver = resolver_->collection_resolver(result_type_, join_column); std::vector objects; if (attr.fetch() == utils::fetch_type::Lazy) { diff --git a/include/matador/sql/record.hpp b/include/matador/sql/record.hpp index 9c4ac8b..942ee6a 100644 --- a/include/matador/sql/record.hpp +++ b/include/matador/sql/record.hpp @@ -44,6 +44,8 @@ public: [[nodiscard]] const field& at(const std::string &name) const; [[nodiscard]] const field& at(size_t index) const; + [[nodiscard]] field& at(const std::string &name); + [[nodiscard]] field& at(size_t index); template std::optional at(const std::string &name) const { return at(name).as(); diff --git a/include/matador/utils/value.hpp b/include/matador/utils/value.hpp index d3a2e50..f7a5471 100644 --- a/include/matador/utils/value.hpp +++ b/include/matador/utils/value.hpp @@ -85,6 +85,8 @@ public: [[nodiscard]] bool is_blob() const; [[nodiscard]] bool is_null() const; + const database_type& raw_value() const; + private: database_type value_; size_t size_{}; diff --git a/source/core/utils/value.cpp b/source/core/utils/value.cpp index 7a46e55..c67e25a 100644 --- a/source/core/utils/value.cpp +++ b/source/core/utils/value.cpp @@ -103,4 +103,7 @@ bool value::is_blob() const { bool value::is_null() const { return type_ == basic_type::Null; } +const database_type &value::raw_value() const { + return value_; } +} // namespace matador::utils diff --git a/source/orm/sql/record.cpp b/source/orm/sql/record.cpp index 1bc2d89..dc7a515 100644 --- a/source/orm/sql/record.cpp +++ b/source/orm/sql/record.cpp @@ -59,6 +59,15 @@ const field &record::at(const size_t index) const return fields_.at(index); } +field &record::at(const std::string &name) { + auto &[fst, snd] = fields_by_name_.at(name); + return fst; +} + +field &record::at(const size_t index) { + return fields_.at(index); +} + record::iterator record::find(const std::string &column_name) { auto it = fields_by_name_.find(column_name);