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,75 +30,39 @@
|
|||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace alias
|
|
||||||
{
|
|
||||||
#define SQLPP_ALIAS_PROVIDER_GENERATOR(name) \
|
|
||||||
struct name##_t\
|
|
||||||
{\
|
|
||||||
struct _name_t\
|
|
||||||
{\
|
|
||||||
static constexpr const char* _get_name() { return #name; }\
|
|
||||||
template<typename T>\
|
|
||||||
struct _member_t\
|
|
||||||
{\
|
|
||||||
T name;\
|
|
||||||
T& operator()() { return name; }\
|
|
||||||
const T& operator()() const { return name; }\
|
|
||||||
};\
|
|
||||||
};\
|
|
||||||
};\
|
|
||||||
constexpr name##_t name = {};
|
|
||||||
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(a);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(b);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(c);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(d);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(e);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(f);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(g);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(h);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(i);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(j);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(k);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(l);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(m);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(n);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(o);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(p);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(q);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(s);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(t);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(u);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(v);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(w);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(x);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(y);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(z);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(left);
|
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(right);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Expression, typename AliasProvider>
|
template<typename Expression, typename AliasProvider>
|
||||||
struct expression_alias_t
|
struct expression_alias_t
|
||||||
{
|
|
||||||
struct _value_type: Expression::_value_type
|
|
||||||
{
|
{
|
||||||
using _is_expression = std::false_type;
|
struct _value_type: Expression::_value_type
|
||||||
using _is_named_expression = std::true_type;
|
{
|
||||||
using _is_alias = std::true_type;
|
using _is_expression = std::false_type;
|
||||||
|
using _is_named_expression = std::true_type;
|
||||||
|
using _is_alias = std::true_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
using _name_t = typename AliasProvider::_name_t;
|
||||||
|
|
||||||
|
Expression _expression;
|
||||||
};
|
};
|
||||||
|
|
||||||
using _name_t = typename AliasProvider::_name_t;
|
namespace vendor
|
||||||
|
{
|
||||||
template<typename Db>
|
template<typename Context, typename Expression, typename AliasProvider>
|
||||||
void serialize(std::ostream& os, Db& db) const
|
struct interpreter_t<Context, expression_alias_t<Expression, AliasProvider>>
|
||||||
{
|
{
|
||||||
os << "("; _expression.serialize(os, db); os << ") AS " << _name_t::_get_name();
|
using T = expression_alias_t<Expression, AliasProvider>;
|
||||||
}
|
|
||||||
|
|
||||||
Expression _expression;
|
static Context& _(const T& t, Context& context)
|
||||||
};
|
{
|
||||||
|
context << '(';
|
||||||
|
interpret(t._expression, context);
|
||||||
|
context << ") AS ";
|
||||||
|
context << T::_name_t::_get_name();
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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 sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Select>
|
template<typename Select>
|
||||||
struct any_t: public boolean::template operators<any_t<Select>>
|
struct any_t: public boolean::template operators<any_t<Select>>
|
||||||
@ -71,26 +71,33 @@ namespace sqlpp
|
|||||||
any_t& operator=(any_t&&) = default;
|
any_t& operator=(any_t&&) = default;
|
||||||
~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;
|
Select _select;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto any(T&& t) -> typename detail::any_t<typename operand_t<T, is_select_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::any_t<typename operand_t<T, is_select_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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 sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct avg_t: public floating_point::template operators<avg_t<Expr>>
|
struct avg_t: public floating_point::template operators<avg_t<Expr>>
|
||||||
@ -70,26 +70,33 @@ namespace sqlpp
|
|||||||
avg_t& operator=(avg_t&&) = default;
|
avg_t& operator=(avg_t&&) = default;
|
||||||
~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;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto avg(T&& t) -> typename detail::avg_t<typename operand_t<T, is_value_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::avg_t<typename operand_t<T, is_value_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,11 +27,11 @@
|
|||||||
#ifndef SQLPP_DETAIL_BASIC_OPERATORS_H
|
#ifndef SQLPP_DETAIL_BASIC_OPERATORS_H
|
||||||
#define SQLPP_DETAIL_BASIC_OPERATORS_H
|
#define SQLPP_DETAIL_BASIC_OPERATORS_H
|
||||||
|
|
||||||
#include <sqlpp11/expression.h>
|
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/sort_order.h>
|
#include <sqlpp11/sort_order.h>
|
||||||
#include <sqlpp11/in.h>
|
#include <sqlpp11/vendor/expression_fwd.h>
|
||||||
#include <sqlpp11/is_null.h>
|
#include <sqlpp11/vendor/in_fwd.h>
|
||||||
|
#include <sqlpp11/vendor/is_null_fwd.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -39,84 +39,60 @@ namespace sqlpp
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
struct boolean;
|
struct boolean;
|
||||||
|
}
|
||||||
|
|
||||||
// operators
|
// basic operators
|
||||||
struct lt_
|
template<typename Base, template<typename> class Constraint>
|
||||||
{
|
struct basic_operators
|
||||||
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>
|
template<typename T>
|
||||||
equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const
|
vendor::equal_t<Base, typename Constraint<T>::type> operator==(T&& t) const
|
||||||
{
|
{
|
||||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const
|
vendor::not_equal_t<Base, typename Constraint<T>::type> operator!=(T&& t) const
|
||||||
{
|
{
|
||||||
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, lt_, typename Constraint<T>::type> operator<(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, le_, typename Constraint<T>::type> operator<=(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, ge_, typename Constraint<T>::type> operator>=(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, gt_, typename Constraint<T>::type> operator>(T&& t) const
|
vendor::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");
|
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()");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_null()");
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
|
|
||||||
is_null_t<false, 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()");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with is_not_null()");
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
@ -136,17 +112,17 @@ namespace sqlpp
|
|||||||
|
|
||||||
// Hint: use value_list wrapper for containers...
|
// Hint: use value_list wrapper for containers...
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
in_t<true, 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()");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used with in()");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t)... };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)}... };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
in_t<false, 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()");
|
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>
|
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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot have a name");
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool _is_trivial() const { return false; }
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -28,7 +28,8 @@
|
|||||||
#define SQLPP_BOOLEAN_H
|
#define SQLPP_BOOLEAN_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <ostream>
|
||||||
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
|
|
||||||
@ -37,18 +38,6 @@ namespace sqlpp
|
|||||||
// boolean operators
|
// boolean operators
|
||||||
namespace detail
|
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
|
// boolean value type
|
||||||
struct boolean
|
struct boolean
|
||||||
{
|
{
|
||||||
@ -62,27 +51,20 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _value_type = boolean;
|
using _value_type = boolean;
|
||||||
|
|
||||||
_parameter_t(const std::true_type&):
|
_parameter_t():
|
||||||
_trivial_value_is_null(true),
|
|
||||||
_value(false),
|
_value(false),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(true)
|
||||||
{}
|
|
||||||
|
|
||||||
_parameter_t(const std::false_type&):
|
|
||||||
_trivial_value_is_null(false),
|
|
||||||
_value(false),
|
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t(const _cpp_value_type& value):
|
_parameter_t(const _cpp_value_type& value):
|
||||||
_value(value),
|
_value(value),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t& operator=(const _cpp_value_type& value)
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
_is_null = (false);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,14 +75,6 @@ namespace sqlpp
|
|||||||
return *this;
|
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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
return _is_null;
|
return _is_null;
|
||||||
@ -120,7 +94,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _trivial_value_is_null;
|
|
||||||
signed char _value;
|
signed char _value;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
@ -158,14 +131,6 @@ namespace sqlpp
|
|||||||
_value = 0;
|
_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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
@ -201,20 +166,20 @@ namespace sqlpp
|
|||||||
struct operators: public basic_operators<Base, _constraint>
|
struct operators: public basic_operators<Base, _constraint>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, and_, typename _constraint<T>::type> operator and(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, or_, typename _constraint<T>::type> operator or(T&& t) const
|
vendor::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");
|
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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be as operand for operator not");
|
||||||
return { *static_cast<const Base*>(this) };
|
return { *static_cast<const Base*>(this) };
|
||||||
|
@ -27,13 +27,13 @@
|
|||||||
#ifndef SQLPP_COLUMN_H
|
#ifndef SQLPP_COLUMN_H
|
||||||
#define SQLPP_COLUMN_H
|
#define SQLPP_COLUMN_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/expression.h>
|
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/alias.h>
|
||||||
#include <sqlpp11/column_fwd.h>
|
#include <sqlpp11/column_fwd.h>
|
||||||
#include <sqlpp11/detail/wrong.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/sort_order.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
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -58,17 +58,10 @@ namespace sqlpp
|
|||||||
column_t& operator=(column_t&&) = default;
|
column_t& operator=(column_t&&) = default;
|
||||||
~column_t() = default;
|
~column_t() = default;
|
||||||
|
|
||||||
template<typename Db>
|
static constexpr const char* _get_name()
|
||||||
void serialize(std::ostream& os, Db& db) const
|
{
|
||||||
{
|
return _name_t::_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();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename alias_provider>
|
template<typename alias_provider>
|
||||||
expression_alias_t<column_t, typename std::decay<alias_provider>::type> as(alias_provider&&) const
|
expression_alias_t<column_t, typename std::decay<alias_provider>::type> as(alias_provider&&) const
|
||||||
@ -79,12 +72,27 @@ namespace sqlpp
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
auto operator =(T&& t) const
|
auto operator =(T&& t) const
|
||||||
-> typename std::enable_if<not std::is_same<column_t, typename std::decay<T>::type>::value,
|
-> typename std::enable_if<not std::is_same<column_t, typename std::decay<T>::type>::value,
|
||||||
assignment_t<column_t, typename _value_type::template _constraint<T>::type>>::type
|
vendor::assignment_t<column_t, typename _value_type::template _constraint<T>::type>>::type
|
||||||
{
|
{
|
||||||
return { *this, std::forward<T>(t) };
|
return { *this, {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
#endif
|
||||||
|
@ -32,14 +32,14 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct count_t: public integral::template operators<count_t<Expr>>
|
struct count_t: public sqlpp::detail::integral::template operators<count_t<Expr>>
|
||||||
{
|
{
|
||||||
static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument");
|
static_assert(is_value_t<Expr>::value, "count() requires a sql value as argument");
|
||||||
|
|
||||||
struct _value_type: public integral
|
struct _value_type: public sqlpp::detail::integral
|
||||||
{
|
{
|
||||||
using _is_named_expression = std::true_type;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
@ -70,26 +70,33 @@ namespace sqlpp
|
|||||||
count_t& operator=(count_t&&) = default;
|
count_t& operator=(count_t&&) = default;
|
||||||
~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;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto count(T&& t) -> typename detail::count_t<typename operand_t<T, is_value_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::count_t<typename operand_t<T, is_value_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
#ifndef SQLPP_EXISTS_H
|
||||||
#define SQLPP_EXISTS_H
|
#define SQLPP_EXISTS_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/boolean.h>
|
#include <sqlpp11/boolean.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Select>
|
template<typename Select>
|
||||||
struct exists_t: public boolean::template operators<exists_t<Select>>
|
struct exists_t: public boolean::template operators<exists_t<Select>>
|
||||||
@ -70,26 +69,34 @@ namespace sqlpp
|
|||||||
exists_t& operator=(exists_t&&) = default;
|
exists_t& operator=(exists_t&&) = default;
|
||||||
~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;
|
Select _select;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto exists(T&& t) -> typename detail::exists_t<typename operand_t<T, is_select_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::exists_t<typename operand_t<T, is_select_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
#define SQLPP_FLOATING_POINT_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/char_result_row.h> // FIXME: Need to update floating_point
|
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -52,27 +51,20 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _value_type = integral;
|
using _value_type = integral;
|
||||||
|
|
||||||
_parameter_t(const std::true_type&):
|
_parameter_t():
|
||||||
_trivial_value_is_null(true),
|
|
||||||
_value(0),
|
_value(0),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(true)
|
||||||
{}
|
|
||||||
|
|
||||||
_parameter_t(const std::false_type&):
|
|
||||||
_trivial_value_is_null(false),
|
|
||||||
_value(0),
|
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t(const _cpp_value_type& value):
|
_parameter_t(const _cpp_value_type& value):
|
||||||
_value(value),
|
_value(value),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t& operator=(const _cpp_value_type& value)
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
_is_null = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,14 +75,6 @@ namespace sqlpp
|
|||||||
return *this;
|
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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
return _is_null;
|
return _is_null;
|
||||||
@ -110,7 +94,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _trivial_value_is_null;
|
|
||||||
_cpp_value_type _value;
|
_cpp_value_type _value;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
@ -150,14 +133,6 @@ namespace sqlpp
|
|||||||
_value = 0;
|
_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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
@ -186,30 +161,6 @@ namespace sqlpp
|
|||||||
_cpp_value_type _value;
|
_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>
|
template<typename T>
|
||||||
using _constraint = operand_t<T, is_numeric_t>;
|
using _constraint = operand_t<T, is_numeric_t>;
|
||||||
|
|
||||||
@ -217,33 +168,45 @@ namespace sqlpp
|
|||||||
struct operators: public basic_operators<Base, _constraint>
|
struct operators: public basic_operators<Base, _constraint>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, plus_, typename _constraint<T>::type> operator +(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, minus_, typename _constraint<T>::type> operator -(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, multiplies_, typename _constraint<T>::type> operator *(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
|
vendor::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");
|
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>
|
template<typename T>
|
||||||
auto operator +=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() + std::forward<T>(t))
|
auto operator +=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() + std::forward<T>(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
|
#ifndef SQLPP_FUNCTIONS_H
|
||||||
#define SQLPP_FUNCTIONS_H
|
#define SQLPP_FUNCTIONS_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/parameter.h>
|
#include <sqlpp11/parameter.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/column_types.h>
|
#include <sqlpp11/column_types.h>
|
||||||
|
#include <sqlpp11/vendor/in.h>
|
||||||
|
#include <sqlpp11/vendor/is_null.h>
|
||||||
#include <sqlpp11/exists.h>
|
#include <sqlpp11/exists.h>
|
||||||
#include <sqlpp11/any.h>
|
#include <sqlpp11/any.h>
|
||||||
#include <sqlpp11/some.h>
|
#include <sqlpp11/some.h>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
#include <sqlpp11/max.h>
|
#include <sqlpp11/max.h>
|
||||||
#include <sqlpp11/avg.h>
|
#include <sqlpp11/avg.h>
|
||||||
#include <sqlpp11/sum.h>
|
#include <sqlpp11/sum.h>
|
||||||
#include <sqlpp11/verbatim_table.h>
|
#include <sqlpp11/verbatim_table.h> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -51,17 +51,11 @@ namespace sqlpp
|
|||||||
return { std::forward<T>(t) };
|
return { std::forward<T>(t) };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||||
struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>>
|
struct verbatim_t: public ValueType::template operators<verbatim_t<ValueType>>
|
||||||
{
|
{
|
||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
void serialize(std::ostream& os, const Db& db) const
|
|
||||||
{
|
|
||||||
os << _verbatim;
|
|
||||||
}
|
|
||||||
|
|
||||||
verbatim_t(const std::string& verbatim): _verbatim(verbatim) {}
|
verbatim_t(const std::string& verbatim): _verbatim(verbatim) {}
|
||||||
verbatim_t(std::string&& verbatim): _verbatim(std::forward<std::string>(verbatim)) {}
|
verbatim_t(std::string&& verbatim): _verbatim(std::forward<std::string>(verbatim)) {}
|
||||||
verbatim_t(const verbatim_t&) = default;
|
verbatim_t(const verbatim_t&) = default;
|
||||||
@ -73,52 +67,76 @@ namespace sqlpp
|
|||||||
std::string _verbatim;
|
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>
|
template<typename ValueType, typename StringType>
|
||||||
auto verbatim(StringType&& s) -> verbatim_t<ValueType>
|
auto verbatim(StringType&& s) -> verbatim_t<ValueType>
|
||||||
{
|
{
|
||||||
return { std::forward<StringType>(s) };
|
return { std::forward<StringType>(s) };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Expression, typename Db>
|
template<typename Expression, typename Context>
|
||||||
auto flatten(const Expression& exp, const Db& db) -> verbatim_t<typename std::decay<Expression>::type::_value_type::_base_value_type>
|
auto flatten(const Expression& exp, const Context& context) -> verbatim_t<typename std::decay<Expression>::type::_value_type::_base_value_type>
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
static_assert(not make_parameter_list_t<Expression>::type::size::value, "parameters not supported in flattened expressions");
|
||||||
exp.serialize(os, db);
|
context.clear();
|
||||||
return { os.str() };
|
interpret(exp, context);
|
||||||
|
return { context.str() };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
struct value_list_t // to be used in .in() method
|
struct value_list_t // to be used in .in() method
|
||||||
{
|
{
|
||||||
using _container_t = Container;
|
using _container_t = Container;
|
||||||
using _value_type = typename operand_t<typename _container_t::value_type, is_value_t>::type::_value_type;
|
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
|
|
||||||
{
|
|
||||||
bool first = true;
|
|
||||||
for (const auto& entry: _container)
|
|
||||||
{
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
os << ',';
|
|
||||||
|
|
||||||
value(entry).serialize(os, db);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_container_t _container;
|
_container_t _container;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Container>
|
namespace vendor
|
||||||
auto value_list(Container&& c) -> value_list_t<typename std::decay<Container>::type>
|
|
||||||
{
|
{
|
||||||
static_assert(not is_value_t<typename std::decay<Container>::type::value_type>::value, "value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
|
template<typename Context, typename Container>
|
||||||
return { std::forward<Container>(c) };
|
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: t._container)
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
context << ',';
|
||||||
|
|
||||||
|
interpret(value(entry), context);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
auto value_list(Container&& c) -> value_list_t<typename std::decay<Container>::type>
|
||||||
|
{
|
||||||
|
static_assert(not is_value_t<typename std::decay<Container>::type::value_type>::value, "value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
|
||||||
|
return { std::forward<Container>(c) };
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr const char* get_sql_name(const T&)
|
constexpr const char* get_sql_name(const T&)
|
||||||
{
|
{
|
||||||
|
@ -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
|
#ifndef SQLPP_INSERT_H
|
||||||
#define SQLPP_INSERT_H
|
#define SQLPP_INSERT_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/noop.h>
|
|
||||||
#include <sqlpp11/select_fwd.h>
|
|
||||||
#include <sqlpp11/insert_list.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
|
||||||
#include <sqlpp11/prepared_insert.h>
|
#include <sqlpp11/prepared_insert.h>
|
||||||
|
#include <sqlpp11/vendor/noop.h>
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/vendor/insert_list.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<
|
|
||||||
typename Database = void,
|
|
||||||
typename Table = noop,
|
|
||||||
typename InsertList = noop
|
|
||||||
>
|
|
||||||
struct insert_t;
|
|
||||||
|
|
||||||
template<
|
template<
|
||||||
typename Database,
|
typename Database = void,
|
||||||
typename Table,
|
typename Table = vendor::noop,
|
||||||
typename InsertList
|
typename InsertList = vendor::noop
|
||||||
>
|
>
|
||||||
struct insert_t
|
struct insert_t
|
||||||
{
|
{
|
||||||
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||||
static_assert(is_noop<InsertList>::value or is_insert_list_t<InsertList>::value, "invalid 'InsertList' argument");
|
static_assert(vendor::is_noop<InsertList>::value or is_insert_list_t<InsertList>::value, "invalid 'InsertList' argument");
|
||||||
|
|
||||||
template<typename AssignmentT>
|
template<typename AssignmentT>
|
||||||
using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
|
using set_insert_list_t = insert_t<Database, Table, AssignmentT>;
|
||||||
|
using use_default_values_t = insert_t<Database, Table, vendor::insert_default_values_t>;
|
||||||
|
|
||||||
using _parameter_tuple_t = std::tuple<Table, InsertList>;
|
using _parameter_tuple_t = std::tuple<Table, InsertList>;
|
||||||
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
|
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
|
||||||
|
|
||||||
template<typename... Assignment>
|
auto default_values()
|
||||||
auto set(Assignment&&... assignment)
|
-> use_default_values_t
|
||||||
-> set_insert_list_t<insert_list_t<void, must_not_insert_t, 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 default_values() after set() or default_values()");
|
||||||
// FIXME: Need to check if all required columns are set
|
// FIXME: Need to check if all required columns are set
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
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>
|
template<typename... Assignment>
|
||||||
auto dynamic_set(Assignment&&... 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 {
|
return {
|
||||||
_table,
|
_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;
|
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()
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
{
|
{
|
||||||
return _parameter_list_t::size::value;
|
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
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
}
|
}
|
||||||
@ -131,7 +110,8 @@ namespace sqlpp
|
|||||||
template<typename Db>
|
template<typename Db>
|
||||||
std::size_t run(Db& db) const
|
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;
|
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
||||||
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
||||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||||
@ -139,29 +119,37 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db) const
|
||||||
-> prepared_insert_t<typename std::decay<Db>::type, insert_t>
|
-> prepared_insert_t<typename std::decay<Db>::type, insert_t>
|
||||||
{
|
{
|
||||||
constexpr bool calledSet = not is_noop<InsertList>::value;
|
constexpr bool calledSet = not vendor::is_noop<InsertList>::value;
|
||||||
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
constexpr bool requireSet = Table::_required_insert_columns::size::value > 0;
|
||||||
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
static_assert(calledSet or not requireSet, "calling set() required for given table");
|
||||||
|
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, db.prepare_insert(*this)};
|
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;
|
Table _table;
|
||||||
InsertList _insert_list;
|
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>
|
template<typename Table>
|
||||||
insert_t<void, typename std::decay<Table>::type> insert_into(Table&& 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
|
#define SQLPP_INTEGRAL_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
|
#include <sqlpp11/vendor/value_type.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -51,27 +52,20 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _value_type = integral;
|
using _value_type = integral;
|
||||||
|
|
||||||
_parameter_t(const std::true_type&):
|
_parameter_t():
|
||||||
_trivial_value_is_null(true),
|
|
||||||
_value(0),
|
_value(0),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(true)
|
||||||
{}
|
|
||||||
|
|
||||||
_parameter_t(const std::false_type&):
|
|
||||||
_trivial_value_is_null(false),
|
|
||||||
_value(0),
|
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit _parameter_t(const _cpp_value_type& value):
|
explicit _parameter_t(const _cpp_value_type& value):
|
||||||
_value(value),
|
_value(value),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t& operator=(const _cpp_value_type& value)
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
_is_null = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,14 +75,6 @@ namespace sqlpp
|
|||||||
_is_null = true;
|
_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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
return _is_null;
|
return _is_null;
|
||||||
@ -108,7 +94,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _trivial_value_is_null;
|
|
||||||
_cpp_value_type _value;
|
_cpp_value_type _value;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
@ -148,14 +133,6 @@ namespace sqlpp
|
|||||||
_is_valid = true;
|
_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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
if (not _is_valid)
|
if (not _is_valid)
|
||||||
@ -184,33 +161,6 @@ namespace sqlpp
|
|||||||
_cpp_value_type _value;
|
_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>
|
template<typename T>
|
||||||
using _constraint = operand_t<T, is_numeric_t>;
|
using _constraint = operand_t<T, is_numeric_t>;
|
||||||
|
|
||||||
@ -218,33 +168,52 @@ namespace sqlpp
|
|||||||
struct operators: public basic_operators<Base, _constraint>
|
struct operators: public basic_operators<Base, _constraint>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, plus_<T>, typename _constraint<T>::type> operator +(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, minus_<T>, typename _constraint<T>::type> operator -(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, multiplies_<T>, typename _constraint<T>::type> operator *(T&& t) const
|
vendor::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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
binary_expression_t<Base, divides_, typename _constraint<T>::type> operator /(T&& t) const
|
vendor::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");
|
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>
|
template<typename T>
|
||||||
auto operator +=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() + std::forward<T>(t))
|
auto operator +=(T&& t) const -> decltype(std::declval<Base>() = std::declval<Base>() + std::forward<T>(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/type_traits.h>
|
||||||
#include <sqlpp11/on.h>
|
#include <sqlpp11/on.h>
|
||||||
|
#include <sqlpp11/vendor/noop.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -73,84 +74,94 @@ namespace sqlpp
|
|||||||
static constexpr const char* _name = " RIGHT OUTER ";
|
static constexpr const char* _name = " RIGHT OUTER ";
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename JoinType, typename Lhs, typename Rhs, typename On = noop>
|
template<typename JoinType, typename Lhs, typename Rhs, typename On = vendor::noop>
|
||||||
struct join_t
|
struct join_t
|
||||||
|
{
|
||||||
|
static_assert(is_table_t<Lhs>::value, "invalid lhs argument for join()");
|
||||||
|
static_assert(is_table_t<Rhs>::value, "invalid rhs argument for join()");
|
||||||
|
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");
|
||||||
|
|
||||||
|
using _is_table = std::true_type;
|
||||||
|
using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type;
|
||||||
|
|
||||||
|
template<typename OnT>
|
||||||
|
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
|
||||||
|
|
||||||
|
template<typename... Expr>
|
||||||
|
auto on(Expr&&... expr)
|
||||||
|
-> set_on_t<on_t<void, typename std::decay<Expr>::type...>>
|
||||||
|
{
|
||||||
|
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)...}}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
join_t<inner_join_t, join_t, typename std::decay<T>::type> join(T&& t)
|
||||||
|
{
|
||||||
|
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 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 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 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 vendor::is_noop<On>::value, "join type requires on()");
|
||||||
|
return { *this, std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
static_assert(is_table_t<Lhs>::value, "invalid lhs argument for join()");
|
template<typename Context, typename JoinType, typename Lhs, typename Rhs, typename On>
|
||||||
static_assert(is_table_t<Rhs>::value, "invalid rhs argument for join()");
|
struct interpreter_t<Context, join_t<JoinType, Lhs, Rhs, On>>
|
||||||
static_assert(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");
|
|
||||||
|
|
||||||
using _is_table = std::true_type;
|
|
||||||
using _table_set = typename Lhs::_table_set::template join<typename Rhs::_table_set>::type;
|
|
||||||
|
|
||||||
template<typename OnT>
|
|
||||||
using set_on_t = join_t<JoinType, Lhs, Rhs, OnT>;
|
|
||||||
|
|
||||||
template<typename... Expr>
|
|
||||||
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()");
|
using T = join_t<JoinType, Lhs, Rhs, On>;
|
||||||
return { _lhs,
|
|
||||||
_rhs,
|
|
||||||
{std::tuple<typename std::decay<Expr>::type...>{std::forward<Expr>(expr)...}}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
static Context& _(const T& t, Context& context)
|
||||||
join_t<inner_join_t, join_t, typename std::decay<T>::type> join(T&& t)
|
{
|
||||||
{
|
static_assert(not vendor::is_noop<On>::value, "joined tables require on()");
|
||||||
static_assert(not is_noop<On>::value, "join type requires on()");
|
interpret(t._lhs, context);
|
||||||
return { *this, std::forward<T>(t) };
|
context << JoinType::_name;
|
||||||
}
|
context << " JOIN ";
|
||||||
|
context << "(";
|
||||||
|
interpret(t._rhs, context);
|
||||||
|
interpret(t._on, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
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()");
|
|
||||||
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()");
|
|
||||||
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()");
|
|
||||||
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()");
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct max_t: public boolean::template operators<max_t<Expr>>
|
struct max_t: public boolean::template operators<max_t<Expr>>
|
||||||
@ -70,26 +70,33 @@ namespace sqlpp
|
|||||||
max_t& operator=(max_t&&) = default;
|
max_t& operator=(max_t&&) = default;
|
||||||
~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;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto max(T&& t) -> typename detail::max_t<typename operand_t<T, is_value_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::max_t<typename operand_t<T, is_value_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct min_t: public boolean::template operators<min_t<Expr>>
|
struct min_t: public boolean::template operators<min_t<Expr>>
|
||||||
@ -70,26 +70,33 @@ namespace sqlpp
|
|||||||
min_t& operator=(min_t&&) = default;
|
min_t& operator=(min_t&&) = default;
|
||||||
~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;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto min(T&& t) -> typename detail::min_t<typename operand_t<T, is_value_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::min_t<typename operand_t<T, is_value_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,20 +52,29 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
using _is_multi_column = std::true_type;
|
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;
|
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
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename AliasProvider, typename... Expr>
|
template<typename AliasProvider, typename... Expr>
|
||||||
using make_multi_column_t =
|
using make_multi_column_t =
|
||||||
multi_column_t<typename std::decay<AliasProvider>::type, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
multi_column_t<typename std::decay<AliasProvider>::type, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename AliasProvider, typename... NamedExpr>
|
template<typename AliasProvider, typename... NamedExpr>
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
// boolean value type
|
|
||||||
struct no_value_t
|
struct no_value_t
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -27,10 +27,9 @@
|
|||||||
#ifndef SQLPP_ON_H
|
#ifndef SQLPP_ON_H
|
||||||
#define SQLPP_ON_H
|
#define SQLPP_ON_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <sqlpp11/detail/serializable_list.h>
|
#include <sqlpp11/vendor/interpretable_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -51,20 +50,31 @@ namespace sqlpp
|
|||||||
_dynamic_expressions.emplace_back(std::forward<E>(expr));
|
_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;
|
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
|
#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
|
#ifndef SQLPP_PARAMETER_H
|
||||||
#define SQLPP_PARAMETER_H
|
#define SQLPP_PARAMETER_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/select_fwd.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename ValueType, typename NameType, typename TrivialValueIsNull>
|
template<typename ValueType, typename NameType>
|
||||||
struct parameter_t
|
struct parameter_t: public ValueType::template operators<parameter_t<ValueType, NameType>>
|
||||||
{
|
{
|
||||||
using _value_type = ValueType;
|
using _value_type = ValueType;
|
||||||
using _is_parameter = std::true_type;
|
using _is_parameter = std::true_type;
|
||||||
using _is_expression_t = 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 _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>
|
parameter_t(const parameter_t&) = default;
|
||||||
void serialize(std::ostream& os, Db& db) const
|
parameter_t(parameter_t&&) = default;
|
||||||
{
|
parameter_t& operator=(const parameter_t&) = default;
|
||||||
static_assert(Db::_supports_prepared, "prepared statements not supported by current database");
|
parameter_t& operator=(parameter_t&&) = default;
|
||||||
static_assert(Db::_use_questionmark_parameter or Db::_use_positional_dollar_parameter, "no known way to serialize parameter placeholders for current database");
|
~parameter_t() = default;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename NamedExpr, typename TrivialValueIsNull = trivial_value_is_null_t<typename std::decay<NamedExpr>::type>>
|
namespace vendor
|
||||||
auto parameter(NamedExpr&& namedExpr)
|
{
|
||||||
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, TrivialValueIsNull>
|
template<typename Context, typename ValueType, typename NameType>
|
||||||
{
|
struct interpreter_t<Context, parameter_t<ValueType, NameType>>
|
||||||
return {};
|
{
|
||||||
}
|
using T = parameter_t<ValueType, NameType>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "?";
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename NamedExpr>
|
template<typename NamedExpr>
|
||||||
auto where_parameter(NamedExpr&& namedExpr)
|
auto parameter(NamedExpr&& namedExpr)
|
||||||
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type, std::false_type>
|
-> parameter_t<typename std::decay<NamedExpr>::type::_value_type, typename std::decay<NamedExpr>::type>
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -32,25 +32,6 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template<typename... T>
|
|
||||||
struct or_t;
|
|
||||||
|
|
||||||
template<typename T, typename... Rest>
|
|
||||||
struct or_t<T, Rest...>
|
|
||||||
{
|
|
||||||
static constexpr bool value = T::value or or_t<Rest...>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct or_t<>
|
|
||||||
{
|
|
||||||
static constexpr bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct parameter_list_t
|
struct parameter_list_t
|
||||||
{
|
{
|
||||||
@ -62,10 +43,8 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
using _member_tuple_t = std::tuple<typename Parameter::_instance_t...>;
|
||||||
using size = std::integral_constant<std::size_t, sizeof...(Parameter)>;
|
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_list_t()
|
||||||
Parameter::_instance_t({typename Parameter::_trivial_value_is_null_t()})...
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<typename Target>
|
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>;
|
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
|
#endif
|
||||||
|
@ -27,21 +27,20 @@
|
|||||||
#ifndef SQLPP_REMOVE_H
|
#ifndef SQLPP_REMOVE_H
|
||||||
#define SQLPP_REMOVE_H
|
#define SQLPP_REMOVE_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/noop.h>
|
|
||||||
#include <sqlpp11/using.h>
|
|
||||||
#include <sqlpp11/where.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_remove.h>
|
#include <sqlpp11/prepared_remove.h>
|
||||||
|
#include <sqlpp11/vendor/noop.h>
|
||||||
|
#include <sqlpp11/vendor/using.h>
|
||||||
|
#include <sqlpp11/vendor/where.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<
|
template<
|
||||||
typename Database,
|
typename Database,
|
||||||
typename Table,
|
typename Table,
|
||||||
typename Using = noop,
|
typename Using = vendor::noop,
|
||||||
typename Where = noop
|
typename Where = vendor::noop
|
||||||
>
|
>
|
||||||
struct remove_t;
|
struct remove_t;
|
||||||
|
|
||||||
@ -53,9 +52,12 @@ namespace sqlpp
|
|||||||
>
|
>
|
||||||
struct remove_t
|
struct remove_t
|
||||||
{
|
{
|
||||||
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||||
static_assert(is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument");
|
static_assert(vendor::is_noop<Using>::value or is_using_t<Using>::value, "invalid 'Using' argument");
|
||||||
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: We might want to have everywhere() or all() to indicate that everything is to be removed, same with update and select
|
||||||
|
|
||||||
template<typename UsingT>
|
template<typename UsingT>
|
||||||
using set_using_t = remove_t<Database, Table, UsingT, Where>;
|
using set_using_t = remove_t<Database, Table, UsingT, Where>;
|
||||||
@ -67,10 +69,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Tab>
|
template<typename... Tab>
|
||||||
auto using_(Tab&&... tab)
|
auto using_(Tab&&... tab)
|
||||||
-> set_using_t<using_t<void, typename std::decay<Tab>::type...>>
|
-> set_using_t<vendor::using_t<void, typename std::decay<Tab>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice");
|
static_assert(vendor::is_noop<Using>::value, "cannot call using() twice");
|
||||||
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()");
|
static_assert(vendor::is_noop<Where>::value, "cannot call using() after where()");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
|
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
|
||||||
@ -80,10 +82,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Tab>
|
template<typename... Tab>
|
||||||
auto dynamic_using_(Tab&&... tab)
|
auto dynamic_using_(Tab&&... tab)
|
||||||
-> set_using_t<using_t<Database, typename std::decay<Tab>::type...>>
|
-> set_using_t<vendor::using_t<Database, typename std::decay<Tab>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<Using, noop>::value, "cannot call using() twice");
|
static_assert(vendor::is_noop<Using>::value, "cannot call using() twice");
|
||||||
static_assert(std::is_same<Where, noop>::value, "cannot call using() after where()");
|
static_assert(vendor::is_noop<Where>::value, "cannot call using() after where()");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
|
{std::tuple<typename std::decay<Tab>::type...>{std::forward<Tab>(tab)...}},
|
||||||
@ -102,9 +104,9 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto where(Expr&&... expr)
|
auto where(Expr&&... expr)
|
||||||
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>>
|
-> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
_using,
|
_using,
|
||||||
@ -114,9 +116,9 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto dynamic_where(Expr&&... expr)
|
auto dynamic_where(Expr&&... expr)
|
||||||
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>>
|
-> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
_using,
|
_using,
|
||||||
@ -134,30 +136,12 @@ namespace sqlpp
|
|||||||
return *this;
|
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()
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
{
|
{
|
||||||
return _parameter_list_t::size::value;
|
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
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
}
|
}
|
||||||
@ -170,27 +154,35 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db) const
|
||||||
-> prepared_remove_t<typename std::decay<Db>::type, remove_t>
|
-> prepared_remove_t<typename std::decay<Db>::type, remove_t>
|
||||||
{
|
{
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, db.prepare_remove(*this)};
|
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;
|
Table _table;
|
||||||
Using _using;
|
Using _using;
|
||||||
Where _where;
|
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>
|
template<typename Table>
|
||||||
constexpr remove_t<void, typename std::decay<Table>::type> remove_from(Table&& table)
|
constexpr remove_t<void, typename std::decay<Table>::type> remove_from(Table&& table)
|
||||||
{
|
{
|
||||||
|
@ -27,10 +27,9 @@
|
|||||||
#ifndef SQLPP_RESULT_ROW_H
|
#ifndef SQLPP_RESULT_ROW_H
|
||||||
#define SQLPP_RESULT_ROW_H
|
#define SQLPP_RESULT_ROW_H
|
||||||
|
|
||||||
#include <sqlpp11/char_result_row.h>
|
#include <sqlpp11/vendor/char_result_row.h>
|
||||||
#include <sqlpp11/field.h>
|
#include <sqlpp11/vendor/field.h>
|
||||||
#include <sqlpp11/text.h>
|
#include <sqlpp11/text.h>
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -87,7 +86,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
template<size_t level, size_t index, typename AliasProvider, typename... Col, typename... Rest>
|
||||||
struct result_row_impl<level, index, multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
struct result_row_impl<level, index, vendor::multi_field_t<AliasProvider, std::tuple<Col...>>, Rest...>:
|
||||||
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
public AliasProvider::_name_t::template _member_t<result_row_impl<level, index, Col...>>, // level prevents identical closures to be present twice in the inheritance tree
|
||||||
public result_row_impl<level, index + sizeof...(Col), Rest...>
|
public result_row_impl<level, index + sizeof...(Col), Rest...>
|
||||||
{
|
{
|
||||||
|
@ -29,20 +29,22 @@
|
|||||||
|
|
||||||
#include <sqlpp11/result.h>
|
#include <sqlpp11/result.h>
|
||||||
#include <sqlpp11/select_fwd.h>
|
#include <sqlpp11/select_fwd.h>
|
||||||
#include <sqlpp11/noop.h>
|
|
||||||
#include <sqlpp11/select_flag_list.h>
|
|
||||||
#include <sqlpp11/select_expression_list.h>
|
|
||||||
#include <sqlpp11/from.h>
|
|
||||||
#include <sqlpp11/where.h>
|
|
||||||
#include <sqlpp11/group_by.h>
|
|
||||||
#include <sqlpp11/having.h>
|
|
||||||
#include <sqlpp11/order_by.h>
|
|
||||||
#include <sqlpp11/limit.h>
|
|
||||||
#include <sqlpp11/offset.h>
|
|
||||||
#include <sqlpp11/expression.h>
|
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_select.h>
|
#include <sqlpp11/prepared_select.h>
|
||||||
|
|
||||||
|
#include <sqlpp11/vendor/noop.h>
|
||||||
|
#include <sqlpp11/vendor/select_flag_list.h>
|
||||||
|
#include <sqlpp11/vendor/select_expression_list.h>
|
||||||
|
#include <sqlpp11/vendor/from.h>
|
||||||
|
#include <sqlpp11/vendor/where.h>
|
||||||
|
#include <sqlpp11/vendor/group_by.h>
|
||||||
|
#include <sqlpp11/vendor/having.h>
|
||||||
|
#include <sqlpp11/vendor/order_by.h>
|
||||||
|
#include <sqlpp11/vendor/limit.h>
|
||||||
|
#include <sqlpp11/vendor/offset.h>
|
||||||
|
#include <sqlpp11/vendor/expression.h>
|
||||||
|
#include <sqlpp11/vendor/interpreter.h>
|
||||||
|
|
||||||
#include <sqlpp11/detail/wrong.h>
|
#include <sqlpp11/detail/wrong.h>
|
||||||
#include <sqlpp11/detail/make_flag_tuple.h>
|
#include <sqlpp11/detail/make_flag_tuple.h>
|
||||||
#include <sqlpp11/detail/make_expression_tuple.h>
|
#include <sqlpp11/detail/make_expression_tuple.h>
|
||||||
@ -79,15 +81,15 @@ namespace sqlpp
|
|||||||
using _Database = Database;
|
using _Database = Database;
|
||||||
using _From = From;
|
using _From = From;
|
||||||
|
|
||||||
static_assert(is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
|
static_assert(vendor::is_noop<Flags>::value or is_select_flag_list_t<Flags>::value, "invalid list of select flags");
|
||||||
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
|
static_assert(is_select_expression_list_t<ExpressionList>::value, "invalid list of select expressions");
|
||||||
static_assert(is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
|
static_assert(vendor::is_noop<From>::value or is_from_t<From>::value, "invalid 'from' argument");
|
||||||
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
|
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'where' argument");
|
||||||
static_assert(is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
|
static_assert(vendor::is_noop<GroupBy>::value or is_group_by_t<GroupBy>::value, "invalid 'group by' arguments");
|
||||||
static_assert(is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
|
static_assert(vendor::is_noop<Having>::value or is_having_t<Having>::value, "invalid 'having' arguments");
|
||||||
static_assert(is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
|
static_assert(vendor::is_noop<OrderBy>::value or is_order_by_t<OrderBy>::value, "invalid 'order by' arguments");
|
||||||
static_assert(is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
|
static_assert(vendor::is_noop<Limit>::value or is_limit_t<Limit>::value, "invalid 'limit' arguments");
|
||||||
static_assert(is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
|
static_assert(vendor::is_noop<Offset>::value or is_offset_t<Offset>::value, "invalid 'offset' arguments");
|
||||||
|
|
||||||
using _is_select = std::true_type;
|
using _is_select = std::true_type;
|
||||||
using _requires_braces = std::true_type;
|
using _requires_braces = std::true_type;
|
||||||
@ -116,7 +118,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
// Indicators
|
// Indicators
|
||||||
using _value_type = typename std::conditional<
|
using _value_type = typename std::conditional<
|
||||||
is_noop<From>::value,
|
vendor::is_noop<From>::value,
|
||||||
no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing)
|
no_value_t, // If there is no from, the select is not complete (this logic is a bit simple, but better than nothing)
|
||||||
typename ExpressionList::_value_type>::type;
|
typename ExpressionList::_value_type>::type;
|
||||||
|
|
||||||
@ -173,7 +175,7 @@ namespace sqlpp
|
|||||||
-> set_expression_list_t<typename ExpressionList::template _dynamic_t<Database>>
|
-> set_expression_list_t<typename ExpressionList::template _dynamic_t<Database>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
||||||
static_assert(is_noop<From>::value, "cannot call dynamic_columns() after from()");
|
static_assert(vendor::is_noop<From>::value, "cannot call dynamic_columns() after from()");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
{_expression_list._expressions},
|
{_expression_list._expressions},
|
||||||
@ -200,10 +202,10 @@ namespace sqlpp
|
|||||||
// sqlpp functions
|
// sqlpp functions
|
||||||
template<typename... Table>
|
template<typename... Table>
|
||||||
auto from(Table&&... table)
|
auto from(Table&&... table)
|
||||||
-> set_from_t<from_t<void, typename std::decay<Table>::type...>>
|
-> set_from_t<vendor::from_t<void, typename std::decay<Table>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||||
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
static_assert(vendor::is_noop<From>::value, "cannot call from() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -219,11 +221,11 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Table>
|
template<typename... Table>
|
||||||
auto dynamic_from(Table&&... table)
|
auto dynamic_from(Table&&... table)
|
||||||
-> set_from_t<from_t<Database, typename std::decay<Table>::type...>>
|
-> set_from_t<vendor::from_t<Database, typename std::decay<Table>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
static_assert(not std::is_same<Database, void>::value, "cannot call dynamic_from() in a non-dynamic select");
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call from() without having selected anything");
|
||||||
static_assert(is_noop<From>::value, "cannot call from() twice for a single select");
|
static_assert(vendor::is_noop<From>::value, "cannot call from() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -240,7 +242,7 @@ namespace sqlpp
|
|||||||
template<typename Table>
|
template<typename Table>
|
||||||
select_t& add_from(Table&& table)
|
select_t& add_from(Table&& table)
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
|
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot call add_from() without having selected anything");
|
||||||
static_assert(is_dynamic_t<From>::value, "cannot call add_from() in a non-dynamic from");
|
static_assert(is_dynamic_t<From>::value, "cannot call add_from() in a non-dynamic from");
|
||||||
|
|
||||||
_from.add(std::forward<Table>(table));
|
_from.add(std::forward<Table>(table));
|
||||||
@ -250,10 +252,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto where(Expr&&... expr)
|
auto where(Expr&&... expr)
|
||||||
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>>
|
-> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call where() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call where() without a from()");
|
||||||
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
static_assert(vendor::is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -269,10 +271,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto dynamic_where(Expr&&... expr)
|
auto dynamic_where(Expr&&... expr)
|
||||||
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>>
|
-> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call dynamic_where() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call dynamic_where() without a from()");
|
||||||
static_assert(is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
static_assert(vendor::is_noop<Where>::value, "cannot call where() or dynamic_where() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -298,10 +300,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Col>
|
template<typename... Col>
|
||||||
auto group_by(Col&&... column)
|
auto group_by(Col&&... column)
|
||||||
-> set_group_by_t<group_by_t<void, typename std::decay<Col>::type...>>
|
-> set_group_by_t<vendor::group_by_t<void, typename std::decay<Col>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call group_by() without a from()");
|
||||||
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
static_assert(vendor::is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -317,10 +319,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Col>
|
template<typename... Col>
|
||||||
auto dynamic_group_by(Col&&... column)
|
auto dynamic_group_by(Col&&... column)
|
||||||
-> set_group_by_t<group_by_t<Database, typename std::decay<Col>::type...>>
|
-> set_group_by_t<vendor::group_by_t<Database, typename std::decay<Col>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call group_by() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call group_by() without a from()");
|
||||||
static_assert(is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
static_assert(vendor::is_noop<GroupBy>::value, "cannot call group_by() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -346,10 +348,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto having(Expr&&... expr)
|
auto having(Expr&&... expr)
|
||||||
-> set_having_t<having_t<void, typename std::decay<Expr>::type...>>
|
-> set_having_t<vendor::having_t<void, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
static_assert(not vendor::is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
||||||
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select");
|
static_assert(vendor::is_noop<Having>::value, "cannot call having() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -365,10 +367,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto dynamic_having(Expr&&... expr)
|
auto dynamic_having(Expr&&... expr)
|
||||||
-> set_having_t<having_t<Database, typename std::decay<Expr>::type...>>
|
-> set_having_t<vendor::having_t<Database, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
static_assert(not vendor::is_noop<GroupBy>::value, "cannot call having() without a group_by");
|
||||||
static_assert(is_noop<Having>::value, "cannot call having() twice for a single select");
|
static_assert(vendor::is_noop<Having>::value, "cannot call having() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -394,10 +396,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... OrderExpr>
|
template<typename... OrderExpr>
|
||||||
auto order_by(OrderExpr&&... expr)
|
auto order_by(OrderExpr&&... expr)
|
||||||
-> set_order_by_t<order_by_t<void, typename std::decay<OrderExpr>::type...>>
|
-> set_order_by_t<vendor::order_by_t<void, typename std::decay<OrderExpr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call order_by() without a from()");
|
||||||
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
static_assert(vendor::is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -413,10 +415,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... OrderExpr>
|
template<typename... OrderExpr>
|
||||||
auto dynamic_order_by(OrderExpr&&... expr)
|
auto dynamic_order_by(OrderExpr&&... expr)
|
||||||
-> set_order_by_t<order_by_t<Database, typename std::decay<OrderExpr>::type...>>
|
-> set_order_by_t<vendor::order_by_t<Database, typename std::decay<OrderExpr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call order_by() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call order_by() without a from()");
|
||||||
static_assert(is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
static_assert(vendor::is_noop<OrderBy>::value, "cannot call order_by() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -442,10 +444,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
auto limit(Expr limit)
|
auto limit(Expr limit)
|
||||||
-> set_limit_t<limit_t<typename 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(not vendor::is_noop<From>::value, "cannot call limit() without a from()");
|
||||||
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
static_assert(vendor::is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -460,10 +462,10 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dynamic_limit(std::size_t limit = 0)
|
auto dynamic_limit(std::size_t limit = 0)
|
||||||
->set_limit_t<dynamic_limit_t>
|
->set_limit_t<vendor::dynamic_limit_t>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<From>::value, "cannot call limit() without a from()");
|
static_assert(not vendor::is_noop<From>::value, "cannot call limit() without a from()");
|
||||||
static_assert(is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
static_assert(vendor::is_noop<Limit>::value, "cannot call limit() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -488,10 +490,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
auto offset(Expr offset)
|
auto offset(Expr offset)
|
||||||
-> set_offset_t<offset_t<typename 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(not vendor::is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||||
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
static_assert(vendor::is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -506,10 +508,10 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dynamic_offset(std::size_t offset = 0)
|
auto dynamic_offset(std::size_t offset = 0)
|
||||||
-> set_offset_t<dynamic_offset_t>
|
-> set_offset_t<vendor::dynamic_offset_t>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<Limit>::value, "cannot call offset() without a limit");
|
static_assert(not vendor::is_noop<Limit>::value, "cannot call offset() without a limit");
|
||||||
static_assert(is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
static_assert(vendor::is_noop<Offset>::value, "cannot call offset() twice for a single select");
|
||||||
return {
|
return {
|
||||||
_flags,
|
_flags,
|
||||||
_expression_list,
|
_expression_list,
|
||||||
@ -536,7 +538,7 @@ namespace sqlpp
|
|||||||
struct _pseudo_table_t
|
struct _pseudo_table_t
|
||||||
{
|
{
|
||||||
using table = typename ExpressionList::template _pseudo_table_t<select_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>
|
template<typename AliasProvider>
|
||||||
@ -546,32 +548,6 @@ namespace sqlpp
|
|||||||
*this).as(aliasProvider);
|
*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
|
const typename ExpressionList::_dynamic_names_t& get_dynamic_names() const
|
||||||
{
|
{
|
||||||
return _expression_list._dynamic_expressions._dynamic_expression_names;
|
return _expression_list._dynamic_expressions._dynamic_expression_names;
|
||||||
@ -582,7 +558,7 @@ namespace sqlpp
|
|||||||
return _parameter_list_t::size::value;
|
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
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
}
|
}
|
||||||
@ -597,7 +573,7 @@ namespace sqlpp
|
|||||||
auto run(Db& db) const
|
auto run(Db& db) const
|
||||||
-> result_t<decltype(db.select(*this)), _result_row_t>
|
-> result_t<decltype(db.select(*this)), _result_row_t>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
static_assert(not vendor::is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||||
// FIXME: Check for missing aliases (if references are used)
|
// FIXME: Check for missing aliases (if references are used)
|
||||||
@ -608,30 +584,17 @@ namespace sqlpp
|
|||||||
|
|
||||||
// Prepare
|
// Prepare
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db) const
|
||||||
-> prepared_select_t<typename std::decay<Db>::type, select_t>
|
-> 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()");
|
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||||
// FIXME: Check for missing aliases (if references are used)
|
// FIXME: Check for missing aliases (if references are used)
|
||||||
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||||
|
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
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;
|
Flags _flags;
|
||||||
ExpressionList _expression_list;
|
ExpressionList _expression_list;
|
||||||
From _from;
|
From _from;
|
||||||
@ -643,12 +606,68 @@ namespace sqlpp
|
|||||||
Offset _offset;
|
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
|
// construct select flag list
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
using make_select_flag_list_t =
|
using make_select_flag_list_t =
|
||||||
select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>;
|
vendor::select_flag_list_t<decltype(make_flag_tuple(std::declval<Expr>()...))>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct select expression list
|
// construct select expression list
|
||||||
@ -656,7 +675,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
using make_select_expression_list_t =
|
using make_select_expression_list_t =
|
||||||
select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
vendor::select_expression_list_t<void, decltype(make_expression_tuple(std::declval<Expr>()...))>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... NamedExpr>
|
template<typename... NamedExpr>
|
||||||
@ -665,7 +684,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
||||||
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
template<typename Db, typename... NamedExpr>
|
template<typename Db, typename... NamedExpr>
|
||||||
@ -674,7 +693,7 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
{ detail::make_flag_tuple(std::forward<NamedExpr>(namedExpr)...) },
|
||||||
{ detail::make_expression_tuple(std::forward<NamedExpr>(namedExpr)...) }
|
{ detail::make_expression_tuple(std::forward<NamedExpr>(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
|
#ifndef SQLPP_SELECT_FWD_H
|
||||||
#define SQLPP_SELECT_FWD_H
|
#define SQLPP_SELECT_FWD_H
|
||||||
|
|
||||||
#include <sqlpp11/noop_fwd.h>
|
// FIXME: Do we really need this file?
|
||||||
|
#include <sqlpp11/vendor/noop_fwd.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
@ -37,36 +38,17 @@ namespace sqlpp
|
|||||||
struct distinct_t;
|
struct distinct_t;
|
||||||
struct straight_join_t;
|
struct straight_join_t;
|
||||||
|
|
||||||
template<typename FlagTuple> struct select_flag_list_t;
|
|
||||||
template<typename Database, typename NamedExprTuple> struct select_expression_list_t;
|
|
||||||
|
|
||||||
template<typename Database, typename... TableOrJoin> struct from_t;
|
|
||||||
|
|
||||||
template<typename Database, typename... Expr> struct where_t;
|
|
||||||
|
|
||||||
template<typename Database, typename... Expr> struct group_by_t;
|
|
||||||
|
|
||||||
template<typename Database, typename... Expr> struct having_t;
|
|
||||||
|
|
||||||
template<typename Database, typename... Expr> struct order_by_t;
|
|
||||||
|
|
||||||
template<typename Limit>
|
|
||||||
struct limit_t;
|
|
||||||
|
|
||||||
template<typename Offset>
|
|
||||||
struct offset_t;
|
|
||||||
|
|
||||||
template<
|
template<
|
||||||
typename Db,
|
typename Db,
|
||||||
typename Flags = noop,
|
typename Flags = vendor::noop,
|
||||||
typename ExpressionList = noop,
|
typename ExpressionList = vendor::noop,
|
||||||
typename From = noop,
|
typename From = vendor::noop,
|
||||||
typename Where = noop,
|
typename Where = vendor::noop,
|
||||||
typename GroupBy = noop,
|
typename GroupBy = vendor::noop,
|
||||||
typename Having = noop,
|
typename Having = vendor::noop,
|
||||||
typename OrderBy = noop,
|
typename OrderBy = vendor::noop,
|
||||||
typename Limit = noop,
|
typename Limit = vendor::noop,
|
||||||
typename Offset = noop
|
typename Offset = vendor::noop
|
||||||
>
|
>
|
||||||
struct select_t;
|
struct select_t;
|
||||||
}
|
}
|
||||||
|
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 sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Select>
|
template<typename Select>
|
||||||
struct some_t: public boolean::template operators<some_t<Select>>
|
struct some_t: public boolean::template operators<some_t<Select>>
|
||||||
@ -71,26 +71,33 @@ namespace sqlpp
|
|||||||
some_t& operator=(some_t&&) = default;
|
some_t& operator=(some_t&&) = default;
|
||||||
~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;
|
Select _select;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto some(T&& t) -> typename detail::some_t<typename operand_t<T, is_select_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::some_t<typename operand_t<T, is_select_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,23 +40,33 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_sort_order = std::true_type;
|
using _is_sort_order = std::true_type;
|
||||||
|
|
||||||
template<typename Db>
|
Expression _expression;
|
||||||
void serialize(std::ostream& os, Db& db) const
|
};
|
||||||
|
|
||||||
|
namespace vendor
|
||||||
|
{
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
_expression.serialize(os, db);
|
interpret(t._expression, context);
|
||||||
switch(SortType)
|
switch(SortType)
|
||||||
{
|
{
|
||||||
case sort_type::asc:
|
case sort_type::asc:
|
||||||
os << " ASC";
|
context << " ASC";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
os << " DESC";
|
context << " DESC";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Expression _expression;
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#ifndef SQLPP_H
|
#ifndef SQLPP_H
|
||||||
#define SQLPP_H
|
#define SQLPP_H
|
||||||
|
|
||||||
|
#include <sqlpp11/alias_provider.h>
|
||||||
#include <sqlpp11/column_types.h>
|
#include <sqlpp11/column_types.h>
|
||||||
#include <sqlpp11/insert.h>
|
#include <sqlpp11/insert.h>
|
||||||
#include <sqlpp11/remove.h>
|
#include <sqlpp11/remove.h>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Expr>
|
template<typename Expr>
|
||||||
struct sum_t: public boolean::template operators<sum_t<Expr>>
|
struct sum_t: public boolean::template operators<sum_t<Expr>>
|
||||||
@ -70,26 +70,33 @@ namespace sqlpp
|
|||||||
sum_t& operator=(sum_t&&) = default;
|
sum_t& operator=(sum_t&&) = default;
|
||||||
~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;
|
Expr _expr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
namespace vendor
|
||||||
auto sum(T&& t) -> typename detail::sum_t<typename operand_t<T, is_value_t>::type>
|
|
||||||
{
|
{
|
||||||
return { std::forward<T>(t) };
|
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 vendor::sum_t<typename operand_t<T, is_value_t>::type>
|
||||||
|
{
|
||||||
|
return { std::forward<T>(t) };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,27 +24,30 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_TABLE_BASE_H
|
#ifndef SQLPP_TABLE_H
|
||||||
#define SQLPP_TABLE_BASE_H
|
#define SQLPP_TABLE_H
|
||||||
|
|
||||||
#include <ostream>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/alias.h>
|
#include <sqlpp11/table_alias.h>
|
||||||
#include <sqlpp11/no_value.h>
|
|
||||||
#include <sqlpp11/column.h>
|
#include <sqlpp11/column.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
|
||||||
#include <sqlpp11/join.h>
|
#include <sqlpp11/join.h>
|
||||||
|
#include <sqlpp11/no_value.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
|
struct table_base_t {};
|
||||||
|
|
||||||
template<typename Table, typename... ColumnSpec>
|
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 _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;
|
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");
|
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 _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>...>;
|
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;
|
using _is_table = std::true_type;
|
||||||
|
|
||||||
@ -79,50 +82,15 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename AliasProvider>
|
template<typename AliasProvider>
|
||||||
struct alias_t: public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
_alias_t<AliasProvider> as(const AliasProvider&) const
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
return {*static_cast<const Table*>(this)};
|
return {*static_cast<const Table*>(this)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
const Table& ref() const
|
||||||
void serialize(std::ostream& os, Db& db) const
|
{
|
||||||
{
|
return *static_cast<const Table*>(this);
|
||||||
static_cast<const Table*>(this)->serialize_impl(os, db);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
@ -131,6 +99,22 @@ namespace sqlpp
|
|||||||
return {};
|
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
|
#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
|
#define SQLPP_TEXT_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sqlpp11/detail/basic_operators.h>
|
#include <sqlpp11/basic_operators.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/exception.h>
|
#include <sqlpp11/exception.h>
|
||||||
#include <sqlpp11/concat.h>
|
#include <sqlpp11/vendor/concat.h>
|
||||||
#include <sqlpp11/like.h>
|
#include <sqlpp11/vendor/like.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -51,27 +51,20 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _value_type = integral;
|
using _value_type = integral;
|
||||||
|
|
||||||
_parameter_t(const std::true_type&):
|
_parameter_t():
|
||||||
_trivial_value_is_null(true),
|
|
||||||
_value(""),
|
_value(""),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(true)
|
||||||
{}
|
|
||||||
|
|
||||||
_parameter_t(const std::false_type&):
|
|
||||||
_trivial_value_is_null(false),
|
|
||||||
_value(""),
|
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t(const _cpp_value_type& value):
|
_parameter_t(const _cpp_value_type& value):
|
||||||
_value(value),
|
_value(value),
|
||||||
_is_null(_trivial_value_is_null and _is_trivial())
|
_is_null(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
_parameter_t& operator=(const _cpp_value_type& value)
|
_parameter_t& operator=(const _cpp_value_type& value)
|
||||||
{
|
{
|
||||||
_value = value;
|
_value = value;
|
||||||
_is_null = (_trivial_value_is_null and _is_trivial());
|
_is_null = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,14 +75,6 @@ namespace sqlpp
|
|||||||
return *this;
|
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
|
bool is_null() const
|
||||||
{
|
{
|
||||||
return _is_null;
|
return _is_null;
|
||||||
@ -109,7 +94,6 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _trivial_value_is_null;
|
|
||||||
_cpp_value_type _value;
|
_cpp_value_type _value;
|
||||||
bool _is_null;
|
bool _is_null;
|
||||||
};
|
};
|
||||||
@ -147,14 +131,6 @@ namespace sqlpp
|
|||||||
_len = 0;
|
_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 value() == rhs; }
|
||||||
bool operator!=(const _cpp_value_type& rhs) const { return not operator==(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>
|
struct operators: public basic_operators<Base, _constraint>
|
||||||
{
|
{
|
||||||
template<typename T>
|
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");
|
static_assert(not is_multi_expression_t<Base>::value, "multi-expression cannot be used as left hand side operand");
|
||||||
return { *static_cast<const Base*>(this), std::forward<T>(t) };
|
return { *static_cast<const Base*>(this), {std::forward<T>(t)} };
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
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");
|
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
|
#define SQLPP_TYPE_TRAITS_H
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sqlpp11/detail/wrap_operand.h>
|
#include <sqlpp11/vendor/wrap_operand.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -92,9 +92,9 @@ namespace sqlpp
|
|||||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update);
|
SQLPP_IS_COLUMN_TRAIT_GENERATOR(must_not_update);
|
||||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
SQLPP_IS_COLUMN_TRAIT_GENERATOR(require_insert);
|
||||||
SQLPP_IS_COLUMN_TRAIT_GENERATOR(can_be_null);
|
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_table);
|
||||||
|
SQLPP_TYPE_TRAIT_GENERATOR(is_pseudo_table);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_select);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_select_flag_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_select_expression_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_multi_column);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_value_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_value_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_assignment_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_update_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_insert_list);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
|
SQLPP_TYPE_TRAIT_GENERATOR(is_sort_order);
|
||||||
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
SQLPP_TYPE_TRAIT_GENERATOR(requires_braces);
|
||||||
@ -126,12 +126,11 @@ namespace sqlpp
|
|||||||
template<typename T, template<typename> class IsCorrectType>
|
template<typename T, template<typename> class IsCorrectType>
|
||||||
struct operand_t
|
struct operand_t
|
||||||
{
|
{
|
||||||
using type = typename 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(not is_alias_t<type>::value, "expression operand must not be an alias");
|
||||||
static_assert(is_expression_t<type>::value, "expression required");
|
static_assert(is_expression_t<type>::value, "expression required");
|
||||||
static_assert(IsCorrectType<type>::value, "invalid operand type");
|
static_assert(IsCorrectType<type>::value, "invalid operand type");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,21 +27,20 @@
|
|||||||
#ifndef SQLPP_UPDATE_H
|
#ifndef SQLPP_UPDATE_H
|
||||||
#define SQLPP_UPDATE_H
|
#define SQLPP_UPDATE_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/noop.h>
|
|
||||||
#include <sqlpp11/assignment_list.h>
|
|
||||||
#include <sqlpp11/where.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_update.h>
|
#include <sqlpp11/prepared_update.h>
|
||||||
|
#include <sqlpp11/vendor/update_list.h>
|
||||||
|
#include <sqlpp11/vendor/noop.h>
|
||||||
|
#include <sqlpp11/vendor/where.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<
|
template<
|
||||||
typename Database = void,
|
typename Database = void,
|
||||||
typename Table = noop,
|
typename Table = vendor::noop,
|
||||||
typename Assignments = noop,
|
typename Assignments = vendor::noop,
|
||||||
typename Where = noop
|
typename Where = vendor::noop
|
||||||
>
|
>
|
||||||
struct update_t;
|
struct update_t;
|
||||||
|
|
||||||
@ -53,23 +52,24 @@ namespace sqlpp
|
|||||||
>
|
>
|
||||||
struct update_t
|
struct update_t
|
||||||
{
|
{
|
||||||
static_assert(is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
static_assert(vendor::is_noop<Table>::value or is_table_t<Table>::value, "invalid 'Table' argument");
|
||||||
static_assert(is_noop<Assignments>::value or is_assignment_list_t<Assignments>::value, "invalid 'Assignments' arguments");
|
static_assert(vendor::is_noop<Assignments>::value or is_update_list_t<Assignments>::value, "invalid 'Assignments' arguments");
|
||||||
static_assert(is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
static_assert(vendor::is_noop<Where>::value or is_where_t<Where>::value, "invalid 'Where' argument");
|
||||||
|
|
||||||
template<typename AssignmentsT>
|
template<typename AssignmentsT>
|
||||||
using set_assignments_t = update_t<Database, Table, AssignmentsT, Where>;
|
using set_assignments_t = update_t<Database, Table, AssignmentsT, Where>;
|
||||||
template<typename WhereT>
|
template<typename WhereT>
|
||||||
using set_where_t = update_t<Database, Table, Assignments, 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_tuple_t = std::tuple<Table, Assignments, Where>;
|
||||||
using _parameter_list_t = typename make_parameter_list_t<update_t>::type;
|
using _parameter_list_t = typename make_parameter_list_t<update_t>::type;
|
||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto set(Assignment&&... 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 {
|
return {
|
||||||
_table,
|
_table,
|
||||||
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
|
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
|
||||||
@ -79,9 +79,9 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto dynamic_set(Assignment&&... assignment)
|
auto dynamic_set(Assignment&&... assignment)
|
||||||
-> set_assignments_t<assignment_list_t<Database, 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 {
|
return {
|
||||||
_table,
|
_table,
|
||||||
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
|
{std::tuple<typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...}},
|
||||||
@ -101,10 +101,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto where(Expr&&... expr)
|
auto where(Expr&&... expr)
|
||||||
-> set_where_t<where_t<void, typename std::decay<Expr>::type...>>
|
-> set_where_t<vendor::where_t<void, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet");
|
static_assert(not vendor::is_noop<Assignments>::value, "cannot call where() if set() hasn't been called yet");
|
||||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
_assignments,
|
_assignments,
|
||||||
@ -114,10 +114,10 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Expr>
|
template<typename... Expr>
|
||||||
auto dynamic_where(Expr&&... expr)
|
auto dynamic_where(Expr&&... expr)
|
||||||
-> set_where_t<where_t<Database, typename std::decay<Expr>::type...>>
|
-> set_where_t<vendor::where_t<Database, typename std::decay<Expr>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(not std::is_same<Assignments, noop>::value, "cannot call where() if set() hasn't been called yet");
|
static_assert(not vendor::is_noop<Assignments>::value, "cannot call where() if set() hasn't been called yet");
|
||||||
static_assert(std::is_same<Where, noop>::value, "cannot call where() twice");
|
static_assert(vendor::is_noop<Where>::value, "cannot call where() twice");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
_assignments,
|
_assignments,
|
||||||
@ -135,29 +135,12 @@ namespace sqlpp
|
|||||||
return *this;
|
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()
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
{
|
{
|
||||||
return _parameter_list_t::size::value;
|
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
|
return _parameter_list_t::size::value; // FIXME: Need to add dynamic parameters here
|
||||||
}
|
}
|
||||||
@ -165,33 +148,48 @@ namespace sqlpp
|
|||||||
template<typename Db>
|
template<typename Db>
|
||||||
std::size_t run(Db& db) const
|
std::size_t run(Db& db) const
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
static_assert(not vendor::is_noop<Assignments>::value, "calling set() required before running update");
|
||||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
||||||
return db.update(*this);
|
return db.update(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db) const
|
||||||
-> prepared_update_t<typename std::decay<Db>::type, update_t>
|
-> prepared_update_t<typename std::decay<Db>::type, update_t>
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
static_assert(not vendor::is_noop<Assignments>::value, "calling set() required before running update");
|
||||||
|
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, db.prepare_update(*this)};
|
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;
|
Table _table;
|
||||||
Assignments _assignments;
|
Assignments _assignments;
|
||||||
Where _where;
|
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>
|
template<typename Table>
|
||||||
constexpr update_t<void, typename std::decay<Table>::type> update(Table&& 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
|
#ifndef SQLPP_CONCAT_H
|
||||||
#define SQLPP_CONCAT_H
|
#define SQLPP_CONCAT_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename First, typename... Args>
|
template<typename First, typename... Args>
|
||||||
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
|
struct concat_t: public First::_value_type::template operators<concat_t<First, Args...>>
|
||||||
{
|
{
|
||||||
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
static_assert(sizeof...(Args) > 0, "concat requires two arguments at least");
|
||||||
using _valid_args = typename detail::make_set_if_not<is_text_t, First, Args...>::type;
|
using _valid_args = typename ::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()");
|
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
|
struct _value_type: public First::_value_type::_base_value_type
|
||||||
@ -57,11 +57,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
concat_t(First&& first, Args&&... args):
|
concat_t(First first, Args... args):
|
||||||
_args(std::move(first), std::move(args)...)
|
|
||||||
{}
|
|
||||||
|
|
||||||
concat_t(const First& first, const Args&... args):
|
|
||||||
_args(first, args...)
|
_args(first, args...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -71,35 +67,23 @@ namespace sqlpp
|
|||||||
concat_t& operator=(concat_t&&) = default;
|
concat_t& operator=(concat_t&&) = default;
|
||||||
~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;
|
std::tuple<First, Args...> _args;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... T>
|
template<typename Context, typename First, typename... Args>
|
||||||
auto concat(T&&... t) -> typename detail::concat_t<typename operand_t<T, is_text_t>::type...>
|
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
|
#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,41 +27,43 @@
|
|||||||
#ifndef SQLPP_FIELD_H
|
#ifndef SQLPP_FIELD_H
|
||||||
#define SQLPP_FIELD_H
|
#define SQLPP_FIELD_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/multi_column.h>
|
#include <sqlpp11/multi_column.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename NameType, typename ValueType>
|
namespace vendor
|
||||||
struct field_t
|
|
||||||
{
|
|
||||||
using _name_t = NameType;
|
|
||||||
using _value_type = ValueType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename AliasProvider, typename FieldTuple>
|
|
||||||
struct multi_field_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
{
|
||||||
|
template<typename NameType, typename ValueType>
|
||||||
|
struct field_t
|
||||||
|
{
|
||||||
|
using _name_t = NameType;
|
||||||
|
using _value_type = ValueType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename AliasProvider, typename FieldTuple>
|
||||||
|
struct multi_field_t
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<typename NamedExpr>
|
||||||
|
struct make_field_t_impl
|
||||||
|
{
|
||||||
|
using type = field_t<typename NamedExpr::_name_t, typename NamedExpr::_value_type::_base_value_type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename AliasProvider, typename... NamedExpr>
|
||||||
|
struct make_field_t_impl<multi_column_t<AliasProvider, std::tuple<NamedExpr...>>>
|
||||||
|
{
|
||||||
|
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<NamedExpr>::type...>>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename NamedExpr>
|
template<typename NamedExpr>
|
||||||
struct make_field_t_impl
|
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
||||||
{
|
|
||||||
using type = field_t<typename NamedExpr::_name_t, typename NamedExpr::_value_type::_base_value_type>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename AliasProvider, typename... NamedExpr>
|
|
||||||
struct make_field_t_impl<multi_column_t<AliasProvider, std::tuple<NamedExpr...>>>
|
|
||||||
{
|
|
||||||
using type = multi_field_t<AliasProvider, std::tuple<typename make_field_t_impl<NamedExpr>::type...>>;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename NamedExpr>
|
|
||||||
using make_field_t = typename detail::make_field_t_impl<NamedExpr>::type;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
91
include/sqlpp11/vendor/from.h
vendored
Normal file
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
|
#ifndef SQLPP_IN_H
|
||||||
#define SQLPP_IN_H
|
#define SQLPP_IN_H
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
#include <sqlpp11/boolean.h>
|
||||||
|
#include <sqlpp11/vendor/in_fwd.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
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 Operand, typename... Args>
|
||||||
template<bool NotInverted, typename ValueType, typename Operand, typename... Args>
|
struct in_t: public boolean::template operators<in_t<NotInverted, Operand, Args...>>
|
||||||
struct in_t: public ValueType::_base_value_type::template operators<in_t<NotInverted, ValueType, Args...>>
|
|
||||||
{
|
{
|
||||||
static constexpr bool _inverted = not NotInverted;
|
static constexpr bool _inverted = not NotInverted;
|
||||||
static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
|
static_assert(sizeof...(Args) > 0, "in() requires at least one argument");
|
||||||
|
|
||||||
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;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
@ -73,22 +73,26 @@ namespace sqlpp
|
|||||||
in_t& operator=(in_t&&) = default;
|
in_t& operator=(in_t&&) = default;
|
||||||
~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;
|
Operand _operand;
|
||||||
std::tuple<Args...> _args;
|
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
|
#endif
|
@ -24,16 +24,17 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_EXPRESSION_FWD_H
|
#ifndef SQLPP_IN_FWD_H
|
||||||
#define SQLPP_EXPRESSION_FWD_H
|
#define SQLPP_IN_FWD_H
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename T>
|
namespace vendor
|
||||||
struct is_expression_t;
|
{
|
||||||
|
template<bool NotInverted, typename Operand, typename... Args>
|
||||||
|
struct in_t;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_named_expression_t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_SERIALIZABLE_H
|
#ifndef SQLPP_INTERPRETABLE_H
|
||||||
#define SQLPP_SERIALIZABLE_H
|
#define SQLPP_INTERPRETABLE_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
#include <sqlpp11/interpret.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
struct serializable_t
|
struct interpretable_t
|
||||||
{
|
{
|
||||||
template<typename T,
|
using _context_t = typename Db::_context_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
|
|
||||||
>
|
template<typename T>
|
||||||
serializable_t(T&& t):
|
interpretable_t(T t):
|
||||||
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(std::forward<T>(t)))
|
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
serializable_t(const serializable_t&) = default;
|
interpretable_t(const interpretable_t&) = default;
|
||||||
serializable_t(serializable_t&&) = default;
|
interpretable_t(interpretable_t&&) = default;
|
||||||
serializable_t& operator=(const serializable_t&) = default;
|
interpretable_t& operator=(const interpretable_t&) = default;
|
||||||
serializable_t& operator=(serializable_t&&) = default;
|
interpretable_t& operator=(interpretable_t&&) = default;
|
||||||
~serializable_t() = default;
|
~interpretable_t() = default;
|
||||||
|
|
||||||
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:
|
private:
|
||||||
struct _impl_base
|
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>
|
template<typename T>
|
||||||
@ -75,15 +81,36 @@ namespace sqlpp
|
|||||||
_t(std::move(t))
|
_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;
|
T _t;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<const _impl_base> _impl;
|
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.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SQLPP_SERIALIZABLE_LIST_H
|
#ifndef SQLPP_INTERPRETABLE_LIST_H
|
||||||
#define SQLPP_SERIALIZABLE_LIST_H
|
#define SQLPP_INTERPRETABLE_LIST_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sqlpp11/detail/serializable.h>
|
#include <sqlpp11/vendor/interpretable.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
struct serializable_list
|
struct interpretable_list_t
|
||||||
{
|
{
|
||||||
std::vector<detail::serializable_t<Db>> _serializables;
|
std::vector<interpretable_t<Db>> _serializables;
|
||||||
|
|
||||||
std::size_t size() const
|
std::size_t size() const
|
||||||
{
|
{
|
||||||
@ -55,59 +55,67 @@ namespace sqlpp
|
|||||||
_serializables.emplace_back(std::forward<Expr>(expr));
|
_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<>
|
template<>
|
||||||
struct serializable_list<void>
|
struct interpretable_list_t<void>
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void emplace_back(const T&) {}
|
void emplace_back(const T&) {}
|
||||||
|
|
||||||
constexpr std::size_t size() const
|
static constexpr std::size_t size()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool empty() const
|
static constexpr bool empty()
|
||||||
{
|
{
|
||||||
return true;
|
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
|
#ifndef SQLPP_IS_NULL_H
|
||||||
#define SQLPP_IS_NULL_H
|
#define SQLPP_IS_NULL_H
|
||||||
|
|
||||||
#include <sstream>
|
#include <sqlpp11/boolean.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
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 Operand>
|
||||||
template<bool NotInverted, typename ValueType, typename Operand>
|
struct is_null_t: public boolean::template operators<is_null_t<NotInverted, Operand>>
|
||||||
struct is_null_t: public ValueType::_base_value_type::template operators<is_null_t<NotInverted, ValueType, Operand>>
|
|
||||||
{
|
{
|
||||||
static constexpr bool _inverted = not NotInverted;
|
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;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
@ -70,19 +69,23 @@ namespace sqlpp
|
|||||||
is_null_t& operator=(is_null_t&&) = default;
|
is_null_t& operator=(is_null_t&&) = default;
|
||||||
~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;
|
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
|
#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
|
#ifndef SQLPP_LIKE_H
|
||||||
#define SQLPP_LIKE_H
|
#define SQLPP_LIKE_H
|
||||||
|
|
||||||
#include <sstream>
|
#include <sqlpp11/boolean.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
|
|
||||||
namespace sqlpp
|
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 Operand, typename Pattern>
|
||||||
template<typename ValueType, typename Operand, typename Pattern>
|
struct like_t: public boolean::template operators<like_t<Operand, Pattern>>
|
||||||
struct like_t: public ValueType::_base_value_type::template operators<like_t<ValueType, Operand, Pattern>>
|
|
||||||
{
|
{
|
||||||
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
static_assert(is_text_t<Operand>::value, "Operand for like() has to be a text");
|
||||||
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
static_assert(is_text_t<Pattern>::value, "Pattern for like() has to be a text");
|
||||||
using _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;
|
using _is_named_expression = std::true_type;
|
||||||
};
|
};
|
||||||
@ -74,27 +73,24 @@ namespace sqlpp
|
|||||||
like_t& operator=(like_t&&) = default;
|
like_t& operator=(like_t&&) = default;
|
||||||
~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;
|
Operand _operand;
|
||||||
Pattern _pattern;
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,50 +33,57 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename Limit>
|
namespace vendor
|
||||||
struct limit_t
|
{
|
||||||
|
template<typename Limit>
|
||||||
|
struct limit_t
|
||||||
|
{
|
||||||
|
using _is_limit = std::true_type;
|
||||||
|
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||||
|
|
||||||
|
Limit _limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Limit>
|
||||||
|
struct interpreter_t<Context, limit_t<Limit>>
|
||||||
|
{
|
||||||
|
using T = limit_t<Limit>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " LIMIT ";
|
||||||
|
interpret(t._limit, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dynamic_limit_t
|
||||||
{
|
{
|
||||||
using _is_limit = std::true_type;
|
using _is_limit = std::true_type;
|
||||||
using _parameter_tuple_t = std::tuple<Limit>;
|
using _is_dynamic = std::true_type;
|
||||||
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 set(std::size_t limit)
|
||||||
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);
|
_limit = limit;
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Limit _limit;
|
std::size_t _limit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynamic_limit_t
|
template<typename Context>
|
||||||
{
|
struct interpreter_t<Context, dynamic_limit_t>
|
||||||
using _is_limit = std::true_type;
|
|
||||||
using _is_dynamic = std::true_type;
|
|
||||||
|
|
||||||
void set(std::size_t limit)
|
|
||||||
{
|
|
||||||
_limit = limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
void serialize(std::ostream& os, Db& db) const
|
|
||||||
{
|
{
|
||||||
static_assert(Db::_supports_limit, "limit not supported by current database");
|
using T = dynamic_limit_t;
|
||||||
if (_limit > 0)
|
|
||||||
os << " LIMIT " << _limit;
|
static Context& _(const T& t, Context& context)
|
||||||
}
|
{
|
||||||
|
if (t._limit > 0)
|
||||||
|
context << " LIMIT " << t._limit;
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t _limit;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -27,33 +27,38 @@
|
|||||||
#ifndef SQLPP_NAMED_SERIALIZABLE_H
|
#ifndef SQLPP_NAMED_SERIALIZABLE_H
|
||||||
#define SQLPP_NAMED_SERIALIZABLE_H
|
#define SQLPP_NAMED_SERIALIZABLE_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
#include <sqlpp11/parameter_list.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
struct named_serializable_t
|
struct named_interpretable_t
|
||||||
{
|
{
|
||||||
template<typename T,
|
using _context_t = typename Db::_context_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
|
|
||||||
>
|
template<typename T>
|
||||||
named_serializable_t(T&& t):
|
named_interpretable_t(T t):
|
||||||
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(std::forward<T>(t)))
|
_impl(std::make_shared<_impl_t<typename std::decay<T>::type>>(t))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
named_serializable_t(const named_serializable_t&) = default;
|
named_interpretable_t(const named_interpretable_t&) = default;
|
||||||
named_serializable_t(named_serializable_t&&) = default;
|
named_interpretable_t(named_interpretable_t&&) = default;
|
||||||
named_serializable_t& operator=(const named_serializable_t&) = default;
|
named_interpretable_t& operator=(const named_interpretable_t&) = default;
|
||||||
named_serializable_t& operator=(named_serializable_t&&) = default;
|
named_interpretable_t& operator=(named_interpretable_t&&) = default;
|
||||||
~named_serializable_t() = default;
|
~named_interpretable_t() = default;
|
||||||
|
|
||||||
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
|
std::string _get_name() const
|
||||||
@ -64,13 +69,15 @@ namespace sqlpp
|
|||||||
private:
|
private:
|
||||||
struct _impl_base
|
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;
|
virtual std::string _get_name() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct _impl_t: public _impl_base
|
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):
|
_impl_t(const T& t):
|
||||||
_t(t)
|
_t(t)
|
||||||
{}
|
{}
|
||||||
@ -79,9 +86,16 @@ namespace sqlpp
|
|||||||
_t(std::move(t))
|
_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
|
std::string _get_name() const
|
||||||
@ -94,7 +108,20 @@ namespace sqlpp
|
|||||||
|
|
||||||
std::shared_ptr<const _impl_base> _impl;
|
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
|
#endif
|
@ -28,18 +28,30 @@
|
|||||||
#define SQLPP_NOOP_H
|
#define SQLPP_NOOP_H
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <sqlpp11/vendor/noop_fwd.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct noop
|
namespace vendor
|
||||||
{
|
{
|
||||||
template<typename Db>
|
struct noop
|
||||||
void serialize(std::ostream& os, Db& db) const
|
{
|
||||||
{}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename Context>
|
||||||
struct is_noop: std::is_same<T, noop> {};
|
struct interpreter_t<Context, noop>
|
||||||
|
{
|
||||||
|
using T = noop;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_noop: std::is_same<T, noop> {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -29,9 +29,12 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
struct noop;
|
namespace vendor
|
||||||
|
{
|
||||||
|
struct noop;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_noop;
|
struct is_noop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -27,56 +27,61 @@
|
|||||||
#ifndef SQLPP_OFFSET_H
|
#ifndef SQLPP_OFFSET_H
|
||||||
#define SQLPP_OFFSET_H
|
#define SQLPP_OFFSET_H
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <sqlpp11/select_fwd.h>
|
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename Offset>
|
namespace vendor
|
||||||
struct offset_t
|
{
|
||||||
|
template<typename Offset>
|
||||||
|
struct offset_t
|
||||||
|
{
|
||||||
|
using _is_offset = std::true_type;
|
||||||
|
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||||
|
|
||||||
|
Offset _offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Offset>
|
||||||
|
struct interpreter_t<Context, offset_t<Offset>>
|
||||||
|
{
|
||||||
|
using T = offset_t<Offset>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " OFFSET ";
|
||||||
|
interpret(t._offset, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dynamic_offset_t
|
||||||
{
|
{
|
||||||
using _is_offset = std::true_type;
|
using _is_offset = std::true_type;
|
||||||
using _parameter_tuple_t = std::tuple<Offset>;
|
using _is_dynamic = std::true_type;
|
||||||
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");
|
|
||||||
|
|
||||||
|
void set(std::size_t offset)
|
||||||
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);
|
_offset = offset;
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset _offset;
|
std::size_t _offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dynamic_offset_t
|
template<typename Context>
|
||||||
{
|
struct interpreter_t<Context, dynamic_offset_t>
|
||||||
using _is_offset = std::true_type;
|
|
||||||
using _is_dynamic = std::true_type;
|
|
||||||
|
|
||||||
void set(std::size_t offset)
|
|
||||||
{
|
|
||||||
_offset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
void serialize(std::ostream& os, Db& db) const
|
|
||||||
{
|
{
|
||||||
if (_offset > 0)
|
using T = dynamic_offset_t;
|
||||||
os << " OFFSET " << _offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t _offset;
|
static Context& _(const T& t, Context& context)
|
||||||
};
|
{
|
||||||
|
if (t._offset > 0)
|
||||||
|
context << " OFFSET " << t._offset;
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
88
include/sqlpp11/vendor/order_by.h
vendored
Normal file
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/select_fwd.h>
|
||||||
#include <sqlpp11/type_traits.h>
|
#include <sqlpp11/type_traits.h>
|
||||||
#include <sqlpp11/detail/set.h>
|
#include <sqlpp11/detail/set.h>
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
#include <sqlpp11/vendor/interpret_tuple.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -43,67 +42,104 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
using _is_select_flag = std::true_type;
|
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 = {};
|
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 distinct_t
|
||||||
{
|
{
|
||||||
struct _value_type
|
struct _value_type
|
||||||
{
|
{
|
||||||
using _is_select_flag = std::true_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 = {};
|
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 straight_join_t
|
||||||
{
|
{
|
||||||
struct _value_type
|
struct _value_type
|
||||||
{
|
{
|
||||||
using _is_select_flag = std::true_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 = {};
|
static constexpr straight_join_t straight_join = {};
|
||||||
|
|
||||||
// select_flag_list_t
|
namespace vendor
|
||||||
template<typename... Flag>
|
{
|
||||||
struct select_flag_list_t<std::tuple<Flag...>>
|
template<typename Context>
|
||||||
{
|
struct interpreter_t<Context, straight_join_t>
|
||||||
// check for duplicate order expressions
|
{
|
||||||
static_assert(not detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
|
static Context& _(const straight_join_t&, Context& context)
|
||||||
|
|
||||||
// check for invalid order expressions
|
|
||||||
using _valid_flags = typename detail::make_set_if<is_select_flag_t, Flag...>::type;
|
|
||||||
static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list");
|
|
||||||
|
|
||||||
using _is_select_flag_list = std::true_type;
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
void serialize(std::ostream& os, Db& db) const
|
|
||||||
{
|
{
|
||||||
detail::serialize_tuple(os, db, _flags, ' ');
|
context << "STRAIGHT_JOIN";
|
||||||
os << ' ';
|
return context;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::tuple<Flag...> _flags;
|
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...>>
|
||||||
|
{
|
||||||
|
// check for duplicate order expressions
|
||||||
|
static_assert(not detail::has_duplicates<Flag...>::value, "at least one duplicate argument detected in select flag list");
|
||||||
|
|
||||||
|
// check for invalid order expressions
|
||||||
|
using _valid_flags = typename detail::make_set_if<is_select_flag_t, Flag...>::type;
|
||||||
|
static_assert(_valid_flags::size::value == sizeof...(Flag), "at least one argument is not a select flag in select flag list");
|
||||||
|
|
||||||
|
using _is_select_flag_list = std::true_type;
|
||||||
|
|
||||||
|
std::tuple<Flag...> _flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename... Flag>
|
||||||
|
struct interpreter_t<Context, select_flag_list_t<std::tuple<Flag...>>>
|
||||||
|
{
|
||||||
|
using T = select_flag_list_t<std::tuple<Flag...>>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
interpret_tuple(t._flags, ' ', context);
|
||||||
|
if (sizeof...(Flag))
|
||||||
|
context << ' ';
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -44,11 +44,12 @@ namespace sqlpp
|
|||||||
typename Select,
|
typename Select,
|
||||||
typename... NamedExpr
|
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,
|
Select,
|
||||||
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
||||||
{
|
{
|
||||||
using _value_type = no_value_t;
|
using _value_type = no_value_t;
|
||||||
|
using _is_pseudo_table = std::true_type;
|
||||||
|
|
||||||
select_pseudo_table_t(const Select& select):
|
select_pseudo_table_t(const Select& select):
|
||||||
_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& operator=(select_pseudo_table_t&& rhs) = default;
|
||||||
~select_pseudo_table_t() = 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;
|
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
|
#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
|
#ifndef SQLPP_DETAIL_WRAP_OPERAND_H
|
||||||
#define SQLPP_DETAIL_WRAP_OPERAND_H
|
#define SQLPP_DETAIL_WRAP_OPERAND_H
|
||||||
|
|
||||||
#include <ostream>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <sqlpp11/vendor/interpreter.h>
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
@ -38,100 +38,99 @@ namespace sqlpp
|
|||||||
struct integral;
|
struct integral;
|
||||||
struct floating_point;
|
struct floating_point;
|
||||||
struct text;
|
struct text;
|
||||||
|
}
|
||||||
|
|
||||||
struct bool_operand
|
namespace vendor
|
||||||
|
{
|
||||||
|
struct boolean_operand
|
||||||
{
|
{
|
||||||
static constexpr bool _is_expression = true;
|
static constexpr bool _is_expression = true;
|
||||||
using _value_type = boolean;
|
using _value_type = detail::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _is_trivial() const { return _t == false; }
|
bool _is_trivial() const { return _t == false; }
|
||||||
|
|
||||||
bool _t;
|
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>
|
template<typename T>
|
||||||
struct integral_operand
|
struct integral_operand
|
||||||
{
|
{
|
||||||
static constexpr bool _is_expression = true;
|
static constexpr bool _is_expression = true;
|
||||||
using _value_type = integral;
|
using _value_type = detail::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _is_trivial() const { return _t == 0; }
|
bool _is_trivial() const { return _t == 0; }
|
||||||
|
|
||||||
T _t;
|
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>
|
template<typename T>
|
||||||
struct floating_point_operand
|
struct floating_point_operand
|
||||||
{
|
{
|
||||||
static constexpr bool _is_expression = true;
|
static constexpr bool _is_expression = true;
|
||||||
using _value_type = floating_point;
|
using _value_type = detail::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _is_trivial() const { return _t == 0; }
|
bool _is_trivial() const { return _t == 0; }
|
||||||
|
|
||||||
T _t;
|
T _t;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename Context, typename T>
|
||||||
struct text_operand
|
struct interpreter_t<Context, floating_point_operand<T>>
|
||||||
{
|
{
|
||||||
static constexpr bool _is_expression = true;
|
using Operand = floating_point_operand<T>;
|
||||||
using _value_type = text;
|
|
||||||
|
|
||||||
text_operand(const T& t): _t(t) {}
|
static Context& _(const Operand& t, Context& context)
|
||||||
text_operand(const text_operand&) = default;
|
{
|
||||||
text_operand(text_operand&&) = default;
|
context << t._t;
|
||||||
text_operand& operator=(const text_operand&) = default;
|
return context;
|
||||||
text_operand& operator=(text_operand&&) = default;
|
}
|
||||||
~text_operand() = default;
|
};
|
||||||
|
|
||||||
template<typename Db>
|
struct text_operand
|
||||||
void serialize(std::ostream& os, Db& db) const
|
{
|
||||||
{
|
static constexpr bool _is_expression = true;
|
||||||
os << '\'' << db.escape(_t) << '\'';
|
using _value_type = detail::text;
|
||||||
}
|
|
||||||
|
|
||||||
bool _is_trivial() const { return _t.empty(); }
|
bool _is_trivial() const { return _t.empty(); }
|
||||||
|
|
||||||
std::string _t;
|
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>
|
template<typename T, typename Enable = void>
|
||||||
@ -143,7 +142,7 @@ namespace sqlpp
|
|||||||
template<>
|
template<>
|
||||||
struct wrap_operand<bool, void>
|
struct wrap_operand<bool, void>
|
||||||
{
|
{
|
||||||
using type = bool_operand;
|
using type = boolean_operand;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -161,7 +160,7 @@ namespace sqlpp
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct wrap_operand<T, typename std::enable_if<std::is_convertible<T, std::string>::value>::type>
|
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;
|
using _value_type = no_value_t;
|
||||||
|
|
||||||
@ -62,15 +62,25 @@ namespace sqlpp
|
|||||||
verbatim_table_t& operator=(verbatim_table_t&& rhs) = default;
|
verbatim_table_t& operator=(verbatim_table_t&& rhs) = default;
|
||||||
~verbatim_table_t() = default;
|
~verbatim_table_t() = default;
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
void serialize(std::ostream& os, Db& db) const
|
|
||||||
{
|
|
||||||
os << _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string _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)
|
verbatim_table_t verbatim_table(std::string name)
|
||||||
{
|
{
|
||||||
return { 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})
|
add_test(${arg} ${arg})
|
||||||
endmacro ()
|
endmacro ()
|
||||||
|
|
||||||
|
build_and_run(InterpretTest)
|
||||||
build_and_run(InsertTest)
|
build_and_run(InsertTest)
|
||||||
build_and_run(RemoveTest)
|
build_and_run(RemoveTest)
|
||||||
build_and_run(UpdateTest)
|
build_and_run(UpdateTest)
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "TabSample.h"
|
#include "TabSample.h"
|
||||||
#include "MockDb.h"
|
#include "MockDb.h"
|
||||||
|
#include <sqlpp11/alias_provider.h>
|
||||||
#include <sqlpp11/select.h>
|
#include <sqlpp11/select.h>
|
||||||
#include <sqlpp11/functions.h>
|
#include <sqlpp11/functions.h>
|
||||||
#include <sqlpp11/connection.h>
|
#include <sqlpp11/connection.h>
|
||||||
@ -32,7 +33,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db = {};
|
DbMock db = {};
|
||||||
SQLPP_ALIAS_PROVIDER_GENERATOR(kaesekuchen);
|
SQLPP_ALIAS_PROVIDER(kaesekuchen);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db;
|
DbMock db;
|
||||||
|
DbMock::_context_t printer(std::cerr);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -56,11 +57,11 @@ int main()
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_into(t).serialize(std::cerr, db); std::cerr << "\n";
|
interpret(insert_into(t), printer).flush();
|
||||||
insert_into(t).set(t.beta = "kirschauflauf").serialize(std::cerr, db); std::cerr << "\n";
|
interpret(insert_into(t).set(t.beta = "kirschauflauf"), printer).flush();
|
||||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
auto i = dynamic_insert_into(db, t).dynamic_set();
|
||||||
i = i.add_set(t.beta = "kirschauflauf");
|
i = i.add_set(t.beta = "kirschauflauf");
|
||||||
i.serialize(std::cerr, db); std::cerr << "\n";
|
interpret(i, printer).flush();
|
||||||
|
|
||||||
return 0;
|
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
|
#define SQLPP_MOCK_DB_H
|
||||||
|
|
||||||
#include <sqlpp11/connection.h>
|
#include <sqlpp11/connection.h>
|
||||||
|
#include <sqlpp11/serializer.h>
|
||||||
|
|
||||||
class DbMock: public sqlpp::connection
|
struct DbMock: public sqlpp::connection
|
||||||
{
|
{
|
||||||
public:
|
struct _context_t : public sqlpp::serializer_t
|
||||||
// join types
|
{
|
||||||
static constexpr bool _supports_inner_join = true;
|
_context_t(std::ostream& os): sqlpp::serializer_t(os) {}
|
||||||
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; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -87,7 +87,7 @@ int main()
|
|||||||
|
|
||||||
// Wonderful, now take a look at the parameter list of a select
|
// 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 S = decltype(s);
|
||||||
using T = sqlpp::make_parameter_list_t<S>::type;
|
using T = sqlpp::make_parameter_list_t<S>::type;
|
||||||
T npl;
|
T npl;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
|
|
||||||
DbMock db;
|
DbMock db;
|
||||||
|
DbMock::_context_t printer(std::cerr);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -56,13 +57,13 @@ int main()
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_from(t).serialize(std::cerr, db); std::cerr << "\n";
|
interpret(remove_from(t), printer).flush();
|
||||||
remove_from(t).where(t.beta != "transparent").serialize(std::cerr, db); std::cerr << "\n";
|
interpret(remove_from(t).where(t.beta != "transparent"), printer).flush();
|
||||||
remove_from(t).using_(t).serialize(std::cerr, db); std::cerr << "\n";
|
interpret(remove_from(t).using_(t), printer).flush();
|
||||||
auto r = dynamic_remove_from(db, t).dynamic_using_().dynamic_where();
|
auto r = dynamic_remove_from(db, t).dynamic_using_().dynamic_where();
|
||||||
r = r.add_using_(t);
|
r = r.add_using_(t);
|
||||||
r = r.add_where(t.beta != "transparent");
|
r = r.add_where(t.beta != "transparent");
|
||||||
r.serialize(std::cerr, db); std::cerr << "\n";
|
interpret(r, printer).flush();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "TabSample.h"
|
#include "TabSample.h"
|
||||||
#include "MockDb.h"
|
#include "MockDb.h"
|
||||||
#include "is_regular.h"
|
#include "is_regular.h"
|
||||||
|
#include <sqlpp11/alias_provider.h>
|
||||||
#include <sqlpp11/select.h>
|
#include <sqlpp11/select.h>
|
||||||
#include <sqlpp11/functions.h>
|
#include <sqlpp11/functions.h>
|
||||||
#include <sqlpp11/connection.h>
|
#include <sqlpp11/connection.h>
|
||||||
@ -33,6 +34,15 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
DbMock db = {};
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
@ -59,7 +69,7 @@ int main()
|
|||||||
|
|
||||||
// Test an alias of table
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_integral_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");
|
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
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(sqlpp::is_integral_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");
|
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
|
// 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(sqlpp::is_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||||
static_assert(sqlpp::is_named_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
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(sqlpp::is_expression_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");
|
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
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_named_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
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
static_assert(not sqlpp::is_expression_t<T>::value, "type requirement");
|
||||||
static_assert(not sqlpp::is_named_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
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(sqlpp::is_expression_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");
|
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
|
// 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_numeric_t<T>::value, "type requirement");
|
||||||
static_assert(sqlpp::is_expression_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");
|
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
|
// Test that select(all_of(tab)) is expanded in multi_column
|
||||||
{
|
{
|
||||||
auto a = multi_column(sqlpp::alias::a, all_of(t));
|
auto a = multi_column(alias::a, all_of(t));
|
||||||
auto b = multi_column(sqlpp::alias::a, t.alpha, t.beta, t.gamma);
|
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");
|
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
|
// Test that select(tab) is expanded in multi_column
|
||||||
{
|
{
|
||||||
auto a = multi_column(sqlpp::alias::a, all_of(t));
|
auto a = multi_column(alias::a, all_of(t));
|
||||||
auto b = multi_column(sqlpp::alias::a, t.alpha, t.beta, t.gamma);
|
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");
|
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
|
// Test that a multicolumn is not a value
|
||||||
{
|
{
|
||||||
auto m = multi_column(sqlpp::alias::a, t.alpha, t.beta);
|
auto m = multi_column(alias::a, t.alpha, t.beta);
|
||||||
auto a = select(m).from(t).as(sqlpp::alias::b).a;
|
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");
|
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(30);
|
||||||
s = s.set_limit(3);
|
s = s.set_limit(3);
|
||||||
std::cerr << "------------------------\n";
|
std::cerr << "------------------------\n";
|
||||||
s.serialize(std::cerr, db);
|
interpret(s, printer).flush();
|
||||||
std::cerr << "------------------------\n";
|
std::cerr << "------------------------\n";
|
||||||
using T = decltype(s);
|
using T = decltype(s);
|
||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
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.
|
// 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);
|
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
|
// Test that verbatim_table compiles
|
||||||
{
|
{
|
||||||
auto s = select(t.alpha).from(sqlpp::verbatim_table("my_unknown_table"));
|
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");
|
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(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
static_assert(T::_is_expression, "T has to be an expression");
|
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");
|
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;
|
auto y = t.gamma and true and t.gamma;
|
||||||
!t.gamma;
|
!t.gamma;
|
||||||
t.beta < "kaesekuchen";
|
t.beta < "kaesekuchen";
|
||||||
(t.beta + "hallenhalma").serialize(std::cerr, db);
|
interpret(t.beta + "hallenhalma", printer).flush();
|
||||||
concat(t.beta, "hallenhalma").serialize(std::cerr, db);
|
|
||||||
static_assert(sqlpp::must_not_insert_t<decltype(t.alpha)>::value, "alpha must not be inserted");
|
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;
|
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(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)>::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_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(sqlpp::alias::a))>::value, "an alias of alpha should be an alias");
|
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 z = select(t.alpha) == 7;
|
||||||
auto l = t.as(sqlpp::alias::left);
|
auto l = t.as(alias::left);
|
||||||
auto r = select(t.gamma.as(sqlpp::alias::a)).from(t).where(t.gamma == true).as(sqlpp::alias::right);
|
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");
|
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)
|
.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)
|
.group_by(l.gamma, r.a)
|
||||||
.having(r.a != true)
|
.having(r.a != true)
|
||||||
.order_by(l.beta.asc())
|
.order_by(l.beta.asc())
|
||||||
.limit(17)
|
.limit(17)
|
||||||
.offset(3)
|
.offset(3)
|
||||||
.as(sqlpp::alias::a)
|
.as(alias::a)
|
||||||
.serialize(std::cerr, db);
|
, printer).flush();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#ifndef SQLPP_TAB_SAMPLE_H
|
#ifndef SQLPP_TAB_SAMPLE_H
|
||||||
#define SQLPP_TAB_SAMPLE_H
|
#define SQLPP_TAB_SAMPLE_H
|
||||||
|
|
||||||
#include <sqlpp11/table_base.h>
|
#include <sqlpp11/table.h>
|
||||||
#include <sqlpp11/column_types.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,
|
||||||
TabFoo_::Epsilon,
|
TabFoo_::Epsilon,
|
||||||
TabFoo_::Omega
|
TabFoo_::Omega
|
||||||
@ -166,7 +166,7 @@ namespace TabSample_
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TabSample: sqlpp::table_base_t<
|
struct TabSample: sqlpp::table_t<
|
||||||
TabSample,
|
TabSample,
|
||||||
TabSample_::Alpha,
|
TabSample_::Alpha,
|
||||||
TabSample_::Beta,
|
TabSample_::Beta,
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "is_regular.h"
|
#include "is_regular.h"
|
||||||
|
|
||||||
DbMock db;
|
DbMock db;
|
||||||
|
DbMock::_context_t printer(std::cerr);
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -54,12 +55,12 @@ int main()
|
|||||||
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
static_assert(sqlpp::is_regular<T>::value, "type requirement");
|
||||||
}
|
}
|
||||||
|
|
||||||
update(t).serialize(std::cerr, db); std::cerr << "\n";
|
interpret(update(t), printer).flush();
|
||||||
update(t).set(t.gamma = false).serialize(std::cerr, db); std::cerr << "\n";
|
interpret(update(t).set(t.gamma = false), printer).flush();
|
||||||
update(t).set(t.gamma = false).where(t.beta != "transparent").serialize(std::cerr, db); std::cerr << "\n";
|
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();
|
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
|
||||||
u = u.add_set(t.gamma = false);
|
u = u.add_set(t.gamma = false);
|
||||||
u.serialize(std::cerr, db); std::cerr << "\n";
|
interpret(u, printer).flush();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user