From 1824f9cde0797414ec5288c440cec6d6f504fbc6 Mon Sep 17 00:00:00 2001 From: rbock Date: Thu, 13 Mar 2014 08:52:22 +0100 Subject: [PATCH] Changed NULL handling in results. If the column or the connector indicates that NULL corresponds to a trivial value, then the trivial value is returned. Otherwise, an assert fails or an exception is thrown, depending on the preferences of the connector. --- include/sqlpp11/boolean.h | 22 ++++++++++++++++++---- include/sqlpp11/floating_point.h | 22 ++++++++++++++++++---- include/sqlpp11/integral.h | 20 +++++++++++++++++--- include/sqlpp11/text.h | 24 +++++++++++++++++++----- include/sqlpp11/type_traits.h | 3 ++- 5 files changed, 74 insertions(+), 17 deletions(-) diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index dfffaca1..117d75b9 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -28,6 +28,7 @@ #define SQLPP_BOOLEAN_H #include +#include #include #include #include @@ -98,7 +99,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { _result_entry_t(): @@ -134,15 +135,28 @@ namespace sqlpp bool is_null() const { - if (not _is_valid) + if (connector_assert_result_validity_t::value) + assert(_is_valid); + else if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _is_null; } _cpp_value_type value() const { - if (not _is_valid) - throw exception("accessing value in non-existing row"); + const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + if (connector_assert_result_validity_t::value) + { + assert(_is_valid); + assert(not null_value); + } + else + { + if (not _is_valid) + throw exception("accessing value in non-existing row"); + if (null_value) + throw exception("accessing value of NULL field"); + } return _value; } diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index 026dcfe9..4f8a47e8 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -28,6 +28,7 @@ #define SQLPP_FLOATING_POINT_H #include +#include #include #include #include @@ -98,7 +99,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { using _value_type = integral; @@ -136,15 +137,28 @@ namespace sqlpp bool is_null() const { - if (not _is_valid) + if (connector_assert_result_validity_t::value) + assert(_is_valid); + else if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _is_null; } _cpp_value_type value() const { - if (not _is_valid) - throw exception("accessing value in non-existing row"); + const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + if (connector_assert_result_validity_t::value) + { + assert(_is_valid); + assert(not null_value); + } + else + { + if (not _is_valid) + throw exception("accessing value in non-existing row"); + if (null_value) + throw exception("accessing value of NULL field"); + } return _value; } diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index 55cc77cb..a143e5de 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -28,6 +28,7 @@ #define SQLPP_INTEGRAL_H #include +#include #include #include #include @@ -136,15 +137,28 @@ namespace sqlpp bool is_null() const { - if (not _is_valid) + if (connector_assert_result_validity_t::value) + assert(_is_valid); + else if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _is_null; } _cpp_value_type value() const { - if (not _is_valid) - throw exception("accessing value in non-existing row"); + const bool null_value = _is_null and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + if (connector_assert_result_validity_t::value) + { + assert(_is_valid); + assert(not null_value); + } + else + { + if (not _is_valid) + throw exception("accessing value in non-existing row"); + if (null_value) + throw exception("accessing value of NULL field"); + } return _value; } diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index b4f2c386..b16f4ea8 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -27,6 +27,7 @@ #ifndef SQLPP_TEXT_H #define SQLPP_TEXT_H +#include #include #include #include @@ -97,7 +98,7 @@ namespace sqlpp bool _is_null; }; - template + template struct _result_entry_t { _result_entry_t(): @@ -136,16 +137,29 @@ namespace sqlpp bool is_null() const { - if (not _is_valid) + if (connector_assert_result_validity_t::value) + assert(_is_valid); + else if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _value_ptr == nullptr; } _cpp_value_type value() const { - if (not _is_valid) - throw exception("accessing value in non-existing row"); - if (_value_ptr) + const bool null_value = _value_ptr == nullptr and not NullIsTrivial and not connector_null_result_is_trivial_value_t::value; + if (connector_assert_result_validity_t::value) + { + assert(_is_valid); + assert(not null_value); + } + else + { + if (not _is_valid) + throw exception("accessing value in non-existing row"); + if (null_value) + throw exception("accessing value of NULL field"); + } + if (_value_ptr) return std::string(_value_ptr, _value_ptr + _len); else return ""; diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index b7ce94f0..8ee87cfa 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -124,7 +124,8 @@ namespace sqlpp SQLPP_TYPE_TRAIT_GENERATOR(requires_braces); SQLPP_TYPE_TRAIT_GENERATOR(is_parameter); - SQLPP_CONNECTOR_TRAIT_GENERATOR(has_empty_list_insert); + SQLPP_CONNECTOR_TRAIT_GENERATOR(null_result_is_trivial_value); + SQLPP_CONNECTOR_TRAIT_GENERATOR(assert_result_validity); template class IsTag> using copy_type_trait = typename std::conditional::value, std::true_type, std::false_type>::type;