mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-05 12:40:40 -06:00
Transport null_is_trivial_value and can_be_null to result fields
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user