#pragma once namespace cpphibernate { namespace mariadb { /* base_context */ base_context::base_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection) : schema (p_schema) , connection(p_connection) { } /* data_context */ template data_context::data_context( const schema_t& p_schema, ::cppmariadb::connection& p_connection, T_dataset& p_dataset) : base_context (p_schema, p_connection) , _dataset_id (0) , _dataset (nullptr) , _table (nullptr) { set(p_dataset); } template decltype(auto) data_context::get() const { using dataset_type = mp::decay_t; /* check if tha context has a dataset assigned (should never fail) */ if (!_dataset) throw misc::hibernate_exception("no data assigned!"); auto dataset_id = misc::get_type_id(hana::type_c); /* if the dataset IDs does not match, search in the base tables for a matching ID */ if (dataset_id != _dataset_id) { /* get the table of the stored dataset */ if (!_table) _table = &schema.table(_dataset_id); /* check if the table matches the stored dataset (should never happen) */ else if (_table->dataset_id != _dataset_id) throw misc::hibernate_exception("invalid table!"); /* walk through base tables until we have found a matching ID */ auto table = _table; while(table && table->dataset_id != dataset_id) table = table->base_table; /* check if we have found a suitable table, if not throw an exception */ if (!table) { throw misc::hibernate_exception(utl::type_helper::name() + " is not a derived type of dataset with id " + std::to_string(_dataset_id)); } } /* return the dataset */ return *static_cast(_dataset); } template void data_context::set(T_dataset& dataset) { _dataset_id = misc::get_type_id(hana::type_c>); _dataset = &dataset; _table = nullptr; } namespace __impl { /* change_context_builder */ template struct change_context_builder { template static constexpr decltype(auto) apply(T_args&&...) { static_assert(sizeof...(T_args) == -1, "Invalid parameters for change_context(...)!"); } }; template struct change_context_builder< mp::list, mp::enable_if_t< mp::is_base_of_v>>> { static constexpr decltype(auto) apply(const T_context& context, T_dataset& dataset) { auto new_context = context; new_context.set(dataset); return new_context; } }; } #if 0 /* read_context */ template T_dataset& read_context ::emplace(const table_t* table) const { using dataset_type = mp::decay_t; // check table auto dataset_id = misc::get_type_id(hana::type_c); if (!table) table = &schema.table(dataset_id); else if (table->dataset_id != dataset_id) throw misc::hibernate_exception("wrong table passed!"); // check base auto tbl = table; while (tbl && tbl->dataset_id != base_dataset_id) tbl = tbl->base_table; if (!tbl) { throw misc::hibernate_exception(utl::type_helper::name() + " is not a derived type of dataset with id " + std::to_string(base_dataset_id)); } // create dataset auto ptr = std::make_unique(); auto data = emplace_intern(ptr.get(), dataset_id); if (!data) throw misc::hibernate_exception("unable to store created dataset in context!"); ptr.release(); return *static_cast(data); } #endif } }