mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
Merge branch 'feature/vendor_neutrality' into develop
This commit is contained in:
commit
83afe20923
@ -30,54 +30,6 @@
|
||||
#include <sqlpp11/type_traits.h>
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace alias
|
||||
{
|
||||
#define SQLPP_ALIAS_PROVIDER_GENERATOR(name) \
|
||||
struct name##_t\
|
||||
{\
|
||||
struct _name_t\
|
||||
{\
|
||||
static constexpr const char* _get_name() { return #name; }\
|
||||
template<typename T>\
|
||||
struct _member_t\
|
||||
{\
|
||||
T name;\
|
||||
T& operator()() { return name; }\
|
||||
const T& operator()() const { return name; }\
|
||||
};\
|
||||
};\
|
||||
};\
|
||||
constexpr name##_t name = {};
|
||||
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(a);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(b);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(c);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(d);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(e);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(f);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(g);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(h);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(i);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(j);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(k);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(l);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(m);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(n);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(o);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(p);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(q);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(s);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(t);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(u);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(v);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(w);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(x);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(y);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(z);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(left);
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(right);
|
||||
};
|
||||
|
||||
template<typename Expression, typename AliasProvider>
|
||||
struct expression_alias_t
|
||||
{
|
||||
@ -90,15 +42,27 @@ namespace sqlpp
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "("; _expression.serialize(os, db); os << ") AS " << _name_t::_get_name();
|
||||
}
|
||||
|
||||
Expression _expression;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Expression, typename AliasProvider>
|
||||
struct interpreter_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||
{
|
||||
using T = expression_alias_t<Expression, AliasProvider>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << '(';
|
||||
interpret(t._expression, context);
|
||||
context << ") AS ";
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
82
include/sqlpp11/alias_provider.h
Normal file
82
include/sqlpp11/alias_provider.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_ALIAS_PROVIDER_H
|
||||
#define SQLPP_ALIAS_PROVIDER_H
|
||||
|
||||
#define SQLPP_ALIAS_PROVIDER(name) \
|
||||
struct name##_t\
|
||||
{\
|
||||
struct _name_t\
|
||||
{\
|
||||
static constexpr const char* _get_name() { return #name; }\
|
||||
template<typename T>\
|
||||
struct _member_t\
|
||||
{\
|
||||
T name;\
|
||||
T& operator()() { return name; }\
|
||||
const T& operator()() const { return name; }\
|
||||
};\
|
||||
};\
|
||||
};\
|
||||
constexpr name##_t name = {};
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace alias
|
||||
{
|
||||
SQLPP_ALIAS_PROVIDER(a);
|
||||
SQLPP_ALIAS_PROVIDER(b);
|
||||
SQLPP_ALIAS_PROVIDER(c);
|
||||
SQLPP_ALIAS_PROVIDER(d);
|
||||
SQLPP_ALIAS_PROVIDER(e);
|
||||
SQLPP_ALIAS_PROVIDER(f);
|
||||
SQLPP_ALIAS_PROVIDER(g);
|
||||
SQLPP_ALIAS_PROVIDER(h);
|
||||
SQLPP_ALIAS_PROVIDER(i);
|
||||
SQLPP_ALIAS_PROVIDER(j);
|
||||
SQLPP_ALIAS_PROVIDER(k);
|
||||
SQLPP_ALIAS_PROVIDER(l);
|
||||
SQLPP_ALIAS_PROVIDER(m);
|
||||
SQLPP_ALIAS_PROVIDER(n);
|
||||
SQLPP_ALIAS_PROVIDER(o);
|
||||
SQLPP_ALIAS_PROVIDER(p);
|
||||
SQLPP_ALIAS_PROVIDER(q);
|
||||
SQLPP_ALIAS_PROVIDER(s);
|
||||
SQLPP_ALIAS_PROVIDER(t);
|
||||
SQLPP_ALIAS_PROVIDER(u);
|
||||
SQLPP_ALIAS_PROVIDER(v);
|
||||
SQLPP_ALIAS_PROVIDER(w);
|
||||
SQLPP_ALIAS_PROVIDER(x);
|
||||
SQLPP_ALIAS_PROVIDER(y);
|
||||
SQLPP_ALIAS_PROVIDER(z);
|
||||
SQLPP_ALIAS_PROVIDER(left);
|
||||
SQLPP_ALIAS_PROVIDER(right);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Select>
|
||||
struct any_t: public boolean::template operators<any_t<Select>>
|
||||
@ -71,26 +71,33 @@ namespace sqlpp
|
||||
any_t& operator=(any_t&&) = default;
|
||||
~any_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_any, "any() not supported by current database");
|
||||
os << "ANY(";
|
||||
_select.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Select _select;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Select>
|
||||
struct interpreter_t<Context, vendor::any_t<Select>>
|
||||
{
|
||||
using T = vendor::any_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "ANY(";
|
||||
interpret(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
auto any(T&& t) -> typename detail::any_t<typename operand_t<T, is_select_t>::type>
|
||||
auto any(T&& t) -> typename vendor::any_t<typename operand_t<T, is_select_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_ASSIGNMENT_LIST_H
|
||||
#define SQLPP_ASSIGNMENT_LIST_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
|
||||
struct assignment_list_t
|
||||
{
|
||||
using _is_assignment_list = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Assignments...>;
|
||||
|
||||
// check for at least one order expression
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||
|
||||
// check for duplicate assignments
|
||||
static_assert(not detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
// check for invalid assignments
|
||||
using _assignment_set = typename detail::make_set_if<is_assignment_t, Assignments...>::type;
|
||||
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
||||
|
||||
// check for prohibited assignments
|
||||
using _prohibited_assignment_set = typename detail::make_set_if<ProhibitPredicate, typename Assignments::column_type...>::type;
|
||||
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
template<typename Assignment>
|
||||
void add(Assignment&& assignment)
|
||||
{
|
||||
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
||||
static_assert(not ProhibitPredicate<typename std::decay<Assignment>::type::column_type>::value, "set() argument must not be updated");
|
||||
_dynamic_assignments.emplace_back(std::forward<Assignment>(assignment));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << " SET ";
|
||||
detail::serialize_tuple(os, db, _assignments, ',');
|
||||
_dynamic_assignments.serialize(os, db, sizeof...(Assignments) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_assignments, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _assignments;
|
||||
typename detail::serializable_list<Database> _dynamic_assignments;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct avg_t: public floating_point::template operators<avg_t<Expr>>
|
||||
@ -70,22 +70,29 @@ namespace sqlpp
|
||||
avg_t& operator=(avg_t&&) = default;
|
||||
~avg_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_avg, "avg() not supported by current database");
|
||||
os << "AVG(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, vendor::avg_t<Expr>>
|
||||
{
|
||||
using T = vendor::avg_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "AVG(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto avg(T&& t) -> typename detail::avg_t<typename operand_t<T, is_value_t>::type>
|
||||
auto avg(T&& t) -> typename vendor::avg_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -27,11 +27,11 @@
|
||||
#ifndef SQLPP_DETAIL_BASIC_OPERATORS_H
|
||||
#define SQLPP_DETAIL_BASIC_OPERATORS_H
|
||||
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/sort_order.h>
|
||||
#include <sqlpp11/in.h>
|
||||
#include <sqlpp11/is_null.h>
|
||||
#include <sqlpp11/vendor/expression_fwd.h>
|
||||
#include <sqlpp11/vendor/in_fwd.h>
|
||||
#include <sqlpp11/vendor/is_null_fwd.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -39,84 +39,60 @@ namespace sqlpp
|
||||
namespace detail
|
||||
{
|
||||
struct boolean;
|
||||
|
||||
// operators
|
||||
struct lt_
|
||||
{
|
||||
using _value_type = boolean;
|
||||
static constexpr const char* _name = "<";
|
||||
};
|
||||
|
||||
struct le_
|
||||
{
|
||||
using _value_type = boolean;
|
||||
static constexpr const char* _name = "<=";
|
||||
};
|
||||
|
||||
struct ge_
|
||||
{
|
||||
using _value_type = boolean;
|
||||
static constexpr const char* _name = ">=";
|
||||
};
|
||||
|
||||
struct gt_
|
||||
{
|
||||
using _value_type = boolean;
|
||||
static constexpr const char* _name = ">";
|
||||
};
|
||||
}
|
||||
|
||||
// basic operators
|
||||
template<typename Base, template<typename> class Constraint>
|
||||
struct basic_operators
|
||||
{
|
||||
template<typename T>
|
||||
equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const
|
||||
vendor::equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const
|
||||
vendor::not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
template<typename T>
|
||||
binary_expression_t<Base, lt_, typename Constraint<T>::type> operator<(T&& t) const
|
||||
vendor::less_than_t<Base, typename Constraint<T>::type> operator<(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, le_, typename Constraint<T>::type> operator<=(T&& t) const
|
||||
vendor::less_equal_t<Base, typename Constraint<T>::type> operator<=(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, ge_, typename Constraint<T>::type> operator>=(T&& t) const
|
||||
vendor::greater_than_t<Base, typename Constraint<T>::type> operator>(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, gt_, typename Constraint<T>::type> operator>(T&& t) const
|
||||
vendor::greater_equal_t<Base, typename Constraint<T>::type> operator>=(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
is_null_t<true, boolean, Base> is_null() const
|
||||
vendor::is_null_t<true, Base> is_null() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_null()");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
is_null_t<false, boolean, Base> is_not_null() const
|
||||
vendor::is_null_t<false, Base> is_not_null() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_not_null()");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
@ -136,17 +112,17 @@ namespace sqlpp
|
||||
|
||||
// Hint: use value_list wrapper for containers...
|
||||
template<typename... T>
|
||||
in_t<true, boolean, Base, typename Constraint<T>::type...> in(T&&... t) const
|
||||
vendor::in_t<true, Base, typename Constraint<T>::type...> in(T&&... t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with in()");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t)... };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)}... };
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
in_t<false, boolean, Base, typename Constraint<T>::type...> not_in(T&&... t) const
|
||||
vendor::in_t<false, Base, typename Constraint<T>::type...> not_in(T&&... t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot with be used with not_in()");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t)... };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)}... };
|
||||
}
|
||||
|
||||
template<typename alias_provider>
|
||||
@ -155,10 +131,7 @@ namespace sqlpp
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot have a name");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
constexpr bool _is_trivial() const { return false; }
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
@ -28,7 +28,8 @@
|
||||
#define SQLPP_BOOLEAN_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlpp11/detail/basic_operators.h>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
|
||||
@ -37,18 +38,6 @@ namespace sqlpp
|
||||
// boolean operators
|
||||
namespace detail
|
||||
{
|
||||
struct or_
|
||||
{
|
||||
using _value_type = boolean;
|
||||
static constexpr const char* _name = "OR";
|
||||
};
|
||||
|
||||
struct and_
|
||||
{
|
||||
using _value_type = boolean;
|
||||
static constexpr const char* _name = "AND";
|
||||
};
|
||||
|
||||
// boolean value type
|
||||
struct boolean
|
||||
{
|
||||
@ -62,27 +51,20 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = boolean;
|
||||
|
||||
_parameter_t(const std::true_type&):
|
||||
_trivial_value_is_null(true),
|
||||
_parameter_t():
|
||||
_value(false),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
{}
|
||||
|
||||
_parameter_t(const std::false_type&):
|
||||
_trivial_value_is_null(false),
|
||||
_value(false),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(true)
|
||||
{}
|
||||
|
||||
_parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(false)
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
_value = value;
|
||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||
_is_null = (false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -93,14 +75,6 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == false; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
@ -120,7 +94,6 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
private:
|
||||
bool _trivial_value_is_null;
|
||||
signed char _value;
|
||||
bool _is_null;
|
||||
};
|
||||
@ -158,14 +131,6 @@ namespace sqlpp
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == false; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
@ -201,20 +166,20 @@ namespace sqlpp
|
||||
struct operators: public basic_operators<Base, _constraint>
|
||||
{
|
||||
template<typename T>
|
||||
binary_expression_t<Base, and_, typename _constraint<T>::type> operator and(T&& t) const
|
||||
vendor::logical_and_t<Base, typename _constraint<T>::type> operator and(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, or_, typename _constraint<T>::type> operator or(T&& t) const
|
||||
vendor::logical_or_t<Base, typename _constraint<T>::type> operator or(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
not_t<Base> operator not() const
|
||||
vendor::logical_not_t<Base> operator not() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be as operand for operator not");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
|
@ -27,13 +27,13 @@
|
||||
#ifndef SQLPP_COLUMN_H
|
||||
#define SQLPP_COLUMN_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/column_fwd.h>
|
||||
#include <sqlpp11/detail/wrong.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/sort_order.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/detail/wrong.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -58,16 +58,9 @@ namespace sqlpp
|
||||
column_t& operator=(column_t&&) = default;
|
||||
~column_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
static constexpr const char* _get_name()
|
||||
{
|
||||
os << Table::_name_t::_get_name() << '.' << _name_t::_get_name();
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize_name(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _name_t::_get_name();
|
||||
return _name_t::_get_name();
|
||||
}
|
||||
|
||||
template<typename alias_provider>
|
||||
@ -79,12 +72,27 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
auto operator =(T&& t) const
|
||||
-> typename std::enable_if<not std::is_same<column_t, typename std::decay<T>::type>::value,
|
||||
assignment_t<column_t, typename _value_type::template _constraint<T>::type>>::type
|
||||
vendor::assignment_t<column_t, typename _value_type::template _constraint<T>::type>>::type
|
||||
{
|
||||
return { *this, std::forward<T>(t) };
|
||||
return { *this, {std::forward<T>(t)} };
|
||||
}
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename... Args>
|
||||
struct interpreter_t<Context, column_t<Args...>>
|
||||
{
|
||||
using T = column_t<Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_table::_name_t::_get_name() << '.' << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,14 +32,14 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct count_t: public integral::template operators<count_t<Expr>>
|
||||
struct count_t: public sqlpp::detail::integral::template operators<count_t<Expr>>
|
||||
{
|
||||
static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument");
|
||||
|
||||
struct _value_type: public integral
|
||||
struct _value_type: public sqlpp::detail::integral
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
@ -70,22 +70,29 @@ namespace sqlpp
|
||||
count_t& operator=(count_t&&) = default;
|
||||
~count_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_count, "count() not supported by current database");
|
||||
os << "COUNT(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, vendor::count_t<Expr>>
|
||||
{
|
||||
using T = vendor::count_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "COUNT(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto count(T&& t) -> typename detail::count_t<typename operand_t<T, is_value_t>::type>
|
||||
auto count(T&& t) -> typename vendor::count_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_DETAIL_SERIALIZE_TUPLE_H
|
||||
#define SQLPP_DETAIL_SERIALIZE_TUPLE_H
|
||||
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<std::size_t begin, std::size_t index, std::size_t end>
|
||||
struct tuple_serializer_impl
|
||||
{
|
||||
template<typename Db, typename Tuple, typename Separator>
|
||||
static void serialize(std::ostream& os, Db& db, const Tuple& flags_and_columns, const Separator& separator)
|
||||
{
|
||||
if (index > begin)
|
||||
os << separator;
|
||||
const auto& entry = std::get<index>(flags_and_columns);
|
||||
using entry_type = typename std::tuple_element<index, Tuple>::type;
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
os << "(";
|
||||
entry.serialize(os, db);
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
os << ")";
|
||||
tuple_serializer_impl<begin, index + 1, end>::serialize(os, db, flags_and_columns, separator);
|
||||
}
|
||||
};
|
||||
template<std::size_t begin, std::size_t end>
|
||||
struct tuple_serializer_impl<begin, end, end>
|
||||
{
|
||||
template<typename Db, typename Tuple, typename Separator>
|
||||
static void serialize(std::ostream& os, Db& db, const Tuple& flags_and_columns, const Separator& separator)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Db, typename Tuple, typename Separator>
|
||||
static void serialize_tuple(std::ostream& os, Db& db, const Tuple& flags_and_columns, const Separator& separator)
|
||||
{
|
||||
tuple_serializer_impl<0, 0, std::tuple_size<Tuple>::value>::serialize(os, db, flags_and_columns, separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -27,12 +27,11 @@
|
||||
#ifndef SQLPP_EXISTS_H
|
||||
#define SQLPP_EXISTS_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/boolean.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Select>
|
||||
struct exists_t: public boolean::template operators<exists_t<Select>>
|
||||
@ -70,22 +69,30 @@ namespace sqlpp
|
||||
exists_t& operator=(exists_t&&) = default;
|
||||
~exists_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_exists, "exists() not supported by current database");
|
||||
os << "EXISTS(";
|
||||
_select.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Select _select;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Select>
|
||||
struct interpreter_t<Context, vendor::exists_t<Select>>
|
||||
{
|
||||
using T = vendor::exists_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "EXISTS(";
|
||||
interpret(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto exists(T&& t) -> typename detail::exists_t<typename operand_t<T, is_select_t>::type>
|
||||
auto exists(T&& t) -> typename vendor::exists_t<typename operand_t<T, is_select_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -1,251 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_EXPRESSION_H
|
||||
#define SQLPP_EXPRESSION_H
|
||||
|
||||
#include <sqlpp11/detail/wrap_operand.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/parameter_list.h> // FIXME: a forward for set_parameter_index would be nice here
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t
|
||||
{
|
||||
using _is_assignment = std::true_type;
|
||||
using column_type = Lhs;
|
||||
using value_type = Rhs;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_lhs, index);
|
||||
index = set_parameter_index(_rhs, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
_lhs.serialize_name(os, db);
|
||||
if (trivial_value_is_null_t<Lhs>::value and _rhs._is_trivial())
|
||||
{
|
||||
os << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "=";
|
||||
_rhs.serialize(os, db);
|
||||
}
|
||||
}
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename ValueType = detail::boolean>
|
||||
struct equal_t: public ValueType::template operators<equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_lhs, index);
|
||||
return set_parameter_index(_rhs, index);
|
||||
}
|
||||
|
||||
template<typename L, typename R>
|
||||
equal_t(L&& l, R&& r):
|
||||
_lhs(std::forward<L>(l)),
|
||||
_rhs(std::forward<R>(r))
|
||||
{}
|
||||
|
||||
equal_t(const equal_t&) = default;
|
||||
equal_t(equal_t&&) = default;
|
||||
equal_t& operator=(const equal_t&) = default;
|
||||
equal_t& operator=(equal_t&&) = default;
|
||||
~equal_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "(";
|
||||
_lhs.serialize(os, db);
|
||||
if (trivial_value_is_null_t<Lhs>::value and _rhs._is_trivial())
|
||||
{
|
||||
os << " IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "=";
|
||||
_rhs.serialize(os, db);
|
||||
}
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename ValueType = detail::boolean>
|
||||
struct not_equal_t: public ValueType::template operators<not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_lhs, index);
|
||||
return set_parameter_index(_rhs, index);
|
||||
}
|
||||
|
||||
template<typename L, typename R>
|
||||
not_equal_t(L&& l, R&& r):
|
||||
_lhs(std::forward<L>(l)),
|
||||
_rhs(std::forward<R>(r))
|
||||
{}
|
||||
|
||||
not_equal_t(const not_equal_t&) = default;
|
||||
not_equal_t(not_equal_t&&) = default;
|
||||
not_equal_t& operator=(const not_equal_t&) = default;
|
||||
not_equal_t& operator=(not_equal_t&&) = default;
|
||||
~not_equal_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "(";
|
||||
_lhs.serialize(os, db);
|
||||
if (trivial_value_is_null_t<Lhs>::value and _rhs._is_trivial())
|
||||
{
|
||||
os << " IS NOT NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "!=";
|
||||
_rhs.serialize(os, db);
|
||||
}
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename ValueType = detail::boolean>
|
||||
struct not_t: public ValueType::template operators<not_t<Lhs>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _parameter_tuple_t = std::tuple<Lhs>;
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
return set_parameter_index(_lhs, index);
|
||||
}
|
||||
|
||||
not_t(Lhs l):
|
||||
_lhs(l)
|
||||
{}
|
||||
|
||||
not_t(const not_t&) = default;
|
||||
not_t(not_t&&) = default;
|
||||
not_t& operator=(const not_t&) = default;
|
||||
not_t& operator=(not_t&&) = default;
|
||||
~not_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "(";
|
||||
if (trivial_value_is_null_t<Lhs>::value and _lhs._is_trivial())
|
||||
{
|
||||
_lhs.serialize(os, db);
|
||||
os << " IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "NOT";
|
||||
_lhs.serialize(os, db);
|
||||
}
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Lhs _lhs;
|
||||
};
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _value_type = typename O::_value_type;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_lhs, index);
|
||||
return set_parameter_index(_rhs, index);
|
||||
}
|
||||
|
||||
binary_expression_t(Lhs&& l, Rhs&& r):
|
||||
_lhs(std::move(l)),
|
||||
_rhs(std::move(r))
|
||||
{}
|
||||
|
||||
binary_expression_t(const Lhs& l, const Rhs& r):
|
||||
_lhs(l),
|
||||
_rhs(r)
|
||||
{}
|
||||
|
||||
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;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "(";
|
||||
_lhs.serialize(os, db);
|
||||
os << O::_name;
|
||||
_rhs.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -28,9 +28,8 @@
|
||||
#define SQLPP_FLOATING_POINT_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlpp11/detail/basic_operators.h>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/char_result_row.h> // FIXME: Need to update floating_point
|
||||
#include <sqlpp11/exception.h>
|
||||
|
||||
namespace sqlpp
|
||||
@ -52,27 +51,20 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = integral;
|
||||
|
||||
_parameter_t(const std::true_type&):
|
||||
_trivial_value_is_null(true),
|
||||
_parameter_t():
|
||||
_value(0),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
{}
|
||||
|
||||
_parameter_t(const std::false_type&):
|
||||
_trivial_value_is_null(false),
|
||||
_value(0),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(true)
|
||||
{}
|
||||
|
||||
_parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(false)
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
_value = value;
|
||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||
_is_null = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -83,14 +75,6 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == 0; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
@ -110,7 +94,6 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
private:
|
||||
bool _trivial_value_is_null;
|
||||
_cpp_value_type _value;
|
||||
bool _is_null;
|
||||
};
|
||||
@ -150,14 +133,6 @@ namespace sqlpp
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == 0; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
@ -186,30 +161,6 @@ namespace sqlpp
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
|
||||
struct plus_
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
|
||||
struct minus_
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
struct multiplies_
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "*";
|
||||
};
|
||||
|
||||
struct divides_
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using _constraint = operand_t<T, is_numeric_t>;
|
||||
|
||||
@ -217,31 +168,43 @@ namespace sqlpp
|
||||
struct operators: public basic_operators<Base, _constraint>
|
||||
{
|
||||
template<typename T>
|
||||
binary_expression_t<Base, plus_, typename _constraint<T>::type> operator +(T&& t) const
|
||||
vendor::plus_t<Base, floating_point, typename _constraint<T>::type> operator +(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, minus_, typename _constraint<T>::type> operator -(T&& t) const
|
||||
vendor::minus_t<Base, floating_point, typename _constraint<T>::type> operator -(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, multiplies_, typename _constraint<T>::type> operator *(T&& t) const
|
||||
vendor::multiplies_t<Base, floating_point, typename _constraint<T>::type> operator *(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
|
||||
vendor::divides_t<Base, typename _constraint<T>::type> operator /(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
vendor::unary_plus_t<floating_point, Base> operator +() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as unary operand");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
vendor::unary_minus_t<floating_point, Base> operator -() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as unary operand");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_FROM_H
|
||||
#define SQLPP_FROM_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... TableOrJoin>
|
||||
struct from_t
|
||||
{
|
||||
using _is_from = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
// ensure one argument at least
|
||||
static_assert(_is_dynamic::value or sizeof...(TableOrJoin), "at least one table or join argument required in from()");
|
||||
|
||||
// check for duplicate arguments
|
||||
static_assert(not detail::has_duplicates<TableOrJoin...>::value, "at least one duplicate argument detected in from()");
|
||||
|
||||
// check for invalid arguments
|
||||
using _valid_expressions = typename detail::make_set_if<is_table_t, TableOrJoin...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
|
||||
|
||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||
|
||||
|
||||
template<typename Table>
|
||||
void add(Table&& table)
|
||||
{
|
||||
static_assert(is_table_t<typename std::decay<Table>::type>::value, "from arguments require to be tables or joins");
|
||||
_dynamic_tables.emplace_back(std::forward<Table>(table));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (sizeof...(TableOrJoin) == 0 and _dynamic_tables.empty())
|
||||
return;
|
||||
os << " FROM ";
|
||||
detail::serialize_tuple(os, db, _tables, ',');
|
||||
_dynamic_tables.serialize(os, db, sizeof...(TableOrJoin) == 0);
|
||||
}
|
||||
|
||||
std::tuple<TableOrJoin...> _tables;
|
||||
detail::serializable_list<Database> _dynamic_tables;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -27,11 +27,11 @@
|
||||
#ifndef SQLPP_FUNCTIONS_H
|
||||
#define SQLPP_FUNCTIONS_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/parameter.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/vendor/in.h>
|
||||
#include <sqlpp11/vendor/is_null.h>
|
||||
#include <sqlpp11/exists.h>
|
||||
#include <sqlpp11/any.h>
|
||||
#include <sqlpp11/some.h>
|
||||
@ -40,7 +40,7 @@
|
||||
#include <sqlpp11/max.h>
|
||||
#include <sqlpp11/avg.h>
|
||||
#include <sqlpp11/sum.h>
|
||||
#include <sqlpp11/verbatim_table.h>
|
||||
#include <sqlpp11/verbatim_table.h> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -51,17 +51,11 @@ namespace sqlpp
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||
struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db& db) const
|
||||
{
|
||||
os << _verbatim;
|
||||
}
|
||||
|
||||
verbatim_t(const std::string& verbatim): _verbatim(verbatim) {}
|
||||
verbatim_t(std::string&& verbatim): _verbatim(std::forward<std::string>(verbatim)) {}
|
||||
verbatim_t(const verbatim_t&) = default;
|
||||
@ -73,18 +67,34 @@ namespace sqlpp
|
||||
std::string _verbatim;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename ValueType>
|
||||
struct interpreter_t<Context, verbatim_t<ValueType>>
|
||||
{
|
||||
using T = verbatim_t<ValueType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._verbatim;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ValueType, typename StringType>
|
||||
auto verbatim(StringType&& s) -> verbatim_t<ValueType>
|
||||
{
|
||||
return { std::forward<StringType>(s) };
|
||||
}
|
||||
|
||||
template<typename Expression, typename Db>
|
||||
auto flatten(const Expression& exp, const Db& db) -> verbatim_t<typename std::decay<Expression>::type::_value_type::_base_value_type>
|
||||
template<typename Expression, typename Context>
|
||||
auto flatten(const Expression& exp, const Context& context) -> verbatim_t<typename std::decay<Expression>::type::_value_type::_base_value_type>
|
||||
{
|
||||
std::ostringstream os;
|
||||
exp.serialize(os, db);
|
||||
return { os.str() };
|
||||
static_assert(not make_parameter_list_t<Expression>::type::size::value, "parameters not supported in flattened expressions");
|
||||
context.clear();
|
||||
interpret(exp, context);
|
||||
return { context.str() };
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
@ -92,25 +102,33 @@ namespace sqlpp
|
||||
{
|
||||
using _container_t = Container;
|
||||
using _value_type = typename operand_t<typename _container_t::value_type, is_value_t>::type::_value_type;
|
||||
using _iterator = decltype(std::begin(std::declval<_container_t>()));
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db& db) const
|
||||
_container_t _container;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Container>
|
||||
struct interpreter_t<Context, value_list_t<Container>>
|
||||
{
|
||||
using T = value_list_t<Container>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto& entry: _container)
|
||||
for (const auto& entry: t._container)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
os << ',';
|
||||
context << ',';
|
||||
|
||||
value(entry).serialize(os, db);
|
||||
interpret(value(entry), context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
_container_t _container;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
auto value_list(Container&& c) -> value_list_t<typename std::decay<Container>::type>
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_GROUP_BY_H
|
||||
#define SQLPP_GROUP_BY_H
|
||||
|
||||
#include <ostream>
|
||||
#include <tuple>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
struct group_by_t
|
||||
{
|
||||
using _is_group_by = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
// ensure one argument at least
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
|
||||
|
||||
// check for duplicate expressions
|
||||
static_assert(not detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
// check for invalid expressions
|
||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()");
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_table_t<typename std::decay<E>::type>::value, "from arguments require to be tables or joins");
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_group_by, "group_by() not supported by current database");
|
||||
if (sizeof...(Expr) == 0 and _dynamic_expressions.empty())
|
||||
return;
|
||||
|
||||
os << " GROUP BY ";
|
||||
detail::serialize_tuple(os, db, _expressions, ',');
|
||||
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_expressions, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
detail::serializable_list<Database> _dynamic_expressions;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_HAVING_H
|
||||
#define SQLPP_HAVING_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
struct having_t
|
||||
{
|
||||
using _is_having = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
|
||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of having expression, use where_parameter() instead of parameter() to turn off automatic conversion");
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_having()");
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_having, "having() not supported by current database");
|
||||
|
||||
if (sizeof...(Expr) == 0 and _dynamic_expressions.empty())
|
||||
return;
|
||||
os << " HAVING ";
|
||||
detail::serialize_tuple(os, db, _expressions, " AND ");
|
||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_expressions, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
detail::serializable_list<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,61 +27,63 @@
|
||||
#ifndef SQLPP_INSERT_H
|
||||
#define SQLPP_INSERT_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/insert_list.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_insert.h>
|
||||
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/insert_list.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<
|
||||
typename Database = void,
|
||||
typename Table = noop,
|
||||
typename InsertList = noop
|
||||
>
|
||||
struct insert_t;
|
||||
|
||||
template<
|
||||
typename Database,
|
||||
typename Table,
|
||||
typename InsertList
|
||||
typename Database = void,
|
||||
typename Table = vendor::noop,
|
||||
typename InsertList = vendor::noop
|
||||
>
|
||||
struct insert_t
|
||||
{
|
||||
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||
static_assert(is_noop<InsertList>::value or is_insert_list_t<InsertList>::value, "invalid 'InsertList' argument");
|
||||
static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||
static_assert(vendor::is_noop<InsertList>::value or is_insert_list_t<InsertList>::value, "invalid 'InsertList' argument");
|
||||
|
||||
template<typename AssignmentT>
|
||||
using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
|
||||
using use_default_values_t = insert_t<Database, Table, vendor::insert_default_values_t>;
|
||||
|
||||
using _parameter_tuple_t = std::tuple<Table, InsertList>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
|
||||
|
||||
template<typename... Assignment>
|
||||
auto set(Assignment&&... assignment)
|
||||
-> set_insert_list_t<insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>>
|
||||
auto default_values()
|
||||
-> use_default_values_t
|
||||
{
|
||||
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() twice");
|
||||
static_assert(std::is_same<InsertList, vendor::noop>::value, "cannot call default_values() after set() or default_values()");
|
||||
// FIXME: Need to check if all required columns are set
|
||||
return {
|
||||
_table,
|
||||
insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
||||
{},
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Assignment>
|
||||
auto set(Assignment&&... assignment)
|
||||
-> set_insert_list_t<vendor::insert_list_t<void, typename std::decay<Assignment>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<InsertList, vendor::noop>::value, "cannot call set() after set() or default_values()");
|
||||
// FIXME: Need to check if all required columns are set
|
||||
return {
|
||||
_table,
|
||||
vendor::insert_list_t<void, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... Assignment>
|
||||
auto dynamic_set(Assignment&&... assignment)
|
||||
-> set_insert_list_t<insert_list_t<Database, must_not_insert_t, typename std::decay<Assignment>::type...>>
|
||||
-> set_insert_list_t<vendor::insert_list_t<Database, typename std::decay<Assignment>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() twice");
|
||||
static_assert(std::is_same<InsertList, vendor::noop>::value, "cannot call set() after set() or default_values()");
|
||||
return {
|
||||
_table,
|
||||
insert_list_t<Database, must_not_insert_t, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
||||
vendor::insert_list_t<Database, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
||||
};
|
||||
}
|
||||
|
||||
@ -95,35 +97,12 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
const insert_t& serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "INSERT INTO ";
|
||||
_table.serialize(os, db);
|
||||
if (is_noop<InsertList>::value)
|
||||
{
|
||||
detail::serialize_empty_insert_list(os, db);
|
||||
}
|
||||
else
|
||||
{
|
||||
_insert_list.serialize(os, db);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
insert_t& serialize(std::ostream& os, Db& db)
|
||||
{
|
||||
static_cast<const insert_t*>(this)->serialize(os, db);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters()
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||
}
|
||||
@ -131,7 +110,8 @@ namespace sqlpp
|
||||
template<typename Db>
|
||||
std::size_t run(Db& db) const
|
||||
{
|
||||
constexpr bool calledSet = not is_noop<InsertList>::value;
|
||||
// FIXME: check if set or default_values() has ben called
|
||||
constexpr bool calledSet = not vendor::is_noop<InsertList>::value;
|
||||
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
||||
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
@ -139,29 +119,37 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto prepare(Db& db)
|
||||
auto prepare(Db& db) const
|
||||
-> prepared_insert_t<typename std::decay<Db>::type, insert_t>
|
||||
{
|
||||
constexpr bool calledSet = not is_noop<InsertList>::value;
|
||||
constexpr bool calledSet = not vendor::is_noop<InsertList>::value;
|
||||
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
||||
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
||||
|
||||
_set_parameter_index(0);
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_table, index);
|
||||
index = set_parameter_index(_insert_list, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
Table _table;
|
||||
InsertList _insert_list;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename Table, typename InsertList>
|
||||
struct interpreter_t<Context, insert_t<Database, Table, InsertList>>
|
||||
{
|
||||
using T = insert_t<Database, Table, InsertList>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "INSERT INTO ";
|
||||
interpret(t._table, context);
|
||||
interpret(t._insert_list, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
insert_t<void, typename std::decay<Table>::type> insert_into(Table&& table)
|
||||
{
|
||||
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_INSERT_LIST_H
|
||||
#define SQLPP_INSERT_LIST_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Db>
|
||||
void serialize_empty_insert_list(std::ostream& os, const Db& db)
|
||||
{
|
||||
|
||||
if (connector_has_empty_list_insert_t<typename std::decay<Db>::type>::value)
|
||||
os << " () VALUES()";
|
||||
else
|
||||
os << " DEFAULT VALUES";
|
||||
}
|
||||
|
||||
template<typename Column>
|
||||
struct insert_column
|
||||
{
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
_column.serialize_name(os, db);
|
||||
}
|
||||
|
||||
Column _column;
|
||||
};
|
||||
}
|
||||
template<typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
|
||||
struct insert_list_t
|
||||
{
|
||||
using _is_insert_list = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<typename Assignments::value_type...>;
|
||||
|
||||
// check for at least one order expression
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
|
||||
|
||||
// check for duplicate assignments
|
||||
static_assert(not detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
// check for invalid assignments
|
||||
using _assignment_set = typename detail::make_set_if<is_assignment_t, Assignments...>::type;
|
||||
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
||||
|
||||
// check for prohibited assignments
|
||||
using _prohibited_assignment_set = typename detail::make_set_if<ProhibitPredicate, typename Assignments::column_type...>::type;
|
||||
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
insert_list_t(Assignments... assignment):
|
||||
_columns({assignment._lhs}...),
|
||||
_values(assignment._rhs...)
|
||||
{}
|
||||
|
||||
insert_list_t(const insert_list_t&) = default;
|
||||
insert_list_t(insert_list_t&&) = default;
|
||||
insert_list_t& operator=(const insert_list_t&) = default;
|
||||
insert_list_t& operator=(insert_list_t&&) = default;
|
||||
~insert_list_t() = default;
|
||||
|
||||
template<typename Assignment>
|
||||
void add(Assignment&& assignment)
|
||||
{
|
||||
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
||||
static_assert(not ProhibitPredicate<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
|
||||
_dynamic_columns.emplace_back(detail::insert_column<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
|
||||
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (sizeof...(Assignments) + _dynamic_columns.size() == 0)
|
||||
{
|
||||
detail::serialize_empty_insert_list(os, db);
|
||||
}
|
||||
else
|
||||
{
|
||||
constexpr bool first = sizeof...(Assignments) == 0;
|
||||
|
||||
os << " (";
|
||||
detail::serialize_tuple(os, db, _columns, ',');
|
||||
_dynamic_columns.serialize(os, db, first);
|
||||
os << ") VALUES (";
|
||||
detail::serialize_tuple(os, db, _values, ',');
|
||||
_dynamic_values.serialize(os, db, first);
|
||||
os << ")";
|
||||
}
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_values, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
std::tuple<detail::insert_column<typename Assignments::column_type>...> _columns;
|
||||
_parameter_tuple_t _values;
|
||||
typename detail::serializable_list<Database> _dynamic_columns;
|
||||
typename detail::serializable_list<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -28,9 +28,10 @@
|
||||
#define SQLPP_INTEGRAL_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlpp11/detail/basic_operators.h>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
#include <sqlpp11/vendor/value_type.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -51,27 +52,20 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = integral;
|
||||
|
||||
_parameter_t(const std::true_type&):
|
||||
_trivial_value_is_null(true),
|
||||
_parameter_t():
|
||||
_value(0),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
{}
|
||||
|
||||
_parameter_t(const std::false_type&):
|
||||
_trivial_value_is_null(false),
|
||||
_value(0),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(true)
|
||||
{}
|
||||
|
||||
explicit _parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(false)
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
_value = value;
|
||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||
_is_null = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -81,14 +75,6 @@ namespace sqlpp
|
||||
_is_null = true;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == 0; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
@ -108,7 +94,6 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
private:
|
||||
bool _trivial_value_is_null;
|
||||
_cpp_value_type _value;
|
||||
bool _is_null;
|
||||
};
|
||||
@ -148,14 +133,6 @@ namespace sqlpp
|
||||
_is_valid = true;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == 0; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
if (not _is_valid)
|
||||
@ -184,33 +161,6 @@ namespace sqlpp
|
||||
_cpp_value_type _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct plus_
|
||||
{
|
||||
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct minus_
|
||||
{
|
||||
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct multiplies_
|
||||
{
|
||||
using _value_type = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
static constexpr const char* _name = "*";
|
||||
};
|
||||
|
||||
struct divides_
|
||||
{
|
||||
using _value_type = floating_point;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using _constraint = operand_t<T, is_numeric_t>;
|
||||
|
||||
@ -218,31 +168,50 @@ namespace sqlpp
|
||||
struct operators: public basic_operators<Base, _constraint>
|
||||
{
|
||||
template<typename T>
|
||||
binary_expression_t<Base, plus_<T>, typename _constraint<T>::type> operator +(T&& t) const
|
||||
vendor::plus_t<Base, vendor::value_type_t<T>, typename _constraint<T>::type> operator +(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, minus_<T>, typename _constraint<T>::type> operator -(T&& t) const
|
||||
vendor::minus_t<Base, vendor::value_type_t<T>, typename _constraint<T>::type> operator -(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, multiplies_<T>, typename _constraint<T>::type> operator *(T&& t) const
|
||||
vendor::multiplies_t<Base, vendor::value_type_t<T>, typename _constraint<T>::type> operator *(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
|
||||
vendor::divides_t<Base, typename _constraint<T>::type> operator /(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
vendor::modulus_t<Base, typename _constraint<T>::type> operator %(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
vendor::unary_plus_t<integral, Base> operator +() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as unary operand");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
vendor::unary_minus_t<integral, Base> operator -() const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as unary operand");
|
||||
return { *static_cast<const Base*>(this) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
43
include/sqlpp11/interpret.h
Normal file
43
include/sqlpp11/interpret.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_INTERPRET_H
|
||||
#define SQLPP_INTERPRET_H
|
||||
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T, typename Context>
|
||||
auto interpret(const T& t, Context& context)
|
||||
-> decltype(vendor::interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context))
|
||||
{
|
||||
return vendor::interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/on.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -73,12 +74,12 @@ namespace sqlpp
|
||||
static constexpr const char* _name = " RIGHT OUTER ";
|
||||
};
|
||||
|
||||
template<typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
||||
template<typename JoinType, typename Lhs, typename Rhs, typename On = vendor::noop>
|
||||
struct join_t
|
||||
{
|
||||
static_assert(is_table_t<Lhs>::value, "invalid lhs argument for join()");
|
||||
static_assert(is_table_t<Rhs>::value, "invalid rhs argument for join()");
|
||||
static_assert(is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
||||
static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
||||
|
||||
static_assert(Lhs::_table_set::template is_disjunct_from<typename Rhs::_table_set>::value, "joined tables must not be identical");
|
||||
|
||||
@ -92,7 +93,7 @@ namespace sqlpp
|
||||
auto on(Expr&&... expr)
|
||||
-> set_on_t<on_t<void, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(is_noop<On>::value, "cannot call on() twice for a single join()");
|
||||
static_assert(vendor::is_noop<On>::value, "cannot call on() twice for a single join()");
|
||||
return { _lhs,
|
||||
_rhs,
|
||||
{std::tuple<typename std::decay<Expr>::type...>{std::forward<Expr>(expr)...}}
|
||||
@ -102,55 +103,65 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
join_t<inner_join_t, join_t, typename std::decay<T>::type> join(T&& t)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
||||
return { *this, std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
join_t<inner_join_t, join_t, typename std::decay<T>::type> inner_join(T&& t)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
||||
return { *this, std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
join_t<outer_join_t, join_t, typename std::decay<T>::type> outer_join(T&& t)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
||||
return { *this, std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
join_t<left_outer_join_t, join_t, typename std::decay<T>::type> left_outer_join(T&& t)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
||||
return { *this, std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
join_t<right_outer_join_t, join_t, typename std::decay<T>::type> right_outer_join(T&& t)
|
||||
{
|
||||
static_assert(not is_noop<On>::value, "join type requires on()");
|
||||
static_assert(not vendor::is_noop<On>::value, "join type requires on()");
|
||||
return { *this, std::forward<T>(t) };
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
// FIXME: Need to check if db supports the join type. e.g. sqlite does not support right outer or full outer join
|
||||
static_assert(JoinType::template _is_supported<Db>::value, "join type not supported by current database");
|
||||
static_assert(not is_noop<On>::value, "joined tables require on()");
|
||||
_lhs.serialize(os, db);
|
||||
os << JoinType::_name;
|
||||
os << " JOIN ";
|
||||
_rhs.serialize(os, db);
|
||||
_on.serialize(os, db);
|
||||
}
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
On _on;
|
||||
};
|
||||
|
||||
// FIXME: Need to check if db supports the join type. e.g. sqlite does not support right outer or full outer join
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
||||
struct interpreter_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
||||
{
|
||||
using T = join_t<JoinType, Lhs, Rhs, On>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(not vendor::is_noop<On>::value, "joined tables require on()");
|
||||
interpret(t._lhs, context);
|
||||
context << JoinType::_name;
|
||||
context << " JOIN ";
|
||||
context << "(";
|
||||
interpret(t._rhs, context);
|
||||
interpret(t._on, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct max_t: public boolean::template operators<max_t<Expr>>
|
||||
@ -70,22 +70,29 @@ namespace sqlpp
|
||||
max_t& operator=(max_t&&) = default;
|
||||
~max_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_max, "max not supported by current database");
|
||||
os << "MAX(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, vendor::max_t<Expr>>
|
||||
{
|
||||
using T = vendor::max_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MAX(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto max(T&& t) -> typename detail::max_t<typename operand_t<T, is_value_t>::type>
|
||||
auto max(T&& t) -> typename vendor::max_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct min_t: public boolean::template operators<min_t<Expr>>
|
||||
@ -70,22 +70,29 @@ namespace sqlpp
|
||||
min_t& operator=(min_t&&) = default;
|
||||
~min_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_min, "min not supported by current database");
|
||||
os << "MIN(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, vendor::min_t<Expr>>
|
||||
{
|
||||
using T = vendor::min_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "MIN(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto min(T&& t) -> typename detail::min_t<typename operand_t<T, is_value_t>::type>
|
||||
auto min(T&& t) -> typename vendor::min_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -52,15 +52,24 @@ namespace sqlpp
|
||||
};
|
||||
using _is_multi_column = std::true_type;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
detail::serialize_tuple(os, db, _columns, ',');
|
||||
}
|
||||
|
||||
std::tuple<NamedExpr...> _columns;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename AliasProvider, typename... NamedExpr>
|
||||
struct interpreter_t<Context, multi_column_t<AliasProvider, NamedExpr...>>
|
||||
{
|
||||
using T = multi_column_t<AliasProvider, NamedExpr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple(t._columns, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename AliasProvider, typename... Expr>
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
// boolean value type
|
||||
struct no_value_t
|
||||
{
|
||||
template<typename T>
|
||||
|
@ -27,10 +27,9 @@
|
||||
#ifndef SQLPP_ON_H
|
||||
#define SQLPP_ON_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -51,20 +50,31 @@ namespace sqlpp
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and _dynamic_expressions.empty())
|
||||
return;
|
||||
os << " ON ";
|
||||
detail::serialize_tuple(os, db, _expressions, " AND ");
|
||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||
}
|
||||
|
||||
std::tuple<Expr...> _expressions;
|
||||
detail::serializable_list<Database> _dynamic_expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct interpreter_t<Context, on_t<Database, Expr...>>
|
||||
{
|
||||
using T = on_t<Database, Expr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ON ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_ORDER_BY_H
|
||||
#define SQLPP_ORDER_BY_H
|
||||
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database,typename... Expr>
|
||||
struct order_by_t
|
||||
{
|
||||
using _is_order_by = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
// check for at least one order expression
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
|
||||
|
||||
// check for duplicate order expressions
|
||||
static_assert(not detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
// check for invalid order expressions
|
||||
using _valid_expressions = typename detail::make_set_if<is_sort_order_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()");
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_sort_order_t<typename std::decay<E>::type>::value, "order_by arguments require to be sort-order expressions");
|
||||
_dynamic_expressions.push_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_order_by, "order by not supported by current database");
|
||||
if (sizeof...(Expr) == 0 and _dynamic_expressions.empty())
|
||||
return;
|
||||
|
||||
os << " ORDER BY ";
|
||||
detail::serialize_tuple(os, db, _expressions, ',');
|
||||
_dynamic_expressions.serialize(os, db, sizeof...(Expr) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_expressions, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
detail::serializable_list<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,58 +27,46 @@
|
||||
#ifndef SQLPP_PARAMETER_H
|
||||
#define SQLPP_PARAMETER_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename ValueType, typename NameType, typename TrivialValueIsNull>
|
||||
struct parameter_t
|
||||
template<typename ValueType, typename NameType>
|
||||
struct parameter_t: public ValueType::template operators<parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
using _is_parameter = std::true_type;
|
||||
using _is_expression_t = std::true_type;
|
||||
using _instance_t = typename NameType::_name_t::template _member_t<typename ValueType::_parameter_t>;
|
||||
using _trivial_value_is_null_t = TrivialValueIsNull;
|
||||
|
||||
static_assert(std::is_same<_trivial_value_is_null_t, std::true_type>::value or std::is_same<_trivial_value_is_null_t, std::false_type>::value, "Invalid template parameter TrivialValueIsNull");
|
||||
parameter_t()
|
||||
{}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_prepared, "prepared statements not supported by current database");
|
||||
static_assert(Db::_use_questionmark_parameter or Db::_use_positional_dollar_parameter, "no known way to serialize parameter placeholders for current database");
|
||||
if (Db::_use_questionmark_parameter)
|
||||
os << '?';
|
||||
else if (Db::_use_positional_dollar_parameter)
|
||||
os << '$' << _index + 1;
|
||||
}
|
||||
|
||||
constexpr bool _is_trivial() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
_index = index;
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
size_t _index;
|
||||
parameter_t(const parameter_t&) = default;
|
||||
parameter_t(parameter_t&&) = default;
|
||||
parameter_t& operator=(const parameter_t&) = default;
|
||||
parameter_t& operator=(parameter_t&&) = default;
|
||||
~parameter_t() = default;
|
||||
};
|
||||
|
||||
template<typename NamedExpr, typename TrivialValueIsNull = trivial_value_is_null_t<typename std::decay<NamedExpr>::type>>
|
||||
auto parameter(NamedExpr&& namedExpr)
|
||||
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, TrivialValueIsNull>
|
||||
namespace vendor
|
||||
{
|
||||
return {};
|
||||
template<typename Context, typename ValueType, typename NameType>
|
||||
struct interpreter_t<Context, parameter_t<ValueType, NameType>>
|
||||
{
|
||||
using T = parameter_t<ValueType, NameType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "?";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename NamedExpr>
|
||||
auto where_parameter(NamedExpr&& namedExpr)
|
||||
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, std::false_type>
|
||||
auto parameter(NamedExpr&& namedExpr)
|
||||
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type>
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -32,25 +32,6 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename... T>
|
||||
struct or_t;
|
||||
|
||||
template<typename T, typename... Rest>
|
||||
struct or_t<T, Rest...>
|
||||
{
|
||||
static constexpr bool value = T::value or or_t<Rest...>::value;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct or_t<>
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct parameter_list_t
|
||||
{
|
||||
@ -62,10 +43,8 @@ namespace sqlpp
|
||||
{
|
||||
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
||||
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
||||
using _contains_trivial_value_is_null_t = detail::or_t<typename Parameter::_trivial_value_is_null_t...>;
|
||||
|
||||
parameter_list_t():
|
||||
Parameter::_instance_t({typename Parameter::_trivial_value_is_null_t()})...
|
||||
parameter_list_t()
|
||||
{}
|
||||
|
||||
template<typename Target>
|
||||
@ -126,70 +105,6 @@ namespace sqlpp
|
||||
using type = parameter_list_t<typename detail::get_parameter_tuple<typename std::decay<Exp>::type>::type>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
size_t set_parameter_index(T& t, size_t index);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Exp, typename Enable = void>
|
||||
struct set_parameter_index_t
|
||||
{
|
||||
size_t operator()(Exp& e, size_t index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Exp>
|
||||
struct set_parameter_index_t<Exp, typename std::enable_if<is_parameter_t<Exp>::value, void>::type>
|
||||
{
|
||||
size_t operator()(Exp& e, size_t index)
|
||||
{
|
||||
return e._set_parameter_index(index);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Param>
|
||||
struct set_parameter_index_t<std::tuple<Param...>, void>
|
||||
{
|
||||
template<size_t> struct type{};
|
||||
|
||||
size_t operator()(std::tuple<Param...>& t, size_t index)
|
||||
{
|
||||
return impl(t, index, type<0>());
|
||||
}
|
||||
private:
|
||||
template<size_t pos>
|
||||
size_t impl(std::tuple<Param...>& t, size_t index, const type<pos>&)
|
||||
{
|
||||
index = sqlpp::set_parameter_index(std::get<pos>(t), index);
|
||||
return impl(t, index, type<pos + 1>());
|
||||
}
|
||||
|
||||
size_t impl(std::tuple<Param...>& t, size_t index, const type<sizeof...(Param)>&)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Exp>
|
||||
struct set_parameter_index_t<Exp, typename std::enable_if<not std::is_same<typename Exp::_parameter_tuple_t, void>::value, void>::type>
|
||||
{
|
||||
size_t operator()(Exp& e, size_t index)
|
||||
{
|
||||
return e._set_parameter_index(index);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
size_t set_parameter_index(T& t, size_t index)
|
||||
{
|
||||
return detail::set_parameter_index_t<T>()(t, index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -27,21 +27,20 @@
|
||||
#ifndef SQLPP_REMOVE_H
|
||||
#define SQLPP_REMOVE_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/using.h>
|
||||
#include <sqlpp11/where.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_remove.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/using.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<
|
||||
typename Database,
|
||||
typename Table,
|
||||
typename Using = noop,
|
||||
typename Where = noop
|
||||
typename Using = vendor::noop,
|
||||
typename Where = vendor::noop
|
||||
>
|
||||
struct remove_t;
|
||||
|
||||
@ -53,9 +52,12 @@ namespace sqlpp
|
||||
>
|
||||
struct remove_t
|
||||
{
|
||||
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||
static_assert(is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument");
|
||||
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
||||
static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||
static_assert(vendor::is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument");
|
||||
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
||||
|
||||
|
||||
// FIXME: We might want to have everywhere() or all() to indicate that everything is to be removed, same with update and select
|
||||
|
||||
template<typename UsingT>
|
||||
using set_using_t = remove_t<Database, Table, UsingT, Where>;
|
||||
@ -67,10 +69,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Tab>
|
||||
auto using_(Tab&&... tab)
|
||||
-> set_using_t<using_t<void, typename std::decay<Tab>::type...>>
|
||||
-> set_using_t<vendor::using_t<void, typename std::decay<Tab>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice");
|
||||
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()");
|
||||
static_assert(vendor::is_noop<Using>::value, "cannot call using() twice");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call using() after where()");
|
||||
return {
|
||||
_table,
|
||||
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
|
||||
@ -80,10 +82,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Tab>
|
||||
auto dynamic_using_(Tab&&... tab)
|
||||
-> set_using_t<using_t<Database, typename std::decay<Tab>::type...>>
|
||||
-> set_using_t<vendor::using_t<Database, typename std::decay<Tab>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice");
|
||||
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()");
|
||||
static_assert(vendor::is_noop<Using>::value, "cannot call using() twice");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call using() after where()");
|
||||
return {
|
||||
_table,
|
||||
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
|
||||
@ -102,9 +104,9 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto where(Expr&&... expr)
|
||||
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>>
|
||||
-> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||
return {
|
||||
_table,
|
||||
_using,
|
||||
@ -114,9 +116,9 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto dynamic_where(Expr&&... expr)
|
||||
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>>
|
||||
-> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||
return {
|
||||
_table,
|
||||
_using,
|
||||
@ -134,30 +136,12 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<typename Db>
|
||||
const remove_t& serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "DELETE FROM ";
|
||||
_table.serialize(os, db);
|
||||
_using.serialize(os, db);
|
||||
_where.serialize(os, db);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
remove_t& serialize(std::ostream& os, Db& db)
|
||||
{
|
||||
static_cast<const remove_t*>(this)->serialize(os, db);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters()
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||
}
|
||||
@ -170,27 +154,35 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto prepare(Db& db)
|
||||
auto prepare(Db& db) const
|
||||
-> prepared_remove_t<typename std::decay<Db>::type, remove_t>
|
||||
{
|
||||
_set_parameter_index(0);
|
||||
return {{}, db.prepare_remove(*this)};
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_table, index);
|
||||
index = set_parameter_index(_using, index);
|
||||
index = set_parameter_index(_where, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
Table _table;
|
||||
Using _using;
|
||||
Where _where;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename Table, typename Using, typename Where>
|
||||
struct interpreter_t<Context, remove_t<Database, Table, Using, Where>>
|
||||
{
|
||||
using T = remove_t<Database, Table, Using, Where>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "DELETE FROM ";
|
||||
interpret(t._table, context);
|
||||
interpret(t._using, context);
|
||||
interpret(t._where, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
constexpr remove_t<void, typename std::decay<Table>::type> remove_from(Table&& table)
|
||||
{
|
||||
|
@ -27,10 +27,9 @@
|
||||
#ifndef SQLPP_RESULT_ROW_H
|
||||
#define SQLPP_RESULT_ROW_H
|
||||
|
||||
#include <sqlpp11/char_result_row.h>
|
||||
#include <sqlpp11/field.h>
|
||||
#include <sqlpp11/vendor/char_result_row.h>
|
||||
#include <sqlpp11/vendor/field.h>
|
||||
#include <sqlpp11/text.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
namespace sqlpp
|
||||
@ -87,7 +86,7 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
||||
struct result_row_impl<level, index, multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
||||
struct result_row_impl<level, index, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
||||
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
||||
public result_row_impl<level, index + sizeof...(Col), Rest...>
|
||||
{
|
||||
|
@ -29,20 +29,22 @@
|
||||
|
||||
#include <sqlpp11/result.h>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/select_flag_list.h>
|
||||
#include <sqlpp11/select_expression_list.h>
|
||||
#include <sqlpp11/from.h>
|
||||
#include <sqlpp11/where.h>
|
||||
#include <sqlpp11/group_by.h>
|
||||
#include <sqlpp11/having.h>
|
||||
#include <sqlpp11/order_by.h>
|
||||
#include <sqlpp11/limit.h>
|
||||
#include <sqlpp11/offset.h>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_select.h>
|
||||
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/select_flag_list.h>
|
||||
#include <sqlpp11/vendor/select_expression_list.h>
|
||||
#include <sqlpp11/vendor/from.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
#include <sqlpp11/vendor/group_by.h>
|
||||
#include <sqlpp11/vendor/having.h>
|
||||
#include <sqlpp11/vendor/order_by.h>
|
||||
#include <sqlpp11/vendor/limit.h>
|
||||
#include <sqlpp11/vendor/offset.h>
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
|
||||
#include <sqlpp11/detail/wrong.h>
|
||||
#include <sqlpp11/detail/make_flag_tuple.h>
|
||||
#include <sqlpp11/detail/make_expression_tuple.h>
|
||||
@ -79,15 +81,15 @@ namespace sqlpp
|
||||
using _Database = Database;
|
||||
using _From = From;
|
||||
|
||||
static_assert(is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
|
||||
static_assert(vendor::is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
|
||||
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
|
||||
static_assert(is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
|
||||
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
|
||||
static_assert(is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
|
||||
static_assert(is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
|
||||
static_assert(is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
|
||||
static_assert(is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
|
||||
static_assert(is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
|
||||
static_assert(vendor::is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
|
||||
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
|
||||
static_assert(vendor::is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
|
||||
static_assert(vendor::is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
|
||||
static_assert(vendor::is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
|
||||
static_assert(vendor::is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
|
||||
static_assert(vendor::is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
|
||||
|
||||
using _is_select = std::true_type;
|
||||
using _requires_braces = std::true_type;
|
||||
@ -116,7 +118,7 @@ namespace sqlpp
|
||||
|
||||
// Indicators
|
||||
using _value_type = typename std::conditional<
|
||||
is_noop<From>::value,
|
||||
vendor::is_noop<From>::value,
|
||||
no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing)
|
||||
typename ExpressionList::_value_type>::type;
|
||||
|
||||
@ -173,7 +175,7 @@ namespace sqlpp
|
||||
-> set_expression_list_t<typename ExpressionList::template _dynamic_t<Database>>
|
||||
{
|
||||
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
||||
static_assert(is_noop<From>::value, "cannot call dynamic_columns() after from()");
|
||||
static_assert(vendor::is_noop<From>::value, "cannot call dynamic_columns() after from()");
|
||||
return {
|
||||
_flags,
|
||||
{_expression_list._expressions},
|
||||
@ -200,10 +202,10 @@ namespace sqlpp
|
||||
// sqlpp functions
|
||||
template<typename... Table>
|
||||
auto from(Table&&... table)
|
||||
-> set_from_t<from_t<void, typename std::decay<Table>::type...>>
|
||||
-> set_from_t<vendor::from_t<void, typename std::decay<Table>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
||||
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||
static_assert(vendor::is_noop<From>::value, "cannot call from() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -219,11 +221,11 @@ namespace sqlpp
|
||||
|
||||
template<typename... Table>
|
||||
auto dynamic_from(Table&&... table)
|
||||
-> set_from_t<from_t<Database, typename std::decay<Table>::type...>>
|
||||
-> set_from_t<vendor::from_t<Database, typename std::decay<Table>::type...>>
|
||||
{
|
||||
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
||||
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||
static_assert(vendor::is_noop<From>::value, "cannot call from() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -240,7 +242,7 @@ namespace sqlpp
|
||||
template<typename Table>
|
||||
select_t& add_from(Table&& table)
|
||||
{
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
|
||||
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
|
||||
static_assert(is_dynamic_t<From>::value, "cannot call add_from() in a non-dynamic from");
|
||||
|
||||
_from.add(std::forward<Table>(table));
|
||||
@ -250,10 +252,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto where(Expr&&... expr)
|
||||
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>>
|
||||
-> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call where() without a from()");
|
||||
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call where() without a from()");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -269,10 +271,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto dynamic_where(Expr&&... expr)
|
||||
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>>
|
||||
-> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call dynamic_where() without a from()");
|
||||
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call dynamic_where() without a from()");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -298,10 +300,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Col>
|
||||
auto group_by(Col&&... column)
|
||||
-> set_group_by_t<group_by_t<void, typename std::decay<Col>::type...>>
|
||||
-> set_group_by_t<vendor::group_by_t<void, typename std::decay<Col>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()");
|
||||
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call group_by() without a from()");
|
||||
static_assert(vendor::is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -317,10 +319,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Col>
|
||||
auto dynamic_group_by(Col&&... column)
|
||||
-> set_group_by_t<group_by_t<Database, typename std::decay<Col>::type...>>
|
||||
-> set_group_by_t<vendor::group_by_t<Database, typename std::decay<Col>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()");
|
||||
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call group_by() without a from()");
|
||||
static_assert(vendor::is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -346,10 +348,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto having(Expr&&... expr)
|
||||
-> set_having_t<having_t<void, typename std::decay<Expr>::type...>>
|
||||
-> set_having_t<vendor::having_t<void, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
||||
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select");
|
||||
static_assert(not vendor::is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
||||
static_assert(vendor::is_noop<Having>::value, "cannot call having() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -365,10 +367,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto dynamic_having(Expr&&... expr)
|
||||
-> set_having_t<having_t<Database, typename std::decay<Expr>::type...>>
|
||||
-> set_having_t<vendor::having_t<Database, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
||||
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select");
|
||||
static_assert(not vendor::is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
||||
static_assert(vendor::is_noop<Having>::value, "cannot call having() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -394,10 +396,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... OrderExpr>
|
||||
auto order_by(OrderExpr&&... expr)
|
||||
-> set_order_by_t<order_by_t<void, typename std::decay<OrderExpr>::type...>>
|
||||
-> set_order_by_t<vendor::order_by_t<void, typename std::decay<OrderExpr>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()");
|
||||
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call order_by() without a from()");
|
||||
static_assert(vendor::is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -413,10 +415,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... OrderExpr>
|
||||
auto dynamic_order_by(OrderExpr&&... expr)
|
||||
-> set_order_by_t<order_by_t<Database, typename std::decay<OrderExpr>::type...>>
|
||||
-> set_order_by_t<vendor::order_by_t<Database, typename std::decay<OrderExpr>::type...>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()");
|
||||
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call order_by() without a from()");
|
||||
static_assert(vendor::is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -442,10 +444,10 @@ namespace sqlpp
|
||||
|
||||
template<typename Expr>
|
||||
auto limit(Expr limit)
|
||||
-> set_limit_t<limit_t<typename std::decay<Expr>::type>>
|
||||
-> set_limit_t<vendor::limit_t<typename vendor::wrap_operand<typename std::decay<Expr>::type>::type>>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
|
||||
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call limit() without a from()");
|
||||
static_assert(vendor::is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -460,10 +462,10 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
auto dynamic_limit(std::size_t limit = 0)
|
||||
->set_limit_t<dynamic_limit_t>
|
||||
->set_limit_t<vendor::dynamic_limit_t>
|
||||
{
|
||||
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
|
||||
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||
static_assert(not vendor::is_noop<From>::value, "cannot call limit() without a from()");
|
||||
static_assert(vendor::is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -488,10 +490,10 @@ namespace sqlpp
|
||||
|
||||
template<typename Expr>
|
||||
auto offset(Expr offset)
|
||||
-> set_offset_t<offset_t<typename std::decay<Expr>::type>>
|
||||
-> set_offset_t<vendor::offset_t<typename vendor::wrap_operand<typename std::decay<Expr>::type>::type>>
|
||||
{
|
||||
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||
static_assert(not vendor::is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||
static_assert(vendor::is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -506,10 +508,10 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
auto dynamic_offset(std::size_t offset = 0)
|
||||
-> set_offset_t<dynamic_offset_t>
|
||||
-> set_offset_t<vendor::dynamic_offset_t>
|
||||
{
|
||||
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||
static_assert(not vendor::is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||
static_assert(vendor::is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||
return {
|
||||
_flags,
|
||||
_expression_list,
|
||||
@ -536,7 +538,7 @@ namespace sqlpp
|
||||
struct _pseudo_table_t
|
||||
{
|
||||
using table = typename ExpressionList::template _pseudo_table_t<select_t>;
|
||||
using alias = typename table::template alias_t<AliasProvider>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
@ -546,32 +548,6 @@ namespace sqlpp
|
||||
*this).as(aliasProvider);
|
||||
}
|
||||
|
||||
// Serialize
|
||||
template<typename Db>
|
||||
const select_t& serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "SELECT ";
|
||||
|
||||
_flags.serialize(os, db);
|
||||
_expression_list.serialize(os, db);
|
||||
_from.serialize(os, db);
|
||||
_where.serialize(os, db);
|
||||
_group_by.serialize(os, db);
|
||||
_having.serialize(os, db);
|
||||
_order_by.serialize(os, db);
|
||||
_limit.serialize(os, db);
|
||||
_offset.serialize(os, db);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
select_t& serialize(std::ostream& os, Db& db)
|
||||
{
|
||||
const_cast<const select_t*>(this)->serialize(os, db);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const typename ExpressionList::_dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
return _expression_list._dynamic_expressions._dynamic_expression_names;
|
||||
@ -582,7 +558,7 @@ namespace sqlpp
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters()
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||
}
|
||||
@ -597,7 +573,7 @@ namespace sqlpp
|
||||
auto run(Db& db) const
|
||||
-> result_t<decltype(db.select(*this)), _result_row_t>
|
||||
{
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
// FIXME: Check for missing aliases (if references are used)
|
||||
@ -608,30 +584,17 @@ namespace sqlpp
|
||||
|
||||
// Prepare
|
||||
template<typename Db>
|
||||
auto prepare(Db& db)
|
||||
auto prepare(Db& db) const
|
||||
-> prepared_select_t<typename std::decay<Db>::type, select_t>
|
||||
{
|
||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||
// FIXME: Check for missing aliases (if references are used)
|
||||
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||
|
||||
_set_parameter_index(0);
|
||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_expression_list, index);
|
||||
index = set_parameter_index(_where, index);
|
||||
index = set_parameter_index(_group_by, index);
|
||||
index = set_parameter_index(_having, index);
|
||||
index = set_parameter_index(_order_by, index);
|
||||
index = set_parameter_index(_limit, index);
|
||||
index = set_parameter_index(_offset, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
Flags _flags;
|
||||
ExpressionList _expression_list;
|
||||
From _from;
|
||||
@ -643,12 +606,68 @@ namespace sqlpp
|
||||
Offset _offset;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context,
|
||||
typename Database,
|
||||
typename Flags,
|
||||
typename ExpressionList,
|
||||
typename From,
|
||||
typename Where,
|
||||
typename GroupBy,
|
||||
typename Having,
|
||||
typename OrderBy,
|
||||
typename Limit,
|
||||
typename Offset
|
||||
>
|
||||
struct interpreter_t<Context, select_t<Database,
|
||||
Flags,
|
||||
ExpressionList,
|
||||
From,
|
||||
Where,
|
||||
GroupBy,
|
||||
Having,
|
||||
OrderBy,
|
||||
Limit,
|
||||
Offset>>
|
||||
{
|
||||
using T = select_t<Database,
|
||||
Flags,
|
||||
ExpressionList,
|
||||
From,
|
||||
Where,
|
||||
GroupBy,
|
||||
Having,
|
||||
OrderBy,
|
||||
Limit,
|
||||
Offset>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SELECT ";
|
||||
|
||||
interpret(t._flags, context);
|
||||
interpret(t._expression_list, context);
|
||||
interpret(t._from, context);
|
||||
interpret(t._where, context);
|
||||
interpret(t._group_by, context);
|
||||
interpret(t._having, context);
|
||||
interpret(t._order_by, context);
|
||||
interpret(t._limit, context);
|
||||
interpret(t._offset, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// construct select flag list
|
||||
namespace detail
|
||||
{
|
||||
template<typename... Expr>
|
||||
using make_select_flag_list_t =
|
||||
select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>;
|
||||
vendor::select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>;
|
||||
}
|
||||
|
||||
// construct select expression list
|
||||
@ -656,7 +675,7 @@ namespace sqlpp
|
||||
{
|
||||
template<typename... Expr>
|
||||
using make_select_expression_list_t =
|
||||
select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
||||
vendor::select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
||||
}
|
||||
|
||||
template<typename... NamedExpr>
|
||||
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_SELECT_EXPRESSION_LIST_H
|
||||
#define SQLPP_SELECT_EXPRESSION_LIST_H
|
||||
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/expression_fwd.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/field.h>
|
||||
#include <sqlpp11/result_row.h>
|
||||
#include <sqlpp11/table_base.h>
|
||||
#include <sqlpp11/select_pseudo_table.h>
|
||||
#include <sqlpp11/detail/named_serializable.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename... Rest>
|
||||
struct get_first_argument_if_unique
|
||||
{
|
||||
using _value_type = no_value_t;
|
||||
struct _name_t {};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct get_first_argument_if_unique<T>
|
||||
{
|
||||
using _value_type = typename T::_value_type;
|
||||
using _name_t = typename T::_name_t;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
struct dynamic_select_expression_list
|
||||
{
|
||||
using _names_t = std::vector<std::string>;
|
||||
std::vector<detail::named_serializable_t<Db>> _dynamic_expressions;
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
template<typename Expr>
|
||||
void push_back(Expr&& expr)
|
||||
{
|
||||
_dynamic_expression_names.push_back(std::decay<Expr>::type::_name_t::_get_name());
|
||||
_dynamic_expressions.emplace_back(std::forward<Expr>(expr));
|
||||
}
|
||||
void serialize(std::ostream& os, Db& db, bool first) const
|
||||
{
|
||||
for (const auto column : _dynamic_expressions)
|
||||
{
|
||||
if (not first)
|
||||
os << ',';
|
||||
column.serialize(os, db);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct dynamic_select_expression_list<void>
|
||||
{
|
||||
struct _names_t {};
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
template<typename T>
|
||||
void push_back(const T&) {}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream&, Db&, bool) const
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename Database, typename... NamedExpr>
|
||||
struct select_expression_list_t<Database, std::tuple<NamedExpr...>>
|
||||
{
|
||||
using _is_select_expression_list = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<NamedExpr...>;
|
||||
|
||||
// check for duplicate select expressions
|
||||
static_assert(not detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
||||
|
||||
// check for invalid select expressions
|
||||
template<typename T>
|
||||
struct is_valid_expression_t: public std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value> {};
|
||||
using _valid_expressions = typename detail::make_set_if<is_valid_expression_t, NamedExpr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression");
|
||||
|
||||
// check for duplicate select expression names
|
||||
static_assert(not detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
|
||||
|
||||
// provide type information for sub-selects that are used as expressions
|
||||
struct _column_type {};
|
||||
struct _value_type: detail::get_first_argument_if_unique<NamedExpr...>::_value_type
|
||||
{
|
||||
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
||||
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
||||
using _is_alias = std::false_type;
|
||||
};
|
||||
using _name_t = typename detail::get_first_argument_if_unique<NamedExpr...>::_name_t;
|
||||
|
||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||
dynamic_result_row_t<make_field_t<NamedExpr>...>,
|
||||
result_row_t<make_field_t<NamedExpr>...>>::type;
|
||||
|
||||
using _dynamic_names_t = typename detail::dynamic_select_expression_list<Database>::_names_t;
|
||||
|
||||
template <typename Select>
|
||||
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
|
||||
|
||||
template <typename Db>
|
||||
using _dynamic_t = select_expression_list_t<Db, std::tuple<NamedExpr...>>;
|
||||
|
||||
template<typename Expr>
|
||||
void add(Expr&& namedExpr)
|
||||
{
|
||||
static_assert(is_named_expression_t<typename std::decay<Expr>::type>::value, "select() arguments require to be named expressions");
|
||||
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
|
||||
_dynamic_expressions.push_back(std::forward<Expr>(namedExpr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
// check for at least one select expression
|
||||
static_assert(_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
|
||||
|
||||
detail::serialize_tuple(os, db, _expressions, ',');
|
||||
_dynamic_expressions.serialize(os, db, sizeof...(NamedExpr) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_expressions, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
detail::dynamic_select_expression_list<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,7 +27,8 @@
|
||||
#ifndef SQLPP_SELECT_FWD_H
|
||||
#define SQLPP_SELECT_FWD_H
|
||||
|
||||
#include <sqlpp11/noop_fwd.h>
|
||||
// FIXME: Do we really need this file?
|
||||
#include <sqlpp11/vendor/noop_fwd.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace sqlpp
|
||||
@ -37,36 +38,17 @@ namespace sqlpp
|
||||
struct distinct_t;
|
||||
struct straight_join_t;
|
||||
|
||||
template<typename FlagTuple> struct select_flag_list_t;
|
||||
template<typename Database, typename NamedExprTuple> struct select_expression_list_t;
|
||||
|
||||
template<typename Database, typename... TableOrJoin> struct from_t;
|
||||
|
||||
template<typename Database, typename... Expr> struct where_t;
|
||||
|
||||
template<typename Database, typename... Expr> struct group_by_t;
|
||||
|
||||
template<typename Database, typename... Expr> struct having_t;
|
||||
|
||||
template<typename Database, typename... Expr> struct order_by_t;
|
||||
|
||||
template<typename Limit>
|
||||
struct limit_t;
|
||||
|
||||
template<typename Offset>
|
||||
struct offset_t;
|
||||
|
||||
template<
|
||||
typename Db,
|
||||
typename Flags = noop,
|
||||
typename ExpressionList = noop,
|
||||
typename From = noop,
|
||||
typename Where = noop,
|
||||
typename GroupBy = noop,
|
||||
typename Having = noop,
|
||||
typename OrderBy = noop,
|
||||
typename Limit = noop,
|
||||
typename Offset = noop
|
||||
typename Flags = vendor::noop,
|
||||
typename ExpressionList = vendor::noop,
|
||||
typename From = vendor::noop,
|
||||
typename Where = vendor::noop,
|
||||
typename GroupBy = vendor::noop,
|
||||
typename Having = vendor::noop,
|
||||
typename OrderBy = vendor::noop,
|
||||
typename Limit = vendor::noop,
|
||||
typename Offset = vendor::noop
|
||||
>
|
||||
struct select_t;
|
||||
}
|
||||
|
60
include/sqlpp11/serializer.h
Normal file
60
include/sqlpp11/serializer.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_SERIALIZER_H
|
||||
#define SQLPP_SERIALIZER_H
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct serializer_t
|
||||
{
|
||||
serializer_t(std::ostream& os):
|
||||
_os(os)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(T t)
|
||||
{
|
||||
return _os << t;
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
_os << std::endl;
|
||||
}
|
||||
|
||||
std::string escape(std::string arg)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
std::ostream& _os;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Select>
|
||||
struct some_t: public boolean::template operators<some_t<Select>>
|
||||
@ -71,22 +71,29 @@ namespace sqlpp
|
||||
some_t& operator=(some_t&&) = default;
|
||||
~some_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_some, "some() not supported by current database");
|
||||
os << "SOME(";
|
||||
_select.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Select _select;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Select>
|
||||
struct interpreter_t<Context, vendor::some_t<Select>>
|
||||
{
|
||||
using T = vendor::some_t<Select>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SOME(";
|
||||
interpret(t._select, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto some(T&& t) -> typename detail::some_t<typename operand_t<T, is_select_t>::type>
|
||||
auto some(T&& t) -> typename vendor::some_t<typename operand_t<T, is_select_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -40,23 +40,33 @@ namespace sqlpp
|
||||
{
|
||||
using _is_sort_order = std::true_type;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
Expression _expression;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
_expression.serialize(os, db);
|
||||
template<typename Context, typename Expression, sort_type SortType>
|
||||
struct interpreter_t<Context, sort_order_t<Expression, SortType>>
|
||||
{
|
||||
using T = sort_order_t<Expression, SortType>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._expression, context);
|
||||
switch(SortType)
|
||||
{
|
||||
case sort_type::asc:
|
||||
os << " ASC";
|
||||
context << " ASC";
|
||||
break;
|
||||
default:
|
||||
os << " DESC";
|
||||
context << " DESC";
|
||||
break;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
Expression _expression;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#ifndef SQLPP_H
|
||||
#define SQLPP_H
|
||||
|
||||
#include <sqlpp11/alias_provider.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
#include <sqlpp11/insert.h>
|
||||
#include <sqlpp11/remove.h>
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct sum_t: public boolean::template operators<sum_t<Expr>>
|
||||
@ -70,22 +70,29 @@ namespace sqlpp
|
||||
sum_t& operator=(sum_t&&) = default;
|
||||
~sum_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_sum, "sum not supported by current database");
|
||||
os << "SUM(";
|
||||
_expr.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Expr _expr;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Expr>
|
||||
struct interpreter_t<Context, vendor::sum_t<Expr>>
|
||||
{
|
||||
using T = vendor::sum_t<Expr>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SUM(";
|
||||
interpret(t._expr, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto sum(T&& t) -> typename detail::sum_t<typename operand_t<T, is_value_t>::type>
|
||||
auto sum(T&& t) -> typename vendor::sum_t<typename operand_t<T, is_value_t>::type>
|
||||
{
|
||||
return { std::forward<T>(t) };
|
||||
}
|
||||
|
@ -24,27 +24,30 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_TABLE_BASE_H
|
||||
#define SQLPP_TABLE_BASE_H
|
||||
#ifndef SQLPP_TABLE_H
|
||||
#define SQLPP_TABLE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/table_alias.h>
|
||||
#include <sqlpp11/column.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/join.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct table_base_t {};
|
||||
|
||||
template<typename Table, typename... ColumnSpec>
|
||||
struct table_base_t: public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
|
||||
struct table_t: public table_base_t, public ColumnSpec::_name_t::template _member_t<column_t<Table, ColumnSpec>>...
|
||||
{
|
||||
using _table_set = detail::set<Table>; // Hint need a set here to be similar to a join (which always represents more than one table)
|
||||
using _all_columns = typename detail::make_set<column_t<Table, ColumnSpec>...>::type;
|
||||
static_assert(_all_columns::size::value, "at least one column required per table");
|
||||
using _required_insert_columns = typename detail::make_set_if<require_insert_t, column_t<Table, ColumnSpec>...>::type;
|
||||
using _all_of_t = std::tuple<column_t<Table, ColumnSpec>...>;
|
||||
template<typename AliasProvider>
|
||||
using _alias_t = table_alias_t<typename std::decay<AliasProvider>::type, Table, ColumnSpec...>;
|
||||
|
||||
using _is_table = std::true_type;
|
||||
|
||||
@ -79,50 +82,15 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
template<typename AliasProvider>
|
||||
struct alias_t: public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||
{
|
||||
using _is_table = std::true_type;
|
||||
using _table_set = detail::set<alias_t>;
|
||||
|
||||
struct _value_type: Table::_value_type
|
||||
{
|
||||
using _is_expression = std::false_type;
|
||||
using _is_named_expression = copy_type_trait<Table, is_value_t>;
|
||||
using _is_alias = std::true_type;
|
||||
};
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
using _all_of_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>;
|
||||
|
||||
alias_t(const Table& table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
alias_t(Table&& table):
|
||||
_table(std::move(table))
|
||||
{}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "("; _table.serialize(os, db); os << ") AS " << _name_t::_get_name();
|
||||
}
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
alias_t<AliasProvider> as(const AliasProvider&) const
|
||||
_alias_t<AliasProvider> as(const AliasProvider&) const
|
||||
{
|
||||
return {*static_cast<const Table*>(this)};
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
const Table& ref() const
|
||||
{
|
||||
static_cast<const Table*>(this)->serialize_impl(os, db);
|
||||
return *static_cast<const Table*>(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Table>
|
||||
@ -131,6 +99,22 @@ namespace sqlpp
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename X>
|
||||
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_base_t, X>::value and not is_pseudo_table_t<X>::value, void>::type>
|
||||
{
|
||||
using T = X;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
84
include/sqlpp11/table_alias.h
Normal file
84
include/sqlpp11/table_alias.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_TABLE_ALIAS_H
|
||||
#define SQLPP_TABLE_ALIAS_H
|
||||
|
||||
#include <sqlpp11/column_fwd.h>
|
||||
#include <sqlpp11/interpret.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
struct table_alias_base_t {};
|
||||
|
||||
template<typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||
struct table_alias_t: public table_alias_base_t, public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||
{
|
||||
//FIXME: Need to add join functionality
|
||||
using _is_table = std::true_type;
|
||||
using _table_set = detail::set<table_alias_t>;
|
||||
|
||||
struct _value_type: Table::_value_type
|
||||
{
|
||||
using _is_expression = std::false_type;
|
||||
using _is_named_expression = copy_type_trait<Table, is_value_t>;
|
||||
using _is_alias = std::true_type;
|
||||
};
|
||||
|
||||
using _name_t = typename AliasProvider::_name_t;
|
||||
using _all_of_t = std::tuple<column_t<AliasProvider, ColumnSpec>...>;
|
||||
|
||||
table_alias_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename X>
|
||||
struct interpreter_t<Context, X, typename std::enable_if<std::is_base_of<table_alias_base_t, X>::value, void>::type>
|
||||
{
|
||||
using T = X;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._table, context);
|
||||
context << ") AS " << T::_name_t::_get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -28,11 +28,11 @@
|
||||
#define SQLPP_TEXT_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sqlpp11/detail/basic_operators.h>
|
||||
#include <sqlpp11/basic_operators.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/exception.h>
|
||||
#include <sqlpp11/concat.h>
|
||||
#include <sqlpp11/like.h>
|
||||
#include <sqlpp11/vendor/concat.h>
|
||||
#include <sqlpp11/vendor/like.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -51,27 +51,20 @@ namespace sqlpp
|
||||
{
|
||||
using _value_type = integral;
|
||||
|
||||
_parameter_t(const std::true_type&):
|
||||
_trivial_value_is_null(true),
|
||||
_parameter_t():
|
||||
_value(""),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
{}
|
||||
|
||||
_parameter_t(const std::false_type&):
|
||||
_trivial_value_is_null(false),
|
||||
_value(""),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(true)
|
||||
{}
|
||||
|
||||
_parameter_t(const _cpp_value_type& value):
|
||||
_value(value),
|
||||
_is_null(_trivial_value_is_null and _is_trivial())
|
||||
_is_null(false)
|
||||
{}
|
||||
|
||||
_parameter_t& operator=(const _cpp_value_type& value)
|
||||
{
|
||||
_value = value;
|
||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
||||
_is_null = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -82,14 +75,6 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return value() == ""; }
|
||||
|
||||
bool is_null() const
|
||||
{
|
||||
return _is_null;
|
||||
@ -109,7 +94,6 @@ namespace sqlpp
|
||||
}
|
||||
|
||||
private:
|
||||
bool _trivial_value_is_null;
|
||||
_cpp_value_type _value;
|
||||
bool _is_null;
|
||||
};
|
||||
@ -147,14 +131,6 @@ namespace sqlpp
|
||||
_len = 0;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << value();
|
||||
}
|
||||
|
||||
bool _is_trivial() const { return _len == 0; }
|
||||
|
||||
bool operator==(const _cpp_value_type& rhs) const { return value() == rhs; }
|
||||
bool operator!=(const _cpp_value_type& rhs) const { return not operator==(rhs); }
|
||||
|
||||
@ -196,17 +172,17 @@ namespace sqlpp
|
||||
struct operators: public basic_operators<Base, _constraint>
|
||||
{
|
||||
template<typename T>
|
||||
detail::concat_t<Base, typename _constraint<T>::type> operator+(T&& t) const
|
||||
vendor::concat_t<Base, typename _constraint<T>::type> operator+(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
detail::like_t<boolean, Base, typename _constraint<T>::type> like(T&& t) const
|
||||
vendor::like_t<Base, typename _constraint<T>::type> like(T&& t) const
|
||||
{
|
||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
||||
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||
}
|
||||
|
||||
};
|
||||
|
140
include/sqlpp11/tvin.h
Normal file
140
include/sqlpp11/tvin.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_TVIN_H
|
||||
#define SQLPP_TVIN_H
|
||||
|
||||
// TVIN: Trivial value is NULL
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T>
|
||||
struct tvin_t
|
||||
{
|
||||
using _operand_t = typename vendor::wrap_operand<T>::type;
|
||||
static_assert(not std::is_same<_operand_t, T>::value, "tvin() used with invalid type (only string and primitive types allowed)");
|
||||
using _value_type = typename _operand_t::_value_type;
|
||||
|
||||
tvin_t(T t):
|
||||
_value({t})
|
||||
{}
|
||||
tvin_t(const tvin_t&) = default;
|
||||
tvin_t(tvin_t&&) = default;
|
||||
tvin_t& operator=(const tvin_t&) = default;
|
||||
tvin_t& operator=(tvin_t&&) = default;
|
||||
~tvin_t() = default;
|
||||
|
||||
_operand_t _value;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Type>
|
||||
struct interpreter_t<Context, tvin_t<Type>>
|
||||
{
|
||||
using T = tvin_t<Type>;
|
||||
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(detail::wrong<T>::value, "tvin() must not be used with anything but =, ==, != and !");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct tvin_wrap_t
|
||||
{
|
||||
static constexpr bool _is_trivial()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tvin_wrap_t(T t):
|
||||
_value(t)
|
||||
{}
|
||||
tvin_wrap_t(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t(tvin_wrap_t&&) = default;
|
||||
tvin_wrap_t& operator=(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
|
||||
~tvin_wrap_t() = default;
|
||||
|
||||
T _value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct tvin_wrap_t<tvin_t<T>>
|
||||
{
|
||||
bool _is_trivial() const
|
||||
{
|
||||
return _value._is_trivial();
|
||||
};
|
||||
|
||||
tvin_wrap_t(tvin_t<T> t):
|
||||
_value(t._value)
|
||||
{}
|
||||
tvin_wrap_t(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t(tvin_wrap_t&&) = default;
|
||||
tvin_wrap_t& operator=(const tvin_wrap_t&) = default;
|
||||
tvin_wrap_t& operator=(tvin_wrap_t&&) = default;
|
||||
~tvin_wrap_t() = default;
|
||||
|
||||
typename tvin_t<T>::_operand_t _value;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Type>
|
||||
struct interpreter_t<Context, tvin_wrap_t<Type>>
|
||||
{
|
||||
using T = tvin_wrap_t<Type>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._is_trivial())
|
||||
{
|
||||
context << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
interpret(t._value, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto tvin(T t) -> tvin_t<typename std::decay<T>::type>
|
||||
{
|
||||
return {t};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -28,7 +28,7 @@
|
||||
#define SQLPP_TYPE_TRAITS_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <sqlpp11/detail/wrap_operand.h>
|
||||
#include <sqlpp11/vendor/wrap_operand.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -92,9 +92,9 @@ namespace sqlpp
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(trivial_value_is_null);
|
||||
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_table);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_pseudo_table);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_list);
|
||||
@ -112,7 +112,7 @@ namespace sqlpp
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_multi_column);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_value_list);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment_list);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_update_list);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
|
||||
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
||||
@ -126,13 +126,12 @@ namespace sqlpp
|
||||
template<typename T, template<typename> class IsCorrectType>
|
||||
struct operand_t
|
||||
{
|
||||
using type = typename detail::wrap_operand<typename std::decay<T>::type>::type;
|
||||
using type = typename vendor::wrap_operand<typename std::decay<T>::type>::type;
|
||||
static_assert(not is_alias_t<type>::value, "expression operand must not be an alias");
|
||||
static_assert(is_expression_t<type>::value, "expression required");
|
||||
static_assert(IsCorrectType<type>::value, "invalid operand type");
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -27,21 +27,20 @@
|
||||
#ifndef SQLPP_UPDATE_H
|
||||
#define SQLPP_UPDATE_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/noop.h>
|
||||
#include <sqlpp11/assignment_list.h>
|
||||
#include <sqlpp11/where.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_update.h>
|
||||
#include <sqlpp11/vendor/update_list.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<
|
||||
typename Database = void,
|
||||
typename Table = noop,
|
||||
typename Assignments = noop,
|
||||
typename Where = noop
|
||||
typename Table = vendor::noop,
|
||||
typename Assignments = vendor::noop,
|
||||
typename Where = vendor::noop
|
||||
>
|
||||
struct update_t;
|
||||
|
||||
@ -53,23 +52,24 @@ namespace sqlpp
|
||||
>
|
||||
struct update_t
|
||||
{
|
||||
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||
static_assert(is_noop<Assignments>::value or is_assignment_list_t<Assignments>::value, "invalid 'Assignments' arguments");
|
||||
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
||||
static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||
static_assert(vendor::is_noop<Assignments>::value or is_update_list_t<Assignments>::value, "invalid 'Assignments' arguments");
|
||||
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
||||
|
||||
template<typename AssignmentsT>
|
||||
using set_assignments_t = update_t<Database, Table, AssignmentsT, Where>;
|
||||
template<typename WhereT>
|
||||
using set_where_t = update_t<Database, Table, Assignments, WhereT>;
|
||||
//FIXME: add method to explicitly indicate that EVERYTHING should be updated?
|
||||
|
||||
using _parameter_tuple_t = std::tuple<Table, Assignments, Where>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<update_t>::type;
|
||||
|
||||
template<typename... Assignment>
|
||||
auto set(Assignment&&... assignment)
|
||||
-> set_assignments_t<assignment_list_t<void, must_not_update_t, typename std::decay<Assignment>::type...>>
|
||||
-> set_assignments_t<vendor::update_list_t<void, typename std::decay<Assignment>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
|
||||
static_assert(vendor::is_noop<Assignments>::value, "cannot call set() twice");
|
||||
return {
|
||||
_table,
|
||||
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
|
||||
@ -79,9 +79,9 @@ namespace sqlpp
|
||||
|
||||
template<typename... Assignment>
|
||||
auto dynamic_set(Assignment&&... assignment)
|
||||
-> set_assignments_t<assignment_list_t<Database, must_not_update_t, typename std::decay<Assignment>::type...>>
|
||||
-> set_assignments_t<vendor::update_list_t<Database, typename std::decay<Assignment>::type...>>
|
||||
{
|
||||
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
|
||||
static_assert(vendor::is_noop<Assignments>::value, "cannot call set() twice");
|
||||
return {
|
||||
_table,
|
||||
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
|
||||
@ -101,10 +101,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto where(Expr&&... expr)
|
||||
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>>
|
||||
-> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet");
|
||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
||||
static_assert(not vendor::is_noop<Assignments>::value, "cannot call where() if set() hasn't been called yet");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||
return {
|
||||
_table,
|
||||
_assignments,
|
||||
@ -114,10 +114,10 @@ namespace sqlpp
|
||||
|
||||
template<typename... Expr>
|
||||
auto dynamic_where(Expr&&... expr)
|
||||
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>>
|
||||
-> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
|
||||
{
|
||||
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet");
|
||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
||||
static_assert(not vendor::is_noop<Assignments>::value, "cannot call where() if set() hasn't been called yet");
|
||||
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||
return {
|
||||
_table,
|
||||
_assignments,
|
||||
@ -135,29 +135,12 @@ namespace sqlpp
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
const update_t& serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << "UPDATE ";
|
||||
_table.serialize(os, db);
|
||||
_assignments.serialize(os, db);
|
||||
_where.serialize(os, db);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
update_t& serialize(std::ostream& os, Db& db)
|
||||
{
|
||||
static_cast<const update_t*>(this)->serialize(os, db);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters()
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||
}
|
||||
@ -165,33 +148,48 @@ namespace sqlpp
|
||||
template<typename Db>
|
||||
std::size_t run(Db& db) const
|
||||
{
|
||||
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
||||
static_assert(not vendor::is_noop<Assignments>::value, "calling set() required before running update");
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
||||
return db.update(*this);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto prepare(Db& db)
|
||||
auto prepare(Db& db) const
|
||||
-> prepared_update_t<typename std::decay<Db>::type, update_t>
|
||||
{
|
||||
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
||||
static_assert(not vendor::is_noop<Assignments>::value, "calling set() required before running update");
|
||||
|
||||
_set_parameter_index(0);
|
||||
return {{}, db.prepare_update(*this)};
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_table, index);
|
||||
index = set_parameter_index(_assignments, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
Table _table;
|
||||
Assignments _assignments;
|
||||
Where _where;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context,
|
||||
typename Database,
|
||||
typename Table,
|
||||
typename Assignments,
|
||||
typename Where
|
||||
>
|
||||
struct interpreter_t<Context, update_t<Database, Table, Assignments, Where>>
|
||||
{
|
||||
using T = update_t<Database, Table, Assignments, Where>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "UPDATE ";
|
||||
interpret(t._table, context);
|
||||
interpret(t._assignments, context);
|
||||
interpret(t._where, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
constexpr update_t<void, typename std::decay<Table>::type> update(Table&& table)
|
||||
{
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_USING_H
|
||||
#define SQLPP_USING_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Table>
|
||||
struct using_t
|
||||
{
|
||||
using _is_using = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Table...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()");
|
||||
|
||||
// check for duplicate arguments
|
||||
static_assert(not detail::has_duplicates<Table...>::value, "at least one duplicate argument detected in using()");
|
||||
|
||||
// check for invalid arguments
|
||||
using _valid_expressions = typename detail::make_set_if<is_table_t, Table...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()");
|
||||
|
||||
|
||||
template<typename T>
|
||||
void add(T&& table)
|
||||
{
|
||||
static_assert(is_table_t<typename std::decay<T>::type>::value, "using() arguments require to be tables");
|
||||
_dynamic_tables.emplace_back(std::forward<T>(table));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (sizeof...(Table) == 0 and _dynamic_tables.empty())
|
||||
return;
|
||||
os << " USING ";
|
||||
detail::serialize_tuple(os, db, _tables, ',');
|
||||
_dynamic_tables.serialize(os, db, sizeof...(Table) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_tables, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _tables;
|
||||
detail::serializable_list<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,19 +27,19 @@
|
||||
#ifndef SQLPP_CONCAT_H
|
||||
#define SQLPP_CONCAT_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename First, typename... Args>
|
||||
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
|
||||
{
|
||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||
using _valid_args = typename detail::make_set_if_not<is_text_t, First, Args...>::type;
|
||||
using _valid_args = typename ::sqlpp::detail::make_set_if_not<is_text_t, First, Args...>::type;
|
||||
static_assert(_valid_args::size::value == 0, "at least one non-text argument detected in concat()");
|
||||
|
||||
struct _value_type: public First::_value_type::_base_value_type
|
||||
@ -57,11 +57,7 @@ namespace sqlpp
|
||||
};
|
||||
};
|
||||
|
||||
concat_t(First&& first, Args&&... args):
|
||||
_args(std::move(first), std::move(args)...)
|
||||
{}
|
||||
|
||||
concat_t(const First& first, const Args&... args):
|
||||
concat_t(First first, Args... args):
|
||||
_args(first, args...)
|
||||
{}
|
||||
|
||||
@ -71,35 +67,23 @@ namespace sqlpp
|
||||
concat_t& operator=(concat_t&&) = default;
|
||||
~concat_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_use_concat_operator or Db::_use_concat_function, "neither concat operator nor concat function supported by current database");
|
||||
if (Db::_use_concat_operator)
|
||||
{
|
||||
os << "(";
|
||||
detail::serialize_tuple(os, db, _args, "||");
|
||||
os << ")";
|
||||
}
|
||||
else if (Db::_use_concat_function)
|
||||
{
|
||||
os << "CONCAT(";
|
||||
detail::serialize_tuple(os, db, _args, ',');
|
||||
os << ")";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::tuple<First, Args...> _args;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
auto concat(T&&... t) -> typename detail::concat_t<typename operand_t<T, is_text_t>::type...>
|
||||
template<typename Context, typename First, typename... Args>
|
||||
struct interpreter_t<Context, concat_t<First, Args...>>
|
||||
{
|
||||
return { std::forward<T>(t)... };
|
||||
}
|
||||
using T = concat_t<First, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret_tuple(t._args, "||", context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
282
include/sqlpp11/vendor/expression.h
vendored
Normal file
282
include/sqlpp11/vendor/expression.h
vendored
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_EXPRESSION_H
|
||||
#define SQLPP_EXPRESSION_H
|
||||
|
||||
#include <sqlpp11/alias.h>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/tvin.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/expression_fwd.h>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
#include <sqlpp11/vendor/wrap_operand.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t
|
||||
{
|
||||
using _is_assignment = std::true_type;
|
||||
using column_type = Lhs;
|
||||
using value_type = tvin_wrap_t<Rhs>;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
assignment_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
assignment_t(const assignment_t&) = default;
|
||||
assignment_t(assignment_t&&) = default;
|
||||
assignment_t& operator=(const assignment_t&) = default;
|
||||
assignment_t& operator=(assignment_t&&) = default;
|
||||
~assignment_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
tvin_wrap_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Context, assignment_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = assignment_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << "=NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct equal_t: public detail::boolean::template operators<equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
equal_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
equal_t(const equal_t&) = default;
|
||||
equal_t(equal_t&&) = default;
|
||||
equal_t& operator=(const equal_t&) = default;
|
||||
equal_t& operator=(equal_t&&) = default;
|
||||
~equal_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
tvin_wrap_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Context, equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = equal_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << " IS NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct not_equal_t: public detail::boolean::template operators<not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
not_equal_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
not_equal_t(const not_equal_t&) = default;
|
||||
not_equal_t(not_equal_t&&) = default;
|
||||
not_equal_t& operator=(const not_equal_t&) = default;
|
||||
not_equal_t& operator=(not_equal_t&&) = default;
|
||||
~not_equal_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
tvin_wrap_t<Rhs> _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename Rhs>
|
||||
struct interpreter_t<Context, not_equal_t<Lhs, Rhs>>
|
||||
{
|
||||
using T = not_equal_t<Lhs, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
if (t._rhs._is_trivial())
|
||||
{
|
||||
context << " IS NOT NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
context << "!=";
|
||||
interpret(t._rhs, context);
|
||||
}
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs>
|
||||
struct logical_not_t: public detail::boolean::template operators<logical_not_t<Lhs>>
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
using _parameter_tuple_t = std::tuple<Lhs>;
|
||||
|
||||
logical_not_t(Lhs l):
|
||||
_lhs(l)
|
||||
{}
|
||||
|
||||
logical_not_t(const logical_not_t&) = default;
|
||||
logical_not_t(logical_not_t&&) = default;
|
||||
logical_not_t& operator=(const logical_not_t&) = default;
|
||||
logical_not_t& operator=(logical_not_t&&) = default;
|
||||
~logical_not_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs>
|
||||
struct interpreter_t<Context, logical_not_t<Lhs>>
|
||||
{
|
||||
using T = logical_not_t<Lhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
context << "NOT ";
|
||||
interpret(t._lhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t: public O::_value_type::template operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _value_type = typename O::_value_type;
|
||||
using _parameter_tuple_t = std::tuple<Lhs, Rhs>;
|
||||
|
||||
binary_expression_t(Lhs lhs, Rhs rhs):
|
||||
_lhs(lhs),
|
||||
_rhs(rhs)
|
||||
{}
|
||||
|
||||
binary_expression_t(const binary_expression_t&) = default;
|
||||
binary_expression_t(binary_expression_t&&) = default;
|
||||
binary_expression_t& operator=(const binary_expression_t&) = default;
|
||||
binary_expression_t& operator=(binary_expression_t&&) = default;
|
||||
~binary_expression_t() = default;
|
||||
|
||||
Lhs _lhs;
|
||||
Rhs _rhs;
|
||||
};
|
||||
|
||||
template<typename Context, typename Lhs, typename O, typename Rhs>
|
||||
struct interpreter_t<Context, binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using T = binary_expression_t<Lhs, O, Rhs>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "(";
|
||||
interpret(t._lhs, context);
|
||||
context << O::_name;
|
||||
interpret(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename O, typename Rhs>
|
||||
struct unary_expression_t: public O::_value_type::template operators<unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using _value_type = typename O::_value_type;
|
||||
using _parameter_tuple_t = std::tuple<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 interpreter_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;
|
||||
interpret(t._rhs, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
180
include/sqlpp11/vendor/expression_fwd.h
vendored
Normal file
180
include/sqlpp11/vendor/expression_fwd.h
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_EXPRESSION_FWD_H
|
||||
#define SQLPP_EXPRESSION_FWD_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct assignment_t;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct equal_t;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct not_equal_t;
|
||||
|
||||
template<typename Lhs>
|
||||
struct logical_not_t;
|
||||
|
||||
namespace tag
|
||||
{
|
||||
struct less_than
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
static constexpr const char* _name = "<";
|
||||
};
|
||||
|
||||
struct less_equal
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
static constexpr const char* _name = "<=";
|
||||
};
|
||||
|
||||
struct greater_equal
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
static constexpr const char* _name = ">=";
|
||||
};
|
||||
|
||||
struct greater_than
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
static constexpr const char* _name = ">";
|
||||
};
|
||||
|
||||
struct logical_or
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
static constexpr const char* _name = " OR ";
|
||||
};
|
||||
|
||||
struct logical_and
|
||||
{
|
||||
using _value_type = detail::boolean;
|
||||
static constexpr const char* _name = " AND ";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
struct plus
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
static constexpr const char* _name = "+";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
struct minus
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
struct multiplies
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
static constexpr const char* _name = "*";
|
||||
};
|
||||
|
||||
struct divides
|
||||
{
|
||||
using _value_type = detail::floating_point;
|
||||
static constexpr const char* _name = "/";
|
||||
};
|
||||
|
||||
struct modulus
|
||||
{
|
||||
using _value_type = detail::integral;
|
||||
static constexpr const char* _name = "%";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
struct unary_minus
|
||||
{
|
||||
using _value_type = ValueType;
|
||||
static constexpr const char* _name = "-";
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
struct unary_plus
|
||||
{
|
||||
using _value_type = 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, tag::less_than, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using less_equal_t = binary_expression_t<Lhs, tag::less_equal, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using greater_than_t = binary_expression_t<Lhs, tag::greater_than, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using greater_equal_t = binary_expression_t<Lhs, tag::greater_equal, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using logical_and_t = binary_expression_t<Lhs, tag::logical_and, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using logical_or_t = binary_expression_t<Lhs, tag::logical_or, Rhs>;
|
||||
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using plus_t = binary_expression_t<Lhs, tag::plus<ValueType>, Rhs>;
|
||||
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using minus_t = binary_expression_t<Lhs, tag::minus<ValueType>, Rhs>;
|
||||
|
||||
template<typename Lhs, typename ValueType, typename Rhs>
|
||||
using multiplies_t = binary_expression_t<Lhs, tag::multiplies<ValueType>, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using divides_t = binary_expression_t<Lhs, tag::divides, Rhs>;
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
using modulus_t = binary_expression_t<Lhs, tag::modulus, Rhs>;
|
||||
|
||||
template<typename ValueType, typename Rhs>
|
||||
using unary_plus_t = unary_expression_t<tag::unary_plus<ValueType>, Rhs>;
|
||||
|
||||
template<typename ValueType, typename Rhs>
|
||||
using unary_minus_t = unary_expression_t<tag::unary_minus<ValueType>, Rhs>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -27,10 +27,11 @@
|
||||
#ifndef SQLPP_FIELD_H
|
||||
#define SQLPP_FIELD_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/multi_column.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename NameType, typename ValueType>
|
||||
struct field_t
|
||||
@ -61,6 +62,7 @@ namespace sqlpp
|
||||
|
||||
template<typename NamedExpr>
|
||||
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
||||
}
|
||||
|
||||
}
|
||||
|
91
include/sqlpp11/vendor/from.h
vendored
Normal file
91
include/sqlpp11/vendor/from.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_FROM_H
|
||||
#define SQLPP_FROM_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database, typename... TableOrJoin>
|
||||
struct from_t
|
||||
{
|
||||
using _is_from = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
// ensure one argument at least
|
||||
static_assert(_is_dynamic::value or sizeof...(TableOrJoin), "at least one table or join argument required in from()");
|
||||
|
||||
// check for duplicate arguments
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<TableOrJoin...>::value, "at least one duplicate argument detected in from()");
|
||||
|
||||
// check for invalid arguments
|
||||
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_table_t, TableOrJoin...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(TableOrJoin), "at least one argument is not a table or join in from()");
|
||||
|
||||
// FIXME: Joins contain two tables. This is not being dealt with at the moment when looking at duplicates, for instance
|
||||
|
||||
|
||||
template<typename Table>
|
||||
void add(Table&& table)
|
||||
{
|
||||
static_assert(is_table_t<typename std::decay<Table>::type>::value, "from arguments require to be tables or joins");
|
||||
_dynamic_tables.emplace_back(std::forward<Table>(table));
|
||||
}
|
||||
|
||||
std::tuple<TableOrJoin...> _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... TableOrJoin>
|
||||
struct interpreter_t<Context, from_t<Database, TableOrJoin...>>
|
||||
{
|
||||
using T = from_t<Database, TableOrJoin...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(TableOrJoin) == 0 and t._dynamic_tables.empty())
|
||||
return context;
|
||||
context << " FROM ";
|
||||
interpret_tuple(t._tables, ',', context);
|
||||
if (sizeof...(TableOrJoin) and not t._dynamic_tables.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_tables, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
90
include/sqlpp11/vendor/group_by.h
vendored
Normal file
90
include/sqlpp11/vendor/group_by.h
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_GROUP_BY_H
|
||||
#define SQLPP_GROUP_BY_H
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
struct group_by_t
|
||||
{
|
||||
using _is_group_by = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
// ensure one argument at least
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression (e.g. a column) required in group_by()");
|
||||
|
||||
// check for duplicate expressions
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in group_by()");
|
||||
|
||||
// check for invalid expressions
|
||||
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_expression_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in group_by()");
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_table_t<typename std::decay<E>::type>::value, "from arguments require to be tables or joins");
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct interpreter_t<Context, group_by_t<Database, Expr...>>
|
||||
{
|
||||
using T = group_by_t<Database, Expr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " GROUP BY ";
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_expressions, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
84
include/sqlpp11/vendor/having.h
vendored
Normal file
84
include/sqlpp11/vendor/having.h
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_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/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
struct having_t
|
||||
{
|
||||
using _is_having = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in having()");
|
||||
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_expression_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in having()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_having()");
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct interpreter_t<Context, having_t<Database, Expr...>>
|
||||
{
|
||||
using T = having_t<Database, Expr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " HAVING ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -27,22 +27,22 @@
|
||||
#ifndef SQLPP_IN_H
|
||||
#define SQLPP_IN_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/vendor/in_fwd.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
// The ValueType should be boolean, this is a hack because boolean is not fully defined when the compiler first gets here...
|
||||
template<bool NotInverted, typename ValueType, typename Operand, typename... Args>
|
||||
struct in_t: public ValueType::_base_value_type::template operators<in_t<NotInverted, ValueType, Args...>>
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
struct in_t: public boolean::template operators<in_t<NotInverted, Operand, Args...>>
|
||||
{
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
|
||||
|
||||
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
@ -73,22 +73,26 @@ namespace sqlpp
|
||||
in_t& operator=(in_t&&) = default;
|
||||
~in_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert((NotInverted and Db::_supports_in)
|
||||
or (_inverted and Db::_supports_not_in), "in() and/or not_in() not supported by current database");
|
||||
_operand.serialize(os, db);
|
||||
os << (_inverted ? " NOT IN(" : " IN(");
|
||||
detail::serialize_tuple(os, db, _args, ',');
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Operand _operand;
|
||||
std::tuple<Args...> _args;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand, typename... Args>
|
||||
struct interpreter_t<Context, vendor::in_t<NotInverted, Operand, Args...>>
|
||||
{
|
||||
using T = vendor::in_t<NotInverted, Operand, Args...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._operand, context);
|
||||
context << (t._inverted ? " NOT IN(" : " IN(");
|
||||
interpret_tuple(t._args, ',', context);
|
||||
context << ')';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -24,16 +24,17 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_EXPRESSION_FWD_H
|
||||
#define SQLPP_EXPRESSION_FWD_H
|
||||
#ifndef SQLPP_IN_FWD_H
|
||||
#define SQLPP_IN_FWD_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename T>
|
||||
struct is_expression_t;
|
||||
namespace vendor
|
||||
{
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
struct in_t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct is_named_expression_t;
|
||||
}
|
||||
|
||||
#endif
|
155
include/sqlpp11/vendor/insert_list.h
vendored
Normal file
155
include/sqlpp11/vendor/insert_list.h
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_INSERT_LIST_H
|
||||
#define SQLPP_INSERT_LIST_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
struct insert_default_values_t
|
||||
{
|
||||
using _is_insert_list = std::true_type;
|
||||
using _is_dynamic = std::false_type;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, insert_default_values_t>
|
||||
{
|
||||
using T = insert_default_values_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " DEFAULT VALUES";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Column>
|
||||
struct insert_column_t
|
||||
{
|
||||
Column _column;
|
||||
};
|
||||
|
||||
template<typename Context, typename Column>
|
||||
struct interpreter_t<Context, insert_column_t<Column>>
|
||||
{
|
||||
using T = insert_column_t<Column>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._column._get_name();
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_t
|
||||
{
|
||||
using _is_insert_list = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Assignments...>;
|
||||
|
||||
// check for at least one order expression
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one select expression required in set()");
|
||||
|
||||
// check for duplicate assignments
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
// check for invalid assignments
|
||||
using _assignment_set = typename ::sqlpp::detail::make_set_if<is_assignment_t, Assignments...>::type;
|
||||
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
||||
|
||||
// check for prohibited assignments
|
||||
using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if<must_not_insert_t, typename Assignments::column_type...>::type;
|
||||
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
insert_list_t(Assignments... assignment):
|
||||
_columns({assignment._lhs}...),
|
||||
_values(assignment._rhs...)
|
||||
{}
|
||||
|
||||
insert_list_t(const insert_list_t&) = default;
|
||||
insert_list_t(insert_list_t&&) = default;
|
||||
insert_list_t& operator=(const insert_list_t&) = default;
|
||||
insert_list_t& operator=(insert_list_t&&) = default;
|
||||
~insert_list_t() = default;
|
||||
|
||||
template<typename Assignment>
|
||||
void add(Assignment&& assignment)
|
||||
{
|
||||
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
||||
static_assert(not must_not_insert_t<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
|
||||
_dynamic_columns.emplace_back(insert_column_t<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
|
||||
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
|
||||
}
|
||||
|
||||
|
||||
std::tuple<insert_column_t<typename Assignments::column_type>...> _columns;
|
||||
std::tuple<typename Assignments::value_type...> _values;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_columns;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct interpreter_t<Context, insert_list_t<Database, Assignments...>>
|
||||
{
|
||||
using T = insert_list_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
||||
{
|
||||
interpret(insert_default_values_t(), context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context << " (";
|
||||
interpret_tuple(t._columns, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_columns.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_columns, ',', context);
|
||||
context << ") VALUES(";
|
||||
interpret_tuple(t._values, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_values.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_values, ',', context);
|
||||
context << ")";
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
77
include/sqlpp11/vendor/interpret_tuple.h
vendored
Normal file
77
include/sqlpp11/vendor/interpret_tuple.h
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_INTERPRET_TUPLE_H
|
||||
#define SQLPP_INTERPRET_TUPLE_H
|
||||
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Context, typename Tuple>
|
||||
struct tuple_interpreter_t
|
||||
{
|
||||
template<typename Separator>
|
||||
static void _(const Tuple& t, const Separator& separator, Context& context)
|
||||
{
|
||||
_impl(t, separator, context, type<0>());
|
||||
};
|
||||
|
||||
private:
|
||||
template<size_t> struct type {};
|
||||
|
||||
template<typename Separator, size_t index>
|
||||
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<index>&)
|
||||
{
|
||||
if (index)
|
||||
context << separator;
|
||||
const auto& entry = std::get<index>(t);
|
||||
using entry_type = typename std::tuple_element<index, Tuple>::type;
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
context << "(";
|
||||
interpret(entry, context);
|
||||
if (requires_braces_t<entry_type>::value)
|
||||
context << ")";
|
||||
_impl(t, separator, context, type<index + 1>());
|
||||
}
|
||||
|
||||
template<typename Separator>
|
||||
static void _impl(const Tuple& t, const Separator& separator, Context& context, const type<std::tuple_size<Tuple>::value>&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tuple, typename Separator, typename Context>
|
||||
auto interpret_tuple(const Tuple& t, const Separator& separator, Context& context)
|
||||
-> decltype(tuple_interpreter_t<typename std::decay<Context>::type, typename std::decay<Tuple>::type>::_(t, separator, context))
|
||||
{
|
||||
return tuple_interpreter_t<typename std::decay<Context>::type, typename std::decay<Tuple>::type>::_(t, separator, context);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -24,43 +24,49 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_SERIALIZABLE_H
|
||||
#define SQLPP_SERIALIZABLE_H
|
||||
#ifndef SQLPP_INTERPRETABLE_H
|
||||
#define SQLPP_INTERPRETABLE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <sqlpp11/serializer.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/interpret.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Db>
|
||||
struct serializable_t
|
||||
struct interpretable_t
|
||||
{
|
||||
template<typename T,
|
||||
typename std::enable_if<not std::is_same<typename std::decay<T>::type, serializable_t<Db>>::value, int>::type = 0 // prevent accidental overload for copy constructor
|
||||
>
|
||||
serializable_t(T&& t):
|
||||
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(std::forward<T>(t)))
|
||||
using _context_t = typename Db::_context_t;
|
||||
|
||||
template<typename T>
|
||||
interpretable_t(T t):
|
||||
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t))
|
||||
{}
|
||||
|
||||
serializable_t(const serializable_t&) = default;
|
||||
serializable_t(serializable_t&&) = default;
|
||||
serializable_t& operator=(const serializable_t&) = default;
|
||||
serializable_t& operator=(serializable_t&&) = default;
|
||||
~serializable_t() = default;
|
||||
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;
|
||||
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
sqlpp::serializer_t& interpret(sqlpp::serializer_t& context) const
|
||||
{
|
||||
_impl->serialize(os, db);
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
_context_t& interpret(_context_t& context) const
|
||||
{
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
virtual void serialize(std::ostream& os, Db& db) const = 0;
|
||||
virtual sqlpp::serializer_t& interpret(sqlpp::serializer_t& context) const = 0;
|
||||
virtual _context_t& interpret(_context_t& context) const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -75,15 +81,36 @@ namespace sqlpp
|
||||
_t(std::move(t))
|
||||
{}
|
||||
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
sqlpp::serializer_t& interpret(sqlpp::serializer_t& context) const
|
||||
{
|
||||
_t.serialize(os, db);
|
||||
sqlpp::interpret(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_context_t& interpret(_context_t& context) const
|
||||
{
|
||||
sqlpp::interpret(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
std::shared_ptr<const _impl_base> _impl;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct interpreter_t<Context, interpretable_t<Database>>
|
||||
{
|
||||
using T = interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
t.interpret(context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,20 +24,20 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_SERIALIZABLE_LIST_H
|
||||
#define SQLPP_SERIALIZABLE_LIST_H
|
||||
#ifndef SQLPP_INTERPRETABLE_LIST_H
|
||||
#define SQLPP_INTERPRETABLE_LIST_H
|
||||
|
||||
#include <vector>
|
||||
#include <sqlpp11/detail/serializable.h>
|
||||
#include <sqlpp11/vendor/interpretable.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Db>
|
||||
struct serializable_list
|
||||
struct interpretable_list_t
|
||||
{
|
||||
std::vector<detail::serializable_t<Db>> _serializables;
|
||||
std::vector<interpretable_t<Db>> _serializables;
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
@ -55,59 +55,67 @@ namespace sqlpp
|
||||
_serializables.emplace_back(std::forward<Expr>(expr));
|
||||
}
|
||||
|
||||
void serialize(std::ostream& os, Db& db, bool first) const
|
||||
{
|
||||
for (const auto entry : _serializables)
|
||||
{
|
||||
if (not first)
|
||||
os << ',';
|
||||
entry.serialize(os, db);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Separator>
|
||||
void serialize(std::ostream& os, Db& db, const Separator& separator, bool first) const
|
||||
{
|
||||
for (const auto entry : _serializables)
|
||||
{
|
||||
if (not first)
|
||||
os << separator;
|
||||
entry.serialize(os, db);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct serializable_list<void>
|
||||
struct interpretable_list_t<void>
|
||||
{
|
||||
template<typename T>
|
||||
void emplace_back(const T&) {}
|
||||
|
||||
constexpr std::size_t size() const
|
||||
static constexpr std::size_t size()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
constexpr bool empty() const
|
||||
static constexpr bool empty()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream&, Db&, bool) const
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Db, typename Separator>
|
||||
void serialize(std::ostream& os, Db& db, const Separator& separator, bool first) const
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Context, typename List>
|
||||
struct serializable_list_interpreter_t
|
||||
{
|
||||
using T = List;
|
||||
|
||||
template<typename Separator>
|
||||
static Context& _(const T& t, const Separator& separator, Context& context)
|
||||
{
|
||||
bool first = true;
|
||||
for (const auto entry : t._serializables)
|
||||
{
|
||||
if (not first)
|
||||
{
|
||||
context << separator;
|
||||
first = false;
|
||||
}
|
||||
interpret(entry, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializable_list_interpreter_t<Context, interpretable_list_t<void>>
|
||||
{
|
||||
using T = interpretable_list_t<void>;
|
||||
|
||||
template<typename Separator>
|
||||
static Context& _(const T& t, const Separator& separator, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Separator, typename Context>
|
||||
auto interpret_list(const T& t, const Separator& separator, Context& context)
|
||||
-> decltype(serializable_list_interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, separator, context))
|
||||
{
|
||||
return serializable_list_interpreter_t<typename std::decay<Context>::type, typename std::decay<T>::type>::_(t, separator, context);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
48
include/sqlpp11/vendor/interpreter.h
vendored
Normal file
48
include/sqlpp11/vendor/interpreter.h
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_VENDOR_INTERPRET_H
|
||||
#define SQLPP_VENDOR_INTERPRET_H
|
||||
|
||||
#include <sqlpp11/detail/wrong.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename T, typename Enable = void>
|
||||
struct interpreter_t
|
||||
{
|
||||
static void _(const T& t, Context& context)
|
||||
{
|
||||
static_assert(detail::wrong<Context, T>::value, "missing interpreter specialization");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,21 +27,20 @@
|
||||
#ifndef SQLPP_IS_NULL_H
|
||||
#define SQLPP_IS_NULL_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
// The ValueType should be boolean, this is a hack because boolean is not fully defined when the compiler first gets here...
|
||||
template<bool NotInverted, typename ValueType, typename Operand>
|
||||
struct is_null_t: public ValueType::_base_value_type::template operators<is_null_t<NotInverted, ValueType, Operand>>
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t: public boolean::template operators<is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
static constexpr bool _inverted = not NotInverted;
|
||||
|
||||
struct _value_type: public ValueType::_base_value_type // we requite fully defined boolean here
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
@ -70,19 +69,23 @@ namespace sqlpp
|
||||
is_null_t& operator=(is_null_t&&) = default;
|
||||
~is_null_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert((NotInverted and Db::_supports_is_null)
|
||||
or (_inverted and Db::_supports_is_not_null), "is_null() and/or is_not_null() not supported by current database");
|
||||
_operand.serialize(os, db);
|
||||
os << (_inverted ? " IS NOT NULL" : " IS NULL");
|
||||
}
|
||||
|
||||
private:
|
||||
Operand _operand;
|
||||
};
|
||||
|
||||
template<typename Context, bool NotInverted, typename Operand>
|
||||
struct interpreter_t<Context, ::sqlpp::vendor::is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
using T = ::sqlpp::vendor::is_null_t<NotInverted, Operand>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._operand, context);
|
||||
context << (t._inverted ? " IS NOT NULL" : " IS NULL");
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
39
include/sqlpp11/vendor/is_null_fwd.h
vendored
Normal file
39
include/sqlpp11/vendor/is_null_fwd.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_IS_NULL_FWD_H
|
||||
#define SQLPP_IS_NULL_FWD_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -27,23 +27,22 @@
|
||||
#ifndef SQLPP_LIKE_H
|
||||
#define SQLPP_LIKE_H
|
||||
|
||||
#include <sstream>
|
||||
#include <sqlpp11/boolean.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
// The ValueType should be boolean, this is a hack because boolean is not fully defined when the compiler first gets here...
|
||||
template<typename ValueType, typename Operand, typename Pattern>
|
||||
struct like_t: public ValueType::_base_value_type::template operators<like_t<ValueType, Operand, Pattern>>
|
||||
template<typename Operand, typename Pattern>
|
||||
struct like_t: public boolean::template operators<like_t<Operand, Pattern>>
|
||||
{
|
||||
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
||||
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
||||
using _parameter_tuple_t = std::tuple<ValueType, Pattern>;
|
||||
using _parameter_tuple_t = std::tuple<Operand, Pattern>;
|
||||
|
||||
struct _value_type: public ValueType::_base_value_type // we require fully defined boolean here
|
||||
struct _value_type: public boolean
|
||||
{
|
||||
using _is_named_expression = std::true_type;
|
||||
};
|
||||
@ -74,27 +73,24 @@ namespace sqlpp
|
||||
like_t& operator=(like_t&&) = default;
|
||||
~like_t() = default;
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_operand, index);
|
||||
index = set_parameter_index(_pattern, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_like, "like() not supported by current database");
|
||||
_operand.serialize(os, db);
|
||||
os << " LIKE(";
|
||||
_pattern.serialize(os, db);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
private:
|
||||
Operand _operand;
|
||||
Pattern _pattern;
|
||||
};
|
||||
|
||||
template<typename Context, typename Operand, typename Pattern>
|
||||
struct interpreter_t<Context, like_t<Operand, Pattern>>
|
||||
{
|
||||
using T = like_t<Operand, Pattern>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._operand, context);
|
||||
context << " LIKE(";
|
||||
interpret(t._pattern, context);
|
||||
context << ")";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -32,31 +32,31 @@
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Limit>
|
||||
struct limit_t
|
||||
{
|
||||
using _is_limit = std::true_type;
|
||||
using _parameter_tuple_t = std::tuple<Limit>;
|
||||
static_assert(std::is_integral<Limit>::value
|
||||
or (is_parameter_t<Limit>::value and is_numeric_t<Limit>::value), "limit requires an integral value or integral parameter");
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_limit, "limit not supported by current database");
|
||||
os << " LIMIT " << _limit;
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_limit, index);
|
||||
return index;
|
||||
}
|
||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||
|
||||
Limit _limit;
|
||||
};
|
||||
|
||||
template<typename Context, typename Limit>
|
||||
struct interpreter_t<Context, limit_t<Limit>>
|
||||
{
|
||||
using T = limit_t<Limit>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " LIMIT ";
|
||||
interpret(t._limit, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct dynamic_limit_t
|
||||
{
|
||||
using _is_limit = std::true_type;
|
||||
@ -67,16 +67,23 @@ namespace sqlpp
|
||||
_limit = limit;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_limit, "limit not supported by current database");
|
||||
if (_limit > 0)
|
||||
os << " LIMIT " << _limit;
|
||||
}
|
||||
|
||||
std::size_t _limit;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, dynamic_limit_t>
|
||||
{
|
||||
using T = dynamic_limit_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._limit > 0)
|
||||
context << " LIMIT " << t._limit;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,33 +27,38 @@
|
||||
#ifndef SQLPP_NAMED_SERIALIZABLE_H
|
||||
#define SQLPP_NAMED_SERIALIZABLE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <sqlpp11/serializer.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Db>
|
||||
struct named_serializable_t
|
||||
struct named_interpretable_t
|
||||
{
|
||||
template<typename T,
|
||||
typename std::enable_if<not std::is_same<typename std::decay<T>::type, named_serializable_t<Db>>::value, int>::type = 0 // prevent accidental overload for copy constructor
|
||||
>
|
||||
named_serializable_t(T&& t):
|
||||
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(std::forward<T>(t)))
|
||||
using _context_t = typename Db::_context_t;
|
||||
|
||||
template<typename T>
|
||||
named_interpretable_t(T t):
|
||||
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t))
|
||||
{}
|
||||
|
||||
named_serializable_t(const named_serializable_t&) = default;
|
||||
named_serializable_t(named_serializable_t&&) = default;
|
||||
named_serializable_t& operator=(const named_serializable_t&) = default;
|
||||
named_serializable_t& operator=(named_serializable_t&&) = default;
|
||||
~named_serializable_t() = default;
|
||||
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;
|
||||
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
sqlpp::serializer_t& interpret(sqlpp::serializer_t& context) const
|
||||
{
|
||||
_impl->serialize(os, db);
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
_context_t& interpret(_context_t& context) const
|
||||
{
|
||||
return _impl->interpret(context);
|
||||
}
|
||||
|
||||
std::string _get_name() const
|
||||
@ -64,13 +69,15 @@ namespace sqlpp
|
||||
private:
|
||||
struct _impl_base
|
||||
{
|
||||
virtual void serialize(std::ostream& os, Db& db) const = 0;
|
||||
virtual sqlpp::serializer_t& interpret(sqlpp::serializer_t& context) const = 0;
|
||||
virtual _context_t& interpret(_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 query parts");
|
||||
_impl_t(const T& t):
|
||||
_t(t)
|
||||
{}
|
||||
@ -79,9 +86,16 @@ namespace sqlpp
|
||||
_t(std::move(t))
|
||||
{}
|
||||
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
sqlpp::serializer_t& interpret(sqlpp::serializer_t& context) const
|
||||
{
|
||||
_t.serialize(os, db);
|
||||
sqlpp::interpret(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
_context_t& interpret(_context_t& context) const
|
||||
{
|
||||
sqlpp::interpret(_t, context);
|
||||
return context;
|
||||
}
|
||||
|
||||
std::string _get_name() const
|
||||
@ -94,7 +108,20 @@ namespace sqlpp
|
||||
|
||||
std::shared_ptr<const _impl_base> _impl;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct interpreter_t<Context, named_interpretable_t<Database>>
|
||||
{
|
||||
using T = named_interpretable_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
t.interpret(context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -28,18 +28,30 @@
|
||||
#define SQLPP_NOOP_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <sqlpp11/vendor/noop_fwd.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
struct noop
|
||||
{
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, noop>
|
||||
{
|
||||
using T = noop;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_noop: std::is_same<T, noop> {};
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
@ -28,10 +28,13 @@
|
||||
#define SQLPP_NOOP_FWD_H
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
struct noop;
|
||||
|
||||
template<typename T>
|
||||
struct is_noop;
|
||||
}
|
||||
}
|
||||
#endif
|
@ -27,36 +27,34 @@
|
||||
#ifndef SQLPP_OFFSET_H
|
||||
#define SQLPP_OFFSET_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Offset>
|
||||
struct offset_t
|
||||
{
|
||||
using _is_offset = std::true_type;
|
||||
using _parameter_tuple_t = std::tuple<Offset>;
|
||||
static_assert(std::is_integral<Offset>::value
|
||||
or (is_parameter_t<Offset>::value and is_numeric_t<Offset>::value), "offset requires an integral value or integral parameter");
|
||||
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << " OFFSET " << _offset;
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_offset, index);
|
||||
return index;
|
||||
}
|
||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||
|
||||
Offset _offset;
|
||||
};
|
||||
|
||||
template<typename Context, typename Offset>
|
||||
struct interpreter_t<Context, offset_t<Offset>>
|
||||
{
|
||||
using T = offset_t<Offset>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " OFFSET ";
|
||||
interpret(t._offset, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct dynamic_offset_t
|
||||
{
|
||||
using _is_offset = std::true_type;
|
||||
@ -67,16 +65,23 @@ namespace sqlpp
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (_offset > 0)
|
||||
os << " OFFSET " << _offset;
|
||||
}
|
||||
|
||||
std::size_t _offset;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, dynamic_offset_t>
|
||||
{
|
||||
using T = dynamic_offset_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (t._offset > 0)
|
||||
context << " OFFSET " << t._offset;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
88
include/sqlpp11/vendor/order_by.h
vendored
Normal file
88
include/sqlpp11/vendor/order_by.h
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_ORDER_BY_H
|
||||
#define SQLPP_ORDER_BY_H
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database,typename... Expr>
|
||||
struct order_by_t
|
||||
{
|
||||
using _is_order_by = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
// check for at least one order expression
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one sort-order expression required in order_by()");
|
||||
|
||||
// check for duplicate order expressions
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expr...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
// check for invalid order expressions
|
||||
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_sort_order_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not a sort order expression in order_by()");
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_sort_order_t<typename std::decay<E>::type>::value, "order_by arguments require to be sort-order expressions");
|
||||
_dynamic_expressions.push_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct interpreter_t<Context, order_by_t<Database, Expr...>>
|
||||
{
|
||||
using T = order_by_t<Database, Expr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " ORDER BY ";
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_expressions, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
204
include/sqlpp11/vendor/select_expression_list.h
vendored
Normal file
204
include/sqlpp11/vendor/select_expression_list.h
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_SELECT_EXPRESSION_LIST_H
|
||||
#define SQLPP_SELECT_EXPRESSION_LIST_H
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/result_row.h>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/vendor/expression_fwd.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/vendor/field.h>
|
||||
#include <sqlpp11/vendor/select_pseudo_table.h>
|
||||
#include <sqlpp11/vendor/named_interpretable.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename... Rest>
|
||||
struct get_first_argument_if_unique
|
||||
{
|
||||
using _value_type = no_value_t;
|
||||
struct _name_t {};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct get_first_argument_if_unique<T>
|
||||
{
|
||||
using _value_type = typename T::_value_type;
|
||||
using _name_t = typename T::_name_t;
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Db>
|
||||
struct dynamic_select_expression_list
|
||||
{
|
||||
using _names_t = std::vector<std::string>;
|
||||
std::vector<vendor::named_interpretable_t<Db>> _dynamic_expressions;
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
template<typename Expr>
|
||||
void push_back(Expr&& expr)
|
||||
{
|
||||
_dynamic_expression_names.push_back(std::decay<Expr>::type::_name_t::_get_name());
|
||||
_dynamic_expressions.emplace_back(std::forward<Expr>(expr));
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return _dynamic_expressions.empty();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct dynamic_select_expression_list<void>
|
||||
{
|
||||
struct _names_t {};
|
||||
_names_t _dynamic_expression_names;
|
||||
|
||||
template<typename T>
|
||||
void push_back(const T&) {}
|
||||
|
||||
static constexpr bool empty()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context, typename Db>
|
||||
struct interpreter_t<Context, dynamic_select_expression_list<Db>>
|
||||
{
|
||||
using T = dynamic_select_expression_list<Db>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
for (const auto column : t._dynamic_expressions)
|
||||
{
|
||||
interpret(column, context);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, dynamic_select_expression_list<void>>
|
||||
{
|
||||
using T = dynamic_select_expression_list<void>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Database, typename T>
|
||||
struct select_expression_list_t
|
||||
{
|
||||
static_assert(::sqlpp::detail::wrong<Database, T>::value, "invalid template argument for select_expression_list");
|
||||
};
|
||||
|
||||
template<typename Database, typename... NamedExpr>
|
||||
struct select_expression_list_t<Database, std::tuple<NamedExpr...>>
|
||||
{
|
||||
using _is_select_expression_list = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<NamedExpr...>;
|
||||
|
||||
// check for duplicate select expressions
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<NamedExpr...>::value, "at least one duplicate argument detected");
|
||||
|
||||
// check for invalid select expressions
|
||||
template<typename T>
|
||||
struct is_valid_expression_t: public std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value> {};
|
||||
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_valid_expression_t, NamedExpr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(NamedExpr), "at least one argument is not a named expression");
|
||||
|
||||
// check for duplicate select expression names
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<typename NamedExpr::_name_t...>::value, "at least one duplicate name detected");
|
||||
|
||||
// provide type information for sub-selects that are used as expressions
|
||||
struct _column_type {};
|
||||
struct _value_type: ::sqlpp::detail::get_first_argument_if_unique<NamedExpr...>::_value_type
|
||||
{
|
||||
using _is_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
||||
using _is_named_expression = typename std::conditional<sizeof...(NamedExpr) == 1, std::true_type, std::false_type>::type;
|
||||
using _is_alias = std::false_type;
|
||||
};
|
||||
using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique<NamedExpr...>::_name_t;
|
||||
|
||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||
dynamic_result_row_t<make_field_t<NamedExpr>...>,
|
||||
result_row_t<make_field_t<NamedExpr>...>>::type;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_expression_list<Database>::_names_t;
|
||||
|
||||
template <typename Select>
|
||||
using _pseudo_table_t = select_pseudo_table_t<Select, NamedExpr...>;
|
||||
|
||||
template <typename Db>
|
||||
using _dynamic_t = select_expression_list_t<Db, std::tuple<NamedExpr...>>;
|
||||
|
||||
template<typename Expr>
|
||||
void add(Expr&& namedExpr)
|
||||
{
|
||||
static_assert(is_named_expression_t<typename std::decay<Expr>::type>::value, "select() arguments require to be named expressions");
|
||||
static_assert(_is_dynamic::value, "cannot add columns to a non-dynamic column list");
|
||||
_dynamic_expressions.push_back(std::forward<Expr>(namedExpr));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
dynamic_select_expression_list<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... NamedExpr>
|
||||
struct interpreter_t<Context, select_expression_list_t<Database, NamedExpr...>>
|
||||
{
|
||||
using T = select_expression_list_t<Database, NamedExpr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
// check for at least one expression
|
||||
static_assert(T::_is_dynamic::value or sizeof...(NamedExpr), "at least one select expression required");
|
||||
|
||||
interpret_tuple(t._expressions, ',', context);
|
||||
if (sizeof...(NamedExpr) and not t._dynamic_expressions.empty())
|
||||
context << ',';
|
||||
interpret(t._dynamic_expressions, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -30,9 +30,8 @@
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <tuple>
|
||||
#include <ostream>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -43,45 +42,74 @@ namespace sqlpp
|
||||
{
|
||||
using _is_select_flag = std::true_type;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db&) const
|
||||
{
|
||||
os << "ALL";
|
||||
}
|
||||
};
|
||||
static constexpr all_t all = {};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, all_t>
|
||||
{
|
||||
static Context& _(const all_t&, Context& context)
|
||||
{
|
||||
context << "ALL";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct distinct_t
|
||||
{
|
||||
struct _value_type
|
||||
{
|
||||
using _is_select_flag = std::true_type;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db&) const
|
||||
{
|
||||
os << "DISTINCT";
|
||||
}
|
||||
};
|
||||
static constexpr distinct_t distinct = {};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, distinct_t>
|
||||
{
|
||||
static Context& _(const distinct_t&, Context& context)
|
||||
{
|
||||
context << "DISTINCT";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct straight_join_t
|
||||
{
|
||||
struct _value_type
|
||||
{
|
||||
using _is_select_flag = std::true_type;
|
||||
};
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, const Db&) const
|
||||
{
|
||||
os << "STRAIGHT_JOIN";
|
||||
}
|
||||
};
|
||||
static constexpr straight_join_t straight_join = {};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, straight_join_t>
|
||||
{
|
||||
static Context& _(const straight_join_t&, Context& context)
|
||||
{
|
||||
context << "STRAIGHT_JOIN";
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename T>
|
||||
struct select_flag_list_t
|
||||
{
|
||||
static_assert(detail::wrong<T>::value, "invalid argument for select_flag_list");
|
||||
};
|
||||
|
||||
// select_flag_list_t
|
||||
template<typename... Flag>
|
||||
struct select_flag_list_t<std::tuple<Flag...>>
|
||||
@ -95,16 +123,24 @@ namespace sqlpp
|
||||
|
||||
using _is_select_flag_list = std::true_type;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
detail::serialize_tuple(os, db, _flags, ' ');
|
||||
os << ' ';
|
||||
}
|
||||
|
||||
std::tuple<Flag...> _flags;
|
||||
};
|
||||
|
||||
template<typename Context, typename... Flag>
|
||||
struct interpreter_t<Context, select_flag_list_t<std::tuple<Flag...>>>
|
||||
{
|
||||
using T = select_flag_list_t<std::tuple<Flag...>>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret_tuple(t._flags, ' ', context);
|
||||
if (sizeof...(Flag))
|
||||
context << ' ';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -44,11 +44,12 @@ namespace sqlpp
|
||||
typename Select,
|
||||
typename... NamedExpr
|
||||
>
|
||||
struct select_pseudo_table_t: public sqlpp::table_base_t<select_pseudo_table_t<
|
||||
struct select_pseudo_table_t: public sqlpp::table_t<select_pseudo_table_t<
|
||||
Select,
|
||||
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
||||
{
|
||||
using _value_type = no_value_t;
|
||||
using _is_pseudo_table = std::true_type;
|
||||
|
||||
select_pseudo_table_t(const Select& select):
|
||||
_select(select)
|
||||
@ -66,16 +67,24 @@ namespace sqlpp
|
||||
select_pseudo_table_t& operator=(select_pseudo_table_t&& rhs) = default;
|
||||
~select_pseudo_table_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
static_assert(Db::_supports_select_as_table, "select as table not supported by current database");
|
||||
_select.serialize(os, db);
|
||||
}
|
||||
|
||||
Select _select;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Select, typename... NamedExpr>
|
||||
struct interpreter_t<Context, select_pseudo_table_t<Select, NamedExpr...>>
|
||||
{
|
||||
using T = select_pseudo_table_t<Select, NamedExpr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
interpret(t._select, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
90
include/sqlpp11/vendor/update_list.h
vendored
Normal file
90
include/sqlpp11/vendor/update_list.h
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_UPDATE_LIST_H
|
||||
#define SQLPP_UPDATE_LIST_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_t
|
||||
{
|
||||
using _is_update_list = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Assignments...>;
|
||||
|
||||
// check for at least one order expression
|
||||
static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()");
|
||||
|
||||
// check for duplicate assignments
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Assignments...>::value, "at least one duplicate argument detected in set()");
|
||||
|
||||
// check for invalid assignments
|
||||
using _assignment_set = typename ::sqlpp::detail::make_set_if<is_assignment_t, Assignments...>::type;
|
||||
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
||||
|
||||
// check for prohibited assignments
|
||||
using _prohibited_assignment_set = typename ::sqlpp::detail::make_set_if<must_not_update_t, typename Assignments::column_type...>::type;
|
||||
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
||||
|
||||
template<typename Assignment>
|
||||
void add(Assignment&& assignment)
|
||||
{
|
||||
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
||||
static_assert(not must_not_update_t<typename std::decay<Assignment>::type::column_type>::value, "set() argument must not be updated");
|
||||
_dynamic_assignments.emplace_back(std::forward<Assignment>(assignment));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _assignments;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct interpreter_t<Context, update_list_t<Database, Assignments...>>
|
||||
{
|
||||
using T = update_list_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " SET ";
|
||||
interpret_tuple(t._assignments, ",", context);
|
||||
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_assignments, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
87
include/sqlpp11/vendor/using.h
vendored
Normal file
87
include/sqlpp11/vendor/using.h
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_USING_H
|
||||
#define SQLPP_USING_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database, typename... Table>
|
||||
struct using_t
|
||||
{
|
||||
using _is_using = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Table...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()");
|
||||
|
||||
// check for duplicate arguments
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Table...>::value, "at least one duplicate argument detected in using()");
|
||||
|
||||
// check for invalid arguments
|
||||
using _valid_expressions = typename ::sqlpp::detail::make_set_if<is_table_t, Table...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Table), "at least one argument is not an table in using()");
|
||||
|
||||
|
||||
template<typename T>
|
||||
void add(T&& table)
|
||||
{
|
||||
static_assert(is_table_t<typename std::decay<T>::type>::value, "using() arguments require to be tables");
|
||||
_dynamic_tables.emplace_back(std::forward<T>(table));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Table>
|
||||
struct interpreter_t<Context, using_t<Database, Table...>>
|
||||
{
|
||||
using T = using_t<Database, Table...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Table) == 0 and t._dynamic_tables.empty())
|
||||
return context;
|
||||
context << " USING ";
|
||||
interpret_tuple(t._tables, ',', context);
|
||||
if (sizeof...(Table) and not t._dynamic_tables.empty())
|
||||
context << ',';
|
||||
interpret_list(t._dynamic_tables, ',', context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
41
include/sqlpp11/vendor/value_type.h
vendored
Normal file
41
include/sqlpp11/vendor/value_type.h
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_VALUE_TYPE_H
|
||||
#define SQLPP_VALUE_TYPE_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <sqlpp11/vendor/wrap_operand.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename T>
|
||||
using value_type_t = typename wrap_operand<typename std::decay<T>::type>::type::_value_type;
|
||||
}
|
||||
}
|
||||
#endif
|
88
include/sqlpp11/vendor/where.h
vendored
Normal file
88
include/sqlpp11/vendor/where.h
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_WHERE_H
|
||||
#define SQLPP_WHERE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||
#include <sqlpp11/vendor/interpretable_list.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
struct where_t
|
||||
{
|
||||
using _is_where = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
|
||||
using _valid_expressions = typename sqlpp::detail::make_set_if<is_expression_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_where()");
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Expr>
|
||||
struct interpreter_t<Context, where_t<Database, Expr...>>
|
||||
{
|
||||
using T = where_t<Database, Expr...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and t._dynamic_expressions.empty())
|
||||
return context;
|
||||
context << " WHERE ";
|
||||
interpret_tuple(t._expressions, " AND ", context);
|
||||
if (sizeof...(Expr) and not t._dynamic_expressions.empty())
|
||||
context << " AND ";
|
||||
interpret_list(t._dynamic_expressions, " AND ", context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -27,8 +27,8 @@
|
||||
#ifndef SQLPP_DETAIL_WRAP_OPERAND_H
|
||||
#define SQLPP_DETAIL_WRAP_OPERAND_H
|
||||
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <sqlpp11/vendor/interpreter.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
@ -38,102 +38,101 @@ namespace sqlpp
|
||||
struct integral;
|
||||
struct floating_point;
|
||||
struct text;
|
||||
}
|
||||
|
||||
struct bool_operand
|
||||
namespace vendor
|
||||
{
|
||||
struct boolean_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = boolean;
|
||||
|
||||
bool_operand(bool t): _t(t) {}
|
||||
bool_operand(const bool_operand&) = default;
|
||||
bool_operand(bool_operand&&) = default;
|
||||
bool_operand& operator=(const bool_operand&) = default;
|
||||
bool_operand& operator=(bool_operand&&) = default;
|
||||
~bool_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
using _value_type = detail::boolean;
|
||||
|
||||
bool _is_trivial() const { return _t == false; }
|
||||
|
||||
bool _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, boolean_operand>
|
||||
{
|
||||
using Operand = boolean_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct integral_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = integral;
|
||||
|
||||
integral_operand(T t): _t(t) {}
|
||||
integral_operand(const integral_operand&) = default;
|
||||
integral_operand(integral_operand&&) = default;
|
||||
integral_operand& operator=(const integral_operand&) = default;
|
||||
integral_operand& operator=(integral_operand&&) = default;
|
||||
~integral_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
using _value_type = detail::integral;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t<Context, integral_operand<T>>
|
||||
{
|
||||
using Operand = integral_operand<T>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct floating_point_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = floating_point;
|
||||
|
||||
floating_point_operand(T t): _t(t) {}
|
||||
floating_point_operand(const floating_point_operand&) = default;
|
||||
floating_point_operand(floating_point_operand&&) = default;
|
||||
floating_point_operand& operator=(const floating_point_operand&) = default;
|
||||
floating_point_operand& operator=(floating_point_operand&&) = default;
|
||||
~floating_point_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _t;
|
||||
}
|
||||
using _value_type = detail::floating_point;
|
||||
|
||||
bool _is_trivial() const { return _t == 0; }
|
||||
|
||||
T _t;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename Context, typename T>
|
||||
struct interpreter_t<Context, floating_point_operand<T>>
|
||||
{
|
||||
using Operand = floating_point_operand<T>;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << t._t;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct text_operand
|
||||
{
|
||||
static constexpr bool _is_expression = true;
|
||||
using _value_type = text;
|
||||
|
||||
text_operand(const T& t): _t(t) {}
|
||||
text_operand(const text_operand&) = default;
|
||||
text_operand(text_operand&&) = default;
|
||||
text_operand& operator=(const text_operand&) = default;
|
||||
text_operand& operator=(text_operand&&) = default;
|
||||
~text_operand() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << '\'' << db.escape(_t) << '\'';
|
||||
}
|
||||
using _value_type = detail::text;
|
||||
|
||||
bool _is_trivial() const { return _t.empty(); }
|
||||
|
||||
std::string _t;
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, text_operand>
|
||||
{
|
||||
using Operand = text_operand;
|
||||
|
||||
static Context& _(const Operand& t, Context& context)
|
||||
{
|
||||
context << '\'' << context.escape(t._t) << '\'';
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct wrap_operand
|
||||
{
|
||||
@ -143,7 +142,7 @@ namespace sqlpp
|
||||
template<>
|
||||
struct wrap_operand<bool, void>
|
||||
{
|
||||
using type = bool_operand;
|
||||
using type = boolean_operand;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -161,7 +160,7 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
||||
{
|
||||
using type = text_operand<T>;
|
||||
using type = text_operand;
|
||||
};
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ namespace sqlpp
|
||||
};
|
||||
}
|
||||
|
||||
struct verbatim_table_t: public sqlpp::table_base_t<verbatim_table_t, detail::unusable_pseudo_column_t>
|
||||
struct verbatim_table_t: public sqlpp::table_t<verbatim_table_t, detail::unusable_pseudo_column_t>
|
||||
{
|
||||
using _value_type = no_value_t;
|
||||
|
||||
@ -62,15 +62,25 @@ namespace sqlpp
|
||||
verbatim_table_t& operator=(verbatim_table_t&& rhs) = default;
|
||||
~verbatim_table_t() = default;
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
os << _name;
|
||||
}
|
||||
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context>
|
||||
struct interpreter_t<Context, verbatim_table_t>
|
||||
{
|
||||
using T = verbatim_table_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << t._name;
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
verbatim_table_t verbatim_table(std::string name)
|
||||
{
|
||||
return { name };
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_WHERE_H
|
||||
#define SQLPP_WHERE_H
|
||||
|
||||
#include <ostream>
|
||||
#include <sqlpp11/select_fwd.h>
|
||||
#include <sqlpp11/expression.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/detail/set.h>
|
||||
#include <sqlpp11/detail/serialize_tuple.h>
|
||||
#include <sqlpp11/detail/serializable_list.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Database, typename... Expr>
|
||||
struct where_t
|
||||
{
|
||||
using _is_where = std::true_type;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
using _parameter_tuple_t = std::tuple<Expr...>;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expr), "at least one expression argument required in where()");
|
||||
using _valid_expressions = typename detail::make_set_if<is_expression_t, Expr...>::type;
|
||||
static_assert(_valid_expressions::size::value == sizeof...(Expr), "at least one argument is not an expression in where()");
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<_parameter_tuple_t>::type;
|
||||
static_assert(not _parameter_list_t::_contains_trivial_value_is_null_t::value, "must not use trivial_value_is_null in parameters of where expression, use where_parameter() instead of parameter() to turn off automatic conversion");
|
||||
|
||||
template<typename E>
|
||||
void add(E&& expr)
|
||||
{
|
||||
static_assert(is_expression_t<typename std::decay<E>::type>::value, "invalid expression argument in add_where()");
|
||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
void serialize(std::ostream& os, Db& db) const
|
||||
{
|
||||
if (sizeof...(Expr) == 0 and _dynamic_expressions.empty())
|
||||
return;
|
||||
os << " WHERE ";
|
||||
detail::serialize_tuple(os, db, _expressions, " AND ");
|
||||
_dynamic_expressions.serialize(os, db, " AND ", sizeof...(Expr) == 0);
|
||||
}
|
||||
|
||||
size_t _set_parameter_index(size_t index)
|
||||
{
|
||||
index = set_parameter_index(_expressions, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
_parameter_tuple_t _expressions;
|
||||
detail::serializable_list<Database> _dynamic_expressions;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -3,6 +3,7 @@ macro (build_and_run arg)
|
||||
add_test(${arg} ${arg})
|
||||
endmacro ()
|
||||
|
||||
build_and_run(InterpretTest)
|
||||
build_and_run(InsertTest)
|
||||
build_and_run(RemoveTest)
|
||||
build_and_run(UpdateTest)
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "TabSample.h"
|
||||
#include "MockDb.h"
|
||||
#include <sqlpp11/alias_provider.h>
|
||||
#include <sqlpp11/select.h>
|
||||
#include <sqlpp11/functions.h>
|
||||
#include <sqlpp11/connection.h>
|
||||
@ -32,7 +33,7 @@
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen);
|
||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <iostream>
|
||||
|
||||
DbMock db;
|
||||
DbMock::_context_t printer(std::cerr);
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -56,11 +57,11 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
insert_into(t).serialize(std::cerr, db); std::cerr << "\n";
|
||||
insert_into(t).set(t.beta = "kirschauflauf").serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(insert_into(t), printer).flush();
|
||||
interpret(insert_into(t).set(t.beta = "kirschauflauf"), printer).flush();
|
||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
||||
i = i.add_set(t.beta = "kirschauflauf");
|
||||
i.serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(i, printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
116
tests/InterpretTest.cpp
Normal file
116
tests/InterpretTest.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "TabSample.h"
|
||||
#include "MockDb.h"
|
||||
#include <sqlpp11/alias_provider.h>
|
||||
#include <sqlpp11/insert.h>
|
||||
#include <sqlpp11/select.h>
|
||||
#include <sqlpp11/update.h>
|
||||
#include <sqlpp11/remove.h>
|
||||
#include <sqlpp11/functions.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
DbMock::_context_t printer(std::cerr);
|
||||
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||
|
||||
int main()
|
||||
{
|
||||
TabSample t;
|
||||
|
||||
interpret(t.alpha, printer).flush();
|
||||
interpret(-t.alpha, printer).flush();
|
||||
interpret(+t.alpha, printer).flush();
|
||||
interpret(-(t.alpha + 7), printer).flush();
|
||||
interpret(t.alpha = 0, printer).flush();
|
||||
interpret(t.alpha = sqlpp::tvin(0), printer).flush();
|
||||
interpret(t.alpha == 0, printer).flush();
|
||||
interpret(t.alpha == sqlpp::tvin(0), printer).flush();
|
||||
interpret(t.alpha != 0, printer).flush();
|
||||
interpret(t.gamma != sqlpp::tvin(false), printer).flush();
|
||||
interpret(t.alpha == 7, printer).flush();
|
||||
interpret(t.beta + "kaesekuchen", printer).flush();
|
||||
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta), printer).flush();
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t), printer).flush();
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3), printer).flush();
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma), printer).flush();
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")), printer).flush();
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()), printer).flush();
|
||||
interpret(select(sqlpp::distinct, t.alpha, t.beta).from(t).where(t.alpha == 3).group_by(t.gamma).having(t.beta.like("%kuchen")).order_by(t.beta.asc()).limit(17).offset(3), printer).flush();
|
||||
|
||||
interpret(parameter(t.alpha), printer).flush();
|
||||
interpret(t.alpha == parameter(t.alpha), printer).flush();
|
||||
interpret(t.alpha == parameter(t.alpha) and (t.beta + "gimmick").like(parameter(t.beta)), printer).flush();
|
||||
|
||||
interpret(insert_into(t), printer).flush();
|
||||
interpret(insert_into(t).default_values(), printer).flush();
|
||||
interpret(insert_into(t).set(t.gamma = true), printer).flush();
|
||||
interpret(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).flush();
|
||||
|
||||
interpret(update(t), printer).flush();
|
||||
interpret(update(t).set(t.gamma = true), printer).flush();
|
||||
interpret(update(t).set(t.gamma = true).where(t.beta.in("kaesekuchen", "cheesecake")), printer).flush();
|
||||
|
||||
interpret(remove_from(t), printer).flush();
|
||||
interpret(remove_from(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
||||
interpret(remove_from(t).using_(t).where(t.alpha == sqlpp::tvin(0)), printer).flush();
|
||||
|
||||
// functions
|
||||
sqlpp::interpret(sqlpp::value(7), printer).flush(); // FIXME: Why is the namespace specifier required?
|
||||
interpret(sqlpp::verbatim<sqlpp::detail::integral>("irgendwas integrales"), printer).flush();
|
||||
interpret(sqlpp::value_list(std::vector<int>({1,2,3,4,5,6,8})), printer).flush();
|
||||
interpret(exists(select(t.alpha).from(t)), printer).flush();
|
||||
interpret(any(select(t.alpha).from(t)), printer).flush();
|
||||
interpret(some(select(t.alpha).from(t)), printer).flush();
|
||||
interpret(count(t.alpha), printer).flush();
|
||||
interpret(min(t.alpha), printer).flush();
|
||||
interpret(max(t.alpha), printer).flush();
|
||||
interpret(avg(t.alpha), printer).flush();
|
||||
interpret(sum(t.alpha), printer).flush();
|
||||
interpret(sqlpp::verbatim_table("whatever"), printer).flush();
|
||||
|
||||
// alias
|
||||
interpret(t.as(t.alpha), printer).flush();
|
||||
interpret(t.as(t.alpha).beta, printer).flush();
|
||||
|
||||
// select alias
|
||||
interpret(select(t.alpha).from(t).where(t.beta > "kaesekuchen").as(t.gamma), printer).flush();
|
||||
|
||||
interpret(t.alpha.is_null(), printer).flush();
|
||||
|
||||
// join
|
||||
interpret(t.inner_join(t.as(t.alpha)).on(t.beta == t.as(t.alpha).beta), printer).flush();
|
||||
|
||||
// multi_column
|
||||
interpret(multi_column(t.alpha, t.alpha, (t.beta + "cake").as(t.gamma)), printer).flush();
|
||||
|
||||
// dynamic select
|
||||
interpret(dynamic_select(db, t.alpha).dynamic_columns().add_column(t.beta), printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
@ -27,40 +27,14 @@
|
||||
#define SQLPP_MOCK_DB_H
|
||||
|
||||
#include <sqlpp11/connection.h>
|
||||
#include <sqlpp11/serializer.h>
|
||||
|
||||
class DbMock: public sqlpp::connection
|
||||
struct DbMock: public sqlpp::connection
|
||||
{
|
||||
public:
|
||||
// join types
|
||||
static constexpr bool _supports_inner_join = true;
|
||||
static constexpr bool _supports_outer_join = true;
|
||||
static constexpr bool _supports_left_outer_join = true;
|
||||
static constexpr bool _supports_right_outer_join = true;
|
||||
|
||||
// functions
|
||||
static constexpr bool _supports_avg = true;
|
||||
static constexpr bool _supports_count = true;
|
||||
static constexpr bool _supports_exists = true;
|
||||
static constexpr bool _supports_like = true;
|
||||
static constexpr bool _supports_in = true;
|
||||
static constexpr bool _supports_max = true;
|
||||
static constexpr bool _supports_min = true;
|
||||
static constexpr bool _supports_not_in = true;
|
||||
static constexpr bool _supports_sum = true;
|
||||
|
||||
// select
|
||||
static constexpr bool _supports_group_by = true;
|
||||
static constexpr bool _supports_having = true;
|
||||
static constexpr bool _supports_limit = true;
|
||||
static constexpr bool _supports_order_by = true;
|
||||
static constexpr bool _supports_select_as_table = true;
|
||||
|
||||
static constexpr bool _supports_some = true;
|
||||
static constexpr bool _supports_any = true;
|
||||
static constexpr bool _use_concat_operator = true;
|
||||
static constexpr bool _use_concat_function = true;
|
||||
|
||||
const std::string& escape(const std::string& text) { return text; }
|
||||
struct _context_t : public sqlpp::serializer_t
|
||||
{
|
||||
_context_t(std::ostream& os): sqlpp::serializer_t(os) {}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -87,7 +87,7 @@ int main()
|
||||
|
||||
// Wonderful, now take a look at the parameter list of a select
|
||||
{
|
||||
auto s = select(all_of(t)).from(t).where(t.beta.like(where_parameter(t.beta)) and t.alpha == where_parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||
auto s = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma));
|
||||
using S = decltype(s);
|
||||
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||
T npl;
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
|
||||
DbMock db;
|
||||
DbMock::_context_t printer(std::cerr);
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -56,13 +57,13 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
remove_from(t).serialize(std::cerr, db); std::cerr << "\n";
|
||||
remove_from(t).where(t.beta != "transparent").serialize(std::cerr, db); std::cerr << "\n";
|
||||
remove_from(t).using_(t).serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(remove_from(t), printer).flush();
|
||||
interpret(remove_from(t).where(t.beta != "transparent"), printer).flush();
|
||||
interpret(remove_from(t).using_(t), printer).flush();
|
||||
auto r = dynamic_remove_from(db, t).dynamic_using_().dynamic_where();
|
||||
r = r.add_using_(t);
|
||||
r = r.add_where(t.beta != "transparent");
|
||||
r.serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(r, printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "TabSample.h"
|
||||
#include "MockDb.h"
|
||||
#include "is_regular.h"
|
||||
#include <sqlpp11/alias_provider.h>
|
||||
#include <sqlpp11/select.h>
|
||||
#include <sqlpp11/functions.h>
|
||||
#include <sqlpp11/connection.h>
|
||||
@ -33,6 +34,15 @@
|
||||
#include <iostream>
|
||||
|
||||
DbMock db = {};
|
||||
DbMock::_context_t printer(std::cerr);
|
||||
|
||||
namespace alias
|
||||
{
|
||||
SQLPP_ALIAS_PROVIDER(a);
|
||||
SQLPP_ALIAS_PROVIDER(b);
|
||||
SQLPP_ALIAS_PROVIDER(left);
|
||||
SQLPP_ALIAS_PROVIDER(right);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -59,7 +69,7 @@ int main()
|
||||
|
||||
// Test an alias of table
|
||||
{
|
||||
using T = decltype(t.as(sqlpp::alias::a));
|
||||
using T = decltype(t.as(alias::a));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
@ -77,7 +87,7 @@ int main()
|
||||
|
||||
// Test an integral column of an alias of table
|
||||
{
|
||||
using T = decltype(t.as(sqlpp::alias::a).alpha);
|
||||
using T = decltype(t.as(alias::a).alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_integral_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_floating_point_t<T>::value, "type requirement");
|
||||
@ -132,7 +142,7 @@ int main()
|
||||
|
||||
// Test a an alias of a numeric table column
|
||||
{
|
||||
using T = decltype(t.alpha.as(sqlpp::alias::a));
|
||||
using T = decltype(t.alpha.as(alias::a));
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -180,7 +190,7 @@ int main()
|
||||
|
||||
// Test a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(sqlpp::alias::a)).from(t));
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t));
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -196,7 +206,7 @@ int main()
|
||||
|
||||
// Test an alias of a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t).as(sqlpp::alias::b));
|
||||
using T = decltype(select(t.alpha).from(t).as(alias::b));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -212,7 +222,7 @@ int main()
|
||||
|
||||
// Test the column of an alias of a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(sqlpp::alias::a)).from(t).as(sqlpp::alias::b));
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b));
|
||||
static_assert(not sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(not sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -228,7 +238,7 @@ int main()
|
||||
|
||||
// Test the column of an alias of a select of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha).from(t).as(sqlpp::alias::b).alpha);
|
||||
using T = decltype(select(t.alpha).from(t).as(alias::b).alpha);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -244,7 +254,7 @@ int main()
|
||||
|
||||
// Test an alias of a select of an alias of a single numeric table column
|
||||
{
|
||||
using T = decltype(select(t.alpha.as(sqlpp::alias::a)).from(t).as(sqlpp::alias::b).a);
|
||||
using T = decltype(select(t.alpha.as(alias::a)).from(t).as(alias::b).a);
|
||||
static_assert(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_expression_t<T>::value, "type requirement");
|
||||
static_assert(sqlpp::is_named_expression_t<T>::value, "type requirement");
|
||||
@ -269,22 +279,22 @@ int main()
|
||||
|
||||
// Test that select(all_of(tab)) is expanded in multi_column
|
||||
{
|
||||
auto a = multi_column(sqlpp::alias::a, all_of(t));
|
||||
auto b = multi_column(sqlpp::alias::a, t.alpha, t.beta, t.gamma);
|
||||
auto a = multi_column(alias::a, all_of(t));
|
||||
auto b = multi_column(alias::a, t.alpha, t.beta, t.gamma);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "all_of(t) has to be expanded by multi_column");
|
||||
}
|
||||
|
||||
// Test that select(tab) is expanded in multi_column
|
||||
{
|
||||
auto a = multi_column(sqlpp::alias::a, all_of(t));
|
||||
auto b = multi_column(sqlpp::alias::a, t.alpha, t.beta, t.gamma);
|
||||
auto a = multi_column(alias::a, all_of(t));
|
||||
auto b = multi_column(alias::a, t.alpha, t.beta, t.gamma);
|
||||
static_assert(std::is_same<decltype(a), decltype(b)>::value, "t has to be expanded by multi_column");
|
||||
}
|
||||
|
||||
// Test that a multicolumn is not a value
|
||||
{
|
||||
auto m = multi_column(sqlpp::alias::a, t.alpha, t.beta);
|
||||
auto a = select(m).from(t).as(sqlpp::alias::b).a;
|
||||
auto m = multi_column(alias::a, t.alpha, t.beta);
|
||||
auto a = select(m).from(t).as(alias::b).a;
|
||||
static_assert(not sqlpp::is_value_t<decltype(a)>::value, "a multi_column is not a value");
|
||||
}
|
||||
|
||||
@ -307,7 +317,7 @@ int main()
|
||||
s = s.set_limit(30);
|
||||
s = s.set_limit(3);
|
||||
std::cerr << "------------------------\n";
|
||||
s.serialize(std::cerr, db);
|
||||
interpret(s, printer).flush();
|
||||
std::cerr << "------------------------\n";
|
||||
using T = decltype(s);
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
@ -316,18 +326,18 @@ int main()
|
||||
// Test that select can be called with zero columns if it is used with dynamic columns.
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_columns().add_column(t.alpha);
|
||||
s.serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(s, printer).flush();
|
||||
}
|
||||
|
||||
// Test that verbatim_table compiles
|
||||
{
|
||||
auto s = select(t.alpha).from(sqlpp::verbatim_table("my_unknown_table"));
|
||||
s.serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(s, printer).flush();
|
||||
}
|
||||
|
||||
|
||||
static_assert(sqlpp::is_select_flag_t<decltype(sqlpp::all)>::value, "sqlpp::all has to be a select_flag");
|
||||
using T = sqlpp::detail::wrap_operand<int>::type;
|
||||
using T = sqlpp::vendor::wrap_operand<int>::type;
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
static_assert(T::_is_expression, "T has to be an expression");
|
||||
static_assert(std::is_same<typename T::_value_type::_is_numeric, std::true_type>::value, "T has to be a numeric");
|
||||
@ -339,29 +349,28 @@ int main()
|
||||
auto y = t.gamma and true and t.gamma;
|
||||
!t.gamma;
|
||||
t.beta < "kaesekuchen";
|
||||
(t.beta + "hallenhalma").serialize(std::cerr, db);
|
||||
concat(t.beta, "hallenhalma").serialize(std::cerr, db);
|
||||
interpret(t.beta + "hallenhalma", printer).flush();
|
||||
static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted");
|
||||
t.alpha.serialize(std::cerr, db);
|
||||
interpret(t.alpha, printer).flush();
|
||||
std::cerr << "\n" << sizeof(TabSample) << std::endl;
|
||||
static_assert(std::is_same<typename decltype(t.alpha)::_value_type::_is_named_expression, std::true_type>::value, "alpha should be a named expression");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha)>::value, "alpha should be a named expression");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(sqlpp::alias::a))>::value, "an alias of alpha should be a named expression");
|
||||
static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(sqlpp::alias::a))>::value, "an alias of alpha should be an alias");
|
||||
static_assert(sqlpp::is_named_expression_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be a named expression");
|
||||
static_assert(sqlpp::is_alias_t<decltype(t.alpha.as(alias::a))>::value, "an alias of alpha should be an alias");
|
||||
auto z = select(t.alpha) == 7;
|
||||
auto l = t.as(sqlpp::alias::left);
|
||||
auto r = select(t.gamma.as(sqlpp::alias::a)).from(t).where(t.gamma == true).as(sqlpp::alias::right);
|
||||
auto l = t.as(alias::left);
|
||||
auto r = select(t.gamma.as(alias::a)).from(t).where(t.gamma == true).as(alias::right);
|
||||
static_assert(sqlpp::is_boolean_t<decltype(select(t.gamma).from(t))>::value, "select(bool) has to be a bool");
|
||||
select(sqlpp::distinct, sqlpp::straight_join, l.alpha, l.beta, select(r.a).from(r))
|
||||
interpret(select(sqlpp::distinct, sqlpp::straight_join, l.alpha, l.beta, select(r.a).from(r))
|
||||
.from(l, r)
|
||||
.where(t.beta == "hello world" and select(t.gamma).from(t))// .as(sqlpp::alias::right))
|
||||
.where(t.beta == "hello world" and select(t.gamma).from(t))// .as(alias::right))
|
||||
.group_by(l.gamma, r.a)
|
||||
.having(r.a != true)
|
||||
.order_by(l.beta.asc())
|
||||
.limit(17)
|
||||
.offset(3)
|
||||
.as(sqlpp::alias::a)
|
||||
.serialize(std::cerr, db);
|
||||
.as(alias::a)
|
||||
, printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#ifndef SQLPP_TAB_SAMPLE_H
|
||||
#define SQLPP_TAB_SAMPLE_H
|
||||
|
||||
#include <sqlpp11/table_base.h>
|
||||
#include <sqlpp11/table.h>
|
||||
#include <sqlpp11/column_types.h>
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ namespace TabFoo_
|
||||
};
|
||||
}
|
||||
|
||||
struct TabFoo: sqlpp::table_base_t<
|
||||
struct TabFoo: sqlpp::table_t<
|
||||
TabFoo,
|
||||
TabFoo_::Epsilon,
|
||||
TabFoo_::Omega
|
||||
@ -166,7 +166,7 @@ namespace TabSample_
|
||||
};
|
||||
}
|
||||
|
||||
struct TabSample: sqlpp::table_base_t<
|
||||
struct TabSample: sqlpp::table_t<
|
||||
TabSample,
|
||||
TabSample_::Alpha,
|
||||
TabSample_::Beta,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "is_regular.h"
|
||||
|
||||
DbMock db;
|
||||
DbMock::_context_t printer(std::cerr);
|
||||
|
||||
int main()
|
||||
{
|
||||
@ -54,12 +55,12 @@ int main()
|
||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||
}
|
||||
|
||||
update(t).serialize(std::cerr, db); std::cerr << "\n";
|
||||
update(t).set(t.gamma = false).serialize(std::cerr, db); std::cerr << "\n";
|
||||
update(t).set(t.gamma = false).where(t.beta != "transparent").serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(update(t), printer).flush();
|
||||
interpret(update(t).set(t.gamma = false), printer).flush();
|
||||
interpret(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).flush();
|
||||
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
|
||||
u = u.add_set(t.gamma = false);
|
||||
u.serialize(std::cerr, db); std::cerr << "\n";
|
||||
interpret(u, printer).flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user