|
- #pragma once
-
- #include "data_context.h"
-
- #include "base_context.inl"
- #include "../classes/schema/schema.inl"
-
- namespace cpphibernate {
- namespace mariadb {
-
- /* data_context */
-
- data_context::data_context(
- const schema_t& p_schema,
- ::cppmariadb::connection& p_connection)
- : base_context (p_schema, p_connection)
- , _dataset_id (0)
- , _dataset (nullptr)
- , _table (nullptr)
- { }
-
- template<typename T_dataset>
- 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<typename T_dataset>
- decltype(auto) data_context::get() const
- {
- using dataset_type = mp::decay_t<T_dataset>;
-
- /* check if tha context has a dataset assigned (should never fail) */
- if (!_dataset)
- throw exception("no data assigned!");
-
- auto dataset_id = get_type_id(hana::type_c<dataset_type>);
-
- /* 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 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 exception(cppcore::type_helper<dataset_type>::name() +
- " is not a derived type of dataset with id " + std::to_string(_dataset_id));
- }
- }
-
- /* return the dataset */
- return *static_cast<dataset_type*>(_dataset);
- }
-
- template<typename T_dataset>
- void * data_context::set(T_dataset& dataset, size_t dataset_id) const
- {
- _dataset_id = dataset_id
- ? dataset_id
- : get_type_id(hana::type_c<mp::decay_t<T_dataset>>);
- _dataset = &dataset;
- _table = nullptr;
- return _dataset;
- }
-
- void data_context::clear() const
- {
- _dataset_id = 0;
- _dataset = nullptr;
- _table = nullptr;
- }
-
- namespace __impl
- {
-
- /* change_context_builder */
-
- template<typename X, typename>
- struct change_context_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for change_context(...)!"); }
- };
-
- template<typename T_context, typename T_dataset>
- struct change_context_builder<
- mp::list<T_context, T_dataset>,
- mp::enable_if_t<
- mp::is_base_of_v<data_context, mp::decay_t<T_context>>>>
- {
- static constexpr decltype(auto) apply(const T_context& context, T_dataset& dataset)
- {
- auto new_context = context;
- new_context.set(dataset);
- return new_context;
- }
- };
-
- }
-
- } }
|