diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index fa86f3c6..bb9ce319 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -63,26 +63,24 @@ namespace sqlpp using _value_type = boolean; _parameter_t(const std::true_type&): - _trivial_value_is_null(true), _value(false), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t(const std::false_type&): - _trivial_value_is_null(false), _value(false), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (_trivial_value_is_null and _is_trivial()); + _is_null = (false); return *this; } @@ -99,8 +97,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == false; } - bool is_null() const { return _is_null; @@ -120,7 +116,6 @@ namespace sqlpp } private: - bool _trivial_value_is_null; signed char _value; bool _is_null; }; @@ -164,8 +159,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == false; } - bool is_null() const { if (not _is_valid) diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index 033108bb..16896ecc 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -75,7 +75,7 @@ namespace sqlpp -> typename std::enable_if::type>::value, assignment_t::type>>::type { - return { *this, std::forward(t) }; + return { *this, {std::forward(t)} }; } }; diff --git a/include/sqlpp11/detail/basic_operators.h b/include/sqlpp11/detail/basic_operators.h index 7e74fe29..46ad7e0f 100644 --- a/include/sqlpp11/detail/basic_operators.h +++ b/include/sqlpp11/detail/basic_operators.h @@ -155,8 +155,6 @@ namespace sqlpp static_assert(not is_multi_expression_t::value, "multi-expression cannot have a name"); return { *static_cast(this) }; } - - constexpr bool _is_trivial() const { return false; } }; } diff --git a/include/sqlpp11/expression.h b/include/sqlpp11/expression.h index 9c59dc70..a896bcd4 100644 --- a/include/sqlpp11/expression.h +++ b/include/sqlpp11/expression.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -42,10 +43,22 @@ namespace sqlpp { using _is_assignment = std::true_type; using column_type = Lhs; - using value_type = Rhs; + using value_type = tvin_wrap_t; + // FIXME: Need parameter_tuple back + + assignment_t(Lhs lhs, Rhs rhs): + _lhs(lhs), + _rhs(rhs) + {} + + assignment_t(const assignment_t&) = default; + assignment_t(assignment_t&&) = default; + assignment_t& operator=(const assignment_t&) = default; + assignment_t& operator=(assignment_t&&) = default; + ~assignment_t() = default; Lhs _lhs; - Rhs _rhs; + tvin_wrap_t _rhs; }; template @@ -56,7 +69,7 @@ namespace sqlpp static Context& _(const T& t, Context& context) { interpret(t._lhs, context); - if (trivial_value_is_null_t::value and t._rhs._is_trivial()) + if (t._rhs._is_trivial()) { context << "=NULL"; } @@ -75,9 +88,9 @@ namespace sqlpp { using _value_type = detail::boolean; - equal_t(Lhs lhs, Rhs rhs): - _lhs(lhs), - _rhs(rhs) + equal_t(Lhs lhs, Rhs rhs): + _lhs(lhs), + _rhs(rhs) {} equal_t(const equal_t&) = default; @@ -87,7 +100,7 @@ namespace sqlpp ~equal_t() = default; Lhs _lhs; - Rhs _rhs; + tvin_wrap_t _rhs; }; template @@ -99,9 +112,9 @@ namespace sqlpp { context << "("; interpret(t._lhs, context); - if (trivial_value_is_null_t::value and t._rhs._is_trivial()) + if (t._rhs._is_trivial()) { - context << "IS NULL"; + context << " IS NULL"; } else { @@ -130,7 +143,7 @@ namespace sqlpp ~not_equal_t() = default; Lhs _lhs; - Rhs _rhs; + tvin_wrap_t _rhs; }; template @@ -142,9 +155,9 @@ namespace sqlpp { context << "("; interpret(t._lhs, context); - if (trivial_value_is_null_t::value and t._rhs._is_trivial()) + if (t._rhs._is_trivial()) { - context << "IS NOT NULL"; + context << " IS NOT NULL"; } else { @@ -182,16 +195,8 @@ namespace sqlpp static Context& _(const T& t, Context& context) { context << "("; - if (trivial_value_is_null_t::value and t._lhs._is_trivial()) - { - interpret(t._lhs, context); - context << "IS NULL"; - } - else - { - context << "NOT "; - interpret(t._lhs, context); - } + context << "NOT "; + interpret(t._lhs, context); context << ")"; return context; } diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index b5236ab3..7eae7ac0 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -52,27 +52,20 @@ namespace sqlpp { using _value_type = integral; - _parameter_t(const std::true_type&): - _trivial_value_is_null(true), + _parameter_t(): _value(0), - _is_null(_trivial_value_is_null and _is_trivial()) - {} - - _parameter_t(const std::false_type&): - _trivial_value_is_null(false), - _value(0), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (_trivial_value_is_null and _is_trivial()); + _is_null = false; return *this; } @@ -89,8 +82,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == 0; } - bool is_null() const { return _is_null; @@ -110,7 +101,6 @@ namespace sqlpp } private: - bool _trivial_value_is_null; _cpp_value_type _value; bool _is_null; }; @@ -156,8 +146,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == 0; } - bool is_null() const { if (not _is_valid) diff --git a/include/sqlpp11/having.h b/include/sqlpp11/having.h index 60d65b05..1ba4c6ba 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/having.h @@ -48,7 +48,6 @@ namespace sqlpp static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()"); using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; - static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of having expression, use where_parameter() instead of parameter() to turn off automatic conversion"); template void add(E&& expr) diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index ac2e6b82..17b49c19 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -52,26 +52,24 @@ namespace sqlpp using _value_type = integral; _parameter_t(const std::true_type&): - _trivial_value_is_null(true), _value(0), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t(const std::false_type&): - _trivial_value_is_null(false), _value(0), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} explicit _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (_trivial_value_is_null and _is_trivial()); + _is_null = false; return *this; } @@ -87,8 +85,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == 0; } - bool is_null() const { return _is_null; @@ -108,7 +104,6 @@ namespace sqlpp } private: - bool _trivial_value_is_null; _cpp_value_type _value; bool _is_null; }; @@ -154,8 +149,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == 0; } - bool is_null() const { if (not _is_valid) diff --git a/include/sqlpp11/limit.h b/include/sqlpp11/limit.h index a88b281e..741bbe30 100644 --- a/include/sqlpp11/limit.h +++ b/include/sqlpp11/limit.h @@ -50,7 +50,7 @@ namespace sqlpp static Context& _(const T& t, Context& context) { - context << "LIMIT " << t._limit; + context << " LIMIT " << t._limit; return context; } }; diff --git a/include/sqlpp11/offset.h b/include/sqlpp11/offset.h index 24b2be3c..9545a8fe 100644 --- a/include/sqlpp11/offset.h +++ b/include/sqlpp11/offset.h @@ -50,7 +50,7 @@ namespace sqlpp static Context& _(const T& t, Context& context) { - context << "OFFSET " << t._offset; + context << " OFFSET " << t._offset; return context; } }; diff --git a/include/sqlpp11/parameter.h b/include/sqlpp11/parameter.h index 07b49ae6..3f056bb8 100644 --- a/include/sqlpp11/parameter.h +++ b/include/sqlpp11/parameter.h @@ -33,16 +33,13 @@ namespace sqlpp { - template - struct parameter_t: public ValueType::template operators> + template + struct parameter_t: public ValueType::template operators> { using _value_type = ValueType; using _is_parameter = std::true_type; using _is_expression_t = std::true_type; using _instance_t = typename NameType::_name_t::template _member_t; - using _trivial_value_is_null_t = TrivialValueIsNull; - - static_assert(std::is_same<_trivial_value_is_null_t, std::true_type>::value or std::is_same<_trivial_value_is_null_t, std::false_type>::value, "Invalid template parameter TrivialValueIsNull"); parameter_t() {} @@ -52,17 +49,12 @@ namespace sqlpp parameter_t& operator=(const parameter_t&) = default; parameter_t& operator=(parameter_t&&) = default; ~parameter_t() = default; - - constexpr bool _is_trivial() const - { - return false; - } }; - template - struct interpreter_t> + template + struct interpreter_t> { - using T = parameter_t; + using T = parameter_t; static Context& _(const T& t, Context& context) { @@ -71,16 +63,9 @@ namespace sqlpp } }; - template::type>> - auto parameter(NamedExpr&& namedExpr) - -> parameter_t::type::_value_type, typename std::decay::type, TrivialValueIsNull> - { - return {}; - } - template - auto where_parameter(NamedExpr&& namedExpr) - -> parameter_t::type::_value_type, typename std::decay::type, std::false_type> + auto parameter(NamedExpr&& namedExpr) + -> parameter_t::type::_value_type, typename std::decay::type> { return {}; } diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index c2bf0b68..37b32f8e 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -62,10 +62,8 @@ namespace sqlpp { using _member_tuple_t = std::tuple; using size = std::integral_constant; - using _contains_trivial_value_is_null_t = detail::or_t; - parameter_list_t(): - Parameter::_instance_t({typename Parameter::_trivial_value_is_null_t()})... + parameter_list_t() {} template diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index af2677b1..35252a92 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -52,26 +52,24 @@ namespace sqlpp using _value_type = integral; _parameter_t(const std::true_type&): - _trivial_value_is_null(true), _value(""), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t(const std::false_type&): - _trivial_value_is_null(false), _value(""), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t(const _cpp_value_type& value): _value(value), - _is_null(_trivial_value_is_null and _is_trivial()) + _is_null(false) {} _parameter_t& operator=(const _cpp_value_type& value) { _value = value; - _is_null = (_trivial_value_is_null and _is_trivial()); + _is_null = false; return *this; } @@ -88,8 +86,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return value() == ""; } - bool is_null() const { return _is_null; @@ -109,7 +105,6 @@ namespace sqlpp } private: - bool _trivial_value_is_null; _cpp_value_type _value; bool _is_null; }; @@ -153,8 +148,6 @@ namespace sqlpp os << value(); } - bool _is_trivial() const { return _len == 0; } - bool operator==(const _cpp_value_type& rhs) const { return value() == rhs; } bool operator!=(const _cpp_value_type& rhs) const { return not operator==(rhs); } diff --git a/include/sqlpp11/tvin.h b/include/sqlpp11/tvin.h new file mode 100644 index 00000000..6f77085b --- /dev/null +++ b/include/sqlpp11/tvin.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_TVIN_H +#define SQLPP_TVIN_H + +// TVIN: Trivial value is NULL + +#include +#include + +namespace sqlpp +{ + template + struct tvin_t + { + using _wrapped_t = typename wrap_operand::type; + static_assert(not std::is_same<_wrapped_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)"); + using _value_type = typename _wrapped_t::_value_type; + + tvin_t(T t): + _value({t}) + {} + tvin_t(const tvin_t&) = default; + tvin_t(tvin_t&&) = default; + tvin_t& operator=(const tvin_t&) = default; + tvin_t& operator=(tvin_t&&) = default; + ~tvin_t() = default; + + _wrapped_t _value; + }; + + template + struct interpreter_t> + { + using T = tvin_t; + + static void _(const T& t, Context& context) + { + static_assert(detail::wrong::value, "tvin() must not be used with anything but =, ==, != and !"); + } + }; + + template + struct tvin_wrap_t + { + static constexpr bool _is_trivial() + { + return false; + } + + tvin_wrap_t(T t): + _value(t) + {} + tvin_wrap_t(const tvin_wrap_t&) = default; + tvin_wrap_t(tvin_wrap_t&&) = default; + tvin_wrap_t& operator=(const tvin_wrap_t&) = default; + tvin_wrap_t& operator=(tvin_wrap_t&&) = default; + ~tvin_wrap_t() = default; + + T _value; + }; + + template + struct tvin_wrap_t> + { + bool _is_trivial() const + { + return _value._is_trivial(); + }; + + tvin_wrap_t(tvin_t t): + _value(t._value) + {} + tvin_wrap_t(const tvin_wrap_t&) = default; + tvin_wrap_t(tvin_wrap_t&&) = default; + tvin_wrap_t& operator=(const tvin_wrap_t&) = default; + tvin_wrap_t& operator=(tvin_wrap_t&&) = default; + ~tvin_wrap_t() = default; + + typename tvin_t::_wrapped_t _value; + }; + + template + struct interpreter_t> + { + using T = tvin_wrap_t; + + static Context& _(const T& t, Context& context) + { + if (t._is_trivial()) + { + context << "NULL"; + } + else + { + interpret(t._value, context); + } + return context; + } + }; + + + template + auto tvin(T t) -> tvin_t::type> + { + return {t}; + } + +} + +#endif diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index a9a923c0..23e1894d 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -92,7 +92,6 @@ namespace sqlpp SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update); SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert); SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null); - SQLPP_IS_COLUMN_TRAIT_GENERATOR(trivial_value_is_null); SQLPP_TYPE_TRAIT_GENERATOR(is_table); SQLPP_TYPE_TRAIT_GENERATOR(is_select); diff --git a/include/sqlpp11/where.h b/include/sqlpp11/where.h index a4d736d8..0aa5e936 100644 --- a/include/sqlpp11/where.h +++ b/include/sqlpp11/where.h @@ -50,7 +50,6 @@ namespace sqlpp static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()"); using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type; - static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of where expression, use where_parameter() instead of parameter() to turn off automatic conversion"); template void add(E&& expr) diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 25035371..b1ea8bef 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -40,7 +40,12 @@ int main() TabSample t; interpret(t.alpha, printer).flush(); - interpret(t.alpha = 7, printer).flush(); + interpret(t.alpha = 0, printer).flush(); + interpret(t.alpha = sqlpp::tvin(0), printer).flush(); + interpret(t.alpha == 0, printer).flush(); + interpret(t.alpha == sqlpp::tvin(0), printer).flush(); + interpret(t.alpha != 0, printer).flush(); + interpret(t.gamma != sqlpp::tvin(false), printer).flush(); interpret(t.alpha == 7, printer).flush(); interpret(t.beta + "kaesekuchen", printer).flush(); @@ -58,6 +63,7 @@ int main() interpret(insert_into(t), printer).flush(); interpret(insert_into(t).default_values(), printer).flush(); interpret(insert_into(t).set(t.gamma = true), printer).flush(); + interpret(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).flush(); return 0; }