選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

194 行
7.0 KiB

  1. #pragma once
  2. #include <cpphibernate/driver/mariadb/schema/field.h>
  3. #include <cpphibernate/driver/mariadb/impl/create_update.h>
  4. beg_namespace_cpphibernate_driver_mariadb
  5. {
  6. /* simple_field_t */
  7. template<typename T_field>
  8. void simple_field_t<T_field>
  9. ::update()
  10. {
  11. base_type::update();
  12. id = misc::get_type_id(hana::type_c<field_type>);
  13. dataset_id = misc::get_type_id(hana::type_c<dataset_type>);
  14. real_dataset_id = misc::get_type_id(hana::type_c<real_dataset_type>);
  15. value_id = misc::get_type_id(hana::type_c<value_type>);
  16. real_value_id = misc::get_type_id(hana::type_c<real_value_type>);
  17. value_is_nullable = misc::is_nullable<value_type>::value;
  18. value_is_pointer = misc::is_pointer<value_type>::value;
  19. value_is_container = misc::is_container<value_type>::value;
  20. value_is_ordered = misc::is_ordered<value_type>::value;
  21. }
  22. /* value_field_t */
  23. template<typename T_field>
  24. void value_field_t<T_field>
  25. ::update()
  26. {
  27. base_type::update();
  28. this->type = type_props::type();
  29. }
  30. template<typename T_field>
  31. value_t value_field_t<T_field>
  32. ::get(const data_context& context) const
  33. {
  34. auto& dataset = context.get<dataset_type>();
  35. return type_props::convert_from(this->field.getter(dataset));
  36. }
  37. template<typename T_field>
  38. void value_field_t<T_field>
  39. ::set(const data_context& context, const value_t& value) const
  40. {
  41. auto& dataset = context.get<dataset_type>();
  42. this->field.setter(dataset, type_props::convert_to(value));
  43. }
  44. /* primary_key_field_t */
  45. template<typename T_field>
  46. bool primary_key_field_t<T_field>
  47. ::is_default(const data_context& context) const
  48. {
  49. auto& dataset = context.get<dataset_type>();
  50. return key_props::is_default(this->field.getter(dataset));
  51. }
  52. template<typename T_field>
  53. std::string primary_key_field_t<T_field>
  54. ::generate_value(::cppmariadb::connection& connection) const
  55. {
  56. auto ret = connection.execute_used(key_props::create_key_query);
  57. if (!ret || !ret->next())
  58. throw misc::hibernate_exception("unable to generate key value!");
  59. return ret->current()->at(0).template get<std::string>();
  60. }
  61. /* foreign_table_field_t */
  62. template<typename T_field>
  63. value_t foreign_table_field_t<T_field>
  64. ::foreign_create_update(const create_update_context& context) const
  65. {
  66. auto& dataset = context.get<dataset_type>();
  67. auto& foreign = this->field.getter(dataset);
  68. auto next_context = change_context(context, foreign);
  69. using foreign_dataset_type = mp::decay_t<decltype(foreign)>;
  70. return create_update_impl_t<foreign_dataset_type>::apply(
  71. next_context,
  72. false);
  73. }
  74. template<typename T_field>
  75. read_context_ptr foreign_table_field_t<T_field>
  76. ::foreign_read(const read_context& context, bool fake_context) const
  77. {
  78. if (!fake_context)
  79. {
  80. auto& dataset = context.get<dataset_type>();
  81. auto& member = this->field.getter(dataset);
  82. auto new_context = make_read_context(member, context.schema, context.connection, context.filter);
  83. using context_type = mp::decay_t<decltype(new_context)>;
  84. return std::make_unique<context_type>(new_context);
  85. }
  86. else
  87. {
  88. auto new_context = make_fake_context(hana::type_c<value_type>, context.schema, context.connection, context.filter);
  89. using context_type = mp::decay_t<decltype(new_context)>;
  90. return std::make_unique<context_type>(new_context);
  91. }
  92. }
  93. namespace __impl
  94. {
  95. /* is_primary_key_field */
  96. template<typename T_field>
  97. struct is_primary_key_field
  98. : public mp::decay_t<decltype(
  99. hana::contains(
  100. std::declval<T_field>().attributes,
  101. schema::attribute::primary_key))>
  102. { };
  103. /* is_foreign_table_field */
  104. template<typename T_schema, typename T_field>
  105. struct is_foreign_table_field
  106. : public mp::decay_t<decltype(
  107. hana::contains(
  108. hana::transform(
  109. std::declval<T_schema>().tables,
  110. schema::table::get_wrapped_dataset),
  111. hana::type_c<misc::real_dataset_t<typename T_field::getter_type::value_type>>))>
  112. { };
  113. /* field_type */
  114. template<typename T_schema, typename T_field, typename = void>
  115. struct field_type
  116. { using type = data_field_t<T_field>; };
  117. template<typename T_schema, typename T_field>
  118. struct field_type<T_schema, T_field, mp::enable_if<is_primary_key_field<T_field>>>
  119. { using type = primary_key_field_t<T_field>; };
  120. template<typename T_schema, typename T_field>
  121. struct field_type<T_schema, T_field, mp::enable_if<is_foreign_table_field<T_schema, T_field>>>
  122. { using type = foreign_table_field_t<T_field>; };
  123. template<typename T_schema, typename T_field>
  124. using field_type_t = typename field_type<T_schema, T_field>::type;
  125. /* make_field_impl */
  126. template<typename T, typename>
  127. struct make_field_impl
  128. {
  129. template<typename... T_args>
  130. static constexpr decltype(auto) apply(T_args&&... args)
  131. { static_assert(sizeof...(args) == -1, "Invalid parameters for mariadb::make_field(...)!"); }
  132. };
  133. template<typename T_schema, typename T_table, typename T_field>
  134. struct make_field_impl<
  135. mp::list<T_schema, T_table, T_field>,
  136. mp::enable_if_c<
  137. schema::is_schema<mp::decay_t<T_schema>>::value
  138. && schema::is_table <mp::decay_t<T_table >>::value
  139. && schema::is_field <mp::decay_t<T_field >>::value>>
  140. {
  141. static constexpr decltype(auto) apply(const T_schema& schema, const T_table& table, const T_field& field)
  142. {
  143. using schema_type = mp::decay_t<T_schema>;
  144. using field_type = mp::decay_t<T_field>;
  145. using return_type = field_type_t<schema_type, field_type>;
  146. using primary_key_type = primary_key_field_t<field_type>;
  147. return_type ret(field);
  148. ret.schema_name = schema.name;
  149. ret.table_name = table.name;
  150. ret.field_name = field.name;
  151. ret.attributes = make_attributes(field.attributes);
  152. hana::eval_if(
  153. hana::equal(hana::type_c<return_type>, hana::type_c<primary_key_type>),
  154. [&ret](){
  155. ret.field_name = ret.table_name + "_" + ret.field_name;
  156. }, [](){ });
  157. return ret;
  158. }
  159. };
  160. }
  161. }
  162. end_namespace_cpphibernate_driver_mariadb