diff --git a/include/sqlpp11/boolean.h b/include/sqlpp11/boolean.h index 8aefdb30..b1afd3e6 100644 --- a/include/sqlpp11/boolean.h +++ b/include/sqlpp11/boolean.h @@ -160,20 +160,22 @@ namespace sqlpp }; template - using _constraint = operand_t; + using _operand_t = operand_t; + template + using _constraint = is_boolean_t; template - struct operators: public basic_operators + struct operators: public basic_operators { template - vendor::logical_and_t::type> operator and(T&& t) const + vendor::logical_and_t::type> operator and(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::logical_or_t::type> operator or(T&& t) const + vendor::logical_or_t::type> operator or(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index 5eda1df1..3f852406 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -29,10 +29,13 @@ #include #include +#include +#include #include #include -#include +#include #include +#include #include namespace sqlpp @@ -70,11 +73,24 @@ namespace sqlpp } template - auto operator =(T&& t) const - -> typename std::enable_if::type>::value, - vendor::assignment_t::type>>::type + auto operator =(T t) const + -> typename std::enable_if<_value_type::template _constraint::type>::value and not std::is_same::value, + vendor::assignment_t::type>>::type { - return { *this, {std::forward(t)} }; + return { *this, {t} }; + } + + auto operator =(sqlpp::null_t) const + ->vendor::assignment_t + { + static_assert(can_be_null_t::value, "column cannot be null"); + return { *this, {} }; + } + + auto operator =(sqlpp::default_value_t) const + ->vendor::assignment_t + { + return { *this, {} }; } }; diff --git a/include/sqlpp11/default_value.h b/include/sqlpp11/default_value.h new file mode 100644 index 00000000..78eb71c5 --- /dev/null +++ b/include/sqlpp11/default_value.h @@ -0,0 +1,61 @@ +/* + * 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_DEFAULT_VALUE_H +#define SQLPP_DEFAULT_VALUE_H + +#include + +namespace sqlpp +{ + struct default_value_t + { + static constexpr bool _is_expression = true; + using _value_type = no_value_t; + + static constexpr bool _is_trivial() { return false; } + }; + + namespace vendor + { + template + struct interpreter_t + { + using Operand = default_value_t; + + static Context& _(const Operand& t, Context& context) + { + context << "DEFAULT"; + return context; + } + }; + } + + constexpr default_value_t default_value = {}; + +} + +#endif diff --git a/include/sqlpp11/floating_point.h b/include/sqlpp11/floating_point.h index ea1bce12..3ebb5e9d 100644 --- a/include/sqlpp11/floating_point.h +++ b/include/sqlpp11/floating_point.h @@ -162,34 +162,36 @@ namespace sqlpp }; template - using _constraint = operand_t; + using _operand_t = operand_t; + template + using _constraint = is_numeric_t; template - struct operators: public basic_operators + struct operators: public basic_operators { template - vendor::plus_t::type> operator +(T&& t) const + vendor::plus_t::type> operator +(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::minus_t::type> operator -(T&& t) const + vendor::minus_t::type> operator -(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::multiplies_t::type> operator *(T&& t) const + vendor::multiplies_t::type> operator *(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::divides_t::type> operator /(T&& t) const + vendor::divides_t::type> operator /(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; diff --git a/include/sqlpp11/integral.h b/include/sqlpp11/integral.h index 308014dc..c66a7067 100644 --- a/include/sqlpp11/integral.h +++ b/include/sqlpp11/integral.h @@ -162,41 +162,43 @@ namespace sqlpp }; template - using _constraint = operand_t; + using _operand_t = operand_t; + template + using _constraint = is_numeric_t; template - struct operators: public basic_operators + struct operators: public basic_operators { template - vendor::plus_t, typename _constraint::type> operator +(T&& t) const + vendor::plus_t, typename _operand_t::type> operator +(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::minus_t, typename _constraint::type> operator -(T&& t) const + vendor::minus_t, typename _operand_t::type> operator -(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::multiplies_t, typename _constraint::type> operator *(T&& t) const + vendor::multiplies_t, typename _operand_t::type> operator *(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::divides_t::type> operator /(T&& t) const + vendor::divides_t::type> operator /(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::modulus_t::type> operator %(T&& t) const + vendor::modulus_t::type> operator %(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; diff --git a/include/sqlpp11/null.h b/include/sqlpp11/null.h new file mode 100644 index 00000000..c07a3001 --- /dev/null +++ b/include/sqlpp11/null.h @@ -0,0 +1,61 @@ +/* + * 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_NULL_H +#define SQLPP_NULL_H + +#include + +namespace sqlpp +{ + struct null_t + { + static constexpr bool _is_expression = true; + using _value_type = no_value_t; + + static constexpr bool _is_trivial() { return false; } + }; + + namespace vendor + { + template + struct interpreter_t + { + using Operand = null_t; + + static Context& _(const Operand& t, Context& context) + { + context << "NULL"; + return context; + } + }; + } + + constexpr null_t null = {}; + +} + +#endif diff --git a/include/sqlpp11/text.h b/include/sqlpp11/text.h index 18aa3529..76ee4450 100644 --- a/include/sqlpp11/text.h +++ b/include/sqlpp11/text.h @@ -166,20 +166,22 @@ namespace sqlpp }; template - using _constraint = operand_t; + using _operand_t = operand_t; + template + using _constraint = is_text_t; template - struct operators: public basic_operators + struct operators: public basic_operators { template - vendor::concat_t::type> operator+(T&& t) const + vendor::concat_t::type> operator+(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; } template - vendor::like_t::type> like(T&& t) const + vendor::like_t::type> like(T&& t) const { static_assert(not is_multi_expression_t::value, "multi-expression cannot be used as left hand side operand"); return { *static_cast(this), {std::forward(t)} }; diff --git a/include/sqlpp11/vendor/assignment.h b/include/sqlpp11/vendor/assignment.h new file mode 100644 index 00000000..3b5061c4 --- /dev/null +++ b/include/sqlpp11/vendor/assignment.h @@ -0,0 +1,126 @@ +/* + * 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_ASSIGNMENT_H +#define SQLPP_ASSIGNMENT_H + +#include +#include +#include +#include + +namespace sqlpp +{ + namespace vendor + { + template + struct assignment_t + { + using _is_assignment = std::true_type; + using _column_t = Lhs; + using value_type = Rhs; + using _parameter_tuple_t = std::tuple<_column_t, Rhs>; + + static_assert(not std::is_same::value or can_be_null_t<_column_t>::value, "column cannot be null"); + + assignment_t(_column_t lhs, value_type 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; + + _column_t _lhs; + value_type _rhs; + }; + + template + struct interpreter_t> + { + using T = assignment_t; + + static Context& _(const T& t, Context& context) + { + interpret(t._lhs, context); + context << "="; + interpret(t._rhs, context); + return context; + } + }; + + template + struct assignment_t> + { + using _is_assignment = std::true_type; + using _column_t = Lhs; + using value_type = tvin_t; + using _parameter_tuple_t = std::tuple<_column_t, Rhs>; + + static_assert(can_be_null_t<_column_t>::value, "column cannot be null"); + + assignment_t(_column_t lhs, value_type 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; + + _column_t _lhs; + value_type _rhs; + }; + + template + struct interpreter_t>> + { + using T = assignment_t>; + + static Context& _(const T& t, Context& context) + { + interpret(t._lhs, context); + if (t._rhs._value._is_trivial()) + { + context << "=NULL"; + } + else + { + context << "="; + interpret(t._rhs._value, context); + } + return context; + } + }; + } +} + +#endif diff --git a/include/sqlpp11/vendor/expression.h b/include/sqlpp11/vendor/expression.h index ba66ef85..b64ce3a6 100644 --- a/include/sqlpp11/vendor/expression.h +++ b/include/sqlpp11/vendor/expression.h @@ -39,51 +39,6 @@ namespace sqlpp { namespace vendor { - template - struct assignment_t - { - using _is_assignment = std::true_type; - using column_type = Lhs; - using value_type = tvin_wrap_t; - using _parameter_tuple_t = std::tuple; - - 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; - tvin_wrap_t _rhs; - }; - - template - struct interpreter_t> - { - using T = assignment_t; - - static Context& _(const T& t, Context& context) - { - interpret(t._lhs, context); - if (t._rhs._is_trivial()) - { - context << "=NULL"; - } - else - { - context << "="; - interpret(t._rhs, context); - } - return context; - } - }; - - template struct equal_t: public detail::boolean::template operators> { diff --git a/include/sqlpp11/vendor/expression_fwd.h b/include/sqlpp11/vendor/expression_fwd.h index 988ae2a7..233a56fc 100644 --- a/include/sqlpp11/vendor/expression_fwd.h +++ b/include/sqlpp11/vendor/expression_fwd.h @@ -31,9 +31,6 @@ namespace sqlpp { namespace vendor { - template - struct assignment_t; - template struct equal_t; diff --git a/include/sqlpp11/vendor/insert_list.h b/include/sqlpp11/vendor/insert_list.h index 9162f232..23dd989c 100644 --- a/include/sqlpp11/vendor/insert_list.h +++ b/include/sqlpp11/vendor/insert_list.h @@ -91,7 +91,7 @@ namespace sqlpp static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()"); // check for prohibited assignments - using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if::type; + using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if::type; static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()"); insert_list_t(Assignments... assignment): @@ -110,12 +110,12 @@ namespace sqlpp { static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); static_assert(not must_not_insert_t::type>::value, "set() argument must not be used in insert"); - _dynamic_columns.emplace_back(insert_column_t{std::forward(assignment._lhs)}); + _dynamic_columns.emplace_back(insert_column_t{std::forward(assignment._lhs)}); _dynamic_values.emplace_back(std::forward(assignment._rhs)); } - std::tuple...> _columns; + std::tuple...> _columns; std::tuple _values; typename vendor::interpretable_list_t _dynamic_columns; typename vendor::interpretable_list_t _dynamic_values; diff --git a/include/sqlpp11/vendor/update_list.h b/include/sqlpp11/vendor/update_list.h index 89b347d0..6e729403 100644 --- a/include/sqlpp11/vendor/update_list.h +++ b/include/sqlpp11/vendor/update_list.h @@ -54,14 +54,14 @@ namespace sqlpp static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()"); // check for prohibited assignments - using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if::type; + using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if::type; static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()"); template void add(Assignment&& assignment) { static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); - static_assert(not must_not_update_t::type::column_type>::value, "set() argument must not be updated"); + static_assert(not must_not_update_t::type::_column_t>::value, "set() argument must not be updated"); _dynamic_assignments.emplace_back(std::forward(assignment)); } diff --git a/include/sqlpp11/vendor/wrap_operand.h b/include/sqlpp11/vendor/wrap_operand.h index 96edd920..184fe5cb 100644 --- a/include/sqlpp11/vendor/wrap_operand.h +++ b/include/sqlpp11/vendor/wrap_operand.h @@ -162,6 +162,9 @@ namespace sqlpp { using type = text_operand; }; + + // FIXME: Need to allow std::ref arguments + // FIXME: insert requires to work with value_list } } diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 9aa6b521..80ad465a 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -43,6 +43,8 @@ int main() TabSample t; TabFoo f; + interpret(t.alpha = sqlpp::null, printer).flush(); + interpret(t.alpha = sqlpp::default_value, printer).flush(); interpret(t.alpha, printer).flush(); interpret(-t.alpha, printer).flush(); interpret(+t.alpha, printer).flush(); @@ -71,7 +73,7 @@ int main() interpret(insert_into(t), printer).flush(); interpret(insert_into(f).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(); + //interpret(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).flush(); cannot test this since gamma cannot be null and a static assert is thrown interpret(update(t), printer).flush(); interpret(update(t).set(t.gamma = true), printer).flush();