mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Merge branch 'feature/remove_namespace_vendor' into develop
This commit is contained in:
commit
d4684f7dc0
@ -28,7 +28,7 @@
|
|||||||
#define SQLPP_ALIAS_H
|
#define SQLPP_ALIAS_H
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -46,8 +46,6 @@ namespace sqlpp
|
|||||||
Expression _expression;
|
Expression _expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Expression, typename AliasProvider>
|
template<typename Context, typename Expression, typename AliasProvider>
|
||||||
struct serializer_t<Context, expression_alias_t<Expression, AliasProvider>>
|
struct serializer_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||||
{
|
{
|
||||||
@ -64,6 +62,5 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,8 +51,6 @@ namespace sqlpp
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Table>
|
template<typename Context, typename Table>
|
||||||
struct serializer_t<Context, all_of_t<Table>>
|
struct serializer_t<Context, all_of_t<Table>>
|
||||||
{
|
{
|
||||||
@ -63,7 +61,6 @@ namespace sqlpp
|
|||||||
static_assert(wrong_t<T>::value, "all_of(table) does not seem to be used in select");
|
static_assert(wrong_t<T>::value, "all_of(table) does not seem to be used in select");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@
|
|||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Select>
|
template<typename Select>
|
||||||
struct any_t
|
struct any_t
|
||||||
@ -64,14 +62,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Select _select;
|
Select _select;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Select>
|
template<typename Context, typename Select>
|
||||||
struct serializer_t<Context, vendor::any_t<Select>>
|
struct serializer_t<Context, any_t<Select>>
|
||||||
{
|
{
|
||||||
using T = vendor::any_t<Select>;
|
using T = any_t<Select>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -83,15 +78,14 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto any(T t) -> typename vendor::any_t<vendor::wrap_operand_t<T>>
|
auto any(T t) -> any_t<wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_select_t<vendor::wrap_operand_t<T>>::value, "any() requires a select expression as argument");
|
static_assert(is_select_t<wrap_operand_t<T>>::value, "any() requires a select expression as argument");
|
||||||
static_assert(is_expression_t<vendor::wrap_operand_t<T>>::value, "any() requires a single column select expression as argument");
|
static_assert(is_expression_t<wrap_operand_t<T>>::value, "any() requires a single column select expression as argument");
|
||||||
// FIXME: can we accept non-values like NULL here?
|
// FIXME: can we accept non-values like NULL here?
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
161
include/sqlpp11/assignment.h
Normal file
161
include/sqlpp11/assignment.h
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_H
|
||||||
|
#define SQLPP_ASSIGNMENT_H
|
||||||
|
|
||||||
|
#include <sqlpp11/default_value.h>
|
||||||
|
#include <sqlpp11/null.h>
|
||||||
|
#include <sqlpp11/tvin.h>
|
||||||
|
#include <sqlpp11/serialize.h>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
#include <sqlpp11/simple_column.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename T, typename Enable = void>
|
||||||
|
struct is_trivial_t
|
||||||
|
{
|
||||||
|
static constexpr bool _(const T&)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_trivial_t<T, typename std::enable_if<std::is_member_function_pointer<decltype(&T::_is_trivial)>::value, void>::type>
|
||||||
|
{
|
||||||
|
static bool _(const T& t)
|
||||||
|
{
|
||||||
|
return t._is_trivial();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool is_trivial(const T& t)
|
||||||
|
{
|
||||||
|
return is_trivial_t<T>::_(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
struct assignment_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||||
|
|
||||||
|
using _column_t = Lhs;
|
||||||
|
using _value_t = Rhs;
|
||||||
|
|
||||||
|
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<_value_t, null_t>::value, "column must not be null");
|
||||||
|
|
||||||
|
assignment_t(_column_t lhs, _value_t 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;
|
||||||
|
|
||||||
|
_column_t _lhs;
|
||||||
|
_value_t _rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Lhs, typename Rhs>
|
||||||
|
struct serializer_t<Context, assignment_t<Lhs, Rhs>>
|
||||||
|
{
|
||||||
|
using T = assignment_t<Lhs, Rhs>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
||||||
|
and is_trivial(t._rhs))
|
||||||
|
or (std::is_same<Rhs, null_t>::value))
|
||||||
|
{
|
||||||
|
serialize(simple_column(t._lhs), context);
|
||||||
|
context << "=NULL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serialize(simple_column(t._lhs), context);
|
||||||
|
context << "=";
|
||||||
|
serialize(t._rhs, context);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
struct assignment_t<Lhs, tvin_t<Rhs>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||||
|
|
||||||
|
using _column_t = Lhs;
|
||||||
|
using _value_t = tvin_t<Rhs>;
|
||||||
|
|
||||||
|
static_assert(can_be_null_t<_column_t>::value, "column cannot be null");
|
||||||
|
|
||||||
|
assignment_t(_column_t lhs, _value_t 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;
|
||||||
|
|
||||||
|
_column_t _lhs;
|
||||||
|
_value_t _rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Lhs, typename Rhs>
|
||||||
|
struct serializer_t<Context, assignment_t<Lhs, tvin_t<Rhs>>>
|
||||||
|
{
|
||||||
|
using T = assignment_t<Lhs, tvin_t<Rhs>>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
serialize(simple_column(t._lhs), context);
|
||||||
|
if (t._rhs._value._is_trivial())
|
||||||
|
{
|
||||||
|
context << "=NULL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context << "=";
|
||||||
|
serialize(t._rhs._value, context);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -30,8 +30,6 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Flag, typename Expr>
|
template<typename Flag, typename Expr>
|
||||||
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>,
|
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>,
|
||||||
@ -67,14 +65,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Expr _expr;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Flag, typename Expr>
|
template<typename Context, typename Flag, typename Expr>
|
||||||
struct serializer_t<Context, vendor::avg_t<Flag, Expr>>
|
struct serializer_t<Context, avg_t<Flag, Expr>>
|
||||||
{
|
{
|
||||||
using T = vendor::avg_t<Flag, Expr>;
|
using T = avg_t<Flag, Expr>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -89,19 +84,18 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto avg(T t) -> typename vendor::avg_t<vendor::noop, vendor::wrap_operand_t<T>>
|
auto avg(T t) -> avg_t<noop, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_numeric_t<vendor::wrap_operand_t<T>>::value, "avg() requires a value expression as argument");
|
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a value expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto avg(const sqlpp::distinct_t&, T t) -> typename vendor::avg_t<sqlpp::distinct_t, vendor::wrap_operand_t<T>>
|
auto avg(const sqlpp::distinct_t&, T t) -> avg_t<sqlpp::distinct_t, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_numeric_t<vendor::wrap_operand_t<T>>::value, "avg() requires a value expression as argument");
|
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "avg() requires a value expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@
|
|||||||
|
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/sort_order.h>
|
#include <sqlpp11/sort_order.h>
|
||||||
#include <sqlpp11/vendor/expression_fwd.h>
|
#include <sqlpp11/expression_fwd.h>
|
||||||
#include <sqlpp11/vendor/in_fwd.h>
|
#include <sqlpp11/in_fwd.h>
|
||||||
#include <sqlpp11/vendor/is_null_fwd.h>
|
#include <sqlpp11/is_null_fwd.h>
|
||||||
#include <sqlpp11/vendor/wrap_operand.h>
|
#include <sqlpp11/wrap_operand.h>
|
||||||
#include <sqlpp11/detail/logic.h>
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -52,65 +52,65 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::equal_to_t<Base, vendor::wrap_operand_t<T>> operator==(T t) const
|
equal_to_t<Base, wrap_operand_t<T>> operator==(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::not_equal_to_t<Base, vendor::wrap_operand_t<T>> operator!=(T t) const
|
not_equal_to_t<Base, wrap_operand_t<T>> operator!=(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::less_than_t<Base, vendor::wrap_operand_t<T>> operator<(T t) const
|
less_than_t<Base, wrap_operand_t<T>> operator<(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::less_equal_t<Base, vendor::wrap_operand_t<T>> operator<=(T t) const
|
less_equal_t<Base, wrap_operand_t<T>> operator<=(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::greater_than_t<Base, vendor::wrap_operand_t<T>> operator>(T t) const
|
greater_than_t<Base, wrap_operand_t<T>> operator>(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::greater_equal_t<Base, vendor::wrap_operand_t<T>> operator>=(T t) const
|
greater_equal_t<Base, wrap_operand_t<T>> operator>=(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
static_assert(_is_valid_comparison_operand<rhs>::value, "invalid rhs operand in comparison");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::is_null_t<true, Base> is_null() const
|
is_null_t<true, Base> is_null() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::is_null_t<false, Base> is_not_null() const
|
is_null_t<false, Base> is_not_null() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
@ -127,17 +127,17 @@ namespace sqlpp
|
|||||||
|
|
||||||
// Hint: use value_list wrapper for containers...
|
// Hint: use value_list wrapper for containers...
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
vendor::in_t<true, Base, vendor::wrap_operand_t<T>...> in(T... t) const
|
in_t<true, Base, wrap_operand_t<T>...> in(T... t) const
|
||||||
{
|
{
|
||||||
static_assert(detail::all_t<_is_valid_comparison_operand<vendor::wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
static_assert(detail::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||||
return { *static_cast<const Base*>(this), vendor::wrap_operand_t<T>{t}... };
|
return { *static_cast<const Base*>(this), wrap_operand_t<T>{t}... };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
vendor::in_t<false, Base, vendor::wrap_operand_t<T>...> not_in(T... t) const
|
in_t<false, Base, wrap_operand_t<T>...> not_in(T... t) const
|
||||||
{
|
{
|
||||||
static_assert(detail::all_t<_is_valid_comparison_operand<vendor::wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
static_assert(detail::all_t<_is_valid_comparison_operand<wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||||
return { *static_cast<const Base*>(this), vendor::wrap_operand_t<T>{t}... };
|
return { *static_cast<const Base*>(this), wrap_operand_t<T>{t}... };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,24 +184,24 @@ namespace sqlpp
|
|||||||
struct expression_operators: public basic_expression_operators<Base, is_boolean_t>
|
struct expression_operators: public basic_expression_operators<Base, is_boolean_t>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::logical_and_t<Base, vendor::wrap_operand_t<T>> operator and(T t) const
|
logical_and_t<Base, wrap_operand_t<T>> operator and(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::logical_or_t<Base, vendor::wrap_operand_t<T>> operator or(T t) const
|
logical_or_t<Base, wrap_operand_t<T>> operator or(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::logical_not_t<Base> operator not() const
|
logical_not_t<Base> operator not() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,10 @@
|
|||||||
#include <sqlpp11/null.h>
|
#include <sqlpp11/null.h>
|
||||||
#include <sqlpp11/sort_order.h>
|
#include <sqlpp11/sort_order.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/vendor/assignment.h>
|
#include <sqlpp11/assignment.h>
|
||||||
#include <sqlpp11/vendor/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -81,30 +81,28 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator =(T t) const -> vendor::assignment_t<column_t, vendor::wrap_operand_t<T>>
|
auto operator =(T t) const -> assignment_t<column_t, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand assignment operand");
|
||||||
|
|
||||||
return { *this, rhs{t} };
|
return { *this, rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator =(sqlpp::null_t) const
|
auto operator =(sqlpp::null_t) const
|
||||||
->vendor::assignment_t<column_t, sqlpp::null_t>
|
->assignment_t<column_t, sqlpp::null_t>
|
||||||
{
|
{
|
||||||
static_assert(can_be_null_t<column_t>::value, "column cannot be null");
|
static_assert(can_be_null_t<column_t>::value, "column cannot be null");
|
||||||
return { *this, {} };
|
return { *this, {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator =(sqlpp::default_value_t) const
|
auto operator =(sqlpp::default_value_t) const
|
||||||
->vendor::assignment_t<column_t, sqlpp::default_value_t>
|
->assignment_t<column_t, sqlpp::default_value_t>
|
||||||
{
|
{
|
||||||
return { *this, {} };
|
return { *this, {} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename... Args>
|
template<typename Context, typename... Args>
|
||||||
struct serializer_t<Context, column_t<Args...>>
|
struct serializer_t<Context, column_t<Args...>>
|
||||||
{
|
{
|
||||||
@ -118,6 +116,5 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
84
include/sqlpp11/concat.h
Normal file
84
include/sqlpp11/concat.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_CONCAT_H
|
||||||
|
#define SQLPP_CONCAT_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// FIXME: Remove First, inherit from text_t
|
||||||
|
template<typename First, typename... Args>
|
||||||
|
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>,
|
||||||
|
public alias_operators<concat_t<First, Args...>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||||
|
using _recursive_traits = make_recursive_traits<First, Args...>;
|
||||||
|
|
||||||
|
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||||
|
static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
|
||||||
|
struct _name_t
|
||||||
|
{
|
||||||
|
static constexpr const char* _get_name() { return "CONCAT"; }
|
||||||
|
template<typename T>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
T concat;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
concat_t(First first, Args... args):
|
||||||
|
_args(first, args...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
concat_t(const concat_t&) = default;
|
||||||
|
concat_t(concat_t&&) = default;
|
||||||
|
concat_t& operator=(const concat_t&) = default;
|
||||||
|
concat_t& operator=(concat_t&&) = default;
|
||||||
|
~concat_t() = default;
|
||||||
|
|
||||||
|
std::tuple<First, Args...> _args;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename First, typename... Args>
|
||||||
|
struct serializer_t<Context, concat_t<First, Args...>>
|
||||||
|
{
|
||||||
|
using T = concat_t<First, Args...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "(";
|
||||||
|
interpret_tuple(t._args, "||", context);
|
||||||
|
context << ")";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -31,8 +31,6 @@
|
|||||||
#include <sqlpp11/integral.h>
|
#include <sqlpp11/integral.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Flag, typename Expr>
|
template<typename Flag, typename Expr>
|
||||||
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>,
|
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>,
|
||||||
@ -68,14 +66,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Expr _expr;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Flag, typename Expr>
|
template<typename Context, typename Flag, typename Expr>
|
||||||
struct serializer_t<Context, vendor::count_t<Flag, Expr>>
|
struct serializer_t<Context, count_t<Flag, Expr>>
|
||||||
{
|
{
|
||||||
using T = vendor::count_t<Flag, Expr>;
|
using T = count_t<Flag, Expr>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -90,19 +85,18 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto count(T t) -> typename vendor::count_t<vendor::noop, vendor::wrap_operand_t<T>>
|
auto count(T t) -> count_t<noop, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_expression_t<vendor::wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto count(const sqlpp::distinct_t&, T t) -> typename vendor::count_t<sqlpp::distinct_t, vendor::wrap_operand_t<T>>
|
auto count(const sqlpp::distinct_t&, T t) -> count_t<sqlpp::distinct_t, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_expression_t<vendor::wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
static_assert(is_expression_t<wrap_operand_t<T>>::value, "count() requires an expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@ namespace sqlpp
|
|||||||
static constexpr bool _is_trivial() { return false; }
|
static constexpr bool _is_trivial() { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, default_value_t>
|
struct serializer_t<Context, default_value_t>
|
||||||
{
|
{
|
||||||
@ -52,7 +50,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
constexpr default_value_t default_value = {};
|
constexpr default_value_t default_value = {};
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t LastIndex, std::size_t... Ints, typename AliasProvider, typename... Fields, typename... Rest>
|
template<std::size_t LastIndex, std::size_t... Ints, typename AliasProvider, typename... Fields, typename... Rest>
|
||||||
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>, vendor::multi_field_t<AliasProvider, Fields...>, Rest...>
|
struct make_column_index_sequence_impl<column_index_sequence<LastIndex, Ints...>, multi_field_t<AliasProvider, Fields...>, Rest...>
|
||||||
{
|
{
|
||||||
using type = typename make_column_index_sequence_impl<column_index_sequence<LastIndex + sizeof...(Fields), Ints..., LastIndex + sizeof...(Fields)>, Rest...>::type;
|
using type = typename make_column_index_sequence_impl<column_index_sequence<LastIndex + sizeof...(Fields), Ints..., LastIndex + sizeof...(Fields)>, Rest...>::type;
|
||||||
};
|
};
|
||||||
|
@ -57,7 +57,7 @@ namespace sqlpp
|
|||||||
template<template<typename, typename...> class Target, typename First, typename T>
|
template<template<typename, typename...> class Target, typename First, typename T>
|
||||||
struct copy_tuple_args_impl
|
struct copy_tuple_args_impl
|
||||||
{
|
{
|
||||||
static_assert(vendor::wrong_t<T>::value, "copy_tuple_args must be called with a tuple");
|
static_assert(wrong_t<T>::value, "copy_tuple_args must be called with a tuple");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename First, typename...> class Target, typename First, typename... Args>
|
template<template<typename First, typename...> class Target, typename First, typename... Args>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
#include <sqlpp11/detail/logic.h>
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -73,7 +73,7 @@ namespace sqlpp
|
|||||||
template<typename E, typename SET>
|
template<typename E, typename SET>
|
||||||
struct is_element_of
|
struct is_element_of
|
||||||
{
|
{
|
||||||
static_assert(::sqlpp::vendor::wrong_t<E, SET>::value, "SET has to be a type set");
|
static_assert(::sqlpp::wrong_t<E, SET>::value, "SET has to be a type set");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename E, typename... Elements>
|
template<typename E, typename... Elements>
|
||||||
@ -85,7 +85,7 @@ namespace sqlpp
|
|||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
struct joined_set
|
struct joined_set
|
||||||
{
|
{
|
||||||
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
|
static_assert(::sqlpp::wrong_t<L, R>::value, "L and R have to be type sets");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... LElements, typename... RElements>
|
template<typename... LElements, typename... RElements>
|
||||||
@ -100,7 +100,7 @@ namespace sqlpp
|
|||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
struct is_superset_of
|
struct is_superset_of
|
||||||
{
|
{
|
||||||
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "L and R have to be type sets");
|
static_assert(::sqlpp::wrong_t<L, R>::value, "L and R have to be type sets");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... LElements, typename... RElements>
|
template<typename... LElements, typename... RElements>
|
||||||
@ -118,7 +118,7 @@ namespace sqlpp
|
|||||||
template<typename L, typename R>
|
template<typename L, typename R>
|
||||||
struct is_disjunct_from
|
struct is_disjunct_from
|
||||||
{
|
{
|
||||||
static_assert(::sqlpp::vendor::wrong_t<L, R>::value, "invalid argument for is_disjunct_from");
|
static_assert(::sqlpp::wrong_t<L, R>::value, "invalid argument for is_disjunct_from");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... LElements, typename... RElements>
|
template<typename... LElements, typename... RElements>
|
||||||
@ -174,7 +174,7 @@ namespace sqlpp
|
|||||||
template<typename... T>
|
template<typename... T>
|
||||||
struct make_joined_set
|
struct make_joined_set
|
||||||
{
|
{
|
||||||
static_assert(::sqlpp::vendor::wrong_t<T...>::value, "invalid argument for joined set");
|
static_assert(::sqlpp::wrong_t<T...>::value, "invalid argument for joined set");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -197,7 +197,7 @@ namespace sqlpp
|
|||||||
template<typename Minuend, typename Subtrahend>
|
template<typename Minuend, typename Subtrahend>
|
||||||
struct make_difference_set
|
struct make_difference_set
|
||||||
{
|
{
|
||||||
static_assert(::sqlpp::vendor::wrong_t<Minuend, Subtrahend>::value, "invalid argument for difference set");
|
static_assert(::sqlpp::wrong_t<Minuend, Subtrahend>::value, "invalid argument for difference set");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Minuends, typename... Subtrahends>
|
template<typename... Minuends, typename... Subtrahends>
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
#include <sqlpp11/boolean.h>
|
#include <sqlpp11/boolean.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Select>
|
template<typename Select>
|
||||||
struct exists_t: public boolean::template expression_operators<exists_t<Select>>,
|
struct exists_t: public boolean::template expression_operators<exists_t<Select>>,
|
||||||
@ -66,14 +64,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Select _select;
|
Select _select;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Select>
|
template<typename Context, typename Select>
|
||||||
struct serializer_t<Context, vendor::exists_t<Select>>
|
struct serializer_t<Context, exists_t<Select>>
|
||||||
{
|
{
|
||||||
using T = vendor::exists_t<Select>;
|
using T = exists_t<Select>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -83,13 +78,12 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto exists(T t) -> typename vendor::exists_t<vendor::wrap_operand_t<T>>
|
auto exists(T t) -> exists_t<wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_select_t<vendor::wrap_operand_t<T>>::value, "exists() requires a select expression as argument");
|
static_assert(is_select_t<wrap_operand_t<T>>::value, "exists() requires a select expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
239
include/sqlpp11/expression.h
Normal file
239
include/sqlpp11/expression.h
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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/noop.h>
|
||||||
|
#include <sqlpp11/expression_fwd.h>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
#include <sqlpp11/wrap_operand.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
struct binary_expression_t<Lhs, op::equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>,
|
||||||
|
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||||
|
using _recursive_traits = make_recursive_traits<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;
|
||||||
|
maybe_tvin_t<Rhs> _rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Lhs, typename Rhs>
|
||||||
|
struct serializer_t<Context, equal_to_t<Lhs, Rhs>>
|
||||||
|
{
|
||||||
|
using T = equal_to_t<Lhs, Rhs>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "(";
|
||||||
|
serialize(t._lhs, context);
|
||||||
|
if (t._rhs._is_trivial())
|
||||||
|
{
|
||||||
|
context << " IS NULL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context << "=";
|
||||||
|
serialize(t._rhs, context);
|
||||||
|
}
|
||||||
|
context << ")";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>,
|
||||||
|
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||||
|
using _recursive_traits = make_recursive_traits<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;
|
||||||
|
maybe_tvin_t<Rhs> _rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Lhs, typename Rhs>
|
||||||
|
struct serializer_t<Context, not_equal_to_t<Lhs, Rhs>>
|
||||||
|
{
|
||||||
|
using T = not_equal_to_t<Lhs, Rhs>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "(";
|
||||||
|
serialize(t._lhs, context);
|
||||||
|
if (t._rhs._is_trivial())
|
||||||
|
{
|
||||||
|
context << " IS NOT NULL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context << "!=";
|
||||||
|
serialize(t._rhs, context);
|
||||||
|
}
|
||||||
|
context << ")";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Rhs>
|
||||||
|
struct unary_expression_t<op::logical_not, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<unary_expression_t<op::logical_not, Rhs>>,
|
||||||
|
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||||
|
|
||||||
|
unary_expression_t(Rhs rhs):
|
||||||
|
_rhs(rhs)
|
||||||
|
{}
|
||||||
|
|
||||||
|
unary_expression_t(const unary_expression_t&) = default;
|
||||||
|
unary_expression_t(unary_expression_t&&) = default;
|
||||||
|
unary_expression_t& operator=(const unary_expression_t&) = default;
|
||||||
|
unary_expression_t& operator=(unary_expression_t&&) = default;
|
||||||
|
~unary_expression_t() = default;
|
||||||
|
|
||||||
|
Rhs _rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Rhs>
|
||||||
|
struct serializer_t<Context, logical_not_t<Rhs>>
|
||||||
|
{
|
||||||
|
using T = logical_not_t<Rhs>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "(";
|
||||||
|
context << "NOT ";
|
||||||
|
serialize(t._lhs, context);
|
||||||
|
context << ")";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Lhs, typename O, typename Rhs>
|
||||||
|
struct binary_expression_t: public value_type_of<O>::template expression_operators<binary_expression_t<Lhs, O, Rhs>>,
|
||||||
|
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||||
|
using _recursive_traits = make_recursive_traits<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 serializer_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
||||||
|
{
|
||||||
|
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "(";
|
||||||
|
serialize(t._lhs, context);
|
||||||
|
context << O::_name;
|
||||||
|
serialize(t._rhs, context);
|
||||||
|
context << ")";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename O, typename Rhs>
|
||||||
|
struct unary_expression_t: public value_type_of<O>::template expression_operators<unary_expression_t<O, Rhs>>,
|
||||||
|
public alias_operators<unary_expression_t<O, Rhs>>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||||
|
|
||||||
|
unary_expression_t(Rhs rhs):
|
||||||
|
_rhs(rhs)
|
||||||
|
{}
|
||||||
|
|
||||||
|
unary_expression_t(const unary_expression_t&) = default;
|
||||||
|
unary_expression_t(unary_expression_t&&) = default;
|
||||||
|
unary_expression_t& operator=(const unary_expression_t&) = default;
|
||||||
|
unary_expression_t& operator=(unary_expression_t&&) = default;
|
||||||
|
~unary_expression_t() = default;
|
||||||
|
|
||||||
|
Rhs _rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename O, typename Rhs>
|
||||||
|
struct serializer_t<Context, unary_expression_t<O, Rhs>>
|
||||||
|
{
|
||||||
|
using T = unary_expression_t<O, Rhs>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "(";
|
||||||
|
context << O::_name;
|
||||||
|
serialize(t._rhs, context);
|
||||||
|
context << ")";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
196
include/sqlpp11/expression_fwd.h
Normal file
196
include/sqlpp11/expression_fwd.h
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_FWD_H
|
||||||
|
#define SQLPP_EXPRESSION_FWD_H
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct boolean;
|
||||||
|
struct integral;
|
||||||
|
struct floating_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace op
|
||||||
|
{
|
||||||
|
struct less
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
static constexpr const char* _name = "<";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct less_equal
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
static constexpr const char* _name = "<=";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct equal_to
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct not_equal_to
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct greater_equal
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
static constexpr const char* _name = ">=";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct greater
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
static constexpr const char* _name = ">";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct logical_or
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
static constexpr const char* _name = " OR ";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct logical_and
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
static constexpr const char* _name = " AND ";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct logical_not
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::boolean>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
struct plus
|
||||||
|
{
|
||||||
|
using _traits = make_traits<ValueType>;
|
||||||
|
static constexpr const char* _name = "+";
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
struct minus
|
||||||
|
{
|
||||||
|
using _traits = make_traits<ValueType>;
|
||||||
|
static constexpr const char* _name = "-";
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
struct multiplies
|
||||||
|
{
|
||||||
|
using _traits = make_traits<ValueType>;
|
||||||
|
static constexpr const char* _name = "*";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct divides
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::floating_point>;
|
||||||
|
static constexpr const char* _name = "/";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct modulus
|
||||||
|
{
|
||||||
|
using _traits = make_traits<::sqlpp::detail::integral>;
|
||||||
|
static constexpr const char* _name = "%";
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
struct unary_minus
|
||||||
|
{
|
||||||
|
using _traits = make_traits<ValueType>;
|
||||||
|
static constexpr const char* _name = "-";
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
struct unary_plus
|
||||||
|
{
|
||||||
|
using _traits = make_traits<ValueType>;
|
||||||
|
static constexpr const char* _name = "+";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Lhs, typename O, typename Rhs>
|
||||||
|
struct binary_expression_t;
|
||||||
|
|
||||||
|
template<typename O, typename Rhs>
|
||||||
|
struct unary_expression_t;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using less_than_t = binary_expression_t<Lhs, op::less, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using less_equal_t = binary_expression_t<Lhs, op::less_equal, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using equal_to_t = binary_expression_t<Lhs, op::equal_to, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using not_equal_to_t = binary_expression_t<Lhs, op::not_equal_to, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using greater_than_t = binary_expression_t<Lhs, op::greater, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using greater_equal_t = binary_expression_t<Lhs, op::greater_equal, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using logical_and_t = binary_expression_t<Lhs, op::logical_and, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using logical_or_t = binary_expression_t<Lhs, op::logical_or, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename ValueType, typename Rhs>
|
||||||
|
using plus_t = binary_expression_t<Lhs, op::plus<ValueType>, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename ValueType, typename Rhs>
|
||||||
|
using minus_t = binary_expression_t<Lhs, op::minus<ValueType>, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename ValueType, typename Rhs>
|
||||||
|
using multiplies_t = binary_expression_t<Lhs, op::multiplies<ValueType>, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using divides_t = binary_expression_t<Lhs, op::divides, Rhs>;
|
||||||
|
|
||||||
|
template<typename Lhs, typename Rhs>
|
||||||
|
using modulus_t = binary_expression_t<Lhs, op::modulus, Rhs>;
|
||||||
|
|
||||||
|
template<typename Rhs>
|
||||||
|
using logical_not_t = unary_expression_t<op::logical_not, Rhs>;
|
||||||
|
|
||||||
|
template<typename ValueType, typename Rhs>
|
||||||
|
using unary_plus_t = unary_expression_t<op::unary_plus<ValueType>, Rhs>;
|
||||||
|
|
||||||
|
template<typename ValueType, typename Rhs>
|
||||||
|
using unary_minus_t = unary_expression_t<op::unary_minus<ValueType>, Rhs>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
167
include/sqlpp11/extra_tables.h
Normal file
167
include/sqlpp11/extra_tables.h
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_EXTRA_TABLES_H
|
||||||
|
#define SQLPP_EXTRA_TABLES_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename... Tables>
|
||||||
|
struct extra_tables_data_t
|
||||||
|
{
|
||||||
|
extra_tables_data_t()
|
||||||
|
{}
|
||||||
|
|
||||||
|
extra_tables_data_t(const extra_tables_data_t&) = default;
|
||||||
|
extra_tables_data_t(extra_tables_data_t&&) = default;
|
||||||
|
extra_tables_data_t& operator=(const extra_tables_data_t&) = default;
|
||||||
|
extra_tables_data_t& operator=(extra_tables_data_t&&) = default;
|
||||||
|
~extra_tables_data_t() = default;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// EXTRA_TABLES
|
||||||
|
template<typename... Tables>
|
||||||
|
struct extra_tables_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::extra_tables>;
|
||||||
|
struct _recursive_traits
|
||||||
|
{
|
||||||
|
using _parameters = std::tuple<>;
|
||||||
|
using _required_tables = ::sqlpp::detail::type_set<>;
|
||||||
|
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||||
|
using _extra_tables = ::sqlpp::detail::type_set<Tables...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||||
|
|
||||||
|
// FIXME: extra_tables must not require tables!
|
||||||
|
|
||||||
|
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = extra_tables_data_t<Tables...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = extra_tables_data_t<Tables...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> extra_tables;
|
||||||
|
_impl_t<Policies>& operator()() { return extra_tables; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.extra_tables)
|
||||||
|
{
|
||||||
|
return t.extra_tables;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO EXTRA TABLES YET
|
||||||
|
struct no_extra_tables_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_extra_tables;
|
||||||
|
_impl_t<Policies>& operator()() { return no_extra_tables; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_extra_tables; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_extra_tables)
|
||||||
|
{
|
||||||
|
return t.no_extra_tables;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_extra_tables_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto extra_tables(Args...)
|
||||||
|
-> _new_statement_t<extra_tables_t<Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_data_t<Args...>{} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Tables>
|
||||||
|
struct serializer_t<Context, extra_tables_data_t<Database, Tables...>>
|
||||||
|
{
|
||||||
|
using T = extra_tables_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -30,8 +30,6 @@
|
|||||||
#include <sqlpp11/multi_column.h>
|
#include <sqlpp11/multi_column.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename NameType, typename ValueType, bool TrivialValueIsNull>
|
template<typename NameType, typename ValueType, bool TrivialValueIsNull>
|
||||||
struct field_t
|
struct field_t
|
||||||
@ -67,7 +65,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename NamedExpr>
|
template<typename NamedExpr>
|
||||||
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -185,45 +185,45 @@ namespace sqlpp
|
|||||||
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
|
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::plus_t<Base, floating_point, vendor::wrap_operand_t<T>> operator +(T t) const
|
plus_t<Base, floating_point, wrap_operand_t<T>> operator +(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::minus_t<Base, floating_point, vendor::wrap_operand_t<T>> operator -(T t) const
|
minus_t<Base, floating_point, wrap_operand_t<T>> operator -(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::multiplies_t<Base, floating_point, vendor::wrap_operand_t<T>> operator *(T t) const
|
multiplies_t<Base, floating_point, wrap_operand_t<T>> operator *(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::divides_t<Base, vendor::wrap_operand_t<T>> operator /(T t) const
|
divides_t<Base, wrap_operand_t<T>> operator /(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), rhs{t} };
|
return { *static_cast<const Base*>(this), rhs{t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::unary_plus_t<floating_point, Base> operator +() const
|
unary_plus_t<floating_point, Base> operator +() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::unary_minus_t<floating_point, Base> operator -() const
|
unary_minus_t<floating_point, Base> operator -() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
@ -233,36 +233,36 @@ namespace sqlpp
|
|||||||
struct column_operators
|
struct column_operators
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator +=(T t) const -> vendor::assignment_t<Base, vendor::plus_t<Base, floating_point, vendor::wrap_operand_t<T>>>
|
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, floating_point, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator -=(T t) const -> vendor::assignment_t<Base, vendor::minus_t<Base, floating_point, vendor::wrap_operand_t<T>>>
|
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, floating_point, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator /=(T t) const -> vendor::assignment_t<Base, vendor::divides_t<Base, vendor::wrap_operand_t<T>>>
|
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator *=(T t) const -> vendor::assignment_t<Base, vendor::multiplies_t<Base, floating_point, vendor::wrap_operand_t<T>>>
|
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, floating_point, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
|
209
include/sqlpp11/from.h
Normal file
209
include/sqlpp11/from.h
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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 <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/interpretable_list.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// FROM DATA
|
||||||
|
template<typename Database, typename... Tables>
|
||||||
|
struct from_data_t
|
||||||
|
{
|
||||||
|
from_data_t(Tables... tables):
|
||||||
|
_tables(tables...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
from_data_t(const from_data_t&) = default;
|
||||||
|
from_data_t(from_data_t&&) = default;
|
||||||
|
from_data_t& operator=(const from_data_t&) = default;
|
||||||
|
from_data_t& operator=(from_data_t&&) = default;
|
||||||
|
~from_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Tables...> _tables;
|
||||||
|
interpretable_list_t<Database> _dynamic_tables;
|
||||||
|
};
|
||||||
|
|
||||||
|
// FROM
|
||||||
|
template<typename Database, typename... Tables>
|
||||||
|
struct from_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::from>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()");
|
||||||
|
|
||||||
|
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
||||||
|
|
||||||
|
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = from_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Table>
|
||||||
|
void add(Table table)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
||||||
|
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
||||||
|
#warning need to check if table is already known
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||||
|
|
||||||
|
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Table>
|
||||||
|
void _add_impl(Table table, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_tables.emplace_back(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Table>
|
||||||
|
void _add_impl(Table table, const std::false_type&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = from_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> from;
|
||||||
|
_impl_t<Policies>& operator()() { return from; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return from; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.from)
|
||||||
|
{
|
||||||
|
return t.from;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_from_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_from;
|
||||||
|
_impl_t<Policies>& operator()() { return no_from; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_from)
|
||||||
|
{
|
||||||
|
return t.no_from;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_from_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto from(Args... args)
|
||||||
|
-> _new_statement_t<from_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_from(Args... args)
|
||||||
|
-> _new_statement_t<from_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Tables>
|
||||||
|
struct serializer_t<Context, from_data_t<Database, Tables...>>
|
||||||
|
{
|
||||||
|
using T = from_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
||||||
|
return context;
|
||||||
|
context << " FROM ";
|
||||||
|
interpret_tuple(t._tables, ',', context);
|
||||||
|
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
||||||
|
context << ',';
|
||||||
|
interpret_list(t._dynamic_tables, ',', context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -30,9 +30,9 @@
|
|||||||
#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/vendor/in.h>
|
#include <sqlpp11/in.h>
|
||||||
#include <sqlpp11/vendor/is_null.h>
|
#include <sqlpp11/is_null.h>
|
||||||
#include <sqlpp11/vendor/value_type.h>
|
#include <sqlpp11/value_type.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>
|
||||||
@ -46,11 +46,11 @@
|
|||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto value(T t) -> vendor::wrap_operand_t<T>
|
auto value(T t) -> wrap_operand_t<T>
|
||||||
{
|
{
|
||||||
using _provided_tables = detail::type_set<>;
|
using _provided_tables = detail::type_set<>;
|
||||||
using _required_tables = ::sqlpp::detail::type_set<>;
|
using _required_tables = ::sqlpp::detail::type_set<>;
|
||||||
static_assert(is_wrapped_value_t<vendor::wrap_operand_t<T>>::value, "value() is to be called with non-sql-type like int, or string");
|
static_assert(is_wrapped_value_t<wrap_operand_t<T>>::value, "value() is to be called with non-sql-type like int, or string");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +71,6 @@ namespace sqlpp
|
|||||||
std::string _verbatim;
|
std::string _verbatim;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename ValueType>
|
template<typename Context, typename ValueType>
|
||||||
struct serializer_t<Context, verbatim_t<ValueType>>
|
struct serializer_t<Context, verbatim_t<ValueType>>
|
||||||
{
|
{
|
||||||
@ -84,7 +82,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ValueType, typename StringType>
|
template<typename ValueType, typename StringType>
|
||||||
auto verbatim(StringType s) -> verbatim_t<ValueType>
|
auto verbatim(StringType s) -> verbatim_t<ValueType>
|
||||||
@ -104,7 +101,7 @@ namespace sqlpp
|
|||||||
template<typename Container>
|
template<typename Container>
|
||||||
struct value_list_t // to be used in .in() method
|
struct value_list_t // to be used in .in() method
|
||||||
{
|
{
|
||||||
using _traits = make_traits<vendor::value_type_t<typename Container::value_type>>;
|
using _traits = make_traits<value_type_t<typename Container::value_type>>;
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
using _container_t = Container;
|
using _container_t = Container;
|
||||||
@ -122,8 +119,6 @@ namespace sqlpp
|
|||||||
_container_t _container;
|
_container_t _container;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Container>
|
template<typename Context, typename Container>
|
||||||
struct serializer_t<Context, value_list_t<Container>>
|
struct serializer_t<Context, value_list_t<Container>>
|
||||||
{
|
{
|
||||||
@ -144,12 +139,11 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
auto value_list(Container c) -> value_list_t<Container>
|
auto value_list(Container c) -> value_list_t<Container>
|
||||||
{
|
{
|
||||||
static_assert(is_wrapped_value_t<vendor::wrap_operand_t<typename Container::value_type>>::value, "value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
|
static_assert(is_wrapped_value_t<wrap_operand_t<typename Container::value_type>>::value, "value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
|
||||||
return { c };
|
return { c };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
211
include/sqlpp11/group_by.h
Normal file
211
include/sqlpp11/group_by.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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/expression.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/interpretable_list.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// GROUP BY DATA
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct group_by_data_t
|
||||||
|
{
|
||||||
|
group_by_data_t(Expressions... expressions):
|
||||||
|
_expressions(expressions...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
group_by_data_t(const group_by_data_t&) = default;
|
||||||
|
group_by_data_t(group_by_data_t&&) = default;
|
||||||
|
group_by_data_t& operator=(const group_by_data_t&) = default;
|
||||||
|
group_by_data_t& operator=(group_by_data_t&&) = default;
|
||||||
|
~group_by_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Expressions...> _expressions;
|
||||||
|
interpretable_list_t<Database> _dynamic_expressions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// GROUP BY
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct group_by_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Expression>
|
||||||
|
void add_ntc(Expression expression)
|
||||||
|
{
|
||||||
|
add<Expression, std::false_type>(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Expression expression)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
||||||
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
||||||
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||||
|
|
||||||
|
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_expressions.emplace_back(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> group_by;
|
||||||
|
_impl_t<Policies>& operator()() { return group_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return group_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.group_by)
|
||||||
|
{
|
||||||
|
return t.group_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO GROUP BY YET
|
||||||
|
struct no_group_by_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_group_by;
|
||||||
|
_impl_t<Policies>& operator()() { return no_group_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_group_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_group_by)
|
||||||
|
{
|
||||||
|
return t.no_group_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_group_by_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto group_by(Args... args)
|
||||||
|
-> _new_statement_t<group_by_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_group_by(Args... args)
|
||||||
|
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
|
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
||||||
|
{
|
||||||
|
using T = group_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
|
return context;
|
||||||
|
context << " GROUP BY ";
|
||||||
|
interpret_tuple(t._expressions, ',', context);
|
||||||
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
|
context << ',';
|
||||||
|
interpret_list(t._dynamic_expressions, ',', context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
209
include/sqlpp11/having.h
Normal file
209
include/sqlpp11/having.h
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_HAVING_H
|
||||||
|
#define SQLPP_HAVING_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/expression.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/interpretable_list.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// HAVING DATA
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct having_data_t
|
||||||
|
{
|
||||||
|
having_data_t(Expressions... expressions):
|
||||||
|
_expressions(expressions...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
having_data_t(const having_data_t&) = default;
|
||||||
|
having_data_t(having_data_t&&) = default;
|
||||||
|
having_data_t& operator=(const having_data_t&) = default;
|
||||||
|
having_data_t& operator=(having_data_t&&) = default;
|
||||||
|
~having_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Expressions...> _expressions;
|
||||||
|
interpretable_list_t<Database> _dynamic_expressions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// HAVING
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct having_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::having>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = having_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Expression>
|
||||||
|
void add_ntc(Expression expression)
|
||||||
|
{
|
||||||
|
add<Expression, std::false_type>(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Expression expression)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
||||||
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
||||||
|
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||||
|
|
||||||
|
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_expressions.emplace_back(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::false_type&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = having_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> having;
|
||||||
|
_impl_t<Policies>& operator()() { return having; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return having; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.having)
|
||||||
|
{
|
||||||
|
return t.having;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO HAVING YET
|
||||||
|
struct no_having_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_having;
|
||||||
|
_impl_t<Policies>& operator()() { return no_having; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_having; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_having)
|
||||||
|
{
|
||||||
|
return t.no_having;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_having_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto having(Args... args)
|
||||||
|
-> _new_statement_t<having_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_having(Args... args)
|
||||||
|
-> _new_statement_t<having_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
|
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
||||||
|
{
|
||||||
|
using T = having_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
|
return context;
|
||||||
|
context << " HAVING ";
|
||||||
|
interpret_tuple(t._expressions, " AND ", context);
|
||||||
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
|
context << " AND ";
|
||||||
|
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -29,12 +29,10 @@
|
|||||||
|
|
||||||
#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/in_fwd.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<bool NotInverted, typename Operand, typename... Args>
|
template<bool NotInverted, typename Operand, typename... Args>
|
||||||
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>,
|
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>,
|
||||||
@ -72,9 +70,9 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, bool NotInverted, typename Operand, typename... Args>
|
template<typename Context, bool NotInverted, typename Operand, typename... Args>
|
||||||
struct serializer_t<Context, vendor::in_t<NotInverted, Operand, Args...>>
|
struct serializer_t<Context, in_t<NotInverted, Operand, Args...>>
|
||||||
{
|
{
|
||||||
using T = vendor::in_t<NotInverted, Operand, Args...>;
|
using T = in_t<NotInverted, Operand, Args...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -85,7 +83,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -28,12 +28,9 @@
|
|||||||
#define SQLPP_IN_FWD_H
|
#define SQLPP_IN_FWD_H
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<bool NotInverted, typename Operand, typename... Args>
|
template<bool NotInverted, typename Operand, typename... Args>
|
||||||
struct in_t;
|
struct in_t;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -32,19 +32,17 @@
|
|||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_insert.h>
|
#include <sqlpp11/prepared_insert.h>
|
||||||
#include <sqlpp11/default_value.h>
|
#include <sqlpp11/default_value.h>
|
||||||
#include <sqlpp11/vendor/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
#include <sqlpp11/vendor/into.h>
|
#include <sqlpp11/into.h>
|
||||||
#include <sqlpp11/vendor/insert_value_list.h>
|
#include <sqlpp11/insert_value_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct insert_name_t {};
|
struct insert_name_t {};
|
||||||
|
|
||||||
struct insert_t: public vendor::statement_name_t<insert_name_t>
|
struct insert_t: public statement_name_t<insert_name_t>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, insert_name_t>
|
struct serializer_t<Context, insert_name_t>
|
||||||
{
|
{
|
||||||
@ -57,13 +55,12 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Database>
|
template<typename Database>
|
||||||
using blank_insert_t = statement_t<Database,
|
using blank_insert_t = statement_t<Database,
|
||||||
insert_t,
|
insert_t,
|
||||||
vendor::no_into_t,
|
no_into_t,
|
||||||
vendor::no_insert_value_list_t>;
|
no_insert_value_list_t>;
|
||||||
|
|
||||||
auto insert()
|
auto insert()
|
||||||
-> blank_insert_t<void>
|
-> blank_insert_t<void>
|
||||||
|
121
include/sqlpp11/insert_value.h
Normal file
121
include/sqlpp11/insert_value.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_VALUE_H
|
||||||
|
#define SQLPP_INSERT_VALUE_H
|
||||||
|
|
||||||
|
#include <sqlpp11/default_value.h>
|
||||||
|
#include <sqlpp11/null.h>
|
||||||
|
#include <sqlpp11/tvin.h>
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Type, bool>
|
||||||
|
struct type_if
|
||||||
|
{
|
||||||
|
using type = Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
struct type_if<Type, false>
|
||||||
|
{
|
||||||
|
struct type
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Column>
|
||||||
|
struct insert_value_t
|
||||||
|
{
|
||||||
|
using _is_insert_value = std::true_type;
|
||||||
|
using _pure_value_t = typename value_type_of<Column>::_cpp_value_type;
|
||||||
|
using _wrapped_value_t = typename wrap_operand<_pure_value_t>::type;
|
||||||
|
using _tvin_t = typename detail::type_if<tvin_t<_wrapped_value_t>, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
||||||
|
using _null_t = typename detail::type_if<null_t, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
||||||
|
|
||||||
|
insert_value_t(assignment_t<Column, _wrapped_value_t> assignment):
|
||||||
|
_is_null(false),
|
||||||
|
_is_default(false),
|
||||||
|
_value(assignment._rhs)
|
||||||
|
{}
|
||||||
|
|
||||||
|
insert_value_t(assignment_t<Column, _tvin_t> assignment):
|
||||||
|
_is_null(assignment._rhs._is_trivial()),
|
||||||
|
_is_default(false),
|
||||||
|
_value(assignment._rhs._value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
insert_value_t(const assignment_t<Column, _null_t>&):
|
||||||
|
_is_null(true),
|
||||||
|
_is_default(false),
|
||||||
|
_value()
|
||||||
|
{}
|
||||||
|
|
||||||
|
insert_value_t(const assignment_t<Column, ::sqlpp::default_value_t>&):
|
||||||
|
_is_null(false),
|
||||||
|
_is_default(true),
|
||||||
|
_value()
|
||||||
|
{}
|
||||||
|
|
||||||
|
insert_value_t(const insert_value_t&) = default;
|
||||||
|
insert_value_t(insert_value_t&&) = default;
|
||||||
|
insert_value_t& operator=(const insert_value_t&) = default;
|
||||||
|
insert_value_t& operator=(insert_value_t&&) = default;
|
||||||
|
~insert_value_t() = default;
|
||||||
|
|
||||||
|
bool _is_null;
|
||||||
|
bool _is_default;
|
||||||
|
_wrapped_value_t _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename ValueType>
|
||||||
|
struct serializer_t<Context, insert_value_t<ValueType>>
|
||||||
|
{
|
||||||
|
using T = insert_value_t<ValueType>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (t._is_null)
|
||||||
|
context << "NULL";
|
||||||
|
else if (t._is_default)
|
||||||
|
context << "DEFAULT";
|
||||||
|
else
|
||||||
|
serialize(t._value, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
450
include/sqlpp11/insert_value_list.h
Normal file
450
include/sqlpp11/insert_value_list.h
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_VALUE_LIST_H
|
||||||
|
#define SQLPP_INSERT_VALUE_LIST_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
#include <sqlpp11/assignment.h>
|
||||||
|
#include <sqlpp11/interpretable_list.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/insert_value.h>
|
||||||
|
#include <sqlpp11/simple_column.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
struct insert_default_values_data_t
|
||||||
|
{};
|
||||||
|
|
||||||
|
// COLUMN AND VALUE LIST
|
||||||
|
struct insert_default_values_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = insert_default_values_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = insert_default_values_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> default_values;
|
||||||
|
_impl_t<Policies>& operator()() { return default_values; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return default_values; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.default_values)
|
||||||
|
{
|
||||||
|
return t.default_values;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Database, typename... Assignments>
|
||||||
|
struct insert_list_data_t
|
||||||
|
{
|
||||||
|
insert_list_data_t(Assignments... assignments):
|
||||||
|
_assignments(assignments...),
|
||||||
|
_columns({assignments._lhs}...),
|
||||||
|
_values(assignments._rhs...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
insert_list_data_t(const insert_list_data_t&) = default;
|
||||||
|
insert_list_data_t(insert_list_data_t&&) = default;
|
||||||
|
insert_list_data_t& operator=(const insert_list_data_t&) = default;
|
||||||
|
insert_list_data_t& operator=(insert_list_data_t&&) = default;
|
||||||
|
~insert_list_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||||
|
std::tuple<typename Assignments::_value_t...> _values;
|
||||||
|
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||||
|
interpretable_list_t<Database> _dynamic_columns;
|
||||||
|
interpretable_list_t<Database> _dynamic_values;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Database, typename... Assignments>
|
||||||
|
struct insert_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::insert_list>;
|
||||||
|
using _recursive_traits = make_recursive_traits<typename Assignments::_column_t..., typename Assignments::_value_t...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
template<template<typename...> class Target>
|
||||||
|
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
|
||||||
|
template<template<typename...> class Target, template<typename> class Wrap>
|
||||||
|
using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment required in set()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||||
|
|
||||||
|
static_assert(sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||||
|
|
||||||
|
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||||
|
|
||||||
|
#warning: Need to reactivate these checks
|
||||||
|
/*
|
||||||
|
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_required_tables...>::type;
|
||||||
|
using _value_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_required_tables...>::type;
|
||||||
|
using _provided_tables = ::sqlpp::detail::type_set<>;
|
||||||
|
using _required_tables = typename ::sqlpp::detail::make_joined_set<_column_required_tables, _value_required_tables>::type;
|
||||||
|
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||||
|
static_assert(::sqlpp::detail::is_subset_of<_value_required_tables, _column_required_tables>::value, "set() contains values from foreign tables");
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Assignment>
|
||||||
|
void add_ntc(Assignment assignment)
|
||||||
|
{
|
||||||
|
add<Assignment, std::false_type>(assignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Assignment assignment)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||||
|
static_assert(is_assignment_t<Assignment>::value, "add() arguments require to be assigments");
|
||||||
|
static_assert(not must_not_insert_t<typename Assignment::_column_t>::value, "add() argument must not be used in insert");
|
||||||
|
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add() contains a column from a foreign table");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<
|
||||||
|
_is_dynamic::value,
|
||||||
|
is_assignment_t<Assignment>::value,
|
||||||
|
not must_not_insert_t<typename Assignment::_column_t>::value,
|
||||||
|
(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value)>;
|
||||||
|
|
||||||
|
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Assignment>
|
||||||
|
void _add_impl(Assignment assignment, const std::true_type&)
|
||||||
|
{
|
||||||
|
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||||
|
_data._dynamic_values.emplace_back(assignment._rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Assignment>
|
||||||
|
void _add_impl(Assignment assignment, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> insert_list;
|
||||||
|
_impl_t<Policies>& operator()() { return insert_list; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return insert_list; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.insert_list)
|
||||||
|
{
|
||||||
|
return t.insert_list;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Columns>
|
||||||
|
struct column_list_data_t
|
||||||
|
{
|
||||||
|
column_list_data_t(Columns... columns):
|
||||||
|
_columns(simple_column_t<Columns>{columns}...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
column_list_data_t(const column_list_data_t&) = default;
|
||||||
|
column_list_data_t(column_list_data_t&&) = default;
|
||||||
|
column_list_data_t& operator=(const column_list_data_t&) = default;
|
||||||
|
column_list_data_t& operator=(column_list_data_t&&) = default;
|
||||||
|
~column_list_data_t() = default;
|
||||||
|
|
||||||
|
#warning need to define just one version of value_tuple_t
|
||||||
|
using _value_tuple_t = std::tuple<insert_value_t<Columns>...>;
|
||||||
|
std::tuple<simple_column_t<Columns>...> _columns;
|
||||||
|
std::vector<_value_tuple_t> _insert_values;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename... Columns>
|
||||||
|
struct column_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::column_list>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||||
|
|
||||||
|
static_assert(sizeof...(Columns), "at least one column required in columns()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert flag in its definition");
|
||||||
|
|
||||||
|
using _value_tuple_t = std::tuple<insert_value_t<Columns>...>;
|
||||||
|
|
||||||
|
static_assert(required_tables_of<column_list_t>::size::value == 1, "columns from multiple tables in columns()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = column_list_data_t<Columns...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename... Assignments>
|
||||||
|
void add(Assignments... assignments)
|
||||||
|
{
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
||||||
|
using _arg_value_tuple = std::tuple<insert_value_t<typename Assignments::_column_t>...>;
|
||||||
|
using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
||||||
|
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<
|
||||||
|
::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value,
|
||||||
|
_args_correct::value>;
|
||||||
|
|
||||||
|
_add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename... Assignments>
|
||||||
|
void _add_impl(const std::true_type&, Assignments... assignments)
|
||||||
|
{
|
||||||
|
return _data._insert_values.emplace_back(insert_value_t<typename Assignments::_column_t>{assignments}...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Assignments>
|
||||||
|
void _add_impl(const std::false_type&, Assignments... assignments);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = column_list_data_t<Columns...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> values;
|
||||||
|
_impl_t<Policies>& operator()() { return values; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return values; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.values)
|
||||||
|
{
|
||||||
|
return t.values;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return _insert_values.empty();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO HAVING YET
|
||||||
|
struct no_insert_value_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_insert_values;
|
||||||
|
_impl_t<Policies>& operator()() { return no_insert_values; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_insert_values; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_insert_values)
|
||||||
|
{
|
||||||
|
return t.no_insert_values;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_insert_value_list_t, T>;
|
||||||
|
|
||||||
|
auto default_values()
|
||||||
|
-> _new_statement_t<insert_default_values_t>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), insert_default_values_data_t{} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto columns(Args... args)
|
||||||
|
-> _new_statement_t<column_list_t<Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), column_list_data_t<Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto set(Args... args)
|
||||||
|
-> _new_statement_t<insert_list_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_set(Args... args)
|
||||||
|
-> _new_statement_t<insert_list_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context>
|
||||||
|
struct serializer_t<Context, insert_default_values_data_t>
|
||||||
|
{
|
||||||
|
using T = insert_default_values_data_t;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " DEFAULT VALUES";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename... Columns>
|
||||||
|
struct serializer_t<Context, column_list_data_t<Columns...>>
|
||||||
|
{
|
||||||
|
using T = column_list_data_t<Columns...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " (";
|
||||||
|
interpret_tuple(t._columns, ",", context);
|
||||||
|
context << ")";
|
||||||
|
context << " VALUES ";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto& row : t._insert_values)
|
||||||
|
{
|
||||||
|
if (not first)
|
||||||
|
context << ',';
|
||||||
|
else
|
||||||
|
first = false;
|
||||||
|
context << '(';
|
||||||
|
interpret_tuple(row, ",", context);
|
||||||
|
context << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Database, typename... Assignments>
|
||||||
|
struct serializer_t<Context, insert_list_data_t<Database, Assignments...>>
|
||||||
|
{
|
||||||
|
using T = insert_list_data_t<Database, Assignments...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
||||||
|
{
|
||||||
|
serialize(insert_default_values_data_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
|
@ -32,7 +32,7 @@
|
|||||||
#include <sqlpp11/basic_expression_operators.h>
|
#include <sqlpp11/basic_expression_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
#include <sqlpp11/vendor/value_type.h>
|
#include <sqlpp11/value_type.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -186,56 +186,56 @@ namespace sqlpp
|
|||||||
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
|
struct expression_operators: public basic_expression_operators<Base, is_numeric_t>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::plus_t<Base, vendor::value_type_t<T>, vendor::wrap_operand_t<T>> operator +(T t) const
|
plus_t<Base, value_type_t<T>, wrap_operand_t<T>> operator +(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::minus_t<Base, vendor::value_type_t<T>, vendor::wrap_operand_t<T>> operator -(T t) const
|
minus_t<Base, value_type_t<T>, wrap_operand_t<T>> operator -(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::multiplies_t<Base, vendor::value_type_t<T>, vendor::wrap_operand_t<T>> operator *(T t) const
|
multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>> operator *(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::divides_t<Base, vendor::wrap_operand_t<T>> operator /(T t) const
|
divides_t<Base, wrap_operand_t<T>> operator /(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::modulus_t<Base, vendor::wrap_operand_t<T>> operator %(T t) const
|
modulus_t<Base, wrap_operand_t<T>> operator %(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::unary_plus_t<integral, Base> operator +() const
|
unary_plus_t<integral, Base> operator +() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
|
|
||||||
vendor::unary_minus_t<integral, Base> operator -() const
|
unary_minus_t<integral, Base> operator -() const
|
||||||
{
|
{
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
@ -245,36 +245,36 @@ namespace sqlpp
|
|||||||
struct column_operators
|
struct column_operators
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator +=(T t) const -> vendor::assignment_t<Base, vendor::plus_t<Base, vendor::value_type_t<T>, vendor::wrap_operand_t<T>>>
|
auto operator +=(T t) const -> assignment_t<Base, plus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator -=(T t) const -> vendor::assignment_t<Base, vendor::minus_t<Base, vendor::value_type_t<T>, vendor::wrap_operand_t<T>>>
|
auto operator -=(T t) const -> assignment_t<Base, minus_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator /=(T t) const -> vendor::assignment_t<Base, vendor::divides_t<Base, vendor::wrap_operand_t<T>>>
|
auto operator /=(T t) const -> assignment_t<Base, divides_t<Base, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator *=(T t) const -> vendor::assignment_t<Base, vendor::multiplies_t<Base, vendor::value_type_t<T>, vendor::wrap_operand_t<T>>>
|
auto operator *=(T t) const -> assignment_t<Base, multiplies_t<Base, value_type_t<T>, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
|
@ -27,15 +27,15 @@
|
|||||||
#ifndef SQLPP_INTERPRET_H
|
#ifndef SQLPP_INTERPRET_H
|
||||||
#define SQLPP_INTERPRET_H
|
#define SQLPP_INTERPRET_H
|
||||||
|
|
||||||
#include <sqlpp11/vendor/interpreter.h>
|
#include <sqlpp11/interpreter.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
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(vendor::interpreter_t<Context, T>::_(t, context))
|
-> decltype(interpreter_t<Context, T>::_(t, context))
|
||||||
{
|
{
|
||||||
return vendor::interpreter_t<Context, T>::_(t, context);
|
return interpreter_t<Context, T>::_(t, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
128
include/sqlpp11/interpretable.h
Normal file
128
include/sqlpp11/interpretable.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_INTERPRETABLE_H
|
||||||
|
#define SQLPP_INTERPRETABLE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <sqlpp11/serializer_context.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/serialize.h>
|
||||||
|
#include <sqlpp11/interpret.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Db>
|
||||||
|
struct interpretable_t
|
||||||
|
{
|
||||||
|
using _serializer_context_t = typename Db::_serializer_context_t;
|
||||||
|
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
interpretable_t(T t):
|
||||||
|
_impl(std::make_shared<_impl_t<T>>(t))
|
||||||
|
{}
|
||||||
|
|
||||||
|
interpretable_t(const interpretable_t&) = default;
|
||||||
|
interpretable_t(interpretable_t&&) = default;
|
||||||
|
interpretable_t& operator=(const interpretable_t&) = default;
|
||||||
|
interpretable_t& operator=(interpretable_t&&) = default;
|
||||||
|
~interpretable_t() = default;
|
||||||
|
|
||||||
|
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||||
|
{
|
||||||
|
return _impl->serialize(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||||
|
template<typename Context>
|
||||||
|
auto serialize(Context& context) const
|
||||||
|
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
||||||
|
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||||
|
{
|
||||||
|
return _impl->db_serialize(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||||
|
{
|
||||||
|
return _impl->interpret(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct _impl_base
|
||||||
|
{
|
||||||
|
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||||
|
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||||
|
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct _impl_t: public _impl_base
|
||||||
|
{
|
||||||
|
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
||||||
|
_impl_t(T t):
|
||||||
|
_t(t)
|
||||||
|
{}
|
||||||
|
|
||||||
|
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||||
|
{
|
||||||
|
sqlpp::serialize(_t, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||||
|
{
|
||||||
|
Db::_serialize_interpretable(_t, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||||
|
{
|
||||||
|
Db::_interpret_interpretable(_t, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
T _t;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<const _impl_base> _impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Database>
|
||||||
|
struct serializer_t<Context, interpretable_t<Database>>
|
||||||
|
{
|
||||||
|
using T = interpretable_t<Database>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
t.serialize(context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -28,11 +28,9 @@
|
|||||||
#define SQLPP_INTERPRETABLE_LIST_H
|
#define SQLPP_INTERPRETABLE_LIST_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sqlpp11/vendor/interpretable.h>
|
#include <sqlpp11/interpretable.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
struct interpretable_list_t
|
struct interpretable_list_t
|
||||||
@ -114,6 +112,5 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -24,14 +24,12 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_VENDOR_INTERPRETER_H
|
#ifndef SQLPP_INTERPRETER_H
|
||||||
#define SQLPP_VENDOR_INTERPRETER_H
|
#define SQLPP_INTERPRETER_H
|
||||||
|
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Context, typename T, typename Enable = void>
|
template<typename Context, typename T, typename Enable = void>
|
||||||
struct interpreter_t
|
struct interpreter_t
|
||||||
@ -41,7 +39,6 @@ namespace sqlpp
|
|||||||
static_assert(wrong_t<Context, T>::value, "missing interpreter specialization");
|
static_assert(wrong_t<Context, T>::value, "missing interpreter specialization");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
195
include/sqlpp11/into.h
Normal file
195
include/sqlpp11/into.h
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_INTO_H
|
||||||
|
#define SQLPP_INTO_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/no_value.h>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// A SINGLE TABLE DATA
|
||||||
|
template<typename Database, typename Table>
|
||||||
|
struct into_data_t
|
||||||
|
{
|
||||||
|
into_data_t(Table table):
|
||||||
|
_table(table)
|
||||||
|
{}
|
||||||
|
|
||||||
|
into_data_t(const into_data_t&) = default;
|
||||||
|
into_data_t(into_data_t&&) = default;
|
||||||
|
into_data_t& operator=(const into_data_t&) = default;
|
||||||
|
into_data_t& operator=(into_data_t&&) = default;
|
||||||
|
~into_data_t() = default;
|
||||||
|
|
||||||
|
Table _table;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A SINGLE TABLE
|
||||||
|
template<typename Database, typename Table>
|
||||||
|
struct into_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::into, tag::return_value>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Table>;
|
||||||
|
|
||||||
|
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||||
|
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||||
|
|
||||||
|
using _data_t = into_data_t<Database, Table>;
|
||||||
|
|
||||||
|
struct _name_t {};
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = into_data_t<Database, Table>;
|
||||||
|
|
||||||
|
_impl_t<Policies> into;
|
||||||
|
_impl_t<Policies>& operator()() { return into; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return into; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.into)
|
||||||
|
{
|
||||||
|
return t.into;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _result_methods_t
|
||||||
|
{
|
||||||
|
using _statement_t = typename Policies::_statement_t;
|
||||||
|
|
||||||
|
const _statement_t& _get_statement() const
|
||||||
|
{
|
||||||
|
return static_cast<const _statement_t&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||||
|
{
|
||||||
|
_statement_t::_check_consistency();
|
||||||
|
|
||||||
|
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||||
|
return db.insert(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
template<typename Db>
|
||||||
|
auto _prepare(Db& db) const
|
||||||
|
-> prepared_insert_t<Db, insert_t>
|
||||||
|
{
|
||||||
|
_statement_t::_check_consistency();
|
||||||
|
|
||||||
|
return {{}, db.prepare_insert(*this)};
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO INTO YET
|
||||||
|
struct no_into_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_into;
|
||||||
|
_impl_t<Policies>& operator()() { return no_into; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_into; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_into)
|
||||||
|
{
|
||||||
|
return t.no_into;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_into_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto into(Args... args)
|
||||||
|
-> _new_statement_t<into_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), into_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename Table>
|
||||||
|
struct serializer_t<Context, into_data_t<Database, Table>>
|
||||||
|
{
|
||||||
|
using T = into_data_t<Database, Table>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " INTO ";
|
||||||
|
serialize(t._table, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -32,8 +32,6 @@
|
|||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<bool NotInverted, typename Operand>
|
template<bool NotInverted, typename Operand>
|
||||||
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>,
|
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>,
|
||||||
@ -73,9 +71,9 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, bool NotInverted, typename Operand>
|
template<typename Context, bool NotInverted, typename Operand>
|
||||||
struct serializer_t<Context, ::sqlpp::vendor::is_null_t<NotInverted, Operand>>
|
struct serializer_t<Context, ::sqlpp::is_null_t<NotInverted, Operand>>
|
||||||
{
|
{
|
||||||
using T = ::sqlpp::vendor::is_null_t<NotInverted, Operand>;
|
using T = ::sqlpp::is_null_t<NotInverted, Operand>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -84,7 +82,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -28,12 +28,9 @@
|
|||||||
#define SQLPP_IS_NULL_FWD_H
|
#define SQLPP_IS_NULL_FWD_H
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<bool NotInverted, typename Operand>
|
template<bool NotInverted, typename Operand>
|
||||||
struct is_null_t;
|
struct is_null_t;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -29,7 +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>
|
#include <sqlpp11/noop.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -74,7 +74,7 @@ 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 = vendor::noop>
|
template<typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
||||||
struct join_t
|
struct join_t
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::table, tag::join>;
|
using _traits = make_traits<no_value_t, tag::table, tag::join>;
|
||||||
@ -83,7 +83,7 @@ namespace sqlpp
|
|||||||
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
|
static_assert(is_table_t<Lhs>::value, "lhs argument for join() has to be a table or join");
|
||||||
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
|
static_assert(is_table_t<Rhs>::value, "rhs argument for join() has to be a table");
|
||||||
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
|
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
|
||||||
static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
static_assert(is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, "joined tables must not be identical");
|
static_assert(::sqlpp::detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, "joined tables must not be identical");
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ namespace sqlpp
|
|||||||
auto on(Expr... expr)
|
auto on(Expr... expr)
|
||||||
-> set_on_t<on_t<void, Expr...>>
|
-> set_on_t<on_t<void, Expr...>>
|
||||||
{
|
{
|
||||||
static_assert(vendor::is_noop<On>::value, "cannot call on() twice for a single join()");
|
static_assert(is_noop<On>::value, "cannot call on() twice for a single join()");
|
||||||
return { _lhs,
|
return { _lhs,
|
||||||
_rhs,
|
_rhs,
|
||||||
{std::tuple<Expr...>{expr...}}
|
{std::tuple<Expr...>{expr...}}
|
||||||
@ -106,35 +106,35 @@ namespace sqlpp
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
join_t<inner_join_t, join_t, T> join(T t)
|
join_t<inner_join_t, join_t, T> join(T t)
|
||||||
{
|
{
|
||||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||||
return { *this, t };
|
return { *this, t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
join_t<inner_join_t, join_t, T> inner_join(T t)
|
join_t<inner_join_t, join_t, T> inner_join(T t)
|
||||||
{
|
{
|
||||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||||
return { *this, t };
|
return { *this, t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
join_t<outer_join_t, join_t, T> outer_join(T t)
|
join_t<outer_join_t, join_t, T> outer_join(T t)
|
||||||
{
|
{
|
||||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||||
return { *this, t };
|
return { *this, t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
join_t<left_outer_join_t, join_t, T> left_outer_join(T t)
|
join_t<left_outer_join_t, join_t, T> left_outer_join(T t)
|
||||||
{
|
{
|
||||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||||
return { *this, t };
|
return { *this, t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
join_t<right_outer_join_t, join_t, T> right_outer_join(T t)
|
join_t<right_outer_join_t, join_t, T> right_outer_join(T t)
|
||||||
{
|
{
|
||||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||||
return { *this, t };
|
return { *this, t };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,8 +143,6 @@ namespace sqlpp
|
|||||||
On _on;
|
On _on;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
||||||
struct serializer_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
struct serializer_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
||||||
{
|
{
|
||||||
@ -152,7 +150,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
static_assert(not vendor::is_noop<On>::value, "joined tables require on()");
|
static_assert(not is_noop<On>::value, "joined tables require on()");
|
||||||
serialize(t._lhs, context);
|
serialize(t._lhs, context);
|
||||||
context << JoinType::_name;
|
context << JoinType::_name;
|
||||||
context << " JOIN ";
|
context << " JOIN ";
|
||||||
@ -163,6 +161,5 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Operand, typename Pattern>
|
template<typename Operand, typename Pattern>
|
||||||
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>,
|
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>,
|
||||||
@ -85,6 +83,5 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
257
include/sqlpp11/limit.h
Normal file
257
include/sqlpp11/limit.h
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_LIMIT_H
|
||||||
|
#define SQLPP_LIMIT_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// LIMIT DATA
|
||||||
|
template<typename Limit>
|
||||||
|
struct limit_data_t
|
||||||
|
{
|
||||||
|
limit_data_t(Limit value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
limit_data_t(const limit_data_t&) = default;
|
||||||
|
limit_data_t(limit_data_t&&) = default;
|
||||||
|
limit_data_t& operator=(const limit_data_t&) = default;
|
||||||
|
limit_data_t& operator=(limit_data_t&&) = default;
|
||||||
|
~limit_data_t() = default;
|
||||||
|
|
||||||
|
Limit _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// LIMIT
|
||||||
|
template<typename Limit>
|
||||||
|
struct limit_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Limit>;
|
||||||
|
|
||||||
|
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = limit_data_t<Limit>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = limit_data_t<Limit>;
|
||||||
|
|
||||||
|
_impl_t<Policies> limit;
|
||||||
|
_impl_t<Policies>& operator()() { return limit; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return limit; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.limit)
|
||||||
|
{
|
||||||
|
return t.limit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// DYNAMIC LIMIT DATA
|
||||||
|
template<typename Database>
|
||||||
|
struct dynamic_limit_data_t
|
||||||
|
{
|
||||||
|
dynamic_limit_data_t():
|
||||||
|
_value(noop())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Limit>
|
||||||
|
dynamic_limit_data_t(Limit value):
|
||||||
|
_initialized(true),
|
||||||
|
_value(typename wrap_operand<Limit>::type(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
|
||||||
|
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
|
||||||
|
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
|
||||||
|
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
|
||||||
|
~dynamic_limit_data_t() = default;
|
||||||
|
|
||||||
|
bool _initialized = false;
|
||||||
|
interpretable_t<Database> _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// DYNAMIC LIMIT
|
||||||
|
template<typename Database>
|
||||||
|
struct dynamic_limit_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = dynamic_limit_data_t<Database>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Limit>
|
||||||
|
void set(Limit value)
|
||||||
|
{
|
||||||
|
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
||||||
|
using arg_t = typename wrap_operand<Limit>::type;
|
||||||
|
_data._value = arg_t{value};
|
||||||
|
_data._initialized = true;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = dynamic_limit_data_t<Database>;
|
||||||
|
|
||||||
|
_impl_t<Policies> limit;
|
||||||
|
_impl_t<Policies>& operator()() { return limit; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return limit; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.limit)
|
||||||
|
{
|
||||||
|
return t.limit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_limit_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_limit;
|
||||||
|
_impl_t<Policies>& operator()() { return no_limit; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_limit; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_limit)
|
||||||
|
{
|
||||||
|
return t.no_limit;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_limit_t, T>;
|
||||||
|
|
||||||
|
template<typename Arg>
|
||||||
|
auto limit(Arg arg)
|
||||||
|
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), limit_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dynamic_limit()
|
||||||
|
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_data_t<_database_t>{} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database>
|
||||||
|
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
||||||
|
{
|
||||||
|
using T = dynamic_limit_data_t<Database>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (t._initialized)
|
||||||
|
{
|
||||||
|
context << " LIMIT ";
|
||||||
|
serialize(t._value, context);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Limit>
|
||||||
|
struct serializer_t<Context, limit_data_t<Limit>>
|
||||||
|
{
|
||||||
|
using T = limit_data_t<Limit>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " LIMIT ";
|
||||||
|
serialize(t._value, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -30,8 +30,6 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>,
|
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>,
|
||||||
@ -66,14 +64,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Expr _expr;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Expr>
|
template<typename Context, typename Expr>
|
||||||
struct serializer_t<Context, vendor::max_t<Expr>>
|
struct serializer_t<Context, max_t<Expr>>
|
||||||
{
|
{
|
||||||
using T = vendor::max_t<Expr>;
|
using T = max_t<Expr>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -83,12 +78,11 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto max(T t) -> typename vendor::max_t<vendor::wrap_operand_t<T>>
|
auto max(T t) -> max_t<wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_expression_t<vendor::wrap_operand_t<T>>::value, "max() requires a value expression as argument");
|
static_assert(is_expression_t<wrap_operand_t<T>>::value, "max() requires a value expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>,
|
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>,
|
||||||
@ -66,14 +64,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Expr _expr;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Expr>
|
template<typename Context, typename Expr>
|
||||||
struct serializer_t<Context, vendor::min_t<Expr>>
|
struct serializer_t<Context, min_t<Expr>>
|
||||||
{
|
{
|
||||||
using T = vendor::min_t<Expr>;
|
using T = min_t<Expr>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -83,12 +78,11 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto min(T t) -> typename vendor::min_t<vendor::wrap_operand_t<T>>
|
auto min(T t) -> min_t<wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_expression_t<vendor::wrap_operand_t<T>>::value, "min() requires a value expression as argument");
|
static_assert(is_expression_t<wrap_operand_t<T>>::value, "min() requires a value expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,8 +110,6 @@ namespace sqlpp
|
|||||||
std::tuple<Columns...> _columns;
|
std::tuple<Columns...> _columns;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename... Columns>
|
template<typename Context, typename... Columns>
|
||||||
struct serializer_t<Context, multi_column_t<void, Columns...>>
|
struct serializer_t<Context, multi_column_t<void, Columns...>>
|
||||||
{
|
{
|
||||||
@ -134,7 +132,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
137
include/sqlpp11/named_interpretable.h
Normal file
137
include/sqlpp11/named_interpretable.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_NAMED_SERIALIZABLE_H
|
||||||
|
#define SQLPP_NAMED_SERIALIZABLE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <sqlpp11/serializer_context.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
template<typename Db>
|
||||||
|
struct named_interpretable_t
|
||||||
|
{
|
||||||
|
using _serializer_context_t = typename Db::_serializer_context_t;
|
||||||
|
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
named_interpretable_t(T t):
|
||||||
|
_impl(std::make_shared<_impl_t<T>>(t))
|
||||||
|
{}
|
||||||
|
|
||||||
|
named_interpretable_t(const named_interpretable_t&) = default;
|
||||||
|
named_interpretable_t(named_interpretable_t&&) = default;
|
||||||
|
named_interpretable_t& operator=(const named_interpretable_t&) = default;
|
||||||
|
named_interpretable_t& operator=(named_interpretable_t&&) = default;
|
||||||
|
~named_interpretable_t() = default;
|
||||||
|
|
||||||
|
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||||
|
{
|
||||||
|
return _impl->serialize(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
||||||
|
template<typename Context>
|
||||||
|
auto serialize(Context& context) const
|
||||||
|
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
||||||
|
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
||||||
|
{
|
||||||
|
return _impl->db_serialize(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||||
|
{
|
||||||
|
return _impl->interpret(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _get_name() const
|
||||||
|
{
|
||||||
|
_impl->_get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct _impl_base
|
||||||
|
{
|
||||||
|
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
||||||
|
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
||||||
|
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
||||||
|
virtual std::string _get_name() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct _impl_t: public _impl_base
|
||||||
|
{
|
||||||
|
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
||||||
|
_impl_t(T t):
|
||||||
|
_t(t)
|
||||||
|
{}
|
||||||
|
|
||||||
|
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
||||||
|
{
|
||||||
|
sqlpp::serialize(_t, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
||||||
|
{
|
||||||
|
Db::_serialize_interpretable(_t, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
||||||
|
{
|
||||||
|
Db::_interpret_interpretable(_t, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _get_name() const
|
||||||
|
{
|
||||||
|
return T::_name_t::_get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
T _t;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<const _impl_base> _impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Database>
|
||||||
|
struct serializer_t<Context, named_interpretable_t<Database>>
|
||||||
|
{
|
||||||
|
using T = named_interpretable_t<Database>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
t.serialize(context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -29,11 +29,9 @@
|
|||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sqlpp11/no_value.h>
|
#include <sqlpp11/no_value.h>
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
#warning: Need extra include file for no_data
|
#warning: Need extra include file for no_data
|
||||||
struct no_data_t {};
|
struct no_data_t {};
|
||||||
@ -74,7 +72,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_noop: std::is_same<T, noop> {};
|
struct is_noop: std::is_same<T, noop> {};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -28,13 +28,10 @@
|
|||||||
#define SQLPP_NOOP_FWD_H
|
#define SQLPP_NOOP_FWD_H
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
struct noop;
|
struct noop;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_noop;
|
struct is_noop;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
@ -37,8 +37,6 @@ namespace sqlpp
|
|||||||
using _recursive_traits = make_recursive_traits<>;
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, null_t>
|
struct serializer_t<Context, null_t>
|
||||||
{
|
{
|
||||||
@ -50,7 +48,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
constexpr null_t null = {};
|
constexpr null_t null = {};
|
||||||
|
|
||||||
|
267
include/sqlpp11/offset.h
Normal file
267
include/sqlpp11/offset.h
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_OFFSET_H
|
||||||
|
#define SQLPP_OFFSET_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// OFFSET DATA
|
||||||
|
template<typename Offset>
|
||||||
|
struct offset_data_t
|
||||||
|
{
|
||||||
|
offset_data_t(Offset value):
|
||||||
|
_value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
offset_data_t(const offset_data_t&) = default;
|
||||||
|
offset_data_t(offset_data_t&&) = default;
|
||||||
|
offset_data_t& operator=(const offset_data_t&) = default;
|
||||||
|
offset_data_t& operator=(offset_data_t&&) = default;
|
||||||
|
~offset_data_t() = default;
|
||||||
|
|
||||||
|
Offset _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// OFFSET
|
||||||
|
template<typename Offset>
|
||||||
|
struct offset_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Offset>;
|
||||||
|
|
||||||
|
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = offset_data_t<Offset>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = offset_data_t<Offset>;
|
||||||
|
|
||||||
|
_impl_t<Policies> offset;
|
||||||
|
_impl_t<Policies>& operator()() { return offset; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return offset; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.offset)
|
||||||
|
{
|
||||||
|
return t.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// DYNAMIC OFFSET DATA
|
||||||
|
template<typename Database>
|
||||||
|
struct dynamic_offset_data_t
|
||||||
|
{
|
||||||
|
dynamic_offset_data_t():
|
||||||
|
_value(noop())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Offset>
|
||||||
|
dynamic_offset_data_t(Offset value):
|
||||||
|
_initialized(true),
|
||||||
|
_value(typename wrap_operand<Offset>::type(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
|
||||||
|
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
|
||||||
|
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
|
||||||
|
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
|
||||||
|
~dynamic_offset_data_t() = default;
|
||||||
|
|
||||||
|
bool _initialized = false;
|
||||||
|
interpretable_t<Database> _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// DYNAMIC OFFSET
|
||||||
|
template<typename Database>
|
||||||
|
struct dynamic_offset_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = dynamic_offset_data_t<Database>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Offset>
|
||||||
|
void set(Offset value)
|
||||||
|
{
|
||||||
|
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||||
|
using arg_t = typename wrap_operand<Offset>::type;
|
||||||
|
_data._value = arg_t{value};
|
||||||
|
_data._initialized = true;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = dynamic_offset_data_t<Database>;
|
||||||
|
|
||||||
|
_impl_t<Policies> offset;
|
||||||
|
_impl_t<Policies>& operator()() { return offset; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return offset; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.offset)
|
||||||
|
{
|
||||||
|
return t.offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
template<typename Offset>
|
||||||
|
void set_offset(Offset value)
|
||||||
|
{
|
||||||
|
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||||
|
using arg_t = typename wrap_operand<Offset>::type;
|
||||||
|
static_cast<typename Policies::_statement_t*>(this)->_offset()._value = arg_t{value};
|
||||||
|
static_cast<typename Policies::_statement_t*>(this)->_offset()._initialized = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool _initialized = false;
|
||||||
|
interpretable_t<Database> _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_offset_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_offset;
|
||||||
|
_impl_t<Policies>& operator()() { return no_offset; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_offset; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_offset)
|
||||||
|
{
|
||||||
|
return t.no_offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_offset_t, T>;
|
||||||
|
|
||||||
|
template<typename Arg>
|
||||||
|
auto offset(Arg arg)
|
||||||
|
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), offset_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dynamic_offset()
|
||||||
|
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_data_t<_database_t>{} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Offset>
|
||||||
|
struct serializer_t<Context, offset_data_t<Offset>>
|
||||||
|
{
|
||||||
|
using T = offset_data_t<Offset>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " OFFSET ";
|
||||||
|
serialize(t._value, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Database>
|
||||||
|
struct serializer_t<Context, dynamic_offset_data_t<Database>>
|
||||||
|
{
|
||||||
|
using T = dynamic_offset_data_t<Database>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (t._initialized)
|
||||||
|
{
|
||||||
|
context << " OFFSET ";
|
||||||
|
serialize(t._value, context);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -28,8 +28,8 @@
|
|||||||
#define SQLPP_ON_H
|
#define SQLPP_ON_H
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
#include <sqlpp11/interpretable_list.h>
|
||||||
#include <sqlpp11/detail/logic.h>
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -53,11 +53,9 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Expr...> _expressions;
|
std::tuple<Expr...> _expressions;
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
interpretable_list_t<Database> _dynamic_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Database, typename... Expr>
|
template<typename Context, typename Database, typename... Expr>
|
||||||
struct serializer_t<Context, on_t<Database, Expr...>>
|
struct serializer_t<Context, on_t<Database, Expr...>>
|
||||||
{
|
{
|
||||||
@ -77,6 +75,5 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
211
include/sqlpp11/order_by.h
Normal file
211
include/sqlpp11/order_by.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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/type_traits.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/interpretable.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/detail/logic.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// ORDER BY DATA
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct order_by_data_t
|
||||||
|
{
|
||||||
|
order_by_data_t(Expressions... expressions):
|
||||||
|
_expressions(expressions...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
order_by_data_t(const order_by_data_t&) = default;
|
||||||
|
order_by_data_t(order_by_data_t&&) = default;
|
||||||
|
order_by_data_t& operator=(const order_by_data_t&) = default;
|
||||||
|
order_by_data_t& operator=(order_by_data_t&&) = default;
|
||||||
|
~order_by_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Expressions...> _expressions;
|
||||||
|
interpretable_list_t<Database> _dynamic_expressions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ORDER BY
|
||||||
|
template<typename Database, typename... Expressions>
|
||||||
|
struct order_by_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Expression>
|
||||||
|
void add_ntc(Expression expression)
|
||||||
|
{
|
||||||
|
add<Expression, std::false_type>(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Expression expression)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
||||||
|
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||||
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||||
|
|
||||||
|
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_expressions.emplace_back(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Expression>
|
||||||
|
void _add_impl(Expression expression, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> order_by;
|
||||||
|
_impl_t<Policies>& operator()() { return order_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return order_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.order_by)
|
||||||
|
{
|
||||||
|
return t.order_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO ORDER BY YET
|
||||||
|
struct no_order_by_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_order_by;
|
||||||
|
_impl_t<Policies>& operator()() { return no_order_by; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_order_by; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_order_by)
|
||||||
|
{
|
||||||
|
return t.no_order_by;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_order_by_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto order_by(Args... args)
|
||||||
|
-> _new_statement_t<order_by_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_order_by(Args... args)
|
||||||
|
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Expressions>
|
||||||
|
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
||||||
|
{
|
||||||
|
using T = order_by_data_t<Database, Expressions...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
||||||
|
return context;
|
||||||
|
context << " ORDER BY ";
|
||||||
|
interpret_tuple(t._expressions, ',', context);
|
||||||
|
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
||||||
|
context << ',';
|
||||||
|
interpret_list(t._dynamic_expressions, ',', context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -57,8 +57,6 @@ namespace sqlpp
|
|||||||
~parameter_t() = default;
|
~parameter_t() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename ValueType, typename NameType>
|
template<typename Context, typename ValueType, typename NameType>
|
||||||
struct serializer_t<Context, parameter_t<ValueType, NameType>>
|
struct serializer_t<Context, parameter_t<ValueType, NameType>>
|
||||||
{
|
{
|
||||||
@ -70,7 +68,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NamedExpr>
|
template<typename NamedExpr>
|
||||||
auto parameter(const NamedExpr&)
|
auto parameter(const NamedExpr&)
|
||||||
@ -82,7 +79,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename ValueType, typename AliasProvider>
|
template<typename ValueType, typename AliasProvider>
|
||||||
auto parameter(const ValueType&, const AliasProvider&)
|
auto parameter(const ValueType&, const AliasProvider&)
|
||||||
-> parameter_t<vendor::wrap_operand_t<ValueType>, AliasProvider>
|
-> parameter_t<wrap_operand_t<ValueType>, AliasProvider>
|
||||||
{
|
{
|
||||||
static_assert(is_expression_t<ValueType>::value, "first argument is not a value type");
|
static_assert(is_expression_t<ValueType>::value, "first argument is not a value type");
|
||||||
static_assert(is_alias_provider_t<AliasProvider>::value, "second argument is not an alias provider");
|
static_assert(is_alias_provider_t<AliasProvider>::value, "second argument is not an alias provider");
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
#include <sqlpp11/detail/index_sequence.h>
|
#include <sqlpp11/detail/index_sequence.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -37,7 +37,7 @@ namespace sqlpp
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct parameter_list_t
|
struct parameter_list_t
|
||||||
{
|
{
|
||||||
static_assert(vendor::wrong_t<T>::value, "Template parameter for parameter_list_t has to be a tuple");
|
static_assert(wrong_t<T>::value, "Template parameter for parameter_list_t has to be a tuple");
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Parameter>
|
template<typename... Parameter>
|
||||||
|
@ -24,14 +24,12 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_VENDOR_POLICY_UPDATE_H
|
#ifndef SQLPP_POLICY_UPDATE_H
|
||||||
#define SQLPP_VENDOR_POLICY_UPDATE_H
|
#define SQLPP_POLICY_UPDATE_H
|
||||||
|
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Needle, typename Replacement>
|
template<typename Needle, typename Replacement>
|
||||||
struct policy_update_impl
|
struct policy_update_impl
|
||||||
@ -52,7 +50,6 @@ namespace sqlpp
|
|||||||
template<typename Original, typename Needle, typename Replacement>
|
template<typename Original, typename Needle, typename Replacement>
|
||||||
using update_policies_t = typename update_policies_impl<Original, Needle, Replacement>::type;
|
using update_policies_t = typename update_policies_impl<Original, Needle, Replacement>::type;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -31,17 +31,17 @@
|
|||||||
#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/noop.h>
|
||||||
#warning: need to use another table provider, since delete can be used with several tables
|
#warning: need to use another table provider, since delete can be used with several tables
|
||||||
#include <sqlpp11/vendor/from.h>
|
#include <sqlpp11/from.h>
|
||||||
#include <sqlpp11/vendor/extra_tables.h>
|
#include <sqlpp11/extra_tables.h>
|
||||||
#include <sqlpp11/vendor/using.h>
|
#include <sqlpp11/using.h>
|
||||||
#include <sqlpp11/vendor/where.h>
|
#include <sqlpp11/where.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct remove_name_t {};
|
struct remove_name_t {};
|
||||||
struct remove_t: public vendor::statement_name_t<remove_name_t>
|
struct remove_t: public statement_name_t<remove_name_t>
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||||
struct _name_t {};
|
struct _name_t {};
|
||||||
@ -79,8 +79,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, remove_name_t>
|
struct serializer_t<Context, remove_name_t>
|
||||||
{
|
{
|
||||||
@ -93,15 +91,14 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Database>
|
template<typename Database>
|
||||||
using blank_remove_t = statement_t<Database,
|
using blank_remove_t = statement_t<Database,
|
||||||
remove_t,
|
remove_t,
|
||||||
vendor::no_from_t,
|
no_from_t,
|
||||||
vendor::no_using_t,
|
no_using_t,
|
||||||
vendor::no_extra_tables_t,
|
no_extra_tables_t,
|
||||||
vendor::no_where_t>;
|
no_where_t>;
|
||||||
|
|
||||||
auto remove()
|
auto remove()
|
||||||
-> blank_remove_t<void>
|
-> blank_remove_t<void>
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
#define SQLPP_RESULT_ROW_H
|
#define SQLPP_RESULT_ROW_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sqlpp11/vendor/char_result_row.h>
|
#include <sqlpp11/char_result_row.h>
|
||||||
#include <sqlpp11/vendor/field.h>
|
#include <sqlpp11/field.h>
|
||||||
#include <sqlpp11/text.h>
|
#include <sqlpp11/text.h>
|
||||||
#include <sqlpp11/detail/column_index_sequence.h>
|
#include <sqlpp11/detail/column_index_sequence.h>
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t index, typename AliasProvider, typename Db, typename... NamedExprs>
|
template<std::size_t index, typename AliasProvider, typename Db, typename... NamedExprs>
|
||||||
struct result_field<Db, index, vendor::multi_field_t<AliasProvider, std::tuple<NamedExprs...>>>:
|
struct result_field<Db, index, multi_field_t<AliasProvider, std::tuple<NamedExprs...>>>:
|
||||||
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>
|
public AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>
|
||||||
{
|
{
|
||||||
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>;
|
using _multi_field = typename AliasProvider::_name_t::template _member_t<result_row_impl<Db, detail::make_column_index_sequence<index, NamedExprs...>, NamedExprs...>>;
|
||||||
|
@ -29,30 +29,28 @@
|
|||||||
|
|
||||||
#include <sqlpp11/statement.h>
|
#include <sqlpp11/statement.h>
|
||||||
|
|
||||||
#include <sqlpp11/vendor/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
#include <sqlpp11/vendor/select_flag_list.h>
|
#include <sqlpp11/select_flag_list.h>
|
||||||
#include <sqlpp11/vendor/select_column_list.h>
|
#include <sqlpp11/select_column_list.h>
|
||||||
#include <sqlpp11/vendor/from.h>
|
#include <sqlpp11/from.h>
|
||||||
#include <sqlpp11/vendor/extra_tables.h>
|
#include <sqlpp11/extra_tables.h>
|
||||||
#include <sqlpp11/vendor/where.h>
|
#include <sqlpp11/where.h>
|
||||||
#include <sqlpp11/vendor/group_by.h>
|
#include <sqlpp11/group_by.h>
|
||||||
#include <sqlpp11/vendor/having.h>
|
#include <sqlpp11/having.h>
|
||||||
#include <sqlpp11/vendor/order_by.h>
|
#include <sqlpp11/order_by.h>
|
||||||
#include <sqlpp11/vendor/limit.h>
|
#include <sqlpp11/limit.h>
|
||||||
#include <sqlpp11/vendor/offset.h>
|
#include <sqlpp11/offset.h>
|
||||||
#include <sqlpp11/vendor/expression.h>
|
#include <sqlpp11/expression.h>
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
|
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct select_name_t {};
|
struct select_name_t {};
|
||||||
|
|
||||||
struct select_t: public vendor::statement_name_t<select_name_t>
|
struct select_t: public statement_name_t<select_name_t>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, select_name_t>
|
struct serializer_t<Context, select_name_t>
|
||||||
{
|
{
|
||||||
@ -65,21 +63,20 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Database>
|
template<typename Database>
|
||||||
using blank_select_t = statement_t<Database,
|
using blank_select_t = statement_t<Database,
|
||||||
select_t,
|
select_t,
|
||||||
vendor::no_select_flag_list_t,
|
no_select_flag_list_t,
|
||||||
vendor::no_select_column_list_t,
|
no_select_column_list_t,
|
||||||
vendor::no_from_t,
|
no_from_t,
|
||||||
vendor::no_extra_tables_t,
|
no_extra_tables_t,
|
||||||
vendor::no_where_t,
|
no_where_t,
|
||||||
vendor::no_group_by_t,
|
no_group_by_t,
|
||||||
vendor::no_having_t,
|
no_having_t,
|
||||||
vendor::no_order_by_t,
|
no_order_by_t,
|
||||||
vendor::no_limit_t,
|
no_limit_t,
|
||||||
vendor::no_offset_t>;
|
no_offset_t>;
|
||||||
|
|
||||||
|
|
||||||
blank_select_t<void> select() // FIXME: These should be constexpr
|
blank_select_t<void> select() // FIXME: These should be constexpr
|
||||||
|
401
include/sqlpp11/select_column_list.h
Normal file
401
include/sqlpp11/select_column_list.h
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_COLUMN_LIST_H
|
||||||
|
#define SQLPP_SELECT_COLUMN_LIST_H
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <sqlpp11/result_row.h>
|
||||||
|
#include <sqlpp11/table.h>
|
||||||
|
#include <sqlpp11/no_value.h>
|
||||||
|
#include <sqlpp11/field.h>
|
||||||
|
#include <sqlpp11/expression_fwd.h>
|
||||||
|
#include <sqlpp11/select_pseudo_table.h>
|
||||||
|
#include <sqlpp11/named_interpretable.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
#include <sqlpp11/detail/copy_tuple_args.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename... Columns>
|
||||||
|
struct select_traits
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, tag::select_column_list, tag::return_value>;
|
||||||
|
struct _name_t {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Column>
|
||||||
|
struct select_traits<Column>
|
||||||
|
{
|
||||||
|
using _traits = make_traits<value_type_of<Column>, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>;
|
||||||
|
using _name_t = typename Column::_name_t;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
struct dynamic_select_column_list
|
||||||
|
{
|
||||||
|
using _names_t = std::vector<std::string>;
|
||||||
|
std::vector<named_interpretable_t<Db>> _dynamic_columns;
|
||||||
|
_names_t _dynamic_expression_names;
|
||||||
|
|
||||||
|
template<typename Expr>
|
||||||
|
void emplace_back(Expr expr)
|
||||||
|
{
|
||||||
|
_dynamic_expression_names.push_back(Expr::_name_t::_get_name());
|
||||||
|
_dynamic_columns.emplace_back(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return _dynamic_columns.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct dynamic_select_column_list<void>
|
||||||
|
{
|
||||||
|
struct _names_t
|
||||||
|
{
|
||||||
|
static constexpr size_t size() { return 0; }
|
||||||
|
};
|
||||||
|
_names_t _dynamic_expression_names;
|
||||||
|
|
||||||
|
static constexpr bool empty()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Db>
|
||||||
|
struct serializer_t<Context, dynamic_select_column_list<Db>>
|
||||||
|
{
|
||||||
|
using T = dynamic_select_column_list<Db>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
for (const auto column : t._dynamic_columns)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
context << ',';
|
||||||
|
serialize(column, context);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context>
|
||||||
|
struct serializer_t<Context, dynamic_select_column_list<void>>
|
||||||
|
{
|
||||||
|
using T = dynamic_select_column_list<void>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SELECTED COLUMNS DATA
|
||||||
|
template<typename Database, typename... Columns>
|
||||||
|
struct select_column_list_data_t
|
||||||
|
{
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
select_column_list_data_t(Columns... columns):
|
||||||
|
_columns(columns...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
select_column_list_data_t(std::tuple<Columns...> columns):
|
||||||
|
_columns(columns)
|
||||||
|
{}
|
||||||
|
|
||||||
|
select_column_list_data_t(const select_column_list_data_t&) = default;
|
||||||
|
select_column_list_data_t(select_column_list_data_t&&) = default;
|
||||||
|
select_column_list_data_t& operator=(const select_column_list_data_t&) = default;
|
||||||
|
select_column_list_data_t& operator=(select_column_list_data_t&&) = default;
|
||||||
|
~select_column_list_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Columns...> _columns;
|
||||||
|
dynamic_select_column_list<Database> _dynamic_columns;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// SELECTED COLUMNS
|
||||||
|
template<typename Database, typename... Columns>
|
||||||
|
struct select_column_list_t
|
||||||
|
{
|
||||||
|
using _traits = typename ::sqlpp::detail::select_traits<Columns...>::_traits;
|
||||||
|
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||||
|
|
||||||
|
using _name_t = typename ::sqlpp::detail::select_traits<Columns...>::_name_t;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<(is_named_expression_t<Columns>::value or is_multi_column_t<Columns>::value)...>::value, "at least one argument is not a named expression");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
||||||
|
|
||||||
|
struct _column_type {};
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename NamedExpression>
|
||||||
|
void add_ntc(NamedExpression namedExpression)
|
||||||
|
{
|
||||||
|
add<NamedExpression, std::false_type>(namedExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename NamedExpression, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(NamedExpression namedExpression)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
|
||||||
|
static_assert(is_named_expression_t<NamedExpression>::value, "invalid named expression argument in selected_columns::add()");
|
||||||
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<NamedExpression>::value, "named expression uses tables unknown to this statement in selected_columns::add()");
|
||||||
|
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_name_t...>;
|
||||||
|
static_assert(not ::sqlpp::detail::is_element_of<typename NamedExpression::_name_t, column_names>::value, "a column of this name is present in the select already");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<
|
||||||
|
_is_dynamic::value,
|
||||||
|
is_named_expression_t<NamedExpression>::value
|
||||||
|
>;
|
||||||
|
|
||||||
|
_add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
//private:
|
||||||
|
template<typename NamedExpression>
|
||||||
|
void _add_impl(NamedExpression namedExpression, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_columns.emplace_back(namedExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename NamedExpression>
|
||||||
|
void _add_column_impl(NamedExpression namedExpression, const std::false_type&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> selected_columns;
|
||||||
|
_impl_t<Policies>& operator()() { return selected_columns; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return selected_columns; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.selected_columns)
|
||||||
|
{
|
||||||
|
return t.selected_columns;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// Result methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _result_methods_t
|
||||||
|
{
|
||||||
|
using _statement_t = typename Policies::_statement_t;
|
||||||
|
|
||||||
|
const _statement_t& _get_statement() const
|
||||||
|
{
|
||||||
|
return static_cast<const _statement_t&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||||
|
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
||||||
|
result_row_t<Db, make_field_t<Columns>...>>::type;
|
||||||
|
|
||||||
|
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||||
|
|
||||||
|
template<typename AliasProvider>
|
||||||
|
struct _deferred_table_t
|
||||||
|
{
|
||||||
|
using table = select_pseudo_table_t<_statement_t, Columns...>;
|
||||||
|
using alias = typename table::template _alias_t<AliasProvider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename AliasProvider>
|
||||||
|
using _table_t = typename _deferred_table_t<AliasProvider>::table;
|
||||||
|
|
||||||
|
template<typename AliasProvider>
|
||||||
|
using _alias_t = typename _deferred_table_t<AliasProvider>::alias;
|
||||||
|
|
||||||
|
template<typename AliasProvider>
|
||||||
|
_alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const
|
||||||
|
{
|
||||||
|
static_assert(Policies::_can_be_used_as_table::value, "statement cannot be used as table, e.g. due to missing tables");
|
||||||
|
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
const _dynamic_names_t& get_dynamic_names() const
|
||||||
|
{
|
||||||
|
return _get_statement().selected_columns._data._dynamic_columns._dynamic_expression_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_no_of_result_columns() const
|
||||||
|
{
|
||||||
|
return sizeof...(Columns) + get_dynamic_names().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
template<typename Db>
|
||||||
|
auto _run(Db& db) const
|
||||||
|
-> result_t<decltype(db.select(_get_statement())), _result_row_t<Db>>
|
||||||
|
{
|
||||||
|
_statement_t::_check_consistency();
|
||||||
|
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||||
|
|
||||||
|
return {db.select(_get_statement()), get_dynamic_names()};
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
template<typename Db>
|
||||||
|
auto _prepare(Db& db) const
|
||||||
|
-> prepared_select_t<Db, select_t>
|
||||||
|
{
|
||||||
|
_statement_t::_check_consistency();
|
||||||
|
|
||||||
|
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename Database, typename... Columns>
|
||||||
|
using make_select_column_list_t =
|
||||||
|
copy_tuple_args_t<select_column_list_t, Database,
|
||||||
|
decltype(std::tuple_cat(as_tuple<Columns>::_(std::declval<Columns>())...))>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct no_select_column_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop, ::sqlpp::tag::missing>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
struct _name_t {};
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_selected_columns;
|
||||||
|
_impl_t<Policies>& operator()() { return no_selected_columns; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_selected_columns; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_selected_columns)
|
||||||
|
{
|
||||||
|
return t.no_selected_columns;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_select_column_list_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto columns(Args... args)
|
||||||
|
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<void, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_columns(Args... args)
|
||||||
|
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_columns must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Columns>
|
||||||
|
struct serializer_t<Context, select_column_list_data_t<Database, Columns...>>
|
||||||
|
{
|
||||||
|
using T = select_column_list_data_t<Database, Columns...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
// check for at least one expression
|
||||||
|
static_assert(T::_is_dynamic::value or sizeof...(Columns), "at least one select expression required");
|
||||||
|
|
||||||
|
interpret_tuple(t._columns, ',', context);
|
||||||
|
if (sizeof...(Columns) and not t._dynamic_columns.empty())
|
||||||
|
context << ',';
|
||||||
|
serialize(t._dynamic_columns, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
211
include/sqlpp11/select_flag_list.h
Normal file
211
include/sqlpp11/select_flag_list.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_FLAG_LIST_H
|
||||||
|
#define SQLPP_SELECT_FLAG_LIST_H
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/select_flags.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// SELECTED FLAGS DATA
|
||||||
|
template<typename Database, typename... Flags>
|
||||||
|
struct select_flag_list_data_t
|
||||||
|
{
|
||||||
|
select_flag_list_data_t(Flags... flags):
|
||||||
|
_flags(flags...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
select_flag_list_data_t(const select_flag_list_data_t&) = default;
|
||||||
|
select_flag_list_data_t(select_flag_list_data_t&&) = default;
|
||||||
|
select_flag_list_data_t& operator=(const select_flag_list_data_t&) = default;
|
||||||
|
select_flag_list_data_t& operator=(select_flag_list_data_t&&) = default;
|
||||||
|
~select_flag_list_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Flags...> _flags;
|
||||||
|
interpretable_list_t<Database> _dynamic_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
// SELECT FLAGS
|
||||||
|
template<typename Database, typename... Flags>
|
||||||
|
struct select_flag_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::select_flag_list>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Flags...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Flag>
|
||||||
|
void add_ntc(Flag flag)
|
||||||
|
{
|
||||||
|
add<Flag, std::false_type>(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Flag, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Flag flag)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "select_flags::add() must not be called for static select flags");
|
||||||
|
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in select_flags::add()");
|
||||||
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in select_flags::add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
|
||||||
|
|
||||||
|
_add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Flag>
|
||||||
|
void _add_impl(Flag flag, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_flags.emplace_back(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Flag>
|
||||||
|
void _add_impl(Flag flag, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> select_flags;
|
||||||
|
_impl_t<Policies>& operator()() { return select_flags; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return select_flags; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.select_flags)
|
||||||
|
{
|
||||||
|
return t.select_flags;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_select_flag_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_select_flags;
|
||||||
|
_impl_t<Policies>& operator()() { return no_select_flags; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_select_flags; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_select_flags)
|
||||||
|
{
|
||||||
|
return t.no_select_flags;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_select_flag_list_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto flags(Args... args)
|
||||||
|
-> _new_statement_t<select_flag_list_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_flags(Args... args)
|
||||||
|
-> _new_statement_t<select_flag_list_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Flags>
|
||||||
|
struct serializer_t<Context, select_flag_list_data_t<Database, Flags...>>
|
||||||
|
{
|
||||||
|
using T = select_flag_list_data_t<Database, Flags...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
interpret_tuple(t._flags, ' ', context);
|
||||||
|
if (sizeof...(Flags))
|
||||||
|
context << ' ';
|
||||||
|
interpret_list(t._dynamic_flags, ',', context);
|
||||||
|
if (not t._dynamic_flags.empty())
|
||||||
|
context << ' ';
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -42,8 +42,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
static constexpr all_t all = {};
|
static constexpr all_t all = {};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, all_t>
|
struct serializer_t<Context, all_t>
|
||||||
{
|
{
|
||||||
@ -53,7 +51,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
struct distinct_t
|
struct distinct_t
|
||||||
{
|
{
|
||||||
@ -62,8 +59,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
static constexpr distinct_t distinct = {};
|
static constexpr distinct_t distinct = {};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, distinct_t>
|
struct serializer_t<Context, distinct_t>
|
||||||
{
|
{
|
||||||
@ -73,7 +68,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
struct straight_join_t
|
struct straight_join_t
|
||||||
{
|
{
|
||||||
@ -82,8 +76,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
static constexpr straight_join_t straight_join = {};
|
static constexpr straight_join_t straight_join = {};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, straight_join_t>
|
struct serializer_t<Context, straight_join_t>
|
||||||
{
|
{
|
||||||
@ -93,7 +85,6 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +72,6 @@ namespace sqlpp
|
|||||||
Select _select;
|
Select _select;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Select, typename... NamedExpr>
|
template<typename Context, typename Select, typename... NamedExpr>
|
||||||
struct serializer_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
|
struct serializer_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
|
||||||
{
|
{
|
||||||
@ -87,6 +85,5 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -27,26 +27,23 @@
|
|||||||
#ifndef SQLPP_SERIALIZE_H
|
#ifndef SQLPP_SERIALIZE_H
|
||||||
#define SQLPP_SERIALIZE_H
|
#define SQLPP_SERIALIZE_H
|
||||||
|
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename T, typename Context>
|
template<typename T, typename Context>
|
||||||
auto serialize(const T& t, Context& context)
|
auto serialize(const T& t, Context& context)
|
||||||
-> decltype(vendor::serializer_t<Context, T>::_(t, context))
|
-> decltype(serializer_t<Context, T>::_(t, context))
|
||||||
{
|
{
|
||||||
return vendor::serializer_t<Context, T>::_(t, context);
|
return serializer_t<Context, T>::_(t, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
namespace vendor // Required if you want to call serialize(sqlpp::value(7), printer), for instance
|
|
||||||
{
|
|
||||||
template<typename T, typename Context>
|
template<typename T, typename Context>
|
||||||
auto serialize(const T& t, Context& context)
|
auto serialize(const T& t, Context& context)
|
||||||
-> decltype(vendor::serializer_t<Context, T>::_(t, context))
|
-> decltype(serializer_t<Context, T>::_(t, context))
|
||||||
{
|
{
|
||||||
return vendor::serializer_t<Context, T>::_(t, context);
|
return serializer_t<Context, T>::_(t, context);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -24,14 +24,12 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_VENDOR_SERIALIZER_H
|
#ifndef SQLPP_SERIALIZER_H
|
||||||
#define SQLPP_VENDOR_SERIALIZER_H
|
#define SQLPP_SERIALIZER_H
|
||||||
|
|
||||||
#include <sqlpp11/vendor/wrong.h>
|
#include <sqlpp11/wrong.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Context, typename T, typename Enable = void>
|
template<typename Context, typename T, typename Enable = void>
|
||||||
struct serializer_t
|
struct serializer_t
|
||||||
@ -41,7 +39,6 @@ namespace sqlpp
|
|||||||
static_assert(wrong_t<Context, T>::value, "missing serializer specialization");
|
static_assert(wrong_t<Context, T>::value, "missing serializer specialization");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -27,11 +27,9 @@
|
|||||||
#ifndef SQLPP_SIMPLE_COLUMN_H
|
#ifndef SQLPP_SIMPLE_COLUMN_H
|
||||||
#define SQLPP_SIMPLE_COLUMN_H
|
#define SQLPP_SIMPLE_COLUMN_H
|
||||||
|
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Column>
|
template<typename Column>
|
||||||
struct simple_column_t
|
struct simple_column_t
|
||||||
@ -57,6 +55,5 @@ namespace sqlpp
|
|||||||
return {c};
|
return {c};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
214
include/sqlpp11/single_table.h
Normal file
214
include/sqlpp11/single_table.h
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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_SINGLE_TABLE_H
|
||||||
|
#define SQLPP_SINGLE_TABLE_H
|
||||||
|
|
||||||
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/no_value.h>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// A SINGLE TABLE DATA
|
||||||
|
template<typename Database, typename Table>
|
||||||
|
struct single_table_data_t
|
||||||
|
{
|
||||||
|
single_table_data_t(Table table):
|
||||||
|
_table(table)
|
||||||
|
{}
|
||||||
|
|
||||||
|
single_table_data_t(const single_table_data_t&) = default;
|
||||||
|
single_table_data_t(single_table_data_t&&) = default;
|
||||||
|
single_table_data_t& operator=(const single_table_data_t&) = default;
|
||||||
|
single_table_data_t& operator=(single_table_data_t&&) = default;
|
||||||
|
~single_table_data_t() = default;
|
||||||
|
|
||||||
|
Table _table;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A SINGLE TABLE
|
||||||
|
template<typename Database, typename Table>
|
||||||
|
struct single_table_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table, tag::return_value>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Table>;
|
||||||
|
|
||||||
|
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||||
|
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||||
|
|
||||||
|
using _data_t = single_table_data_t<Database, Table>;
|
||||||
|
|
||||||
|
struct _name_t {};
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = single_table_data_t<Database, Table>;
|
||||||
|
|
||||||
|
_impl_t<Policies> from;
|
||||||
|
_impl_t<Policies>& operator()() { return from; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return from; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.from)
|
||||||
|
{
|
||||||
|
return t.from;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _result_methods_t
|
||||||
|
{
|
||||||
|
using _statement_t = typename Policies::_statement_t;
|
||||||
|
|
||||||
|
const _statement_t& _get_statement() const
|
||||||
|
{
|
||||||
|
return static_cast<const _statement_t&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
|
{
|
||||||
|
#warning need to fix this
|
||||||
|
return 0;
|
||||||
|
//return _parameter_list_t::size::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _get_no_of_parameters() const
|
||||||
|
{
|
||||||
|
#warning need to fix this
|
||||||
|
return 0;
|
||||||
|
//return _parameter_list_t::size::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _check_consistency() const
|
||||||
|
{
|
||||||
|
// FIXME: Read up on what is allowed/prohibited in INSERT
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Db>
|
||||||
|
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||||
|
{
|
||||||
|
_check_consistency();
|
||||||
|
|
||||||
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||||
|
return db.insert(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
template<typename Db>
|
||||||
|
auto _prepare(Db& db) const
|
||||||
|
-> prepared_insert_t<Db, insert_t>
|
||||||
|
{
|
||||||
|
_check_consistency();
|
||||||
|
|
||||||
|
return {{}, db.prepare_insert(*this)};
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO INTO YET
|
||||||
|
struct no_single_table_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_from;
|
||||||
|
_impl_t<Policies>& operator()() { return no_from; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_from)
|
||||||
|
{
|
||||||
|
return t.no_from;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_single_table_t, T>;
|
||||||
|
|
||||||
|
#warning: remove can operate on several tables at once, so it should not use single_table anyway
|
||||||
|
template<typename... Args>
|
||||||
|
auto from(Args... args)
|
||||||
|
-> _new_statement_t<single_table_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), single_table_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename Table>
|
||||||
|
struct serializer_t<Context, single_table_data_t<Database, Table>>
|
||||||
|
{
|
||||||
|
using T = single_table_data_t<Database, Table>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
serialize(t._table, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -31,8 +31,6 @@
|
|||||||
#include <sqlpp11/detail/type_set.h>
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Select>
|
template<typename Select>
|
||||||
struct some_t
|
struct some_t
|
||||||
@ -64,14 +62,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Select _select;
|
Select _select;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Select>
|
template<typename Context, typename Select>
|
||||||
struct serializer_t<Context, vendor::some_t<Select>>
|
struct serializer_t<Context, some_t<Select>>
|
||||||
{
|
{
|
||||||
using T = vendor::some_t<Select>;
|
using T = some_t<Select>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -81,13 +76,12 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto some(T t) -> typename vendor::some_t<vendor::wrap_operand_t<T>>
|
auto some(T t) -> some_t<wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_select_t<vendor::wrap_operand_t<T>>::value, "some() requires a single column select expression as argument");
|
static_assert(is_select_t<wrap_operand_t<T>>::value, "some() requires a single column select expression as argument");
|
||||||
static_assert(is_expression_t<vendor::wrap_operand_t<T>>::value, "some() requires a single column select expression as argument");
|
static_assert(is_expression_t<wrap_operand_t<T>>::value, "some() requires a single column select expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,6 @@ namespace sqlpp
|
|||||||
Expression _expression;
|
Expression _expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Expression, sort_type SortType>
|
template<typename Context, typename Expression, sort_type SortType>
|
||||||
struct serializer_t<Context, sort_order_t<Expression, SortType>>
|
struct serializer_t<Context, sort_order_t<Expression, SortType>>
|
||||||
{
|
{
|
||||||
@ -70,6 +68,5 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,9 +31,9 @@
|
|||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_select.h>
|
#include <sqlpp11/prepared_select.h>
|
||||||
#include <sqlpp11/serialize.h>
|
#include <sqlpp11/serialize.h>
|
||||||
#include <sqlpp11/vendor/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
#include <sqlpp11/policy_update.h>
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
|
|
||||||
#include <sqlpp11/detail/get_last.h>
|
#include <sqlpp11/detail/get_last.h>
|
||||||
#include <sqlpp11/detail/pick_arg.h>
|
#include <sqlpp11/detail/pick_arg.h>
|
||||||
@ -61,7 +61,7 @@ namespace sqlpp
|
|||||||
struct _policies_update_t
|
struct _policies_update_t
|
||||||
{
|
{
|
||||||
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
||||||
using type = statement_t<Db, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
using type = statement_t<Db, policy_update_t<Policies, Needle, Replacement>...>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Needle, typename Replacement>
|
template<typename Needle, typename Replacement>
|
||||||
@ -82,7 +82,7 @@ namespace sqlpp
|
|||||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using _result_type_provider = detail::get_last_if<is_return_value_t, vendor::noop, Policies...>;
|
using _result_type_provider = detail::get_last_if<is_return_value_t, noop, Policies...>;
|
||||||
|
|
||||||
struct _result_methods_t: public _result_type_provider::template _result_methods_t<statement_policies_t>
|
struct _result_methods_t: public _result_type_provider::template _result_methods_t<statement_policies_t>
|
||||||
{};
|
{};
|
||||||
@ -181,8 +181,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Database, typename... Policies>
|
template<typename Context, typename Database, typename... Policies>
|
||||||
struct serializer_t<Context, statement_t<Database, Policies...>>
|
struct serializer_t<Context, statement_t<Database, Policies...>>
|
||||||
{
|
{
|
||||||
@ -239,7 +237,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename Flag, typename Expr>
|
template<typename Flag, typename Expr>
|
||||||
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>,
|
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>,
|
||||||
@ -67,14 +65,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
Expr _expr;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Flag, typename Expr>
|
template<typename Context, typename Flag, typename Expr>
|
||||||
struct serializer_t<Context, vendor::sum_t<Flag, Expr>>
|
struct serializer_t<Context, sum_t<Flag, Expr>>
|
||||||
{
|
{
|
||||||
using T = vendor::sum_t<Flag, Expr>;
|
using T = sum_t<Flag, Expr>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
@ -89,19 +84,18 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto sum(T t) -> typename vendor::sum_t<vendor::noop, vendor::wrap_operand_t<T>>
|
auto sum(T t) -> sum_t<noop, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_numeric_t<vendor::wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
|
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto sum(const sqlpp::distinct_t&, T t) -> typename vendor::sum_t<sqlpp::distinct_t, vendor::wrap_operand_t<T>>
|
auto sum(const sqlpp::distinct_t&, T t) -> sum_t<sqlpp::distinct_t, wrap_operand_t<T>>
|
||||||
{
|
{
|
||||||
static_assert(is_numeric_t<vendor::wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
|
static_assert(is_numeric_t<wrap_operand_t<T>>::value, "sum() requires a numeric expression as argument");
|
||||||
return { t };
|
return { t };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +101,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename X>
|
template<typename Context, typename X>
|
||||||
struct serializer_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 serializer_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>
|
||||||
{
|
{
|
||||||
@ -117,7 +115,6 @@ namespace sqlpp
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -61,8 +61,6 @@ namespace sqlpp
|
|||||||
Table _table;
|
Table _table;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename AliasProvider, typename Table, typename... ColumnSpec>
|
template<typename Context, typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||||
struct serializer_t<Context, table_alias_t<AliasProvider, Table, ColumnSpec...>>
|
struct serializer_t<Context, table_alias_t<AliasProvider, Table, ColumnSpec...>>
|
||||||
{
|
{
|
||||||
@ -78,7 +76,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#include <sqlpp11/basic_expression_operators.h>
|
#include <sqlpp11/basic_expression_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
#include <sqlpp11/vendor/concat.h>
|
#include <sqlpp11/concat.h>
|
||||||
#include <sqlpp11/vendor/like.h>
|
#include <sqlpp11/like.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -189,18 +189,18 @@ namespace sqlpp
|
|||||||
struct expression_operators: public basic_expression_operators<Base, is_text_t>
|
struct expression_operators: public basic_expression_operators<Base, is_text_t>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::concat_t<Base, vendor::wrap_operand_t<T>> operator+(T t) const
|
concat_t<Base, wrap_operand_t<T>> operator+(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
vendor::like_t<Base, vendor::wrap_operand_t<T>> like(T t) const
|
like_t<Base, wrap_operand_t<T>> like(T t) const
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid argument for like()");
|
static_assert(_is_valid_operand<rhs>::value, "invalid argument for like()");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), {t} };
|
return { *static_cast<const Base*>(this), {t} };
|
||||||
@ -211,9 +211,9 @@ namespace sqlpp
|
|||||||
struct column_operators
|
struct column_operators
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator +=(T t) const -> vendor::assignment_t<Base, vendor::concat_t<Base, vendor::wrap_operand_t<T>>>
|
auto operator +=(T t) const -> assignment_t<Base, concat_t<Base, wrap_operand_t<T>>>
|
||||||
{
|
{
|
||||||
using rhs = vendor::wrap_operand_t<T>;
|
using rhs = wrap_operand_t<T>;
|
||||||
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
static_assert(_is_valid_operand<rhs>::value, "invalid rhs assignment operand");
|
||||||
|
|
||||||
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
return { *static_cast<const Base*>(this), { *static_cast<const Base*>(this), rhs{t} } };
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/serialize.h>
|
#include <sqlpp11/serialize.h>
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
#include <sqlpp11/serializer.h>
|
||||||
#include <sqlpp11/vendor/wrap_operand.h>
|
#include <sqlpp11/wrap_operand.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -61,8 +61,6 @@ namespace sqlpp
|
|||||||
Operand _value;
|
Operand _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Operand>
|
template<typename Context, typename Operand>
|
||||||
struct serializer_t<Context, tvin_t<Operand>>
|
struct serializer_t<Context, tvin_t<Operand>>
|
||||||
{
|
{
|
||||||
@ -70,10 +68,9 @@ namespace sqlpp
|
|||||||
|
|
||||||
static void _(const T& t, Context& context)
|
static void _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
static_assert(vendor::wrong_t<T>::value, "tvin() must not be used with anything but =, ==, != and !");
|
static_assert(wrong_t<T>::value, "tvin() must not be used with anything but =, ==, != and !");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Operand>
|
template<typename Operand>
|
||||||
struct maybe_tvin_t
|
struct maybe_tvin_t
|
||||||
@ -121,8 +118,6 @@ namespace sqlpp
|
|||||||
typename tvin_t<Operand>::_operand_t _value;
|
typename tvin_t<Operand>::_operand_t _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context, typename Operand>
|
template<typename Context, typename Operand>
|
||||||
struct serializer_t<Context, maybe_tvin_t<Operand>>
|
struct serializer_t<Context, maybe_tvin_t<Operand>>
|
||||||
{
|
{
|
||||||
@ -141,13 +136,12 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Operand>
|
template<typename Operand>
|
||||||
auto tvin(Operand operand) -> tvin_t<typename vendor::wrap_operand<Operand>::type>
|
auto tvin(Operand operand) -> tvin_t<typename wrap_operand<Operand>::type>
|
||||||
{
|
{
|
||||||
using _operand_t = typename vendor::wrap_operand<Operand>::type;
|
using _operand_t = typename wrap_operand<Operand>::type;
|
||||||
static_assert(std::is_same<_operand_t, vendor::text_operand>::value
|
static_assert(std::is_same<_operand_t, text_operand>::value
|
||||||
or not std::is_same<_operand_t, Operand>::value, "tvin() used with invalid type (only string and primitive types allowed)");
|
or not std::is_same<_operand_t, Operand>::value, "tvin() used with invalid type (only string and primitive types allowed)");
|
||||||
return {{operand}};
|
return {{operand}};
|
||||||
}
|
}
|
||||||
|
@ -32,16 +32,16 @@
|
|||||||
#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/single_table.h>
|
#include <sqlpp11/single_table.h>
|
||||||
#include <sqlpp11/vendor/update_list.h>
|
#include <sqlpp11/update_list.h>
|
||||||
#include <sqlpp11/vendor/noop.h>
|
#include <sqlpp11/noop.h>
|
||||||
#include <sqlpp11/vendor/where.h>
|
#include <sqlpp11/where.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct update_name_t {};
|
struct update_name_t {};
|
||||||
|
|
||||||
struct update_t: public vendor::statement_name_t<update_name_t>
|
struct update_t: public statement_name_t<update_name_t>
|
||||||
{
|
{
|
||||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||||
struct _name_t {};
|
struct _name_t {};
|
||||||
@ -79,8 +79,6 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
struct serializer_t<Context, update_name_t>
|
struct serializer_t<Context, update_name_t>
|
||||||
{
|
{
|
||||||
@ -93,14 +91,13 @@ namespace sqlpp
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Database>
|
template<typename Database>
|
||||||
using blank_update_t = statement_t<Database,
|
using blank_update_t = statement_t<Database,
|
||||||
update_t,
|
update_t,
|
||||||
vendor::no_single_table_t,
|
no_single_table_t,
|
||||||
vendor::no_update_list_t,
|
no_update_list_t,
|
||||||
vendor::no_where_t>;
|
no_where_t>;
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
constexpr auto update(Table table)
|
constexpr auto update(Table table)
|
||||||
|
220
include/sqlpp11/update_list.h
Normal file
220
include/sqlpp11/update_list.h
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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/type_set.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/interpretable_list.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// UPDATE ASSIGNMENTS DATA
|
||||||
|
template<typename Database, typename... Assignments>
|
||||||
|
struct update_list_data_t
|
||||||
|
{
|
||||||
|
update_list_data_t(Assignments... assignments):
|
||||||
|
_assignments(assignments...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
update_list_data_t(const update_list_data_t&) = default;
|
||||||
|
update_list_data_t(update_list_data_t&&) = default;
|
||||||
|
update_list_data_t& operator=(const update_list_data_t&) = default;
|
||||||
|
update_list_data_t& operator=(update_list_data_t&&) = default;
|
||||||
|
~update_list_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Assignments...> _assignments;
|
||||||
|
interpretable_list_t<Database> _dynamic_assignments;
|
||||||
|
};
|
||||||
|
|
||||||
|
// UPDATE ASSIGNMENTS
|
||||||
|
template<typename Database, typename... Assignments>
|
||||||
|
struct update_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::update_list>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Assignments...>;
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
||||||
|
|
||||||
|
#warning reactivate tests
|
||||||
|
/*
|
||||||
|
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
||||||
|
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
||||||
|
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
||||||
|
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
||||||
|
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Assignment>
|
||||||
|
void add_ntc(Assignment assignment)
|
||||||
|
{
|
||||||
|
add<Assignment, std::false_type>(assignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||||
|
void add(Assignment assignment)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||||
|
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
|
||||||
|
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add() argument must not be updated");
|
||||||
|
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<
|
||||||
|
_is_dynamic::value,
|
||||||
|
is_assignment_t<Assignment>::value,
|
||||||
|
not must_not_update_t<typename Assignment::_column_t>::value>;
|
||||||
|
|
||||||
|
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Assignment>
|
||||||
|
void _add_impl(Assignment assignment, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_assignments.emplace_back(assignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Assignment>
|
||||||
|
void _add_impl(Assignment assignment, const std::false_type&);
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> assignments;
|
||||||
|
_impl_t<Policies>& operator()() { return assignments; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return assignments; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.assignments)
|
||||||
|
{
|
||||||
|
return t.assignments;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct no_update_list_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_assignments;
|
||||||
|
_impl_t<Policies>& operator()() { return no_assignments; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_assignments; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_assignments)
|
||||||
|
{
|
||||||
|
return t.no_assignments;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_update_list_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto set(Args... args)
|
||||||
|
-> _new_statement_t<update_list_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_set(Args... args)
|
||||||
|
-> _new_statement_t<update_list_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Assignments>
|
||||||
|
struct serializer_t<Context, update_list_data_t<Database, Assignments...>>
|
||||||
|
{
|
||||||
|
using T = update_list_data_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
|
204
include/sqlpp11/using.h
Normal file
204
include/sqlpp11/using.h
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, 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/interpretable_list.h>
|
||||||
|
#include <sqlpp11/interpret_tuple.h>
|
||||||
|
#include <sqlpp11/detail/type_set.h>
|
||||||
|
#include <sqlpp11/policy_update.h>
|
||||||
|
|
||||||
|
namespace sqlpp
|
||||||
|
{
|
||||||
|
// USING DATA
|
||||||
|
template<typename Database, typename... Tables>
|
||||||
|
struct using_data_t
|
||||||
|
{
|
||||||
|
using_data_t(Tables... tables):
|
||||||
|
_tables(tables...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
using_data_t(const using_data_t&) = default;
|
||||||
|
using_data_t(using_data_t&&) = default;
|
||||||
|
using_data_t& operator=(const using_data_t&) = default;
|
||||||
|
using_data_t& operator=(using_data_t&&) = default;
|
||||||
|
~using_data_t() = default;
|
||||||
|
|
||||||
|
std::tuple<Tables...> _tables;
|
||||||
|
interpretable_list_t<Database> _dynamic_tables;
|
||||||
|
};
|
||||||
|
|
||||||
|
// USING
|
||||||
|
template<typename Database, typename... Tables>
|
||||||
|
struct using_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::using_>;
|
||||||
|
using _recursive_traits = make_recursive_traits<Tables...>;
|
||||||
|
|
||||||
|
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||||
|
|
||||||
|
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table argument required in using()");
|
||||||
|
|
||||||
|
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
|
||||||
|
|
||||||
|
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = using_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template <typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
template<typename Table>
|
||||||
|
void add(Table table)
|
||||||
|
{
|
||||||
|
static_assert(_is_dynamic::value, "add must not be called for static using()");
|
||||||
|
static_assert(is_table_t<Table>::value, "invalid table argument in add()");
|
||||||
|
|
||||||
|
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||||
|
|
||||||
|
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename Table>
|
||||||
|
void _add_impl(Table table, const std::true_type&)
|
||||||
|
{
|
||||||
|
return _data._dynamic_tables.emplace_back(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Table>
|
||||||
|
void _add_impl(Table table, const std::false_type&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = using_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
_impl_t<Policies> using_;
|
||||||
|
_impl_t<Policies>& operator()() { return using_; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return using_; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.using_)
|
||||||
|
{
|
||||||
|
return t.using_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Additional methods for the statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// NO USING YET
|
||||||
|
struct no_using_t
|
||||||
|
{
|
||||||
|
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||||
|
using _recursive_traits = make_recursive_traits<>;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
// Member implementation with data and methods
|
||||||
|
template<typename Policies>
|
||||||
|
struct _impl_t
|
||||||
|
{
|
||||||
|
_data_t _data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Member template for adding the named member to a statement
|
||||||
|
template<typename Policies>
|
||||||
|
struct _member_t
|
||||||
|
{
|
||||||
|
using _data_t = no_data_t;
|
||||||
|
|
||||||
|
_impl_t<Policies> no_using;
|
||||||
|
_impl_t<Policies>& operator()() { return no_using; }
|
||||||
|
const _impl_t<Policies>& operator()() const { return no_using; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static auto _get_member(T t) -> decltype(t.no_using)
|
||||||
|
{
|
||||||
|
return t.no_using;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Policies>
|
||||||
|
struct _methods_t
|
||||||
|
{
|
||||||
|
using _database_t = typename Policies::_database_t;
|
||||||
|
template<typename T>
|
||||||
|
using _new_statement_t = typename Policies::template _new_statement_t<no_using_t, T>;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto using_(Args... args)
|
||||||
|
-> _new_statement_t<using_t<void, Args...>>
|
||||||
|
{
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<void, Args...>{args...} };
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
auto dynamic_using(Args... args)
|
||||||
|
-> _new_statement_t<using_t<_database_t, Args...>>
|
||||||
|
{
|
||||||
|
static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement");
|
||||||
|
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<_database_t, Args...>{args...} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interpreters
|
||||||
|
template<typename Context, typename Database, typename... Tables>
|
||||||
|
struct serializer_t<Context, using_data_t<Database, Tables...>>
|
||||||
|
{
|
||||||
|
using T = using_data_t<Database, Tables...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
||||||
|
return context;
|
||||||
|
context << " USING ";
|
||||||
|
interpret_tuple(t._tables, ',', context);
|
||||||
|
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
||||||
|
context << ',';
|
||||||
|
interpret_list(t._dynamic_tables, ',', context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -28,14 +28,11 @@
|
|||||||
#define SQLPP_VALUE_TYPE_H
|
#define SQLPP_VALUE_TYPE_H
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sqlpp11/vendor/wrap_operand.h>
|
#include <sqlpp11/wrap_operand.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using value_type_t = value_type_of<wrap_operand_t<T>>;
|
using value_type_t = value_type_of<wrap_operand_t<T>>;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
164
include/sqlpp11/vendor/assignment.h
vendored
164
include/sqlpp11/vendor/assignment.h
vendored
@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_H
|
|
||||||
#define SQLPP_ASSIGNMENT_H
|
|
||||||
|
|
||||||
#include <sqlpp11/default_value.h>
|
|
||||||
#include <sqlpp11/null.h>
|
|
||||||
#include <sqlpp11/tvin.h>
|
|
||||||
#include <sqlpp11/serialize.h>
|
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
|
||||||
#include <sqlpp11/vendor/simple_column.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename T, typename Enable = void>
|
|
||||||
struct is_trivial_t
|
|
||||||
{
|
|
||||||
static constexpr bool _(const T&)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_trivial_t<T, typename std::enable_if<std::is_member_function_pointer<decltype(&T::_is_trivial)>::value, void>::type>
|
|
||||||
{
|
|
||||||
static bool _(const T& t)
|
|
||||||
{
|
|
||||||
return t._is_trivial();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool is_trivial(const T& t)
|
|
||||||
{
|
|
||||||
return is_trivial_t<T>::_(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct assignment_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
|
||||||
|
|
||||||
using _column_t = Lhs;
|
|
||||||
using _value_t = Rhs;
|
|
||||||
|
|
||||||
static_assert(can_be_null_t<_column_t>::value ? true : not std::is_same<_value_t, null_t>::value, "column must not be null");
|
|
||||||
|
|
||||||
assignment_t(_column_t lhs, _value_t 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;
|
|
||||||
|
|
||||||
_column_t _lhs;
|
|
||||||
_value_t _rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Lhs, typename Rhs>
|
|
||||||
struct serializer_t<Context, assignment_t<Lhs, Rhs>>
|
|
||||||
{
|
|
||||||
using T = assignment_t<Lhs, Rhs>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if ((trivial_value_is_null_t<typename T::_column_t>::value
|
|
||||||
and is_trivial(t._rhs))
|
|
||||||
or (std::is_same<Rhs, null_t>::value))
|
|
||||||
{
|
|
||||||
serialize(simple_column(t._lhs), context);
|
|
||||||
context << "=NULL";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serialize(simple_column(t._lhs), context);
|
|
||||||
context << "=";
|
|
||||||
serialize(t._rhs, context);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct assignment_t<Lhs, tvin_t<Rhs>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::assignment>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
|
||||||
|
|
||||||
using _column_t = Lhs;
|
|
||||||
using _value_t = tvin_t<Rhs>;
|
|
||||||
|
|
||||||
static_assert(can_be_null_t<_column_t>::value, "column cannot be null");
|
|
||||||
|
|
||||||
assignment_t(_column_t lhs, _value_t 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;
|
|
||||||
|
|
||||||
_column_t _lhs;
|
|
||||||
_value_t _rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Lhs, typename Rhs>
|
|
||||||
struct serializer_t<Context, assignment_t<Lhs, tvin_t<Rhs>>>
|
|
||||||
{
|
|
||||||
using T = assignment_t<Lhs, tvin_t<Rhs>>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
serialize(simple_column(t._lhs), context);
|
|
||||||
if (t._rhs._value._is_trivial())
|
|
||||||
{
|
|
||||||
context << "=NULL";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context << "=";
|
|
||||||
serialize(t._rhs._value, context);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
87
include/sqlpp11/vendor/concat.h
vendored
87
include/sqlpp11/vendor/concat.h
vendored
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_CONCAT_H
|
|
||||||
#define SQLPP_CONCAT_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// FIXME: Remove First, inherit from text_t
|
|
||||||
template<typename First, typename... Args>
|
|
||||||
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>,
|
|
||||||
public alias_operators<concat_t<First, Args...>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
|
||||||
using _recursive_traits = make_recursive_traits<First, Args...>;
|
|
||||||
|
|
||||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
|
||||||
static_assert(sqlpp::detail::all_t<is_text_t<First>::value, is_text_t<Args>::value...>::value, "at least one non-text argument detected in concat()");
|
|
||||||
struct _name_t
|
|
||||||
{
|
|
||||||
static constexpr const char* _get_name() { return "CONCAT"; }
|
|
||||||
template<typename T>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
T concat;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
concat_t(First first, Args... args):
|
|
||||||
_args(first, args...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
concat_t(const concat_t&) = default;
|
|
||||||
concat_t(concat_t&&) = default;
|
|
||||||
concat_t& operator=(const concat_t&) = default;
|
|
||||||
concat_t& operator=(concat_t&&) = default;
|
|
||||||
~concat_t() = default;
|
|
||||||
|
|
||||||
std::tuple<First, Args...> _args;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename First, typename... Args>
|
|
||||||
struct serializer_t<Context, concat_t<First, Args...>>
|
|
||||||
{
|
|
||||||
using T = concat_t<First, Args...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "(";
|
|
||||||
interpret_tuple(t._args, "||", context);
|
|
||||||
context << ")";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
242
include/sqlpp11/vendor/expression.h
vendored
242
include/sqlpp11/vendor/expression.h
vendored
@ -1,242 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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/serializer.h>
|
|
||||||
#include <sqlpp11/vendor/wrap_operand.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct binary_expression_t<Lhs, op::equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>,
|
|
||||||
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
|
||||||
using _recursive_traits = make_recursive_traits<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;
|
|
||||||
maybe_tvin_t<Rhs> _rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Lhs, typename Rhs>
|
|
||||||
struct serializer_t<Context, equal_to_t<Lhs, Rhs>>
|
|
||||||
{
|
|
||||||
using T = equal_to_t<Lhs, Rhs>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "(";
|
|
||||||
serialize(t._lhs, context);
|
|
||||||
if (t._rhs._is_trivial())
|
|
||||||
{
|
|
||||||
context << " IS NULL";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context << "=";
|
|
||||||
serialize(t._rhs, context);
|
|
||||||
}
|
|
||||||
context << ")";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>,
|
|
||||||
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
|
||||||
using _recursive_traits = make_recursive_traits<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;
|
|
||||||
maybe_tvin_t<Rhs> _rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Lhs, typename Rhs>
|
|
||||||
struct serializer_t<Context, not_equal_to_t<Lhs, Rhs>>
|
|
||||||
{
|
|
||||||
using T = not_equal_to_t<Lhs, Rhs>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "(";
|
|
||||||
serialize(t._lhs, context);
|
|
||||||
if (t._rhs._is_trivial())
|
|
||||||
{
|
|
||||||
context << " IS NOT NULL";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
context << "!=";
|
|
||||||
serialize(t._rhs, context);
|
|
||||||
}
|
|
||||||
context << ")";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Rhs>
|
|
||||||
struct unary_expression_t<op::logical_not, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<unary_expression_t<op::logical_not, Rhs>>,
|
|
||||||
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
|
||||||
|
|
||||||
unary_expression_t(Rhs rhs):
|
|
||||||
_rhs(rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
unary_expression_t(const unary_expression_t&) = default;
|
|
||||||
unary_expression_t(unary_expression_t&&) = default;
|
|
||||||
unary_expression_t& operator=(const unary_expression_t&) = default;
|
|
||||||
unary_expression_t& operator=(unary_expression_t&&) = default;
|
|
||||||
~unary_expression_t() = default;
|
|
||||||
|
|
||||||
Rhs _rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Rhs>
|
|
||||||
struct serializer_t<Context, logical_not_t<Rhs>>
|
|
||||||
{
|
|
||||||
using T = logical_not_t<Rhs>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "(";
|
|
||||||
context << "NOT ";
|
|
||||||
serialize(t._lhs, context);
|
|
||||||
context << ")";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename O, typename Rhs>
|
|
||||||
struct binary_expression_t: public value_type_of<O>::template expression_operators<binary_expression_t<Lhs, O, Rhs>>,
|
|
||||||
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
|
||||||
using _recursive_traits = make_recursive_traits<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 serializer_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
|
||||||
{
|
|
||||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "(";
|
|
||||||
serialize(t._lhs, context);
|
|
||||||
context << O::_name;
|
|
||||||
serialize(t._rhs, context);
|
|
||||||
context << ")";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename O, typename Rhs>
|
|
||||||
struct unary_expression_t: public value_type_of<O>::template expression_operators<unary_expression_t<O, Rhs>>,
|
|
||||||
public alias_operators<unary_expression_t<O, Rhs>>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
|
||||||
|
|
||||||
unary_expression_t(Rhs rhs):
|
|
||||||
_rhs(rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
unary_expression_t(const unary_expression_t&) = default;
|
|
||||||
unary_expression_t(unary_expression_t&&) = default;
|
|
||||||
unary_expression_t& operator=(const unary_expression_t&) = default;
|
|
||||||
unary_expression_t& operator=(unary_expression_t&&) = default;
|
|
||||||
~unary_expression_t() = default;
|
|
||||||
|
|
||||||
Rhs _rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename O, typename Rhs>
|
|
||||||
struct serializer_t<Context, unary_expression_t<O, Rhs>>
|
|
||||||
{
|
|
||||||
using T = unary_expression_t<O, Rhs>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << "(";
|
|
||||||
context << O::_name;
|
|
||||||
serialize(t._rhs, context);
|
|
||||||
context << ")";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
199
include/sqlpp11/vendor/expression_fwd.h
vendored
199
include/sqlpp11/vendor/expression_fwd.h
vendored
@ -1,199 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_FWD_H
|
|
||||||
#define SQLPP_EXPRESSION_FWD_H
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
struct boolean;
|
|
||||||
struct integral;
|
|
||||||
struct floating_point;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
namespace op
|
|
||||||
{
|
|
||||||
struct less
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
static constexpr const char* _name = "<";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct less_equal
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
static constexpr const char* _name = "<=";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct equal_to
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct not_equal_to
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct greater_equal
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
static constexpr const char* _name = ">=";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct greater
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
static constexpr const char* _name = ">";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct logical_or
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
static constexpr const char* _name = " OR ";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct logical_and
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
static constexpr const char* _name = " AND ";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct logical_not
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::boolean>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ValueType>
|
|
||||||
struct plus
|
|
||||||
{
|
|
||||||
using _traits = make_traits<ValueType>;
|
|
||||||
static constexpr const char* _name = "+";
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ValueType>
|
|
||||||
struct minus
|
|
||||||
{
|
|
||||||
using _traits = make_traits<ValueType>;
|
|
||||||
static constexpr const char* _name = "-";
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ValueType>
|
|
||||||
struct multiplies
|
|
||||||
{
|
|
||||||
using _traits = make_traits<ValueType>;
|
|
||||||
static constexpr const char* _name = "*";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct divides
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::floating_point>;
|
|
||||||
static constexpr const char* _name = "/";
|
|
||||||
};
|
|
||||||
|
|
||||||
struct modulus
|
|
||||||
{
|
|
||||||
using _traits = make_traits<::sqlpp::detail::integral>;
|
|
||||||
static constexpr const char* _name = "%";
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ValueType>
|
|
||||||
struct unary_minus
|
|
||||||
{
|
|
||||||
using _traits = make_traits<ValueType>;
|
|
||||||
static constexpr const char* _name = "-";
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ValueType>
|
|
||||||
struct unary_plus
|
|
||||||
{
|
|
||||||
using _traits = make_traits<ValueType>;
|
|
||||||
static constexpr const char* _name = "+";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, typename O, typename Rhs>
|
|
||||||
struct binary_expression_t;
|
|
||||||
|
|
||||||
template<typename O, typename Rhs>
|
|
||||||
struct unary_expression_t;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using less_than_t = binary_expression_t<Lhs, op::less, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using less_equal_t = binary_expression_t<Lhs, op::less_equal, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using equal_to_t = binary_expression_t<Lhs, op::equal_to, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using not_equal_to_t = binary_expression_t<Lhs, op::not_equal_to, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using greater_than_t = binary_expression_t<Lhs, op::greater, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using greater_equal_t = binary_expression_t<Lhs, op::greater_equal, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using logical_and_t = binary_expression_t<Lhs, op::logical_and, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using logical_or_t = binary_expression_t<Lhs, op::logical_or, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename ValueType, typename Rhs>
|
|
||||||
using plus_t = binary_expression_t<Lhs, op::plus<ValueType>, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename ValueType, typename Rhs>
|
|
||||||
using minus_t = binary_expression_t<Lhs, op::minus<ValueType>, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename ValueType, typename Rhs>
|
|
||||||
using multiplies_t = binary_expression_t<Lhs, op::multiplies<ValueType>, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using divides_t = binary_expression_t<Lhs, op::divides, Rhs>;
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
using modulus_t = binary_expression_t<Lhs, op::modulus, Rhs>;
|
|
||||||
|
|
||||||
template<typename Rhs>
|
|
||||||
using logical_not_t = unary_expression_t<op::logical_not, Rhs>;
|
|
||||||
|
|
||||||
template<typename ValueType, typename Rhs>
|
|
||||||
using unary_plus_t = unary_expression_t<op::unary_plus<ValueType>, Rhs>;
|
|
||||||
|
|
||||||
template<typename ValueType, typename Rhs>
|
|
||||||
using unary_minus_t = unary_expression_t<op::unary_minus<ValueType>, Rhs>;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
170
include/sqlpp11/vendor/extra_tables.h
vendored
170
include/sqlpp11/vendor/extra_tables.h
vendored
@ -1,170 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_EXTRA_TABLES_H
|
|
||||||
#define SQLPP_EXTRA_TABLES_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename... Tables>
|
|
||||||
struct extra_tables_data_t
|
|
||||||
{
|
|
||||||
extra_tables_data_t()
|
|
||||||
{}
|
|
||||||
|
|
||||||
extra_tables_data_t(const extra_tables_data_t&) = default;
|
|
||||||
extra_tables_data_t(extra_tables_data_t&&) = default;
|
|
||||||
extra_tables_data_t& operator=(const extra_tables_data_t&) = default;
|
|
||||||
extra_tables_data_t& operator=(extra_tables_data_t&&) = default;
|
|
||||||
~extra_tables_data_t() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// EXTRA_TABLES
|
|
||||||
template<typename... Tables>
|
|
||||||
struct extra_tables_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::extra_tables>;
|
|
||||||
struct _recursive_traits
|
|
||||||
{
|
|
||||||
using _parameters = std::tuple<>;
|
|
||||||
using _required_tables = ::sqlpp::detail::type_set<>;
|
|
||||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
|
||||||
using _extra_tables = ::sqlpp::detail::type_set<Tables...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
|
||||||
|
|
||||||
// FIXME: extra_tables must not require tables!
|
|
||||||
|
|
||||||
static_assert(sizeof...(Tables), "at least one table or join argument required in extra_tables()");
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = extra_tables_data_t<Tables...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = extra_tables_data_t<Tables...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> extra_tables;
|
|
||||||
_impl_t<Policies>& operator()() { return extra_tables; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.extra_tables)
|
|
||||||
{
|
|
||||||
return t.extra_tables;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO EXTRA TABLES YET
|
|
||||||
struct no_extra_tables_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_extra_tables;
|
|
||||||
_impl_t<Policies>& operator()() { return no_extra_tables; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_extra_tables; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_extra_tables)
|
|
||||||
{
|
|
||||||
return t.no_extra_tables;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_extra_tables_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto extra_tables(Args...)
|
|
||||||
-> _new_statement_t<extra_tables_t<Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_data_t<Args...>{} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Tables>
|
|
||||||
struct serializer_t<Context, extra_tables_data_t<Database, Tables...>>
|
|
||||||
{
|
|
||||||
using T = extra_tables_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
212
include/sqlpp11/vendor/from.h
vendored
212
include/sqlpp11/vendor/from.h
vendored
@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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 <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// FROM DATA
|
|
||||||
template<typename Database, typename... Tables>
|
|
||||||
struct from_data_t
|
|
||||||
{
|
|
||||||
from_data_t(Tables... tables):
|
|
||||||
_tables(tables...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
from_data_t(const from_data_t&) = default;
|
|
||||||
from_data_t(from_data_t&&) = default;
|
|
||||||
from_data_t& operator=(const from_data_t&) = default;
|
|
||||||
from_data_t& operator=(from_data_t&&) = default;
|
|
||||||
~from_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Tables...> _tables;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
|
||||||
};
|
|
||||||
|
|
||||||
// FROM
|
|
||||||
template<typename Database, typename... Tables>
|
|
||||||
struct from_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::from>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table or join argument required in from()");
|
|
||||||
|
|
||||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in from()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in from()");
|
|
||||||
|
|
||||||
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = from_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Table>
|
|
||||||
void add(Table table)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
|
||||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
|
||||||
#warning need to check if table is already known
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
|
||||||
|
|
||||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Table>
|
|
||||||
void _add_impl(Table table, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_tables.emplace_back(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Table>
|
|
||||||
void _add_impl(Table table, const std::false_type&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = from_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> from;
|
|
||||||
_impl_t<Policies>& operator()() { return from; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return from; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.from)
|
|
||||||
{
|
|
||||||
return t.from;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct no_from_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_from;
|
|
||||||
_impl_t<Policies>& operator()() { return no_from; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_from)
|
|
||||||
{
|
|
||||||
return t.no_from;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_from_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto from(Args... args)
|
|
||||||
-> _new_statement_t<from_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_from(Args... args)
|
|
||||||
-> _new_statement_t<from_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Tables>
|
|
||||||
struct serializer_t<Context, from_data_t<Database, Tables...>>
|
|
||||||
{
|
|
||||||
using T = from_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
|
||||||
return context;
|
|
||||||
context << " FROM ";
|
|
||||||
interpret_tuple(t._tables, ',', context);
|
|
||||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
|
||||||
context << ',';
|
|
||||||
interpret_list(t._dynamic_tables, ',', context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
214
include/sqlpp11/vendor/group_by.h
vendored
214
include/sqlpp11/vendor/group_by.h
vendored
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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/vendor/policy_update.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// GROUP BY DATA
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct group_by_data_t
|
|
||||||
{
|
|
||||||
group_by_data_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
group_by_data_t(const group_by_data_t&) = default;
|
|
||||||
group_by_data_t(group_by_data_t&&) = default;
|
|
||||||
group_by_data_t& operator=(const group_by_data_t&) = default;
|
|
||||||
group_by_data_t& operator=(group_by_data_t&&) = default;
|
|
||||||
~group_by_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
|
||||||
|
|
||||||
// GROUP BY
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct group_by_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in group_by()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Expression>
|
|
||||||
void add_ntc(Expression expression)
|
|
||||||
{
|
|
||||||
add<Expression, std::false_type>(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Expression expression)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
|
||||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
|
||||||
|
|
||||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_expressions.emplace_back(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::false_type&);
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> group_by;
|
|
||||||
_impl_t<Policies>& operator()() { return group_by; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return group_by; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.group_by)
|
|
||||||
{
|
|
||||||
return t.group_by;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO GROUP BY YET
|
|
||||||
struct no_group_by_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_group_by;
|
|
||||||
_impl_t<Policies>& operator()() { return no_group_by; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_group_by; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_group_by)
|
|
||||||
{
|
|
||||||
return t.no_group_by;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_group_by_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto group_by(Args... args)
|
|
||||||
-> _new_statement_t<group_by_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_group_by(Args... args)
|
|
||||||
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
|
||||||
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
|
||||||
{
|
|
||||||
using T = group_by_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
|
||||||
return context;
|
|
||||||
context << " GROUP BY ";
|
|
||||||
interpret_tuple(t._expressions, ',', context);
|
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
|
||||||
context << ',';
|
|
||||||
interpret_list(t._dynamic_expressions, ',', context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
212
include/sqlpp11/vendor/having.h
vendored
212
include/sqlpp11/vendor/having.h
vendored
@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_HAVING_H
|
|
||||||
#define SQLPP_HAVING_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/expression.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// HAVING DATA
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct having_data_t
|
|
||||||
{
|
|
||||||
having_data_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
having_data_t(const having_data_t&) = default;
|
|
||||||
having_data_t(having_data_t&&) = default;
|
|
||||||
having_data_t& operator=(const having_data_t&) = default;
|
|
||||||
having_data_t& operator=(having_data_t&&) = default;
|
|
||||||
~having_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
|
||||||
|
|
||||||
// HAVING
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct having_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::having>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = having_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Expression>
|
|
||||||
void add_ntc(Expression expression)
|
|
||||||
{
|
|
||||||
add<Expression, std::false_type>(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Expression expression)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
|
||||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
|
||||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
|
||||||
|
|
||||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_expressions.emplace_back(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::false_type&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = having_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> having;
|
|
||||||
_impl_t<Policies>& operator()() { return having; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return having; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.having)
|
|
||||||
{
|
|
||||||
return t.having;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO HAVING YET
|
|
||||||
struct no_having_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_having;
|
|
||||||
_impl_t<Policies>& operator()() { return no_having; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_having; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_having)
|
|
||||||
{
|
|
||||||
return t.no_having;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_having_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto having(Args... args)
|
|
||||||
-> _new_statement_t<having_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_having(Args... args)
|
|
||||||
-> _new_statement_t<having_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
|
||||||
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
|
||||||
{
|
|
||||||
using T = having_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
|
||||||
return context;
|
|
||||||
context << " HAVING ";
|
|
||||||
interpret_tuple(t._expressions, " AND ", context);
|
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
|
||||||
context << " AND ";
|
|
||||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
124
include/sqlpp11/vendor/insert_value.h
vendored
124
include/sqlpp11/vendor/insert_value.h
vendored
@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_VALUE_H
|
|
||||||
#define SQLPP_INSERT_VALUE_H
|
|
||||||
|
|
||||||
#include <sqlpp11/default_value.h>
|
|
||||||
#include <sqlpp11/null.h>
|
|
||||||
#include <sqlpp11/tvin.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename Type, bool>
|
|
||||||
struct type_if
|
|
||||||
{
|
|
||||||
using type = Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
struct type_if<Type, false>
|
|
||||||
{
|
|
||||||
struct type
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Column>
|
|
||||||
struct insert_value_t
|
|
||||||
{
|
|
||||||
using _is_insert_value = std::true_type;
|
|
||||||
using _pure_value_t = typename value_type_of<Column>::_cpp_value_type;
|
|
||||||
using _wrapped_value_t = typename wrap_operand<_pure_value_t>::type;
|
|
||||||
using _tvin_t = typename detail::type_if<tvin_t<_wrapped_value_t>, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
|
||||||
using _null_t = typename detail::type_if<null_t, can_be_null_t<Column>::value>::type; // static asserts and SFINAE do not work together
|
|
||||||
|
|
||||||
insert_value_t(assignment_t<Column, _wrapped_value_t> assignment):
|
|
||||||
_is_null(false),
|
|
||||||
_is_default(false),
|
|
||||||
_value(assignment._rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
insert_value_t(assignment_t<Column, _tvin_t> assignment):
|
|
||||||
_is_null(assignment._rhs._is_trivial()),
|
|
||||||
_is_default(false),
|
|
||||||
_value(assignment._rhs._value)
|
|
||||||
{}
|
|
||||||
|
|
||||||
insert_value_t(const assignment_t<Column, _null_t>&):
|
|
||||||
_is_null(true),
|
|
||||||
_is_default(false),
|
|
||||||
_value()
|
|
||||||
{}
|
|
||||||
|
|
||||||
insert_value_t(const assignment_t<Column, ::sqlpp::default_value_t>&):
|
|
||||||
_is_null(false),
|
|
||||||
_is_default(true),
|
|
||||||
_value()
|
|
||||||
{}
|
|
||||||
|
|
||||||
insert_value_t(const insert_value_t&) = default;
|
|
||||||
insert_value_t(insert_value_t&&) = default;
|
|
||||||
insert_value_t& operator=(const insert_value_t&) = default;
|
|
||||||
insert_value_t& operator=(insert_value_t&&) = default;
|
|
||||||
~insert_value_t() = default;
|
|
||||||
|
|
||||||
bool _is_null;
|
|
||||||
bool _is_default;
|
|
||||||
_wrapped_value_t _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename ValueType>
|
|
||||||
struct serializer_t<Context, insert_value_t<ValueType>>
|
|
||||||
{
|
|
||||||
using T = insert_value_t<ValueType>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (t._is_null)
|
|
||||||
context << "NULL";
|
|
||||||
else if (t._is_default)
|
|
||||||
context << "DEFAULT";
|
|
||||||
else
|
|
||||||
serialize(t._value, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
453
include/sqlpp11/vendor/insert_value_list.h
vendored
453
include/sqlpp11/vendor/insert_value_list.h
vendored
@ -1,453 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_VALUE_LIST_H
|
|
||||||
#define SQLPP_INSERT_VALUE_LIST_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
#include <sqlpp11/vendor/assignment.h>
|
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/insert_value.h>
|
|
||||||
#include <sqlpp11/vendor/simple_column.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
struct insert_default_values_data_t
|
|
||||||
{};
|
|
||||||
|
|
||||||
// COLUMN AND VALUE LIST
|
|
||||||
struct insert_default_values_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = insert_default_values_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = insert_default_values_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> default_values;
|
|
||||||
_impl_t<Policies>& operator()() { return default_values; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return default_values; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.default_values)
|
|
||||||
{
|
|
||||||
return t.default_values;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Database, typename... Assignments>
|
|
||||||
struct insert_list_data_t
|
|
||||||
{
|
|
||||||
insert_list_data_t(Assignments... assignments):
|
|
||||||
_assignments(assignments...),
|
|
||||||
_columns({assignments._lhs}...),
|
|
||||||
_values(assignments._rhs...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
insert_list_data_t(const insert_list_data_t&) = default;
|
|
||||||
insert_list_data_t(insert_list_data_t&&) = default;
|
|
||||||
insert_list_data_t& operator=(const insert_list_data_t&) = default;
|
|
||||||
insert_list_data_t& operator=(insert_list_data_t&&) = default;
|
|
||||||
~insert_list_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
|
||||||
std::tuple<typename Assignments::_value_t...> _values;
|
|
||||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
|
||||||
typename vendor::interpretable_list_t<Database> _dynamic_columns;
|
|
||||||
typename vendor::interpretable_list_t<Database> _dynamic_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Database, typename... Assignments>
|
|
||||||
struct insert_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::insert_list>;
|
|
||||||
using _recursive_traits = make_recursive_traits<typename Assignments::_column_t..., typename Assignments::_value_t...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
template<template<typename...> class Target>
|
|
||||||
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
|
|
||||||
template<template<typename...> class Target, template<typename> class Wrap>
|
|
||||||
using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment required in set()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
|
||||||
|
|
||||||
static_assert(sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
|
||||||
|
|
||||||
static_assert(sqlpp::detail::none_t<must_not_insert_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
|
||||||
|
|
||||||
#warning: Need to reactivate these checks
|
|
||||||
/*
|
|
||||||
using _column_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_required_tables...>::type;
|
|
||||||
using _value_required_tables = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_required_tables...>::type;
|
|
||||||
using _provided_tables = ::sqlpp::detail::type_set<>;
|
|
||||||
using _required_tables = typename ::sqlpp::detail::make_joined_set<_column_required_tables, _value_required_tables>::type;
|
|
||||||
static_assert(sizeof...(Assignments) ? (_column_required_tables::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
|
||||||
static_assert(::sqlpp::detail::is_subset_of<_value_required_tables, _column_required_tables>::value, "set() contains values from foreign tables");
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Assignment>
|
|
||||||
void add_ntc(Assignment assignment)
|
|
||||||
{
|
|
||||||
add<Assignment, std::false_type>(assignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Assignment assignment)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
|
||||||
static_assert(is_assignment_t<Assignment>::value, "add() arguments require to be assigments");
|
|
||||||
static_assert(not must_not_insert_t<typename Assignment::_column_t>::value, "add() argument must not be used in insert");
|
|
||||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add() contains a column from a foreign table");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<
|
|
||||||
_is_dynamic::value,
|
|
||||||
is_assignment_t<Assignment>::value,
|
|
||||||
not must_not_insert_t<typename Assignment::_column_t>::value,
|
|
||||||
(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value)>;
|
|
||||||
|
|
||||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Assignment>
|
|
||||||
void _add_impl(Assignment assignment, const std::true_type&)
|
|
||||||
{
|
|
||||||
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
|
||||||
_data._dynamic_values.emplace_back(assignment._rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Assignment>
|
|
||||||
void _add_impl(Assignment assignment, const std::false_type&);
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> insert_list;
|
|
||||||
_impl_t<Policies>& operator()() { return insert_list; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return insert_list; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.insert_list)
|
|
||||||
{
|
|
||||||
return t.insert_list;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Columns>
|
|
||||||
struct column_list_data_t
|
|
||||||
{
|
|
||||||
column_list_data_t(Columns... columns):
|
|
||||||
_columns(simple_column_t<Columns>{columns}...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
column_list_data_t(const column_list_data_t&) = default;
|
|
||||||
column_list_data_t(column_list_data_t&&) = default;
|
|
||||||
column_list_data_t& operator=(const column_list_data_t&) = default;
|
|
||||||
column_list_data_t& operator=(column_list_data_t&&) = default;
|
|
||||||
~column_list_data_t() = default;
|
|
||||||
|
|
||||||
#warning need to define just one version of value_tuple_t
|
|
||||||
using _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
|
|
||||||
std::tuple<simple_column_t<Columns>...> _columns;
|
|
||||||
std::vector<_value_tuple_t> _insert_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Columns>
|
|
||||||
struct column_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::column_list>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
|
||||||
|
|
||||||
static_assert(sizeof...(Columns), "at least one column required in columns()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected in columns()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_column_t<Columns>::value...>::value, "at least one argument is not a column in columns()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::none_t<must_not_insert_t<Columns>::value...>::value, "at least one column argument has a must_not_insert flag in its definition");
|
|
||||||
|
|
||||||
using _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
|
|
||||||
|
|
||||||
static_assert(required_tables_of<column_list_t>::size::value == 1, "columns from multiple tables in columns()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = column_list_data_t<Columns...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename... Assignments>
|
|
||||||
void add(Assignments... assignments)
|
|
||||||
{
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
|
||||||
using _arg_value_tuple = std::tuple<vendor::insert_value_t<typename Assignments::_column_t>...>;
|
|
||||||
using _args_correct = std::is_same<_arg_value_tuple, _value_tuple_t>;
|
|
||||||
static_assert(_args_correct::value, "add_values() arguments do not match columns() arguments");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<
|
|
||||||
::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value,
|
|
||||||
_args_correct::value>;
|
|
||||||
|
|
||||||
_add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename... Assignments>
|
|
||||||
void _add_impl(const std::true_type&, Assignments... assignments)
|
|
||||||
{
|
|
||||||
return _data._insert_values.emplace_back(vendor::insert_value_t<typename Assignments::_column_t>{assignments}...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Assignments>
|
|
||||||
void _add_impl(const std::false_type&, Assignments... assignments);
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = column_list_data_t<Columns...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> values;
|
|
||||||
_impl_t<Policies>& operator()() { return values; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return values; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.values)
|
|
||||||
{
|
|
||||||
return t.values;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return _insert_values.empty();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO HAVING YET
|
|
||||||
struct no_insert_value_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_insert_values;
|
|
||||||
_impl_t<Policies>& operator()() { return no_insert_values; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_insert_values; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_insert_values)
|
|
||||||
{
|
|
||||||
return t.no_insert_values;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_insert_value_list_t, T>;
|
|
||||||
|
|
||||||
auto default_values()
|
|
||||||
-> _new_statement_t<insert_default_values_t>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_default_values_data_t{} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto columns(Args... args)
|
|
||||||
-> _new_statement_t<column_list_t<Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), column_list_data_t<Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto set(Args... args)
|
|
||||||
-> _new_statement_t<insert_list_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_set(Args... args)
|
|
||||||
-> _new_statement_t<insert_list_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::insert_list_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, insert_default_values_data_t>
|
|
||||||
{
|
|
||||||
using T = insert_default_values_data_t;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << " DEFAULT VALUES";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename... Columns>
|
|
||||||
struct serializer_t<Context, column_list_data_t<Columns...>>
|
|
||||||
{
|
|
||||||
using T = column_list_data_t<Columns...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << " (";
|
|
||||||
interpret_tuple(t._columns, ",", context);
|
|
||||||
context << ")";
|
|
||||||
context << " VALUES ";
|
|
||||||
bool first = true;
|
|
||||||
for (const auto& row : t._insert_values)
|
|
||||||
{
|
|
||||||
if (not first)
|
|
||||||
context << ',';
|
|
||||||
else
|
|
||||||
first = false;
|
|
||||||
context << '(';
|
|
||||||
interpret_tuple(row, ",", context);
|
|
||||||
context << ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Database, typename... Assignments>
|
|
||||||
struct serializer_t<Context, insert_list_data_t<Database, Assignments...>>
|
|
||||||
{
|
|
||||||
using T = insert_list_data_t<Database, Assignments...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
|
||||||
{
|
|
||||||
serialize(insert_default_values_data_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
|
|
131
include/sqlpp11/vendor/interpretable.h
vendored
131
include/sqlpp11/vendor/interpretable.h
vendored
@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_INTERPRETABLE_H
|
|
||||||
#define SQLPP_INTERPRETABLE_H
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <sqlpp11/serializer_context.h>
|
|
||||||
#include <sqlpp11/parameter_list.h>
|
|
||||||
#include <sqlpp11/serialize.h>
|
|
||||||
#include <sqlpp11/interpret.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Db>
|
|
||||||
struct interpretable_t
|
|
||||||
{
|
|
||||||
using _serializer_context_t = typename Db::_serializer_context_t;
|
|
||||||
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
interpretable_t(T t):
|
|
||||||
_impl(std::make_shared<_impl_t<T>>(t))
|
|
||||||
{}
|
|
||||||
|
|
||||||
interpretable_t(const interpretable_t&) = default;
|
|
||||||
interpretable_t(interpretable_t&&) = default;
|
|
||||||
interpretable_t& operator=(const interpretable_t&) = default;
|
|
||||||
interpretable_t& operator=(interpretable_t&&) = default;
|
|
||||||
~interpretable_t() = default;
|
|
||||||
|
|
||||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
|
||||||
{
|
|
||||||
return _impl->serialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
|
||||||
template<typename Context>
|
|
||||||
auto serialize(Context& context) const
|
|
||||||
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
|
||||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
|
||||||
{
|
|
||||||
return _impl->db_serialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
|
||||||
{
|
|
||||||
return _impl->interpret(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct _impl_base
|
|
||||||
{
|
|
||||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
|
||||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
|
||||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct _impl_t: public _impl_base
|
|
||||||
{
|
|
||||||
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
|
||||||
_impl_t(T t):
|
|
||||||
_t(t)
|
|
||||||
{}
|
|
||||||
|
|
||||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
|
||||||
{
|
|
||||||
sqlpp::serialize(_t, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
|
||||||
{
|
|
||||||
Db::_serialize_interpretable(_t, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
|
||||||
{
|
|
||||||
Db::_interpret_interpretable(_t, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
T _t;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<const _impl_base> _impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Database>
|
|
||||||
struct serializer_t<Context, interpretable_t<Database>>
|
|
||||||
{
|
|
||||||
using T = interpretable_t<Database>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
t.serialize(context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
198
include/sqlpp11/vendor/into.h
vendored
198
include/sqlpp11/vendor/into.h
vendored
@ -1,198 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_INTO_H
|
|
||||||
#define SQLPP_VENDOR_INTO_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/no_value.h>
|
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// A SINGLE TABLE DATA
|
|
||||||
template<typename Database, typename Table>
|
|
||||||
struct into_data_t
|
|
||||||
{
|
|
||||||
into_data_t(Table table):
|
|
||||||
_table(table)
|
|
||||||
{}
|
|
||||||
|
|
||||||
into_data_t(const into_data_t&) = default;
|
|
||||||
into_data_t(into_data_t&&) = default;
|
|
||||||
into_data_t& operator=(const into_data_t&) = default;
|
|
||||||
into_data_t& operator=(into_data_t&&) = default;
|
|
||||||
~into_data_t() = default;
|
|
||||||
|
|
||||||
Table _table;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A SINGLE TABLE
|
|
||||||
template<typename Database, typename Table>
|
|
||||||
struct into_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::into, tag::return_value>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Table>;
|
|
||||||
|
|
||||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
|
||||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
|
||||||
|
|
||||||
using _data_t = into_data_t<Database, Table>;
|
|
||||||
|
|
||||||
struct _name_t {};
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = into_data_t<Database, Table>;
|
|
||||||
|
|
||||||
_impl_t<Policies> into;
|
|
||||||
_impl_t<Policies>& operator()() { return into; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return into; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.into)
|
|
||||||
{
|
|
||||||
return t.into;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _result_methods_t
|
|
||||||
{
|
|
||||||
using _statement_t = typename Policies::_statement_t;
|
|
||||||
|
|
||||||
const _statement_t& _get_statement() const
|
|
||||||
{
|
|
||||||
return static_cast<const _statement_t&>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
|
||||||
{
|
|
||||||
_statement_t::_check_consistency();
|
|
||||||
|
|
||||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
|
||||||
return db.insert(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
template<typename Db>
|
|
||||||
auto _prepare(Db& db) const
|
|
||||||
-> prepared_insert_t<Db, insert_t>
|
|
||||||
{
|
|
||||||
_statement_t::_check_consistency();
|
|
||||||
|
|
||||||
return {{}, db.prepare_insert(*this)};
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO INTO YET
|
|
||||||
struct no_into_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_into;
|
|
||||||
_impl_t<Policies>& operator()() { return no_into; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_into; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_into)
|
|
||||||
{
|
|
||||||
return t.no_into;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_into_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto into(Args... args)
|
|
||||||
-> _new_statement_t<into_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), into_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename Table>
|
|
||||||
struct serializer_t<Context, into_data_t<Database, Table>>
|
|
||||||
{
|
|
||||||
using T = into_data_t<Database, Table>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << " INTO ";
|
|
||||||
serialize(t._table, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
260
include/sqlpp11/vendor/limit.h
vendored
260
include/sqlpp11/vendor/limit.h
vendored
@ -1,260 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_LIMIT_H
|
|
||||||
#define SQLPP_LIMIT_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// LIMIT DATA
|
|
||||||
template<typename Limit>
|
|
||||||
struct limit_data_t
|
|
||||||
{
|
|
||||||
limit_data_t(Limit value):
|
|
||||||
_value(value)
|
|
||||||
{}
|
|
||||||
|
|
||||||
limit_data_t(const limit_data_t&) = default;
|
|
||||||
limit_data_t(limit_data_t&&) = default;
|
|
||||||
limit_data_t& operator=(const limit_data_t&) = default;
|
|
||||||
limit_data_t& operator=(limit_data_t&&) = default;
|
|
||||||
~limit_data_t() = default;
|
|
||||||
|
|
||||||
Limit _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// LIMIT
|
|
||||||
template<typename Limit>
|
|
||||||
struct limit_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Limit>;
|
|
||||||
|
|
||||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = limit_data_t<Limit>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = limit_data_t<Limit>;
|
|
||||||
|
|
||||||
_impl_t<Policies> limit;
|
|
||||||
_impl_t<Policies>& operator()() { return limit; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return limit; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.limit)
|
|
||||||
{
|
|
||||||
return t.limit;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// DYNAMIC LIMIT DATA
|
|
||||||
template<typename Database>
|
|
||||||
struct dynamic_limit_data_t
|
|
||||||
{
|
|
||||||
dynamic_limit_data_t():
|
|
||||||
_value(noop())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Limit>
|
|
||||||
dynamic_limit_data_t(Limit value):
|
|
||||||
_initialized(true),
|
|
||||||
_value(typename wrap_operand<Limit>::type(value))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
|
|
||||||
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
|
|
||||||
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
|
|
||||||
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
|
|
||||||
~dynamic_limit_data_t() = default;
|
|
||||||
|
|
||||||
bool _initialized = false;
|
|
||||||
interpretable_t<Database> _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// DYNAMIC LIMIT
|
|
||||||
template<typename Database>
|
|
||||||
struct dynamic_limit_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = dynamic_limit_data_t<Database>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Limit>
|
|
||||||
void set(Limit value)
|
|
||||||
{
|
|
||||||
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
|
||||||
using arg_t = typename wrap_operand<Limit>::type;
|
|
||||||
_data._value = arg_t{value};
|
|
||||||
_data._initialized = true;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = dynamic_limit_data_t<Database>;
|
|
||||||
|
|
||||||
_impl_t<Policies> limit;
|
|
||||||
_impl_t<Policies>& operator()() { return limit; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return limit; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.limit)
|
|
||||||
{
|
|
||||||
return t.limit;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct no_limit_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_limit;
|
|
||||||
_impl_t<Policies>& operator()() { return no_limit; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_limit; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_limit)
|
|
||||||
{
|
|
||||||
return t.no_limit;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_limit_t, T>;
|
|
||||||
|
|
||||||
template<typename Arg>
|
|
||||||
auto limit(Arg arg)
|
|
||||||
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), limit_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dynamic_limit()
|
|
||||||
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_data_t<_database_t>{} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database>
|
|
||||||
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
|
||||||
{
|
|
||||||
using T = dynamic_limit_data_t<Database>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (t._initialized)
|
|
||||||
{
|
|
||||||
context << " LIMIT ";
|
|
||||||
serialize(t._value, context);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Limit>
|
|
||||||
struct serializer_t<Context, limit_data_t<Limit>>
|
|
||||||
{
|
|
||||||
using T = limit_data_t<Limit>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << " LIMIT ";
|
|
||||||
serialize(t._value, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
140
include/sqlpp11/vendor/named_interpretable.h
vendored
140
include/sqlpp11/vendor/named_interpretable.h
vendored
@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_NAMED_SERIALIZABLE_H
|
|
||||||
#define SQLPP_NAMED_SERIALIZABLE_H
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <sqlpp11/serializer_context.h>
|
|
||||||
#include <sqlpp11/parameter_list.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Db>
|
|
||||||
struct named_interpretable_t
|
|
||||||
{
|
|
||||||
using _serializer_context_t = typename Db::_serializer_context_t;
|
|
||||||
using _interpreter_context_t = typename Db::_interpreter_context_t;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
named_interpretable_t(T t):
|
|
||||||
_impl(std::make_shared<_impl_t<T>>(t))
|
|
||||||
{}
|
|
||||||
|
|
||||||
named_interpretable_t(const named_interpretable_t&) = default;
|
|
||||||
named_interpretable_t(named_interpretable_t&&) = default;
|
|
||||||
named_interpretable_t& operator=(const named_interpretable_t&) = default;
|
|
||||||
named_interpretable_t& operator=(named_interpretable_t&&) = default;
|
|
||||||
~named_interpretable_t() = default;
|
|
||||||
|
|
||||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
|
||||||
{
|
|
||||||
return _impl->serialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method only exists if Db::_serializer_context_t and sqlpp::serializer_context_t are not the same
|
|
||||||
template<typename Context>
|
|
||||||
auto serialize(Context& context) const
|
|
||||||
-> typename std::enable_if<std::is_same<Context, _serializer_context_t>::value
|
|
||||||
and not std::is_same<Context, sqlpp::serializer_context_t>::value, Context&>::type
|
|
||||||
{
|
|
||||||
return _impl->db_serialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
|
||||||
{
|
|
||||||
return _impl->interpret(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string _get_name() const
|
|
||||||
{
|
|
||||||
_impl->_get_name();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct _impl_base
|
|
||||||
{
|
|
||||||
virtual sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const = 0;
|
|
||||||
virtual _serializer_context_t& db_serialize(_serializer_context_t& context) const = 0;
|
|
||||||
virtual _interpreter_context_t& interpret(_interpreter_context_t& context) const = 0;
|
|
||||||
virtual std::string _get_name() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct _impl_t: public _impl_base
|
|
||||||
{
|
|
||||||
static_assert(not make_parameter_list_t<T>::type::size::value, "parameters not supported in dynamic statement parts");
|
|
||||||
_impl_t(T t):
|
|
||||||
_t(t)
|
|
||||||
{}
|
|
||||||
|
|
||||||
sqlpp::serializer_context_t& serialize(sqlpp::serializer_context_t& context) const
|
|
||||||
{
|
|
||||||
sqlpp::serialize(_t, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
_serializer_context_t& db_serialize(_serializer_context_t& context) const
|
|
||||||
{
|
|
||||||
Db::_serialize_interpretable(_t, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
_interpreter_context_t& interpret(_interpreter_context_t& context) const
|
|
||||||
{
|
|
||||||
Db::_interpret_interpretable(_t, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string _get_name() const
|
|
||||||
{
|
|
||||||
return T::_name_t::_get_name();
|
|
||||||
}
|
|
||||||
|
|
||||||
T _t;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<const _impl_base> _impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Database>
|
|
||||||
struct serializer_t<Context, named_interpretable_t<Database>>
|
|
||||||
{
|
|
||||||
using T = named_interpretable_t<Database>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
t.serialize(context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
270
include/sqlpp11/vendor/offset.h
vendored
270
include/sqlpp11/vendor/offset.h
vendored
@ -1,270 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_OFFSET_H
|
|
||||||
#define SQLPP_OFFSET_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// OFFSET DATA
|
|
||||||
template<typename Offset>
|
|
||||||
struct offset_data_t
|
|
||||||
{
|
|
||||||
offset_data_t(Offset value):
|
|
||||||
_value(value)
|
|
||||||
{}
|
|
||||||
|
|
||||||
offset_data_t(const offset_data_t&) = default;
|
|
||||||
offset_data_t(offset_data_t&&) = default;
|
|
||||||
offset_data_t& operator=(const offset_data_t&) = default;
|
|
||||||
offset_data_t& operator=(offset_data_t&&) = default;
|
|
||||||
~offset_data_t() = default;
|
|
||||||
|
|
||||||
Offset _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// OFFSET
|
|
||||||
template<typename Offset>
|
|
||||||
struct offset_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Offset>;
|
|
||||||
|
|
||||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = offset_data_t<Offset>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = offset_data_t<Offset>;
|
|
||||||
|
|
||||||
_impl_t<Policies> offset;
|
|
||||||
_impl_t<Policies>& operator()() { return offset; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return offset; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.offset)
|
|
||||||
{
|
|
||||||
return t.offset;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// DYNAMIC OFFSET DATA
|
|
||||||
template<typename Database>
|
|
||||||
struct dynamic_offset_data_t
|
|
||||||
{
|
|
||||||
dynamic_offset_data_t():
|
|
||||||
_value(noop())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Offset>
|
|
||||||
dynamic_offset_data_t(Offset value):
|
|
||||||
_initialized(true),
|
|
||||||
_value(typename wrap_operand<Offset>::type(value))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
|
|
||||||
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
|
|
||||||
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
|
|
||||||
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
|
|
||||||
~dynamic_offset_data_t() = default;
|
|
||||||
|
|
||||||
bool _initialized = false;
|
|
||||||
interpretable_t<Database> _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// DYNAMIC OFFSET
|
|
||||||
template<typename Database>
|
|
||||||
struct dynamic_offset_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = dynamic_offset_data_t<Database>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Offset>
|
|
||||||
void set(Offset value)
|
|
||||||
{
|
|
||||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
|
||||||
using arg_t = typename wrap_operand<Offset>::type;
|
|
||||||
_data._value = arg_t{value};
|
|
||||||
_data._initialized = true;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = dynamic_offset_data_t<Database>;
|
|
||||||
|
|
||||||
_impl_t<Policies> offset;
|
|
||||||
_impl_t<Policies>& operator()() { return offset; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return offset; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.offset)
|
|
||||||
{
|
|
||||||
return t.offset;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
template<typename Offset>
|
|
||||||
void set_offset(Offset value)
|
|
||||||
{
|
|
||||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
|
||||||
using arg_t = typename wrap_operand<Offset>::type;
|
|
||||||
static_cast<typename Policies::_statement_t*>(this)->_offset()._value = arg_t{value};
|
|
||||||
static_cast<typename Policies::_statement_t*>(this)->_offset()._initialized = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool _initialized = false;
|
|
||||||
interpretable_t<Database> _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct no_offset_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_offset;
|
|
||||||
_impl_t<Policies>& operator()() { return no_offset; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_offset; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_offset)
|
|
||||||
{
|
|
||||||
return t.no_offset;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_offset_t, T>;
|
|
||||||
|
|
||||||
template<typename Arg>
|
|
||||||
auto offset(Arg arg)
|
|
||||||
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), offset_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dynamic_offset()
|
|
||||||
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_data_t<_database_t>{} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Offset>
|
|
||||||
struct serializer_t<Context, offset_data_t<Offset>>
|
|
||||||
{
|
|
||||||
using T = offset_data_t<Offset>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
context << " OFFSET ";
|
|
||||||
serialize(t._value, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Database>
|
|
||||||
struct serializer_t<Context, dynamic_offset_data_t<Database>>
|
|
||||||
{
|
|
||||||
using T = dynamic_offset_data_t<Database>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (t._initialized)
|
|
||||||
{
|
|
||||||
context << " OFFSET ";
|
|
||||||
serialize(t._value, context);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
214
include/sqlpp11/vendor/order_by.h
vendored
214
include/sqlpp11/vendor/order_by.h
vendored
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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/type_traits.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/interpretable.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// ORDER BY DATA
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct order_by_data_t
|
|
||||||
{
|
|
||||||
order_by_data_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
order_by_data_t(const order_by_data_t&) = default;
|
|
||||||
order_by_data_t(order_by_data_t&&) = default;
|
|
||||||
order_by_data_t& operator=(const order_by_data_t&) = default;
|
|
||||||
order_by_data_t& operator=(order_by_data_t&&) = default;
|
|
||||||
~order_by_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ORDER BY
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct order_by_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Expression>
|
|
||||||
void add_ntc(Expression expression)
|
|
||||||
{
|
|
||||||
add<Expression, std::false_type>(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Expression expression)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
|
||||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
|
||||||
|
|
||||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_expressions.emplace_back(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::false_type&);
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> order_by;
|
|
||||||
_impl_t<Policies>& operator()() { return order_by; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return order_by; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.order_by)
|
|
||||||
{
|
|
||||||
return t.order_by;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO ORDER BY YET
|
|
||||||
struct no_order_by_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_order_by;
|
|
||||||
_impl_t<Policies>& operator()() { return no_order_by; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_order_by; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_order_by)
|
|
||||||
{
|
|
||||||
return t.no_order_by;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_order_by_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto order_by(Args... args)
|
|
||||||
-> _new_statement_t<order_by_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_order_by(Args... args)
|
|
||||||
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
|
||||||
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
|
||||||
{
|
|
||||||
using T = order_by_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
|
||||||
return context;
|
|
||||||
context << " ORDER BY ";
|
|
||||||
interpret_tuple(t._expressions, ',', context);
|
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
|
||||||
context << ',';
|
|
||||||
interpret_list(t._dynamic_expressions, ',', context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
407
include/sqlpp11/vendor/select_column_list.h
vendored
407
include/sqlpp11/vendor/select_column_list.h
vendored
@ -1,407 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_COLUMN_LIST_H
|
|
||||||
#define SQLPP_SELECT_COLUMN_LIST_H
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <sqlpp11/result_row.h>
|
|
||||||
#include <sqlpp11/table.h>
|
|
||||||
#include <sqlpp11/no_value.h>
|
|
||||||
#include <sqlpp11/vendor/field.h>
|
|
||||||
#include <sqlpp11/vendor/expression_fwd.h>
|
|
||||||
#include <sqlpp11/vendor/select_pseudo_table.h>
|
|
||||||
#include <sqlpp11/vendor/named_interpretable.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
#include <sqlpp11/detail/copy_tuple_args.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename... Columns>
|
|
||||||
struct select_traits
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, tag::select_column_list, tag::return_value>;
|
|
||||||
struct _name_t {};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Column>
|
|
||||||
struct select_traits<Column>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<value_type_of<Column>, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>;
|
|
||||||
using _name_t = typename Column::_name_t;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
template<typename Db>
|
|
||||||
struct dynamic_select_column_list
|
|
||||||
{
|
|
||||||
using _names_t = std::vector<std::string>;
|
|
||||||
std::vector<vendor::named_interpretable_t<Db>> _dynamic_columns;
|
|
||||||
_names_t _dynamic_expression_names;
|
|
||||||
|
|
||||||
template<typename Expr>
|
|
||||||
void emplace_back(Expr expr)
|
|
||||||
{
|
|
||||||
_dynamic_expression_names.push_back(Expr::_name_t::_get_name());
|
|
||||||
_dynamic_columns.emplace_back(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return _dynamic_columns.empty();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct dynamic_select_column_list<void>
|
|
||||||
{
|
|
||||||
struct _names_t
|
|
||||||
{
|
|
||||||
static constexpr size_t size() { return 0; }
|
|
||||||
};
|
|
||||||
_names_t _dynamic_expression_names;
|
|
||||||
|
|
||||||
static constexpr bool empty()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context, typename Db>
|
|
||||||
struct serializer_t<Context, dynamic_select_column_list<Db>>
|
|
||||||
{
|
|
||||||
using T = dynamic_select_column_list<Db>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
bool first = true;
|
|
||||||
for (const auto column : t._dynamic_columns)
|
|
||||||
{
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
context << ',';
|
|
||||||
serialize(column, context);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, dynamic_select_column_list<void>>
|
|
||||||
{
|
|
||||||
using T = dynamic_select_column_list<void>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// SELECTED COLUMNS DATA
|
|
||||||
template<typename Database, typename... Columns>
|
|
||||||
struct select_column_list_data_t
|
|
||||||
{
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
select_column_list_data_t(Columns... columns):
|
|
||||||
_columns(columns...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
select_column_list_data_t(std::tuple<Columns...> columns):
|
|
||||||
_columns(columns)
|
|
||||||
{}
|
|
||||||
|
|
||||||
select_column_list_data_t(const select_column_list_data_t&) = default;
|
|
||||||
select_column_list_data_t(select_column_list_data_t&&) = default;
|
|
||||||
select_column_list_data_t& operator=(const select_column_list_data_t&) = default;
|
|
||||||
select_column_list_data_t& operator=(select_column_list_data_t&&) = default;
|
|
||||||
~select_column_list_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Columns...> _columns;
|
|
||||||
dynamic_select_column_list<Database> _dynamic_columns;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// SELECTED COLUMNS
|
|
||||||
template<typename Database, typename... Columns>
|
|
||||||
struct select_column_list_t
|
|
||||||
{
|
|
||||||
using _traits = typename ::sqlpp::detail::select_traits<Columns...>::_traits;
|
|
||||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
|
||||||
|
|
||||||
using _name_t = typename ::sqlpp::detail::select_traits<Columns...>::_name_t;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<(is_named_expression_t<Columns>::value or is_multi_column_t<Columns>::value)...>::value, "at least one argument is not a named expression");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
|
||||||
|
|
||||||
struct _column_type {};
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename NamedExpression>
|
|
||||||
void add_ntc(NamedExpression namedExpression)
|
|
||||||
{
|
|
||||||
add<NamedExpression, std::false_type>(namedExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NamedExpression, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(NamedExpression namedExpression)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
|
|
||||||
static_assert(is_named_expression_t<NamedExpression>::value, "invalid named expression argument in selected_columns::add()");
|
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<NamedExpression>::value, "named expression uses tables unknown to this statement in selected_columns::add()");
|
|
||||||
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_name_t...>;
|
|
||||||
static_assert(not ::sqlpp::detail::is_element_of<typename NamedExpression::_name_t, column_names>::value, "a column of this name is present in the select already");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<
|
|
||||||
_is_dynamic::value,
|
|
||||||
is_named_expression_t<NamedExpression>::value
|
|
||||||
>;
|
|
||||||
|
|
||||||
_add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
//private:
|
|
||||||
template<typename NamedExpression>
|
|
||||||
void _add_impl(NamedExpression namedExpression, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_columns.emplace_back(namedExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NamedExpression>
|
|
||||||
void _add_column_impl(NamedExpression namedExpression, const std::false_type&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> selected_columns;
|
|
||||||
_impl_t<Policies>& operator()() { return selected_columns; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return selected_columns; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.selected_columns)
|
|
||||||
{
|
|
||||||
return t.selected_columns;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
// Result methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _result_methods_t
|
|
||||||
{
|
|
||||||
using _statement_t = typename Policies::_statement_t;
|
|
||||||
|
|
||||||
const _statement_t& _get_statement() const
|
|
||||||
{
|
|
||||||
return static_cast<const _statement_t&>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
|
||||||
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
|
||||||
result_row_t<Db, make_field_t<Columns>...>>::type;
|
|
||||||
|
|
||||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
|
||||||
|
|
||||||
template<typename AliasProvider>
|
|
||||||
struct _deferred_table_t
|
|
||||||
{
|
|
||||||
using table = select_pseudo_table_t<_statement_t, Columns...>;
|
|
||||||
using alias = typename table::template _alias_t<AliasProvider>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename AliasProvider>
|
|
||||||
using _table_t = typename _deferred_table_t<AliasProvider>::table;
|
|
||||||
|
|
||||||
template<typename AliasProvider>
|
|
||||||
using _alias_t = typename _deferred_table_t<AliasProvider>::alias;
|
|
||||||
|
|
||||||
template<typename AliasProvider>
|
|
||||||
_alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const
|
|
||||||
{
|
|
||||||
static_assert(Policies::_can_be_used_as_table::value, "statement cannot be used as table, e.g. due to missing tables");
|
|
||||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
const _dynamic_names_t& get_dynamic_names() const
|
|
||||||
{
|
|
||||||
return _get_statement().selected_columns._data._dynamic_columns._dynamic_expression_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t get_no_of_result_columns() const
|
|
||||||
{
|
|
||||||
return sizeof...(Columns) + get_dynamic_names().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute
|
|
||||||
template<typename Db>
|
|
||||||
auto _run(Db& db) const
|
|
||||||
-> result_t<decltype(db.select(_get_statement())), _result_row_t<Db>>
|
|
||||||
{
|
|
||||||
_statement_t::_check_consistency();
|
|
||||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
|
||||||
|
|
||||||
return {db.select(_get_statement()), get_dynamic_names()};
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
// Prepare
|
|
||||||
template<typename Db>
|
|
||||||
auto _prepare(Db& db) const
|
|
||||||
-> prepared_select_t<Db, select_t>
|
|
||||||
{
|
|
||||||
_statement_t::_check_consistency();
|
|
||||||
|
|
||||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename Database, typename... Columns>
|
|
||||||
using make_select_column_list_t =
|
|
||||||
copy_tuple_args_t<vendor::select_column_list_t, Database,
|
|
||||||
decltype(std::tuple_cat(as_tuple<Columns>::_(std::declval<Columns>())...))>;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
struct no_select_column_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop, ::sqlpp::tag::missing>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
struct _name_t {};
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_selected_columns;
|
|
||||||
_impl_t<Policies>& operator()() { return no_selected_columns; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_selected_columns; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_selected_columns)
|
|
||||||
{
|
|
||||||
return t.no_selected_columns;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_select_column_list_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto columns(Args... args)
|
|
||||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<void, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_columns(Args... args)
|
|
||||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_columns must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Columns>
|
|
||||||
struct serializer_t<Context, select_column_list_data_t<Database, Columns...>>
|
|
||||||
{
|
|
||||||
using T = select_column_list_data_t<Database, Columns...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
// check for at least one expression
|
|
||||||
static_assert(T::_is_dynamic::value or sizeof...(Columns), "at least one select expression required");
|
|
||||||
|
|
||||||
interpret_tuple(t._columns, ',', context);
|
|
||||||
if (sizeof...(Columns) and not t._dynamic_columns.empty())
|
|
||||||
context << ',';
|
|
||||||
serialize(t._dynamic_columns, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
214
include/sqlpp11/vendor/select_flag_list.h
vendored
214
include/sqlpp11/vendor/select_flag_list.h
vendored
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_SELECT_FLAG_LIST_H
|
|
||||||
#define SQLPP_VENDOR_SELECT_FLAG_LIST_H
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/select_flags.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// SELECTED FLAGS DATA
|
|
||||||
template<typename Database, typename... Flags>
|
|
||||||
struct select_flag_list_data_t
|
|
||||||
{
|
|
||||||
select_flag_list_data_t(Flags... flags):
|
|
||||||
_flags(flags...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
select_flag_list_data_t(const select_flag_list_data_t&) = default;
|
|
||||||
select_flag_list_data_t(select_flag_list_data_t&&) = default;
|
|
||||||
select_flag_list_data_t& operator=(const select_flag_list_data_t&) = default;
|
|
||||||
select_flag_list_data_t& operator=(select_flag_list_data_t&&) = default;
|
|
||||||
~select_flag_list_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Flags...> _flags;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
// SELECT FLAGS
|
|
||||||
template<typename Database, typename... Flags>
|
|
||||||
struct select_flag_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::select_flag_list>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Flags...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Flags...>::value, "at least one duplicate argument detected in select flag list");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Flag>
|
|
||||||
void add_ntc(Flag flag)
|
|
||||||
{
|
|
||||||
add<Flag, std::false_type>(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Flag, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Flag flag)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "select_flags::add() must not be called for static select flags");
|
|
||||||
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in select_flags::add()");
|
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in select_flags::add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
|
|
||||||
|
|
||||||
_add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Flag>
|
|
||||||
void _add_impl(Flag flag, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_flags.emplace_back(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Flag>
|
|
||||||
void _add_impl(Flag flag, const std::false_type&);
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> select_flags;
|
|
||||||
_impl_t<Policies>& operator()() { return select_flags; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return select_flags; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.select_flags)
|
|
||||||
{
|
|
||||||
return t.select_flags;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct no_select_flag_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_select_flags;
|
|
||||||
_impl_t<Policies>& operator()() { return no_select_flags; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_select_flags; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_select_flags)
|
|
||||||
{
|
|
||||||
return t.no_select_flags;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_select_flag_list_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto flags(Args... args)
|
|
||||||
-> _new_statement_t<select_flag_list_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_flags(Args... args)
|
|
||||||
-> _new_statement_t<select_flag_list_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Flags>
|
|
||||||
struct serializer_t<Context, select_flag_list_data_t<Database, Flags...>>
|
|
||||||
{
|
|
||||||
using T = select_flag_list_data_t<Database, Flags...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
interpret_tuple(t._flags, ' ', context);
|
|
||||||
if (sizeof...(Flags))
|
|
||||||
context << ' ';
|
|
||||||
interpret_list(t._dynamic_flags, ',', context);
|
|
||||||
if (not t._dynamic_flags.empty())
|
|
||||||
context << ' ';
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
217
include/sqlpp11/vendor/single_table.h
vendored
217
include/sqlpp11/vendor/single_table.h
vendored
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_SINGLE_TABLE_H
|
|
||||||
#define SQLPP_VENDOR_SINGLE_TABLE_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/no_value.h>
|
|
||||||
#include <sqlpp11/vendor/serializer.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// A SINGLE TABLE DATA
|
|
||||||
template<typename Database, typename Table>
|
|
||||||
struct single_table_data_t
|
|
||||||
{
|
|
||||||
single_table_data_t(Table table):
|
|
||||||
_table(table)
|
|
||||||
{}
|
|
||||||
|
|
||||||
single_table_data_t(const single_table_data_t&) = default;
|
|
||||||
single_table_data_t(single_table_data_t&&) = default;
|
|
||||||
single_table_data_t& operator=(const single_table_data_t&) = default;
|
|
||||||
single_table_data_t& operator=(single_table_data_t&&) = default;
|
|
||||||
~single_table_data_t() = default;
|
|
||||||
|
|
||||||
Table _table;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A SINGLE TABLE
|
|
||||||
template<typename Database, typename Table>
|
|
||||||
struct single_table_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table, tag::return_value>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Table>;
|
|
||||||
|
|
||||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
|
||||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
|
||||||
|
|
||||||
using _data_t = single_table_data_t<Database, Table>;
|
|
||||||
|
|
||||||
struct _name_t {};
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = single_table_data_t<Database, Table>;
|
|
||||||
|
|
||||||
_impl_t<Policies> from;
|
|
||||||
_impl_t<Policies>& operator()() { return from; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return from; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.from)
|
|
||||||
{
|
|
||||||
return t.from;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _result_methods_t
|
|
||||||
{
|
|
||||||
using _statement_t = typename Policies::_statement_t;
|
|
||||||
|
|
||||||
const _statement_t& _get_statement() const
|
|
||||||
{
|
|
||||||
return static_cast<const _statement_t&>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr size_t _get_static_no_of_parameters()
|
|
||||||
{
|
|
||||||
#warning need to fix this
|
|
||||||
return 0;
|
|
||||||
//return _parameter_list_t::size::value;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t _get_no_of_parameters() const
|
|
||||||
{
|
|
||||||
#warning need to fix this
|
|
||||||
return 0;
|
|
||||||
//return _parameter_list_t::size::value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _check_consistency() const
|
|
||||||
{
|
|
||||||
// FIXME: Read up on what is allowed/prohibited in INSERT
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
|
||||||
{
|
|
||||||
_check_consistency();
|
|
||||||
|
|
||||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
|
||||||
return db.insert(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
template<typename Db>
|
|
||||||
auto _prepare(Db& db) const
|
|
||||||
-> prepared_insert_t<Db, insert_t>
|
|
||||||
{
|
|
||||||
_check_consistency();
|
|
||||||
|
|
||||||
return {{}, db.prepare_insert(*this)};
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO INTO YET
|
|
||||||
struct no_single_table_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_from;
|
|
||||||
_impl_t<Policies>& operator()() { return no_from; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_from)
|
|
||||||
{
|
|
||||||
return t.no_from;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_single_table_t, T>;
|
|
||||||
|
|
||||||
#warning: remove can operate on several tables at once, so it should not use single_table anyway
|
|
||||||
template<typename... Args>
|
|
||||||
auto from(Args... args)
|
|
||||||
-> _new_statement_t<single_table_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), single_table_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename Table>
|
|
||||||
struct serializer_t<Context, single_table_data_t<Database, Table>>
|
|
||||||
{
|
|
||||||
using T = single_table_data_t<Database, Table>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
serialize(t._table, context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
223
include/sqlpp11/vendor/update_list.h
vendored
223
include/sqlpp11/vendor/update_list.h
vendored
@ -1,223 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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/type_set.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// UPDATE ASSIGNMENTS DATA
|
|
||||||
template<typename Database, typename... Assignments>
|
|
||||||
struct update_list_data_t
|
|
||||||
{
|
|
||||||
update_list_data_t(Assignments... assignments):
|
|
||||||
_assignments(assignments...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
update_list_data_t(const update_list_data_t&) = default;
|
|
||||||
update_list_data_t(update_list_data_t&&) = default;
|
|
||||||
update_list_data_t& operator=(const update_list_data_t&) = default;
|
|
||||||
update_list_data_t& operator=(update_list_data_t&&) = default;
|
|
||||||
~update_list_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Assignments...> _assignments;
|
|
||||||
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
|
|
||||||
};
|
|
||||||
|
|
||||||
// UPDATE ASSIGNMENTS
|
|
||||||
template<typename Database, typename... Assignments>
|
|
||||||
struct update_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::update_list>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Assignments...>;
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "at least one argument is not an assignment in set()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::none_t<must_not_update_t<typename Assignments::_column_t>::value...>::value, "at least one assignment is prohibited by its column definition in set()");
|
|
||||||
|
|
||||||
#warning reactivate tests
|
|
||||||
/*
|
|
||||||
using _column_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::_column_t::_table_set...>::type;
|
|
||||||
using _value_table_set = typename ::sqlpp::detail::make_joined_set<typename Assignments::value_type::_table_set...>::type;
|
|
||||||
using _table_set = typename ::sqlpp::detail::make_joined_set<_column_table_set, _value_table_set>::type;
|
|
||||||
static_assert(sizeof...(Assignments) ? (_column_table_set::size::value == 1) : true, "set() contains assignments for tables from several columns");
|
|
||||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Assignment>
|
|
||||||
void add_ntc(Assignment assignment)
|
|
||||||
{
|
|
||||||
add<Assignment, std::false_type>(assignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Assignment assignment)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
|
||||||
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
|
|
||||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add() argument must not be updated");
|
|
||||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<
|
|
||||||
_is_dynamic::value,
|
|
||||||
is_assignment_t<Assignment>::value,
|
|
||||||
not must_not_update_t<typename Assignment::_column_t>::value>;
|
|
||||||
|
|
||||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Assignment>
|
|
||||||
void _add_impl(Assignment assignment, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_assignments.emplace_back(assignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Assignment>
|
|
||||||
void _add_impl(Assignment assignment, const std::false_type&);
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> assignments;
|
|
||||||
_impl_t<Policies>& operator()() { return assignments; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return assignments; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.assignments)
|
|
||||||
{
|
|
||||||
return t.assignments;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct no_update_list_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_assignments;
|
|
||||||
_impl_t<Policies>& operator()() { return no_assignments; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_assignments; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_assignments)
|
|
||||||
{
|
|
||||||
return t.no_assignments;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_update_list_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto set(Args... args)
|
|
||||||
-> _new_statement_t<update_list_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_set(Args... args)
|
|
||||||
-> _new_statement_t<update_list_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::update_list_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Assignments>
|
|
||||||
struct serializer_t<Context, update_list_data_t<Database, Assignments...>>
|
|
||||||
{
|
|
||||||
using T = update_list_data_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
|
|
207
include/sqlpp11/vendor/using.h
vendored
207
include/sqlpp11/vendor/using.h
vendored
@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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/vendor/interpretable_list.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/detail/type_set.h>
|
|
||||||
#include <sqlpp11/vendor/policy_update.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// USING DATA
|
|
||||||
template<typename Database, typename... Tables>
|
|
||||||
struct using_data_t
|
|
||||||
{
|
|
||||||
using_data_t(Tables... tables):
|
|
||||||
_tables(tables...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
using_data_t(const using_data_t&) = default;
|
|
||||||
using_data_t(using_data_t&&) = default;
|
|
||||||
using_data_t& operator=(const using_data_t&) = default;
|
|
||||||
using_data_t& operator=(using_data_t&&) = default;
|
|
||||||
~using_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Tables...> _tables;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
|
||||||
};
|
|
||||||
|
|
||||||
// USING
|
|
||||||
template<typename Database, typename... Tables>
|
|
||||||
struct using_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::using_>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Tables...>;
|
|
||||||
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Tables), "at least one table argument required in using()");
|
|
||||||
|
|
||||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in using()");
|
|
||||||
|
|
||||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = using_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Table>
|
|
||||||
void add(Table table)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "add must not be called for static using()");
|
|
||||||
static_assert(is_table_t<Table>::value, "invalid table argument in add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
|
||||||
|
|
||||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Table>
|
|
||||||
void _add_impl(Table table, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_tables.emplace_back(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Table>
|
|
||||||
void _add_impl(Table table, const std::false_type&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = using_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> using_;
|
|
||||||
_impl_t<Policies>& operator()() { return using_; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return using_; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.using_)
|
|
||||||
{
|
|
||||||
return t.using_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO USING YET
|
|
||||||
struct no_using_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_using;
|
|
||||||
_impl_t<Policies>& operator()() { return no_using; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_using; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_using)
|
|
||||||
{
|
|
||||||
return t.no_using;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_using_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto using_(Args... args)
|
|
||||||
-> _new_statement_t<using_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_using(Args... args)
|
|
||||||
-> _new_statement_t<using_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Tables>
|
|
||||||
struct serializer_t<Context, using_data_t<Database, Tables...>>
|
|
||||||
{
|
|
||||||
using T = using_data_t<Database, Tables...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Tables) == 0 and t._dynamic_tables.empty())
|
|
||||||
return context;
|
|
||||||
context << " USING ";
|
|
||||||
interpret_tuple(t._tables, ',', context);
|
|
||||||
if (sizeof...(Tables) and not t._dynamic_tables.empty())
|
|
||||||
context << ',';
|
|
||||||
interpret_list(t._dynamic_tables, ',', context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
277
include/sqlpp11/vendor/where.h
vendored
277
include/sqlpp11/vendor/where.h
vendored
@ -1,277 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013-2014, 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_WHERE_H
|
|
||||||
#define SQLPP_WHERE_H
|
|
||||||
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/parameter_list.h>
|
|
||||||
#include <sqlpp11/vendor/expression.h>
|
|
||||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
|
||||||
#include <sqlpp11/vendor/interpretable_list.h>
|
|
||||||
#include <sqlpp11/detail/logic.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
|
||||||
{
|
|
||||||
namespace vendor
|
|
||||||
{
|
|
||||||
// WHERE DATA
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct where_data_t
|
|
||||||
{
|
|
||||||
where_data_t(Expressions... expressions):
|
|
||||||
_expressions(expressions...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
where_data_t(const where_data_t&) = default;
|
|
||||||
where_data_t(where_data_t&&) = default;
|
|
||||||
where_data_t& operator=(const where_data_t&) = default;
|
|
||||||
where_data_t& operator=(where_data_t&&) = default;
|
|
||||||
~where_data_t() = default;
|
|
||||||
|
|
||||||
std::tuple<Expressions...> _expressions;
|
|
||||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
|
||||||
};
|
|
||||||
|
|
||||||
// WHERE(EXPR)
|
|
||||||
template<typename Database, typename... Expressions>
|
|
||||||
struct where_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
|
||||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
|
||||||
|
|
||||||
#warning: is_dynamic should be using a template alias (making it easier to replace the logic)
|
|
||||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
|
||||||
|
|
||||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
|
|
||||||
static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
|
|
||||||
static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = where_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template <typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
template<typename Expression>
|
|
||||||
void add_ntc(Expression expression)
|
|
||||||
{
|
|
||||||
add<Expression, std::false_type>(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
|
||||||
void add(Expression expression)
|
|
||||||
{
|
|
||||||
static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where");
|
|
||||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in where::add()");
|
|
||||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in where::add()");
|
|
||||||
|
|
||||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
|
||||||
|
|
||||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::true_type&)
|
|
||||||
{
|
|
||||||
return _data._dynamic_expressions.emplace_back(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression>
|
|
||||||
void _add_impl(Expression expression, const std::false_type&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = where_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
_impl_t<Policies> where;
|
|
||||||
_impl_t<Policies>& operator()() { return where; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return where; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.where)
|
|
||||||
{
|
|
||||||
return t.where;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct where_data_t<void, bool>
|
|
||||||
{
|
|
||||||
bool _condition;
|
|
||||||
};
|
|
||||||
|
|
||||||
// WHERE(BOOL)
|
|
||||||
template<>
|
|
||||||
struct where_t<void, bool>
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = where_data_t<void, bool>;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = where_data_t<void, bool>;
|
|
||||||
|
|
||||||
_impl_t<Policies> where;
|
|
||||||
_impl_t<Policies>& operator()() { return where; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return where; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.where)
|
|
||||||
{
|
|
||||||
return t.where;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// NO WHERE YET
|
|
||||||
struct no_where_t
|
|
||||||
{
|
|
||||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
|
||||||
using _recursive_traits = make_recursive_traits<>;
|
|
||||||
|
|
||||||
// Data
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
// Member implementation with data and methods
|
|
||||||
template<typename Policies>
|
|
||||||
struct _impl_t
|
|
||||||
{
|
|
||||||
_data_t _data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Member template for adding the named member to a statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _member_t
|
|
||||||
{
|
|
||||||
using _data_t = no_data_t;
|
|
||||||
|
|
||||||
_impl_t<Policies> no_where;
|
|
||||||
_impl_t<Policies>& operator()() { return no_where; }
|
|
||||||
const _impl_t<Policies>& operator()() const { return no_where; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static auto _get_member(T t) -> decltype(t.no_where)
|
|
||||||
{
|
|
||||||
return t.no_where;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Additional methods for the statement
|
|
||||||
template<typename Policies>
|
|
||||||
struct _methods_t
|
|
||||||
{
|
|
||||||
using _database_t = typename Policies::_database_t;
|
|
||||||
template<typename T>
|
|
||||||
using _new_statement_t = typename Policies::template _new_statement_t<no_where_t, T>;
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto where(Args... args)
|
|
||||||
-> _new_statement_t<where_t<void, Args...>>
|
|
||||||
{
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<void, Args...>{args...} };
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
auto dynamic_where(Args... args)
|
|
||||||
-> _new_statement_t<where_t<_database_t, Args...>>
|
|
||||||
{
|
|
||||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
|
||||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<_database_t, Args...>{args...} };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Interpreters
|
|
||||||
template<typename Context, typename Database, typename... Expressions>
|
|
||||||
struct serializer_t<Context, where_data_t<Database, Expressions...>>
|
|
||||||
{
|
|
||||||
using T = where_data_t<Database, Expressions...>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (sizeof...(Expressions) == 0 and t._dynamic_expressions.empty())
|
|
||||||
return context;
|
|
||||||
context << " WHERE ";
|
|
||||||
interpret_tuple(t._expressions, " AND ", context);
|
|
||||||
if (sizeof...(Expressions) and not t._dynamic_expressions.empty())
|
|
||||||
context << " AND ";
|
|
||||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Context>
|
|
||||||
struct serializer_t<Context, where_data_t<void, bool>>
|
|
||||||
{
|
|
||||||
using T = where_data_t<void, bool>;
|
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
|
||||||
{
|
|
||||||
if (not t._condition)
|
|
||||||
context << " WHERE NULL";
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user