0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Added testability and tests for can_be_null and null_is_trivial in result entries

This commit is contained in:
rbock 2014-07-27 19:40:31 +02:00
parent 12f723d021
commit 6d851f17ff
9 changed files with 90 additions and 21 deletions

View File

@ -102,21 +102,38 @@ namespace sqlpp
template<typename Field, typename Enable = void>
struct field_methods_t
{
static constexpr bool _null_is_trivial = true;
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
};
template<typename Db, typename FieldSpec>
struct field_methods_t<
_result_field_t<Db, FieldSpec>,
typename std::enable_if<connector_enforce_result_validity_t<Db>::value
typename std::enable_if<connector_enforce_null_result_treatment_t<Db>::value
and column_spec_can_be_null_t<FieldSpec>::value
and not null_is_trivial_value_t<FieldSpec>::value>::type>
{
static constexpr bool _null_is_trivial = false;
};
template<typename Db, typename FieldSpec>
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
{
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
using _traits = make_traits<integral,
typename std::conditional<_field_methods_t::_null_is_trivial, ::sqlpp::tag::null_is_trivial_value, void>::type>;
struct _recursive_traits
{
using _parameters = std::tuple<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
};
_result_field_t():
_is_valid(false),
_is_null(true),
@ -149,7 +166,7 @@ namespace sqlpp
if (_is_null)
{
if (connector_enforce_result_validity_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
if (connector_enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
{
throw exception("accessing value of NULL field");
}

View File

@ -101,22 +101,37 @@ namespace sqlpp
template<typename Field, typename Enable = void>
struct field_methods_t
{
static constexpr bool _null_is_trivial = true;
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
};
template<typename Db, typename FieldSpec>
struct field_methods_t<
_result_field_t<Db, FieldSpec>,
typename std::enable_if<connector_enforce_result_validity_t<Db>::value
typename std::enable_if<connector_enforce_null_result_treatment_t<Db>::value
and column_spec_can_be_null_t<FieldSpec>::value
and not null_is_trivial_value_t<FieldSpec>::value>::type>
{
static constexpr bool _null_is_trivial = false;
};
template<typename Db, typename FieldSpec>
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
{
using _value_type = integral;
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
using _traits = make_traits<integral,
typename std::conditional<_field_methods_t::_null_is_trivial, ::sqlpp::tag::null_is_trivial_value, void>::type>;
struct _recursive_traits
{
using _parameters = std::tuple<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
};
_result_field_t():
_is_valid(false),
@ -150,7 +165,7 @@ namespace sqlpp
if (_is_null)
{
if (connector_enforce_result_validity_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
if (connector_enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
{
throw exception("accessing value of NULL field");
}

View File

@ -103,22 +103,37 @@ namespace sqlpp
template<typename Field, typename Enable = void>
struct field_methods_t
{
static constexpr bool _null_is_trivial = true;
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
};
template<typename Db, typename FieldSpec>
struct field_methods_t<
_result_field_t<Db, FieldSpec>,
typename std::enable_if<connector_enforce_result_validity_t<Db>::value
typename std::enable_if<connector_enforce_null_result_treatment_t<Db>::value
and column_spec_can_be_null_t<FieldSpec>::value
and not null_is_trivial_value_t<FieldSpec>::value>::type>
{
static constexpr bool _null_is_trivial = false;
};
template<typename Db, typename FieldSpec>
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
{
using _value_type = integral;
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
using _traits = make_traits<integral,
typename std::conditional<_field_methods_t::_null_is_trivial, ::sqlpp::tag::null_is_trivial_value, void>::type>;
struct _recursive_traits
{
using _parameters = std::tuple<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
};
_result_field_t():
_is_valid(false),
@ -152,7 +167,7 @@ namespace sqlpp
if (_is_null)
{
if (connector_enforce_result_validity_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
if (connector_enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
{
throw exception("accessing value of NULL field");
}

View File

@ -101,21 +101,38 @@ namespace sqlpp
template<typename Field, typename Enable = void>
struct field_methods_t
{
static constexpr bool _null_is_trivial = true;
operator _cpp_value_type() const { return static_cast<const Field&>(*this).value(); }
};
template<typename Db, typename FieldSpec>
struct field_methods_t<
_result_field_t<Db, FieldSpec>,
typename std::enable_if<connector_enforce_result_validity_t<Db>::value
typename std::enable_if<connector_enforce_null_result_treatment_t<Db>::value
and column_spec_can_be_null_t<FieldSpec>::value
and not null_is_trivial_value_t<FieldSpec>::value>::type>
{
static constexpr bool _null_is_trivial = false;
};
template<typename Db, typename FieldSpec>
struct _result_field_t: public field_methods_t<_result_field_t<Db, FieldSpec>>
{
using _field_methods_t = field_methods_t<_result_field_t<Db, FieldSpec>>;
using _traits = make_traits<integral,
typename std::conditional<_field_methods_t::_null_is_trivial, ::sqlpp::tag::null_is_trivial_value, void>::type>;
struct _recursive_traits
{
using _parameters = std::tuple<>;
using _provided_tables = detail::type_set<>;
using _provided_outer_tables = detail::type_set<>;
using _required_tables = detail::type_set<>;
using _extra_tables = detail::type_set<>;
using _can_be_null = column_spec_can_be_null_t<FieldSpec>;
};
_result_field_t():
_is_valid(false),
_value_ptr(nullptr),
@ -151,7 +168,7 @@ namespace sqlpp
if (not _value_ptr)
{
if (connector_enforce_result_validity_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
if (connector_enforce_null_result_treatment_t<Db>::value and not null_is_trivial_value_t<FieldSpec>::value)
{
throw exception("accessing value of NULL field");
}

View File

@ -174,7 +174,7 @@ namespace sqlpp
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
SQLPP_CONNECTOR_TRAIT_GENERATOR(enforce_result_validity);
SQLPP_CONNECTOR_TRAIT_GENERATOR(enforce_null_result_treatment);
template<typename Database>
using is_database = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;

View File

@ -15,6 +15,7 @@ build_and_run(SelectTypeTest)
build_and_run(FunctionTest)
build_and_run(PreparedTest)
build_and_run(Minimalistic)
build_and_run(ResultTest)
# if you want to use the generator, you can do something like this:
#find_package(PythonInterp REQUIRED)

View File

@ -36,7 +36,6 @@
MockDb db = {};
MockDb::_serializer_context_t printer;
SQLPP_ALIAS_PROVIDER(kaesekuchen);
int main()
{
@ -125,6 +124,10 @@ int main()
// join
serialize(t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta), printer).str();
{
auto inner = t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta);
serialize(select(t.alpha).from(inner), printer).str();
}
// multi_column
serialize(multi_column(t.alpha, (t.beta + "cake").as(t.gamma)).as(t.alpha), printer).str();

View File

@ -30,8 +30,14 @@
#include <sqlpp11/serializer_context.h>
#include <sqlpp11/connection.h>
struct MockDb: public sqlpp::connection
template<bool enforceNullResultTreatment>
struct MockDbT: public sqlpp::connection
{
struct _tags
{
using _enforce_null_result_treatment = std::integral_constant<bool, enforceNullResultTreatment>;
};
struct _serializer_context_t
{
std::ostringstream _os;
@ -156,5 +162,8 @@ struct MockDb: public sqlpp::connection
};
using MockDb = MockDbT<false>;
using EnforceDb = MockDbT<true>;
#endif

View File

@ -36,14 +36,6 @@
MockDb db = {};
MockDb::_serializer_context_t printer;
namespace alias
{
SQLPP_ALIAS_PROVIDER(a);
SQLPP_ALIAS_PROVIDER(b);
SQLPP_ALIAS_PROVIDER(left);
SQLPP_ALIAS_PROVIDER(right);
}
int main()
{
test::TabFoo f;