Merge branch 'feature/distinct_aggregates' into develop

This commit is contained in:
rbock
2014-01-22 09:32:40 +01:00
6 changed files with 170 additions and 89 deletions

View File

@@ -34,9 +34,10 @@ namespace sqlpp
{
namespace vendor
{
template<typename Expr>
struct avg_t: public floating_point::template operators<avg_t<Expr>>
template<typename Flag, typename Expr>
struct avg_t: public floating_point::template operators<avg_t<Flag, Expr>>
{
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "avg() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "avg() requires a value expression as argument");
struct _value_type: public floating_point
@@ -76,14 +77,19 @@ namespace sqlpp
namespace vendor
{
template<typename Context, typename Expr>
struct interpreter_t<Context, vendor::avg_t<Expr>>
template<typename Context, typename Flag, typename Expr>
struct interpreter_t<Context, vendor::avg_t<Flag, Expr>>
{
using T = vendor::avg_t<Expr>;
using T = vendor::avg_t<Flag, Expr>;
static Context& _(const T& t, Context& context)
{
context << "AVG(";
if (std::is_same<sqlpp::distinct_t, Flag>::value)
{
interpret(Flag(), context);
context << ' ';
}
interpret(t._expr, context);
context << ")";
return context;
@@ -92,7 +98,13 @@ namespace sqlpp
}
template<typename T>
auto avg(T&& t) -> typename vendor::avg_t<typename operand_t<T, is_value_t>::type>
auto avg(T&& t) -> typename vendor::avg_t<vendor::noop, typename operand_t<T, is_value_t>::type>
{
return { std::forward<T>(t) };
}
template<typename T>
auto avg(const sqlpp::distinct_t&, T&& t) -> typename vendor::avg_t<sqlpp::distinct_t, typename operand_t<T, is_value_t>::type>
{
return { std::forward<T>(t) };
}

View File

@@ -27,16 +27,17 @@
#ifndef SQLPP_COUNT_H
#define SQLPP_COUNT_H
#include <sstream>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/integral.h>
namespace sqlpp
{
namespace vendor
{
template<typename Expr>
struct count_t: public sqlpp::detail::integral::template operators<count_t<Expr>>
template<typename Flag, typename Expr>
struct count_t: public sqlpp::detail::integral::template operators<count_t<Flag, Expr>>
{
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "count() used with flag other than 'distinct'");
static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument");
struct _value_type: public sqlpp::detail::integral
@@ -76,14 +77,19 @@ namespace sqlpp
namespace vendor
{
template<typename Context, typename Expr>
struct interpreter_t<Context, vendor::count_t<Expr>>
template<typename Context, typename Flag, typename Expr>
struct interpreter_t<Context, vendor::count_t<Flag, Expr>>
{
using T = vendor::count_t<Expr>;
using T = vendor::count_t<Flag, Expr>;
static Context& _(const T& t, Context& context)
{
context << "COUNT(";
if (std::is_same<sqlpp::distinct_t, Flag>::value)
{
interpret(Flag(), context);
context << ' ';
}
interpret(t._expr, context);
context << ")";
return context;
@@ -91,9 +97,14 @@ namespace sqlpp
};
}
#warning: Add optional distinct flag to aggregate functions
template<typename T>
auto count(T&& t) -> typename vendor::count_t<typename operand_t<T, is_value_t>::type>
auto count(T&& t) -> typename vendor::count_t<vendor::noop, typename operand_t<T, is_value_t>::type>
{
return { std::forward<T>(t) };
}
template<typename T>
auto count(const sqlpp::distinct_t&, T&& t) -> typename vendor::count_t<sqlpp::distinct_t, typename operand_t<T, is_value_t>::type>
{
return { std::forward<T>(t) };
}

View File

@@ -0,0 +1,107 @@
/*
* 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_SELECT_FLAGS_H
#define SQLPP_SELECT_FLAGS_H
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <tuple>
namespace sqlpp
{
// standard select flags
struct all_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
};
static constexpr all_t all = {};
namespace vendor
{
template<typename Context>
struct interpreter_t<Context, all_t>
{
static Context& _(const all_t&, Context& context)
{
context << "ALL";
return context;
}
};
}
struct distinct_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
};
static constexpr distinct_t distinct = {};
namespace vendor
{
template<typename Context>
struct interpreter_t<Context, distinct_t>
{
static Context& _(const distinct_t&, Context& context)
{
context << "DISTINCT";
return context;
}
};
}
struct straight_join_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
};
static constexpr straight_join_t straight_join = {};
namespace vendor
{
template<typename Context>
struct interpreter_t<Context, straight_join_t>
{
static Context& _(const straight_join_t&, Context& context)
{
context << "STRAIGHT_JOIN";
return context;
}
};
}
}
#endif

View File

@@ -34,9 +34,10 @@ namespace sqlpp
{
namespace vendor
{
template<typename Expr>
struct sum_t: public boolean::template operators<sum_t<Expr>>
template<typename Flag, typename Expr>
struct sum_t: public boolean::template operators<sum_t<Flag, Expr>>
{
static_assert(is_noop<Flag>::value or std::is_same<sqlpp::distinct_t, Flag>::value, "sum() used with flag other than 'distinct'");
static_assert(is_numeric_t<Expr>::value, "sum() requires a numeric expression as argument");
struct _value_type: public Expr::_value_type::_base_value_type
@@ -76,14 +77,19 @@ namespace sqlpp
namespace vendor
{
template<typename Context, typename Expr>
struct interpreter_t<Context, vendor::sum_t<Expr>>
template<typename Context, typename Flag, typename Expr>
struct interpreter_t<Context, vendor::sum_t<Flag, Expr>>
{
using T = vendor::sum_t<Expr>;
using T = vendor::sum_t<Flag, Expr>;
static Context& _(const T& t, Context& context)
{
context << "SUM(";
if (std::is_same<sqlpp::distinct_t, Flag>::value)
{
interpret(Flag(), context);
context << ' ';
}
interpret(t._expr, context);
context << ")";
return context;
@@ -92,7 +98,13 @@ namespace sqlpp
}
template<typename T>
auto sum(T&& t) -> typename vendor::sum_t<typename operand_t<T, is_value_t>::type>
auto sum(T&& t) -> typename vendor::sum_t<vendor::noop, typename operand_t<T, is_value_t>::type>
{
return { std::forward<T>(t) };
}
template<typename T>
auto sum(const sqlpp::distinct_t&, T&& t) -> typename vendor::sum_t<sqlpp::distinct_t, typename operand_t<T, is_value_t>::type>
{
return { std::forward<T>(t) };
}

View File

@@ -24,84 +24,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SQLPP_SELECT_FLAGS_H
#define SQLPP_SELECT_FLAGS_H
#ifndef SQLPP_VENDOR_SELECT_FLAG_LIST_H
#define SQLPP_VENDOR_SELECT_FLAG_LIST_H
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/select_flags.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <tuple>
namespace sqlpp
{
// standard select flags
struct all_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
};
static constexpr all_t all = {};
namespace vendor
{
template<typename Context>
struct interpreter_t<Context, all_t>
{
static Context& _(const all_t&, Context& context)
{
context << "ALL";
return context;
}
};
}
struct distinct_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
};
static constexpr distinct_t distinct = {};
namespace vendor
{
template<typename Context>
struct interpreter_t<Context, distinct_t>
{
static Context& _(const distinct_t&, Context& context)
{
context << "DISTINCT";
return context;
}
};
}
struct straight_join_t
{
struct _value_type
{
using _is_select_flag = std::true_type;
};
};
static constexpr straight_join_t straight_join = {};
namespace vendor
{
template<typename Context>
struct interpreter_t<Context, straight_join_t>
{
static Context& _(const straight_join_t&, Context& context)
{
context << "STRAIGHT_JOIN";
return context;
}
};
}
namespace vendor
{
template<typename Database, typename T>

View File

@@ -114,5 +114,10 @@ int main()
interpret(dynamic_select(db).dynamic_flags().add_flag(sqlpp::distinct).dynamic_columns().add_column(t.gamma).add_column(t.beta), printer).flush();
interpret(dynamic_select(db).dynamic_flags(sqlpp::distinct).add_flag(sqlpp::all).dynamic_columns(t.alpha).add_column(t.beta), printer).flush();
// distinct aggregate
interpret(count(sqlpp::distinct, t.alpha % 7), printer).flush();
interpret(avg(sqlpp::distinct, t.alpha - 7), printer).flush();
interpret(sum(sqlpp::distinct, t.alpha + 7), printer).flush();
return 0;
}