diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index da6f5b6e..51608433 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/include/sqlpp11/enable_comparison.h b/include/sqlpp11/enable_comparison.h index e9d5f4de..eede5d96 100644 --- a/include/sqlpp11/enable_comparison.h +++ b/include/sqlpp11/enable_comparison.h @@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include namespace sqlpp @@ -100,6 +101,21 @@ namespace sqlpp return ::sqlpp::is_not_distinct_from(this->derived(), std::move(r)); } + constexpr auto asc() const ->sort_order_expression + { + return ::sqlpp::asc(this->derived()); + } + + constexpr auto desc() const ->sort_order_expression + { + return ::sqlpp::desc(this->derived()); + } + + constexpr auto order(::sqlpp::sort_type t) const ->sort_order_expression + { + return ::sqlpp::order(this->derived(), t); + } + }; } // namespace sqlpp diff --git a/include/sqlpp11/having.h b/include/sqlpp11/having.h index 529aa13b..d940d70a 100644 --- a/include/sqlpp11/having.h +++ b/include/sqlpp11/having.h @@ -90,9 +90,6 @@ namespace sqlpp }; }; - SQLPP_PORTABLE_STATIC_ASSERT(assert_having_not_cpp_bool_t, - "having() argument has to be an sqlpp boolean expression. Please use " - "sqlpp::value(bool_expresson) if you really want to use a bool value here"); SQLPP_PORTABLE_STATIC_ASSERT(assert_having_boolean_expression_t, "having() argument has to be an sqlpp boolean expression."); @@ -100,9 +97,7 @@ namespace sqlpp struct check_having { using type = - static_combined_check_t::value, assert_having_not_cpp_bool_t>, - static_check_t::value, assert_having_boolean_expression_t>, - static_check_t::value, assert_having_boolean_expression_t>>; + static_combined_check_t::value, assert_having_boolean_expression_t>>; }; template diff --git a/include/sqlpp11/insert_value.h b/include/sqlpp11/insert_value.h index c499cdcb..b837ae5c 100644 --- a/include/sqlpp11/insert_value.h +++ b/include/sqlpp11/insert_value.h @@ -56,22 +56,15 @@ namespace sqlpp struct insert_value_t { using _is_insert_value = std::true_type; - using _column_t = Column; - using _pure_value_t = typename value_type_of_t::_cpp_value_type; - using _value_t = value_t; + using _value_t = parameter_value_t>; - insert_value_t(_pure_value_t rhs) - : _is_null(false), _is_default(false), _value(rhs._t) + insert_value_t(_value_t value) + : _is_default(false), _value(std::move(value)) { } insert_value_t(const default_value_t& /*unused*/) - : _is_null(false), _is_default(true), _value{} - { - } - - insert_value_t(const _value_t& rhs) - : _is_null(rhs._is_null), _is_default(false), _value{rhs._value} + : _is_default(true), _value{} { } @@ -81,19 +74,14 @@ namespace sqlpp insert_value_t& operator=(insert_value_t&&) = default; ~insert_value_t() = default; - bool _is_null; bool _is_default; - _pure_value_t _value; + _value_t _value; }; template - Context& serialize(Context& context, const insert_value_t& t) + auto serialize(Context& context, const insert_value_t& t) -> Context& { - if (t._is_null) - { - context << "NULL"; - } - else if (t._is_default) + if (t._is_default) { context << "DEFAULT"; } diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h index 381a0466..df63969a 100644 --- a/include/sqlpp11/insert_value_list.h +++ b/include/sqlpp11/insert_value_list.h @@ -271,7 +271,7 @@ namespace sqlpp template void _add_impl(const std::true_type& /*unused*/, Assignments... assignments) { - _data._insert_values.emplace_back(insert_value_t>{assignments._rhs}...); + _data._insert_values.emplace_back(insert_value_t>{assignments._r}...); } template diff --git a/include/sqlpp11/operator/sort_order_expression.h b/include/sqlpp11/operator/sort_order_expression.h index 8aff5fb9..6ec3f0f2 100644 --- a/include/sqlpp11/operator/sort_order_expression.h +++ b/include/sqlpp11/operator/sort_order_expression.h @@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace sqlpp { - enum class sort_order + enum class sort_type { asc, desc, @@ -41,7 +41,7 @@ namespace sqlpp template struct sort_order_expression { - constexpr sort_order_expression(L l, sort_order r) : _l(std::move(l)), _r(std::move(r)) + constexpr sort_order_expression(L l, sort_type r) : _l(std::move(l)), _r(std::move(r)) { } sort_order_expression(const sort_order_expression&) = default; @@ -51,58 +51,76 @@ namespace sqlpp ~sort_order_expression() = default; L _l; - sort_order _r; + sort_type _r; }; template using check_sort_order_args = std::enable_if_t::value>; template - struct nodes_of> + struct nodes_of> { using type = detail::type_vector; }; + template + struct is_sort_order> : std::true_type {}; + /* template constexpr auto requires_braces_v> = false; - template - constexpr auto is_sort_order_v> = true; - template - [[nodiscard]] auto to_sql_string(Context& context, const sort_order& t) + [[nodiscard]] auto to_sql_string(Context& context, const sort_type& t) { switch (t) { - case sort_order::asc: + case sort_type::asc: return std::string(" ASC"); - case sort_order::desc: + case sort_type::desc: return std::string(" DESC"); } } - template - [[nodiscard]] auto to_sql_string(Context& context, const sort_order_t& t) - { - return to_sql_string(context, embrace(t.l)) + to_sql_string(context, t.order); - } */ + template + auto serialize(Context& context, const sort_type& t) -> Context& + { + switch (t) + { + case sort_type::asc: + context << " ASC"; + break; + case sort_type::desc: + context << " DESC"; + break; + } + return context; + } + + template + auto serialize(Context& context, const sort_order_expression& t) -> Context& + { + serialize_operand(context, t._l); + serialize(context, t._r); + return context; + } + template > constexpr auto asc(L l) -> sort_order_expression { - return {l, sort_order::asc}; + return {l, sort_type::asc}; } template > constexpr auto desc(L l) -> sort_order_expression { - return {l, sort_order::desc}; + return {l, sort_type::desc}; } template > - constexpr auto order(L l, sort_order order) -> sort_order_expression + constexpr auto order(L l, sort_type order) -> sort_order_expression { return {l, order}; } diff --git a/include/sqlpp11/order_by.h b/include/sqlpp11/order_by.h index 2fb20e02..f3eb33e3 100644 --- a/include/sqlpp11/order_by.h +++ b/include/sqlpp11/order_by.h @@ -86,7 +86,7 @@ namespace sqlpp template struct check_order_by { - using type = static_combined_check_t::value...>::value, + using type = static_combined_check_t::value...>::value, assert_order_by_args_are_sort_order_expressions_t>>; }; template @@ -124,7 +124,7 @@ namespace sqlpp { static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()"); - return _order_by_impl(check_order_by_t{}, expressions...); + return _order_by_impl(check_order_by_t{}, std::move(expressions)...); } private: @@ -139,7 +139,7 @@ namespace sqlpp "at least one duplicate argument detected in order_by()"); return {static_cast&>(*this), - order_by_data_t{expressions...}}; + order_by_data_t{std::move(expressions)...}}; } }; }; @@ -154,9 +154,9 @@ namespace sqlpp } template - auto order_by(T&&... t) -> decltype(statement_t().order_by(std::forward(t)...)) + auto order_by(T... t) -> decltype(statement_t().order_by(std::forward(t)...)) { - return statement_t().order_by(std::forward(t)...); + return statement_t().order_by(std::move(t)...); } } // namespace sqlpp diff --git a/include/sqlpp11/sort_order.h b/include/sqlpp11/sort_order.h deleted file mode 100644 index 9a67adfa..00000000 --- a/include/sqlpp11/sort_order.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -/* - * Copyright (c) 2013-2015, 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. - */ - -#include - -namespace sqlpp -{ - struct no_value_t; - - enum class sort_type - { - asc, - desc - }; - - template - struct sort_order_t - { - using _traits = make_traits; - using _nodes = detail::type_vector; - - Expression _expression; - sort_type _sort_type; - }; - - template - Context& serialize(Context& context, const sort_order_t& t) - { - serialize_operand(context, t._expression); - switch (t._sort_type) - { - case sort_type::asc: - context << " ASC"; - break; - default: - context << " DESC"; - break; - } - return context; - } -} // namespace sqlpp diff --git a/include/sqlpp11/type_traits.h b/include/sqlpp11/type_traits.h index 31d8cae7..8b7176a8 100644 --- a/include/sqlpp11/type_traits.h +++ b/include/sqlpp11/type_traits.h @@ -404,7 +404,7 @@ namespace sqlpp struct parameter_value { using type = uint64_t; }; template<> - struct parameter_value { using type = floating_point; }; + struct parameter_value { using type = double; }; template<> struct parameter_value { using type = std::string; }; @@ -491,7 +491,6 @@ namespace sqlpp SQLPP_VALUE_TRAIT_GENERATOR(is_insert_list) SQLPP_VALUE_TRAIT_GENERATOR(is_insert_value) SQLPP_VALUE_TRAIT_GENERATOR(is_insert_value_list) - SQLPP_VALUE_TRAIT_GENERATOR(is_sort_order) SQLPP_VALUE_TRAIT_GENERATOR(is_parameter) SQLPP_VALUE_TRAIT_GENERATOR(requires_parens) @@ -875,6 +874,10 @@ namespace sqlpp using type = typename Db::_serializer_context_t; }; + template + struct is_sort_order : public std::false_type {}; + + template using serializer_context_of = typename serializer_context_of_impl::type; } // namespace sqlpp diff --git a/tests/core/serialize/CMakeLists.txt b/tests/core/serialize/CMakeLists.txt index 63f20580..1627c069 100644 --- a/tests/core/serialize/CMakeLists.txt +++ b/tests/core/serialize/CMakeLists.txt @@ -29,7 +29,7 @@ set(test_files Avg.cpp Blob.cpp Count.cpp - #CustomQuery.cpp + CustomQuery.cpp DynamicWhere.cpp Exists.cpp Float.cpp diff --git a/tests/core/serialize/CustomQuery.cpp b/tests/core/serialize/CustomQuery.cpp index e65aec80..ffa2da65 100644 --- a/tests/core/serialize/CustomQuery.cpp +++ b/tests/core/serialize/CustomQuery.cpp @@ -47,8 +47,8 @@ int CustomQuery(int, char*[]) custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.doubleN), from(foo.join(bar).on(foo.doubleN == bar.id)), where(bar.id > 17), group_by(foo.doubleN), having(avg(bar.id) > 19), order_by(foo.doubleN.asc()), sqlpp::limit(10u), sqlpp::offset(100u)), - "SELECT DISTINCT tab_foo.double_n FROM tab_foo INNER JOIN tab_bar ON (tab_foo.double_n=tab_bar.id) WHERE " - "(tab_bar.id>17) GROUP BY tab_foo.double_n HAVING (AVG(tab_bar.id)>19) ORDER BY tab_foo.double_n ASC " + "SELECT DISTINCT tab_foo.double_n FROM tab_foo INNER JOIN tab_bar ON (tab_foo.double_n = tab_bar.id) WHERE " + "(tab_bar.id > 17) GROUP BY tab_foo.double_n HAVING (AVG(tab_bar.id) > 19) ORDER BY tab_foo.double_n ASC " "LIMIT 10 OFFSET 100"); // A full select statement made individual clauses @@ -59,8 +59,8 @@ int CustomQuery(int, char*[]) group_by(foo.doubleN), having(avg(bar.id) > 19), order_by(foo.doubleN.asc(), foo.uIntN.order(sqlpp::sort_type::desc)), sqlpp::limit(7u), sqlpp::offset(3u)), - "SELECT DISTINCT tab_foo.double_n FROM tab_foo INNER JOIN tab_bar ON (tab_foo.double_n=tab_bar.id) WHERE " - "(tab_bar.id>17) GROUP BY tab_foo.double_n HAVING (AVG(tab_bar.id)>19) ORDER BY tab_foo.double_n " + "SELECT DISTINCT tab_foo.double_n FROM tab_foo INNER JOIN tab_bar ON (tab_foo.double_n = tab_bar.id) WHERE " + "(tab_bar.id > 17) GROUP BY tab_foo.double_n HAVING (AVG(tab_bar.id) > 19) ORDER BY tab_foo.double_n " "ASC,tab_foo.u_int_n DESC LIMIT 7 OFFSET 3"); // A pragma query for sqlite @@ -77,7 +77,7 @@ int CustomQuery(int, char*[]) .where(not exists(select(foo.doubleN).from(foo).where(foo.doubleN == x)))), "INSERT INTO tab_foo (double_n) " "SELECT 17 AS double_n FROM tab_foo " - "WHERE (NOT EXISTS(SELECT tab_foo.double_n FROM tab_foo WHERE (tab_foo.double_n=17)))"); + "WHERE (NOT EXISTS(SELECT tab_foo.double_n FROM tab_foo WHERE (tab_foo.double_n = 17)))"); // A multi-row "insert or ignore" auto batch = insert_columns(bar.textN, bar.boolNn);