From e5f055ac19ad85833aafa5c4eb89d2ccb2363a54 Mon Sep 17 00:00:00 2001 From: rbock Date: Fri, 25 Jul 2014 01:01:42 +0200 Subject: [PATCH] Using column's can_be_null and connector's enforce_validity --- include/sqlpp11/boolean.h | 49 +++++++++++++++++--------- include/sqlpp11/field.h | 3 +- include/sqlpp11/floating_point.h | 49 +++++++++++++++++--------- include/sqlpp11/integral.h | 49 +++++++++++++++++--------- include/sqlpp11/text.h | 60 +++++++++++++++++++------------- include/sqlpp11/type_traits.h | 3 +- 6 files changed, 134 insertions(+), 79 deletions(-) diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index fcd61093..c1268564 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -28,7 +28,6 @@ #define SQLPP_BOOLEAN_H #include -#include #include #include #include @@ -97,7 +96,26 @@ namespace sqlpp }; template - struct _result_entry_t + struct _result_entry_t; + + // I am SO waiting for concepts lite! + template + struct field_methods_t + { + operator _cpp_value_type() const { return static_cast(*this).value(); } + }; + + template + struct field_methods_t< + _result_entry_t, + typename std::enable_if::value + and column_spec_can_be_null_t::value + and not null_is_trivial_value_t::value>::type> + { + }; + + template + struct _result_entry_t: public field_methods_t<_result_entry_t> { _result_entry_t(): _is_valid(false), @@ -119,33 +137,30 @@ namespace sqlpp bool is_null() const { - if (connector_assert_result_validity_t::value) - assert(_is_valid); - else if (not _is_valid) + if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _is_null; } _cpp_value_type value() const { - 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) + if (not _is_valid) + throw exception("accessing value in non-existing row"); + + if (_is_null) { - assert(_is_valid); - assert(not null_value); - } - else - { - if (not _is_valid) - throw exception("accessing value in non-existing row"); - if (null_value) + if (connector_enforce_result_validity_t::value and not null_is_trivial_value_t::value) + { throw exception("accessing value of NULL field"); + } + else + { + return false; + } } return _value; } - operator _cpp_value_type() const { return value(); } - template void _bind(Target& target, size_t i) { diff --git a/include/sqlpp11/field.h b/include/sqlpp11/field.h index ad8d9421..958974bd 100644 --- a/include/sqlpp11/field.h +++ b/include/sqlpp11/field.h @@ -50,7 +50,6 @@ namespace sqlpp namespace detail { -#warning: Need to transport the "can be null" information via field_t to result_entry structs template struct make_field_t_impl { @@ -60,7 +59,7 @@ namespace sqlpp using type = field_t, detail::any_t<_can_be_null, _depends_on_outer_table>::value, - null_is_trivial_value::value>; + null_is_trivial_value_t::value>; }; template diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index 95e854ca..53d520ef 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -28,7 +28,6 @@ #define SQLPP_FLOATING_POINT_H #include -#include #include #include #include @@ -96,7 +95,26 @@ namespace sqlpp }; template - struct _result_entry_t + struct _result_entry_t; + + // I am SO waiting for concepts lite! + template + struct field_methods_t + { + operator _cpp_value_type() const { return static_cast(*this).value(); } + }; + + template + struct field_methods_t< + _result_entry_t, + typename std::enable_if::value + and column_spec_can_be_null_t::value + and not null_is_trivial_value_t::value>::type> + { + }; + + template + struct _result_entry_t: public field_methods_t<_result_entry_t> { using _value_type = integral; @@ -120,33 +138,30 @@ namespace sqlpp bool is_null() const { - if (connector_assert_result_validity_t::value) - assert(_is_valid); - else if (not _is_valid) + if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _is_null; } _cpp_value_type value() const { - 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) + if (not _is_valid) + throw exception("accessing value in non-existing row"); + + if (_is_null) { - assert(_is_valid); - assert(not null_value); - } - else - { - if (not _is_valid) - throw exception("accessing value in non-existing row"); - if (null_value) + if (connector_enforce_result_validity_t::value and not null_is_trivial_value_t::value) + { throw exception("accessing value of NULL field"); + } + else + { + return 0; + } } return _value; } - operator _cpp_value_type() const { return value(); } - template void _bind(Target& target, size_t i) { diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index e458ab72..9714c443 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -28,7 +28,6 @@ #define SQLPP_INTEGRAL_H #include -#include #include #include #include @@ -98,7 +97,26 @@ namespace sqlpp }; template - struct _result_entry_t + struct _result_entry_t; + + // I am SO waiting for concepts lite! + template + struct field_methods_t + { + operator _cpp_value_type() const { return static_cast(*this).value(); } + }; + + template + struct field_methods_t< + _result_entry_t, + typename std::enable_if::value + and column_spec_can_be_null_t::value + and not null_is_trivial_value_t::value>::type> + { + }; + + template + struct _result_entry_t: public field_methods_t<_result_entry_t> { using _value_type = integral; @@ -122,33 +140,30 @@ namespace sqlpp bool is_null() const { - if (connector_assert_result_validity_t::value) - assert(_is_valid); - else if (not _is_valid) + if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _is_null; } _cpp_value_type value() const { - 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) + if (not _is_valid) + throw exception("accessing value in non-existing row"); + + if (_is_null) { - assert(_is_valid); - assert(not null_value); - } - else - { - if (not _is_valid) - throw exception("accessing value in non-existing row"); - if (null_value) + if (connector_enforce_result_validity_t::value and not null_is_trivial_value_t::value) + { throw exception("accessing value of NULL field"); + } + else + { + return 0; + } } return _value; } - operator _cpp_value_type() const { return value(); } - template void _bind(Target& target, size_t i) { diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 85ef236f..29749438 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -27,7 +27,6 @@ #ifndef SQLPP_TEXT_H #define SQLPP_TEXT_H -#include #include #include #include @@ -96,7 +95,26 @@ namespace sqlpp }; template - struct _result_entry_t + struct _result_entry_t; + + // I am SO waiting for concepts lite! + template + struct field_methods_t + { + operator _cpp_value_type() const { return static_cast(*this).value(); } + }; + + template + struct field_methods_t< + _result_entry_t, + typename std::enable_if::value + and column_spec_can_be_null_t::value + and not null_is_trivial_value_t::value>::type> + { + }; + + template + struct _result_entry_t: public field_methods_t<_result_entry_t> { _result_entry_t(): _is_valid(false), @@ -121,35 +139,29 @@ namespace sqlpp bool is_null() const { - if (connector_assert_result_validity_t::value) - assert(_is_valid); - else if (not _is_valid) + if (not _is_valid) throw exception("accessing is_null in non-existing row"); return _value_ptr == nullptr; } _cpp_value_type value() const { - 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); - 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 ""; - } + if (not _is_valid) + throw exception("accessing value in non-existing row"); - operator _cpp_value_type() const { return value(); } + if (not _value_ptr) + { + if (connector_enforce_result_validity_t::value and not null_is_trivial_value_t::value) + { + throw exception("accessing value of NULL field"); + } + else + { + return ""; + } + } + return std::string(_value_ptr, _value_ptr + _len); + } template void _bind(Target& target, size_t i) diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index dbfa69c3..ddf3bf58 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -174,8 +174,7 @@ namespace sqlpp SQLPP_TYPE_TRAIT_GENERATOR(requires_braces); - SQLPP_CONNECTOR_TRAIT_GENERATOR(null_result_is_trivial_value); - SQLPP_CONNECTOR_TRAIT_GENERATOR(assert_result_validity); + SQLPP_CONNECTOR_TRAIT_GENERATOR(enforce_result_validity); template using is_database = typename std::conditional::value, std::false_type, std::true_type>::type;