Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

212 righe
8.2 KiB

  1. #pragma once
  2. #include <memory>
  3. #include <vector>
  4. #include <cppmariadb.h>
  5. #include <cpphibernate/misc.h>
  6. #include <cpphibernate/config.h>
  7. #include <cpphibernate/schema/table.h>
  8. #include <cpphibernate/schema/schema.h>
  9. #include <cpphibernate/driver/mariadb/schema/fields.h>
  10. #include <cpphibernate/driver/mariadb/schema/table.fwd.h>
  11. #include <cpphibernate/driver/mariadb/helper/context.h>
  12. beg_namespace_cpphibernate_driver_mariadb
  13. {
  14. /* table_t */
  15. struct table_t
  16. {
  17. size_t dataset_id { 0 };
  18. size_t base_dataset_id { 0 };
  19. size_t table_id { 0 };
  20. std::vector<size_t> derived_dataset_ids;
  21. std::string table_name;
  22. std::string schema_name;
  23. fields_t fields;
  24. const table_t* base_table { nullptr };
  25. std::vector<const table_t*> derived_tables;
  26. const field_t* primary_key_field { nullptr };
  27. std::vector<const field_t*> foreign_key_fields;
  28. std::vector<const field_t*> foreign_table_fields;
  29. std::vector<const field_t*> foreign_table_one_fields;
  30. std::vector<const field_t*> foreign_table_many_fields;
  31. std::vector<const field_t*> data_fields;
  32. inline table_t() = default;
  33. inline table_t(const table_t&) = delete;
  34. inline table_t(table_t&& other)
  35. : dataset_id (std::move(other).dataset_id)
  36. , base_dataset_id (std::move(other).base_dataset_id)
  37. , table_id (std::move(other).table_id)
  38. , derived_dataset_ids (std::move(other).derived_dataset_ids)
  39. , table_name (std::move(other).table_name)
  40. , schema_name (std::move(other).schema_name)
  41. , fields (std::move(other).fields)
  42. , base_table (nullptr)
  43. , derived_tables ()
  44. , primary_key_field (nullptr)
  45. , foreign_key_fields ()
  46. , foreign_table_fields ()
  47. , foreign_table_one_fields ()
  48. , foreign_table_many_fields ()
  49. , data_fields ()
  50. { }
  51. virtual ~table_t() { };
  52. void print(std::ostream& os) const;
  53. /* CRUD */
  54. inline void init(const init_context& context) const
  55. { return init_intern(context); }
  56. private:
  57. using statement_ptr = std::unique_ptr<::cppmariadb::statement>;
  58. mutable statement_ptr _statement_create_table;
  59. ::cppmariadb::statement& get_statement_create_table() const;
  60. protected:
  61. void init_intern(const init_context& context) const;
  62. };
  63. /* table_simple_t */
  64. template<typename T_schema, typename T_table, typename T_base_dataset>
  65. struct table_simple_t
  66. : public table_t
  67. {
  68. using schema_type = T_schema;
  69. using table_type = T_table;
  70. using base_dataset_type = T_base_dataset;
  71. const schema_type& schema;
  72. const table_type& table;
  73. inline table_simple_t(const schema_type& p_schema, const table_type& p_table)
  74. : schema(p_schema)
  75. , table (p_table)
  76. { }
  77. inline table_simple_t(const table_simple_t&) = delete;
  78. inline table_simple_t(table_simple_t&& other)
  79. : table_t(std::move(other))
  80. , schema (std::move(other).schema)
  81. , table (std::move(other).table)
  82. { }
  83. };
  84. /* table_polymorphic_t */
  85. template<typename T_schema, typename T_table, typename T_base_dataset>
  86. struct table_polymorphic_t
  87. : public table_simple_t<T_schema, T_table, T_base_dataset>
  88. {
  89. using base_type = table_simple_t<T_schema, T_table, T_base_dataset>;
  90. using schema_type = T_schema;
  91. using table_type = T_table;
  92. using base_dataset_type = T_base_dataset;
  93. using base_type::base_type;
  94. const schema_type& schema;
  95. const table_type& table;
  96. };
  97. namespace __impl
  98. {
  99. /* make_dataset_id_vector */
  100. struct make_dataset_id_vector_impl
  101. {
  102. template<typename T_wrapped_datasets, size_t... I>
  103. static constexpr decltype(auto) helper(const T_wrapped_datasets& wrapped_datasets, std::index_sequence<I...>)
  104. {
  105. return std::vector<size_t>({
  106. misc::get_type_id(wrapped_datasets[hana::size_c<I>])...
  107. });
  108. }
  109. template<typename T_wrapped_datasets>
  110. constexpr decltype(auto) operator()(T_wrapped_datasets&& wrapped_datasets) const
  111. {
  112. using size = mp::decay_t<decltype(hana::size(wrapped_datasets))>;
  113. return helper(std::forward<T_wrapped_datasets>(wrapped_datasets), std::make_index_sequence<size::value> { });
  114. }
  115. };
  116. static constexpr decltype(auto) make_dataset_id_vector = make_dataset_id_vector_impl { };
  117. /* make_table_impl */
  118. template<typename T, typename>
  119. struct make_table_impl
  120. {
  121. template<typename... T_args>
  122. static constexpr decltype(auto) apply(T_args&&... args)
  123. { static_assert(sizeof...(args) == 0, "Invalid parameters for mariadb::make_table(...)!"); }
  124. };
  125. template<typename T_schema, typename T_table>
  126. struct make_table_impl<
  127. mp::list<T_schema, T_table>,
  128. mp::enable_if_c<
  129. schema::is_schema<mp::decay_t<T_schema>>::value
  130. && schema::is_table <mp::decay_t<T_table>>::value>>
  131. {
  132. /* table_type */
  133. template<typename T_dataset, typename T_base_dataset, typename = void>
  134. struct table_type
  135. { using type = table_simple_t<mp::decay_t<T_schema>, mp::decay_t<T_table>, T_base_dataset>; };
  136. template<typename T_dataset, typename T_base_dataset>
  137. struct table_type<T_dataset, T_base_dataset, mp::enable_if_c<
  138. std::is_polymorphic<T_dataset>::value>>
  139. { using type = table_polymorphic_t<mp::decay_t<T_schema>, mp::decay_t<T_table>, T_base_dataset>; };
  140. template<typename T_dataset, typename T_base_dataset>
  141. using table_type_t = typename table_type<T_dataset, T_base_dataset>::type;
  142. /* apply */
  143. static decltype(auto) apply(const T_schema& schema, const T_table& table)
  144. {
  145. using wrapped_base_type = mp::decay_t<decltype(
  146. schema::get_base_type(
  147. std::declval<T_schema>(),
  148. std::declval<T_table>().wrapped_dataset))>;
  149. using base_type = misc::unwrap_t<wrapped_base_type>;
  150. using derived_wrapped_types_type = mp::decay_t<decltype(
  151. schema::get_derived_types(
  152. std::declval<T_schema>(),
  153. std::declval<T_table>().wrapped_dataset))>;
  154. using wrapped_dataset_type = typename mp::decay_t<T_table>::wrapped_dataset_type;
  155. using dataset_type = misc::unwrap_t<wrapped_dataset_type>;
  156. using table_type = table_type_t<dataset_type, base_type>;
  157. table_type ret(schema, table);
  158. ret.dataset_id = misc::get_type_id(table.wrapped_dataset);
  159. ret.base_dataset_id = misc::get_type_id(wrapped_base_type { });
  160. ret.derived_dataset_ids = make_dataset_id_vector(derived_wrapped_types_type { });
  161. ret.table_id = hana::value(table.table_id);
  162. ret.schema_name = schema.name;
  163. ret.table_name = table.name;
  164. ret.fields = make_fields(schema, table);
  165. return ret;
  166. }
  167. };
  168. }
  169. }
  170. end_namespace_cpphibernate_driver_mariadb