No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

132 líneas
4.0 KiB

  1. #pragma once
  2. #include <cpphibernate/config.h>
  3. #include "filter.h"
  4. #include "../classes/fields/field.h"
  5. #include "../classes/tables/table.h"
  6. #include "../classes/schema/schema.h"
  7. #include <cpphibernate/schema/field.inl>
  8. #include <cpphibernate/schema/table.inl>
  9. #include <cpphibernate/schema/schema.inl>
  10. namespace cpphibernate {
  11. namespace mariadb {
  12. namespace __impl
  13. {
  14. /* filter_add_element_impl */
  15. template<typename X, typename = void>
  16. struct filter_add_element_impl
  17. {
  18. template<typename... T_args>
  19. static constexpr decltype(auto) apply(T_args&&... args)
  20. { static_assert(sizeof...(args) == -1, "Invalid parameters for filter_add_element(...)!"); }
  21. };
  22. template<typename T_table>
  23. struct filter_add_element_impl<
  24. mp::list<filter_t&, const schema_t&, T_table>,
  25. mp::enable_if_t<
  26. schema::is_table_v<mp::decay_t<T_table>>>>
  27. {
  28. static constexpr decltype(auto) apply(filter_t& filter, const schema_t& schema, const T_table& table)
  29. {
  30. auto dataset_id = get_type_id(table.wrapped_dataset);
  31. auto& t = schema.table(dataset_id);
  32. filter.tables.emplace(&t);
  33. for (auto& ptr : t.fields)
  34. {
  35. filter.fields.emplace(ptr.get());
  36. }
  37. }
  38. };
  39. template<typename T_field>
  40. struct filter_add_element_impl<
  41. mp::list<filter_t&, const schema_t&, T_field>,
  42. mp::enable_if_t<
  43. schema::is_field_v<mp::decay_t<T_field>>>>
  44. {
  45. static constexpr decltype(auto) apply(filter_t& filter, const schema_t& schema, const T_field& field)
  46. {
  47. auto field_id = get_type_id(hana::type_c<mp::decay_t<T_field>>);
  48. auto& f = schema.field(field_id);
  49. filter.fields.emplace(&f);
  50. filter.tables.emplace(f.table);
  51. }
  52. };
  53. constexpr decltype(auto) filter_add_element = ::cppmp::generic_predicate<__impl::filter_add_element_impl> { };
  54. }
  55. /* filter_t */
  56. bool filter_t::is_excluded(const table_t& table) const
  57. {
  58. auto ret = static_cast<bool>(tables.count(&table));
  59. if (!exclusive)
  60. ret = !ret;
  61. return ret;
  62. }
  63. bool filter_t::is_excluded(const field_t& field) const
  64. {
  65. auto ret = static_cast<bool>(fields.count(&field));
  66. if (!exclusive)
  67. ret = !ret;
  68. return ret;
  69. }
  70. template<typename... T_args>
  71. void filter_t::set_inclusive(const schema_t& schema, T_args&&... args)
  72. {
  73. clear();
  74. exclusive = false;
  75. cache_id = static_cast<ssize_t>(cppcore::get_unique_id<filter_t, mp::decay_t<T_args>...>() + 1);
  76. int dummy[] = { 0, (__impl::filter_add_element(*this, schema, std::forward<T_args>(args)), void(), 0)... };
  77. (void)dummy;
  78. }
  79. template<typename... T_args>
  80. void filter_t::set_exclusive(const schema_t& schema, T_args&&... args)
  81. {
  82. clear();
  83. exclusive = true;
  84. cache_id = -static_cast<ssize_t>(cppcore::get_unique_id<filter_t, mp::decay_t<T_args>...>() + 1);
  85. int dummy[] = { 0, (__impl::filter_add_element(*this, schema, std::forward<T_args>(args)), void(), 0)... };
  86. (void)dummy;
  87. // remove excluded tables if not all fields are excluded
  88. auto it = tables.begin();
  89. while (it != tables.end())
  90. {
  91. bool removed = false;
  92. for (auto& field : (*it)->fields)
  93. {
  94. if (fields.count(field.get()))
  95. {
  96. it = tables.erase(it);
  97. removed = true;
  98. break;
  99. }
  100. }
  101. if (!removed)
  102. ++it;
  103. }
  104. }
  105. void filter_t::clear()
  106. {
  107. cache_id = 0;
  108. exclusive = true;
  109. fields.clear();
  110. tables.clear();
  111. }
  112. } }