Transport null_is_trivial_value and can_be_null to result fields

This commit is contained in:
rbock
2014-07-24 23:02:08 +02:00
parent 6f056ced8a
commit e21fdb4829
9 changed files with 76 additions and 51 deletions

View File

@@ -96,7 +96,7 @@ namespace sqlpp
bool _is_null;
};
template<typename Db, bool NullIsTrivial = false>
template<typename Db, typename FieldSpec>
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<Db>::value;
const bool null_value = _is_null and not null_is_trivial_value_t<FieldSpec>::value and not connector_null_result_is_trivial_value_t<Db>::value;
if (connector_assert_result_validity_t<Db>::value)
{
assert(_is_valid);
@@ -200,8 +200,8 @@ namespace sqlpp
};
};
template<typename Db, bool TrivialIsNull>
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<Db, TrivialIsNull>& e)
template<typename Db, typename FieldSpec>
inline std::ostream& operator<<(std::ostream& os, const boolean::_result_entry_t<Db, FieldSpec>& e)
{
return os << e.value();
}

View File

@@ -31,14 +31,16 @@
namespace sqlpp
{
template<typename NameType, typename ValueType, bool TrivialValueIsNull>
template<typename NameType, typename ValueType, bool CanBeNull, bool NullIsTrivialValue>
struct field_t
{
using _traits = make_traits<ValueType, tag::noop>;
using _traits = make_traits<ValueType, tag::noop,
typename std::conditional<CanBeNull, tag::can_be_null, void>::type,
typename std::conditional<NullIsTrivialValue, tag::null_is_trivial_value, void>::type
>;
using _recursive_traits = make_recursive_traits<>;
using _name_t = NameType;
static constexpr bool _trivial_value_is_null = TrivialValueIsNull;
};
template<typename AliasProvider, typename FieldTuple>
@@ -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<typename NamedExpr>
template<typename Select, typename NamedExpr>
struct make_field_t_impl
{
static constexpr bool _can_be_null = can_be_null_t<NamedExpr>::value;
static constexpr bool _depends_on_outer_table = detail::make_intersect_set_t<required_tables_of<NamedExpr>, typename Select::_used_outer_tables>::size::value > 0;
using type = field_t<typename NamedExpr::_name_t,
value_type_of<NamedExpr>,
trivial_value_is_null_t<NamedExpr>::value>;
detail::any_t<_can_be_null, _depends_on_outer_table>::value,
null_is_trivial_value<NamedExpr>::value>;
};
template<typename AliasProvider, typename... NamedExpr>
struct make_field_t_impl<multi_column_alias_t<AliasProvider, NamedExpr...>>
template<typename Select, typename AliasProvider, typename... NamedExprs>
struct make_field_t_impl<Select, multi_column_alias_t<AliasProvider, NamedExprs...>>
{
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<NamedExpr>::type...>>;
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<Select, NamedExprs>::type...>>;
};
}
template<typename NamedExpr>
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
template<typename Select, typename NamedExpr>
using make_field_t = typename detail::make_field_t_impl<Select, NamedExpr>::type;
}

View File

@@ -95,7 +95,7 @@ namespace sqlpp
bool _is_null;
};
template<typename Db, bool NullIsTrivial = false>
template<typename Db, typename FieldSpec>
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<Db>::value;
const bool null_value = _is_null and not null_is_trivial_value_t<FieldSpec>::value and not connector_null_result_is_trivial_value_t<Db>::value;
if (connector_assert_result_validity_t<Db>::value)
{
assert(_is_valid);
@@ -257,8 +257,8 @@ namespace sqlpp
};
};
template<typename Db, bool TrivialIsNull>
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<Db, TrivialIsNull>& e)
template<typename Db, typename FieldSpec>
inline std::ostream& operator<<(std::ostream& os, const floating_point::_result_entry_t<Db, FieldSpec>& e)
{
return os << e.value();
}

View File

@@ -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<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>,
public alias_operators<verbatim_t<ValueType>>
{
using _traits = make_traits<ValueType, ::sqlpp::tag::expression>;
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;

View File

@@ -97,7 +97,7 @@ namespace sqlpp
bool _is_null;
};
template<typename Db, bool NullIsTrivial = false>
template<typename Db, typename FieldSpec>
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<Db>::value;
const bool null_value = _is_null and not null_is_trivial_value_t<FieldSpec>::value and not connector_null_result_is_trivial_value_t<Db>::value;
if (connector_assert_result_validity_t<Db>::value)
{
assert(_is_valid);
@@ -270,8 +270,8 @@ namespace sqlpp
};
};
template<typename Db, bool NullIsTrivial>
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<Db, NullIsTrivial>& e)
template<typename Db, typename FieldSpec>
inline std::ostream& operator<<(std::ostream& os, const integral::_result_entry_t<Db, FieldSpec>& e)
{
return os << e.value();
}

View File

@@ -36,14 +36,14 @@ namespace sqlpp
{
namespace detail
{
template<typename Db, typename IndexSequence, typename... NamedExprs>
template<typename Db, typename IndexSequence, typename... FieldSpecs>
struct result_row_impl;
template<typename Db, std::size_t index, typename NamedExpr>
template<typename Db, std::size_t index, typename FieldSpec>
struct result_field:
public NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>
public FieldSpec::_name_t::template _member_t<typename value_type_of<FieldSpec>::template _result_entry_t<Db, FieldSpec>>
{
using _field = typename NamedExpr::_name_t::template _member_t<typename value_type_of<NamedExpr>::template _result_entry_t<Db, NamedExpr::_trivial_value_is_null>>;
using _field = typename FieldSpec::_name_t::template _member_t<typename value_type_of<FieldSpec>::template _result_entry_t<Db, FieldSpec>>;
result_field() = default;
@@ -64,11 +64,11 @@ namespace sqlpp
}
};
template<std::size_t index, typename AliasProvider, typename Db, typename... NamedExprs>
struct result_field<Db, index, multi_field_t<AliasProvider, std::tuple<NamedExprs...>>>:
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>
template<std::size_t index, typename AliasProvider, typename Db, typename... FieldSpecs>
struct result_field<Db, index, multi_field_t<AliasProvider, std::tuple<FieldSpecs...>>>:
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, FieldSpecs...>, FieldSpecs...>>
{
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>;
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, FieldSpecs...>, FieldSpecs...>>;
result_field() = default;
@@ -89,9 +89,9 @@ namespace sqlpp
}
};
template<typename Db, std::size_t LastIndex, std::size_t... Is, typename... NamedExprs>
struct result_row_impl<Db, detail::column_index_sequence<LastIndex, Is...>, NamedExprs...>:
public result_field<Db, Is, NamedExprs>...
template<typename Db, std::size_t LastIndex, std::size_t... Is, typename... FieldSpecs>
struct result_row_impl<Db, detail::column_index_sequence<LastIndex, Is...>, FieldSpecs...>:
public result_field<Db, Is, FieldSpecs>...
{
static constexpr std::size_t _last_index = LastIndex;
@@ -100,29 +100,29 @@ namespace sqlpp
void _validate()
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::_validate(), 0)...};
(void) swallow{(result_field<Db, Is, FieldSpecs>::_validate(), 0)...};
}
void _invalidate()
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::_invalidate(), 0)...};
(void) swallow{(result_field<Db, Is, FieldSpecs>::_invalidate(), 0)...};
}
template<typename Target>
void _bind(Target& target)
{
using swallow = int[];
(void) swallow{(result_field<Db, Is, NamedExprs>::_bind(target), 0)...};
(void) swallow{(result_field<Db, Is, FieldSpecs>::_bind(target), 0)...};
}
};
}
template<typename Db, typename... NamedExprs>
struct result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>
template<typename Db, typename... FieldSpecs>
struct result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>
{
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>;
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>;
bool _is_valid;
static constexpr size_t _last_static_index = _impl::_last_index;
@@ -178,11 +178,18 @@ namespace sqlpp
}
};
template<typename Db, typename... NamedExprs>
struct dynamic_result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>
template<typename Db, typename... FieldSpecs>
struct dynamic_result_row_t: public detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>
{
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, NamedExprs...>, NamedExprs...>;
using _field_type = detail::text::_result_entry_t<Db, false>;
using _impl = detail::result_row_impl<Db, detail::make_column_index_sequence<0, FieldSpecs...>, FieldSpecs...>;
struct _field_spec_t
{
using _traits = make_traits<detail::text, tag::noop, tag::can_be_null, tag::null_is_trivial_value>;
using _recursive_traits = make_recursive_traits<>;
struct _name_t {};
};
using _field_type = detail::text::_result_entry_t<Db, _field_spec_t>;
static constexpr size_t _last_static_index = _impl::_last_index;
bool _is_valid;

View File

@@ -245,10 +245,19 @@ namespace sqlpp
return static_cast<const _statement_t&>(*this);
}
template<typename Db, typename Column>
struct _deferred_field_t
{
using type = make_field_t<_statement_t, Column>;
};
template<typename Db, typename Column>
using _field_t = typename _deferred_field_t<Db, Column>::type;
template<typename Db>
using _result_row_t = typename std::conditional<_is_dynamic::value,
dynamic_result_row_t<Db, make_field_t<Columns>...>,
result_row_t<Db, make_field_t<Columns>...>>::type;
dynamic_result_row_t<Db, _field_t<Db, Columns>...>,
result_row_t<Db, _field_t<Db, Columns>...>>::type;
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;

View File

@@ -95,7 +95,7 @@ namespace sqlpp
bool _is_null;
};
template<typename Db, bool NullIsTrivial = false>
template<typename Db, typename FieldSpec>
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<Db>::value;
const bool null_value = _value_ptr == nullptr and not null_is_trivial_value_t<FieldSpec>::value and not connector_null_result_is_trivial_value_t<Db>::value;
if (connector_assert_result_validity_t<Db>::value)
{
assert(_is_valid);
@@ -208,8 +208,8 @@ namespace sqlpp
};
};
template<typename Db, bool TrivialIsNull>
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<Db, TrivialIsNull>& e)
template<typename Db, typename FieldSpec>
inline std::ostream& operator<<(std::ostream& os, const text::_result_entry_t<Db, FieldSpec>& e)
{
return os << e.value();
}

View File

@@ -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);