#pragma once namespace cpphibernate { namespace mariadb { /** * @brief Base class for all mariadb driver context classes. */ struct base_context { const schema_t& schema; //!< schema to use for the operation ::cppmariadb::connection& connection; //!< mariadb connection to use for executing queries /** * @brief Constructor. * * @param[in] p_schema Mariadb driver schema to use for the operation. * @param[in] p_connection Mariadb connection to execute queries with. */ inline base_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection); }; /** * @brief Mariadb driver context for initializing the database. */ struct init_context : public base_context { bool recreate; //!< Drop existing tables before createing new once. /** * @brief Constructor. * * @param[in] p_schema Mariadb driver schema to use for the operation. * @param[in] p_connection Mariadb connection to execute queries with. * @param[in] p_recreate Drop existing tables before createing new once. */ inline init_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection, bool p_recreate); }; /** * @brief Mariadb driver context that helds a specific dataset. */ struct data_context : public base_context { private: mutable size_t _dataset_id; //!< Unique type id of the dataset that is stored in this context. mutable void* _dataset; //!< Pointer to the stored dataset. mutable const table_t* _table; //!< Table this context/dataset belongs to friend __impl::change_context_builder; public: /** * @brief Constructor. * * @param[in] p_schema Mariadb driver schema to use for the operation. * @param[in] p_connection Mariadb connection to execute queries with. * @param[in] p_dataset Dataset to store in the context. */ template inline data_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection, T_dataset& p_dataset); /** * @brief Get a reference to the stored dataset if the type matches. * If an invalid type is requested an exception is thrown. */ template inline decltype(auto) get() const; private: /** * @brief Set the dataset that is stored in this context. */ template inline void set(T_dataset& dataset); }; namespace __impl { /** * @brief Helper class to create the change_context predicate. */ template struct change_context_builder; } /** * @brief Change the stored dataset of any data_context. * * @param[in] context Any data_context. * @param[in] dataset New dataset of the context. * * @return The new conext that stores the passed dataset. */ constexpr decltype(auto) change_context = cppmp::generic_predicate<__impl::change_context_builder> { }; #if 0 /* filter_context */ struct filter_context : public data_context { const filter_t& filter; inline filter_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection, const filter_t& p_filter) : data_context (p_schema, p_connection) , filter (p_filter) { } template inline filter_context( T_data& p_data, const schema_t& p_schema, ::cppmariadb::connection& p_connection, const filter_t& p_filter) : data_context (p_data, p_schema, p_connection) , filter (p_filter) { } }; /* create_update_context */ struct create_update_context : public filter_context { bool is_update; const table_t* derived_table; const field_t* owner_field; std::string owner_key; ssize_t index; template inline create_update_context( T_data& p_data, const schema_t& p_schema, ::cppmariadb::connection& p_connection, const filter_t& p_filter, bool p_is_update) : filter_context(p_data, p_schema, p_connection, p_filter) , is_update (p_is_update) , derived_table (nullptr) , owner_field (nullptr) , index (-1) { } }; /* read_context */ struct read_context : public filter_context { protected: size_t base_dataset_id; public: bool is_dynamic; std::string where; std::string limit; std::string order_by; protected: inline read_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection, const filter_t& p_filter) : filter_context (p_schema, p_connection, p_filter) , is_dynamic (false) , base_dataset_id (0) { } public: virtual ~read_context() = default; template inline T_dataset& emplace(const table_t* table = nullptr) const; void emplace() const { emplace_intern(nullptr, 0); } void finish() const { finish_intern(); } private: virtual void* emplace_intern(void* data, size_t dataset_id) const = 0; virtual void finish_intern () const = 0; }; using read_context_ptr = std::unique_ptr; /* destroy_context */ struct destroy_context : public data_context { std::string where; template inline destroy_context( T_data& p_data, const schema_t& p_schema, ::cppmariadb::connection& p_connection) : data_context( p_data, p_schema, p_connection) { } }; #endif } }