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.
 
 
 

131 lines
4.4 KiB

  1. #pragma once
  2. #include "create_update.h"
  3. #include "../classes/schema/schema.inl"
  4. #include "../helper/nullable_helper.inl"
  5. #include "../context/create_update_context.inl"
  6. namespace cpphibernate {
  7. namespace mariadb {
  8. /* create_update_impl_t - default (normal dataset) */
  9. template<typename T_dataset, typename>
  10. struct create_update_impl_t
  11. {
  12. using dataset_type = T_dataset;
  13. static inline value_t apply(const create_update_context& context, bool strict = true)
  14. {
  15. using namespace ::cppmariadb;
  16. value_t ret;
  17. auto dataset_id = get_type_id(hana::type_c<dataset_type>);
  18. auto& connection = context.connection;
  19. auto& schema = context.schema;
  20. auto& table = schema.table(dataset_id);
  21. assert(table.primary_key_field);
  22. transaction_lock trans(connection);
  23. /* if the value of primary key field does not match the operation of the context */
  24. if (table.primary_key_field->is_default(context) != context.is_create())
  25. {
  26. /* if we are not in strict mode, change the context to an update context */
  27. if (!strict)
  28. {
  29. static const filter_t dummy;
  30. ret = table.create_update(context.is_create()
  31. ? context.make_update_context(dummy)
  32. : context.make_create_context());
  33. }
  34. /* if we expect an update operation in strict mode throw an exception
  35. * because an update operation needs an primary key assigned */
  36. else if (context.is_update())
  37. {
  38. throw exception("can not update dataset with no primary key assigned!");
  39. }
  40. /* if we expect an create operation in strict mode throw an exception
  41. because an create operation expects the primary key to not be assigned */
  42. else
  43. {
  44. throw exception("can not create dataset with primary key assigned!");
  45. }
  46. }
  47. else
  48. {
  49. ret = table.create_update(context);
  50. }
  51. trans.commit();
  52. return ret;
  53. }
  54. };
  55. /* create_update_impl_t - nullable */
  56. template<typename T_dataset>
  57. struct create_update_impl_t<
  58. T_dataset,
  59. mp::enable_if_t<is_nullable_v<T_dataset>>>
  60. {
  61. using dataset_type = T_dataset;
  62. using nullable_helper_type = nullable_helper<dataset_type>;
  63. static inline value_t apply(const create_update_context& context, bool strict = true)
  64. {
  65. value_t ret;
  66. auto& dataset = context.get<dataset_type>();
  67. auto* value = nullable_helper_type::get(dataset);
  68. if (value)
  69. {
  70. using new_dataset_type = mp::decay_t<decltype(*value)>;
  71. using new_create_update_impl_type = create_update_impl_t<new_dataset_type>;
  72. ret = new_create_update_impl_type::apply(change_context(context, *value), strict);
  73. }
  74. else if (strict)
  75. {
  76. throw exception("can not create nullable type with no value!");
  77. }
  78. return ret;
  79. }
  80. };
  81. /* create_update_impl_t - container */
  82. template<typename T_dataset>
  83. struct create_update_impl_t<
  84. T_dataset,
  85. mp::enable_if_t<is_container_v<T_dataset>>>
  86. {
  87. using dataset_type = T_dataset;
  88. static inline value_t apply(const create_update_context& context, bool strict = true)
  89. {
  90. using namespace ::cppmariadb;
  91. value_t ret;
  92. auto& connection = context.connection;
  93. auto& dataset = context.get<dataset_type>();
  94. transaction_lock trans(connection);
  95. ssize_t index = 0;
  96. for (auto& x : dataset)
  97. {
  98. using new_dataset_type = mp::decay_t<decltype(x)>;
  99. using new_create_update_impl_type = create_update_impl_t<new_dataset_type>;
  100. auto new_context = change_context(context, x);
  101. new_context.index = index++;
  102. new_create_update_impl_type::apply(new_context, strict);
  103. }
  104. trans.commit();
  105. return ret;
  106. }
  107. };
  108. } }