0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 12:51:13 +08:00

More tests and changed parentheses handling in operators

This commit is contained in:
Roland Bock 2024-08-03 11:41:32 +02:00
parent 4a9f9c384c
commit dfa9924288
15 changed files with 36 additions and 294 deletions

View File

@ -88,45 +88,15 @@ namespace sqlpp
using type = detail::type_vector<L, R>; using type = detail::type_vector<L, R>;
}; };
#if 0
template <typename L, typename Operator, typename R> template <typename L, typename Operator, typename R>
struct value_type_of_t<arithmetic_expression<L, Operator, R>> struct requires_braces<arithmetic_expression<L, Operator, R>> : public std::true_type{};
{
using type = numeric_t;
};
template <typename L, typename Operator, typename R>
constexpr auto requires_braces_v<arithmetic_expression<L, Operator, R>> = true;
template <typename Context, typename L, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const arithmetic_expression<L, Operator, R>& t)
{
return to_sql_string(context, embrace(t._l)) + Operator::symbol + to_sql_string(context, embrace(t._r));
}
template <typename Context, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const arithmetic_expression<none_t, Operator, R>& t)
{
return Operator::symbol + to_sql_string(context, embrace(t._r));
}
template <typename Context, typename L1, typename Operator, typename R1, typename R2>
[[nodiscard]] auto to_sql_string(Context& context,
const arithmetic_expression<arithmetic_expression<L1, Operator, R1>, Operator, R2>& t)
{
return to_sql_string(context, t._l) + Operator::symbol + to_sql_string(context, embrace(t._r));
}
#endif
template <typename Context, typename L, typename Operator, typename R> template <typename Context, typename L, typename Operator, typename R>
auto serialize(Context& context, const arithmetic_expression<L, Operator, R>& t) -> Context& auto serialize(Context& context, const arithmetic_expression<L, Operator, R>& t) -> Context&
{ {
context << "(";
serialize_operand(context, t._l); serialize_operand(context, t._l);
context << Operator::symbol; context << Operator::symbol;
serialize_operand(context, t._r); serialize_operand(context, t._r);
context << ")";
return context; return context;
} }

View File

@ -39,11 +39,6 @@ namespace sqlpp
using _traits = make_traits<value_type_of_t<Expression>, tag::is_selectable, tag::is_alias>; using _traits = make_traits<value_type_of_t<Expression>, tag::is_selectable, tag::is_alias>;
#warning Maybe make constructor of expressions private to force construction in the respective functions? #warning Maybe make constructor of expressions private to force construction in the respective functions?
/*
static_assert(is_expression_t<Expression>::value, "invalid argument for an expression alias");
static_assert(not is_alias_t<Expression>::value, "cannot create an alias of an alias");
*/
constexpr as_expression(Expression expression) : _expression(std::move(expression)) constexpr as_expression(Expression expression) : _expression(std::move(expression))
{ {
} }

View File

@ -77,22 +77,7 @@ namespace sqlpp
using type = R; using type = R;
}; };
/* #warning does this require braces?
template <typename L, typename R>
struct column_of<assign_t<L, R>>
{
using type = L;
};
template <typename L, typename R>
constexpr auto requires_braces_v<assign_t<L, R>> = true;
template <typename Context, typename L, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const assign_t<L, R>& t)
{
return to_sql_string(context, t.column) + " = " + to_sql_string(context, embrace(t.value));
}
*/
template <typename Context, typename L, typename Operator, typename R> template <typename Context, typename L, typename Operator, typename R>
Context& serialize(Context& context, const assign_expression<L, Operator, R>& t) Context& serialize(Context& context, const assign_expression<L, Operator, R>& t)

View File

@ -67,38 +67,8 @@ namespace sqlpp
using type = detail::type_vector<L, R1, R2>; using type = detail::type_vector<L, R1, R2>;
}; };
template <typename L, typename R1, typename R2>
/* struct requires_braces<between_expression<L, R1, R2>> : public std::true_type{};
template <typename L, typename... Args>
struct nodes_of<between_t<L, Args...>>
{
using type = type_vector<L, Args...>;
};
template <typename L, typename... Args>
constexpr auto in(L l, Args... args)
-> ::sqlpp::enable_if_t<((sizeof...(Args) > 0) and ... and values_are_compatible_v<L, Args>), between_t<L, Args...>>
{
return between_t<L, Args...>{l, std::tuple{args...}};
}
template <typename L, typename... Args>
constexpr auto requires_braces_v<between_t<L, Args...>> = true;
template <typename Context, typename L, typename... Args>
[[nodiscard]] auto to_sql_string(Context& context, const between_t<L, Args...>& t)
{
if constexpr (sizeof...(Args) == 1)
{
return to_sql_string(context, embrace(t.l)) + " IN(" + to_sql_string(context, std::get<0>(t.args)) + ")";
}
else
{
return to_sql_string(context, embrace(t.l)) + " IN(" + tuple_to_sql_string(context, ", ", t.args) + ")";
}
}
*/
#warning: Need tests for between expressions #warning: Need tests for between expressions
template <typename L, typename R1, typename R2, typename = check_between_args<L, R1, R2>> template <typename L, typename R1, typename R2, typename = check_between_args<L, R1, R2>>
@ -107,52 +77,15 @@ namespace sqlpp
return {std::move(l), std::move(r1), std::move(r2)}; return {std::move(l), std::move(r1), std::move(r2)};
} }
#if 0 // original serialize implementation template <typename Context, typename L, typename R1, typename R2>
template <typename Context, typename Operand, typename Arg, typename... Args> auto serialize(Context& context, const between_expression<L, R1, R2>& t) -> Context&
Context& serialize(Context& context, const between_t<Operand, Arg, Args...>& t)
{ {
serialize(context, t._operand); serialize_operand(context, t._l);
context << " IN("; context << " BETWEEN ";
if (sizeof...(Args) == 0) serialize_operand(context, t._r1);
{ context << " AND ";
serialize(context, std::get<0>(t._args)); serialize_operand(context, t._r2);
}
else
{
interpret_tuple(t._args, ',', context);
}
context << ')';
return context; return context;
} }
template <typename Context, typename Operand>
Context& serialize(Context& context, const between_t<Operand>&)
{
serialize(context, boolean_operand{false});
return context;
}
template <typename Container>
struct value_list_t;
template <typename Context, typename Operand, typename Container>
Context& serialize(Context& context, const between_t<Operand, value_list_t<Container>>& t)
{
const auto& value_list = std::get<0>(t._args);
if (value_list._container.empty())
{
serialize(context, boolean_operand{false});
}
else
{
serialize(context, t._operand);
context << " IN(";
serialize(context, value_list);
context << ')';
}
return context;
}
#endif
} // namespace sqlpp } // namespace sqlpp

View File

@ -71,37 +71,15 @@ namespace sqlpp
template <typename L, typename R> template <typename L, typename R>
using check_bit_shift_expression_args = ::sqlpp::enable_if_t<is_integral<L>::value and (is_integral<R>::value or is_unsigned_integral<R>::value)>; using check_bit_shift_expression_args = ::sqlpp::enable_if_t<is_integral<L>::value and (is_integral<R>::value or is_unsigned_integral<R>::value)>;
#if 0
template <typename L, typename Operator, typename R> template <typename L, typename Operator, typename R>
struct value_type_of_t<binary_t<L, Operator, R>> struct requires_braces<bit_expression<L, Operator, R>> : public std::true_type {};
{
using type = integral_t;
};
template <typename L, typename Operator, typename R>
constexpr auto requires_braces_v<binary_t<L, Operator, R>> = true;
template <typename Context, typename L, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const binary_t<L, Operator, R>& t)
{
return to_sql_string(context, embrace(t._l)) + Operator::symbol + to_sql_string(context, embrace(t._r));
}
template <typename Context, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const binary_t<none_t, Operator, R>& t)
{
return Operator::symbol + to_sql_string(context, embrace(t._r));
}
#endif
template <typename Context, typename L, typename Operator, typename R> template <typename Context, typename L, typename Operator, typename R>
auto serialize(Context& context, const bit_expression<L, Operator, R>& t) -> Context& auto serialize(Context& context, const bit_expression<L, Operator, R>& t) -> Context&
{ {
context << "(";
serialize_operand(context, t._l); serialize_operand(context, t._l);
context << Operator::symbol; context << Operator::symbol;
serialize_operand(context, t._r); serialize_operand(context, t._r);
context << ")";
return context; return context;
} }

View File

@ -86,6 +86,9 @@ namespace sqlpp
{ {
}; };
template <typename When, typename Then, typename Else>
struct requires_braces<case_t<When, Then, Else>> : public std::true_type{};
template <typename When, typename Then> template <typename When, typename Then>
class case_then_t class case_then_t
{ {
@ -156,13 +159,13 @@ namespace sqlpp
template <typename Context, typename When, typename Then, typename Else> template <typename Context, typename When, typename Then, typename Else>
Context& serialize(Context& context, const case_t<When, Then, Else>& t) Context& serialize(Context& context, const case_t<When, Then, Else>& t)
{ {
context << "(CASE WHEN "; context << "CASE WHEN ";
serialize(context, t._when); serialize(context, t._when);
context << " THEN "; context << " THEN ";
serialize(context, t._then); serialize(context, t._then);
context << " ELSE "; context << " ELSE ";
serialize(context, t._else); serialize(context, t._else);
context << " END)"; context << " END";
return context; return context;
} }

View File

@ -84,48 +84,15 @@ namespace sqlpp
using type = detail::type_vector<L, R>; using type = detail::type_vector<L, R>;
}; };
#if 0
SQLPP_WRAPPED_STATIC_ASSERT(assert_comparison_operands_are_compatible,
"comparison operands must have compatible value types");
template <typename L, typename R>
constexpr auto check_comparison_args()
{
if constexpr (not values_are_compatible_v<L, R>)
{
return failed<assert_comparison_operands_are_compatible>{};
}
else
{
return succeeded{};
}
}
template <typename L, typename Operator, typename R> template <typename L, typename Operator, typename R>
struct value_type_of_t<comparison_expression<L, Operator, R>> struct requires_braces<comparison_expression<L, Operator, R>> : public std::true_type{};
{
using type = bool;
};
template <typename L, typename Operator, typename R>
constexpr auto requires_braces_v<comparison_expression<L, Operator, R>> = true;
template <typename Context, typename L, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const comparison_expression<L, Operator, R>& t)
{
return to_sql_string(context, embrace(t.l)) + Operator::symbol + to_sql_string(context, embrace(t.r));
}
#endif
template <typename Context, typename L, typename Operator, typename R> template <typename Context, typename L, typename Operator, typename R>
auto serialize(Context& context, const comparison_expression<L, Operator, R>& t) -> Context& auto serialize(Context& context, const comparison_expression<L, Operator, R>& t) -> Context&
{ {
context << "(";
serialize_operand(context, t._l); serialize_operand(context, t._l);
context << Operator::symbol; context << Operator::symbol;
serialize_operand(context, t._r); serialize_operand(context, t._r);
context << ")";
return context; return context;
} }

View File

@ -66,7 +66,7 @@ namespace sqlpp
template <typename Context, typename Select> template <typename Context, typename Select>
auto serialize(Context& context, const exists_expression<Select>& t) -> Context& auto serialize(Context& context, const exists_expression<Select>& t) -> Context&
{ {
context << "EXISTS("; context << "EXISTS (";
serialize(context, t._select); serialize(context, t._select);
context << ")"; context << ")";
return context; return context;

View File

@ -95,26 +95,22 @@ namespace sqlpp
using type = detail::type_vector<L, R>; using type = detail::type_vector<L, R>;
}; };
template <typename L, typename Operator, typename R>
struct requires_braces<in_expression<L, Operator, std::vector<R>>> : public std::true_type{};
template <typename L, typename Operator, typename... Args> template <typename L, typename Operator, typename... Args>
struct nodes_of<in_expression<L, Operator, std::tuple<Args...>>> struct nodes_of<in_expression<L, Operator, std::tuple<Args...>>>
{ {
using type = detail::type_vector<L, Args...>; using type = detail::type_vector<L, Args...>;
}; };
/* template <typename L, typename Operator, typename... Args>
struct requires_braces<in_expression<L, Operator, std::tuple<Args...>>> : public std::true_type{};
template <typename L, typename Operator, typename R>
constexpr auto requires_braces_v<in_expression<L, operator, std::vector<R>>> = true;
template <typename L, typename... Args>
constexpr auto requires_braces_v<in_expression<L, std::tuple<Args...>>> = true;
*/
template <typename Context, typename L, typename Operator, typename... Args> template <typename Context, typename L, typename Operator, typename... Args>
Context& serialize(Context& context, const in_expression<L, Operator, std::tuple<Args...>>& t) auto serialize(Context& context, const in_expression<L, Operator, std::tuple<Args...>>& t) -> Context&
{ {
serialize(context, t._l); serialize_operand(context, t._l);
context << Operator::symbol << "("; context << Operator::symbol << "(";
if (sizeof...(Args) == 1) if (sizeof...(Args) == 1)
{ {
@ -122,7 +118,7 @@ namespace sqlpp
} }
else else
{ {
#warning: interpret_tuple arguments should be reverted, too #warning: interpret_tuple arguments should take Context first, too
interpret_tuple(t._r, ',', context); interpret_tuple(t._r, ',', context);
} }
context << ')'; context << ')';

View File

@ -31,8 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sqlpp11/core/operator/enable_as.h> #include <sqlpp11/core/operator/enable_as.h>
#include <sqlpp11/core/query/dynamic.h> #include <sqlpp11/core/query/dynamic.h>
#include <sqlpp11/core/noop.h> #include <sqlpp11/core/noop.h>
//#include <sqlpp11/embrace.h>
//#include <sqlpp11/to_sql_string.h>
#include <sqlpp11/core/type_traits.h> #include <sqlpp11/core/type_traits.h>
namespace sqlpp namespace sqlpp
@ -71,42 +69,15 @@ namespace sqlpp
using type = detail::type_vector<L, R>; using type = detail::type_vector<L, R>;
}; };
/*
template <typename L, typename Operator, typename R> template <typename L, typename Operator, typename R>
struct value_type_of_t<logical_binary_expression<L, Operator, R>> struct requires_braces<logical_expression<L, Operator, R>> : public std::true_type{};
{
using type = bool;
};
template <typename L, typename Operator, typename R>
constexpr auto requires_braces_v<logical_binary_expression<L, Operator, R>> = true;
template <typename Context, typename L, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const logical_binary_expression<L, Operator, R>& t)
{
return to_sql_string(context, embrace(t._l)) + Operator::symbol + to_sql_string(context, embrace(t._r));
}
template <typename Context, typename Operator, typename R>
[[nodiscard]] auto to_sql_string(Context& context, const logical_binary_expression<none_t, Operator, R>& t)
{
return Operator::symbol + to_sql_string(context, embrace(t._r));
}
template <typename Context, typename L1, typename Operator, typename R1, typename R2>
[[nodiscard]] auto to_sql_string(Context& context, const logical_binary_expression<logical_binary_expression<L1, Operator, R1>, Operator, R2>& t)
{
return to_sql_string(context, t._l) + Operator::symbol + to_sql_string(context, embrace(t._r));
}
*/
template <typename Context, typename L, typename Operator, typename R> template <typename Context, typename L, typename Operator, typename R>
auto serialize_impl(Context& context, const logical_expression<L, Operator, R>& t) -> Context& auto serialize_impl(Context& context, const logical_expression<L, Operator, R>& t) -> Context&
{ {
context << "(";
serialize_operand(context, t._l); serialize_operand(context, t._l);
context << Operator::symbol; context << Operator::symbol;
serialize_operand(context, t._r); serialize_operand(context, t._r);
context << ")";
return context; return context;
} }

View File

@ -66,24 +66,6 @@ namespace sqlpp
template <typename L> template <typename L>
struct is_sort_order<sort_order_expression<L>> : std::true_type {}; struct is_sort_order<sort_order_expression<L>> : std::true_type {};
/*
template <typename L>
constexpr auto requires_braces_v<sort_order_t<L>> = false;
template <typename Context>
[[nodiscard]] auto to_sql_string(Context& context, const sort_type& t)
{
switch (t)
{
case sort_type::asc:
return std::string(" ASC");
case sort_type::desc:
return std::string(" DESC");
}
}
*/
template <typename Context> template <typename Context>
auto serialize(Context& context, const sort_type& t) -> Context& auto serialize(Context& context, const sort_type& t) -> Context&
{ {

View File

@ -843,6 +843,10 @@ namespace sqlpp
template <typename Statement, template <typename> class Predicate> template <typename Statement, template <typename> class Predicate>
using has_policy_t = typename has_policy_impl<Statement, Predicate>::type; using has_policy_t = typename has_policy_impl<Statement, Predicate>::type;
#warning rename to requires_parentheses
template<typename T>
struct requires_braces : public std::false_type {};
struct no_context_t struct no_context_t
{ {
}; };
@ -861,7 +865,6 @@ namespace sqlpp
template <typename T> template <typename T>
struct is_sort_order : public std::false_type {}; struct is_sort_order : public std::false_type {};
template <typename Db> template <typename Db>
using serializer_context_of = typename serializer_context_of_impl<Db>::type; using serializer_context_of = typename serializer_context_of_impl<Db>::type;
} // namespace sqlpp } // namespace sqlpp

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2023, 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 "Sample.h"
#include "compare.h"
#include <sqlpp11/sqlpp11.h>
int Any(int, char* [])
{
const auto bar = test::TabBar{};
// With sub select.
static_assert(sqlpp::is_table<test::TabBar>::value, "");
compare(__LINE__, any(select(bar.id).from(bar).where(bar.id > 17)),
"ANY(SELECT tab_bar.id FROM tab_bar WHERE (tab_bar.id > 17))");
compare(__LINE__, bar.intN == any(select(bar.id).from(bar).where(bar.id > 17)),
"(tab_bar.int_n = ANY(SELECT tab_bar.id FROM tab_bar WHERE (tab_bar.id > 17)))");
return 0;
}

View File

@ -24,7 +24,6 @@
set(test_files set(test_files
logical_expression.cpp logical_expression.cpp
Any.cpp
As.cpp As.cpp
Avg.cpp Avg.cpp
Blob.cpp Blob.cpp
@ -66,3 +65,5 @@ foreach(test_file IN LISTS test_files)
COMMAND sqlpp11_core_serialize ${test} COMMAND sqlpp11_core_serialize ${test}
) )
endforeach() endforeach()
add_subdirectory(operator)

View File

@ -23,7 +23,7 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function(test_compile name) function(test_compile name)
set(target sqlpp11_types_operator_${name}) set(target sqlpp11_core_types_operator_${name})
add_executable(${target} ${name}.cpp) add_executable(${target} ${name}.cpp)
target_link_libraries(${target} PRIVATE sqlpp11::sqlpp11 sqlpp11_testing) target_link_libraries(${target} PRIVATE sqlpp11::sqlpp11 sqlpp11_testing)
endfunction() endfunction()