0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Moved a bunch of things into namespace vendor

This namespace is for things the developer will not get in touch with
(normally) but the vendor might need to use for specialization of the
interpreter.

This separation is not fully completed yet, some changes will have to
follow...
This commit is contained in:
rbock 2014-01-18 15:50:16 +01:00
parent 93129be748
commit 312e735d6d
77 changed files with 2153 additions and 2095 deletions

View File

@ -30,71 +30,23 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
namespace alias
{
#define SQLPP_ALIAS_PROVIDER_GENERATOR(name) \
struct name##_t\
{\
struct _name_t\
{\
static constexpr const char* _get_name() { return #name; }\
template<typename T>\
struct _member_t\
{\
T name;\
T& operator()() { return name; }\
const T& operator()() const { return name; }\
};\
};\
};\
constexpr name##_t name = {};
SQLPP_ALIAS_PROVIDER_GENERATOR(a);
SQLPP_ALIAS_PROVIDER_GENERATOR(b);
SQLPP_ALIAS_PROVIDER_GENERATOR(c);
SQLPP_ALIAS_PROVIDER_GENERATOR(d);
SQLPP_ALIAS_PROVIDER_GENERATOR(e);
SQLPP_ALIAS_PROVIDER_GENERATOR(f);
SQLPP_ALIAS_PROVIDER_GENERATOR(g);
SQLPP_ALIAS_PROVIDER_GENERATOR(h);
SQLPP_ALIAS_PROVIDER_GENERATOR(i);
SQLPP_ALIAS_PROVIDER_GENERATOR(j);
SQLPP_ALIAS_PROVIDER_GENERATOR(k);
SQLPP_ALIAS_PROVIDER_GENERATOR(l);
SQLPP_ALIAS_PROVIDER_GENERATOR(m);
SQLPP_ALIAS_PROVIDER_GENERATOR(n);
SQLPP_ALIAS_PROVIDER_GENERATOR(o);
SQLPP_ALIAS_PROVIDER_GENERATOR(p);
SQLPP_ALIAS_PROVIDER_GENERATOR(q);
SQLPP_ALIAS_PROVIDER_GENERATOR(s);
SQLPP_ALIAS_PROVIDER_GENERATOR(t);
SQLPP_ALIAS_PROVIDER_GENERATOR(u);
SQLPP_ALIAS_PROVIDER_GENERATOR(v);
SQLPP_ALIAS_PROVIDER_GENERATOR(w);
SQLPP_ALIAS_PROVIDER_GENERATOR(x);
SQLPP_ALIAS_PROVIDER_GENERATOR(y);
SQLPP_ALIAS_PROVIDER_GENERATOR(z);
SQLPP_ALIAS_PROVIDER_GENERATOR(left);
SQLPP_ALIAS_PROVIDER_GENERATOR(right);
};
template<typename Expression, typename AliasProvider> template<typename Expression, typename AliasProvider>
struct expression_alias_t struct expression_alias_t
{
struct _value_type: Expression::_value_type
{ {
using _is_expression = std::false_type; struct _value_type: Expression::_value_type
using _is_named_expression = std::true_type; {
using _is_alias = std::true_type; using _is_expression = std::false_type;
using _is_named_expression = std::true_type;
using _is_alias = std::true_type;
};
using _name_t = typename AliasProvider::_name_t;
Expression _expression;
}; };
using _name_t = typename AliasProvider::_name_t;
Expression _expression;
};
template<typename Context, typename Expression, typename AliasProvider> template<typename Context, typename Expression, typename AliasProvider>
struct interpreter_t<Context, expression_alias_t<Expression, AliasProvider>> struct vendor::interpreter_t<Context, expression_alias_t<Expression, AliasProvider>>
{ {
using T = expression_alias_t<Expression, AliasProvider>; using T = expression_alias_t<Expression, AliasProvider>;

View File

@ -0,0 +1,82 @@
/*
* 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_ALIAS_PROVIDER_H
#define SQLPP_ALIAS_PROVIDER_H
#define SQLPP_ALIAS_PROVIDER(name) \
struct name##_t\
{\
struct _name_t\
{\
static constexpr const char* _get_name() { return #name; }\
template<typename T>\
struct _member_t\
{\
T name;\
T& operator()() { return name; }\
const T& operator()() const { return name; }\
};\
};\
};\
constexpr name##_t name = {};
namespace sqlpp
{
namespace alias
{
SQLPP_ALIAS_PROVIDER(a);
SQLPP_ALIAS_PROVIDER(b);
SQLPP_ALIAS_PROVIDER(c);
SQLPP_ALIAS_PROVIDER(d);
SQLPP_ALIAS_PROVIDER(e);
SQLPP_ALIAS_PROVIDER(f);
SQLPP_ALIAS_PROVIDER(g);
SQLPP_ALIAS_PROVIDER(h);
SQLPP_ALIAS_PROVIDER(i);
SQLPP_ALIAS_PROVIDER(j);
SQLPP_ALIAS_PROVIDER(k);
SQLPP_ALIAS_PROVIDER(l);
SQLPP_ALIAS_PROVIDER(m);
SQLPP_ALIAS_PROVIDER(n);
SQLPP_ALIAS_PROVIDER(o);
SQLPP_ALIAS_PROVIDER(p);
SQLPP_ALIAS_PROVIDER(q);
SQLPP_ALIAS_PROVIDER(s);
SQLPP_ALIAS_PROVIDER(t);
SQLPP_ALIAS_PROVIDER(u);
SQLPP_ALIAS_PROVIDER(v);
SQLPP_ALIAS_PROVIDER(w);
SQLPP_ALIAS_PROVIDER(x);
SQLPP_ALIAS_PROVIDER(y);
SQLPP_ALIAS_PROVIDER(z);
SQLPP_ALIAS_PROVIDER(left);
SQLPP_ALIAS_PROVIDER(right);
}
}
#endif

View File

@ -32,7 +32,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Select> template<typename Select>
struct any_t: public boolean::template operators<any_t<Select>> struct any_t: public boolean::template operators<any_t<Select>>
@ -76,9 +76,9 @@ namespace sqlpp
} }
template<typename Context, typename Select> template<typename Context, typename Select>
struct interpreter_t<Context, detail::any_t<Select>> struct vendor::interpreter_t<Context, vendor::any_t<Select>>
{ {
using T = detail::any_t<Select>; using T = vendor::any_t<Select>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -90,7 +90,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto any(T&& t) -> typename detail::any_t<typename operand_t<T, is_select_t>::type> auto any(T&& t) -> typename vendor::any_t<typename operand_t<T, is_select_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -1,88 +0,0 @@
/*
* 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_ASSIGNMENT_LIST_H
#define SQLPP_ASSIGNMENT_LIST_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/serializable_list.h>
namespace sqlpp
{
template<typename Database, typename... Assignments>
struct assignment_list_t
{
using _is_assignment_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Assignments...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
// check for duplicate assignments
static_assert(not detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments
using _assignment_set = typename detail::make_set_if<is_assignment_t, Assignments...>::type;
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
// check for prohibited assignments
using _prohibited_assignment_set = typename detail::make_set_if<must_not_update_t, typename Assignments::column_type...>::type;
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
template<typename Assignment>
void add(Assignment&& assignment)
{
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
static_assert(not must_not_update_t<typename std::decay<Assignment>::type::column_type>::value, "set() argument must not be updated");
_dynamic_assignments.emplace_back(std::forward<Assignment>(assignment));
}
_parameter_tuple_t _assignments;
typename detail::serializable_list<Database> _dynamic_assignments;
};
template<typename Context, typename Database, typename... Assignments>
struct interpreter_t<Context, assignment_list_t<Database, Assignments...>>
{
using T = assignment_list_t<Database, Assignments...>;
static Context& _(const T& t, Context& context)
{
context << " SET ";
interpret_tuple(t._assignments, ",", context);
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
context << ',';
interpret_serializable_list(t._dynamic_assignments, ',', context);
return context;
}
};
}
#endif

View File

@ -32,7 +32,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Expr> template<typename Expr>
struct avg_t: public floating_point::template operators<avg_t<Expr>> struct avg_t: public floating_point::template operators<avg_t<Expr>>
@ -75,9 +75,9 @@ namespace sqlpp
} }
template<typename Context, typename Expr> template<typename Context, typename Expr>
struct interpreter_t<Context, detail::avg_t<Expr>> struct vendor::interpreter_t<Context, vendor::avg_t<Expr>>
{ {
using T = detail::avg_t<Expr>; using T = vendor::avg_t<Expr>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -89,7 +89,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto avg(T&& t) -> typename detail::avg_t<typename operand_t<T, is_value_t>::type> auto avg(T&& t) -> typename vendor::avg_t<typename operand_t<T, is_value_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -27,11 +27,11 @@
#ifndef SQLPP_DETAIL_BASIC_OPERATORS_H #ifndef SQLPP_DETAIL_BASIC_OPERATORS_H
#define SQLPP_DETAIL_BASIC_OPERATORS_H #define SQLPP_DETAIL_BASIC_OPERATORS_H
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/alias.h> #include <sqlpp11/alias.h>
#include <sqlpp11/sort_order.h> #include <sqlpp11/sort_order.h>
#include <sqlpp11/in_fwd.h> #include <sqlpp11/vendor/expression_fwd.h>
#include <sqlpp11/is_null_fwd.h> #include <sqlpp11/vendor/in_fwd.h>
#include <sqlpp11/vendor/is_null_fwd.h>
namespace sqlpp namespace sqlpp
{ {
@ -39,84 +39,88 @@ namespace sqlpp
namespace detail namespace detail
{ {
struct boolean; struct boolean;
}
namespace vendor
{
// operators // operators
struct lt_ struct lt_
{ {
using _value_type = boolean; using _value_type = detail::boolean;
static constexpr const char* _name = "<"; static constexpr const char* _name = "<";
}; };
struct le_ struct le_
{ {
using _value_type = boolean; using _value_type = detail::boolean;
static constexpr const char* _name = "<="; static constexpr const char* _name = "<=";
}; };
struct ge_ struct ge_
{ {
using _value_type = boolean; using _value_type = detail::boolean;
static constexpr const char* _name = ">="; static constexpr const char* _name = ">=";
}; };
struct gt_ struct gt_
{ {
using _value_type = boolean; using _value_type = detail::boolean;
static constexpr const char* _name = ">"; static constexpr const char* _name = ">";
}; };
}
// basic operators // basic operators
template<typename Base, template<typename> class Constraint> template<typename Base, template<typename> class Constraint>
struct basic_operators struct basic_operators
{ {
template<typename T> template<typename T>
equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const vendor::equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
template<typename T> template<typename T>
not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const vendor::not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
template<typename T> template<typename T>
binary_expression_t<Base, lt_, typename Constraint<T>::type> operator<(T&& t) const vendor::binary_expression_t<Base, vendor::lt_, typename Constraint<T>::type> operator<(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
template<typename T> template<typename T>
binary_expression_t<Base, le_, typename Constraint<T>::type> operator<=(T&& t) const vendor::binary_expression_t<Base, vendor::le_, typename Constraint<T>::type> operator<=(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
template<typename T> template<typename T>
binary_expression_t<Base, ge_, typename Constraint<T>::type> operator>=(T&& t) const vendor::binary_expression_t<Base, vendor::ge_, typename Constraint<T>::type> operator>=(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
template<typename T> template<typename T>
binary_expression_t<Base, gt_, typename Constraint<T>::type> operator>(T&& t) const vendor::binary_expression_t<Base, vendor::gt_, typename Constraint<T>::type> operator>(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
is_null_t<true, Base> is_null() const vendor::is_null_t<true, Base> is_null() const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_null()"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_null()");
return { *static_cast<const Base*>(this) }; return { *static_cast<const Base*>(this) };
} }
is_null_t<false, Base> is_not_null() const vendor::is_null_t<false, Base> is_not_null() const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_not_null()"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_not_null()");
return { *static_cast<const Base*>(this) }; return { *static_cast<const Base*>(this) };
@ -136,14 +140,14 @@ namespace sqlpp
// Hint: use value_list wrapper for containers... // Hint: use value_list wrapper for containers...
template<typename... T> template<typename... T>
in_t<true, Base, typename Constraint<T>::type...> in(T&&... t) const vendor::in_t<true, Base, typename Constraint<T>::type...> in(T&&... t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with in()"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with in()");
return { *static_cast<const Base*>(this), {std::forward<T>(t)}... }; return { *static_cast<const Base*>(this), {std::forward<T>(t)}... };
} }
template<typename... T> template<typename... T>
in_t<false, Base, typename Constraint<T>::type...> not_in(T&&... t) const vendor::in_t<false, Base, typename Constraint<T>::type...> not_in(T&&... t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot with be used with not_in()"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot with be used with not_in()");
return { *static_cast<const Base*>(this), {std::forward<T>(t)}... }; return { *static_cast<const Base*>(this), {std::forward<T>(t)}... };
@ -156,7 +160,6 @@ namespace sqlpp
return { *static_cast<const Base*>(this) }; return { *static_cast<const Base*>(this) };
} }
}; };
}
} }
#endif #endif

View File

@ -28,7 +28,8 @@
#define SQLPP_BOOLEAN_H #define SQLPP_BOOLEAN_H
#include <cstdlib> #include <cstdlib>
#include <sqlpp11/detail/basic_operators.h> #include <ostream>
#include <sqlpp11/basic_operators.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/exception.h> #include <sqlpp11/exception.h>
@ -40,13 +41,13 @@ namespace sqlpp
struct or_ struct or_
{ {
using _value_type = boolean; using _value_type = boolean;
static constexpr const char* _name = "OR"; static constexpr const char* _name = " OR ";
}; };
struct and_ struct and_
{ {
using _value_type = boolean; using _value_type = boolean;
static constexpr const char* _name = "AND"; static constexpr const char* _name = " AND ";
}; };
// boolean value type // boolean value type
@ -182,20 +183,20 @@ namespace sqlpp
struct operators: public basic_operators<Base, _constraint> struct operators: public basic_operators<Base, _constraint>
{ {
template<typename T> template<typename T>
binary_expression_t<Base, and_, typename _constraint<T>::type> operator and(T&& t) const vendor::binary_expression_t<Base, and_, typename _constraint<T>::type> operator and(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, or_, typename _constraint<T>::type> operator or(T&& t) const vendor::binary_expression_t<Base, or_, typename _constraint<T>::type> operator or(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
not_t<Base> operator not() const vendor::not_t<Base> operator not() const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be as operand for operator not"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be as operand for operator not");
return { *static_cast<const Base*>(this) }; return { *static_cast<const Base*>(this) };

View File

@ -27,14 +27,13 @@
#ifndef SQLPP_COLUMN_H #ifndef SQLPP_COLUMN_H
#define SQLPP_COLUMN_H #define SQLPP_COLUMN_H
#include <ostream>
#include <sqlpp11/column_fwd.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/alias.h> #include <sqlpp11/alias.h>
#include <sqlpp11/detail/wrong.h> #include <sqlpp11/column_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/sort_order.h> #include <sqlpp11/sort_order.h>
#include <sqlpp11/interpreter.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/vendor/interpreter.h>
#include <sqlpp11/vendor/expression.h>
#include <sqlpp11/detail/wrong.h>
namespace sqlpp namespace sqlpp
{ {
@ -73,14 +72,14 @@ namespace sqlpp
template<typename T> template<typename T>
auto operator =(T&& t) const auto operator =(T&& t) const
-> typename std::enable_if<not std::is_same<column_t, typename std::decay<T>::type>::value, -> typename std::enable_if<not std::is_same<column_t, typename std::decay<T>::type>::value,
assignment_t<column_t, typename _value_type::template _constraint<T>::type>>::type vendor::assignment_t<column_t, typename _value_type::template _constraint<T>::type>>::type
{ {
return { *this, {std::forward<T>(t)} }; return { *this, {std::forward<T>(t)} };
} }
}; };
template<typename Context, typename... Args> template<typename Context, typename... Args>
struct interpreter_t<Context, column_t<Args...>> struct vendor::interpreter_t<Context, column_t<Args...>>
{ {
using T = column_t<Args...>; using T = column_t<Args...>;

View File

@ -32,14 +32,14 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Expr> template<typename Expr>
struct count_t: public integral::template operators<count_t<Expr>> struct count_t: public sqlpp::detail::integral::template operators<count_t<Expr>>
{ {
static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument"); static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument");
struct _value_type: public integral struct _value_type: public sqlpp::detail::integral
{ {
using _is_named_expression = std::true_type; using _is_named_expression = std::true_type;
}; };
@ -75,9 +75,9 @@ namespace sqlpp
} }
template<typename Context, typename Expr> template<typename Context, typename Expr>
struct interpreter_t<Context, detail::count_t<Expr>> struct vendor::interpreter_t<Context, vendor::count_t<Expr>>
{ {
using T = detail::count_t<Expr>; using T = vendor::count_t<Expr>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -89,7 +89,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto count(T&& t) -> typename detail::count_t<typename operand_t<T, is_value_t>::type> auto count(T&& t) -> typename vendor::count_t<typename operand_t<T, is_value_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -1,166 +0,0 @@
/*
* 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_DETAIL_WRAP_OPERAND_H
#define SQLPP_DETAIL_WRAP_OPERAND_H
#include <sqlpp11/interpreter.h>
// FIXME: must leave detail, since it is interpreted (and might require specializations)
namespace sqlpp
{
namespace detail
{
struct boolean;
struct integral;
struct floating_point;
struct text;
}
struct boolean_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::boolean;
bool _is_trivial() const { return _t == false; }
bool _t;
};
template<typename Context>
struct interpreter_t<Context, boolean_operand>
{
using Operand = boolean_operand;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
template<typename T>
struct integral_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::integral;
bool _is_trivial() const { return _t == 0; }
T _t;
};
template<typename Context, typename T>
struct interpreter_t<Context, integral_operand<T>>
{
using Operand = integral_operand<T>;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
template<typename T>
struct floating_point_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::floating_point;
bool _is_trivial() const { return _t == 0; }
T _t;
};
template<typename Context, typename T>
struct interpreter_t<Context, floating_point_operand<T>>
{
using Operand = floating_point_operand<T>;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
struct text_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::text;
bool _is_trivial() const { return _t.empty(); }
std::string _t;
};
template<typename Context>
struct interpreter_t<Context, text_operand>
{
using Operand = text_operand;
static Context& _(const Operand& t, Context& context)
{
context << '\'' << context.escape(t._t) << '\'';
return context;
}
};
template<typename T, typename Enable = void>
struct wrap_operand
{
using type = T;
};
template<>
struct wrap_operand<bool, void>
{
using type = boolean_operand;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
using type = integral_operand<T>;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
{
using type = floating_point_operand<T>;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
{
using type = text_operand;
};
}
#endif

View File

@ -31,7 +31,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Select> template<typename Select>
struct exists_t: public boolean::template operators<exists_t<Select>> struct exists_t: public boolean::template operators<exists_t<Select>>
@ -74,9 +74,9 @@ namespace sqlpp
} }
template<typename Context, typename Select> template<typename Context, typename Select>
struct interpreter_t<Context, detail::exists_t<Select>> struct vendor::interpreter_t<Context, vendor::exists_t<Select>>
{ {
using T = detail::exists_t<Select>; using T = vendor::exists_t<Select>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -89,7 +89,7 @@ namespace sqlpp
template<typename T> template<typename T>
auto exists(T&& t) -> typename detail::exists_t<typename operand_t<T, is_select_t>::type> auto exists(T&& t) -> typename vendor::exists_t<typename operand_t<T, is_select_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -1,243 +0,0 @@
/*
* 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_EXPRESSION_H
#define SQLPP_EXPRESSION_H
#include <sqlpp11/alias.h>
#include <sqlpp11/boolean.h>
#include <sqlpp11/noop.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/tvin.h>
#include <sqlpp11/interpreter.h>
#include <sqlpp11/detail/wrap_operand.h>
#include <sqlpp11/detail/serialize_tuple.h>
namespace sqlpp
{
template<typename Lhs, typename Rhs>
struct assignment_t
{
using _is_assignment = std::true_type;
using column_type = Lhs;
using value_type = tvin_wrap_t<Rhs>;
// FIXME: Need parameter_tuple back
assignment_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
assignment_t(const assignment_t&) = default;
assignment_t(assignment_t&&) = default;
assignment_t& operator=(const assignment_t&) = default;
assignment_t& operator=(assignment_t&&) = default;
~assignment_t() = default;
Lhs _lhs;
tvin_wrap_t<Rhs> _rhs;
};
template<typename Context, typename Lhs, typename Rhs>
struct interpreter_t<Context, assignment_t<Lhs, Rhs>>
{
using T = assignment_t<Lhs, Rhs>;
static Context& _(const T& t, Context& context)
{
interpret(t._lhs, context);
if (t._rhs._is_trivial())
{
context << "=NULL";
}
else
{
context << "=";
interpret(t._rhs, context);
}
return context;
}
};
template<typename Lhs, typename Rhs>
struct equal_t: public detail::boolean::template operators<equal_t<Lhs, Rhs>>
{
using _value_type = detail::boolean;
equal_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
equal_t(const equal_t&) = default;
equal_t(equal_t&&) = default;
equal_t& operator=(const equal_t&) = default;
equal_t& operator=(equal_t&&) = default;
~equal_t() = default;
Lhs _lhs;
tvin_wrap_t<Rhs> _rhs;
};
template<typename Context, typename Lhs, typename Rhs>
struct interpreter_t<Context, equal_t<Lhs, Rhs>>
{
using T = equal_t<Lhs, Rhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
interpret(t._lhs, context);
if (t._rhs._is_trivial())
{
context << " IS NULL";
}
else
{
context << "=";
interpret(t._rhs, context);
}
context << ")";
return context;
}
};
template<typename Lhs, typename Rhs>
struct not_equal_t: public detail::boolean::template operators<not_equal_t<Lhs, Rhs>>
{
using _value_type = detail::boolean;
not_equal_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
not_equal_t(const not_equal_t&) = default;
not_equal_t(not_equal_t&&) = default;
not_equal_t& operator=(const not_equal_t&) = default;
not_equal_t& operator=(not_equal_t&&) = default;
~not_equal_t() = default;
Lhs _lhs;
tvin_wrap_t<Rhs> _rhs;
};
template<typename Context, typename Lhs, typename Rhs>
struct interpreter_t<Context, not_equal_t<Lhs, Rhs>>
{
using T = not_equal_t<Lhs, Rhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
interpret(t._lhs, context);
if (t._rhs._is_trivial())
{
context << " IS NOT NULL";
}
else
{
context << "!=";
interpret(t._rhs, context);
}
context << ")";
return context;
}
};
template<typename Lhs>
struct not_t: public detail::boolean::template operators<not_t<Lhs>>
{
using _value_type = detail::boolean;
not_t(Lhs l):
_lhs(l)
{}
not_t(const not_t&) = default;
not_t(not_t&&) = default;
not_t& operator=(const not_t&) = default;
not_t& operator=(not_t&&) = default;
~not_t() = default;
Lhs _lhs;
};
template<typename Context, typename Lhs>
struct interpreter_t<Context, not_t<Lhs>>
{
using T = not_t<Lhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
context << "NOT ";
interpret(t._lhs, context);
context << ")";
return context;
}
};
template<typename Lhs, typename O, typename Rhs>
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
{
using _value_type = typename O::_value_type;
binary_expression_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
binary_expression_t(const binary_expression_t&) = default;
binary_expression_t(binary_expression_t&&) = default;
binary_expression_t& operator=(const binary_expression_t&) = default;
binary_expression_t& operator=(binary_expression_t&&) = default;
~binary_expression_t() = default;
Lhs _lhs;
Rhs _rhs;
};
template<typename Context, typename Lhs, typename O, typename Rhs>
struct interpreter_t<Context, binary_expression_t<Lhs, O, Rhs>>
{
using T = binary_expression_t<Lhs, O, Rhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
interpret(t._lhs, context);
context << O::_name;
interpret(t._rhs, context);
context << ")";
return context;
}
};
}
#endif

View File

@ -28,9 +28,8 @@
#define SQLPP_FLOATING_POINT_H #define SQLPP_FLOATING_POINT_H
#include <cstdlib> #include <cstdlib>
#include <sqlpp11/detail/basic_operators.h> #include <sqlpp11/basic_operators.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/char_result_row.h> // FIXME: Need to update floating_point
#include <sqlpp11/exception.h> #include <sqlpp11/exception.h>
namespace sqlpp namespace sqlpp
@ -193,28 +192,28 @@ namespace sqlpp
struct operators: public basic_operators<Base, _constraint> struct operators: public basic_operators<Base, _constraint>
{ {
template<typename T> template<typename T>
binary_expression_t<Base, plus_, typename _constraint<T>::type> operator +(T&& t) const vendor::binary_expression_t<Base, plus_, typename _constraint<T>::type> operator +(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, minus_, typename _constraint<T>::type> operator -(T&& t) const vendor::binary_expression_t<Base, minus_, typename _constraint<T>::type> operator -(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, multiplies_, typename _constraint<T>::type> operator *(T&& t) const vendor::binary_expression_t<Base, multiplies_, typename _constraint<T>::type> operator *(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const vendor::binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };

View File

@ -1,88 +0,0 @@
/*
* 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_FROM_H
#define SQLPP_FROM_H
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/serializable_list.h>
#include <sqlpp11/detail/serialize_tuple.h>
namespace sqlpp
{
template<typename Database, typename... TableOrJoin>
struct from_t
{
using _is_from = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
// ensure one argument at least
static_assert(_is_dynamic::value or sizeof...(TableOrJoin), "at least one table or join argument required in from()");
// check for duplicate arguments
static_assert(not detail::has_duplicates<TableOrJoin...>::value, "at least one duplicate argument detected in from()");
// check for invalid arguments
using _valid_expressions = typename detail::make_set_if<is_table_t, TableOrJoin...>::type;
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
template<typename Table>
void add(Table&& table)
{
static_assert(is_table_t<typename std::decay<Table>::type>::value, "from arguments require to be tables or joins");
_dynamic_tables.emplace_back(std::forward<Table>(table));
}
std::tuple<TableOrJoin...> _tables;
detail::serializable_list<Database> _dynamic_tables;
};
template<typename Context, typename Database, typename... TableOrJoin>
struct interpreter_t<Context, from_t<Database, TableOrJoin...>>
{
using T = from_t<Database, TableOrJoin...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(TableOrJoin) == 0 and t._dynamic_tables.empty())
return context;
context << " FROM ";
interpret_tuple(t._tables, ',', context);
if (sizeof...(TableOrJoin) and not t._dynamic_tables.empty())
context << ',';
interpret_serializable_list(t._dynamic_tables, ',', context);
return context;
}
};
}
#endif

View File

@ -30,8 +30,8 @@
#include <sqlpp11/parameter.h> #include <sqlpp11/parameter.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
#include <sqlpp11/column_types.h> #include <sqlpp11/column_types.h>
#include <sqlpp11/in.h> #include <sqlpp11/vendor/in.h>
#include <sqlpp11/is_null.h> #include <sqlpp11/vendor/is_null.h>
#include <sqlpp11/exists.h> #include <sqlpp11/exists.h>
#include <sqlpp11/any.h> #include <sqlpp11/any.h>
#include <sqlpp11/some.h> #include <sqlpp11/some.h>
@ -40,7 +40,7 @@
#include <sqlpp11/max.h> #include <sqlpp11/max.h>
#include <sqlpp11/avg.h> #include <sqlpp11/avg.h>
#include <sqlpp11/sum.h> #include <sqlpp11/sum.h>
#include <sqlpp11/verbatim_table.h> #include <sqlpp11/verbatim_table.h> // Csaba Csoma suggests: unsafe_sql instead of verbatim
namespace sqlpp namespace sqlpp
{ {
@ -51,7 +51,7 @@ namespace sqlpp
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }
template<typename ValueType> template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>> struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>>
{ {
using _value_type = ValueType; using _value_type = ValueType;
@ -68,7 +68,7 @@ namespace sqlpp
}; };
template<typename Context, typename ValueType> template<typename Context, typename ValueType>
struct interpreter_t<Context, verbatim_t<ValueType>> struct vendor::interpreter_t<Context, verbatim_t<ValueType>>
{ {
using T = verbatim_t<ValueType>; using T = verbatim_t<ValueType>;
@ -104,7 +104,7 @@ namespace sqlpp
}; };
template<typename Context, typename Container> template<typename Context, typename Container>
struct interpreter_t<Context, value_list_t<Container>> struct vendor::interpreter_t<Context, value_list_t<Container>>
{ {
using T = value_list_t<Container>; using T = value_list_t<Container>;

View File

@ -1,90 +0,0 @@
/*
* 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_GROUP_BY_H
#define SQLPP_GROUP_BY_H
#include <ostream>
#include <tuple>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/serializable_list.h>
namespace sqlpp
{
template<typename Database, typename... Expr>
struct group_by_t
{
using _is_group_by = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
// ensure one argument at least
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
// check for duplicate expressions
static_assert(not detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
// check for invalid expressions
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()");
template<typename E>
void add(E&& expr)
{
static_assert(is_table_t<typename std::decay<E>::type>::value, "from arguments require to be tables or joins");
_dynamic_expressions.emplace_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
detail::serializable_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, group_by_t<Database, Expr...>>
{
using T = group_by_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context;
context << " GROUP BY ";
interpret_tuple(t._expressions, ',', context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << ',';
interpret_serializable_list(t._dynamic_expressions, ',', context);
return context;
}
};
}
#endif

View File

@ -27,37 +27,28 @@
#ifndef SQLPP_INSERT_H #ifndef SQLPP_INSERT_H
#define SQLPP_INSERT_H #define SQLPP_INSERT_H
#include <sstream>
#include <sqlpp11/noop.h>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/insert_list.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_insert.h> #include <sqlpp11/prepared_insert.h>
#include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/insert_list.h>
#include <sqlpp11/parameter_list.h>
namespace sqlpp namespace sqlpp
{ {
template< template<
typename Database = void, typename Database = void,
typename Table = noop, typename Table = vendor::noop,
typename InsertList = noop typename InsertList = vendor::noop
>
struct insert_t;
template<
typename Database,
typename Table,
typename InsertList
> >
struct insert_t struct insert_t
{ {
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument"); static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
static_assert(is_noop<InsertList>::value or is_insert_list_t<InsertList>::value, "invalid 'InsertList' argument"); static_assert(vendor::is_noop<InsertList>::value or is_insert_list_t<InsertList>::value, "invalid 'InsertList' argument");
template<typename AssignmentT> template<typename AssignmentT>
using set_insert_list_t = insert_t<Database, Table, AssignmentT>; using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
using use_default_values_t = insert_t<Database, Table, insert_default_values_t>; using use_default_values_t = insert_t<Database, Table, vendor::insert_default_values_t>;
using _parameter_tuple_t = std::tuple<Table, InsertList>; using _parameter_tuple_t = std::tuple<Table, InsertList>;
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type; using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
@ -65,7 +56,7 @@ namespace sqlpp
auto default_values() auto default_values()
-> use_default_values_t -> use_default_values_t
{ {
static_assert(std::is_same<InsertList, noop>::value, "cannot call default_values() after set() or default_values()"); static_assert(std::is_same<InsertList, vendor::noop>::value, "cannot call default_values() after set() or default_values()");
// FIXME: Need to check if all required columns are set // FIXME: Need to check if all required columns are set
return { return {
_table, _table,
@ -75,24 +66,24 @@ namespace sqlpp
template<typename... Assignment> template<typename... Assignment>
auto set(Assignment&&... assignment) auto set(Assignment&&... assignment)
-> set_insert_list_t<insert_list_t<void, typename std::decay<Assignment>::type...>> -> set_insert_list_t<vendor::insert_list_t<void, typename std::decay<Assignment>::type...>>
{ {
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()"); static_assert(std::is_same<InsertList, vendor::noop>::value, "cannot call set() after set() or default_values()");
// FIXME: Need to check if all required columns are set // FIXME: Need to check if all required columns are set
return { return {
_table, _table,
insert_list_t<void, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}, vendor::insert_list_t<void, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
}; };
} }
template<typename... Assignment> template<typename... Assignment>
auto dynamic_set(Assignment&&... assignment) auto dynamic_set(Assignment&&... assignment)
-> set_insert_list_t<insert_list_t<Database, typename std::decay<Assignment>::type...>> -> set_insert_list_t<vendor::insert_list_t<Database, typename std::decay<Assignment>::type...>>
{ {
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()"); static_assert(std::is_same<InsertList, vendor::noop>::value, "cannot call set() after set() or default_values()");
return { return {
_table, _table,
insert_list_t<Database, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}, vendor::insert_list_t<Database, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
}; };
} }
@ -120,7 +111,7 @@ namespace sqlpp
std::size_t run(Db& db) const std::size_t run(Db& db) const
{ {
// FIXME: check if set or default_values() has ben called // FIXME: check if set or default_values() has ben called
constexpr bool calledSet = not is_noop<InsertList>::value; constexpr bool calledSet = not vendor::is_noop<InsertList>::value;
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0; constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
static_assert(calledSet or not requireSet, "calling set() required for given table"); static_assert(calledSet or not requireSet, "calling set() required for given table");
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead"); static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
@ -131,7 +122,7 @@ namespace sqlpp
auto prepare(Db& db) const auto prepare(Db& db) const
-> prepared_insert_t<typename std::decay<Db>::type, insert_t> -> prepared_insert_t<typename std::decay<Db>::type, insert_t>
{ {
constexpr bool calledSet = not is_noop<InsertList>::value; constexpr bool calledSet = not vendor::is_noop<InsertList>::value;
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0; constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
static_assert(calledSet or not requireSet, "calling set() required for given table"); static_assert(calledSet or not requireSet, "calling set() required for given table");
@ -143,7 +134,7 @@ namespace sqlpp
}; };
template<typename Context, typename Database, typename Table, typename InsertList> template<typename Context, typename Database, typename Table, typename InsertList>
struct interpreter_t<Context, insert_t<Database, Table, InsertList>> struct vendor::interpreter_t<Context, insert_t<Database, Table, InsertList>>
{ {
using T = insert_t<Database, Table, InsertList>; using T = insert_t<Database, Table, InsertList>;

View File

@ -1,154 +0,0 @@
/*
* 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_INSERT_LIST_H
#define SQLPP_INSERT_LIST_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/serializable_list.h>
namespace sqlpp
{
struct insert_default_values_t
{
using _is_insert_list = std::true_type;
using _is_dynamic = std::false_type;
};
template<typename Context>
struct interpreter_t<Context, insert_default_values_t>
{
using T = insert_default_values_t;
static Context& _(const T& t, Context& context)
{
context << " DEFAULT VALUES";
return context;
}
};
template<typename Column>
struct insert_column_t
{
Column _column;
};
template<typename Context, typename Column>
struct interpreter_t<Context, insert_column_t<Column>>
{
using T = insert_column_t<Column>;
static Context& _(const T& t, Context& context)
{
context << t._column._get_name();
return context;
}
};
template<typename Database, typename... Assignments>
struct insert_list_t
{
using _is_insert_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<typename Assignments::value_type...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
// check for duplicate assignments
static_assert(not detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments
using _assignment_set = typename detail::make_set_if<is_assignment_t, Assignments...>::type;
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
// check for prohibited assignments
using _prohibited_assignment_set = typename detail::make_set_if<must_not_insert_t, typename Assignments::column_type...>::type;
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
insert_list_t(Assignments... assignment):
_columns({assignment._lhs}...),
_values(assignment._rhs...)
{}
insert_list_t(const insert_list_t&) = default;
insert_list_t(insert_list_t&&) = default;
insert_list_t& operator=(const insert_list_t&) = default;
insert_list_t& operator=(insert_list_t&&) = default;
~insert_list_t() = default;
template<typename Assignment>
void add(Assignment&& assignment)
{
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
static_assert(not must_not_insert_t<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
_dynamic_columns.emplace_back(insert_column_t<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
}
std::tuple<insert_column_t<typename Assignments::column_type>...> _columns;
_parameter_tuple_t _values;
typename detail::serializable_list<Database> _dynamic_columns;
typename detail::serializable_list<Database> _dynamic_values;
};
template<typename Context, typename Database, typename... Assignments>
struct interpreter_t<Context, insert_list_t<Database, Assignments...>>
{
using T = insert_list_t<Database, Assignments...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
{
interpret(insert_default_values_t(), context);
}
else
{
context << " (";
interpret_tuple(t._columns, ",", context);
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
context << ',';
interpret_serializable_list(t._dynamic_columns, ',', context);
context << ") VALUES(";
interpret_tuple(t._values, ",", context);
if (sizeof...(Assignments) and not t._dynamic_values.empty())
context << ',';
interpret_serializable_list(t._dynamic_values, ',', context);
context << ")";
}
return context;
}
};
}
#endif

View File

@ -28,7 +28,7 @@
#define SQLPP_INTEGRAL_H #define SQLPP_INTEGRAL_H
#include <cstdlib> #include <cstdlib>
#include <sqlpp11/detail/basic_operators.h> #include <sqlpp11/basic_operators.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/exception.h> #include <sqlpp11/exception.h>
@ -168,21 +168,21 @@ namespace sqlpp
template<typename T> template<typename T>
struct plus_ struct plus_
{ {
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type; using _value_type = typename vendor::wrap_operand<typename std::decay<T>::type>::type::_value_type;
static constexpr const char* _name = "+"; static constexpr const char* _name = "+";
}; };
template<typename T> template<typename T>
struct minus_ struct minus_
{ {
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type; using _value_type = typename vendor::wrap_operand<typename std::decay<T>::type>::type::_value_type;
static constexpr const char* _name = "-"; static constexpr const char* _name = "-";
}; };
template<typename T> template<typename T>
struct multiplies_ struct multiplies_
{ {
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type; using _value_type = typename vendor::wrap_operand<typename std::decay<T>::type>::type::_value_type;
static constexpr const char* _name = "*"; static constexpr const char* _name = "*";
}; };
@ -199,28 +199,28 @@ namespace sqlpp
struct operators: public basic_operators<Base, _constraint> struct operators: public basic_operators<Base, _constraint>
{ {
template<typename T> template<typename T>
binary_expression_t<Base, plus_<T>, typename _constraint<T>::type> operator +(T&& t) const vendor::binary_expression_t<Base, plus_<T>, typename _constraint<T>::type> operator +(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, minus_<T>, typename _constraint<T>::type> operator -(T&& t) const vendor::binary_expression_t<Base, minus_<T>, typename _constraint<T>::type> operator -(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, multiplies_<T>, typename _constraint<T>::type> operator *(T&& t) const vendor::binary_expression_t<Base, multiplies_<T>, typename _constraint<T>::type> operator *(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };
} }
template<typename T> template<typename T>
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const vendor::binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), std::forward<T>(t) }; return { *static_cast<const Base*>(this), std::forward<T>(t) };

View File

@ -24,28 +24,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_INTERPRETER_H #ifndef SQLPP_INTERPRET_H
#define SQLPP_INTERPRETER_H #define SQLPP_INTERPRET_H
#include <type_traits> #include <sqlpp11/vendor/interpreter.h>
#include <sqlpp11/detail/wrong.h>
namespace sqlpp namespace sqlpp
{ {
template<typename Context, typename T, typename Enable = void>
struct interpreter_t
{
static void _(const T& t, Context& context)
{
static_assert(detail::wrong<Context, T>::value, "missing interpreter specialization");
}
};
template<typename T, typename Context> template<typename T, typename Context>
auto interpret(const T& t, Context& context) auto interpret(const T& t, Context& context)
-> decltype(interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context)) -> decltype(vendor::interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context))
{ {
return interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context); return vendor::interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context);
} }
} }

View File

@ -29,6 +29,7 @@
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/on.h> #include <sqlpp11/on.h>
#include <sqlpp11/vendor/noop.h>
namespace sqlpp namespace sqlpp
{ {
@ -73,84 +74,84 @@ namespace sqlpp
static constexpr const char* _name = " RIGHT OUTER "; static constexpr const char* _name = " RIGHT OUTER ";
}; };
template<typename JoinType, typename Lhs, typename Rhs, typename On = noop> template<typename JoinType, typename Lhs, typename Rhs, typename On = vendor::noop>
struct join_t struct join_t
{ {
static_assert(is_table_t<Lhs>::value, "invalid lhs argument for join()"); static_assert(is_table_t<Lhs>::value, "invalid lhs argument for join()");
static_assert(is_table_t<Rhs>::value, "invalid rhs argument for join()"); static_assert(is_table_t<Rhs>::value, "invalid rhs argument for join()");
static_assert(is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()"); static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
static_assert(Lhs::_table_set::template is_disjunct_from<typename Rhs::_table_set>::value, "joined tables must not be identical"); static_assert(Lhs::_table_set::template is_disjunct_from<typename Rhs::_table_set>::value, "joined tables must not be identical");
using _is_table = std::true_type; using _is_table = std::true_type;
using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type; using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type;
template<typename OnT> template<typename OnT>
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>; using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
template<typename... Expr> template<typename... Expr>
auto on(Expr&&... expr) auto on(Expr&&... expr)
-> set_on_t<on_t<void, typename std::decay<Expr>::type...>> -> set_on_t<on_t<void, typename std::decay<Expr>::type...>>
{ {
static_assert(is_noop<On>::value, "cannot call on() twice for a single join()"); static_assert(vendor::is_noop<On>::value, "cannot call on() twice for a single join()");
return { _lhs, return { _lhs,
_rhs, _rhs,
{std::tuple<typename std::decay<Expr>::type...>{std::forward<Expr>(expr)...}} {std::tuple<typename std::decay<Expr>::type...>{std::forward<Expr>(expr)...}}
}; };
} }
template<typename T> template<typename T>
join_t<inner_join_t, join_t, typename std::decay<T>::type> join(T&& t) join_t<inner_join_t, join_t, typename std::decay<T>::type> join(T&& t)
{ {
static_assert(not is_noop<On>::value, "join type requires on()"); static_assert(not vendor::is_noop<On>::value, "join type requires on()");
return { *this, std::forward<T>(t) }; return { *this, std::forward<T>(t) };
} }
template<typename T> template<typename T>
join_t<inner_join_t, join_t, typename std::decay<T>::type> inner_join(T&& t) join_t<inner_join_t, join_t, typename std::decay<T>::type> inner_join(T&& t)
{ {
static_assert(not is_noop<On>::value, "join type requires on()"); static_assert(not vendor::is_noop<On>::value, "join type requires on()");
return { *this, std::forward<T>(t) }; return { *this, std::forward<T>(t) };
} }
template<typename T> template<typename T>
join_t<outer_join_t, join_t, typename std::decay<T>::type> outer_join(T&& t) join_t<outer_join_t, join_t, typename std::decay<T>::type> outer_join(T&& t)
{ {
static_assert(not is_noop<On>::value, "join type requires on()"); static_assert(not vendor::is_noop<On>::value, "join type requires on()");
return { *this, std::forward<T>(t) }; return { *this, std::forward<T>(t) };
} }
template<typename T> template<typename T>
join_t<left_outer_join_t, join_t, typename std::decay<T>::type> left_outer_join(T&& t) join_t<left_outer_join_t, join_t, typename std::decay<T>::type> left_outer_join(T&& t)
{ {
static_assert(not is_noop<On>::value, "join type requires on()"); static_assert(not vendor::is_noop<On>::value, "join type requires on()");
return { *this, std::forward<T>(t) }; return { *this, std::forward<T>(t) };
} }
template<typename T> template<typename T>
join_t<right_outer_join_t, join_t, typename std::decay<T>::type> right_outer_join(T&& t) join_t<right_outer_join_t, join_t, typename std::decay<T>::type> right_outer_join(T&& t)
{ {
static_assert(not is_noop<On>::value, "join type requires on()"); static_assert(not vendor::is_noop<On>::value, "join type requires on()");
return { *this, std::forward<T>(t) }; return { *this, std::forward<T>(t) };
} }
Lhs _lhs; Lhs _lhs;
Rhs _rhs; Rhs _rhs;
On _on; On _on;
}; };
// FIXME: Need to check if db supports the join type. e.g. sqlite does not support right outer or full outer join // FIXME: Need to check if db supports the join type. e.g. sqlite does not support right outer or full outer join
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On> template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
struct interpreter_t<Context, join_t<JoinType, Lhs, Rhs, On>> struct vendor::interpreter_t<Context, join_t<JoinType, Lhs, Rhs, On>>
{ {
using T = join_t<JoinType, Lhs, Rhs, On>; using T = join_t<JoinType, Lhs, Rhs, On>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
static_assert(not is_noop<On>::value, "joined tables require on()"); static_assert(not vendor::is_noop<On>::value, "joined tables require on()");
interpret(t._lhs, context); interpret(t._lhs, context);
context << JoinType::_name; context << JoinType::_name;
context << " JOIN "; context << " JOIN ";
context << "("; context << "(";
interpret(t._rhs, context); interpret(t._rhs, context);
interpret(t._on, context); interpret(t._on, context);

View File

@ -32,7 +32,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Expr> template<typename Expr>
struct max_t: public boolean::template operators<max_t<Expr>> struct max_t: public boolean::template operators<max_t<Expr>>
@ -75,9 +75,9 @@ namespace sqlpp
} }
template<typename Context, typename Expr> template<typename Context, typename Expr>
struct interpreter_t<Context, detail::max_t<Expr>> struct vendor::interpreter_t<Context, vendor::max_t<Expr>>
{ {
using T = detail::max_t<Expr>; using T = vendor::max_t<Expr>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -89,7 +89,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto max(T&& t) -> typename detail::max_t<typename operand_t<T, is_value_t>::type> auto max(T&& t) -> typename vendor::max_t<typename operand_t<T, is_value_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -32,7 +32,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Expr> template<typename Expr>
struct min_t: public boolean::template operators<min_t<Expr>> struct min_t: public boolean::template operators<min_t<Expr>>
@ -75,9 +75,9 @@ namespace sqlpp
} }
template<typename Context, typename Expr> template<typename Context, typename Expr>
struct interpreter_t<Context, detail::min_t<Expr>> struct vendor::interpreter_t<Context, vendor::min_t<Expr>>
{ {
using T = detail::min_t<Expr>; using T = vendor::min_t<Expr>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -89,7 +89,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto min(T&& t) -> typename detail::min_t<typename operand_t<T, is_value_t>::type> auto min(T&& t) -> typename vendor::min_t<typename operand_t<T, is_value_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -56,7 +56,7 @@ namespace sqlpp
}; };
template<typename Context, typename AliasProvider, typename... NamedExpr> template<typename Context, typename AliasProvider, typename... NamedExpr>
struct interpreter_t<Context, multi_column_t<AliasProvider, NamedExpr...>> struct vendor::interpreter_t<Context, multi_column_t<AliasProvider, NamedExpr...>>
{ {
using T = multi_column_t<AliasProvider, NamedExpr...>; using T = multi_column_t<AliasProvider, NamedExpr...>;

View File

@ -31,7 +31,6 @@
namespace sqlpp namespace sqlpp
{ {
// boolean value type
struct no_value_t struct no_value_t
{ {
template<typename T> template<typename T>

View File

@ -27,10 +27,9 @@
#ifndef SQLPP_ON_H #ifndef SQLPP_ON_H
#define SQLPP_ON_H #define SQLPP_ON_H
#include <ostream>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/serialize_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/serializable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
namespace sqlpp namespace sqlpp
{ {
@ -52,24 +51,24 @@ namespace sqlpp
} }
std::tuple<Expr...> _expressions; std::tuple<Expr...> _expressions;
detail::serializable_list<Database> _dynamic_expressions; vendor::interpretable_list_t<Database> _dynamic_expressions;
}; };
template<typename Context, typename Database, typename... Expr> template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, on_t<Database, Expr...>> struct vendor::interpreter_t<Context, on_t<Database, Expr...>>
{ {
using T = on_t<Database, Expr...>; using T = on_t<Database, Expr...>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context;
context << " ON ";
interpret_tuple(t._expressions, " AND ", context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << " AND ";
interpret_serializable_list(t._dynamic_expressions, " AND ", context);
return context; return context;
context << " ON ";
interpret_tuple(t._expressions, " AND ", context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << " AND ";
interpret_list(t._dynamic_expressions, " AND ", context);
return context;
} }
}; };

View File

@ -1,88 +0,0 @@
/*
* 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_ORDER_BY_H
#define SQLPP_ORDER_BY_H
#include <tuple>
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/serializable.h>
namespace sqlpp
{
template<typename Database,typename... Expr>
struct order_by_t
{
using _is_order_by = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
// check for duplicate order expressions
static_assert(not detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()");
// check for invalid order expressions
using _valid_expressions = typename detail::make_set_if<is_sort_order_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()");
template<typename E>
void add(E&& expr)
{
static_assert(is_sort_order_t<typename std::decay<E>::type>::value, "order_by arguments require to be sort-order expressions");
_dynamic_expressions.push_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
detail::serializable_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, order_by_t<Database, Expr...>>
{
using T = order_by_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context;
context << " ORDER BY ";
interpret_tuple(t._expressions, ',', context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << ',';
interpret_serializable_list(t._dynamic_expressions, ',', context);
return context;
}
};
}
#endif

View File

@ -27,8 +27,6 @@
#ifndef SQLPP_PARAMETER_H #ifndef SQLPP_PARAMETER_H
#define SQLPP_PARAMETER_H #define SQLPP_PARAMETER_H
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
@ -52,7 +50,7 @@ namespace sqlpp
}; };
template<typename Context, typename ValueType, typename NameType> template<typename Context, typename ValueType, typename NameType>
struct interpreter_t<Context, parameter_t<ValueType, NameType>> struct vendor::interpreter_t<Context, parameter_t<ValueType, NameType>>
{ {
using T = parameter_t<ValueType, NameType>; using T = parameter_t<ValueType, NameType>;

View File

@ -32,25 +32,6 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail
{
template<typename... T>
struct or_t;
template<typename T, typename... Rest>
struct or_t<T, Rest...>
{
static constexpr bool value = T::value or or_t<Rest...>::value;
};
template<>
struct or_t<>
{
static constexpr bool value = false;
};
}
template<typename T> template<typename T>
struct parameter_list_t struct parameter_list_t
{ {

View File

@ -27,21 +27,20 @@
#ifndef SQLPP_REMOVE_H #ifndef SQLPP_REMOVE_H
#define SQLPP_REMOVE_H #define SQLPP_REMOVE_H
#include <sstream>
#include <sqlpp11/noop.h>
#include <sqlpp11/using.h>
#include <sqlpp11/where.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_remove.h> #include <sqlpp11/prepared_remove.h>
#include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/using.h>
#include <sqlpp11/vendor/where.h>
namespace sqlpp namespace sqlpp
{ {
template< template<
typename Database, typename Database,
typename Table, typename Table,
typename Using = noop, typename Using = vendor::noop,
typename Where = noop typename Where = vendor::noop
> >
struct remove_t; struct remove_t;
@ -53,9 +52,9 @@ namespace sqlpp
> >
struct remove_t struct remove_t
{ {
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument"); static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
static_assert(is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument"); static_assert(vendor::is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument");
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument"); static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
// FIXME: We might want to have everywhere() or all() to indicate that everything is to be removed, same with update and select // FIXME: We might want to have everywhere() or all() to indicate that everything is to be removed, same with update and select
@ -70,10 +69,10 @@ namespace sqlpp
template<typename... Tab> template<typename... Tab>
auto using_(Tab&&... tab) auto using_(Tab&&... tab)
-> set_using_t<using_t<void, typename std::decay<Tab>::type...>> -> set_using_t<vendor::using_t<void, typename std::decay<Tab>::type...>>
{ {
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice"); static_assert(vendor::is_noop<Using>::value, "cannot call using() twice");
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()"); static_assert(vendor::is_noop<Where>::value, "cannot call using() after where()");
return { return {
_table, _table,
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}}, {std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
@ -83,10 +82,10 @@ namespace sqlpp
template<typename... Tab> template<typename... Tab>
auto dynamic_using_(Tab&&... tab) auto dynamic_using_(Tab&&... tab)
-> set_using_t<using_t<Database, typename std::decay<Tab>::type...>> -> set_using_t<vendor::using_t<Database, typename std::decay<Tab>::type...>>
{ {
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice"); static_assert(vendor::is_noop<Using>::value, "cannot call using() twice");
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()"); static_assert(vendor::is_noop<Where>::value, "cannot call using() after where()");
return { return {
_table, _table,
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}}, {std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
@ -105,9 +104,9 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto where(Expr&&... expr) auto where(Expr&&... expr)
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>> -> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
{ {
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice"); static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
return { return {
_table, _table,
_using, _using,
@ -117,9 +116,9 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto dynamic_where(Expr&&... expr) auto dynamic_where(Expr&&... expr)
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>> -> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
{ {
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice"); static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
return { return {
_table, _table,
_using, _using,
@ -167,7 +166,7 @@ namespace sqlpp
}; };
template<typename Context, typename Database, typename Table, typename Using, typename Where> template<typename Context, typename Database, typename Table, typename Using, typename Where>
struct interpreter_t<Context, remove_t<Database, Table, Using, Where>> struct vendor::interpreter_t<Context, remove_t<Database, Table, Using, Where>>
{ {
using T = remove_t<Database, Table, Using, Where>; using T = remove_t<Database, Table, Using, Where>;

View File

@ -27,10 +27,9 @@
#ifndef SQLPP_RESULT_ROW_H #ifndef SQLPP_RESULT_ROW_H
#define SQLPP_RESULT_ROW_H #define SQLPP_RESULT_ROW_H
#include <sqlpp11/char_result_row.h> #include <sqlpp11/vendor/char_result_row.h>
#include <sqlpp11/field.h> #include <sqlpp11/vendor/field.h>
#include <sqlpp11/text.h> #include <sqlpp11/text.h>
#include <iostream>
#include <map> #include <map>
namespace sqlpp namespace sqlpp
@ -87,7 +86,7 @@ namespace sqlpp
}; };
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest> template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
struct result_row_impl<level, index, multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>: struct result_row_impl<level, index, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
public result_row_impl<level, index + sizeof...(Col), Rest...> public result_row_impl<level, index + sizeof...(Col), Rest...>
{ {

View File

@ -29,20 +29,21 @@
#include <sqlpp11/result.h> #include <sqlpp11/result.h>
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/noop.h>
#include <sqlpp11/select_flag_list.h>
#include <sqlpp11/select_expression_list.h>
#include <sqlpp11/from.h>
#include <sqlpp11/where.h>
#include <sqlpp11/group_by.h>
#include <sqlpp11/having.h>
#include <sqlpp11/order_by.h>
#include <sqlpp11/limit.h>
#include <sqlpp11/offset.h>
#include <sqlpp11/expression.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_select.h> #include <sqlpp11/prepared_select.h>
#include <sqlpp11/interpreter.h>
#include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/select_flag_list.h>
#include <sqlpp11/vendor/select_expression_list.h>
#include <sqlpp11/vendor/from.h>
#include <sqlpp11/vendor/where.h>
#include <sqlpp11/vendor/group_by.h>
#include <sqlpp11/vendor/having.h>
#include <sqlpp11/vendor/order_by.h>
#include <sqlpp11/vendor/limit.h>
#include <sqlpp11/vendor/offset.h>
#include <sqlpp11/vendor/expression.h>
#include <sqlpp11/vendor/interpreter.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>
@ -80,15 +81,15 @@ namespace sqlpp
using _Database = Database; using _Database = Database;
using _From = From; using _From = From;
static_assert(is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags"); static_assert(vendor::is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions"); static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
static_assert(is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument"); static_assert(vendor::is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument"); static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
static_assert(is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments"); static_assert(vendor::is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
static_assert(is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments"); static_assert(vendor::is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
static_assert(is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments"); static_assert(vendor::is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
static_assert(is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments"); static_assert(vendor::is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
static_assert(is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments"); static_assert(vendor::is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
using _is_select = std::true_type; using _is_select = std::true_type;
using _requires_braces = std::true_type; using _requires_braces = std::true_type;
@ -117,7 +118,7 @@ namespace sqlpp
// Indicators // Indicators
using _value_type = typename std::conditional< using _value_type = typename std::conditional<
is_noop<From>::value, vendor::is_noop<From>::value,
no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing) no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing)
typename ExpressionList::_value_type>::type; typename ExpressionList::_value_type>::type;
@ -174,7 +175,7 @@ namespace sqlpp
-> set_expression_list_t<typename ExpressionList::template _dynamic_t<Database>> -> set_expression_list_t<typename ExpressionList::template _dynamic_t<Database>>
{ {
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select"); static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
static_assert(is_noop<From>::value, "cannot call dynamic_columns() after from()"); static_assert(vendor::is_noop<From>::value, "cannot call dynamic_columns() after from()");
return { return {
_flags, _flags,
{_expression_list._expressions}, {_expression_list._expressions},
@ -201,10 +202,10 @@ namespace sqlpp
// sqlpp functions // sqlpp functions
template<typename... Table> template<typename... Table>
auto from(Table&&... table) auto from(Table&&... table)
-> set_from_t<from_t<void, typename std::decay<Table>::type...>> -> set_from_t<vendor::from_t<void, typename std::decay<Table>::type...>>
{ {
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything"); static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
static_assert(is_noop<From>::value, "cannot call from() twice for a single select"); static_assert(vendor::is_noop<From>::value, "cannot call from() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -220,11 +221,11 @@ namespace sqlpp
template<typename... Table> template<typename... Table>
auto dynamic_from(Table&&... table) auto dynamic_from(Table&&... table)
-> set_from_t<from_t<Database, typename std::decay<Table>::type...>> -> set_from_t<vendor::from_t<Database, typename std::decay<Table>::type...>>
{ {
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select"); static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything"); static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
static_assert(is_noop<From>::value, "cannot call from() twice for a single select"); static_assert(vendor::is_noop<From>::value, "cannot call from() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -241,7 +242,7 @@ namespace sqlpp
template<typename Table> template<typename Table>
select_t& add_from(Table&& table) select_t& add_from(Table&& table)
{ {
static_assert(not is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything"); static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
static_assert(is_dynamic_t<From>::value, "cannot call add_from() in a non-dynamic from"); static_assert(is_dynamic_t<From>::value, "cannot call add_from() in a non-dynamic from");
_from.add(std::forward<Table>(table)); _from.add(std::forward<Table>(table));
@ -251,10 +252,10 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto where(Expr&&... expr) auto where(Expr&&... expr)
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>> -> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
{ {
static_assert(not is_noop<From>::value, "cannot call where() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call where() without a from()");
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select"); static_assert(vendor::is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -270,10 +271,10 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto dynamic_where(Expr&&... expr) auto dynamic_where(Expr&&... expr)
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>> -> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
{ {
static_assert(not is_noop<From>::value, "cannot call dynamic_where() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call dynamic_where() without a from()");
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select"); static_assert(vendor::is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -299,10 +300,10 @@ namespace sqlpp
template<typename... Col> template<typename... Col>
auto group_by(Col&&... column) auto group_by(Col&&... column)
-> set_group_by_t<group_by_t<void, typename std::decay<Col>::type...>> -> set_group_by_t<vendor::group_by_t<void, typename std::decay<Col>::type...>>
{ {
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call group_by() without a from()");
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select"); static_assert(vendor::is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -318,10 +319,10 @@ namespace sqlpp
template<typename... Col> template<typename... Col>
auto dynamic_group_by(Col&&... column) auto dynamic_group_by(Col&&... column)
-> set_group_by_t<group_by_t<Database, typename std::decay<Col>::type...>> -> set_group_by_t<vendor::group_by_t<Database, typename std::decay<Col>::type...>>
{ {
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call group_by() without a from()");
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select"); static_assert(vendor::is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -347,10 +348,10 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto having(Expr&&... expr) auto having(Expr&&... expr)
-> set_having_t<having_t<void, typename std::decay<Expr>::type...>> -> set_having_t<vendor::having_t<void, typename std::decay<Expr>::type...>>
{ {
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by"); static_assert(not vendor::is_noop<GroupBy>::value, "cannot call having() without a group_by");
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select"); static_assert(vendor::is_noop<Having>::value, "cannot call having() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -366,10 +367,10 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto dynamic_having(Expr&&... expr) auto dynamic_having(Expr&&... expr)
-> set_having_t<having_t<Database, typename std::decay<Expr>::type...>> -> set_having_t<vendor::having_t<Database, typename std::decay<Expr>::type...>>
{ {
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by"); static_assert(not vendor::is_noop<GroupBy>::value, "cannot call having() without a group_by");
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select"); static_assert(vendor::is_noop<Having>::value, "cannot call having() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -395,10 +396,10 @@ namespace sqlpp
template<typename... OrderExpr> template<typename... OrderExpr>
auto order_by(OrderExpr&&... expr) auto order_by(OrderExpr&&... expr)
-> set_order_by_t<order_by_t<void, typename std::decay<OrderExpr>::type...>> -> set_order_by_t<vendor::order_by_t<void, typename std::decay<OrderExpr>::type...>>
{ {
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call order_by() without a from()");
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select"); static_assert(vendor::is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -414,10 +415,10 @@ namespace sqlpp
template<typename... OrderExpr> template<typename... OrderExpr>
auto dynamic_order_by(OrderExpr&&... expr) auto dynamic_order_by(OrderExpr&&... expr)
-> set_order_by_t<order_by_t<Database, typename std::decay<OrderExpr>::type...>> -> set_order_by_t<vendor::order_by_t<Database, typename std::decay<OrderExpr>::type...>>
{ {
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call order_by() without a from()");
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select"); static_assert(vendor::is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -443,10 +444,10 @@ namespace sqlpp
template<typename Expr> template<typename Expr>
auto limit(Expr limit) auto limit(Expr limit)
-> set_limit_t<limit_t<typename wrap_operand<typename std::decay<Expr>::type>::type>> -> set_limit_t<vendor::limit_t<typename vendor::wrap_operand<typename std::decay<Expr>::type>::type>>
{ {
static_assert(not is_noop<From>::value, "cannot call limit() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call limit() without a from()");
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select"); static_assert(vendor::is_noop<Limit>::value, "cannot call limit() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -461,10 +462,10 @@ namespace sqlpp
} }
auto dynamic_limit(std::size_t limit = 0) auto dynamic_limit(std::size_t limit = 0)
->set_limit_t<dynamic_limit_t> ->set_limit_t<vendor::dynamic_limit_t>
{ {
static_assert(not is_noop<From>::value, "cannot call limit() without a from()"); static_assert(not vendor::is_noop<From>::value, "cannot call limit() without a from()");
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select"); static_assert(vendor::is_noop<Limit>::value, "cannot call limit() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -489,10 +490,10 @@ namespace sqlpp
template<typename Expr> template<typename Expr>
auto offset(Expr offset) auto offset(Expr offset)
-> set_offset_t<offset_t<typename wrap_operand<typename std::decay<Expr>::type>::type>> -> set_offset_t<vendor::offset_t<typename vendor::wrap_operand<typename std::decay<Expr>::type>::type>>
{ {
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit"); static_assert(not vendor::is_noop<Limit>::value, "cannot call offset() without a limit");
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select"); static_assert(vendor::is_noop<Offset>::value, "cannot call offset() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -507,10 +508,10 @@ namespace sqlpp
} }
auto dynamic_offset(std::size_t offset = 0) auto dynamic_offset(std::size_t offset = 0)
-> set_offset_t<dynamic_offset_t> -> set_offset_t<vendor::dynamic_offset_t>
{ {
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit"); static_assert(not vendor::is_noop<Limit>::value, "cannot call offset() without a limit");
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select"); static_assert(vendor::is_noop<Offset>::value, "cannot call offset() twice for a single select");
return { return {
_flags, _flags,
_expression_list, _expression_list,
@ -572,7 +573,7 @@ namespace sqlpp
auto run(Db& db) const auto run(Db& db) const
-> result_t<decltype(db.select(*this)), _result_row_t> -> result_t<decltype(db.select(*this)), _result_row_t>
{ {
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything"); static_assert(not vendor::is_noop<ExpressionList>::value, "cannot run select without having selected anything");
static_assert(is_from_t<From>::value, "cannot run select without a from()"); static_assert(is_from_t<From>::value, "cannot run select without a from()");
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead"); static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
// FIXME: Check for missing aliases (if references are used) // FIXME: Check for missing aliases (if references are used)
@ -586,7 +587,7 @@ namespace sqlpp
auto prepare(Db& db) auto prepare(Db& db)
-> prepared_select_t<typename std::decay<Db>::type, select_t> const -> prepared_select_t<typename std::decay<Db>::type, select_t> const
{ {
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything"); static_assert(not vendor::is_noop<ExpressionList>::value, "cannot run select without having selected anything");
static_assert(is_from_t<From>::value, "cannot run select without a from()"); static_assert(is_from_t<From>::value, "cannot run select without a from()");
// FIXME: Check for missing aliases (if references are used) // FIXME: Check for missing aliases (if references are used)
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc. // FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
@ -617,7 +618,7 @@ namespace sqlpp
typename Limit, typename Limit,
typename Offset typename Offset
> >
struct interpreter_t<Context, select_t<Database, struct vendor::interpreter_t<Context, select_t<Database,
Flags, Flags,
ExpressionList, ExpressionList,
From, From,
@ -663,7 +664,7 @@ namespace sqlpp
{ {
template<typename... Expr> template<typename... Expr>
using make_select_flag_list_t = using make_select_flag_list_t =
select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>; vendor::select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>;
} }
// construct select expression list // construct select expression list
@ -671,7 +672,7 @@ namespace sqlpp
{ {
template<typename... Expr> template<typename... Expr>
using make_select_expression_list_t = using make_select_expression_list_t =
select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>; vendor::select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>;
} }
template<typename... NamedExpr> template<typename... NamedExpr>

View File

@ -1,197 +0,0 @@
/*
* 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_EXPRESSION_LIST_H
#define SQLPP_SELECT_EXPRESSION_LIST_H
#include <tuple>
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/expression_fwd.h>
#include <sqlpp11/no_value.h>
#include <sqlpp11/field.h>
#include <sqlpp11/result_row.h>
#include <sqlpp11/table.h>
#include <sqlpp11/select_pseudo_table.h>
#include <sqlpp11/detail/named_serializable.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/set.h>
namespace sqlpp
{
namespace detail
{
template<typename... Rest>
struct get_first_argument_if_unique
{
using _value_type = no_value_t;
struct _name_t {};
};
template<typename T>
struct get_first_argument_if_unique<T>
{
using _value_type = typename T::_value_type;
using _name_t = typename T::_name_t;
};
}
template<typename Db>
struct dynamic_select_expression_list
{
using _names_t = std::vector<std::string>;
std::vector<detail::named_serializable_t<Db>> _dynamic_expressions;
_names_t _dynamic_expression_names;
template<typename Expr>
void push_back(Expr&& expr)
{
_dynamic_expression_names.push_back(std::decay<Expr>::type::_name_t::_get_name());
_dynamic_expressions.emplace_back(std::forward<Expr>(expr));
}
bool empty() const
{
return _dynamic_expressions.empty();
}
};
template<>
struct dynamic_select_expression_list<void>
{
struct _names_t {};
_names_t _dynamic_expression_names;
template<typename T>
void push_back(const T&) {}
static constexpr bool empty()
{
return true;
}
};
template<typename Context, typename Db>
struct interpreter_t<Context, dynamic_select_expression_list<Db>>
{
using T = dynamic_select_expression_list<Db>;
static Context& _(const T& t, Context& context)
{
for (const auto column : t._dynamic_expressions)
{
interpret(column, context);
}
return context;
}
};
template<typename Context>
struct interpreter_t<Context, dynamic_select_expression_list<void>>
{
using T = dynamic_select_expression_list<void>;
static Context& _(const T& t, Context& context)
{
return context;
}
};
template<typename Database, typename... NamedExpr>
struct select_expression_list_t<Database, std::tuple<NamedExpr...>>
{
using _is_select_expression_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<NamedExpr...>;
// check for at least one expression
static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
// check for duplicate select expressions
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
// check for invalid select expressions
template<typename T>
struct is_valid_expression_t: public std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value> {};
using _valid_expressions = typename detail::make_set_if<is_valid_expression_t, NamedExpr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression");
// check for duplicate select expression names
static_assert(not detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
// provide type information for sub-selects that are used as expressions
struct _column_type {};
struct _value_type: detail::get_first_argument_if_unique<NamedExpr...>::_value_type
{
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
using _is_alias = std::false_type;
};
using _name_t = typename detail::get_first_argument_if_unique<NamedExpr...>::_name_t;
using _result_row_t = typename std::conditional<_is_dynamic::value,
dynamic_result_row_t<make_field_t<NamedExpr>...>,
result_row_t<make_field_t<NamedExpr>...>>::type;
using _dynamic_names_t = typename dynamic_select_expression_list<Database>::_names_t;
template <typename Select>
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
template <typename Db>
using _dynamic_t = select_expression_list_t<Db, std::tuple<NamedExpr...>>;
template<typename Expr>
void add(Expr&& namedExpr)
{
static_assert(is_named_expression_t<typename std::decay<Expr>::type>::value, "select() arguments require to be named expressions");
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
_dynamic_expressions.push_back(std::forward<Expr>(namedExpr));
}
_parameter_tuple_t _expressions;
dynamic_select_expression_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... NamedExpr>
struct interpreter_t<Context, select_expression_list_t<Database, NamedExpr...>>
{
using T = select_expression_list_t<Database, NamedExpr...>;
static Context& _(const T& t, Context& context)
{
interpret_tuple(t._expressions, ',', context);
if (sizeof...(NamedExpr) and not t._dynamic_expressions.empty())
context << ',';
interpret(t._dynamic_expressions, context);
return context;
}
};
}
#endif

View File

@ -27,7 +27,8 @@
#ifndef SQLPP_SELECT_FWD_H #ifndef SQLPP_SELECT_FWD_H
#define SQLPP_SELECT_FWD_H #define SQLPP_SELECT_FWD_H
#include <sqlpp11/noop_fwd.h> // FIXME: Do we really need this file?
#include <sqlpp11/vendor/noop_fwd.h>
#include <type_traits> #include <type_traits>
namespace sqlpp namespace sqlpp
@ -37,36 +38,17 @@ namespace sqlpp
struct distinct_t; struct distinct_t;
struct straight_join_t; struct straight_join_t;
template<typename FlagTuple> struct select_flag_list_t;
template<typename Database, typename NamedExprTuple> struct select_expression_list_t;
template<typename Database, typename... TableOrJoin> struct from_t;
template<typename Database, typename... Expr> struct where_t;
template<typename Database, typename... Expr> struct group_by_t;
template<typename Database, typename... Expr> struct having_t;
template<typename Database, typename... Expr> struct order_by_t;
template<typename Limit>
struct limit_t;
template<typename Offset>
struct offset_t;
template< template<
typename Db, typename Db,
typename Flags = noop, typename Flags = vendor::noop,
typename ExpressionList = noop, typename ExpressionList = vendor::noop,
typename From = noop, typename From = vendor::noop,
typename Where = noop, typename Where = vendor::noop,
typename GroupBy = noop, typename GroupBy = vendor::noop,
typename Having = noop, typename Having = vendor::noop,
typename OrderBy = noop, typename OrderBy = vendor::noop,
typename Limit = noop, typename Limit = vendor::noop,
typename Offset = noop typename Offset = vendor::noop
> >
struct select_t; struct select_t;
} }

View File

@ -32,7 +32,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Select> template<typename Select>
struct some_t: public boolean::template operators<some_t<Select>> struct some_t: public boolean::template operators<some_t<Select>>
@ -76,9 +76,9 @@ namespace sqlpp
} }
template<typename Context, typename Select> template<typename Context, typename Select>
struct interpreter_t<Context, detail::some_t<Select>> struct vendor::interpreter_t<Context, vendor::some_t<Select>>
{ {
using T = detail::some_t<Select>; using T = vendor::some_t<Select>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -90,7 +90,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto some(T&& t) -> typename detail::some_t<typename operand_t<T, is_select_t>::type> auto some(T&& t) -> typename vendor::some_t<typename operand_t<T, is_select_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -44,7 +44,7 @@ namespace sqlpp
}; };
template<typename Context, typename Expression, sort_type SortType> template<typename Context, typename Expression, sort_type SortType>
struct interpreter_t<Context, sort_order_t<Expression, SortType>> struct vendor::interpreter_t<Context, sort_order_t<Expression, SortType>>
{ {
using T = sort_order_t<Expression, SortType>; using T = sort_order_t<Expression, SortType>;

View File

@ -32,7 +32,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Expr> template<typename Expr>
struct sum_t: public boolean::template operators<sum_t<Expr>> struct sum_t: public boolean::template operators<sum_t<Expr>>
@ -75,9 +75,9 @@ namespace sqlpp
} }
template<typename Context, typename Expr> template<typename Context, typename Expr>
struct interpreter_t<Context, detail::sum_t<Expr>> struct vendor::interpreter_t<Context, vendor::sum_t<Expr>>
{ {
using T = detail::sum_t<Expr>; using T = vendor::sum_t<Expr>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -89,7 +89,7 @@ namespace sqlpp
}; };
template<typename T> template<typename T>
auto sum(T&& t) -> typename detail::sum_t<typename operand_t<T, is_value_t>::type> auto sum(T&& t) -> typename vendor::sum_t<typename operand_t<T, is_value_t>::type>
{ {
return { std::forward<T>(t) }; return { std::forward<T>(t) };
} }

View File

@ -27,12 +27,12 @@
#ifndef SQLPP_TABLE_H #ifndef SQLPP_TABLE_H
#define SQLPP_TABLE_H #define SQLPP_TABLE_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/table_alias.h> #include <sqlpp11/table_alias.h>
#include <sqlpp11/no_value.h>
#include <sqlpp11/column.h> #include <sqlpp11/column.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/join.h> #include <sqlpp11/join.h>
#include <sqlpp11/no_value.h>
namespace sqlpp namespace sqlpp
{ {
@ -100,7 +100,7 @@ namespace sqlpp
} }
template<typename Context, typename X> template<typename Context, typename X>
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value and not is_pseudo_table_t<X>::value, void>::type> struct vendor::interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value and not is_pseudo_table_t<X>::value, void>::type>
{ {
using T = X; using T = X;

View File

@ -27,12 +27,11 @@
#ifndef SQLPP_TABLE_ALIAS_H #ifndef SQLPP_TABLE_ALIAS_H
#define SQLPP_TABLE_ALIAS_H #define SQLPP_TABLE_ALIAS_H
#include <string> #include <sqlpp11/column_fwd.h>
#include <sqlpp11/interpreter.h> #include <sqlpp11/interpret.h>
#include <sqlpp11/column.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/alias.h> #include <sqlpp11/alias.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
#include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
@ -63,7 +62,7 @@ namespace sqlpp
}; };
template<typename Context, typename X> template<typename Context, typename X>
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_alias_base_t, X>::value, void>::type> struct vendor::interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_alias_base_t, X>::value, void>::type>
{ {
using T = X; using T = X;

View File

@ -28,11 +28,11 @@
#define SQLPP_TEXT_H #define SQLPP_TEXT_H
#include <cstdlib> #include <cstdlib>
#include <sqlpp11/detail/basic_operators.h> #include <sqlpp11/basic_operators.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/exception.h> #include <sqlpp11/exception.h>
#include <sqlpp11/concat.h> #include <sqlpp11/vendor/concat.h>
#include <sqlpp11/like.h> #include <sqlpp11/vendor/like.h>
namespace sqlpp namespace sqlpp
{ {
@ -177,14 +177,14 @@ namespace sqlpp
struct operators: public basic_operators<Base, _constraint> struct operators: public basic_operators<Base, _constraint>
{ {
template<typename T> template<typename T>
concat_t<Base, typename _constraint<T>::type> operator+(T&& t) const vendor::concat_t<Base, typename _constraint<T>::type> operator+(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
} }
template<typename T> template<typename T>
like_t<Base, typename _constraint<T>::type> like(T&& t) const vendor::like_t<Base, typename _constraint<T>::type> like(T&& t) const
{ {
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand"); static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
return { *static_cast<const Base*>(this), {std::forward<T>(t)} }; return { *static_cast<const Base*>(this), {std::forward<T>(t)} };

View File

@ -30,16 +30,16 @@
// TVIN: Trivial value is NULL // TVIN: Trivial value is NULL
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/interpreter.h> #include <sqlpp11/vendor/interpreter.h>
namespace sqlpp namespace sqlpp
{ {
template<typename T> template<typename T>
struct tvin_t struct tvin_t
{ {
using _wrapped_t = typename wrap_operand<T>::type; using _operand_t = typename vendor::wrap_operand<T>::type;
static_assert(not std::is_same<_wrapped_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)"); static_assert(not std::is_same<_operand_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)");
using _value_type = typename _wrapped_t::_value_type; using _value_type = typename _operand_t::_value_type;
tvin_t(T t): tvin_t(T t):
_value({t}) _value({t})
@ -50,11 +50,11 @@ namespace sqlpp
tvin_t& operator=(tvin_t&&) = default; tvin_t& operator=(tvin_t&&) = default;
~tvin_t() = default; ~tvin_t() = default;
_wrapped_t _value; _operand_t _value;
}; };
template<typename Context, typename Type> template<typename Context, typename Type>
struct interpreter_t<Context, tvin_t<Type>> struct vendor::interpreter_t<Context, tvin_t<Type>>
{ {
using T = tvin_t<Type>; using T = tvin_t<Type>;
@ -101,11 +101,11 @@ namespace sqlpp
tvin_wrap_t& operator=(tvin_wrap_t&&) = default; tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
~tvin_wrap_t() = default; ~tvin_wrap_t() = default;
typename tvin_t<T>::_wrapped_t _value; typename tvin_t<T>::_operand_t _value;
}; };
template<typename Context, typename Type> template<typename Context, typename Type>
struct interpreter_t<Context, tvin_wrap_t<Type>> struct vendor::interpreter_t<Context, tvin_wrap_t<Type>>
{ {
using T = tvin_wrap_t<Type>; using T = tvin_wrap_t<Type>;

View File

@ -28,7 +28,7 @@
#define SQLPP_TYPE_TRAITS_H #define SQLPP_TYPE_TRAITS_H
#include <type_traits> #include <type_traits>
#include <sqlpp11/detail/wrap_operand.h> #include <sqlpp11/vendor/wrap_operand.h>
namespace sqlpp namespace sqlpp
{ {
@ -112,7 +112,7 @@ namespace sqlpp
SQLPP_TYPE_TRAIT_GENERATOR(is_multi_column); SQLPP_TYPE_TRAIT_GENERATOR(is_multi_column);
SQLPP_TYPE_TRAIT_GENERATOR(is_value_list); SQLPP_TYPE_TRAIT_GENERATOR(is_value_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment); SQLPP_TYPE_TRAIT_GENERATOR(is_assignment);
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment_list); SQLPP_TYPE_TRAIT_GENERATOR(is_update_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list); SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order); SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces); SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
@ -126,12 +126,11 @@ namespace sqlpp
template<typename T, template<typename> class IsCorrectType> template<typename T, template<typename> class IsCorrectType>
struct operand_t struct operand_t
{ {
using type = typename wrap_operand<typename std::decay<T>::type>::type; using type = typename vendor::wrap_operand<typename std::decay<T>::type>::type;
static_assert(not is_alias_t<type>::value, "expression operand must not be an alias"); static_assert(not is_alias_t<type>::value, "expression operand must not be an alias");
static_assert(is_expression_t<type>::value, "expression required"); static_assert(is_expression_t<type>::value, "expression required");
static_assert(IsCorrectType<type>::value, "invalid operand type"); static_assert(IsCorrectType<type>::value, "invalid operand type");
}; };
} }

View File

@ -27,21 +27,20 @@
#ifndef SQLPP_UPDATE_H #ifndef SQLPP_UPDATE_H
#define SQLPP_UPDATE_H #define SQLPP_UPDATE_H
#include <sstream>
#include <sqlpp11/noop.h>
#include <sqlpp11/assignment_list.h>
#include <sqlpp11/where.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_update.h> #include <sqlpp11/prepared_update.h>
#include <sqlpp11/vendor/update_list.h>
#include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/where.h>
namespace sqlpp namespace sqlpp
{ {
template< template<
typename Database = void, typename Database = void,
typename Table = noop, typename Table = vendor::noop,
typename Assignments = noop, typename Assignments = vendor::noop,
typename Where = noop typename Where = vendor::noop
> >
struct update_t; struct update_t;
@ -53,9 +52,9 @@ namespace sqlpp
> >
struct update_t struct update_t
{ {
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument"); static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
static_assert(is_noop<Assignments>::value or is_assignment_list_t<Assignments>::value, "invalid 'Assignments' arguments"); static_assert(vendor::is_noop<Assignments>::value or is_update_list_t<Assignments>::value, "invalid 'Assignments' arguments");
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument"); static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
template<typename AssignmentsT> template<typename AssignmentsT>
using set_assignments_t = update_t<Database, Table, AssignmentsT, Where>; using set_assignments_t = update_t<Database, Table, AssignmentsT, Where>;
@ -68,9 +67,9 @@ namespace sqlpp
template<typename... Assignment> template<typename... Assignment>
auto set(Assignment&&... assignment) auto set(Assignment&&... assignment)
-> set_assignments_t<assignment_list_t<void, typename std::decay<Assignment>::type...>> -> set_assignments_t<vendor::update_list_t<void, typename std::decay<Assignment>::type...>>
{ {
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice"); static_assert(vendor::is_noop<Assignments>::value, "cannot call set() twice");
return { return {
_table, _table,
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}}, {std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
@ -80,9 +79,9 @@ namespace sqlpp
template<typename... Assignment> template<typename... Assignment>
auto dynamic_set(Assignment&&... assignment) auto dynamic_set(Assignment&&... assignment)
-> set_assignments_t<assignment_list_t<Database, typename std::decay<Assignment>::type...>> -> set_assignments_t<vendor::update_list_t<Database, typename std::decay<Assignment>::type...>>
{ {
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice"); static_assert(vendor::is_noop<Assignments>::value, "cannot call set() twice");
return { return {
_table, _table,
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}}, {std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
@ -102,10 +101,10 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto where(Expr&&... expr) auto where(Expr&&... expr)
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>> -> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
{ {
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet"); static_assert(not vendor::is_noop<Assignments>::value, "cannot call where() if set() hasn't been called yet");
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice"); static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
return { return {
_table, _table,
_assignments, _assignments,
@ -115,10 +114,10 @@ namespace sqlpp
template<typename... Expr> template<typename... Expr>
auto dynamic_where(Expr&&... expr) auto dynamic_where(Expr&&... expr)
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>> -> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
{ {
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet"); static_assert(not vendor::is_noop<Assignments>::value, "cannot call where() if set() hasn't been called yet");
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice"); static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
return { return {
_table, _table,
_assignments, _assignments,
@ -149,7 +148,7 @@ namespace sqlpp
template<typename Db> template<typename Db>
std::size_t run(Db& db) const std::size_t run(Db& db) const
{ {
static_assert(not is_noop<Assignments>::value, "calling set() required before running update"); static_assert(not vendor::is_noop<Assignments>::value, "calling set() required before running update");
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead"); static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
return db.update(*this); return db.update(*this);
} }
@ -158,7 +157,7 @@ namespace sqlpp
auto prepare(Db& db) auto prepare(Db& db)
-> prepared_update_t<typename std::decay<Db>::type, update_t> -> prepared_update_t<typename std::decay<Db>::type, update_t>
{ {
static_assert(not is_noop<Assignments>::value, "calling set() required before running update"); static_assert(not vendor::is_noop<Assignments>::value, "calling set() required before running update");
return {{}, db.prepare_update(*this)}; return {{}, db.prepare_update(*this)};
} }
@ -174,7 +173,7 @@ namespace sqlpp
typename Assignments, typename Assignments,
typename Where typename Where
> >
struct interpreter_t<Context, update_t<Database, Table, Assignments, Where>> struct vendor::interpreter_t<Context, update_t<Database, Table, Assignments, Where>>
{ {
using T = update_t<Database, Table, Assignments, Where>; using T = update_t<Database, Table, Assignments, Where>;

View File

@ -1,87 +0,0 @@
/*
* 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_USING_H
#define SQLPP_USING_H
#include <ostream>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serializable_list.h>
#include <sqlpp11/detail/serialize_tuple.h>
namespace sqlpp
{
template<typename Database, typename... Table>
struct using_t
{
using _is_using = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Table...>;
static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()");
// check for duplicate arguments
static_assert(not detail::has_duplicates<Table...>::value, "at least one duplicate argument detected in using()");
// check for invalid arguments
using _valid_expressions = typename detail::make_set_if<is_table_t, Table...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()");
template<typename T>
void add(T&& table)
{
static_assert(is_table_t<typename std::decay<T>::type>::value, "using() arguments require to be tables");
_dynamic_tables.emplace_back(std::forward<T>(table));
}
_parameter_tuple_t _tables;
detail::serializable_list<Database> _dynamic_tables;
};
template<typename Context, typename Database, typename... Table>
struct interpreter_t<Context, using_t<Database, Table...>>
{
using T = using_t<Database, Table...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Table) == 0 and t._dynamic_tables.empty())
return context;
context << " USING ";
interpret_tuple(t._tables, ',', context);
if (sizeof...(Table) and not t._dynamic_tables.empty())
context << ',';
interpret_serializable_list(t._dynamic_tables, ',', context);
return context;
}
};
}
#endif

View File

@ -27,15 +27,16 @@
#ifndef SQLPP_CONCAT_H #ifndef SQLPP_CONCAT_H
#define SQLPP_CONCAT_H #define SQLPP_CONCAT_H
#include <sstream>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/interpret_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
namespace sqlpp namespace sqlpp
{ {
namespace vendor
{
template<typename First, typename... Args> template<typename First, typename... Args>
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>> struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
{ {
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least"); static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
using _valid_args = typename detail::make_set_if_not<is_text_t, First, Args...>::type; using _valid_args = typename detail::make_set_if_not<is_text_t, First, Args...>::type;
@ -69,28 +70,20 @@ namespace sqlpp
std::tuple<First, Args...> _args; std::tuple<First, Args...> _args;
}; };
//FIXME: Write partial specialization for mysql template<typename Context, typename First, typename... Args>
template<typename Context, typename First, typename... Args> struct interpreter_t<Context, concat_t<First, Args...>>
struct interpreter_t<Context, concat_t<First, Args...>>
{
using T = concat_t<First, Args...>;
static Context& _(const T& t, Context& context)
{ {
context << "("; using T = concat_t<First, Args...>;
interpret_tuple(t._args, "||", context);
context << ")";
return context;
}
};
static Context& _(const T& t, Context& context)
template<typename... T> {
auto concat(T&&... t) -> concat_t<typename operand_t<T, is_text_t>::type...> context << "(";
{ interpret_tuple(t._args, "||", context);
return { std::forward<T>(t)... }; context << ")";
return context;
}
};
} }
} }
#endif #endif

248
include/sqlpp11/vendor/expression.h vendored Normal file
View File

@ -0,0 +1,248 @@
/*
* 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_EXPRESSION_H
#define SQLPP_EXPRESSION_H
#include <sqlpp11/alias.h>
#include <sqlpp11/boolean.h>
#include <sqlpp11/tvin.h>
#include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/expression_fwd.h>
#include <sqlpp11/vendor/interpreter.h>
#include <sqlpp11/vendor/wrap_operand.h>
namespace sqlpp
{
namespace vendor
{
template<typename Lhs, typename Rhs>
struct assignment_t
{
using _is_assignment = std::true_type;
using column_type = Lhs;
using value_type = tvin_wrap_t<Rhs>;
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
assignment_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
assignment_t(const assignment_t&) = default;
assignment_t(assignment_t&&) = default;
assignment_t& operator=(const assignment_t&) = default;
assignment_t& operator=(assignment_t&&) = default;
~assignment_t() = default;
Lhs _lhs;
tvin_wrap_t<Rhs> _rhs;
};
template<typename Context, typename Lhs, typename Rhs>
struct interpreter_t<Context, assignment_t<Lhs, Rhs>>
{
using T = assignment_t<Lhs, Rhs>;
static Context& _(const T& t, Context& context)
{
interpret(t._lhs, context);
if (t._rhs._is_trivial())
{
context << "=NULL";
}
else
{
context << "=";
interpret(t._rhs, context);
}
return context;
}
};
template<typename Lhs, typename Rhs>
struct equal_t: public detail::boolean::template operators<equal_t<Lhs, Rhs>>
{
using _value_type = detail::boolean;
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
equal_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
equal_t(const equal_t&) = default;
equal_t(equal_t&&) = default;
equal_t& operator=(const equal_t&) = default;
equal_t& operator=(equal_t&&) = default;
~equal_t() = default;
Lhs _lhs;
tvin_wrap_t<Rhs> _rhs;
};
template<typename Context, typename Lhs, typename Rhs>
struct interpreter_t<Context, equal_t<Lhs, Rhs>>
{
using T = equal_t<Lhs, Rhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
interpret(t._lhs, context);
if (t._rhs._is_trivial())
{
context << " IS NULL";
}
else
{
context << "=";
interpret(t._rhs, context);
}
context << ")";
return context;
}
};
template<typename Lhs, typename Rhs>
struct not_equal_t: public detail::boolean::template operators<not_equal_t<Lhs, Rhs>>
{
using _value_type = detail::boolean;
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
not_equal_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
not_equal_t(const not_equal_t&) = default;
not_equal_t(not_equal_t&&) = default;
not_equal_t& operator=(const not_equal_t&) = default;
not_equal_t& operator=(not_equal_t&&) = default;
~not_equal_t() = default;
Lhs _lhs;
tvin_wrap_t<Rhs> _rhs;
};
template<typename Context, typename Lhs, typename Rhs>
struct interpreter_t<Context, not_equal_t<Lhs, Rhs>>
{
using T = not_equal_t<Lhs, Rhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
interpret(t._lhs, context);
if (t._rhs._is_trivial())
{
context << " IS NOT NULL";
}
else
{
context << "!=";
interpret(t._rhs, context);
}
context << ")";
return context;
}
};
template<typename Lhs>
struct not_t: public detail::boolean::template operators<not_t<Lhs>>
{
using _value_type = detail::boolean;
using _parameter_tuple_t = std::tuple<Lhs>;
not_t(Lhs l):
_lhs(l)
{}
not_t(const not_t&) = default;
not_t(not_t&&) = default;
not_t& operator=(const not_t&) = default;
not_t& operator=(not_t&&) = default;
~not_t() = default;
Lhs _lhs;
};
template<typename Context, typename Lhs>
struct interpreter_t<Context, not_t<Lhs>>
{
using T = not_t<Lhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
context << "NOT ";
interpret(t._lhs, context);
context << ")";
return context;
}
};
template<typename Lhs, typename O, typename 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 _parameter_tuple_t = std::tuple<Lhs, Rhs>;
binary_expression_t(Lhs lhs, Rhs rhs):
_lhs(lhs),
_rhs(rhs)
{}
binary_expression_t(const binary_expression_t&) = default;
binary_expression_t(binary_expression_t&&) = default;
binary_expression_t& operator=(const binary_expression_t&) = default;
binary_expression_t& operator=(binary_expression_t&&) = default;
~binary_expression_t() = default;
Lhs _lhs;
Rhs _rhs;
};
template<typename Context, typename Lhs, typename O, typename Rhs>
struct interpreter_t<Context, binary_expression_t<Lhs, O, Rhs>>
{
using T = binary_expression_t<Lhs, O, Rhs>;
static Context& _(const T& t, Context& context)
{
context << "(";
interpret(t._lhs, context);
context << O::_name;
interpret(t._rhs, context);
context << ")";
return context;
}
};
}
}
#endif

View File

@ -29,20 +29,23 @@
namespace sqlpp namespace sqlpp
{ {
template<typename Lhs, typename Rhs> namespace vendor
struct assignment_t; {
template<typename Lhs, typename Rhs>
struct assignment_t;
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
struct equal_t; struct equal_t;
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
struct not_equal_t; struct not_equal_t;
template<typename Lhs> template<typename Lhs>
struct not_t; struct not_t;
template<typename Lhs, typename O, typename Rhs> template<typename Lhs, typename O, typename Rhs>
struct binary_expression_t; struct binary_expression_t;
}
} }
#endif #endif

View File

@ -27,41 +27,43 @@
#ifndef SQLPP_FIELD_H #ifndef SQLPP_FIELD_H
#define SQLPP_FIELD_H #define SQLPP_FIELD_H
#include <ostream>
#include <sqlpp11/multi_column.h> #include <sqlpp11/multi_column.h>
namespace sqlpp namespace sqlpp
{ {
template<typename NameType, typename ValueType> namespace vendor
struct field_t
{
using _name_t = NameType;
using _value_type = ValueType;
};
template<typename AliasProvider, typename FieldTuple>
struct multi_field_t
{
};
namespace detail
{ {
template<typename NameType, typename ValueType>
struct field_t
{
using _name_t = NameType;
using _value_type = ValueType;
};
template<typename AliasProvider, typename FieldTuple>
struct multi_field_t
{
};
namespace detail
{
template<typename NamedExpr>
struct make_field_t_impl
{
using type = field_t<typename NamedExpr::_name_t, typename NamedExpr::_value_type::_base_value_type>;
};
template<typename AliasProvider, typename... NamedExpr>
struct make_field_t_impl<multi_column_t<AliasProvider, std::tuple<NamedExpr...>>>
{
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<NamedExpr>::type...>>;
};
}
template<typename NamedExpr> template<typename NamedExpr>
struct make_field_t_impl using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
{
using type = field_t<typename NamedExpr::_name_t, typename NamedExpr::_value_type::_base_value_type>;
};
template<typename AliasProvider, typename... NamedExpr>
struct make_field_t_impl<multi_column_t<AliasProvider, std::tuple<NamedExpr...>>>
{
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<NamedExpr>::type...>>;
};
} }
template<typename NamedExpr>
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
} }
#endif #endif

91
include/sqlpp11/vendor/from.h vendored Normal file
View File

@ -0,0 +1,91 @@
/*
* 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_FROM_H
#define SQLPP_FROM_H
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/vendor/interpret_tuple.h>
namespace sqlpp
{
namespace vendor
{
template<typename Database, typename... TableOrJoin>
struct from_t
{
using _is_from = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
// ensure one argument at least
static_assert(_is_dynamic::value or sizeof...(TableOrJoin), "at least one table or join argument required in from()");
// check for duplicate arguments
static_assert(not ::sqlpp::detail::has_duplicates<TableOrJoin...>::value, "at least one duplicate argument detected in from()");
// check for invalid arguments
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_table_t, TableOrJoin...>::type;
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
template<typename Table>
void add(Table&& table)
{
static_assert(is_table_t<typename std::decay<Table>::type>::value, "from arguments require to be tables or joins");
_dynamic_tables.emplace_back(std::forward<Table>(table));
}
std::tuple<TableOrJoin...> _tables;
vendor::interpretable_list_t<Database> _dynamic_tables;
};
template<typename Context, typename Database, typename... TableOrJoin>
struct interpreter_t<Context, from_t<Database, TableOrJoin...>>
{
using T = from_t<Database, TableOrJoin...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(TableOrJoin) == 0 and t._dynamic_tables.empty())
return context;
context << " FROM ";
interpret_tuple(t._tables, ',', context);
if (sizeof...(TableOrJoin) and not t._dynamic_tables.empty())
context << ',';
interpret_list(t._dynamic_tables, ',', context);
return context;
}
};
}
}
#endif

90
include/sqlpp11/vendor/group_by.h vendored Normal file
View File

@ -0,0 +1,90 @@
/*
* 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_GROUP_BY_H
#define SQLPP_GROUP_BY_H
#include <tuple>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/vendor/expression.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/detail/set.h>
namespace sqlpp
{
namespace vendor
{
template<typename Database, typename... Expr>
struct group_by_t
{
using _is_group_by = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
// ensure one argument at least
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
// check for duplicate expressions
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
// check for invalid expressions
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_expression_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()");
template<typename E>
void add(E&& expr)
{
static_assert(is_table_t<typename std::decay<E>::type>::value, "from arguments require to be tables or joins");
_dynamic_expressions.emplace_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
vendor::interpretable_list_t<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, group_by_t<Database, Expr...>>
{
using T = group_by_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context;
context << " GROUP BY ";
interpret_tuple(t._expressions, ',', context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << ',';
interpret_list(t._dynamic_expressions, ',', context);
return context;
}
};
}
}
#endif

View File

@ -27,58 +27,58 @@
#ifndef SQLPP_HAVING_H #ifndef SQLPP_HAVING_H
#define SQLPP_HAVING_H #define SQLPP_HAVING_H
#include <ostream>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/expression.h> #include <sqlpp11/vendor/expression.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h>
#include <sqlpp11/detail/serializable_list.h>
namespace sqlpp namespace sqlpp
{ {
template<typename Database, typename... Expr> namespace vendor
struct having_t {
{ template<typename Database, typename... Expr>
using _is_having = std::true_type; struct having_t
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
template<typename E>
void add(E&& expr)
{
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_having()");
_dynamic_expressions.emplace_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
detail::serializable_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, having_t<Database, Expr...>>
{
using T = having_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{ {
using _is_having = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_expression_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
template<typename E>
void add(E&& expr)
{
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_having()");
_dynamic_expressions.emplace_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
vendor::interpretable_list_t<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, having_t<Database, Expr...>>
{
using T = having_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context; return context;
context << " HAVING "; context << " HAVING ";
interpret_tuple(t._expressions, " AND ", context); interpret_tuple(t._expressions, " AND ", context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty()) if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << " AND "; context << " AND ";
interpret_serializable_list(t._dynamic_expressions, " AND ", context); interpret_list(t._dynamic_expressions, " AND ", context);
return context; return context;
} }
}; };
}
} }
#endif #endif

View File

@ -24,21 +24,20 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_IN_FWD_H #ifndef SQLPP_IN_H
#define SQLPP_IN_FWD_H #define SQLPP_IN_H
#include <sqlpp11/in_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/boolean.h> #include <sqlpp11/boolean.h>
#include <sqlpp11/vendor/in_fwd.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
namespace sqlpp namespace sqlpp
{ {
// FIXME: Move to vendor namespace namespace vendor
namespace detail
{ {
template<bool NotInverted, typename Operand, typename... Args> template<bool NotInverted, typename Operand, typename... Args>
struct in_t: public boolean::template operators<in_t<NotInverted, Operand, Args...>> struct in_t: public boolean::template operators<in_t<NotInverted, Operand, Args...>>
{ {
static constexpr bool _inverted = not NotInverted; static constexpr bool _inverted = not NotInverted;
static_assert(sizeof...(Args) > 0, "in() requires at least one argument"); static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
@ -77,22 +76,22 @@ namespace sqlpp
Operand _operand; Operand _operand;
std::tuple<Args...> _args; std::tuple<Args...> _args;
}; };
}
template<typename Context, bool NotInverted, typename Operand, typename... Args> template<typename Context, bool NotInverted, typename Operand, typename... Args>
struct interpreter_t<Context, detail::in_t<NotInverted, Operand, Args...>> struct interpreter_t<Context, vendor::in_t<NotInverted, Operand, Args...>>
{
using T = detail::in_t<NotInverted, Operand, Args...>;
static Context& _(const T& t, Context& context)
{ {
interpret(t._operand, context); using T = vendor::in_t<NotInverted, Operand, Args...>;
context << (t._inverted ? " NOT IN(" : " IN(");
interpret_tuple(t._args, ',', context); static Context& _(const T& t, Context& context)
context << ')'; {
return context; interpret(t._operand, context);
} context << (t._inverted ? " NOT IN(" : " IN(");
}; interpret_tuple(t._args, ',', context);
context << ')';
return context;
}
};
}
} }

View File

@ -24,13 +24,12 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_IN_H #ifndef SQLPP_IN_FWD_H
#define SQLPP_IN_H #define SQLPP_IN_FWD_H
namespace sqlpp namespace sqlpp
{ {
// FIXME: Move to vendor namespace namespace vendor
namespace detail
{ {
template<bool NotInverted, typename Operand, typename... Args> template<bool NotInverted, typename Operand, typename... Args>
struct in_t; struct in_t;

155
include/sqlpp11/vendor/insert_list.h vendored Normal file
View File

@ -0,0 +1,155 @@
/*
* 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_INSERT_LIST_H
#define SQLPP_INSERT_LIST_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h>
namespace sqlpp
{
namespace vendor
{
struct insert_default_values_t
{
using _is_insert_list = std::true_type;
using _is_dynamic = std::false_type;
};
template<typename Context>
struct interpreter_t<Context, insert_default_values_t>
{
using T = insert_default_values_t;
static Context& _(const T& t, Context& context)
{
context << " DEFAULT VALUES";
return context;
}
};
template<typename Column>
struct insert_column_t
{
Column _column;
};
template<typename Context, typename Column>
struct interpreter_t<Context, insert_column_t<Column>>
{
using T = insert_column_t<Column>;
static Context& _(const T& t, Context& context)
{
context << t._column._get_name();
return context;
}
};
template<typename Database, typename... Assignments>
struct insert_list_t
{
using _is_insert_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<typename Assignments::value_type...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
// check for duplicate assignments
static_assert(not detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments
using _assignment_set = typename detail::make_set_if<is_assignment_t, Assignments...>::type;
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
// check for prohibited assignments
using _prohibited_assignment_set = typename detail::make_set_if<must_not_insert_t, typename Assignments::column_type...>::type;
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
insert_list_t(Assignments... assignment):
_columns({assignment._lhs}...),
_values(assignment._rhs...)
{}
insert_list_t(const insert_list_t&) = default;
insert_list_t(insert_list_t&&) = default;
insert_list_t& operator=(const insert_list_t&) = default;
insert_list_t& operator=(insert_list_t&&) = default;
~insert_list_t() = default;
template<typename Assignment>
void add(Assignment&& assignment)
{
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
static_assert(not must_not_insert_t<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
_dynamic_columns.emplace_back(insert_column_t<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
}
std::tuple<insert_column_t<typename Assignments::column_type>...> _columns;
_parameter_tuple_t _values;
typename vendor::interpretable_list_t<Database> _dynamic_columns;
typename vendor::interpretable_list_t<Database> _dynamic_values;
};
template<typename Context, typename Database, typename... Assignments>
struct interpreter_t<Context, insert_list_t<Database, Assignments...>>
{
using T = insert_list_t<Database, Assignments...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
{
interpret(insert_default_values_t(), context);
}
else
{
context << " (";
interpret_tuple(t._columns, ",", context);
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
context << ',';
interpret_list(t._dynamic_columns, ',', context);
context << ") VALUES(";
interpret_tuple(t._values, ",", context);
if (sizeof...(Assignments) and not t._dynamic_values.empty())
context << ',';
interpret_list(t._dynamic_values, ',', context);
context << ")";
}
return context;
}
};
}
}
#endif

View File

@ -24,8 +24,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_SERIALIZABLE_H #ifndef SQLPP_INTERPRETABLE_H
#define SQLPP_SERIALIZABLE_H #define SQLPP_INTERPRETABLE_H
#include <memory> #include <memory>
#include <sqlpp11/serializer.h> #include <sqlpp11/serializer.h>
@ -33,23 +33,23 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Db> template<typename Db>
struct serializable_t struct interpretable_t
{ {
using _context_t = typename Db::context; using _context_t = typename Db::context;
template<typename T> template<typename T>
serializable_t(T t): interpretable_t(T t):
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t)) _impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t))
{} {}
serializable_t(const serializable_t&) = default; interpretable_t(const interpretable_t&) = default;
serializable_t(serializable_t&&) = default; interpretable_t(interpretable_t&&) = default;
serializable_t& operator=(const serializable_t&) = default; interpretable_t& operator=(const interpretable_t&) = default;
serializable_t& operator=(serializable_t&&) = default; interpretable_t& operator=(interpretable_t&&) = default;
~serializable_t() = default; ~interpretable_t() = default;
sqlpp::serializer& interpret(sqlpp::serializer& context) const sqlpp::serializer& interpret(sqlpp::serializer& context) const
{ {
@ -97,20 +97,20 @@ namespace sqlpp
std::shared_ptr<const _impl_base> _impl; std::shared_ptr<const _impl_base> _impl;
}; };
}
template<typename Context, typename Database> template<typename Context, typename Database>
struct interpreter_t<Context, detail::serializable_t<Database>> struct interpreter_t<Context, interpretable_t<Database>>
{
using T = detail::serializable_t<Database>;
static Context& _(const T& t, Context& context)
{ {
t.interpret(context); using T = interpretable_t<Database>;
return context;
}
};
static Context& _(const T& t, Context& context)
{
t.interpret(context);
return context;
}
};
}
} }
#endif #endif

View File

@ -24,22 +24,20 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef SQLPP_SERIALIZABLE_LIST_H #ifndef SQLPP_INTERPRETABLE_LIST_H
#define SQLPP_SERIALIZABLE_LIST_H #define SQLPP_INTERPRETABLE_LIST_H
#include <vector> #include <vector>
#include <sqlpp11/detail/serializable.h> #include <sqlpp11/vendor/interpretable.h>
// FIXME: Needs to leave detail namespace
// FIXME: serializable is not a very good name any more...
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Db> template<typename Db>
struct serializable_list struct interpretable_list_t
{ {
std::vector<detail::serializable_t<Db>> _serializables; std::vector<interpretable_t<Db>> _serializables;
std::size_t size() const std::size_t size() const
{ {
@ -60,7 +58,7 @@ namespace sqlpp
}; };
template<> template<>
struct serializable_list<void> struct interpretable_list_t<void>
{ {
template<typename T> template<typename T>
void emplace_back(const T&) {} void emplace_back(const T&) {}
@ -77,49 +75,48 @@ namespace sqlpp
}; };
} template<typename Context, typename List>
struct serializable_list_interpreter_t
template<typename Context, typename List>
struct serializable_list_interpreter_t
{
using T = List;
template<typename Separator>
static Context& _(const T& t, const Separator& separator, Context& context)
{ {
bool first = true; using T = List;
for (const auto entry : t._serializables)
{ template<typename Separator>
if (not first) static Context& _(const T& t, const Separator& separator, Context& context)
{ {
context << separator; bool first = true;
first = false; for (const auto entry : t._serializables)
{
if (not first)
{
context << separator;
first = false;
}
interpret(t, context);
}
return context;
} }
interpret(t, context); };
}
return context;
}
};
template<typename Context> template<typename Context>
struct serializable_list_interpreter_t<Context, detail::serializable_list<void>> struct serializable_list_interpreter_t<Context, interpretable_list_t<void>>
{
using T = detail::serializable_list<void>;
template<typename Separator>
static Context& _(const T& t, const Separator& separator, Context& context)
{ {
return context; using T = interpretable_list_t<void>;
template<typename Separator>
static Context& _(const T& t, const Separator& separator, Context& context)
{
return context;
}
};
template<typename T, typename Separator, typename Context>
auto interpret_list(const T& t, const Separator& separator, Context& context)
-> decltype(serializable_list_interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, separator, context))
{
return serializable_list_interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, separator, context);
} }
};
template<typename T, typename Separator, typename Context>
auto interpret_serializable_list(const T& t, const Separator& separator, Context& context)
-> decltype(serializable_list_interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, separator, context))
{
return serializable_list_interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, separator, context);
}
}
} }
#endif #endif

48
include/sqlpp11/vendor/interpreter.h vendored Normal file
View File

@ -0,0 +1,48 @@
/*
* 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_VENDOR_INTERPRET_H
#define SQLPP_VENDOR_INTERPRET_H
#include <sqlpp11/detail/wrong.h>
namespace sqlpp
{
namespace vendor
{
template<typename Context, typename T, typename Enable = void>
struct interpreter_t
{
static void _(const T& t, Context& context)
{
static_assert(detail::wrong<Context, T>::value, "missing interpreter specialization");
}
};
}
}
#endif

View File

@ -33,7 +33,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<bool NotInverted, typename Operand> template<bool NotInverted, typename Operand>
struct is_null_t: public boolean::template operators<is_null_t<NotInverted, Operand>> struct is_null_t: public boolean::template operators<is_null_t<NotInverted, Operand>>
@ -71,20 +71,20 @@ namespace sqlpp
Operand _operand; Operand _operand;
}; };
}
template<typename Context, bool NotInverted, typename Operand> template<typename Context, bool NotInverted, typename Operand>
struct interpreter_t<Context, detail::is_null_t<NotInverted, Operand>> struct interpreter_t<Context, ::sqlpp::vendor::is_null_t<NotInverted, Operand>>
{
using T = detail::is_null_t<NotInverted, Operand>;
static Context& _(const T& t, Context& context)
{ {
interpret(t._operand, context); using T = ::sqlpp::vendor::is_null_t<NotInverted, Operand>;
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
return context; static Context& _(const T& t, Context& context)
} {
}; interpret(t._operand, context);
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
return context;
}
};
}
} }

View File

@ -29,7 +29,7 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<bool NotInverted, typename Operand> template<bool NotInverted, typename Operand>
struct is_null_t; struct is_null_t;

View File

@ -33,62 +33,64 @@
namespace sqlpp namespace sqlpp
{ {
template<typename Operand, typename Pattern> namespace vendor
struct like_t: public boolean::template operators<like_t<Operand, Pattern>>
{ {
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text"); template<typename Operand, typename Pattern>
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text"); struct like_t: public boolean::template operators<like_t<Operand, Pattern>>
struct _value_type: public boolean
{ {
using _is_named_expression = std::true_type; 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");
struct _name_t struct _value_type: public boolean
{
static constexpr const char* _get_name() { return "LIKE"; }
template<typename T>
struct _member_t
{
T like;
};
};
like_t(Operand&& operand, Pattern&& pattern):
_operand(std::move(operand)),
_pattern(std::move(pattern))
{}
like_t(const Operand& operand, const Pattern& pattern):
_operand(operand),
_pattern(pattern)
{}
like_t(const like_t&) = default;
like_t(like_t&&) = default;
like_t& operator=(const like_t&) = default;
like_t& operator=(like_t&&) = default;
~like_t() = default;
Operand _operand;
Pattern _pattern;
};
template<typename Context, typename Operand, typename Pattern>
struct interpreter_t<Context, like_t<Operand, Pattern>>
{
using T = like_t<Operand, Pattern>;
static Context& _(const T& t, Context& context)
{ {
using _is_named_expression = std::true_type;
};
struct _name_t
{
static constexpr const char* _get_name() { return "LIKE"; }
template<typename T>
struct _member_t
{
T like;
};
};
like_t(Operand&& operand, Pattern&& pattern):
_operand(std::move(operand)),
_pattern(std::move(pattern))
{}
like_t(const Operand& operand, const Pattern& pattern):
_operand(operand),
_pattern(pattern)
{}
like_t(const like_t&) = default;
like_t(like_t&&) = default;
like_t& operator=(const like_t&) = default;
like_t& operator=(like_t&&) = default;
~like_t() = default;
Operand _operand;
Pattern _pattern;
};
template<typename Context, typename Operand, typename Pattern>
struct interpreter_t<Context, like_t<Operand, Pattern>>
{
using T = like_t<Operand, Pattern>;
static Context& _(const T& t, Context& context)
{
interpret(t._operand, context); interpret(t._operand, context);
context << " LIKE("; context << " LIKE(";
interpret(t._pattern, context); interpret(t._pattern, context);
context << ")"; context << ")";
return context; return context;
} }
}; };
}
} }
#endif #endif

View File

@ -33,53 +33,56 @@
namespace sqlpp namespace sqlpp
{ {
template<typename Limit> namespace vendor
struct limit_t {
template<typename Limit>
struct limit_t
{
using _is_limit = std::true_type;
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
Limit _limit;
};
template<typename Context, typename Limit>
struct interpreter_t<Context, limit_t<Limit>>
{
using T = limit_t<Limit>;
static Context& _(const T& t, Context& context)
{
context << " LIMIT ";
interpret(t._limit, context);
return context;
}
};
struct dynamic_limit_t
{ {
using _is_limit = std::true_type; using _is_limit = std::true_type;
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter"); using _is_dynamic = std::true_type;
Limit _limit; void set(std::size_t limit)
};
template<typename Context, typename Limit>
struct interpreter_t<Context, limit_t<Limit>>
{
using T = limit_t<Limit>;
static Context& _(const T& t, Context& context)
{ {
context << " LIMIT "; _limit = limit;
interpret(t._limit, context);
return context;
} }
std::size_t _limit;
}; };
struct dynamic_limit_t template<typename Context>
{ struct interpreter_t<Context, dynamic_limit_t>
using _is_limit = std::true_type;
using _is_dynamic = std::true_type;
void set(std::size_t limit)
{
_limit = limit;
}
std::size_t _limit;
};
template<typename Context>
struct interpreter_t<Context, dynamic_limit_t>
{
using T = dynamic_limit_t;
static Context& _(const T& t, Context& context)
{ {
if (t._limit > 0) using T = dynamic_limit_t;
context << " LIMIT " << t._limit;
return context; static Context& _(const T& t, Context& context)
} {
}; if (t._limit > 0)
context << " LIMIT " << t._limit;
return context;
}
};
}
} }

View File

@ -33,23 +33,23 @@
namespace sqlpp namespace sqlpp
{ {
namespace detail namespace vendor
{ {
template<typename Db> template<typename Db>
struct named_serializable_t struct named_interpretable_t
{ {
using _context_t = typename Db::context; using _context_t = typename Db::context;
template<typename T> template<typename T>
named_serializable_t(T t): named_interpretable_t(T t):
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t)) _impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t))
{} {}
named_serializable_t(const named_serializable_t&) = default; named_interpretable_t(const named_interpretable_t&) = default;
named_serializable_t(named_serializable_t&&) = default; named_interpretable_t(named_interpretable_t&&) = default;
named_serializable_t& operator=(const named_serializable_t&) = default; named_interpretable_t& operator=(const named_interpretable_t&) = default;
named_serializable_t& operator=(named_serializable_t&&) = default; named_interpretable_t& operator=(named_interpretable_t&&) = default;
~named_serializable_t() = default; ~named_interpretable_t() = default;
sqlpp::serializer& interpret(sqlpp::serializer& context) const sqlpp::serializer& interpret(sqlpp::serializer& context) const
{ {
@ -108,19 +108,19 @@ namespace sqlpp
std::shared_ptr<const _impl_base> _impl; std::shared_ptr<const _impl_base> _impl;
}; };
}
template<typename Context, typename Database> template<typename Context, typename Database>
struct interpreter_t<Context, detail::named_serializable_t<Database>> struct interpreter_t<Context, named_interpretable_t<Database>>
{
using T = detail::named_serializable_t<Database>;
static Context& _(const T& t, Context& context)
{ {
t.interpret(context); using T = named_interpretable_t<Database>;
return context;
} static Context& _(const T& t, Context& context)
}; {
t.interpret(context);
return context;
}
};
}
} }

View File

@ -28,26 +28,30 @@
#define SQLPP_NOOP_H #define SQLPP_NOOP_H
#include <type_traits> #include <type_traits>
#include <sqlpp11/vendor/noop_fwd.h>
namespace sqlpp namespace sqlpp
{ {
struct noop namespace vendor
{ {
}; struct noop
template<typename Context>
struct interpreter_t<Context, noop>
{ {
using T = noop;
static Context& _(const T& t, Context& context)
{
return context;
}
}; };
template<typename T> template<typename Context>
struct is_noop: std::is_same<T, noop> {}; struct interpreter_t<Context, noop>
{
using T = noop;
static Context& _(const T& t, Context& context)
{
return context;
}
};
template<typename T>
struct is_noop: std::is_same<T, noop> {};
}
} }
#endif #endif

View File

@ -29,9 +29,12 @@
namespace sqlpp namespace sqlpp
{ {
struct noop; namespace vendor
{
struct noop;
template<typename T> template<typename T>
struct is_noop; struct is_noop;
}
} }
#endif #endif

View File

@ -27,60 +27,61 @@
#ifndef SQLPP_OFFSET_H #ifndef SQLPP_OFFSET_H
#define SQLPP_OFFSET_H #define SQLPP_OFFSET_H
#include <ostream>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
namespace sqlpp namespace sqlpp
{ {
template<typename Offset> namespace vendor
struct offset_t {
template<typename Offset>
struct offset_t
{
using _is_offset = std::true_type;
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
Offset _offset;
};
template<typename Context, typename Offset>
struct interpreter_t<Context, offset_t<Offset>>
{
using T = offset_t<Offset>;
static Context& _(const T& t, Context& context)
{
context << " OFFSET ";
interpret(t._offset, context);
return context;
}
};
struct dynamic_offset_t
{ {
using _is_offset = std::true_type; using _is_offset = std::true_type;
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter"); using _is_dynamic = std::true_type;
Offset _offset; void set(std::size_t offset)
};
template<typename Context, typename Offset>
struct interpreter_t<Context, offset_t<Offset>>
{
using T = offset_t<Offset>;
static Context& _(const T& t, Context& context)
{ {
context << " OFFSET "; _offset = offset;
interpret(t._offset, context);
return context;
} }
std::size_t _offset;
}; };
struct dynamic_offset_t template<typename Context>
{ struct interpreter_t<Context, dynamic_offset_t>
using _is_offset = std::true_type;
using _is_dynamic = std::true_type;
void set(std::size_t offset)
{
_offset = offset;
}
std::size_t _offset;
};
template<typename Context>
struct interpreter_t<Context, dynamic_offset_t>
{
using T = dynamic_offset_t;
static Context& _(const T& t, Context& context)
{ {
if (t._offset > 0) using T = dynamic_offset_t;
context << " OFFSET " << t._offset;
return context;
}
};
static Context& _(const T& t, Context& context)
{
if (t._offset > 0)
context << " OFFSET " << t._offset;
return context;
}
};
}
} }
#endif #endif

88
include/sqlpp11/vendor/order_by.h vendored Normal file
View File

@ -0,0 +1,88 @@
/*
* 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_ORDER_BY_H
#define SQLPP_ORDER_BY_H
#include <tuple>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable.h>
namespace sqlpp
{
namespace vendor
{
template<typename Database,typename... Expr>
struct order_by_t
{
using _is_order_by = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
// check for duplicate order expressions
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()");
// check for invalid order expressions
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_sort_order_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()");
template<typename E>
void add(E&& expr)
{
static_assert(is_sort_order_t<typename std::decay<E>::type>::value, "order_by arguments require to be sort-order expressions");
_dynamic_expressions.push_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
vendor::interpretable_list_t<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, order_by_t<Database, Expr...>>
{
using T = order_by_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context;
context << " ORDER BY ";
interpret_tuple(t._expressions, ',', context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << ',';
interpret_list(t._dynamic_expressions, ',', context);
return context;
}
};
}
}
#endif

View File

@ -0,0 +1,204 @@
/*
* 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_EXPRESSION_LIST_H
#define SQLPP_SELECT_EXPRESSION_LIST_H
#include <tuple>
#include <sqlpp11/result_row.h>
#include <sqlpp11/select_fwd.h>
#include <sqlpp11/table.h>
#include <sqlpp11/vendor/expression_fwd.h>
#include <sqlpp11/no_value.h>
#include <sqlpp11/vendor/field.h>
#include <sqlpp11/vendor/select_pseudo_table.h>
#include <sqlpp11/vendor/named_interpretable.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/set.h>
namespace sqlpp
{
namespace detail
{
template<typename... Rest>
struct get_first_argument_if_unique
{
using _value_type = no_value_t;
struct _name_t {};
};
template<typename T>
struct get_first_argument_if_unique<T>
{
using _value_type = typename T::_value_type;
using _name_t = typename T::_name_t;
};
}
namespace vendor
{
template<typename Db>
struct dynamic_select_expression_list
{
using _names_t = std::vector<std::string>;
std::vector<vendor::named_interpretable_t<Db>> _dynamic_expressions;
_names_t _dynamic_expression_names;
template<typename Expr>
void push_back(Expr&& expr)
{
_dynamic_expression_names.push_back(std::decay<Expr>::type::_name_t::_get_name());
_dynamic_expressions.emplace_back(std::forward<Expr>(expr));
}
bool empty() const
{
return _dynamic_expressions.empty();
}
};
template<>
struct dynamic_select_expression_list<void>
{
struct _names_t {};
_names_t _dynamic_expression_names;
template<typename T>
void push_back(const T&) {}
static constexpr bool empty()
{
return true;
}
};
template<typename Context, typename Db>
struct interpreter_t<Context, dynamic_select_expression_list<Db>>
{
using T = dynamic_select_expression_list<Db>;
static Context& _(const T& t, Context& context)
{
for (const auto column : t._dynamic_expressions)
{
interpret(column, context);
}
return context;
}
};
template<typename Context>
struct interpreter_t<Context, dynamic_select_expression_list<void>>
{
using T = dynamic_select_expression_list<void>;
static Context& _(const T& t, Context& context)
{
return context;
}
};
template<typename Database, typename T>
struct select_expression_list_t
{
static_assert(::sqlpp::detail::wrong<Database, T>::value, "invalid template argument for select_expression_list");
};
template<typename Database, typename... NamedExpr>
struct select_expression_list_t<Database, std::tuple<NamedExpr...>>
{
using _is_select_expression_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<NamedExpr...>;
// check for at least one expression
static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
// check for duplicate select expressions
static_assert(not ::sqlpp::detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
// check for invalid select expressions
template<typename T>
struct is_valid_expression_t: public std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value> {};
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_valid_expression_t, NamedExpr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression");
// check for duplicate select expression names
static_assert(not ::sqlpp::detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
// provide type information for sub-selects that are used as expressions
struct _column_type {};
struct _value_type: ::sqlpp::detail::get_first_argument_if_unique<NamedExpr...>::_value_type
{
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
using _is_alias = std::false_type;
};
using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique<NamedExpr...>::_name_t;
using _result_row_t = typename std::conditional<_is_dynamic::value,
dynamic_result_row_t<make_field_t<NamedExpr>...>,
result_row_t<make_field_t<NamedExpr>...>>::type;
using _dynamic_names_t = typename dynamic_select_expression_list<Database>::_names_t;
template <typename Select>
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
template <typename Db>
using _dynamic_t = select_expression_list_t<Db, std::tuple<NamedExpr...>>;
template<typename Expr>
void add(Expr&& namedExpr)
{
static_assert(is_named_expression_t<typename std::decay<Expr>::type>::value, "select() arguments require to be named expressions");
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
_dynamic_expressions.push_back(std::forward<Expr>(namedExpr));
}
_parameter_tuple_t _expressions;
dynamic_select_expression_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... NamedExpr>
struct interpreter_t<Context, select_expression_list_t<Database, NamedExpr...>>
{
using T = select_expression_list_t<Database, NamedExpr...>;
static Context& _(const T& t, Context& context)
{
interpret_tuple(t._expressions, ',', context);
if (sizeof...(NamedExpr) and not t._dynamic_expressions.empty())
context << ',';
interpret(t._dynamic_expressions, context);
return context;
}
};
}
}
#endif

View File

@ -30,9 +30,8 @@
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <tuple> #include <tuple>
#include <ostream>
namespace sqlpp namespace sqlpp
{ {
@ -47,7 +46,7 @@ namespace sqlpp
static constexpr all_t all = {}; static constexpr all_t all = {};
template<typename Context> template<typename Context>
struct interpreter_t<Context, all_t> struct vendor::interpreter_t<Context, all_t>
{ {
static Context& _(const all_t&, Context& context) static Context& _(const all_t&, Context& context)
{ {
@ -66,7 +65,7 @@ namespace sqlpp
static constexpr distinct_t distinct = {}; static constexpr distinct_t distinct = {};
template<typename Context> template<typename Context>
struct interpreter_t<Context, distinct_t> struct vendor::interpreter_t<Context, distinct_t>
{ {
static Context& _(const distinct_t&, Context& context) static Context& _(const distinct_t&, Context& context)
{ {
@ -85,7 +84,7 @@ namespace sqlpp
static constexpr straight_join_t straight_join = {}; static constexpr straight_join_t straight_join = {};
template<typename Context> template<typename Context>
struct interpreter_t<Context, straight_join_t> struct vendor::interpreter_t<Context, straight_join_t>
{ {
static Context& _(const straight_join_t&, Context& context) static Context& _(const straight_join_t&, Context& context)
{ {
@ -94,36 +93,44 @@ namespace sqlpp
} }
}; };
// select_flag_list_t namespace vendor
template<typename... Flag> {
struct select_flag_list_t<std::tuple<Flag...>> template<typename T>
{ struct select_flag_list_t
// check for duplicate order expressions
static_assert(not detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
// check for invalid order expressions
using _valid_flags = typename detail::make_set_if<is_select_flag_t, Flag...>::type;
static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list");
using _is_select_flag_list = std::true_type;
std::tuple<Flag...> _flags;
};
template<typename Context, typename... Flag>
struct interpreter_t<Context, select_flag_list_t<std::tuple<Flag...>>>
{
using T = select_flag_list_t<std::tuple<Flag...>>;
static Context& _(const T& t, Context& context)
{ {
interpret_tuple(t._flags, ' ', context); static_assert(detail::wrong<T>::value, "invalid argument for select_flag_list");
if (sizeof...(Flag)) };
context << ' ';
return context;
}
};
// select_flag_list_t
template<typename... Flag>
struct select_flag_list_t<std::tuple<Flag...>>
{
// check for duplicate order expressions
static_assert(not detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
// check for invalid order expressions
using _valid_flags = typename detail::make_set_if<is_select_flag_t, Flag...>::type;
static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list");
using _is_select_flag_list = std::true_type;
std::tuple<Flag...> _flags;
};
template<typename Context, typename... Flag>
struct interpreter_t<Context, select_flag_list_t<std::tuple<Flag...>>>
{
using T = select_flag_list_t<std::tuple<Flag...>>;
static Context& _(const T& t, Context& context)
{
interpret_tuple(t._flags, ' ', context);
if (sizeof...(Flag))
context << ' ';
return context;
}
};
}
} }

View File

@ -71,7 +71,7 @@ namespace sqlpp
}; };
template<typename Context, typename Select, typename... NamedExpr> template<typename Context, typename Select, typename... NamedExpr>
struct interpreter_t<Context, select_pseudo_table_t<Select, NamedExpr...>> struct vendor::interpreter_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
{ {
using T = select_pseudo_table_t<Select, NamedExpr...>; using T = select_pseudo_table_t<Select, NamedExpr...>;

90
include/sqlpp11/vendor/update_list.h vendored Normal file
View File

@ -0,0 +1,90 @@
/*
* 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_UPDATE_LIST_H
#define SQLPP_UPDATE_LIST_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/vendor/interpretable_list.h>
namespace sqlpp
{
namespace vendor
{
template<typename Database, typename... Assignments>
struct update_list_t
{
using _is_update_list = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Assignments...>;
// check for at least one order expression
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
// check for duplicate assignments
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
// check for invalid assignments
using _assignment_set = typename ::sqlpp::detail::make_set_if<is_assignment_t, Assignments...>::type;
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
// check for prohibited assignments
using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if<must_not_update_t, typename Assignments::column_type...>::type;
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
template<typename Assignment>
void add(Assignment&& assignment)
{
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
static_assert(not must_not_update_t<typename std::decay<Assignment>::type::column_type>::value, "set() argument must not be updated");
_dynamic_assignments.emplace_back(std::forward<Assignment>(assignment));
}
_parameter_tuple_t _assignments;
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
};
template<typename Context, typename Database, typename... Assignments>
struct interpreter_t<Context, update_list_t<Database, Assignments...>>
{
using T = update_list_t<Database, Assignments...>;
static Context& _(const T& t, Context& context)
{
context << " SET ";
interpret_tuple(t._assignments, ",", context);
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
context << ',';
interpret_list(t._dynamic_assignments, ',', context);
return context;
}
};
}
}
#endif

87
include/sqlpp11/vendor/using.h vendored Normal file
View File

@ -0,0 +1,87 @@
/*
* 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_USING_H
#define SQLPP_USING_H
#include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h>
#include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/vendor/interpret_tuple.h>
namespace sqlpp
{
namespace vendor
{
template<typename Database, typename... Table>
struct using_t
{
using _is_using = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Table...>;
static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()");
// check for duplicate arguments
static_assert(not ::sqlpp::detail::has_duplicates<Table...>::value, "at least one duplicate argument detected in using()");
// check for invalid arguments
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_table_t, Table...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()");
template<typename T>
void add(T&& table)
{
static_assert(is_table_t<typename std::decay<T>::type>::value, "using() arguments require to be tables");
_dynamic_tables.emplace_back(std::forward<T>(table));
}
_parameter_tuple_t _tables;
vendor::interpretable_list_t<Database> _dynamic_tables;
};
template<typename Context, typename Database, typename... Table>
struct interpreter_t<Context, using_t<Database, Table...>>
{
using T = using_t<Database, Table...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Table) == 0 and t._dynamic_tables.empty())
return context;
context << " USING ";
interpret_tuple(t._tables, ',', context);
if (sizeof...(Table) and not t._dynamic_tables.empty())
context << ',';
interpret_list(t._dynamic_tables, ',', context);
return context;
}
};
}
}
#endif

View File

@ -29,57 +29,60 @@
#include <ostream> #include <ostream>
#include <sqlpp11/select_fwd.h> #include <sqlpp11/select_fwd.h>
#include <sqlpp11/expression.h> #include <sqlpp11/vendor/expression.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/detail/set.h> #include <sqlpp11/detail/set.h>
#include <sqlpp11/detail/serialize_tuple.h> #include <sqlpp11/vendor/interpret_tuple.h>
#include <sqlpp11/detail/serializable_list.h> #include <sqlpp11/vendor/interpretable_list.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
namespace sqlpp namespace sqlpp
{ {
template<typename Database, typename... Expr> namespace vendor
struct where_t {
{ template<typename Database, typename... Expr>
using _is_where = std::true_type; struct where_t
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
template<typename E>
void add(E&& expr)
{
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_where()");
_dynamic_expressions.emplace_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
detail::serializable_list<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, where_t<Database, Expr...>>
{
using T = where_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{ {
using _is_where = std::true_type;
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
using _parameter_tuple_t = std::tuple<Expr...>;
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
using _valid_expressions = typename sqlpp::detail::make_set_if<is_expression_t, Expr...>::type;
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
template<typename E>
void add(E&& expr)
{
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_where()");
_dynamic_expressions.emplace_back(std::forward<E>(expr));
}
_parameter_tuple_t _expressions;
vendor::interpretable_list_t<Database> _dynamic_expressions;
};
template<typename Context, typename Database, typename... Expr>
struct interpreter_t<Context, where_t<Database, Expr...>>
{
using T = where_t<Database, Expr...>;
static Context& _(const T& t, Context& context)
{
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty()) if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
return context; return context;
context << " WHERE "; context << " WHERE ";
interpret_tuple(t._expressions, " AND ", context); interpret_tuple(t._expressions, " AND ", context);
if (sizeof...(Expr) and not t._dynamic_expressions.empty()) if (sizeof...(Expr) and not t._dynamic_expressions.empty())
context << " AND "; context << " AND ";
interpret_serializable_list(t._dynamic_expressions, " AND ", context); interpret_list(t._dynamic_expressions, " AND ", context);
return context; return context;
} }
}; };
}
} }
#endif #endif

168
include/sqlpp11/vendor/wrap_operand.h vendored Normal file
View File

@ -0,0 +1,168 @@
/*
* 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_DETAIL_WRAP_OPERAND_H
#define SQLPP_DETAIL_WRAP_OPERAND_H
#include <string>
#include <sqlpp11/vendor/interpreter.h>
namespace sqlpp
{
namespace detail
{
struct boolean;
struct integral;
struct floating_point;
struct text;
}
namespace vendor
{
struct boolean_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::boolean;
bool _is_trivial() const { return _t == false; }
bool _t;
};
template<typename Context>
struct interpreter_t<Context, boolean_operand>
{
using Operand = boolean_operand;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
template<typename T>
struct integral_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::integral;
bool _is_trivial() const { return _t == 0; }
T _t;
};
template<typename Context, typename T>
struct interpreter_t<Context, integral_operand<T>>
{
using Operand = integral_operand<T>;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
template<typename T>
struct floating_point_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::floating_point;
bool _is_trivial() const { return _t == 0; }
T _t;
};
template<typename Context, typename T>
struct interpreter_t<Context, floating_point_operand<T>>
{
using Operand = floating_point_operand<T>;
static Context& _(const Operand& t, Context& context)
{
context << t._t;
return context;
}
};
struct text_operand
{
static constexpr bool _is_expression = true;
using _value_type = detail::text;
bool _is_trivial() const { return _t.empty(); }
std::string _t;
};
template<typename Context>
struct interpreter_t<Context, text_operand>
{
using Operand = text_operand;
static Context& _(const Operand& t, Context& context)
{
context << '\'' << context.escape(t._t) << '\'';
return context;
}
};
template<typename T, typename Enable = void>
struct wrap_operand
{
using type = T;
};
template<>
struct wrap_operand<bool, void>
{
using type = boolean_operand;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
using type = integral_operand<T>;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
{
using type = floating_point_operand<T>;
};
template<typename T>
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
{
using type = text_operand;
};
}
}
#endif

View File

@ -66,7 +66,7 @@ namespace sqlpp
}; };
template<typename Context> template<typename Context>
struct interpreter_t<Context, verbatim_table_t> struct vendor::interpreter_t<Context, verbatim_table_t>
{ {
using T = verbatim_table_t; using T = verbatim_table_t;

View File

@ -25,6 +25,7 @@
#include "TabSample.h" #include "TabSample.h"
#include "MockDb.h" #include "MockDb.h"
#include <sqlpp11/alias_provider.h>
#include <sqlpp11/insert.h> #include <sqlpp11/insert.h>
#include <sqlpp11/select.h> #include <sqlpp11/select.h>
#include <sqlpp11/update.h> #include <sqlpp11/update.h>
@ -35,7 +36,7 @@
DbMock db = {}; DbMock db = {};
DbMock::context printer(std::cerr); DbMock::context printer(std::cerr);
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen); SQLPP_ALIAS_PROVIDER(kaesekuchen);
int main() int main()
{ {
@ -61,6 +62,7 @@ int main()
interpret(parameter(t.alpha), printer).flush(); interpret(parameter(t.alpha), printer).flush();
interpret(t.alpha == parameter(t.alpha), printer).flush(); interpret(t.alpha == parameter(t.alpha), printer).flush();
interpret(t.alpha == parameter(t.alpha) and (t.beta + "gimmick").like(parameter(t.beta)), printer).flush();
interpret(insert_into(t), printer).flush(); interpret(insert_into(t), printer).flush();
interpret(insert_into(t).default_values(), printer).flush(); interpret(insert_into(t).default_values(), printer).flush();
@ -76,7 +78,7 @@ int main()
interpret(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).flush(); interpret(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
// functions // functions
interpret(sqlpp::value(7), printer).flush(); sqlpp::interpret(sqlpp::value(7), printer).flush(); // FIXME: Why is the namespace specifier required?
interpret(sqlpp::verbatim<sqlpp::detail::integral>("irgendwas integrales"), printer).flush(); interpret(sqlpp::verbatim<sqlpp::detail::integral>("irgendwas integrales"), printer).flush();
interpret(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).flush(); interpret(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).flush();
interpret(exists(select(t.alpha).from(t)), printer).flush(); interpret(exists(select(t.alpha).from(t)), printer).flush();
@ -107,6 +109,5 @@ int main()
// dynamic select // dynamic select
interpret(dynamic_select(db, t.alpha).dynamic_columns().add_column(t.beta), printer).flush(); interpret(dynamic_select(db, t.alpha).dynamic_columns().add_column(t.beta), printer).flush();
return 0; return 0;
} }