0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

select now collects parameters from Where and Having

This commit is contained in:
Roland Bock 2013-11-26 23:45:31 +01:00
parent 8f99a03359
commit 221e20918b
9 changed files with 89 additions and 17 deletions

View File

@ -40,7 +40,7 @@ namespace sqlpp
using _is_assignment = std::true_type; using _is_assignment = std::true_type;
using column_type = Lhs; using column_type = Lhs;
using value_type = Rhs; using value_type = Rhs;
using _parameters = std::tuple<Lhs, Rhs>; using _parameter_t = std::tuple<Lhs, Rhs>;
template<typename Db> template<typename Db>
void serialize(std::ostream& os, Db& db) const void serialize(std::ostream& os, Db& db) const
@ -65,7 +65,7 @@ namespace sqlpp
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>> struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
{ {
using _value_type = ValueType; using _value_type = ValueType;
using _parameters = std::tuple<Lhs, Rhs>; using _parameter_t = std::tuple<Lhs, Rhs>;
template<typename L, typename R> template<typename L, typename R>
equal_t(L&& l, R&& r): equal_t(L&& l, R&& r):
@ -105,7 +105,7 @@ namespace sqlpp
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>> struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
{ {
using _value_type = ValueType; using _value_type = ValueType;
using _parameters = std::tuple<Lhs, Rhs>; using _parameter_t = std::tuple<Lhs, Rhs>;
template<typename L, typename R> template<typename L, typename R>
not_equal_t(L&& l, R&& r): not_equal_t(L&& l, R&& r):
@ -145,7 +145,7 @@ namespace sqlpp
struct not_t: public ValueType::template operators<not_t<Lhs>> struct not_t: public ValueType::template operators<not_t<Lhs>>
{ {
using _value_type = ValueType; using _value_type = ValueType;
using _parameters = std::tuple<Lhs>; using _parameter_t = std::tuple<Lhs>;
not_t(Lhs l): not_t(Lhs l):
_lhs(l) _lhs(l)
@ -182,7 +182,7 @@ namespace sqlpp
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>> struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
{ {
using _value_type = typename O::_value_type; using _value_type = typename O::_value_type;
using _parameters = std::tuple<Lhs, Rhs>; using _parameter_t = std::tuple<Lhs, Rhs>;
binary_expression_t(Lhs&& l, Rhs&& r): binary_expression_t(Lhs&& l, Rhs&& r):
_lhs(std::move(l)), _lhs(std::move(l)),

View File

@ -65,7 +65,8 @@ namespace sqlpp
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0); _dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
} }
std::tuple<Expr...> _expressions; using _parameter_t = std::tuple<Expr...>;
_parameter_t _expressions;
detail::serializable_list<Database> _dynamic_expressions; detail::serializable_list<Database> _dynamic_expressions;
}; };

View File

@ -41,7 +41,7 @@ namespace sqlpp
{ {
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text"); static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text"); static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
using _parameters = std::tuple<ValueType, Pattern>; using _parameter_t = std::tuple<ValueType, Pattern>;
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
{ {

View File

@ -27,33 +27,54 @@
#ifndef SQLPP_PARAMETER_LIST_H #ifndef SQLPP_PARAMETER_LIST_H
#define SQLPP_PARAMETER_LIST_H #define SQLPP_PARAMETER_LIST_H
#include <sqlpp11/detail/wrong.h>
#include <tuple> #include <tuple>
namespace sqlpp namespace sqlpp
{ {
template<typename T>
struct named_parameter_list_t
{
static_assert(detail::wrong<T>::value, "Template parameter for named_parameter_list_t has to be a tuple");
};
template<typename... Parameter> template<typename... Parameter>
struct named_parameter_list_t: public Parameter::_member_t... struct named_parameter_list_t<std::tuple<Parameter...>>: public Parameter::_member_t...
{ {
named_parameter_list_t(): named_parameter_list_t():
Parameter::_member_t()..., Parameter::_member_t()...,
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...) _parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
{} {}
named_parameter_list_t(const named_parameter_list_t& rhs): named_parameter_list_t(const named_parameter_list_t& rhs)
noexcept(std::is_nothrow_copy_constructible<std::tuple<typename Parameter::_member_t...>>::value):
Parameter::_member_t(static_cast<const typename Parameter::_member_t&>(rhs))..., Parameter::_member_t(static_cast<const typename Parameter::_member_t&>(rhs))...,
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...) _parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
{} {}
named_parameter_list_t(named_parameter_list_t&& rhs): named_parameter_list_t(named_parameter_list_t&& rhs)
noexcept(std::is_nothrow_move_constructible<std::tuple<typename Parameter::_member_t...>>::value):
Parameter::_member_t(std::move(static_cast<typename Parameter::_member_t&>(rhs)))..., Parameter::_member_t(std::move(static_cast<typename Parameter::_member_t&>(rhs)))...,
_parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...) _parameter_tuple(static_cast<typename Parameter::_member_t&>(*this)()...)
{} {}
named_parameter_list_t& operator=(const named_parameter_list_t&) = delete; named_parameter_list_t& operator=(const named_parameter_list_t& rhs)
named_parameter_list_t& operator=(named_parameter_list_t&&) = delete; noexcept(std::is_nothrow_copy_assignable<std::tuple<typename Parameter::_member_t&...>>::value)
{
_parameter_tuple = rhs._parameter_tuple;
return *this;
}
named_parameter_list_t& operator=(named_parameter_list_t&& rhs)
noexcept(std::is_nothrow_move_assignable<std::tuple<typename Parameter::_member_t&...>>::value)
{
_parameter_tuple = std::move(rhs._parameter_tuple);
return *this;
}
~named_parameter_list_t() = default; ~named_parameter_list_t() = default;
std::tuple<const typename Parameter::type&...> _parameter_tuple; std::tuple<typename Parameter::_value_type::_cpp_value_type&...> _parameter_tuple;
}; };
namespace detail namespace detail
@ -78,13 +99,20 @@ namespace sqlpp
}; };
template<typename Exp> template<typename Exp>
struct get_parameter_tuple<Exp, typename std::enable_if<not std::is_same<typename Exp::_parameters, void>::value, void>::type> struct get_parameter_tuple<Exp, typename std::enable_if<not std::is_same<typename Exp::_parameter_t, void>::value, void>::type>
{ {
using type = typename get_parameter_tuple<typename Exp::_parameters>::type; using type = typename get_parameter_tuple<typename Exp::_parameter_t>::type;
}; };
} }
template<typename Exp>
auto named_parameter_list(const Exp& exp)
-> named_parameter_list_t<typename detail::get_parameter_tuple<typename std::decay<Exp>::type>::type>
{
return {};
}
} }
#endif #endif

View File

@ -40,6 +40,7 @@
#include <sqlpp11/limit.h> #include <sqlpp11/limit.h>
#include <sqlpp11/offset.h> #include <sqlpp11/offset.h>
#include <sqlpp11/expression.h> #include <sqlpp11/expression.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/detail/wrong.h> #include <sqlpp11/detail/wrong.h>
#include <sqlpp11/detail/make_flag_tuple.h> #include <sqlpp11/detail/make_flag_tuple.h>
@ -589,6 +590,7 @@ namespace sqlpp
OrderBy _order_by; OrderBy _order_by;
Limit _limit; Limit _limit;
Offset _offset; Offset _offset;
decltype(named_parameter_list(std::declval<std::tuple<Where, Having>>())) _parameter_list;
}; };
// construct select flag list // construct select flag list

View File

@ -64,7 +64,8 @@ namespace sqlpp
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0); _dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
} }
std::tuple<Expr...> _expressions; using _parameter_t = std::tuple<Expr...>;
_parameter_t _expressions;
detail::serializable_list<Database> _dynamic_expressions; detail::serializable_list<Database> _dynamic_expressions;
}; };
} }

View File

@ -32,6 +32,7 @@
#include <iostream> #include <iostream>
DbMock db = {}; DbMock db = {};
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen);
int main() int main()
{ {
@ -374,7 +375,6 @@ int main()
// test verbatim_table alias // test verbatim_table alias
{ {
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen);
using T = decltype(sqlpp::verbatim_table("cheesecake").as(kaesekuchen)); using T = decltype(sqlpp::verbatim_table("cheesecake").as(kaesekuchen));
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement"); static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");

View File

@ -27,6 +27,7 @@
#include "MockDb.h" #include "MockDb.h"
#include "is_regular.h" #include "is_regular.h"
#include <sqlpp11/functions.h> #include <sqlpp11/functions.h>
#include <sqlpp11/select.h>
#include <iostream> #include <iostream>
@ -74,6 +75,35 @@ int main()
static_assert(std::is_same<T, std::tuple<decltype(parameter(t.beta)), decltype(parameter(t.alpha)),decltype(parameter(t.gamma))>>::value, "type requirement"); static_assert(std::is_same<T, std::tuple<decltype(parameter(t.beta)), decltype(parameter(t.alpha)),decltype(parameter(t.gamma))>>::value, "type requirement");
} }
// OK, fine, now create a named parameter list from an expression
{
auto npl = named_parameter_list(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_cpp_value_type, decltype(npl.alpha)>::value, "type requirement");
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_cpp_value_type, decltype(npl.beta)>::value, "type requirement");
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_cpp_value_type, decltype(npl.gamma)>::value, "type requirement");
static_assert(std::is_same<decltype(std::get<0>(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement");
static_assert(std::is_same<decltype(std::get<1>(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement");
static_assert(std::is_same<decltype(std::get<2>(npl._parameter_tuple)), decltype(npl.gamma)&>::value, "type requirement");
}
// Wonderful, now take a look at the parameter list of a select
{
auto npl = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma))._parameter_list;
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_cpp_value_type, decltype(npl.alpha)>::value, "type requirement");
static_assert(std::is_same<typename decltype(t.beta)::_value_type::_cpp_value_type, decltype(npl.beta)>::value, "type requirement");
static_assert(std::is_same<typename decltype(t.gamma)::_value_type::_cpp_value_type, decltype(npl.gamma)>::value, "type requirement");
static_assert(std::is_same<decltype(std::get<0>(npl._parameter_tuple)), decltype(npl.beta)&>::value, "type requirement");
static_assert(std::is_same<decltype(std::get<1>(npl._parameter_tuple)), decltype(npl.alpha)&>::value, "type requirement");
static_assert(std::is_same<decltype(std::get<2>(npl._parameter_tuple)), decltype(npl.gamma)&>::value, "type requirement");
npl.alpha = 7;
auto x = npl;
x = npl;
std::cerr << x.alpha << std::endl;
}
return 0; return 0;
} }

View File

@ -42,6 +42,8 @@ namespace TabFoo_
struct _member_t struct _member_t
{ {
T epsilon; T epsilon;
T& operator()() { return epsilon; }
const T& operator()() const { return epsilon; }
}; };
}; };
using _value_type = sqlpp::bigint; using _value_type = sqlpp::bigint;
@ -59,6 +61,8 @@ namespace TabFoo_
struct _member_t struct _member_t
{ {
T omega; T omega;
T& operator()() { return omega; }
const T& operator()() const { return omega; }
}; };
}; };
using _value_type = sqlpp::floating_point; using _value_type = sqlpp::floating_point;
@ -102,6 +106,8 @@ namespace TabSample_
struct _member_t struct _member_t
{ {
T alpha; T alpha;
T& operator()() { return alpha; }
const T& operator()() const { return alpha; }
}; };
}; };
using _value_type = sqlpp::bigint; using _value_type = sqlpp::bigint;
@ -124,6 +130,8 @@ namespace TabSample_
struct _member_t struct _member_t
{ {
T beta; T beta;
T& operator()() { return beta; }
const T& operator()() const { return beta; }
}; };
}; };
using _value_type = sqlpp::varchar; using _value_type = sqlpp::varchar;
@ -144,6 +152,8 @@ namespace TabSample_
struct _member_t struct _member_t
{ {
T gamma; T gamma;
T& operator()() { return gamma; }
const T& operator()() const { return gamma; }
}; };
}; };
using _value_type = sqlpp::boolean; using _value_type = sqlpp::boolean;