mirror of
https://github.com/rbock/sqlpp11.git
synced 2026-01-01 10:41:22 -06:00
Merge branch 'release/0.44'
This commit is contained in:
@@ -51,3 +51,4 @@ CommentPragmas: '^ IWYU pragma:'
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
SpaceBeforeParens: ControlStatements
|
||||
DisableFormat: false
|
||||
SortIncludes: false
|
||||
|
||||
26
.travis.yml
26
.travis.yml
@@ -4,7 +4,8 @@ os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
osx_image: xcode7
|
||||
dist: trusty
|
||||
sudo: required
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
@@ -12,7 +13,7 @@ compiler:
|
||||
|
||||
env:
|
||||
- CONFIG=Release
|
||||
- CONFIG=Debug
|
||||
#- CONFIG=Debug
|
||||
|
||||
notifications:
|
||||
email:
|
||||
@@ -20,29 +21,12 @@ notifications:
|
||||
on_failure: always
|
||||
|
||||
install:
|
||||
- CMAKE_VERSION_MM=3.2
|
||||
- CMAKE_VERSION_FULL=$CMAKE_VERSION_MM.2
|
||||
- g++ --version
|
||||
- cmake --version
|
||||
- git clone https://github.com/HowardHinnant/date
|
||||
- cd date
|
||||
- git checkout tags/v1.0.0
|
||||
- cd ..
|
||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
&& sudo add-apt-repository -y ppa:apokluda/boost1.53
|
||||
&& sudo apt-get update -qq
|
||||
&& sudo apt-get install -qq g++-4.8 libboost1.53-dev --no-install-recommends
|
||||
&& sudo update-alternatives --quiet --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.6
|
||||
&& sudo update-alternatives --quiet --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.8
|
||||
&& sudo update-alternatives --quiet --set gcc /usr/bin/gcc-4.8
|
||||
&& wget --no-check-certificate http://www.cmake.org/files/v${CMAKE_VERSION_MM}/cmake-${CMAKE_VERSION_FULL}-Linux-x86_64.sh
|
||||
&& sudo sh cmake-${CMAKE_VERSION_FULL}-Linux-x86_64.sh --prefix=/usr/local --exclude-subdir;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew update
|
||||
&& ((brew list -1 | grep -q "^$cmake\$") || brew install cmake)
|
||||
&& (brew outdated cmake || brew upgrade cmake)
|
||||
&& cmake --version;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015, Roland Bock
|
||||
* Copyright (c) 2013-2016, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -89,6 +89,7 @@ namespace sqlpp
|
||||
SQLPP_ALIAS_PROVIDER(o)
|
||||
SQLPP_ALIAS_PROVIDER(p)
|
||||
SQLPP_ALIAS_PROVIDER(q)
|
||||
SQLPP_ALIAS_PROVIDER(r)
|
||||
SQLPP_ALIAS_PROVIDER(s)
|
||||
SQLPP_ALIAS_PROVIDER(t)
|
||||
SQLPP_ALIAS_PROVIDER(u)
|
||||
|
||||
@@ -187,14 +187,19 @@ namespace sqlpp
|
||||
return {*static_cast<const Expr*>(this)};
|
||||
}
|
||||
|
||||
auto asc() const -> sort_order_t<Expr, sort_type::asc>
|
||||
auto asc() const -> sort_order_t<Expr>
|
||||
{
|
||||
return {*static_cast<const Expr*>(this)};
|
||||
return {*static_cast<const Expr*>(this), sort_type::asc};
|
||||
}
|
||||
|
||||
auto desc() const -> sort_order_t<Expr, sort_type::desc>
|
||||
auto desc() const -> sort_order_t<Expr>
|
||||
{
|
||||
return {*static_cast<const Expr*>(this)};
|
||||
return {*static_cast<const Expr*>(this), sort_type::desc};
|
||||
}
|
||||
|
||||
auto order(sort_type s) const -> sort_order_t<Expr>
|
||||
{
|
||||
return {*static_cast<const Expr*>(this), s};
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace sqlpp
|
||||
struct return_type_plus<L, R, binary_operand_check_t<L, is_integral_t, R, is_unsigned_integral_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = integral;
|
||||
using type = plus_t<wrap_operand_t<L>, integral, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
@@ -67,7 +67,7 @@ namespace sqlpp
|
||||
struct return_type_minus<L, R, binary_operand_check_t<L, is_integral_t, R, is_unsigned_integral_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = integral;
|
||||
using type = minus_t<wrap_operand_t<L>, integral, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
@@ -81,7 +81,7 @@ namespace sqlpp
|
||||
struct return_type_multiplies<L, R, binary_operand_check_t<L, is_integral_t, R, is_unsigned_integral_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = integral;
|
||||
using type = multiplies_t<wrap_operand_t<L>, integral, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
@@ -95,7 +95,7 @@ namespace sqlpp
|
||||
struct return_type_divides<L, R, binary_operand_check_t<L, is_integral_t, R, is_unsigned_integral_t>>
|
||||
{
|
||||
using check = consistent_t;
|
||||
using type = integral;
|
||||
using type = divides_t<wrap_operand_t<L>, wrap_operand_t<R>>;
|
||||
};
|
||||
|
||||
template <typename L, typename R>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
namespace sqlpp
|
||||
{
|
||||
struct integral;
|
||||
|
||||
|
||||
template <typename Expression>
|
||||
struct expression_operators<Expression, unsigned_integral> : public basic_expression_operators<Expression>
|
||||
{
|
||||
|
||||
@@ -46,6 +46,46 @@ namespace sqlpp
|
||||
template <typename AliasProvider, typename FieldSpecTuple>
|
||||
struct multi_field_spec_t
|
||||
{
|
||||
static_assert(wrong_t<AliasProvider, FieldSpecTuple>::value,
|
||||
"multi_field_spec_t needs to be specialized with a tuple");
|
||||
};
|
||||
|
||||
template <typename AliasProvider, typename... FieldSpecs>
|
||||
struct multi_field_spec_t<AliasProvider, std::tuple<FieldSpecs...>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Left, typename Right, typename Enable = void>
|
||||
struct is_field_compatible
|
||||
{
|
||||
static constexpr auto value = false;
|
||||
};
|
||||
|
||||
template <typename LeftName,
|
||||
typename LeftValue,
|
||||
bool LeftCanBeNull,
|
||||
bool LeftNullIsTrivial,
|
||||
typename RightName,
|
||||
typename RightValue,
|
||||
bool RightCanBeNull,
|
||||
bool RightNullIsTrivial>
|
||||
struct is_field_compatible<field_spec_t<LeftName, LeftValue, LeftCanBeNull, LeftNullIsTrivial>,
|
||||
field_spec_t<RightName, RightValue, RightCanBeNull, RightNullIsTrivial>>
|
||||
{
|
||||
static constexpr auto value =
|
||||
std::is_same<typename LeftName::_name_t, typename RightName::_name_t>::value and
|
||||
std::is_same<LeftValue, RightValue>::value and // Same value type
|
||||
(LeftCanBeNull or !RightCanBeNull) and // The left hand side determines the result row and therefore must allow
|
||||
// NULL if the right hand side allows it
|
||||
(LeftNullIsTrivial or !RightNullIsTrivial); // as above
|
||||
};
|
||||
|
||||
template <typename LeftAlias, typename... LeftFields, typename RightAlias, typename... RightFields>
|
||||
struct is_field_compatible<multi_field_spec_t<LeftAlias, std::tuple<LeftFields...>>,
|
||||
multi_field_spec_t<RightAlias, std::tuple<RightFields...>>,
|
||||
typename std::enable_if<sizeof...(LeftFields) == sizeof...(RightFields)>::type>
|
||||
{
|
||||
static constexpr auto value = logic::all_t<is_field_compatible<LeftFields, RightFields>::value...>::value;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
|
||||
@@ -251,6 +251,20 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs, typename Enable = void>
|
||||
struct is_result_compatible
|
||||
{
|
||||
static constexpr auto value = false;
|
||||
};
|
||||
|
||||
template <typename LDb, typename... LFields, typename RDb, typename... RFields>
|
||||
struct is_result_compatible<result_row_t<LDb, LFields...>,
|
||||
result_row_t<RDb, RFields...>,
|
||||
typename std::enable_if<sizeof...(LFields) == sizeof...(RFields)>::type>
|
||||
{
|
||||
static constexpr auto value = logic::all_t<is_field_compatible<LFields, RFields>::value...>::value;
|
||||
};
|
||||
|
||||
template <typename Db, typename... FieldSpecs>
|
||||
struct dynamic_result_row_t
|
||||
: public detail::result_row_impl<Db, detail::make_field_index_sequence<0, FieldSpecs...>, FieldSpecs...>
|
||||
|
||||
@@ -376,7 +376,7 @@ namespace sqlpp
|
||||
template <typename... T>
|
||||
static constexpr auto _check_args(T... args) -> decltype(_check_tuple(detail::column_tuple_merge(args...)))
|
||||
{
|
||||
return {};
|
||||
return _check_tuple(detail::column_tuple_merge(args...));
|
||||
}
|
||||
|
||||
template <typename Check, typename T>
|
||||
|
||||
@@ -39,25 +39,26 @@ namespace sqlpp
|
||||
desc
|
||||
};
|
||||
|
||||
template <typename Expression, sort_type SortType>
|
||||
template <typename Expression>
|
||||
struct sort_order_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::is_sort_order>;
|
||||
using _nodes = detail::type_vector<Expression>;
|
||||
|
||||
Expression _expression;
|
||||
sort_type _sort_type;
|
||||
};
|
||||
|
||||
template <typename Context, typename Expression, sort_type SortType>
|
||||
struct serializer_t<Context, sort_order_t<Expression, SortType>>
|
||||
template <typename Context, typename Expression>
|
||||
struct serializer_t<Context, sort_order_t<Expression>>
|
||||
{
|
||||
using _serialize_check = serialize_check_of<Context, Expression>;
|
||||
using T = sort_order_t<Expression, SortType>;
|
||||
using T = sort_order_t<Expression>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
serialize_operand(t._expression, context);
|
||||
switch (SortType)
|
||||
switch (t._sort_type)
|
||||
{
|
||||
case sort_type::asc:
|
||||
context << " ASC";
|
||||
|
||||
@@ -213,10 +213,10 @@ namespace sqlpp
|
||||
static_assert(has_result_row_t<derived_statement_t<Policies>>::value,
|
||||
"left hand side argument of a union has to be a complete select statement or union");
|
||||
|
||||
using _result_row_t = get_result_row_t<Rhs>;
|
||||
static_assert(std::is_same<get_result_row_t<derived_statement_t<Policies>>, _result_row_t>::value,
|
||||
using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>;
|
||||
using rhs_result_row_t = get_result_row_t<Rhs>;
|
||||
static_assert(is_result_compatible<lhs_result_row_t, rhs_result_row_t>::value,
|
||||
"both arguments in a union have to have the same result columns (type and name)");
|
||||
static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns");
|
||||
|
||||
return _union_impl<void, union_distinct_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
|
||||
}
|
||||
@@ -231,10 +231,10 @@ namespace sqlpp
|
||||
static_assert(has_result_row_t<derived_statement_t<Policies>>::value,
|
||||
"left hand side argument of a union has to be a (complete) select statement");
|
||||
|
||||
using _result_row_t = get_result_row_t<Rhs>;
|
||||
static_assert(std::is_same<get_result_row_t<derived_statement_t<Policies>>, _result_row_t>::value,
|
||||
using lhs_result_row_t = get_result_row_t<derived_statement_t<Policies>>;
|
||||
using rhs_result_row_t = get_result_row_t<Rhs>;
|
||||
static_assert(is_result_compatible<lhs_result_row_t, rhs_result_row_t>::value,
|
||||
"both arguments in a union have to have the same result columns (type and name)");
|
||||
static_assert(is_static_result_row_t<_result_row_t>::value, "unions must not have dynamically added columns");
|
||||
|
||||
return _union_impl<void, union_all_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
|
||||
}
|
||||
@@ -253,6 +253,7 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
template <typename T>
|
||||
auto union_all(T&& t) -> decltype(statement_t<void, no_union_t>().union_all(std::forward<T>(t)))
|
||||
{
|
||||
@@ -264,6 +265,7 @@ namespace sqlpp
|
||||
{
|
||||
return statement_t<void, no_union_t>().union_distinct(std::forward<T>(t));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
48
test_serializer/As.cpp
Normal file
48
test_serializer/As.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2016, 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 "compare.h"
|
||||
#include "Sample.h"
|
||||
#include <sqlpp11/sqlpp11.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
SQLPP_ALIAS_PROVIDER(cheese);
|
||||
|
||||
int As(int, char* [])
|
||||
{
|
||||
const auto foo = test::TabFoo{};
|
||||
const auto bar = test::TabBar{};
|
||||
|
||||
compare(__LINE__, foo.omega.as(cheese), "tab_foo.omega AS cheese");
|
||||
compare(__LINE__, (foo.omega + 17).as(cheese), "(tab_foo.omega+17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - 17).as(cheese), "(tab_foo.omega-17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - uint32_t(17)).as(cheese), "(tab_foo.omega-17) AS cheese");
|
||||
compare(__LINE__, (foo.omega - bar.alpha).as(cheese), "(tab_foo.omega-tab_bar.alpha) AS cheese");
|
||||
compare(__LINE__, (count(foo.omega) - bar.alpha).as(cheese), "(COUNT(tab_foo.omega)-tab_bar.alpha) AS cheese");
|
||||
compare(__LINE__, (count(foo.omega) - uint32_t(17)).as(cheese), "(COUNT(tab_foo.omega)-17) AS cheese");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -24,11 +24,12 @@
|
||||
|
||||
set(test_serializer_names
|
||||
CustomQuery
|
||||
As
|
||||
From
|
||||
In
|
||||
Insert
|
||||
Where
|
||||
TableAlias
|
||||
Where
|
||||
)
|
||||
|
||||
create_test_sourcelist(test_serializer_sources test_serializer_main.cpp ${test_serializer_names})
|
||||
|
||||
@@ -57,9 +57,11 @@ int CustomQuery(int, char* [])
|
||||
custom_query(sqlpp::select(), dynamic_select_flags(db, sqlpp::distinct), dynamic_select_columns(db, foo.omega),
|
||||
dynamic_from(db, foo.join(bar).on(foo.omega == bar.alpha)), dynamic_where(db, bar.alpha > 17),
|
||||
dynamic_group_by(db, foo.omega), dynamic_having(db, avg(bar.alpha) > 19),
|
||||
dynamic_order_by(db, foo.omega.asc()), sqlpp::dynamic_limit(db), sqlpp::dynamic_offset(db)),
|
||||
dynamic_order_by(db, foo.omega.asc(), foo.psi.order(sqlpp::sort_type::desc)),
|
||||
sqlpp::dynamic_limit(db), sqlpp::dynamic_offset(db)),
|
||||
"SELECT DISTINCT tab_foo.omega FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega=tab_bar.alpha) WHERE "
|
||||
"(tab_bar.alpha>17) GROUP BY tab_foo.omega HAVING (AVG(tab_bar.alpha)>19) ORDER BY tab_foo.omega ASC ");
|
||||
"(tab_bar.alpha>17) GROUP BY tab_foo.omega HAVING (AVG(tab_bar.alpha)>19) ORDER BY tab_foo.omega "
|
||||
"ASC,tab_foo.psi DESC ");
|
||||
|
||||
// A pragma query for sqlite
|
||||
compare(__LINE__,
|
||||
|
||||
@@ -160,6 +160,7 @@ int Select(int, char* [])
|
||||
s.offset.set(3u);
|
||||
s.group_by.add(t.beta);
|
||||
s.order_by.add(t.beta.asc());
|
||||
s.order_by.add(t.delta.order(sqlpp::sort_type::desc));
|
||||
for (const auto& row : db(s))
|
||||
{
|
||||
int64_t a = row.alpha;
|
||||
|
||||
@@ -167,7 +167,8 @@ int SelectType(int, char* [])
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_minus_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_plus_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_multiplies_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_divides_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
static_assert(sqlpp::is_floating_point_t<sqlpp::return_type_divides_t<sqlpp::integral, T>>::value,
|
||||
"type requirement");
|
||||
static_assert(sqlpp::is_integral_t<sqlpp::return_type_modulus_t<sqlpp::integral, T>>::value, "type requirement");
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@
|
||||
#include <sqlpp11/alias_provider.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace greek
|
||||
{
|
||||
SQLPP_ALIAS_PROVIDER(alpha)
|
||||
SQLPP_ALIAS_PROVIDER(beta)
|
||||
}
|
||||
|
||||
int Union(int, char* [])
|
||||
{
|
||||
MockDb db;
|
||||
@@ -40,6 +46,15 @@ int Union(int, char* [])
|
||||
db(select(t.alpha).from(t).unconditionally().union_distinct(select(f.epsilon.as(t.alpha)).from(f).unconditionally()));
|
||||
db(select(t.alpha).from(t).unconditionally().union_all(select(f.epsilon.as(t.alpha)).from(f).unconditionally()));
|
||||
|
||||
// t.alpha can be null, a given value cannot
|
||||
db(select(t.alpha).from(t).unconditionally().union_all(select(sqlpp::value(1).as(t.alpha))));
|
||||
db(select(t.alpha).from(t).unconditionally().union_all(select(sqlpp::value(1).as(greek::alpha))));
|
||||
|
||||
// t.beta can be null, f.delta cannot
|
||||
static_assert(sqlpp::can_be_null_t<decltype(t.beta)>::value, "");
|
||||
static_assert(!sqlpp::can_be_null_t<decltype(f.delta)>::value, "");
|
||||
db(select(t.beta).from(t).unconditionally().union_all(select(f.delta.as(greek::beta)).from(f).unconditionally()));
|
||||
|
||||
auto u = select(t.alpha)
|
||||
.from(t)
|
||||
.unconditionally()
|
||||
|
||||
Reference in New Issue
Block a user