#ifndef QUERY_SESSION_HPP #define QUERY_SESSION_HPP #include "matador/sql/connection.hpp" #include "matador/sql/connection_pool.hpp" // #include "matador/sql/entity_query_builder.hpp" #include "matador/sql/statement.hpp" #include "matador/object/object_ptr.hpp" #include "matador/object/schema.hpp" #include namespace matador::orm { class dialect; enum class session_error { Ok = 0, NoConnectionAvailable, UnknownType, FailedToBuildQuery, FailedToFindObject }; class session { public: explicit session(sql::connection_pool &pool); template void attach(const std::string &table_name); void create_schema(); template object::object_ptr insert(Type *obj); template< class Type, typename... Args > object::object_ptr insert(Args&&... args) { return insert(new Type(std::forward(args)...)); } template utils::result, session_error> find(const PrimaryKeyType &pk) { auto c = pool_.acquire(); if (!c.valid()) { return utils::failure(session_error::NoConnectionAvailable); } auto info = schema_->info(); if (!info) { return utils::failure(session_error::UnknownType); } entity_query_builder eqb(*schema_); auto data = eqb.build(pk); if (!data.is_ok()) { return utils::failure(session_error::FailedToBuildQuery); } auto obj = build_select_query(c, data.release()).template fetch_one(); if (!obj) { return utils::failure(session_error::FailedToFindObject); } return utils::ok(object::object_ptr{ obj.release() }); } template utils::result, session_error> find() { auto c = pool_.acquire(); if (!c.valid()) { return utils::failure(session_error::NoConnectionAvailable); } auto info = schema_->info(); if (!info) { return utils::failure(session_error::UnknownType); } entity_query_builder eqb(*schema_); auto data = eqb.build(); if (!data.is_ok()) { return utils::failure(session_error::FailedToBuildQuery); } return utils::ok(build_select_query(c, data.release()).template fetch_all()); } template utils::result select() { auto c = pool_.acquire(); if (!c.valid()) { return utils::failure(session_error::NoConnectionAvailable); } auto info = schema_->info(); if (!info) { return utils::failure(session_error::UnknownType); } entity_query_builder eqb(*schema_); auto data = eqb.build(); if (!data.is_ok()) { return utils::failure(session_error::FailedToBuildQuery); } return utils::ok(build_select_query(c, data.release()).template fetch_all()); } template void drop_table(); void drop_table(const std::string &table_name); [[nodiscard]] sql::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; [[nodiscard]] sql::statement prepare(query_context q) const; [[nodiscard]] std::vector describe_table(const std::string &table_name) const; [[nodiscard]] bool table_exists(const std::string &table_name) const; [[nodiscard]] const sql::dialect& dialect() const; private: friend class query_select; [[nodiscard]] std::unique_ptr fetch(const std::string &sql) const; query_select build_select_query(sql::connection_ptr &conn, entity_query_data &&data) const; private: sql::connection_pool &pool_; const sql::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 object::object_ptr 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_, true)) .values(*obj) .execute(); return object::object_ptr{obj}; } template void session::drop_table() { auto info = schema_->info(); if (info) { return drop_table(info.name); } } } #endif //QUERY_SESSION_HPP