You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

120 lines
3.6 KiB

  1. #pragma once
  2. #include "data_context.h"
  3. #include "base_context.inl"
  4. #include "../classes/schema/schema.inl"
  5. namespace cpphibernate {
  6. namespace mariadb {
  7. /* data_context */
  8. data_context::data_context(
  9. const schema_t& p_schema,
  10. ::cppmariadb::connection& p_connection)
  11. : base_context (p_schema, p_connection)
  12. , _dataset_id (0)
  13. , _dataset (nullptr)
  14. , _table (nullptr)
  15. { }
  16. template<typename T_dataset>
  17. data_context::data_context(
  18. const schema_t& p_schema,
  19. ::cppmariadb::connection& p_connection,
  20. T_dataset& p_dataset)
  21. : base_context (p_schema, p_connection)
  22. , _dataset_id (0)
  23. , _dataset (nullptr)
  24. , _table (nullptr)
  25. { set(p_dataset); }
  26. template<typename T_dataset>
  27. decltype(auto) data_context::get() const
  28. {
  29. using dataset_type = mp::decay_t<T_dataset>;
  30. /* check if tha context has a dataset assigned (should never fail) */
  31. if (!_dataset)
  32. throw exception("no data assigned!");
  33. auto dataset_id = get_type_id(hana::type_c<dataset_type>);
  34. /* if the dataset IDs does not match, search in the base tables for a matching ID */
  35. if (dataset_id != _dataset_id)
  36. {
  37. /* get the table of the stored dataset */
  38. if (!_table)
  39. _table = &schema.table(_dataset_id);
  40. /* check if the table matches the stored dataset (should never happen) */
  41. else if (_table->dataset_id != _dataset_id)
  42. throw exception("invalid table!");
  43. /* walk through base tables until we have found a matching ID */
  44. auto table = _table;
  45. while(table && table->dataset_id != dataset_id)
  46. table = table->base_table;
  47. /* check if we have found a suitable table, if not throw an exception */
  48. if (!table)
  49. {
  50. throw exception(cppcore::type_helper<dataset_type>::name() +
  51. " is not a derived type of dataset with id " + std::to_string(_dataset_id));
  52. }
  53. }
  54. /* return the dataset */
  55. return *static_cast<dataset_type*>(_dataset);
  56. }
  57. template<typename T_dataset>
  58. void * data_context::set(T_dataset& dataset, size_t dataset_id) const
  59. {
  60. _dataset_id = dataset_id
  61. ? dataset_id
  62. : get_type_id(hana::type_c<mp::decay_t<T_dataset>>);
  63. _dataset = &dataset;
  64. _table = nullptr;
  65. return _dataset;
  66. }
  67. void data_context::clear() const
  68. {
  69. _dataset_id = 0;
  70. _dataset = nullptr;
  71. _table = nullptr;
  72. }
  73. namespace __impl
  74. {
  75. /* change_context_builder */
  76. template<typename X, typename>
  77. struct change_context_builder
  78. {
  79. template<typename... T_args>
  80. static constexpr decltype(auto) apply(T_args&&...)
  81. { static_assert(sizeof...(T_args) == -1, "Invalid parameters for change_context(...)!"); }
  82. };
  83. template<typename T_context, typename T_dataset>
  84. struct change_context_builder<
  85. mp::list<T_context, T_dataset>,
  86. mp::enable_if_t<
  87. mp::is_base_of_v<data_context, mp::decay_t<T_context>>>>
  88. {
  89. static constexpr decltype(auto) apply(const T_context& context, T_dataset& dataset)
  90. {
  91. auto new_context = context;
  92. new_context.set(dataset);
  93. return new_context;
  94. }
  95. };
  96. }
  97. } }