Merge branch 'release/0.44'

This commit is contained in:
rbock
2016-12-25 14:56:38 +01:00
17 changed files with 163 additions and 47 deletions

View File

@@ -51,3 +51,4 @@ CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
SortIncludes: false

View File

@@ -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

View File

@@ -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)

View File

@@ -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>

View File

@@ -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>

View File

@@ -38,7 +38,7 @@
namespace sqlpp
{
struct integral;
template <typename Expression>
struct expression_operators<Expression, unsigned_integral> : public basic_expression_operators<Expression>
{

View File

@@ -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

View File

@@ -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...>

View File

@@ -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>

View File

@@ -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";

View File

@@ -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
View 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;
}

View File

@@ -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})

View File

@@ -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__,

View File

@@ -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;

View File

@@ -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");
}

View File

@@ -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()