|
- #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<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 misc::hibernate_exception("no data assigned!");
-
- auto dataset_id = misc::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 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<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)
- {
- _dataset_id = misc::get_type_id(hana::type_c<mp::decay_t<T_dataset>>);
- _dataset = &dataset;
- _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;
- }
- };
-
- }
-
- #if 0
-
- /* read_context */
-
- template<typename T_dataset>
- T_dataset& read_context
- ::emplace(const table_t* table) const
- {
- using dataset_type = mp::decay_t<T_dataset>;
-
- // check table
- auto dataset_id = misc::get_type_id(hana::type_c<dataset_type>);
- 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<dataset_type>::name() +
- " is not a derived type of dataset with id " + std::to_string(base_dataset_id));
- }
-
- // create dataset
- auto ptr = std::make_unique<dataset_type>();
- 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<dataset_type*>(data);
- }
- #endif
- } }
|