From 36ded9c55f102fb64c853c5307b1bcd3f43fef88 Mon Sep 17 00:00:00 2001 From: bergmann Date: Sun, 23 Sep 2018 12:24:55 +0200 Subject: [PATCH] * implemented mariadb driver filters * fixed some small errors * added options.cmake --- cmake/options.cmake | 10 ++ include/cpphibernate/config.h | 3 +- include/cpphibernate/context.h | 2 +- .../driver/mariadb/helper/transaction_lock.h | 2 +- include/cpphibernate/driver/mariadb/mariadb.h | 14 +++ include/cpphibernate/driver/mariadb/schema.h | 6 +- .../driver/mariadb/schema/field.h | 8 +- .../driver/mariadb/schema/filter.h | 31 +++++- .../driver/mariadb/schema/filter.inl | 99 +++++++++++++++++++ .../driver/mariadb/schema/table.inl | 12 ++- include/cpphibernate/misc/general.h | 2 - include/cpphibernate/schema/getter.h | 39 ++------ include/cpphibernate/schema/setter.h | 43 +++----- src/CMakeLists.txt | 4 +- src/driver/mariadb/schema/table.cpp | 2 +- test/CMakeLists.txt | 2 + test/test_helper.h | 2 + test/test_schema.h | 3 + 18 files changed, 206 insertions(+), 78 deletions(-) create mode 100644 cmake/options.cmake create mode 100644 include/cpphibernate/driver/mariadb/schema/filter.inl diff --git a/cmake/options.cmake b/cmake/options.cmake new file mode 100644 index 0000000..43c5d8d --- /dev/null +++ b/cmake/options.cmake @@ -0,0 +1,10 @@ +Option ( CPPHIBERNATE_BUILD_SHARED + "Build cpphibernate shared library" + OFF ) +Option ( CPPHIBERNATE_DEBUG_OUTPUT + "Enable debug output" + OFF ) + +If ( CPPHIBERNATE_DEBUG_OUTPUT ) + Add_Definitions ( -DCPPHIBERNATE_DEBUG ) +EndIf ( ) \ No newline at end of file diff --git a/include/cpphibernate/config.h b/include/cpphibernate/config.h index e2092b6..8350fec 100644 --- a/include/cpphibernate/config.h +++ b/include/cpphibernate/config.h @@ -3,8 +3,7 @@ #include #include -#define cpphibernate_debug -#ifdef cpphibernate_debug +#ifdef CPPHIBERNATE_DEBUG # include # define cpphibernate_debug_log(...) log_global_message(debug) << __VA_ARGS__ #else diff --git a/include/cpphibernate/context.h b/include/cpphibernate/context.h index 2df4d92..ae0fd24 100644 --- a/include/cpphibernate/context.h +++ b/include/cpphibernate/context.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include beg_namespace_cpphibernate { diff --git a/include/cpphibernate/driver/mariadb/helper/transaction_lock.h b/include/cpphibernate/driver/mariadb/helper/transaction_lock.h index 8df9148..750891f 100644 --- a/include/cpphibernate/driver/mariadb/helper/transaction_lock.h +++ b/include/cpphibernate/driver/mariadb/helper/transaction_lock.h @@ -24,7 +24,7 @@ beg_namespace_cpphibernate_driver_mariadb private: using transaction_ptr_type = std::unique_ptr<::cppmariadb::transaction>; -#ifdef cpphibernate_debug +#ifdef CPPHIBERNATE_DEBUG # define debug_log(str) cpphibernate_debug_log( \ "transaction (id=" << std::setw(8) << std::setfill(' ') << lock.id << \ ", counter=" << std::setw(2) << std::setfill(' ') << counter << ") " str) diff --git a/include/cpphibernate/driver/mariadb/mariadb.h b/include/cpphibernate/driver/mariadb/mariadb.h index e2dcbcc..5bfcff8 100644 --- a/include/cpphibernate/driver/mariadb/mariadb.h +++ b/include/cpphibernate/driver/mariadb/mariadb.h @@ -26,6 +26,20 @@ beg_namespace_cpphibernate_driver_mariadb cpphibernate_copyable(mariadb_driver_t, delete); cpphibernate_moveable(mariadb_driver_t, default); + inline const ::cppmariadb::connection& connection() const + { return _connection; } + + template + inline void set_filter_inclusive(T_args&&... args) + { _filter.set_inclusive(_schema, std::forward(args)...); } + + template + inline void set_filter_exclusive(T_args&&... args) + { _filter.set_exclusive(_schema, std::forward(args)...); } + + inline void clear_filter() + { _filter.clear(); } + protected: inline void init_impl(bool recreate) const { diff --git a/include/cpphibernate/driver/mariadb/schema.h b/include/cpphibernate/driver/mariadb/schema.h index 0010a5a..f3fa522 100644 --- a/include/cpphibernate/driver/mariadb/schema.h +++ b/include/cpphibernate/driver/mariadb/schema.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include +#include #include -#include -#include \ No newline at end of file +#include \ No newline at end of file diff --git a/include/cpphibernate/driver/mariadb/schema/field.h b/include/cpphibernate/driver/mariadb/schema/field.h index 73bfadd..a507b40 100644 --- a/include/cpphibernate/driver/mariadb/schema/field.h +++ b/include/cpphibernate/driver/mariadb/schema/field.h @@ -106,11 +106,11 @@ beg_namespace_cpphibernate_driver_mariadb : public field_t { using base_type = field_t; - using field_type = T_field; - using getter_type = typename mp::decay_t::getter_type; - using dataset_type = typename getter_type::dataset_type; + using field_type = mp::decay_t; + using getter_type = typename field_type::getter_type; + using dataset_type = mp::decay_t; using real_dataset_type = misc::real_dataset_t; - using value_type = typename getter_type::value_type; + using value_type = mp::decay_t; using real_value_type = misc::real_dataset_t; using type_props = type_properties; diff --git a/include/cpphibernate/driver/mariadb/schema/filter.h b/include/cpphibernate/driver/mariadb/schema/filter.h index fae0931..92c9523 100644 --- a/include/cpphibernate/driver/mariadb/schema/filter.h +++ b/include/cpphibernate/driver/mariadb/schema/filter.h @@ -5,26 +5,49 @@ #include #include #include +#include beg_namespace_cpphibernate_driver_mariadb { + namespace __impl + { + + /* filter_add_element */ + + template + struct filter_add_element_impl; + + constexpr decltype(auto) filter_add_element = misc::make_generic_predicate<__impl::filter_add_element_impl> { }; + + } + /* filter_t */ struct filter_t { + public: using field_set_type = std::set; using table_set_type = std::set; size_t cache_id { 0 }; + bool exclusive; field_set_type fields; table_set_type tables; - inline bool is_excluded(const table_t& table) const - { return tables.count(&table); } + inline bool is_excluded(const table_t& table) const; + inline bool is_excluded(const field_t& field) const; + + template + inline void set_inclusive(const schema_t& schema, T_args&&... args); + + template + inline void set_exclusive(const schema_t& schema, T_args&&... args); + + inline void clear(); - inline bool is_excluded(const field_t& field) const - { return fields.count(&field); } + private: + void update_tables(); }; } diff --git a/include/cpphibernate/driver/mariadb/schema/filter.inl b/include/cpphibernate/driver/mariadb/schema/filter.inl new file mode 100644 index 0000000..37667a9 --- /dev/null +++ b/include/cpphibernate/driver/mariadb/schema/filter.inl @@ -0,0 +1,99 @@ +#pragma once + +#include +#include + +beg_namespace_cpphibernate_driver_mariadb +{ + + namespace __impl + { + + /* filter_add_element_impl */ + + template + struct filter_add_element_impl + { + template + static constexpr decltype(auto) apply(T_args&&... args) + { static_assert(sizeof...(args) == -1, "Invalid parameters for mariadb::filter_add_element(...)!"); } + }; + + template + struct filter_add_element_impl< + mp::list, + mp::enable_if_c< + schema::is_table>::value>> + { + static constexpr decltype(auto) apply(filter_t& filter, const schema_t& schema, const T_table& table) + { + auto dataset_id = misc::get_type_id(table.wrapped_dataset); + auto& t = schema.table(dataset_id); + filter.tables.emplace(&t); + } + }; + + template + struct filter_add_element_impl< + mp::list, + mp::enable_if_c< + schema::is_field>::value>> + { + static constexpr decltype(auto) apply(filter_t& filter, const schema_t& schema, const T_field& field) + { + auto field_id = misc::get_type_id(hana::type_c>); + auto& f = schema.field(field_id); + filter.fields.emplace(&f); + } + }; + + } + + /* filter_t */ + + bool filter_t::is_excluded(const table_t& table) const + { + auto ret = static_cast(tables.count(&table)); + if (!exclusive) + ret = !ret; + return ret; + } + + bool filter_t::is_excluded(const field_t& field) const + { + auto ret = static_cast(fields.count(&field)); + if (!exclusive) + ret = !ret; + return ret; + } + + template + void filter_t::set_inclusive(const schema_t& schema, T_args&&... args) + { + clear(); + exclusive = false; + cache_id = static_cast(utl::get_unique_id...>()); + int dummy[] = { 0, (__impl::filter_add_element(*this, schema, std::forward(args)), void(), 0)... }; + (void)dummy; + } + + template + void filter_t::set_exclusive(const schema_t& schema, T_args&&... args) + { + clear(); + exclusive = true; + cache_id = static_cast(utl::get_unique_id...>()); + int dummy[] = { 0, (__impl::filter_add_element(*this, schema, std::forward(args)), void(), 0)... }; + (void)dummy; + } + + void filter_t::clear() + { + cache_id = 0; + exclusive = true; + fields.clear(); + tables.clear(); + } + +} +end_namespace_cpphibernate_driver_mariadb \ No newline at end of file diff --git a/include/cpphibernate/driver/mariadb/schema/table.inl b/include/cpphibernate/driver/mariadb/schema/table.inl index f569b4a..9191096 100644 --- a/include/cpphibernate/driver/mariadb/schema/table.inl +++ b/include/cpphibernate/driver/mariadb/schema/table.inl @@ -11,7 +11,17 @@ beg_namespace_cpphibernate_driver_mariadb template void table_polymorphic_t ::emplace(const read_context& context) const - { context.emplace(this); } + { + hana::eval_if( + std::is_abstract { }, + [](){ + throw misc::hibernate_exception(std::string("can not create dataset of abstract type: ") + + utl::type_helper::name()); + }, + [&context, this](auto _){ + _(context).template emplace(this); + }); + } template template diff --git a/include/cpphibernate/misc/general.h b/include/cpphibernate/misc/general.h index 181bfea..037db6c 100644 --- a/include/cpphibernate/misc/general.h +++ b/include/cpphibernate/misc/general.h @@ -1,7 +1,5 @@ #pragma once -#include // TODO debug! - #include #include diff --git a/include/cpphibernate/schema/getter.h b/include/cpphibernate/schema/getter.h index 6b421e0..15924d3 100644 --- a/include/cpphibernate/schema/getter.h +++ b/include/cpphibernate/schema/getter.h @@ -143,42 +143,23 @@ beg_namespace_cpphibernate_schema /* getter_make_impl */ - template struct getter_make_impl { - template - static constexpr decltype(auto) apply(Args&&... args) - { static_assert(sizeof...(args) == -1, "Invalid arguments to schema::getter::make(...)!"); } - }; - - template - struct getter_make_impl, void> - { - static constexpr decltype(auto) apply(T_value T_dataset::*member) + template + constexpr decltype(auto) operator()(T_value T_dataset::*member) const { return make_getter_member_var(member); } - }; - template - struct getter_make_impl, void> - { - static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void)) + template + constexpr decltype(auto) operator()(T_value (T_dataset::*member)(void)) const { return make_getter_member_func(member); } - }; - template - struct getter_make_impl, void> - { - static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void) const) + template + constexpr decltype(auto) operator()(T_value (T_dataset::*member)(void) const) const { return make_getter_member_func(member); } - }; - template - struct getter_make_impl, mp::enable_if_c< - hana::is_a> - && hana::is_a>>> - { - static constexpr decltype(auto) apply(T_func&& func, T_wrapped_dataset&& wrapped_dataset, T_value_type&& value_type) - { return make_getter_lambda(std::forward(func), std::forward(wrapped_dataset), std::forward(value_type)); } + template + constexpr decltype(auto) operator()(T_func&& func, hana::type&& wrapped_dataset, hana::type&& wrapped_value) const + { return make_getter_lambda(std::forward(func), std::forward>(wrapped_dataset), std::forward>(wrapped_value)); } }; } @@ -186,7 +167,7 @@ beg_namespace_cpphibernate_schema namespace getter { - constexpr decltype(auto) make = misc::make_generic_predicate<__impl::getter_make_impl> { }; + constexpr decltype(auto) make = __impl::getter_make_impl { }; } diff --git a/include/cpphibernate/schema/setter.h b/include/cpphibernate/schema/setter.h index 17784e4..728e48a 100644 --- a/include/cpphibernate/schema/setter.h +++ b/include/cpphibernate/schema/setter.h @@ -159,42 +159,27 @@ beg_namespace_cpphibernate_schema /* setter_make_impl */ - template struct setter_make_impl { - template - static constexpr decltype(auto) apply(Args&&...) - { return make_setter_none(); } - }; - - template - struct setter_make_impl, void> - { - static constexpr decltype(auto) apply(T_value T_dataset::*member) + template + constexpr decltype(auto) operator()(T_value T_dataset::*member) const { return make_setter_member_var(member); } - }; - template - struct setter_make_impl, void> - { - static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void)) + template + constexpr decltype(auto) operator()(void (T_dataset::*member)(T_value)) const { return make_setter_member_func(member); } - }; - template - struct setter_make_impl, void> - { - static constexpr decltype(auto) apply(T_value (T_dataset::*member)(void) const) + template + constexpr decltype(auto) operator()(void (T_dataset::*member)(T_value&)) const { return make_setter_member_func(member); } - }; - template - struct setter_make_impl, mp::enable_if_c< - hana::is_a> - && hana::is_a>>> - { - static constexpr decltype(auto) apply(T_func&& func, T_wrapped_dataset&& wrapped_dataset, T_value_type&& value_type) - { return make_setter_lambda(std::forward(func), std::forward(wrapped_dataset), std::forward(value_type)); } + template + constexpr decltype(auto) operator()(void (T_dataset::*member)(T_value&&)) const + { return make_setter_member_func(member); } + + template + constexpr decltype(auto) operator()(T_func&& func, hana::type&& wrapped_dataset, hana::type&& wrapped_value) const + { return make_setter_lambda(std::forward(func), std::forward>(wrapped_dataset), std::forward>(wrapped_value)); } }; } @@ -202,7 +187,7 @@ beg_namespace_cpphibernate_schema namespace setter { - constexpr decltype(auto) make = misc::make_generic_predicate<__impl::setter_make_impl> { }; + constexpr decltype(auto) make = __impl::setter_make_impl { }; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d85db15..aa26a3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,9 +4,9 @@ Include ( cotire OPTIONAL ) Include ( pedantic OPTIONAL ) Include ( strip_symbols OPTIONAL ) -Option ( BUILD_SHARED_CPPHIBERNATE "Build cpphibernate shared library" OFF ) +Include ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/options.cmake ) -Set ( BUILD_SHARED_LIBS ${BUILD_SHARED_CPPHIBERNATE} ) +Set ( BUILD_SHARED_LIBS ${CPPHIBERNATE_BUILD_SHARED} ) Set ( CMAKE_CXX_STANDARD 17 ) Set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PEDANTIC_C_FLAGS}" ) Set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PEDANTIC_CXX_FLAGS}" ) diff --git a/src/driver/mariadb/schema/table.cpp b/src/driver/mariadb/schema/table.cpp index 78a7246..85cfca1 100644 --- a/src/driver/mariadb/schema/table.cpp +++ b/src/driver/mariadb/schema/table.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include using namespace ::utl; using namespace ::cpphibernate; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9205f24..c4a9318 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,6 +4,8 @@ Include ( cotire OPTIONAL ) Include ( pedantic OPTIONAL ) Include ( cmake_tests OPTIONAL ) +Include ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/options.cmake ) + Set ( CMAKE_CXX_STANDARD 17 ) Set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PEDANTIC_C_FLAGS}" ) Set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PEDANTIC_CXX_FLAGS}" ) diff --git a/test/test_helper.h b/test/test_helper.h index 9c50e7b..c35c52e 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/test/test_schema.h b/test/test_schema.h index eb60886..c71de21 100644 --- a/test/test_schema.h +++ b/test/test_schema.h @@ -1,4 +1,7 @@ +#pragma once + #include +#include enum class test_enum {