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.
 
 
 

145 lines
4.4 KiB

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