25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

126 satır
4.1 KiB

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