From e21fdb48292e7d3f686687fc14bde8a2429d389f Mon Sep 17 00:00:00 2001 From: rbock Date: Thu, 24 Jul 2014 23:02:08 +0200 Subject: [PATCH] Transport null_is_trivial_value and can_be_null to result fields --- include/sqlpp11/boolean.h | 8 ++--- include/sqlpp11/field.h | 26 +++++++++------ include/sqlpp11/floating_point.h | 8 ++--- include/sqlpp11/functions.h | 6 ++-- include/sqlpp11/integral.h | 8 ++--- include/sqlpp11/result_row.h | 49 ++++++++++++++++------------ include/sqlpp11/select_column_list.h | 13 ++++++-- include/sqlpp11/text.h | 8 ++--- include/sqlpp11/type_traits.h | 1 + 9 files changed, 76 insertions(+), 51 deletions(-) diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index 786b2200..fcd61093 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -96,7 +96,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { _result_entry_t(): @@ -128,7 +128,7 @@ namespace sqlpp _cpp_value_type value() const { - const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + const bool null_value = _is_null and not null_is_trivial_value_t::value and not connector_null_result_is_trivial_value_t::value; if (connector_assert_result_validity_t::value) { assert(_is_valid); @@ -200,8 +200,8 @@ namespace sqlpp }; }; - template - inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t& e) + template + inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t& e) { return os << e.value(); } diff --git a/include/sqlpp11/field.h b/include/sqlpp11/field.h index 02e0a849..ad8d9421 100644 --- a/include/sqlpp11/field.h +++ b/include/sqlpp11/field.h @@ -31,14 +31,16 @@ namespace sqlpp { - template + template struct field_t { - using _traits = make_traits; + using _traits = make_traits::type, + typename std::conditional::type + >; using _recursive_traits = make_recursive_traits<>; using _name_t = NameType; - static constexpr bool _trivial_value_is_null = TrivialValueIsNull; }; template @@ -49,23 +51,27 @@ namespace sqlpp namespace detail { #warning: Need to transport the "can be null" information via field_t to result_entry structs - template + template struct make_field_t_impl { + static constexpr bool _can_be_null = can_be_null_t::value; + static constexpr bool _depends_on_outer_table = detail::make_intersect_set_t, typename Select::_used_outer_tables>::size::value > 0; + using type = field_t, - trivial_value_is_null_t::value>; + detail::any_t<_can_be_null, _depends_on_outer_table>::value, + null_is_trivial_value::value>; }; - template - struct make_field_t_impl> + template + struct make_field_t_impl> { - using type = multi_field_t::type...>>; + using type = multi_field_t::type...>>; }; } - template - using make_field_t = typename detail::make_field_t_impl::type; + template + using make_field_t = typename detail::make_field_t_impl::type; } diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index a39c85ae..95e854ca 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -95,7 +95,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { using _value_type = integral; @@ -129,7 +129,7 @@ namespace sqlpp _cpp_value_type value() const { - const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + const bool null_value = _is_null and not null_is_trivial_value_t::value and not connector_null_result_is_trivial_value_t::value; if (connector_assert_result_validity_t::value) { assert(_is_valid); @@ -257,8 +257,8 @@ namespace sqlpp }; }; - template - inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t& e) + template + inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t& e) { return os << e.value(); } diff --git a/include/sqlpp11/functions.h b/include/sqlpp11/functions.h index 51791ccb..76a32e34 100644 --- a/include/sqlpp11/functions.h +++ b/include/sqlpp11/functions.h @@ -52,13 +52,15 @@ namespace sqlpp return { t }; } -#warning: verbatim_t always "can_be_null" (espcially since we cannot determine the required tables later on) template // Csaba Csoma suggests: unsafe_sql instead of verbatim struct verbatim_t: public ValueType::template expression_operators>, public alias_operators> { using _traits = make_traits; - using _recursive_traits = make_recursive_traits<>; + struct _recursive_traits : public make_recursive_traits<> + { + using _can_be_null = std::true_type; // since we do not know what's going on inside the verbatim, we assume it can be null + }; verbatim_t(std::string verbatim): _verbatim(verbatim) {} verbatim_t(const verbatim_t&) = default; diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index c1ab26bf..e458ab72 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -97,7 +97,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { using _value_type = integral; @@ -131,7 +131,7 @@ namespace sqlpp _cpp_value_type value() const { - const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + const bool null_value = _is_null and not null_is_trivial_value_t::value and not connector_null_result_is_trivial_value_t::value; if (connector_assert_result_validity_t::value) { assert(_is_valid); @@ -270,8 +270,8 @@ namespace sqlpp }; }; - template - inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t& e) + template + inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t& e) { return os << e.value(); } diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 1094692d..27749962 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -36,14 +36,14 @@ namespace sqlpp { namespace detail { - template + template struct result_row_impl; - template + template struct result_field: - public NamedExpr::_name_t::template _member_t::template _result_entry_t> + public FieldSpec::_name_t::template _member_t::template _result_entry_t> { - using _field = typename NamedExpr::_name_t::template _member_t::template _result_entry_t>; + using _field = typename FieldSpec::_name_t::template _member_t::template _result_entry_t>; result_field() = default; @@ -64,11 +64,11 @@ namespace sqlpp } }; - template - struct result_field>>: - public AliasProvider::_name_t::template _member_t, NamedExprs...>> + template + struct result_field>>: + public AliasProvider::_name_t::template _member_t, FieldSpecs...>> { - using _multi_field = typename AliasProvider::_name_t::template _member_t, NamedExprs...>>; + using _multi_field = typename AliasProvider::_name_t::template _member_t, FieldSpecs...>>; result_field() = default; @@ -89,9 +89,9 @@ namespace sqlpp } }; - template - struct result_row_impl, NamedExprs...>: - public result_field... + template + struct result_row_impl, FieldSpecs...>: + public result_field... { static constexpr std::size_t _last_index = LastIndex; @@ -100,29 +100,29 @@ namespace sqlpp void _validate() { using swallow = int[]; - (void) swallow{(result_field::_validate(), 0)...}; + (void) swallow{(result_field::_validate(), 0)...}; } void _invalidate() { using swallow = int[]; - (void) swallow{(result_field::_invalidate(), 0)...}; + (void) swallow{(result_field::_invalidate(), 0)...}; } template void _bind(Target& target) { using swallow = int[]; - (void) swallow{(result_field::_bind(target), 0)...}; + (void) swallow{(result_field::_bind(target), 0)...}; } }; } - template - struct result_row_t: public detail::result_row_impl, NamedExprs...> + template + struct result_row_t: public detail::result_row_impl, FieldSpecs...> { - using _impl = detail::result_row_impl, NamedExprs...>; + using _impl = detail::result_row_impl, FieldSpecs...>; bool _is_valid; static constexpr size_t _last_static_index = _impl::_last_index; @@ -178,11 +178,18 @@ namespace sqlpp } }; - template - struct dynamic_result_row_t: public detail::result_row_impl, NamedExprs...> + template + struct dynamic_result_row_t: public detail::result_row_impl, FieldSpecs...> { - using _impl = detail::result_row_impl, NamedExprs...>; - using _field_type = detail::text::_result_entry_t; + using _impl = detail::result_row_impl, FieldSpecs...>; + struct _field_spec_t + { + using _traits = make_traits; + using _recursive_traits = make_recursive_traits<>; + + struct _name_t {}; + }; + using _field_type = detail::text::_result_entry_t; static constexpr size_t _last_static_index = _impl::_last_index; bool _is_valid; diff --git a/include/sqlpp11/select_column_list.h b/include/sqlpp11/select_column_list.h index 0aab60ff..658d13ae 100644 --- a/include/sqlpp11/select_column_list.h +++ b/include/sqlpp11/select_column_list.h @@ -245,10 +245,19 @@ namespace sqlpp return static_cast(*this); } + template + struct _deferred_field_t + { + using type = make_field_t<_statement_t, Column>; + }; + + template + using _field_t = typename _deferred_field_t::type; + template using _result_row_t = typename std::conditional<_is_dynamic::value, - dynamic_result_row_t...>, - result_row_t...>>::type; + dynamic_result_row_t...>, + result_row_t...>>::type; using _dynamic_names_t = typename dynamic_select_column_list::_names_t; diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 9fff0b77..85ef236f 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -95,7 +95,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { _result_entry_t(): @@ -130,7 +130,7 @@ namespace sqlpp _cpp_value_type value() const { - const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + const bool null_value = _value_ptr == nullptr and not null_is_trivial_value_t::value and not connector_null_result_is_trivial_value_t::value; if (connector_assert_result_validity_t::value) { assert(_is_valid); @@ -208,8 +208,8 @@ namespace sqlpp }; }; - template - inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t& e) + template + inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t& e) { return os << e.value(); } diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 2e08abd4..dbfa69c3 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -137,6 +137,7 @@ namespace sqlpp SQLPP_VALUE_TRAIT_GENERATOR(must_not_update); SQLPP_VALUE_TRAIT_GENERATOR(require_insert); SQLPP_VALUE_TRAIT_GENERATOR(trivial_value_is_null); + SQLPP_VALUE_TRAIT_GENERATOR(null_is_trivial_value); SQLPP_IS_VALUE_TRAIT_GENERATOR(noop); SQLPP_IS_VALUE_TRAIT_GENERATOR(missing);