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.

123 lines
4.3 KiB

  1. #pragma once
  2. #include <memory>
  3. #include <cpphibernate/misc.h>
  4. #include <cpphibernate/config.h>
  5. #include <cpphibernate/schema/table.h>
  6. #include <cpphibernate/schema/tables.h>
  7. #include <cpphibernate/modifier/where.h>
  8. #include <cpphibernate/modifier/modifier.h>
  9. beg_namespace_cpphibernate
  10. {
  11. namespace __impl
  12. {
  13. template<typename T_driver, typename T_schema>
  14. struct context_t
  15. : public T_driver
  16. {
  17. public:
  18. using base_type = T_driver;
  19. using driver_type = T_driver;
  20. using schema_type = T_schema;
  21. private:
  22. const schema_type& _schema;
  23. public:
  24. template<typename... T_args>
  25. constexpr context_t(const schema_type& p_schema, T_args&&... args)
  26. : base_type (p_schema, std::forward<T_args>(args)...)
  27. , _schema (p_schema)
  28. { }
  29. cpphibernate_copyable(context_t, delete);
  30. cpphibernate_moveable(context_t, default);
  31. /* init */
  32. inline void init(bool recreate)
  33. { this->init_impl(recreate); }
  34. /* create */
  35. template<typename T_dataset>
  36. constexpr void create(T_dataset& dataset)
  37. { this->create_impl(dataset); }
  38. /* read */
  39. template<typename T_dataset, typename... T_modifiers>
  40. constexpr auto read(T_dataset& dataset, T_modifiers&&... modifiers)
  41. -> mp::enable_if<
  42. modifier::all_are_modifiers<mp::decay_t<T_modifiers>...>>
  43. {
  44. using namespace modifier;
  45. using real_dataset_type = misc::real_dataset_t<mp::decay_t<T_dataset>>;
  46. schema::tables::find(_schema.tables, hana::type_c<real_dataset_type>);
  47. this->read_impl(dataset, modifier::make_list(std::forward<T_modifiers>(modifiers)...));
  48. }
  49. template<typename T_dataset>
  50. constexpr auto read(T_dataset& dataset)
  51. -> mp::enable_if_c<
  52. !misc::is_container<mp::decay_t<T_dataset>>::value
  53. && !misc::is_nullable<mp::decay_t<T_dataset>>::value>
  54. {
  55. using namespace modifier;
  56. using real_dataset_type = misc::real_dataset_t<mp::decay_t<T_dataset>>;
  57. auto& table = schema::tables::find(_schema.tables, hana::type_c<real_dataset_type>);
  58. auto& primary_key = schema::table::get_primary_key_field(table);
  59. this->read_impl(dataset, modifier::make_list(where(equal(primary_key, primary_key.getter(dataset)))));
  60. }
  61. template<typename T_dataset>
  62. constexpr auto read(T_dataset& dataset)
  63. -> mp::enable_if_c<
  64. misc::is_container<mp::decay_t<T_dataset>>::value
  65. || misc::is_nullable<mp::decay_t<T_dataset>>::value>
  66. {
  67. using namespace modifier;
  68. using real_dataset_type = misc::real_dataset_t<mp::decay_t<T_dataset>>;
  69. schema::tables::find(_schema.tables, hana::type_c<real_dataset_type>);
  70. this->read_impl(dataset, modifier::make_list());
  71. }
  72. /* update */
  73. template<typename T_dataset>
  74. constexpr void update(T_dataset& dataset)
  75. { this->update_impl(dataset); }
  76. /* destroy */
  77. template<typename T_dataset>
  78. constexpr void destroy(T_dataset& dataset)
  79. { this->destroy_impl(dataset); }
  80. };
  81. }
  82. /* make */
  83. template<typename T_driver, typename T_schema, typename... T_args>
  84. constexpr decltype(auto) make_context(T_schema&& schema, T_args&&... args)
  85. {
  86. using context_type = __impl::context_t<T_driver, T_schema>;
  87. return context_type(std::forward<T_schema>(schema), std::forward<T_args>(args)...);
  88. }
  89. template<typename T_driver, typename T_schema, typename... T_args>
  90. constexpr decltype(auto) make_context_ptr(T_schema&& schema, T_args&&... args)
  91. {
  92. using context_type = __impl::context_t<T_driver, T_schema>;
  93. using pointer_type = std::unique_ptr<context_type>;
  94. return pointer_type(new context_type(std::forward<T_schema>(schema), std::forward<T_args>(args)...));
  95. }
  96. }
  97. end_namespace_cpphibernate