|
- #pragma once
-
- #include <cpphibernate/config.h>
-
- #include "filter.h"
- #include "../classes/fields/field.h"
- #include "../classes/tables/table.h"
- #include "../classes/schema/schema.h"
-
- #include <cpphibernate/schema/field.inl>
- #include <cpphibernate/schema/table.inl>
- #include <cpphibernate/schema/schema.inl>
-
- namespace cpphibernate {
- namespace mariadb {
-
- namespace __impl
- {
-
- /* filter_add_element_impl */
-
- template<typename X, typename = void>
- struct filter_add_element_impl
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&... args)
- { static_assert(sizeof...(args) == -1, "Invalid parameters for filter_add_element(...)!"); }
- };
-
- template<typename T_table>
- struct filter_add_element_impl<
- mp::list<filter_t&, const schema_t&, T_table>,
- mp::enable_if_t<
- schema::is_table_v<mp::decay_t<T_table>>>>
- {
- static constexpr decltype(auto) apply(filter_t& filter, const schema_t& schema, const T_table& table)
- {
- auto dataset_id = get_type_id(table.wrapped_dataset);
- auto& t = schema.table(dataset_id);
- filter.tables.emplace(&t);
- for (auto& ptr : t.fields)
- {
- filter.fields.emplace(ptr.get());
- }
- }
- };
-
- template<typename T_field>
- struct filter_add_element_impl<
- mp::list<filter_t&, const schema_t&, T_field>,
- mp::enable_if_t<
- schema::is_field_v<mp::decay_t<T_field>>>>
- {
- static constexpr decltype(auto) apply(filter_t& filter, const schema_t& schema, const T_field& field)
- {
- auto field_id = get_type_id(hana::type_c<mp::decay_t<T_field>>);
- auto& f = schema.field(field_id);
- filter.fields.emplace(&f);
- filter.tables.emplace(f.table);
- }
- };
-
- constexpr decltype(auto) filter_add_element = ::cppmp::generic_predicate<__impl::filter_add_element_impl> { };
-
- }
-
- /* filter_t */
-
- bool filter_t::is_excluded(const table_t& table) const
- {
- auto ret = static_cast<bool>(tables.count(&table));
- if (!exclusive)
- ret = !ret;
- return ret;
- }
-
- bool filter_t::is_excluded(const field_t& field) const
- {
- auto ret = static_cast<bool>(fields.count(&field));
- if (!exclusive)
- ret = !ret;
- return ret;
- }
-
- template<typename... T_args>
- void filter_t::set_inclusive(const schema_t& schema, T_args&&... args)
- {
- clear();
- exclusive = false;
- cache_id = static_cast<ssize_t>(cppcore::get_unique_id<filter_t, mp::decay_t<T_args>...>() + 1);
- int dummy[] = { 0, (__impl::filter_add_element(*this, schema, std::forward<T_args>(args)), void(), 0)... };
- (void)dummy;
- }
-
- template<typename... T_args>
- void filter_t::set_exclusive(const schema_t& schema, T_args&&... args)
- {
- clear();
- exclusive = true;
- cache_id = -static_cast<ssize_t>(cppcore::get_unique_id<filter_t, mp::decay_t<T_args>...>() + 1);
- int dummy[] = { 0, (__impl::filter_add_element(*this, schema, std::forward<T_args>(args)), void(), 0)... };
- (void)dummy;
-
- // remove excluded tables if not all fields are excluded
- auto it = tables.begin();
- while (it != tables.end())
- {
- bool removed = false;
- for (auto& field : (*it)->fields)
- {
- if (fields.count(field.get()))
- {
- it = tables.erase(it);
- removed = true;
- break;
- }
- }
- if (!removed)
- ++it;
- }
- }
-
- void filter_t::clear()
- {
- cache_id = 0;
- exclusive = true;
- fields.clear();
- tables.clear();
- }
-
- } }
|