|
- #pragma once
-
- #include <cpphibernate/modifier.h>
-
- #include "context.h"
-
- namespace cpphibernate
- {
-
- namespace __impl
- {
-
- /* init_builder */
-
- template<typename X, typename = void>
- struct init_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for context::init(...)!"); }
- };
-
- constexpr decltype(auto) init = mp::generic_predicate<init_builder> { };
-
- template<typename T_impl, typename T_bool>
- struct init_builder<
- mp::list<T_impl, T_bool>,
- mp::enable_if_t<
- mp::is_valid_v<decltype(std::declval<T_impl>().init(std::declval<bool>()))>
- && mp::is_same_v<bool, mp::decay_t<T_bool>>
- >>
- {
- static constexpr decltype(auto) apply(T_impl& impl, bool recreate)
- { return impl.init(recreate); }
- };
-
- /* create_builder */
-
- template<typename X, typename = void>
- struct create_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for context::create(...)!"); }
- };
-
- constexpr decltype(auto) create = mp::generic_predicate<create_builder> { };
-
- template<typename T_impl, typename T_dataset>
- struct create_builder<
- mp::list<T_impl, T_dataset>,
- mp::enable_if_t<
- mp::is_valid_v<decltype(std::declval<T_impl>().create(std::declval<T_dataset&>()))>
- >>
- {
- static constexpr decltype(auto) apply(T_impl& impl, T_dataset& dataset)
- { return impl.create(dataset); }
- };
-
- /* read_builder */
-
- template<typename X, typename = void>
- struct read_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for context::read(...)!"); }
- };
-
- constexpr decltype(auto) read = mp::generic_predicate<read_builder> { };
-
- template<typename T_schema, typename T_impl, typename T_dataset, typename T_modifiers>
- struct read_builder<
- mp::list<T_schema, T_impl, T_dataset, T_modifiers>,
- mp::enable_if_t<
- schema::is_schema_v<mp::decay_t<T_schema>>
- && is_modifiers_v<mp::decay_t<T_modifiers>>
- && mp::is_valid_v<decltype(std::declval<T_impl>().read(
- std::declval<T_dataset&>(),
- std::declval<T_modifiers>()))>
- >>
- {
- static constexpr decltype(auto) apply(const T_schema& schema, T_impl& impl, T_dataset& dataset, T_modifiers&& modifiers)
- { return impl.read(dataset, std::forward<T_modifiers>(modifiers)); }
- };
-
- template<typename T_schema, typename T_impl, typename T_dataset>
- struct read_builder<
- mp::list<T_schema, T_impl, T_dataset>,
- mp::enable_if_t<
- schema::is_schema_v<mp::decay_t<T_schema>>
- && !is_container_v<mp::decay_t<T_dataset>>
- && !is_nullable_v<mp::decay_t<T_dataset>>
- >>
- {
- static constexpr decltype(auto) apply(const T_schema& schema, T_impl& impl, T_dataset& dataset)
- {
- using real_dataset_type = real_dataset_t<mp::decay_t<T_dataset>>;
-
- auto& table = schema::find_table(schema.tables, hana::type_c<real_dataset_type>);
- auto& primary_key = schema::get_primary_key_field(table);
-
- return impl.read(dataset, make_modifiers(where(equal(primary_key, primary_key.getter(dataset)))));
- }
- };
-
- template<typename T_schema, typename T_impl, typename T_dataset, typename... T_modifier>
- struct read_builder<
- mp::list<T_schema, T_impl, T_dataset, T_modifier...>,
- mp::enable_if_t<
- schema::is_schema_v<mp::decay_t<T_schema>>
- && mp::is_true_v<is_modifier_v<T_modifier>...>
- && ( is_container_v<mp::decay_t<T_dataset>>
- || is_nullable_v<mp::decay_t<T_dataset>>)
- >>
- {
- static constexpr decltype(auto) apply(const T_schema& schema, T_impl& impl, T_dataset& dataset, T_modifier&&... modifier)
- { return impl.read(dataset, make_modifiers(std::forward<T_modifier>(modifier)...)); }
- };
-
- template<typename T_schema, typename T_impl, typename T_dataset, typename... T_modifier>
- struct read_builder<
- mp::list<T_schema, T_impl, T_dataset, T_modifier...>,
- mp::enable_if_t<
- schema::is_schema_v<mp::decay_t<T_schema>>
- && mp::is_true_v<is_modifier_v<T_modifier>...>
- && !is_container_v<mp::decay_t<T_dataset>>
- && !is_nullable_v<mp::decay_t<T_dataset>>
- && sizeof...(T_modifier)
- >>
- {
- static constexpr decltype(auto) apply(const T_schema& schema, T_impl& impl, T_dataset& dataset, T_modifier&&... modifier)
- { return impl.read(dataset, make_modifiers(std::forward<T_modifier>(modifier)...)); }
- };
-
- /* update_builder */
-
- template<typename X, typename = void>
- struct update_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for context::update(...)!"); }
- };
-
- constexpr decltype(auto) update = mp::generic_predicate<update_builder> { };
-
- template<typename T_impl, typename T_dataset>
- struct update_builder<
- mp::list<T_impl, T_dataset>,
- mp::enable_if_t<
- mp::is_valid_v<decltype(std::declval<T_impl>().update(std::declval<T_dataset&>()))>>>
- {
- static constexpr decltype(auto) apply(T_impl& impl, T_dataset& dataset)
- { return impl.update(dataset); }
- };
-
- /* destroy_builder */
-
- template<typename X, typename = void>
- struct destroy_builder
- {
- template<typename... T_args>
- static constexpr decltype(auto) apply(T_args&&...)
- { static_assert(sizeof...(T_args) == -1, "Invalid parameters for context::destroy(...)!"); }
- };
-
- constexpr decltype(auto) destroy = mp::generic_predicate<destroy_builder> { };
-
- template<typename T_impl, typename T_dataset>
- struct destroy_builder<
- mp::list<T_impl, T_dataset>,
- mp::enable_if_t<
- mp::is_valid_v<decltype(std::declval<T_impl>().destroy(std::declval<T_dataset&>()))>>>
- {
- static constexpr decltype(auto) apply(T_impl& impl, T_dataset& dataset)
- { return impl.destroy(dataset); }
- };
-
- }
-
- /* context */
-
- template<typename T_driver, typename T_schema>
- template<typename... T_args>
- constexpr context<T_driver, T_schema>::context(const schema_type& p_schema, T_args&&... p_args)
- : base_type (p_schema, std::forward<T_args>(p_args)...)
- , _schema (p_schema)
- { }
-
- template<typename T_driver, typename T_schema>
- template<typename... T_args>
- constexpr decltype(auto) context<T_driver, T_schema>::init(T_args&&... args)
- { return __impl::init(this->impl(), std::forward<T_args>(args)...); }
-
- template<typename T_driver, typename T_schema>
- template<typename... T_args>
- constexpr decltype(auto) context<T_driver, T_schema>::create(T_args&&... args)
- { return __impl::create(this->impl(), std::forward<T_args>(args)...); }
-
- template<typename T_driver, typename T_schema>
- template<typename... T_args>
- constexpr decltype(auto) context<T_driver, T_schema>::read(T_args&&... args)
- { return __impl::read(_schema, this->impl(), std::forward<T_args>(args)...); }
-
- template<typename T_driver, typename T_schema>
- template<typename... T_args>
- constexpr decltype(auto) context<T_driver, T_schema>::update(T_args&&... args)
- { return __impl::update(this->impl(), std::forward<T_args>(args)...); }
-
- template<typename T_driver, typename T_schema>
- template<typename... T_args>
- constexpr decltype(auto) context<T_driver, T_schema>::destroy(T_args&&... args)
- { return __impl::destroy(this->impl(), std::forward<T_args>(args)...); }
-
- /* make_context */
-
- template<typename T_driver, typename T_schema, typename... T_args>
- constexpr decltype(auto) make_context(T_schema&& schema, T_args&&... args)
- {
- using context_type = context<T_driver, T_schema>;
- return context_type(std::forward<T_schema>(schema), std::forward<T_args>(args)...);
- }
-
- /* make_context_ptr */
-
- template<typename T_driver, typename T_schema, typename... T_args>
- constexpr decltype(auto) make_context_ptr(T_schema&& schema, T_args&&... args)
- {
- using context_type = context<T_driver, T_schema>;
- using pointer_type = std::unique_ptr<context_type>;
- return pointer_type(new context_type(std::forward<T_schema>(schema), std::forward<T_args>(args)...));
- }
-
- }
|