From b4baf38fab77c6e296f462dcb47cf07eb545106a Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Thu, 26 Dec 2013 19:05:05 +0100 Subject: [PATCH] Parameters of prepared statements can be null now --- include/sqlpp11/boolean.h | 58 +++++++++++++++++++++++++++----- include/sqlpp11/floating_point.h | 54 +++++++++++++++++++++++++++++ include/sqlpp11/integral.h | 54 +++++++++++++++++++++++++++++ include/sqlpp11/parameter.h | 14 ++++---- include/sqlpp11/parameter_list.h | 2 +- include/sqlpp11/text.h | 54 +++++++++++++++++++++++++++++ tests/PreparedTest.cpp | 12 +++---- 7 files changed, 227 insertions(+), 21 deletions(-) diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index 7959acc2..937a4682 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -50,12 +50,6 @@ namespace sqlpp static constexpr const char* _name = "AND"; }; - struct not_ - { - using _value_type = boolean; - static constexpr const char* _name = "NOT"; - }; - // boolean value type struct boolean { @@ -65,10 +59,58 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = bool; - struct plus_ + template + struct _parameter_t { using _value_type = boolean; - static constexpr const char* _name = "+"; + + _parameter_t(): + _value(false), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t(const _cpp_value_type& value): + _value(value), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t& operator=(const _cpp_value_type& value) + { + _value = value; + _is_null = (TrivialValueIsNull and _is_trivial()); + return *this; + } + + _parameter_t& operator=(const std::nullptr_t&) + { + _value = false; + _is_null = true; + return *this; + } + + template + void serialize(std::ostream& os, Db& db) const + { + os << value(); + } + + bool _is_trivial() const { return value() == false; } + + bool is_null() const + { + return _is_null; + } + + _cpp_value_type value() const + { + return _value; + } + + operator _cpp_value_type() const { return value(); } + + private: + _cpp_value_type _value; + bool _is_null; }; template diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index c8926c9b..24ae32e9 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -48,6 +48,60 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = double; + template + struct _parameter_t + { + using _value_type = floating_point; + + _parameter_t(): + _value(0), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t(const _cpp_value_type& value): + _value(value), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t& operator=(const _cpp_value_type& value) + { + _value = value; + _is_null = (TrivialValueIsNull and _is_trivial()); + return *this; + } + + _parameter_t& operator=(const std::nullptr_t&) + { + _value = 0; + _is_null = true; + return *this; + } + + template + void serialize(std::ostream& os, Db& db) const + { + os << value(); + } + + bool _is_trivial() const { return value() == 0; } + + bool is_null() const + { + return _is_null; + } + + _cpp_value_type value() const + { + return _value; + } + + operator _cpp_value_type() const { return value(); } + + private: + _cpp_value_type _value; + bool _is_null; + }; + template struct _result_entry_t { diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index 524dbb74..8582a8b2 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -48,6 +48,60 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = int64_t; + template + struct _parameter_t + { + using _value_type = integral; + + _parameter_t(): + _value(0), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t(const _cpp_value_type& value): + _value(value), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t& operator=(const _cpp_value_type& value) + { + _value = value; + _is_null = (TrivialValueIsNull and _is_trivial()); + return *this; + } + + _parameter_t& operator=(const std::nullptr_t&) + { + _value = 0; + _is_null = true; + return *this; + } + + template + void serialize(std::ostream& os, Db& db) const + { + os << value(); + } + + bool _is_trivial() const { return value() == 0; } + + bool is_null() const + { + return _is_null; + } + + _cpp_value_type value() const + { + return _value; + } + + operator _cpp_value_type() const { return value(); } + + private: + _cpp_value_type _value; + bool _is_null; + }; + template struct _result_entry_t { diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 3de5e6d9..054d5687 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -33,29 +33,31 @@ namespace sqlpp { - template + template struct parameter_t { - using _is_parameter = std::true_type; using _value_type = ValueType; + using _parameter_type = typename ValueType::template _parameter_t; + using _is_parameter = std::true_type; using _is_expression_t = std::true_type; template void serialize(std::ostream& os, Db& db) const { static_assert(Db::_supports_parameter, "parameter not supported by current database"); - os << " ? "; + os << " ? "; // FIXME: Need to support positional placeholders and also type indicators for postgres for instance } - using _member_t = typename NameType::_name_t::template _member_t; + using _member_t = typename NameType::_name_t::template _member_t<_parameter_type>; }; - template + template::type>::value> auto parameter(NamedExpr&& namedExpr) - -> parameter_t::type::_value_type, typename std::decay::type> + -> parameter_t::type::_value_type, typename std::decay::type, TrivialValueIsNull> { return {}; } + } #endif diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index 664a4274..4f21a557 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -74,7 +74,7 @@ namespace sqlpp ~parameter_list_t() = default; - using parameter_tuple_t = std::tuple; + using parameter_tuple_t = std::tuple; using size = std::tuple_size; parameter_tuple_t _parameter_tuple; }; diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 461b7c3e..59e3b803 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -48,6 +48,60 @@ namespace sqlpp using _is_expression = std::true_type; using _cpp_value_type = std::string; + template + struct _parameter_t + { + using _value_type = integral; + + _parameter_t(): + _value(""), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t(const _cpp_value_type& value): + _value(value), + _is_null(TrivialValueIsNull and _is_trivial()) + {} + + _parameter_t& operator=(const _cpp_value_type& value) + { + _value = value; + _is_null = (TrivialValueIsNull and _is_trivial()); + return *this; + } + + _parameter_t& operator=(const std::nullptr_t&) + { + _value = ""; + _is_null = true; + return *this; + } + + template + void serialize(std::ostream& os, Db& db) const + { + os << value(); + } + + bool _is_trivial() const { return value() == ""; } + + bool is_null() const + { + return _is_null; + } + + _cpp_value_type value() const + { + return _value; + } + + operator _cpp_value_type() const { return value(); } + + private: + _cpp_value_type _value; + bool _is_null; + }; + template struct _result_entry_t { diff --git a/tests/PreparedTest.cpp b/tests/PreparedTest.cpp index c83db03b..01936c1a 100644 --- a/tests/PreparedTest.cpp +++ b/tests/PreparedTest.cpp @@ -80,9 +80,9 @@ int main() using Exp = decltype(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma)); using T = sqlpp::make_parameter_list_t::type; T npl; - static_assert(std::is_same::value, "type requirement"); - static_assert(std::is_same::value, "type requirement"); - static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same, decltype(npl.alpha)>::value, "type requirement"); + static_assert(std::is_same, decltype(npl.beta)>::value, "type requirement"); + static_assert(std::is_same, decltype(npl.gamma)>::value, "type requirement"); static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement"); static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement"); @@ -96,9 +96,9 @@ int main() using T = sqlpp::make_parameter_list_t::type; T npl; - static_assert(std::is_same::value, "type requirement"); - static_assert(std::is_same::value, "type requirement"); - static_assert(std::is_same::value, "type requirement"); + static_assert(std::is_same, decltype(npl.alpha)>::value, "type requirement"); + static_assert(std::is_same, decltype(npl.beta)>::value, "type requirement"); + static_assert(std::is_same, decltype(npl.gamma)>::value, "type requirement"); static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement"); static_assert(std::is_same(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement");