#ifndef QUERY_SESSION_HPP #define QUERY_SESSION_HPP #include "matador/sql/connection.hpp" #include "matador/sql/connection_pool.hpp" #include "matador/sql/entity.hpp" #include "matador/sql/statement.hpp" #include "matador/sql/schema.hpp" #include namespace matador::sql { class dialect; struct join_data { table join_table; std::unique_ptr condition; }; //class join_collector //{ //private: // explicit join_collector(const sql::schema &ts, std::vector &joins) // : table_schema_(ts) // , joins_(joins) {} // //public: // template < class Type > // static std::vector collect(const sql::schema &ts) // { // const auto info = ts.info(); // if (!info) { // return {}; // } // std::vector joins; // join_collector collector(ts, joins); // Type obj; // matador::utils::access::process(collector, obj); // return joins; // } // // template < class PrimaryKeyType > // void on_primary_key(const char *id, PrimaryKeyType &, typename std::enable_if::value && !std::is_same::value>::type* = 0) {} // 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) {} // // template // void on_belongs_to(const char *id, Pointer &, const utils::foreign_attributes &attr) // { // if (attr.fetch() == utils::fetch_type::LAZY) { // push(id); // } else { // const auto info = table_schema_.info(); // if (!info) { // return; // } // table_name_stack_.push(info.value().name); // typename Pointer::value_type obj; // matador::utils::access::process(*this, obj); // table_name_stack_.pop(); // } // } // template // void on_has_one(const char *id, Pointer &, const utils::foreign_attributes &attr) // { // if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) { // push(id); // } else { // const auto info = table_schema_.info(); // if (!info) { // return; // } // table_name_stack_.push(info.value().name); // typename Pointer::value_type obj; // matador::utils::access::process(*this, obj); // table_name_stack_.pop(); // } // } // template // void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &attr) // { // if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) { // return; // } // const auto info = table_schema_.info(); // if (!info) { // return; // } // // table_name_stack_.push(info.value().name); // typename ContainerType::value_type::value_type obj; // matador::utils::access::process(*this, obj); // table_name_stack_.pop(); // } // template // void on_has_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr) // { // on_has_many(id, c, "", "", attr); // } // //private: // const sql::schema &table_schema_; // std::vector &joins_; //}; class session { public: explicit session(connection_pool &pool); template void attach(const std::string &table_name); void create_schema(); template entity insert(Type *obj); template< class Type, typename... Args > entity insert(Args&&... args) { return insert(new Type(std::forward(args)...)); } template entity find(const PrimaryKeyType &pk) { auto c = pool_.acquire(); if (!c.valid()) { throw std::logic_error("no database connection available"); } // collect all columns // - evaluate fetch::Eager flag for relations auto info = schema_->info(); if (!info) { return {}; } auto columns = sql::column_generator::generate(*schema_); // auto joins = sql c->query(*schema_).select({}).from(info->name); // build pk where condition // - check if type has pk // - check type // pk_condition_builder builder; // auto cond = builder.build(pk); // create query with relations as requested // // c->query(*schema_).select().from("xyz").where().fetch_all(); return {}; } template void drop_table(); void drop_table(const std::string &table_name); [[nodiscard]] query_result fetch(const query_context &q) const; // [[nodiscard]] query_result fetch(const std::string &sql) const; [[nodiscard]] size_t execute(const std::string &sql) const; statement prepare(query_context q) const; std::vector describe_table(const std::string &table_name) const; bool table_exists(const std::string &table_name) const; [[nodiscard]] const schema& tables() const; const class dialect& dialect() const; private: friend class query_select_finish; [[nodiscard]] std::unique_ptr fetch(const std::string &sql) const; private: connection_pool &pool_; const class dialect &dialect_; std::unique_ptr schema_; mutable std::unordered_map prototypes_; }; template void session::attach(const std::string &table_name) { schema_->attach(table_name); } template entity session::insert(Type *obj) { auto c = pool_.acquire(); auto info = schema_->info(); if (!info) { return {}; } c->query(*schema_) .insert() .into(info->name, column_generator::generate(*schema_)) .values(*obj) .execute(); return entity{obj}; } template void session::drop_table() { auto info = schema_->info(); if (info) { return drop_table(info.name); } } } #endif //QUERY_SESSION_HPP