mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Merge branch 'feature/unified_statement' into develop
This commit is contained in:
commit
07980a72a2
@ -34,7 +34,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Flag, typename Expr>
|
||||
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>
|
||||
struct avg_t: public floating_point::template expression_operators<avg_t<Flag, Expr>>,
|
||||
public alias_operators<avg_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
@ -139,7 +139,11 @@ namespace sqlpp
|
||||
static_assert(detail::all_t<_is_valid_comparison_operand<vendor::wrap_operand_t<T>>::value...>::value, "at least one operand of in() is not valid");
|
||||
return { *static_cast<const Base*>(this), vendor::wrap_operand_t<T>{t}... };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Base>
|
||||
struct alias_operators
|
||||
{
|
||||
template<typename alias_provider>
|
||||
expression_alias_t<Base, alias_provider> as(const alias_provider&)
|
||||
{
|
||||
|
@ -35,7 +35,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Flag, typename Expr>
|
||||
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>
|
||||
struct count_t: public sqlpp::detail::integral::template expression_operators<count_t<Flag, Expr>>,
|
||||
public alias_operators<count_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
@ -34,22 +34,22 @@ namespace sqlpp
|
||||
namespace detail
|
||||
{
|
||||
template<typename Target, typename Statement, typename Term>
|
||||
Target pick_arg_impl(Statement statement, Term term, const std::true_type&)
|
||||
typename Target::_data_t pick_arg_impl(Statement statement, Term term, const std::true_type&)
|
||||
{
|
||||
return term;
|
||||
};
|
||||
|
||||
template<typename Target, typename Statement, typename Term>
|
||||
Target pick_arg_impl(Statement statement, Term term, const std::false_type&)
|
||||
typename Target::_data_t pick_arg_impl(Statement statement, Term term, const std::false_type&)
|
||||
{
|
||||
return static_cast<Target>(statement);
|
||||
return Target::_get_member(statement)._data;
|
||||
};
|
||||
|
||||
// Returns a statement's term either by picking the term from the statement or using the new term
|
||||
template<typename Target, typename Statement, typename Term>
|
||||
Target pick_arg(Statement statement, Term term)
|
||||
typename Target::_data_t pick_arg(Statement statement, Term term)
|
||||
{
|
||||
return pick_arg_impl<Target>(statement, term, std::is_same<Target, Term>());
|
||||
return pick_arg_impl<Target>(statement, term, std::is_same<typename Target::_data_t, Term>());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Select>
|
||||
struct exists_t: public boolean::template expression_operators<exists_t<Select>>
|
||||
struct exists_t: public boolean::template expression_operators<exists_t<Select>>,
|
||||
public alias_operators<exists_t<Select>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Select>;
|
||||
|
@ -50,12 +50,13 @@ namespace sqlpp
|
||||
{
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _required_tables = ::sqlpp::detail::type_set<>;
|
||||
static_assert(not is_expression_t<T>::value, "value() is to be called with non-sql-type like int, or string");
|
||||
static_assert(is_wrapped_value_t<vendor::wrap_operand_t<T>>::value, "value() is to be called with non-sql-type like int, or string");
|
||||
return { t };
|
||||
}
|
||||
|
||||
template<typename ValueType> // Csaba Csoma suggests: unsafe_sql instead of verbatim
|
||||
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>
|
||||
struct verbatim_t: public ValueType::template expression_operators<verbatim_t<ValueType>>,
|
||||
public alias_operators<verbatim_t<ValueType>>
|
||||
{
|
||||
using _traits = make_traits<ValueType, ::sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
@ -148,7 +149,7 @@ namespace sqlpp
|
||||
template<typename Container>
|
||||
auto value_list(Container c) -> value_list_t<Container>
|
||||
{
|
||||
static_assert(not is_expression_t<typename Container::value_type>::value, "value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
|
||||
static_assert(is_wrapped_value_t<vendor::wrap_operand_t<typename Container::value_type>>::value, "value_list() is to be called with a container of non-sql-type like std::vector<int>, or std::list(string)");
|
||||
return { c };
|
||||
}
|
||||
|
||||
|
@ -27,159 +27,45 @@
|
||||
#ifndef SQLPP_INSERT_H
|
||||
#define SQLPP_INSERT_H
|
||||
|
||||
#include <sqlpp11/statement.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_insert.h>
|
||||
#include <sqlpp11/default_value.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/single_table.h>
|
||||
#include <sqlpp11/vendor/into.h>
|
||||
#include <sqlpp11/vendor/insert_value_list.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
#include <sqlpp11/detail/get_last.h>
|
||||
#include <sqlpp11/detail/pick_arg.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename... Policies>
|
||||
struct insert_t;
|
||||
struct insert_name_t {};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Db, typename... Policies>
|
||||
struct insert_policies_t
|
||||
{
|
||||
using _database_t = Db;
|
||||
|
||||
using _statement_t = insert_t<Db, Policies...>;
|
||||
|
||||
struct _methods_t: public Policies::template _methods_t<insert_policies_t>...
|
||||
struct insert_t: public vendor::statement_name_t<insert_name_t>
|
||||
{};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
struct _policies_update_t
|
||||
{
|
||||
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
||||
using type = insert_t<Db, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _new_statement_t = typename _policies_update_t<Needle, Replacement>::type;
|
||||
|
||||
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
|
||||
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
|
||||
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
|
||||
|
||||
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
|
||||
|
||||
template<typename Expression>
|
||||
using _no_unknown_tables = detail::is_subset_of<required_tables_of<Expression>, _known_tables>;
|
||||
|
||||
// The tables not covered by the from.
|
||||
using _required_tables = detail::make_difference_set_t<
|
||||
_all_required_tables,
|
||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||
>;
|
||||
|
||||
using _traits = make_traits<no_value_t>; // FIXME
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>; // FIXME
|
||||
using _required_tables = _required_tables;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// INSERT
|
||||
template<typename Db, typename... Policies>
|
||||
struct insert_t:
|
||||
public Policies...,
|
||||
public detail::insert_policies_t<Db, Policies...>::_methods_t
|
||||
{
|
||||
using _policies_t = typename detail::insert_policies_t<Db, Policies...>;
|
||||
using _database_t = typename _policies_t::_database_t;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<_database_t, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<insert_t>::type;
|
||||
|
||||
// Constructors
|
||||
constexpr insert_t()
|
||||
{}
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
insert_t(Statement statement, Term term):
|
||||
Policies(detail::pick_arg<Policies>(statement, term))...
|
||||
{}
|
||||
|
||||
insert_t(const insert_t&) = default;
|
||||
insert_t(insert_t&&) = default;
|
||||
insert_t& operator=(const insert_t&) = default;
|
||||
insert_t& operator=(insert_t&&) = default;
|
||||
~insert_t() = default;
|
||||
|
||||
// run and prepare
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
// FIXME: Read up on what is allowed/prohibited in INSERT
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
std::size_t _run(Database& db) const
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
auto _prepare(Database& db) const
|
||||
-> prepared_insert_t<Database, insert_t>
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, insert_t<Database, Policies...>>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_name_t>
|
||||
{
|
||||
using T = insert_t<Database, Policies...>;
|
||||
using T = insert_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "INSERT INTO ";
|
||||
context << "INSERT ";
|
||||
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const Policies&>(t), context), 0)...};
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_insert_t = insert_t<Database,
|
||||
vendor::no_single_table_t,
|
||||
using blank_insert_t = statement_t<Database,
|
||||
insert_t,
|
||||
vendor::no_into_t,
|
||||
vendor::no_insert_value_list_t>;
|
||||
|
||||
constexpr auto insert()
|
||||
auto insert()
|
||||
-> blank_insert_t<void>
|
||||
{
|
||||
return { blank_insert_t<void>() };
|
||||
|
@ -42,6 +42,7 @@ namespace sqlpp
|
||||
// integral value type
|
||||
struct integral
|
||||
{
|
||||
using _traits = make_traits<integral, ::sqlpp::tag::expression>;
|
||||
using _tag = ::sqlpp::tag::integral;
|
||||
using _cpp_value_type = int64_t;
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace sqlpp
|
||||
static_assert(not is_join_t<Rhs>::value, "rhs argument for join must not be a join");
|
||||
static_assert(vendor::is_noop<On>::value or is_on_t<On>::value, "invalid on expression in join().on()");
|
||||
|
||||
static_assert(::sqlpp::detail::is_disjunct_from<typename Lhs::_provided_tables, typename Rhs::_provided_tables>::value, "joined tables must not be identical");
|
||||
static_assert(::sqlpp::detail::is_disjunct_from<provided_tables_of<Lhs>, provided_tables_of<Rhs>>::value, "joined tables must not be identical");
|
||||
|
||||
static_assert(_recursive_traits::_required_tables::size::value == 0, "joined tables must not depend on other tables");
|
||||
|
||||
|
@ -34,7 +34,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>
|
||||
struct max_t: public value_type_of<Expr>::template expression_operators<max_t<Expr>>,
|
||||
public alias_operators<max_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
@ -34,7 +34,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Expr>
|
||||
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>
|
||||
struct min_t: public value_type_of<Expr>::template expression_operators<min_t<Expr>>,
|
||||
public alias_operators<min_t<Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
@ -74,7 +74,7 @@ namespace sqlpp
|
||||
|
||||
template<typename NamedExpr>
|
||||
auto parameter(const NamedExpr&)
|
||||
-> parameter_t<typename NamedExpr::_value_type, NamedExpr>
|
||||
-> parameter_t<value_type_of<NamedExpr>, NamedExpr>
|
||||
{
|
||||
static_assert(is_named_expression_t<NamedExpr>::value, "not a named expression");
|
||||
return {};
|
||||
@ -82,7 +82,7 @@ namespace sqlpp
|
||||
|
||||
template<typename ValueType, typename AliasProvider>
|
||||
auto parameter(const ValueType&, const AliasProvider&)
|
||||
-> parameter_t<ValueType, AliasProvider>
|
||||
-> parameter_t<vendor::wrap_operand_t<ValueType>, AliasProvider>
|
||||
{
|
||||
static_assert(is_expression_t<ValueType>::value, "first argument is not a value type");
|
||||
static_assert(is_alias_provider_t<AliasProvider>::value, "second argument is not an alias provider");
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SQLPP_PARAMETER_LIST_H
|
||||
|
||||
#include <tuple>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/vendor/wrong.h>
|
||||
#include <sqlpp11/detail/index_sequence.h>
|
||||
|
||||
|
@ -27,188 +27,104 @@
|
||||
#ifndef SQLPP_REMOVE_H
|
||||
#define SQLPP_REMOVE_H
|
||||
|
||||
#include <sqlpp11/statement.h>
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_remove.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#warning: need to use another table provider, since delete can be used with several tables
|
||||
#include <sqlpp11/vendor/single_table.h>
|
||||
#include <sqlpp11/vendor/from.h>
|
||||
#include <sqlpp11/vendor/extra_tables.h>
|
||||
#include <sqlpp11/vendor/using.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
#include <sqlpp11/detail/get_last.h>
|
||||
#include <sqlpp11/detail/pick_arg.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename... Policies>
|
||||
struct remove_t;
|
||||
|
||||
namespace detail
|
||||
struct remove_name_t {};
|
||||
struct remove_t: public vendor::statement_name_t<remove_name_t>
|
||||
{
|
||||
template<typename Db = void, typename... Policies>
|
||||
struct remove_policies_t
|
||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _database_t = Db;
|
||||
using _statement_t = remove_t<Db, Policies...>;
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
struct _methods_t: public Policies::template _methods_t<remove_policies_t>...
|
||||
{};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
struct _policies_update_t
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
||||
using type = remove_t<Db, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _new_statement_t = typename _policies_update_t<Needle, Replacement>::type;
|
||||
|
||||
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
|
||||
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
|
||||
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
|
||||
|
||||
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
|
||||
|
||||
template<typename Expression>
|
||||
using _no_unknown_tables = detail::is_subset_of<required_tables_of<Expression>, _known_tables>;
|
||||
|
||||
// The tables not covered by the from.
|
||||
using _required_tables = detail::make_difference_set_t<
|
||||
_all_required_tables,
|
||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||
>;
|
||||
|
||||
using _traits = make_traits<no_value_t>; // FIXME
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>; // FIXME
|
||||
using _required_tables = _required_tables;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
};
|
||||
};
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
// REMOVE
|
||||
template<typename Db, typename... Policies>
|
||||
struct remove_t:
|
||||
public Policies...,
|
||||
public detail::remove_policies_t<Db, Policies...>::_methods_t
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.remove(_get_statement()))
|
||||
{
|
||||
using _policies_t = typename detail::remove_policies_t<Db, Policies...>;
|
||||
using _database_t = typename _policies_t::_database_t;
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<_database_t, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<remove_t>::type;
|
||||
|
||||
// Constructors
|
||||
constexpr remove_t()
|
||||
{}
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
remove_t(Statement statement, Term term):
|
||||
Policies(detail::pick_arg<Policies>(statement, term))...
|
||||
{}
|
||||
|
||||
remove_t(const remove_t&) = default;
|
||||
remove_t(remove_t&&) = default;
|
||||
remove_t& operator=(const remove_t&) = default;
|
||||
remove_t& operator=(remove_t&&) = default;
|
||||
~remove_t() = default;
|
||||
|
||||
// run and prepare
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
#warning reactivate checks
|
||||
#if 0
|
||||
static_assert(is_where_t<_where_t>::value, "cannot run update without having a where condition, use .where(true) to update all rows");
|
||||
|
||||
// FIXME: Read more details about what is allowed and what not in SQL DELETE
|
||||
static_assert(is_table_subset_of_table<_where_t>::value, "where requires additional tables");
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
std::size_t _run(Database& db) const
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead");
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead");
|
||||
return db.remove(*this);
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
auto _prepare(Database& db) const
|
||||
-> prepared_remove_t<Database, remove_t>
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_remove_t<Db, remove_t>
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
return {{}, db.prepare_remove(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, remove_t<Database, Policies...>>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, remove_name_t>
|
||||
{
|
||||
using T = remove_t<Database, Policies...>;
|
||||
using T = remove_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "DELETE FROM ";
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const Policies&>(t), context), 0)...};
|
||||
context << "DELETE";
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_remove_t = remove_t<Database,
|
||||
vendor::no_single_table_t,
|
||||
using blank_remove_t = statement_t<Database,
|
||||
remove_t,
|
||||
vendor::no_from_t,
|
||||
vendor::no_using_t,
|
||||
vendor::no_extra_tables_t,
|
||||
vendor::no_where_t>;
|
||||
|
||||
constexpr auto remove()
|
||||
auto remove()
|
||||
-> blank_remove_t<void>
|
||||
{
|
||||
return { blank_remove_t<void>() };
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
constexpr auto remove_from(Table table)
|
||||
auto remove_from(Table table)
|
||||
-> decltype(blank_remove_t<void>().from(table))
|
||||
{
|
||||
return { blank_remove_t<void>().from(table) };
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
constexpr auto dynamic_remove(const Database&)
|
||||
auto dynamic_remove(const Database&)
|
||||
-> decltype(blank_remove_t<Database>())
|
||||
{
|
||||
return { blank_remove_t<Database>() };
|
||||
}
|
||||
|
||||
template<typename Database, typename Table>
|
||||
constexpr auto dynamic_remove_from(const Database&, Table table)
|
||||
auto dynamic_remove_from(const Database&, Table table)
|
||||
-> decltype(blank_remove_t<Database>().from(table))
|
||||
{
|
||||
return { blank_remove_t<Database>().from(table) };
|
||||
|
@ -27,9 +27,7 @@
|
||||
#ifndef SQLPP_SELECT_H
|
||||
#define SQLPP_SELECT_H
|
||||
|
||||
#include <sqlpp11/result.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_select.h>
|
||||
#include <sqlpp11/statement.h>
|
||||
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/select_flag_list.h>
|
||||
@ -43,221 +41,35 @@
|
||||
#include <sqlpp11/vendor/limit.h>
|
||||
#include <sqlpp11/vendor/offset.h>
|
||||
#include <sqlpp11/vendor/expression.h>
|
||||
#include <sqlpp11/vendor/serializer.h>
|
||||
#include <sqlpp11/vendor/wrong.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
#include <sqlpp11/detail/get_last.h>
|
||||
#include <sqlpp11/detail/pick_arg.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename... Policies>
|
||||
struct select_t;
|
||||
struct select_name_t {};
|
||||
|
||||
#warning STEPS:
|
||||
#warning deal with different return types in the connector (select could be a single value, update could be a range of rows)
|
||||
namespace detail
|
||||
{
|
||||
template<typename Db = void, typename... Policies>
|
||||
struct select_policies_t
|
||||
{
|
||||
using _database_t = Db;
|
||||
using _statement_t = select_t<Db, Policies...>;
|
||||
|
||||
struct _methods_t: public Policies::template _methods_t<select_policies_t>...
|
||||
struct select_t: public vendor::statement_name_t<select_name_t>
|
||||
{};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
struct _policies_update_t
|
||||
{
|
||||
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
||||
using type = select_t<Db, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _new_statement_t = typename _policies_update_t<Needle, Replacement>::type;
|
||||
|
||||
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
|
||||
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
|
||||
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
|
||||
|
||||
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
|
||||
|
||||
template<typename Expression>
|
||||
using _no_unknown_tables = detail::is_subset_of<required_tables_of<Expression>, _known_tables>;
|
||||
|
||||
// The tables not covered by the from.
|
||||
using _required_tables = detail::make_difference_set_t<
|
||||
_all_required_tables,
|
||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||
>;
|
||||
|
||||
using _result_type_provider = detail::get_last_if<is_return_value_t, vendor::no_select_column_list_t, Policies...>;
|
||||
|
||||
// A select can be used as a pseudo table if
|
||||
// - at least one column is selected
|
||||
// - the select is complete (leaks no tables)
|
||||
using _can_be_used_as_table = typename std::conditional<
|
||||
is_select_column_list_t<_result_type_provider>::value and _required_tables::size::value == 0,
|
||||
std::true_type,
|
||||
std::false_type
|
||||
>::type;
|
||||
|
||||
using _value_type = typename std::conditional<
|
||||
detail::none_t<is_missing_t<Policies>::value...>::value,
|
||||
value_type_of<_result_type_provider>,
|
||||
no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value
|
||||
>::type;
|
||||
|
||||
using _is_expression = typename std::conditional<
|
||||
std::is_same<_value_type, no_value_t>::value,
|
||||
std::false_type,
|
||||
std::true_type>::type;
|
||||
|
||||
using _traits = make_traits<_value_type>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>; // FIXME
|
||||
using _required_tables = _required_tables;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// SELECT
|
||||
template<typename Db,
|
||||
typename... Policies
|
||||
>
|
||||
struct select_t:
|
||||
public Policies...,
|
||||
public detail::select_policies_t<Db, Policies...>::_value_type::template expression_operators<select_t<Db, Policies...>>,
|
||||
public detail::select_policies_t<Db, Policies...>::_methods_t
|
||||
{
|
||||
using _policies_t = typename detail::select_policies_t<Db, Policies...>;
|
||||
|
||||
using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select, tag::expression_if<typename _policies_t::_is_expression>, tag::named_expression_if<typename _policies_t::_is_expression>>;
|
||||
using _recursive_traits = typename _policies_t::_recursive_traits;
|
||||
|
||||
using _database_t = Db;
|
||||
using _is_dynamic = typename std::conditional<std::is_same<_database_t, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
using _result_type_provider = typename _policies_t::_result_type_provider;
|
||||
|
||||
using _parameter_tuple_t = std::tuple<Policies...>;
|
||||
using _parameter_list_t = typename make_parameter_list_t<select_t>::type;
|
||||
|
||||
template<typename Database>
|
||||
using _result_row_t = typename _result_type_provider::template _result_row_t<Database>;
|
||||
using _dynamic_names_t = typename _result_type_provider::_dynamic_names_t;
|
||||
|
||||
using _requires_braces = std::true_type;
|
||||
|
||||
using _name_t = typename _result_type_provider::_name_t;
|
||||
|
||||
// Constructors
|
||||
select_t()
|
||||
{}
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
select_t(Statement statement, Term term):
|
||||
Policies(detail::pick_arg<Policies>(statement, term))...
|
||||
{}
|
||||
|
||||
select_t(const select_t& r) = default;
|
||||
select_t(select_t&& r) = default;
|
||||
select_t& operator=(const select_t& r) = default;
|
||||
select_t& operator=(select_t&& r) = default;
|
||||
~select_t() = default;
|
||||
|
||||
// PseudoTable
|
||||
template<typename AliasProvider>
|
||||
struct _pseudo_table_t
|
||||
{
|
||||
using table = typename _result_type_provider::template _pseudo_table_t<select_t>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
typename _pseudo_table_t<AliasProvider>::alias as(const AliasProvider& aliasProvider) const
|
||||
{
|
||||
static_assert(_policies_t::_can_be_used_as_table::value, "select cannot be used as table, incomplete from()");
|
||||
return typename _pseudo_table_t<AliasProvider>::table(
|
||||
*this).as(aliasProvider);
|
||||
}
|
||||
|
||||
const _dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
return static_cast<const _result_type_provider&>(*this)._dynamic_columns._dynamic_expression_names;
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t get_no_of_result_columns() const
|
||||
{
|
||||
return _result_type_provider::static_size() + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
#warning check for missing terms here, and for missing tables
|
||||
static_assert(not required_tables_of<_policies_t>::size::value, "one sub expression contains tables which are not in the from()");
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Database>
|
||||
auto _run(Database& db) const
|
||||
-> result_t<decltype(db.select(*this)), _result_row_t<Database>>
|
||||
{
|
||||
_check_consistency();
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
|
||||
return {db.select(*this), get_dynamic_names()};
|
||||
}
|
||||
|
||||
// Prepare
|
||||
template<typename Database>
|
||||
auto _prepare(Database& db) const
|
||||
-> prepared_select_t<Database, select_t>
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||
}
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, select_t<Database, Policies...>>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, select_name_t>
|
||||
{
|
||||
using T = select_t<Database, Policies...>;
|
||||
using T = select_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "SELECT ";
|
||||
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const Policies&>(t), context), 0)...};
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_select_t = select_t<Database,
|
||||
using blank_select_t = statement_t<Database,
|
||||
select_t,
|
||||
vendor::no_select_flag_list_t,
|
||||
vendor::no_select_column_list_t,
|
||||
vendor::no_from_t,
|
||||
|
246
include/sqlpp11/statement.h
Normal file
246
include/sqlpp11/statement.h
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_STATEMENT_H
|
||||
#define SQLPP_STATEMENT_H
|
||||
|
||||
#include <sqlpp11/result.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_select.h>
|
||||
#include <sqlpp11/serialize.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
#include <sqlpp11/vendor/serializer.h>
|
||||
|
||||
#include <sqlpp11/detail/get_last.h>
|
||||
#include <sqlpp11/detail/pick_arg.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename... Policies>
|
||||
struct statement_t;
|
||||
|
||||
#warning STEPS:
|
||||
#warning deal with different return types in the connector (select could be a single value, update could be a range of rows)
|
||||
namespace detail
|
||||
{
|
||||
template<typename Db = void, typename... Policies>
|
||||
struct statement_policies_t
|
||||
{
|
||||
#warning need to check policies' signature, e.g. a _data_t in _member_t template
|
||||
using _database_t = Db;
|
||||
using _statement_t = statement_t<Db, Policies...>;
|
||||
|
||||
struct _methods_t: public Policies::template _methods_t<statement_policies_t>...
|
||||
{};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
struct _policies_update_t
|
||||
{
|
||||
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
||||
using type = statement_t<Db, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _new_statement_t = typename _policies_update_t<Needle, Replacement>::type;
|
||||
|
||||
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
|
||||
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
|
||||
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
|
||||
|
||||
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
|
||||
|
||||
template<typename Expression>
|
||||
using _no_unknown_tables = detail::is_subset_of<required_tables_of<Expression>, _known_tables>;
|
||||
|
||||
// The tables not covered by the from.
|
||||
using _required_tables = detail::make_difference_set_t<
|
||||
_all_required_tables,
|
||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||
>;
|
||||
|
||||
using _result_type_provider = detail::get_last_if<is_return_value_t, vendor::noop, Policies...>;
|
||||
|
||||
struct _result_methods_t: public _result_type_provider::template _result_methods_t<statement_policies_t>
|
||||
{};
|
||||
|
||||
|
||||
// A select can be used as a pseudo table if
|
||||
// - at least one column is selected
|
||||
// - the select is complete (leaks no tables)
|
||||
using _can_be_used_as_table = typename std::conditional<
|
||||
is_select_column_list_t<_result_type_provider>::value and _required_tables::size::value == 0,
|
||||
std::true_type,
|
||||
std::false_type
|
||||
>::type;
|
||||
|
||||
using _value_type = typename std::conditional<
|
||||
detail::none_t<is_missing_t<Policies>::value...>::value,
|
||||
value_type_of<_result_type_provider>,
|
||||
no_value_t // if a required statement part is missing (e.g. columns in a select), then the statement cannot be used as a value
|
||||
>::type;
|
||||
|
||||
using _is_expression = typename std::conditional<
|
||||
std::is_same<_value_type, no_value_t>::value,
|
||||
std::false_type,
|
||||
std::true_type>::type;
|
||||
|
||||
using _traits = make_traits<_value_type>;
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>; // FIXME
|
||||
using _required_tables = _required_tables;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Db,
|
||||
typename... Policies
|
||||
>
|
||||
struct statement_t:
|
||||
public Policies::template _member_t<detail::statement_policies_t<Db, Policies...>>...,
|
||||
public detail::statement_policies_t<Db, Policies...>::_value_type::template expression_operators<statement_t<Db, Policies...>>,
|
||||
public detail::statement_policies_t<Db, Policies...>::_result_methods_t,
|
||||
public detail::statement_policies_t<Db, Policies...>::_methods_t
|
||||
{
|
||||
using _policies_t = typename detail::statement_policies_t<Db, Policies...>;
|
||||
|
||||
using _traits = make_traits<value_type_of<_policies_t>, ::sqlpp::tag::select, tag::expression_if<typename _policies_t::_is_expression>, tag::named_expression_if<typename _policies_t::_is_expression>>;
|
||||
using _recursive_traits = typename _policies_t::_recursive_traits;
|
||||
|
||||
using _result_type_provider = typename _policies_t::_result_type_provider;
|
||||
|
||||
using _requires_braces = std::true_type;
|
||||
|
||||
using _name_t = typename _result_type_provider::_name_t;
|
||||
|
||||
// Constructors
|
||||
statement_t()
|
||||
{}
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
statement_t(Statement statement, Term term):
|
||||
Policies::template _member_t<_policies_t>{
|
||||
typename Policies::template _impl_t<_policies_t>{
|
||||
detail::pick_arg<typename Policies::template _member_t<_policies_t>>(statement, term)
|
||||
}}...
|
||||
//Policies::template _member_t<_policies_t>{{detail::pick_arg<typename Policies::template _member_t<_policies_t>>(statement, term)}}...
|
||||
{}
|
||||
|
||||
statement_t(const statement_t& r) = default;
|
||||
statement_t(statement_t&& r) = default;
|
||||
statement_t& operator=(const statement_t& r) = default;
|
||||
statement_t& operator=(statement_t&& r) = default;
|
||||
~statement_t() = default;
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _get_static_no_of_parameters();
|
||||
}
|
||||
|
||||
static void _check_consistency()
|
||||
{
|
||||
// FIXME: Check each "methods" or each member...
|
||||
#warning check for missing terms here, and for missing tables
|
||||
static_assert(not required_tables_of<_policies_t>::size::value, "one sub expression requires tables which are otherwise not known in the statement");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, statement_t<Database, Policies...>>
|
||||
{
|
||||
using T = statement_t<Database, Policies...>;
|
||||
using P = ::sqlpp::detail::statement_policies_t<Database, Policies...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const typename Policies::template _member_t<P>&>(t)()._data, context), 0)...};
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename NameData>
|
||||
struct statement_name_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = NameData;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = NameData;
|
||||
|
||||
_impl_t<Policies> statement_name;
|
||||
_impl_t<Policies>& operator()() { return statement_name; }
|
||||
const _impl_t<Policies>& operator()() const { return statement_name; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.statement_name)
|
||||
{
|
||||
return t.statement_name;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -34,7 +34,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Flag, typename Expr>
|
||||
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>
|
||||
struct sum_t: public value_type_of<Expr>::template expression_operators<sum_t<Flag, Expr>>,
|
||||
public alias_operators<sum_t<Flag, Expr>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<Expr>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Expr>;
|
||||
|
@ -35,10 +35,8 @@
|
||||
|
||||
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>>...
|
||||
struct table_alias_t: public ColumnSpec::_name_t::template _member_t<column_t<AliasProvider, ColumnSpec>>...
|
||||
{
|
||||
//FIXME: Need to add join functionality
|
||||
using _traits = make_traits<value_type_of<Table>, tag::table, tag::alias, tag::named_expression_if<is_expression_t<Table>>>;
|
||||
@ -65,10 +63,10 @@ namespace sqlpp
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename X>
|
||||
struct serializer_t<Context, X, typename std::enable_if<std::is_base_of<table_alias_base_t, X>::value, void>::type>
|
||||
template<typename Context, typename AliasProvider, typename Table, typename... ColumnSpec>
|
||||
struct serializer_t<Context, table_alias_t<AliasProvider, Table, ColumnSpec...>>
|
||||
{
|
||||
using T = X;
|
||||
using T = table_alias_t<AliasProvider, Table, ColumnSpec...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ namespace sqlpp
|
||||
using _traits = make_traits<value_type_of<Operand>, tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
||||
using _operand_t = Operand;
|
||||
|
||||
tvin_t(Operand operand):
|
||||
_value(operand)
|
||||
{}
|
||||
|
@ -88,6 +88,7 @@ namespace sqlpp
|
||||
detail::is_element_of<tag::integral, typename T::_traits::_tags>::value,
|
||||
detail::is_element_of<tag::floating_point, typename T::_traits::_tags>::value>;
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(text);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(wrapped_value);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(expression);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(named_expression);
|
||||
namespace tag
|
||||
@ -122,6 +123,7 @@ namespace sqlpp
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(select_column_list);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(from);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(single_table);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(into);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(extra_tables);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(on);
|
||||
SQLPP_IS_VALUE_TRAIT_GENERATOR(dynamic);
|
||||
|
@ -27,6 +27,8 @@
|
||||
#ifndef SQLPP_UPDATE_H
|
||||
#define SQLPP_UPDATE_H
|
||||
|
||||
#include <sqlpp11/statement.h>
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/parameter_list.h>
|
||||
#include <sqlpp11/prepared_update.h>
|
||||
@ -34,153 +36,68 @@
|
||||
#include <sqlpp11/vendor/update_list.h>
|
||||
#include <sqlpp11/vendor/noop.h>
|
||||
#include <sqlpp11/vendor/where.h>
|
||||
#include <sqlpp11/vendor/policy_update.h>
|
||||
|
||||
#include <sqlpp11/detail/get_last.h>
|
||||
#include <sqlpp11/detail/pick_arg.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
template<typename Db, typename... Policies>
|
||||
struct update_t;
|
||||
struct update_name_t {};
|
||||
|
||||
namespace detail
|
||||
struct update_t: public vendor::statement_name_t<update_name_t>
|
||||
{
|
||||
template<typename Db = void, typename... Policies>
|
||||
struct update_policies_t
|
||||
using _traits = make_traits<no_value_t, tag::return_value>;
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _database_t = Db;
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
using _statement_t = update_t<Db, Policies...>;
|
||||
|
||||
struct _methods_t: public Policies::template _methods_t<update_policies_t>...
|
||||
{};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
struct _policies_update_t
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
static_assert(detail::is_element_of<Needle, make_type_set_t<Policies...>>::value, "policies update for non-policy class detected");
|
||||
using type = update_t<Db, vendor::policy_update_t<Policies, Needle, Replacement>...>;
|
||||
};
|
||||
|
||||
template<typename Needle, typename Replacement>
|
||||
using _new_statement_t = typename _policies_update_t<Needle, Replacement>::type;
|
||||
|
||||
using _all_required_tables = detail::make_joined_set_t<required_tables_of<Policies>...>;
|
||||
using _all_provided_tables = detail::make_joined_set_t<provided_tables_of<Policies>...>;
|
||||
using _all_extra_tables = detail::make_joined_set_t<extra_tables_of<Policies>...>;
|
||||
|
||||
using _known_tables = detail::make_joined_set_t<_all_provided_tables, _all_extra_tables>;
|
||||
|
||||
template<typename Expression>
|
||||
using _no_unknown_tables = detail::is_subset_of<required_tables_of<Expression>, _known_tables>;
|
||||
|
||||
// The tables not covered by the from.
|
||||
using _required_tables = detail::make_difference_set_t<
|
||||
_all_required_tables,
|
||||
_all_provided_tables // Hint: extra_tables are not used here because they are just a helper for dynamic .add_*()
|
||||
>;
|
||||
|
||||
using _traits = make_traits<no_value_t>; // FIXME
|
||||
|
||||
struct _recursive_traits
|
||||
{
|
||||
using _parameters = std::tuple<>; // FIXME
|
||||
using _required_tables = _required_tables;
|
||||
using _provided_tables = detail::type_set<>;
|
||||
using _extra_tables = detail::type_set<>;
|
||||
};
|
||||
};
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
// UPDATE
|
||||
template<typename Db, typename... Policies>
|
||||
struct update_t:
|
||||
public Policies...,
|
||||
public detail::update_policies_t<Db, Policies...>::_methods_t
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.update(_get_statement()))
|
||||
{
|
||||
using _policies_t = typename detail::update_policies_t<Db, Policies...>;
|
||||
using _database_t = typename _policies_t::_database_t;
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<_database_t, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
using _parameter_list_t = typename make_parameter_list_t<update_t>::type;
|
||||
|
||||
// Constructors
|
||||
constexpr update_t()
|
||||
{}
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
update_t(Statement statement, Term term):
|
||||
Policies(detail::pick_arg<Policies>(statement, term))...
|
||||
{}
|
||||
|
||||
update_t(const update_t&) = default;
|
||||
update_t(update_t&&) = default;
|
||||
update_t& operator=(const update_t&) = default;
|
||||
update_t& operator=(update_t&&) = default;
|
||||
~update_t() = default;
|
||||
|
||||
// run and prepare
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
#warning reactivate tests
|
||||
/*
|
||||
static_assert(is_where_t<_where_t>::value, "cannot run update without having a where condition, use .where(true) to update all rows");
|
||||
|
||||
static_assert(is_table_subset_of_table<_update_list_t>::value, "updates require additional tables");
|
||||
static_assert(is_table_subset_of_table<_where_t>::value, "where requires additional tables");
|
||||
*/
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
std::size_t _run(Database& db) const
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead");
|
||||
return db.update(*this);
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
auto _prepare(Database& db) const
|
||||
-> prepared_update_t<Database, update_t>
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_update_t<Db, update_t>
|
||||
{
|
||||
_check_consistency();
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, db.prepare_update(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Context, typename Database, typename... Policies>
|
||||
struct serializer_t<Context, update_t<Database, Policies...>>
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, update_name_t>
|
||||
{
|
||||
using T = update_t<Database, Policies...>;
|
||||
using T = update_name_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << "UPDATE ";
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const Policies&>(t), context), 0)...};
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Database>
|
||||
using blank_update_t = update_t<Database,
|
||||
using blank_update_t = statement_t<Database,
|
||||
update_t,
|
||||
vendor::no_single_table_t,
|
||||
vendor::no_update_list_t,
|
||||
vendor::no_where_t>;
|
||||
|
3
include/sqlpp11/vendor/concat.h
vendored
3
include/sqlpp11/vendor/concat.h
vendored
@ -37,7 +37,8 @@ namespace sqlpp
|
||||
{
|
||||
// FIXME: Remove First, inherit from text_t
|
||||
template<typename First, typename... Args>
|
||||
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>
|
||||
struct concat_t: public value_type_of<First>::template expression_operators<concat_t<First, Args...>>,
|
||||
public alias_operators<concat_t<First, Args...>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<First>, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<First, Args...>;
|
||||
|
15
include/sqlpp11/vendor/expression.h
vendored
15
include/sqlpp11/vendor/expression.h
vendored
@ -40,7 +40,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct binary_expression_t<Lhs, op::equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<equal_to_t<Lhs, Rhs>>
|
||||
struct binary_expression_t<Lhs, op::equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>,
|
||||
public alias_operators<binary_expression_t<Lhs, op::equal_to, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
@ -84,7 +85,8 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<not_equal_to_t<Lhs, Rhs>>
|
||||
struct binary_expression_t<Lhs, op::not_equal_to, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>,
|
||||
public alias_operators<binary_expression_t<Lhs, op::not_equal_to, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
@ -128,7 +130,8 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Rhs>
|
||||
struct unary_expression_t<op::logical_not, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<logical_not_t<Rhs>>
|
||||
struct unary_expression_t<op::logical_not, Rhs>: public ::sqlpp::detail::boolean::template expression_operators<unary_expression_t<op::logical_not, Rhs>>,
|
||||
public alias_operators<unary_expression_t<op::logical_not, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<boolean, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
@ -162,7 +165,8 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Lhs, typename O, typename Rhs>
|
||||
struct binary_expression_t: public value_type_of<O>::template expression_operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
struct binary_expression_t: public value_type_of<O>::template expression_operators<binary_expression_t<Lhs, O, Rhs>>,
|
||||
public alias_operators<binary_expression_t<Lhs, O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Lhs, Rhs>;
|
||||
@ -199,7 +203,8 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename O, typename Rhs>
|
||||
struct unary_expression_t: public O::_value_type::template expression_operators<unary_expression_t<O, Rhs>>
|
||||
struct unary_expression_t: public value_type_of<O>::template expression_operators<unary_expression_t<O, Rhs>>,
|
||||
public alias_operators<unary_expression_t<O, Rhs>>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<O>, sqlpp::tag::expression>;
|
||||
using _recursive_traits = make_recursive_traits<Rhs>;
|
||||
|
92
include/sqlpp11/vendor/extra_tables.h
vendored
92
include/sqlpp11/vendor/extra_tables.h
vendored
@ -35,6 +35,20 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
template<typename... Tables>
|
||||
struct extra_tables_data_t
|
||||
{
|
||||
extra_tables_data_t()
|
||||
{}
|
||||
|
||||
extra_tables_data_t(const extra_tables_data_t&) = default;
|
||||
extra_tables_data_t(extra_tables_data_t&&) = default;
|
||||
extra_tables_data_t& operator=(const extra_tables_data_t&) = default;
|
||||
extra_tables_data_t& operator=(extra_tables_data_t&&) = default;
|
||||
~extra_tables_data_t() = default;
|
||||
|
||||
};
|
||||
|
||||
// EXTRA_TABLES
|
||||
template<typename... Tables>
|
||||
struct extra_tables_t
|
||||
@ -56,26 +70,73 @@ namespace sqlpp
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Tables...>::value, "at least one duplicate argument detected in extra_tables()");
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not a table or join in extra_tables()");
|
||||
|
||||
extra_tables_t()
|
||||
{}
|
||||
// Data
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
extra_tables_t(const extra_tables_t&) = default;
|
||||
extra_tables_t(extra_tables_t&&) = default;
|
||||
extra_tables_t& operator=(const extra_tables_t&) = default;
|
||||
extra_tables_t& operator=(extra_tables_t&&) = default;
|
||||
~extra_tables_t() = default;
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = extra_tables_data_t<Tables...>;
|
||||
|
||||
_impl_t<Policies> extra_tables;
|
||||
_impl_t<Policies>& operator()() { return extra_tables; }
|
||||
const _impl_t<Policies>& operator()() const { return extra_tables; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.extra_tables)
|
||||
{
|
||||
return t.extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO EXTRA TABLES YET
|
||||
struct no_extra_tables_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_extra_tables;
|
||||
_impl_t<Policies>& operator()() { return no_extra_tables; }
|
||||
const _impl_t<Policies>& operator()() const { return no_extra_tables; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_extra_tables)
|
||||
{
|
||||
return t.no_extra_tables;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -86,27 +147,16 @@ namespace sqlpp
|
||||
auto extra_tables(Args...)
|
||||
-> _new_statement_t<extra_tables_t<Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_t<Args...>{} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), extra_tables_data_t<Args...>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, extra_tables_t<Database, Tables...>>
|
||||
struct serializer_t<Context, extra_tables_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = extra_tables_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_extra_tables_t>
|
||||
{
|
||||
using T = no_extra_tables_t;
|
||||
using T = extra_tables_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
123
include/sqlpp11/vendor/from.h
vendored
123
include/sqlpp11/vendor/from.h
vendored
@ -37,6 +37,24 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// FROM DATA
|
||||
template<typename Database, typename... Tables>
|
||||
struct from_data_t
|
||||
{
|
||||
from_data_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
{}
|
||||
|
||||
from_data_t(const from_data_t&) = default;
|
||||
from_data_t(from_data_t&&) = default;
|
||||
from_data_t& operator=(const from_data_t&) = default;
|
||||
from_data_t& operator=(from_data_t&&) = default;
|
||||
~from_data_t() = default;
|
||||
|
||||
std::tuple<Tables...> _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
// FROM
|
||||
template<typename Database, typename... Tables>
|
||||
struct from_t
|
||||
@ -55,45 +73,61 @@ namespace sqlpp
|
||||
|
||||
static_assert(required_tables_of<from_t>::size::value == 0, "at least one table depends on another table");
|
||||
|
||||
from_t& _from() { return *this; }
|
||||
|
||||
from_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
{}
|
||||
|
||||
from_t(const from_t&) = default;
|
||||
from_t(from_t&&) = default;
|
||||
from_t& operator=(const from_t&) = default;
|
||||
from_t& operator=(from_t&&) = default;
|
||||
~from_t() = default;
|
||||
// Data
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Table>
|
||||
void add_from(Table table)
|
||||
void add(Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_from must not be called for static from()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in add_from()");
|
||||
static_assert(_is_dynamic::value, "from::add() must not be called for static from()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in from::add()");
|
||||
#warning need to check if table is already known
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
_add_from_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Table>
|
||||
void _add_from_impl(Table table, const std::true_type&)
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_from()._dynamic_tables.emplace_back(table);
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
void _add_from_impl(Table table, const std::false_type&);
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
std::tuple<Tables...> _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = from_data_t<Database, Tables...>;
|
||||
|
||||
_impl_t<Policies> from;
|
||||
_impl_t<Policies>& operator()() { return from; }
|
||||
const _impl_t<Policies>& operator()() const { return from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.from)
|
||||
{
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_from_t
|
||||
@ -101,6 +135,34 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_from)
|
||||
{
|
||||
return t.no_from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -112,7 +174,7 @@ namespace sqlpp
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<from_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -120,16 +182,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<from_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_from must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::from_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), from_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, from_t<Database, Tables...>>
|
||||
struct serializer_t<Context, from_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = from_t<Database, Tables...>;
|
||||
using T = from_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -144,17 +206,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_from_t>
|
||||
{
|
||||
using T = no_from_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
128
include/sqlpp11/vendor/group_by.h
vendored
128
include/sqlpp11/vendor/group_by.h
vendored
@ -39,6 +39,24 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// GROUP BY DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_data_t
|
||||
{
|
||||
group_by_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
group_by_data_t(const group_by_data_t&) = default;
|
||||
group_by_data_t(group_by_data_t&&) = default;
|
||||
group_by_data_t& operator=(const group_by_data_t&) = default;
|
||||
group_by_data_t& operator=(group_by_data_t&&) = default;
|
||||
~group_by_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// GROUP BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct group_by_t
|
||||
@ -54,60 +72,100 @@ namespace sqlpp
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in group_by()");
|
||||
|
||||
group_by_t& _group_by() { return *this; }
|
||||
|
||||
group_by_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
group_by_t(const group_by_t&) = default;
|
||||
group_by_t(group_by_t&&) = default;
|
||||
group_by_t& operator=(const group_by_t&) = default;
|
||||
group_by_t& operator=(group_by_t&&) = default;
|
||||
~group_by_t() = default;
|
||||
// Data
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_group_by_ntc(Expression expression)
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add_group_by<Expression, std::false_type>(expression);
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add_group_by(Expression expression)
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_group_by must not be called for static group_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_group_by()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_group_by()");
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static group_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in group_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in group_by::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_group_by_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_group_by_impl(Expression expression, const std::true_type&)
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_group_by()._dynamic_expressions.emplace_back(expression);
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_group_by_impl(Expression expression, const std::false_type&);
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
const group_by_t& _group_by() const { return *this; }
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> group_by;
|
||||
_impl_t<Policies>& operator()() { return group_by; }
|
||||
const _impl_t<Policies>& operator()() const { return group_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.group_by)
|
||||
{
|
||||
return t.group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO GROUP BY YET
|
||||
struct no_group_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_group_by;
|
||||
_impl_t<Policies>& operator()() { return no_group_by; }
|
||||
const _impl_t<Policies>& operator()() const { return no_group_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_group_by)
|
||||
{
|
||||
return t.no_group_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -119,7 +177,7 @@ namespace sqlpp
|
||||
auto group_by(Args... args)
|
||||
-> _new_statement_t<group_by_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -127,16 +185,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<group_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_group_by must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::group_by_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), group_by_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, group_by_t<Database, Expressions...>>
|
||||
struct serializer_t<Context, group_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = group_by_t<Database, Expressions...>;
|
||||
using T = group_by_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -150,18 +208,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_group_by_t>
|
||||
{
|
||||
using T = no_group_by_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
129
include/sqlpp11/vendor/having.h
vendored
129
include/sqlpp11/vendor/having.h
vendored
@ -38,6 +38,24 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// HAVING DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_data_t
|
||||
{
|
||||
having_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
having_data_t(const having_data_t&) = default;
|
||||
having_data_t(having_data_t&&) = default;
|
||||
having_data_t& operator=(const having_data_t&) = default;
|
||||
having_data_t& operator=(having_data_t&&) = default;
|
||||
~having_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// HAVING
|
||||
template<typename Database, typename... Expressions>
|
||||
struct having_t
|
||||
@ -50,59 +68,102 @@ namespace sqlpp
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in having()");
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in having()");
|
||||
|
||||
having_t& _having() { return *this; }
|
||||
|
||||
having_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
having_t(const having_t&) = default;
|
||||
having_t(having_t&&) = default;
|
||||
having_t& operator=(const having_t&) = default;
|
||||
having_t& operator=(having_t&&) = default;
|
||||
~having_t() = default;
|
||||
// Data
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_having_ntc(Expression expression)
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add_having<Expression, std::false_type>(expression);
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add_having(Expression expression)
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_having must not be called for static having");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_having()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_having()");
|
||||
static_assert(_is_dynamic::value, "having::add() can only be called for dynamic_having");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in having::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in having::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_having_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_having_impl(Expression expression, const std::true_type&)
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_having()._dynamic_expressions.emplace_back(expression);
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_having_impl(Expression expression, const std::false_type&);
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = having_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> having;
|
||||
_impl_t<Policies>& operator()() { return having; }
|
||||
const _impl_t<Policies>& operator()() const { return having; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.having)
|
||||
{
|
||||
return t.having;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO HAVING YET
|
||||
struct no_having_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_having;
|
||||
_impl_t<Policies>& operator()() { return no_having; }
|
||||
const _impl_t<Policies>& operator()() const { return no_having; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_having)
|
||||
{
|
||||
return t.no_having;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -114,7 +175,7 @@ namespace sqlpp
|
||||
auto having(Args... args)
|
||||
-> _new_statement_t<having_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -122,16 +183,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<having_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_having must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::having_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), having_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, having_t<Database, Expressions...>>
|
||||
struct serializer_t<Context, having_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = having_t<Database, Expressions...>;
|
||||
using T = having_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -145,18 +206,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_having_t>
|
||||
{
|
||||
using T = no_having_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
3
include/sqlpp11/vendor/in.h
vendored
3
include/sqlpp11/vendor/in.h
vendored
@ -37,7 +37,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<bool NotInverted, typename Operand, typename... Args>
|
||||
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>
|
||||
struct in_t: public boolean::template expression_operators<in_t<NotInverted, Operand, Args...>>,
|
||||
public alias_operators<in_t<NotInverted, Operand, Args...>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Args...>;
|
||||
|
260
include/sqlpp11/vendor/insert_value_list.h
vendored
260
include/sqlpp11/vendor/insert_value_list.h
vendored
@ -39,17 +39,69 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
struct insert_default_values_data_t
|
||||
{};
|
||||
|
||||
// COLUMN AND VALUE LIST
|
||||
struct insert_default_values_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = insert_default_values_data_t;
|
||||
|
||||
_impl_t<Policies> default_values;
|
||||
_impl_t<Policies>& operator()() { return default_values; }
|
||||
const _impl_t<Policies>& operator()() const { return default_values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.default_values)
|
||||
{
|
||||
return t.default_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_data_t
|
||||
{
|
||||
insert_list_data_t(Assignments... assignments):
|
||||
_assignments(assignments...),
|
||||
_columns({assignments._lhs}...),
|
||||
_values(assignments._rhs...)
|
||||
{}
|
||||
|
||||
insert_list_data_t(const insert_list_data_t&) = default;
|
||||
insert_list_data_t(insert_list_data_t&&) = default;
|
||||
insert_list_data_t& operator=(const insert_list_data_t&) = default;
|
||||
insert_list_data_t& operator=(insert_list_data_t&&) = default;
|
||||
~insert_list_data_t() = default;
|
||||
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::_value_t...> _values;
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_columns;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
template<typename Database, typename... Assignments>
|
||||
struct insert_list_t
|
||||
{
|
||||
@ -81,36 +133,26 @@ namespace sqlpp
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_required_tables, _column_required_tables>::value, "set() contains values from foreign tables");
|
||||
*/
|
||||
|
||||
insert_list_t& _insert_value_list() { return *this; }
|
||||
|
||||
insert_list_t(Assignments... assignment):
|
||||
_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;
|
||||
// Data
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Assignment>
|
||||
void add_set_ntc(Assignment assignment)
|
||||
void add_ntc(Assignment assignment)
|
||||
{
|
||||
add_set<Assignment, std::false_type>(assignment);
|
||||
add<Assignment, std::false_type>(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||
void add_set(Assignment assignment)
|
||||
void add(Assignment assignment)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_set must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "add_set() arguments require to be assigments");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_column_t>::value, "add_set() argument must not be used in insert");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add_set() contains a column from a foreign table");
|
||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "add() arguments require to be assigments");
|
||||
static_assert(not must_not_insert_t<typename Assignment::_column_t>::value, "add() argument must not be used in insert");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "add() contains a column from a foreign table");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
_is_dynamic::value,
|
||||
@ -118,28 +160,67 @@ namespace sqlpp
|
||||
not must_not_insert_t<typename Assignment::_column_t>::value,
|
||||
(not TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value)>;
|
||||
|
||||
_add_set_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Assignment>
|
||||
void _add_set_impl(Assignment assignment, const std::true_type&)
|
||||
void _add_impl(Assignment assignment, const std::true_type&)
|
||||
{
|
||||
static_cast<typename Policies::_statement_t*>(this)->_insert_value_list()._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||
static_cast<typename Policies::_statement_t*>(this)->_insert_value_list()._dynamic_values.emplace_back(assignment._rhs);
|
||||
_data._dynamic_columns.emplace_back(simple_column_t<typename Assignment::_column_t>{assignment._lhs});
|
||||
_data._dynamic_values.emplace_back(assignment._rhs);
|
||||
}
|
||||
|
||||
template<typename Assignment>
|
||||
void _add_set_impl(Assignment assignment, const std::false_type&);
|
||||
void _add_impl(Assignment assignment, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
_impl_t<Policies> insert_list;
|
||||
_impl_t<Policies>& operator()() { return insert_list; }
|
||||
const _impl_t<Policies>& operator()() const { return insert_list; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.insert_list)
|
||||
{
|
||||
return t.insert_list;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
||||
std::tuple<simple_column_t<typename Assignments::_column_t>...> _columns;
|
||||
std::tuple<typename Assignments::_value_t...> _values;
|
||||
std::tuple<Assignments...> _assignments; // FIXME: Need to replace _columns and _values by _assignments (connector-container requires assignments)
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_columns;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_values;
|
||||
};
|
||||
|
||||
template<typename... Columns>
|
||||
struct column_list_data_t
|
||||
{
|
||||
column_list_data_t(Columns... columns):
|
||||
_columns(simple_column_t<Columns>{columns}...)
|
||||
{}
|
||||
|
||||
column_list_data_t(const column_list_data_t&) = default;
|
||||
column_list_data_t(column_list_data_t&&) = default;
|
||||
column_list_data_t& operator=(const column_list_data_t&) = default;
|
||||
column_list_data_t& operator=(column_list_data_t&&) = default;
|
||||
~column_list_data_t() = default;
|
||||
|
||||
#warning need to define just one version of value_tuple_t
|
||||
using _value_tuple_t = std::tuple<vendor::insert_value_t<Columns>...>;
|
||||
std::tuple<simple_column_t<Columns>...> _columns;
|
||||
std::vector<_value_tuple_t> _insert_values;
|
||||
};
|
||||
|
||||
template<typename... Columns>
|
||||
@ -160,23 +241,15 @@ namespace sqlpp
|
||||
|
||||
static_assert(required_tables_of<column_list_t>::size::value == 1, "columns from multiple tables in columns()");
|
||||
|
||||
column_list_t& _insert_value_list() { return *this; }
|
||||
|
||||
column_list_t(Columns... columns):
|
||||
_columns(simple_column_t<Columns>{columns}...)
|
||||
{}
|
||||
|
||||
column_list_t(const column_list_t&) = default;
|
||||
column_list_t(column_list_t&&) = default;
|
||||
column_list_t& operator=(const column_list_t&) = default;
|
||||
column_list_t& operator=(column_list_t&&) = default;
|
||||
~column_list_t() = default;
|
||||
// Data
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename... Assignments>
|
||||
void add_values(Assignments... assignments)
|
||||
void add(Assignments... assignments)
|
||||
{
|
||||
static_assert(::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value, "add_values() arguments have to be assignments");
|
||||
using _arg_value_tuple = std::tuple<vendor::insert_value_t<typename Assignments::_column_t>...>;
|
||||
@ -187,35 +260,87 @@ namespace sqlpp
|
||||
::sqlpp::detail::all_t<is_assignment_t<Assignments>::value...>::value,
|
||||
_args_correct::value>;
|
||||
|
||||
_add_values_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(ok(), assignments...); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename... Assignments>
|
||||
void _add_values_impl(const std::true_type&, Assignments... assignments)
|
||||
void _add_impl(const std::true_type&, Assignments... assignments)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_insert_value_list()._insert_values.emplace_back(vendor::insert_value_t<typename Assignments::_column_t>{assignments}...);
|
||||
return _data._insert_values.emplace_back(vendor::insert_value_t<typename Assignments::_column_t>{assignments}...);
|
||||
}
|
||||
|
||||
template<typename... Assignments>
|
||||
void _add_values_impl(const std::false_type&, Assignments... assignments);
|
||||
void _add_impl(const std::false_type&, Assignments... assignments);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = column_list_data_t<Columns...>;
|
||||
|
||||
_impl_t<Policies> values;
|
||||
_impl_t<Policies>& operator()() { return values; }
|
||||
const _impl_t<Policies>& operator()() const { return values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.values)
|
||||
{
|
||||
return t.values;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
/*
|
||||
bool empty() const
|
||||
{
|
||||
return _insert_values.empty();
|
||||
}
|
||||
|
||||
std::tuple<simple_column_t<Columns>...> _columns;
|
||||
std::vector<_value_tuple_t> _insert_values;
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
// NO HAVING YET
|
||||
struct no_insert_value_list_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_insert_values;
|
||||
_impl_t<Policies>& operator()() { return no_insert_values; }
|
||||
const _impl_t<Policies>& operator()() const { return no_insert_values; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_insert_values)
|
||||
{
|
||||
return t.no_insert_values;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -226,21 +351,21 @@ namespace sqlpp
|
||||
auto default_values()
|
||||
-> _new_statement_t<insert_default_values_t>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_default_values_t{} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_default_values_data_t{} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto columns(Args... args)
|
||||
-> _new_statement_t<column_list_t<Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), column_list_t<Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), column_list_data_t<Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
auto set(Args... args)
|
||||
-> _new_statement_t<insert_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), insert_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -248,16 +373,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<insert_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::insert_list_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::insert_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, insert_default_values_t>
|
||||
struct serializer_t<Context, insert_default_values_data_t>
|
||||
{
|
||||
using T = insert_default_values_t;
|
||||
using T = insert_default_values_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -267,9 +392,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context, typename... Columns>
|
||||
struct serializer_t<Context, column_list_t<Columns...>>
|
||||
struct serializer_t<Context, column_list_data_t<Columns...>>
|
||||
{
|
||||
using T = column_list_t<Columns...>;
|
||||
using T = column_list_data_t<Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -294,15 +419,15 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, insert_list_t<Database, Assignments...>>
|
||||
struct serializer_t<Context, insert_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using T = insert_list_t<Database, Assignments...>;
|
||||
using T = insert_list_data_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
if (sizeof...(Assignments) + t._dynamic_columns.size() == 0)
|
||||
{
|
||||
serialize(insert_default_values_t(), context);
|
||||
serialize(insert_default_values_data_t(), context);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -322,17 +447,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_insert_value_list_t>
|
||||
{
|
||||
using T = no_insert_value_list_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
198
include/sqlpp11/vendor/into.h
vendored
Normal file
198
include/sqlpp11/vendor/into.h
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Roland Bock
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SQLPP_VENDOR_INTO_H
|
||||
#define SQLPP_VENDOR_INTO_H
|
||||
|
||||
#include <sqlpp11/type_traits.h>
|
||||
#include <sqlpp11/no_value.h>
|
||||
#include <sqlpp11/vendor/serializer.h>
|
||||
#include <sqlpp11/detail/type_set.h>
|
||||
|
||||
namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// A SINGLE TABLE DATA
|
||||
template<typename Database, typename Table>
|
||||
struct into_data_t
|
||||
{
|
||||
into_data_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
into_data_t(const into_data_t&) = default;
|
||||
into_data_t(into_data_t&&) = default;
|
||||
into_data_t& operator=(const into_data_t&) = default;
|
||||
into_data_t& operator=(into_data_t&&) = default;
|
||||
~into_data_t() = default;
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
// A SINGLE TABLE
|
||||
template<typename Database, typename Table>
|
||||
struct into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::into, tag::return_value>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = into_data_t<Database, Table>;
|
||||
|
||||
_impl_t<Policies> into;
|
||||
_impl_t<Policies>& operator()() { return into; }
|
||||
const _impl_t<Policies>& operator()() const { return into; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.into)
|
||||
{
|
||||
return t.into;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
// NO INTO YET
|
||||
struct no_into_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_into;
|
||||
_impl_t<Policies>& operator()() { return no_into; }
|
||||
const _impl_t<Policies>& operator()() const { return no_into; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_into)
|
||||
{
|
||||
return t.no_into;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
using _database_t = typename Policies::_database_t;
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_into_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto into(Args... args)
|
||||
-> _new_statement_t<into_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), into_data_t<void, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, into_data_t<Database, Table>>
|
||||
{
|
||||
using T = into_data_t<Database, Table>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
context << " INTO ";
|
||||
serialize(t._table, context);
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
3
include/sqlpp11/vendor/is_null.h
vendored
3
include/sqlpp11/vendor/is_null.h
vendored
@ -36,7 +36,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<bool NotInverted, typename Operand>
|
||||
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>
|
||||
struct is_null_t: public boolean::template expression_operators<is_null_t<NotInverted, Operand>>,
|
||||
public alias_operators<is_null_t<NotInverted, Operand>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand>;
|
||||
|
3
include/sqlpp11/vendor/like.h
vendored
3
include/sqlpp11/vendor/like.h
vendored
@ -36,7 +36,8 @@ namespace sqlpp
|
||||
namespace vendor
|
||||
{
|
||||
template<typename Operand, typename Pattern>
|
||||
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>
|
||||
struct like_t: public boolean::template expression_operators<like_t<Operand, Pattern>>,
|
||||
public alias_operators<like_t<Operand, Pattern>>
|
||||
{
|
||||
using _traits = make_traits<boolean, ::sqlpp::tag::expression, ::sqlpp::tag::named_expression>;
|
||||
using _recursive_traits = make_recursive_traits<Operand, Pattern>;
|
||||
|
186
include/sqlpp11/vendor/limit.h
vendored
186
include/sqlpp11/vendor/limit.h
vendored
@ -35,6 +35,23 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// LIMIT DATA
|
||||
template<typename Limit>
|
||||
struct limit_data_t
|
||||
{
|
||||
limit_data_t(Limit value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
limit_data_t(const limit_data_t&) = default;
|
||||
limit_data_t(limit_data_t&&) = default;
|
||||
limit_data_t& operator=(const limit_data_t&) = default;
|
||||
limit_data_t& operator=(limit_data_t&&) = default;
|
||||
~limit_data_t() = default;
|
||||
|
||||
Limit _value;
|
||||
};
|
||||
|
||||
// LIMIT
|
||||
template<typename Limit>
|
||||
struct limit_t
|
||||
@ -44,65 +61,113 @@ namespace sqlpp
|
||||
|
||||
static_assert(is_integral_t<Limit>::value, "limit requires an integral value or integral parameter");
|
||||
|
||||
limit_t(Limit value):
|
||||
_value(value)
|
||||
{}
|
||||
// Data
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
limit_t(const limit_t&) = default;
|
||||
limit_t(limit_t&&) = default;
|
||||
limit_t& operator=(const limit_t&) = default;
|
||||
limit_t& operator=(limit_t&&) = default;
|
||||
~limit_t() = default;
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = limit_data_t<Limit>;
|
||||
|
||||
_impl_t<Policies> limit;
|
||||
_impl_t<Policies>& operator()() { return limit; }
|
||||
const _impl_t<Policies>& operator()() const { return limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.limit)
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
Limit _value;
|
||||
};
|
||||
|
||||
// DYNAMIC LIMIT DATA
|
||||
template<typename Database>
|
||||
struct dynamic_limit_data_t
|
||||
{
|
||||
dynamic_limit_data_t():
|
||||
_value(noop())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Limit>
|
||||
dynamic_limit_data_t(Limit value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Limit>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_limit_data_t(const dynamic_limit_data_t&) = default;
|
||||
dynamic_limit_data_t(dynamic_limit_data_t&&) = default;
|
||||
dynamic_limit_data_t& operator=(const dynamic_limit_data_t&) = default;
|
||||
dynamic_limit_data_t& operator=(dynamic_limit_data_t&&) = default;
|
||||
~dynamic_limit_data_t() = default;
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
// DYNAMIC LIMIT
|
||||
template<typename Database>
|
||||
struct dynamic_limit_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::limit>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
dynamic_limit_t& _limit() { return *this; }
|
||||
|
||||
dynamic_limit_t():
|
||||
_value(noop())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Limit>
|
||||
dynamic_limit_t(Limit value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Limit>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_limit_t(const dynamic_limit_t&) = default;
|
||||
dynamic_limit_t(dynamic_limit_t&&) = default;
|
||||
dynamic_limit_t& operator=(const dynamic_limit_t&) = default;
|
||||
dynamic_limit_t& operator=(dynamic_limit_t&&) = default;
|
||||
~dynamic_limit_t() = default;
|
||||
// Data
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Limit>
|
||||
void set_limit(Limit value)
|
||||
void set(Limit value)
|
||||
{
|
||||
// FIXME: Make sure that Limit does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Limit>::type;
|
||||
static_cast<typename Policies::_statement_t*>(this)->_limit()._value = arg_t{value};
|
||||
static_cast<typename Policies::_statement_t*>(this)->_limit()._initialized = true;
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = dynamic_limit_data_t<Database>;
|
||||
|
||||
_impl_t<Policies> limit;
|
||||
_impl_t<Policies>& operator()() { return limit; }
|
||||
const _impl_t<Policies>& operator()() const { return limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.limit)
|
||||
{
|
||||
return t.limit;
|
||||
}
|
||||
};
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_limit_t
|
||||
@ -110,6 +175,33 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_limit;
|
||||
_impl_t<Policies>& operator()() { return no_limit; }
|
||||
const _impl_t<Policies>& operator()() const { return no_limit; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_limit)
|
||||
{
|
||||
return t.no_limit;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -121,23 +213,23 @@ namespace sqlpp
|
||||
auto limit(Arg arg)
|
||||
-> _new_statement_t<limit_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), limit_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), limit_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_limit()
|
||||
-> _new_statement_t<dynamic_limit_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_limit must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_t<_database_t>{} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_limit_data_t<_database_t>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_limit_t<Database>>
|
||||
struct serializer_t<Context, dynamic_limit_data_t<Database>>
|
||||
{
|
||||
using T = dynamic_limit_t<Database>;
|
||||
using T = dynamic_limit_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -151,9 +243,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context, typename Limit>
|
||||
struct serializer_t<Context, limit_t<Limit>>
|
||||
struct serializer_t<Context, limit_data_t<Limit>>
|
||||
{
|
||||
using T = limit_t<Limit>;
|
||||
using T = limit_data_t<Limit>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -162,18 +254,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_limit_t>
|
||||
{
|
||||
using T = no_limit_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
20
include/sqlpp11/vendor/noop.h
vendored
20
include/sqlpp11/vendor/noop.h
vendored
@ -35,10 +35,30 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
#warning: Need extra include file for no_data
|
||||
struct no_data_t {};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_data_t>
|
||||
{
|
||||
using T = no_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
struct noop
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
struct _name_t {};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{};
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
|
171
include/sqlpp11/vendor/offset.h
vendored
171
include/sqlpp11/vendor/offset.h
vendored
@ -35,6 +35,23 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// OFFSET DATA
|
||||
template<typename Offset>
|
||||
struct offset_data_t
|
||||
{
|
||||
offset_data_t(Offset value):
|
||||
_value(value)
|
||||
{}
|
||||
|
||||
offset_data_t(const offset_data_t&) = default;
|
||||
offset_data_t(offset_data_t&&) = default;
|
||||
offset_data_t& operator=(const offset_data_t&) = default;
|
||||
offset_data_t& operator=(offset_data_t&&) = default;
|
||||
~offset_data_t() = default;
|
||||
|
||||
Offset _value;
|
||||
};
|
||||
|
||||
// OFFSET
|
||||
template<typename Offset>
|
||||
struct offset_t
|
||||
@ -44,49 +61,107 @@ namespace sqlpp
|
||||
|
||||
static_assert(is_integral_t<Offset>::value, "offset requires an integral value or integral parameter");
|
||||
|
||||
offset_t(Offset value):
|
||||
_value(value)
|
||||
{}
|
||||
// Data
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
offset_t(const offset_t&) = default;
|
||||
offset_t(offset_t&&) = default;
|
||||
offset_t& operator=(const offset_t&) = default;
|
||||
offset_t& operator=(offset_t&&) = default;
|
||||
~offset_t() = default;
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = offset_data_t<Offset>;
|
||||
|
||||
_impl_t<Policies> offset;
|
||||
_impl_t<Policies>& operator()() { return offset; }
|
||||
const _impl_t<Policies>& operator()() const { return offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.offset)
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
Offset _value;
|
||||
};
|
||||
|
||||
// DYNAMIC OFFSET DATA
|
||||
template<typename Database>
|
||||
struct dynamic_offset_data_t
|
||||
{
|
||||
dynamic_offset_data_t():
|
||||
_value(noop())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Offset>
|
||||
dynamic_offset_data_t(Offset value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Offset>::type(value))
|
||||
{
|
||||
}
|
||||
|
||||
dynamic_offset_data_t(const dynamic_offset_data_t&) = default;
|
||||
dynamic_offset_data_t(dynamic_offset_data_t&&) = default;
|
||||
dynamic_offset_data_t& operator=(const dynamic_offset_data_t&) = default;
|
||||
dynamic_offset_data_t& operator=(dynamic_offset_data_t&&) = default;
|
||||
~dynamic_offset_data_t() = default;
|
||||
|
||||
bool _initialized = false;
|
||||
interpretable_t<Database> _value;
|
||||
};
|
||||
|
||||
// DYNAMIC OFFSET
|
||||
template<typename Database>
|
||||
struct dynamic_offset_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::offset>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
dynamic_offset_t& _offset() { return *this; }
|
||||
// Data
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
dynamic_offset_t():
|
||||
_value(noop())
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Offset>
|
||||
dynamic_offset_t(Offset value):
|
||||
_initialized(true),
|
||||
_value(typename wrap_operand<Offset>::type(value))
|
||||
void set(Offset value)
|
||||
{
|
||||
// FIXME: Make sure that Offset does not require external tables? Need to read up on SQL
|
||||
using arg_t = typename wrap_operand<Offset>::type;
|
||||
_data._value = arg_t{value};
|
||||
_data._initialized = true;
|
||||
}
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
dynamic_offset_t(const dynamic_offset_t&) = default;
|
||||
dynamic_offset_t(dynamic_offset_t&&) = default;
|
||||
dynamic_offset_t& operator=(const dynamic_offset_t&) = default;
|
||||
dynamic_offset_t& operator=(dynamic_offset_t&&) = default;
|
||||
~dynamic_offset_t() = default;
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = dynamic_offset_data_t<Database>;
|
||||
|
||||
_impl_t<Policies> offset;
|
||||
_impl_t<Policies>& operator()() { return offset; }
|
||||
const _impl_t<Policies>& operator()() const { return offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.offset)
|
||||
{
|
||||
return t.offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
@ -110,6 +185,33 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_offset;
|
||||
_impl_t<Policies>& operator()() { return no_offset; }
|
||||
const _impl_t<Policies>& operator()() const { return no_offset; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_offset)
|
||||
{
|
||||
return t.no_offset;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -121,23 +223,23 @@ namespace sqlpp
|
||||
auto offset(Arg arg)
|
||||
-> _new_statement_t<offset_t<typename wrap_operand<Arg>::type>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), offset_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), offset_data_t<typename wrap_operand<Arg>::type>{{arg}} };
|
||||
}
|
||||
|
||||
auto dynamic_offset()
|
||||
-> _new_statement_t<dynamic_offset_t<_database_t>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_offset must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_t<_database_t>{} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), dynamic_offset_data_t<_database_t>{} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Offset>
|
||||
struct serializer_t<Context, offset_t<Offset>>
|
||||
struct serializer_t<Context, offset_data_t<Offset>>
|
||||
{
|
||||
using T = offset_t<Offset>;
|
||||
using T = offset_data_t<Offset>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -148,9 +250,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context, typename Database>
|
||||
struct serializer_t<Context, dynamic_offset_t<Database>>
|
||||
struct serializer_t<Context, dynamic_offset_data_t<Database>>
|
||||
{
|
||||
using T = dynamic_offset_t<Database>;
|
||||
using T = dynamic_offset_data_t<Database>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -162,17 +264,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_offset_t>
|
||||
{
|
||||
using T = no_offset_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
184
include/sqlpp11/vendor/order_by.h
vendored
184
include/sqlpp11/vendor/order_by.h
vendored
@ -39,73 +39,133 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// ORDER BY DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_t
|
||||
struct order_by_data_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::group_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one sort-order expression required in order_by()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_sort_order_t<Expressions>::value...>::value, "at least one argument is not a sort order expression in order_by()");
|
||||
|
||||
order_by_t& _order_by() { return *this; }
|
||||
|
||||
order_by_t(Expressions... expressions):
|
||||
order_by_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
order_by_t(const order_by_t&) = default;
|
||||
order_by_t(order_by_t&&) = default;
|
||||
order_by_t& operator=(const order_by_t&) = default;
|
||||
order_by_t& operator=(order_by_t&&) = default;
|
||||
~order_by_t() = default;
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_order_by_ntc(Expression expression)
|
||||
{
|
||||
add_order_by<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add_order_by(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_order_by must not be called for static order_by");
|
||||
static_assert(is_sort_order_t<Expression>::value, "invalid expression argument in add_order_by()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_order_by()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_sort_order_t<Expression>::value>;
|
||||
|
||||
_add_order_by_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_order_by_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_order_by()._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_order_by_impl(Expression expression, const std::false_type&);
|
||||
};
|
||||
order_by_data_t(const order_by_data_t&) = default;
|
||||
order_by_data_t(order_by_data_t&&) = default;
|
||||
order_by_data_t& operator=(const order_by_data_t&) = default;
|
||||
order_by_data_t& operator=(order_by_data_t&&) = default;
|
||||
~order_by_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// ORDER BY
|
||||
template<typename Database, typename... Expressions>
|
||||
struct order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::order_by>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Expressions...>::value, "at least one duplicate argument detected in order_by()");
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not an expression in order_by()");
|
||||
|
||||
// Data
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add() must not be called for static order_by");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in order_by::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in order_by::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> order_by;
|
||||
_impl_t<Policies>& operator()() { return order_by; }
|
||||
const _impl_t<Policies>& operator()() const { return order_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.order_by)
|
||||
{
|
||||
return t.order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO ORDER BY YET
|
||||
struct no_order_by_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_order_by;
|
||||
_impl_t<Policies>& operator()() { return no_order_by; }
|
||||
const _impl_t<Policies>& operator()() const { return no_order_by; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_order_by)
|
||||
{
|
||||
return t.no_order_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -117,7 +177,7 @@ namespace sqlpp
|
||||
auto order_by(Args... args)
|
||||
-> _new_statement_t<order_by_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -125,16 +185,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<order_by_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_order_by must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::order_by_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), order_by_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, order_by_t<Database, Expressions...>>
|
||||
struct serializer_t<Context, order_by_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = order_by_t<Database, Expressions...>;
|
||||
using T = order_by_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -148,18 +208,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_order_by_t>
|
||||
{
|
||||
using T = no_order_by_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
255
include/sqlpp11/vendor/select_column_list.h
vendored
255
include/sqlpp11/vendor/select_column_list.h
vendored
@ -44,18 +44,18 @@ namespace sqlpp
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename... Rest>
|
||||
struct get_first_argument_if_unique
|
||||
template<typename... Columns>
|
||||
struct select_traits
|
||||
{
|
||||
using _traits = make_traits<no_value_t, tag::select_column_list, tag::return_value>;
|
||||
struct _name_t {};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct get_first_argument_if_unique<T>
|
||||
template<typename Column>
|
||||
struct select_traits<Column>
|
||||
{
|
||||
using _traits = make_traits<value_type_of<T>, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>;
|
||||
using _name_t = typename T::_name_t;
|
||||
using _traits = make_traits<value_type_of<Column>, tag::select_column_list, tag::return_value, tag::expression, tag::named_expression>;
|
||||
using _name_t = typename Column::_name_t;
|
||||
};
|
||||
}
|
||||
|
||||
@ -127,79 +127,69 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
// SELECTED COLUMNS DATA
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_data_t
|
||||
{
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
// SELECT COLUMNS
|
||||
select_column_list_data_t(Columns... columns):
|
||||
_columns(columns...)
|
||||
{}
|
||||
|
||||
select_column_list_data_t(std::tuple<Columns...> columns):
|
||||
_columns(columns)
|
||||
{}
|
||||
|
||||
select_column_list_data_t(const select_column_list_data_t&) = default;
|
||||
select_column_list_data_t(select_column_list_data_t&&) = default;
|
||||
select_column_list_data_t& operator=(const select_column_list_data_t&) = default;
|
||||
select_column_list_data_t& operator=(select_column_list_data_t&&) = default;
|
||||
~select_column_list_data_t() = default;
|
||||
|
||||
std::tuple<Columns...> _columns;
|
||||
dynamic_select_column_list<Database> _dynamic_columns;
|
||||
};
|
||||
|
||||
|
||||
// SELECTED COLUMNS
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_t
|
||||
{
|
||||
// get_first_argument_if_unique is kind of ugly
|
||||
using _traits = typename ::sqlpp::detail::get_first_argument_if_unique<Columns...>::_traits;
|
||||
using _traits = typename ::sqlpp::detail::select_traits<Columns...>::_traits;
|
||||
using _recursive_traits = make_recursive_traits<Columns...>;
|
||||
|
||||
using _name_t = typename ::sqlpp::detail::get_first_argument_if_unique<Columns...>::_name_t;
|
||||
using _name_t = typename ::sqlpp::detail::select_traits<Columns...>::_name_t;
|
||||
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<Columns...>::value, "at least one duplicate argument detected");
|
||||
|
||||
template<typename T>
|
||||
using is_valid_expression_t = std::integral_constant<bool, is_named_expression_t<T>::value or is_multi_column_t<T>::value>;
|
||||
static_assert(::sqlpp::detail::all_t<is_valid_expression_t<Columns>::value...>::value, "at least one argument is not a named expression");
|
||||
static_assert(::sqlpp::detail::all_t<(is_named_expression_t<Columns>::value or is_multi_column_t<Columns>::value)...>::value, "at least one argument is not a named expression");
|
||||
|
||||
static_assert(not ::sqlpp::detail::has_duplicates<typename Columns::_name_t...>::value, "at least one duplicate name detected");
|
||||
|
||||
struct _column_type {};
|
||||
|
||||
// Data
|
||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
template<typename Db>
|
||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
||||
result_row_t<Db, make_field_t<Columns>...>>::type;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||
|
||||
template <typename Select>
|
||||
using _pseudo_table_t = select_pseudo_table_t<Select, Columns...>;
|
||||
|
||||
template <typename Db>
|
||||
using _dynamic_t = select_column_list_t<Db, std::tuple<Columns...>>;
|
||||
|
||||
select_column_list_t& _select_column_list() { return *this; }
|
||||
|
||||
select_column_list_t(std::tuple<Columns...> columns):
|
||||
_columns(columns)
|
||||
{}
|
||||
|
||||
select_column_list_t(Columns... columns):
|
||||
_columns(columns...)
|
||||
{}
|
||||
|
||||
select_column_list_t(const select_column_list_t&) = default;
|
||||
select_column_list_t(select_column_list_t&&) = default;
|
||||
select_column_list_t& operator=(const select_column_list_t&) = default;
|
||||
select_column_list_t& operator=(select_column_list_t&&) = default;
|
||||
~select_column_list_t() = default;
|
||||
|
||||
static constexpr size_t static_size()
|
||||
{
|
||||
return sizeof...(Columns);
|
||||
}
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename NamedExpression>
|
||||
void add_column_ntc(NamedExpression namedExpression)
|
||||
void add_ntc(NamedExpression namedExpression)
|
||||
{
|
||||
add_column<NamedExpression, std::false_type>(namedExpression);
|
||||
add<NamedExpression, std::false_type>(namedExpression);
|
||||
}
|
||||
|
||||
template<typename NamedExpression, typename TableCheckRequired = std::true_type>
|
||||
void add_column(NamedExpression namedExpression)
|
||||
void add(NamedExpression namedExpression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_column can only be called for dynamic_column");
|
||||
static_assert(is_named_expression_t<NamedExpression>::value, "invalid named expression argument in add_column()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<NamedExpression>::value, "named expression uses tables unknown to this statement in add_column()");
|
||||
static_assert(_is_dynamic::value, "selected_columns::add() can only be called for dynamic_column");
|
||||
static_assert(is_named_expression_t<NamedExpression>::value, "invalid named expression argument in selected_columns::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<NamedExpression>::value, "named expression uses tables unknown to this statement in selected_columns::add()");
|
||||
using column_names = ::sqlpp::detail::make_type_set_t<typename Columns::_name_t...>;
|
||||
static_assert(not ::sqlpp::detail::is_element_of<typename NamedExpression::_name_t, column_names>::value, "a column of this name is present in the select already");
|
||||
|
||||
@ -208,24 +198,118 @@ namespace sqlpp
|
||||
is_named_expression_t<NamedExpression>::value
|
||||
>;
|
||||
|
||||
_add_column_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(namedExpression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
//private:
|
||||
template<typename NamedExpression>
|
||||
void _add_column_impl(NamedExpression namedExpression, const std::true_type&)
|
||||
void _add_impl(NamedExpression namedExpression, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_select_column_list()._dynamic_columns.emplace_back(namedExpression);
|
||||
return _data._dynamic_columns.emplace_back(namedExpression);
|
||||
}
|
||||
|
||||
template<typename NamedExpression>
|
||||
void _add_column_impl(NamedExpression namedExpression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
_impl_t<Policies> selected_columns;
|
||||
_impl_t<Policies>& operator()() { return selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return selected_columns; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.selected_columns)
|
||||
{
|
||||
return t.selected_columns;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
// Result methods
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
using _result_row_t = typename std::conditional<_is_dynamic::value,
|
||||
dynamic_result_row_t<Db, make_field_t<Columns>...>,
|
||||
result_row_t<Db, make_field_t<Columns>...>>::type;
|
||||
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<Database>::_names_t;
|
||||
|
||||
template<typename AliasProvider>
|
||||
struct _deferred_table_t
|
||||
{
|
||||
using table = select_pseudo_table_t<_statement_t, Columns...>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
using _table_t = typename _deferred_table_t<AliasProvider>::table;
|
||||
|
||||
template<typename AliasProvider>
|
||||
using _alias_t = typename _deferred_table_t<AliasProvider>::alias;
|
||||
|
||||
template<typename AliasProvider>
|
||||
_alias_t<AliasProvider> as(const AliasProvider& aliasProvider) const
|
||||
{
|
||||
static_assert(Policies::_can_be_used_as_table::value, "statement cannot be used as table, e.g. due to missing tables");
|
||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
||||
}
|
||||
|
||||
const _dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
return _get_statement().selected_columns._data._dynamic_columns._dynamic_expression_names;
|
||||
}
|
||||
|
||||
size_t get_no_of_result_columns() const
|
||||
{
|
||||
return sizeof...(Columns) + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const
|
||||
-> result_t<decltype(db.select(_get_statement())), _result_row_t<Db>>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
static_assert(_statement_t::_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
|
||||
return {db.select(_get_statement()), get_dynamic_names()};
|
||||
}
|
||||
#if 0
|
||||
|
||||
// Prepare
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_select_t<Db, select_t>
|
||||
{
|
||||
_statement_t::_check_consistency();
|
||||
|
||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
const select_column_list_t& _column_list() const { return *this; }
|
||||
std::tuple<Columns...> _columns;
|
||||
dynamic_select_column_list<Database> _dynamic_columns;
|
||||
};
|
||||
}
|
||||
|
||||
@ -244,17 +328,36 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop, ::sqlpp::tag::missing>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
template<typename Db>
|
||||
using _result_row_t = ::sqlpp::result_row_t<Db>;
|
||||
using _dynamic_names_t = typename dynamic_select_column_list<void>::_names_t;
|
||||
struct _name_t {};
|
||||
|
||||
template<typename T>
|
||||
struct _pseudo_table_t
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "Cannot use a select as a table when no columns have been selected yet");
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_selected_columns;
|
||||
_impl_t<Policies>& operator()() { return no_selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return no_selected_columns; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_selected_columns)
|
||||
{
|
||||
return t.no_selected_columns;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -266,7 +369,7 @@ namespace sqlpp
|
||||
auto columns(Args... args)
|
||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), ::sqlpp::detail::make_select_column_list_t<void, Args...>{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<void, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -274,16 +377,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<::sqlpp::detail::make_select_column_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_columns must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), typename ::sqlpp::detail::make_select_column_list_t<_database_t, Args...>::_data_t{std::tuple_cat(::sqlpp::detail::as_tuple<Args>::_(args)...)} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Columns>
|
||||
struct serializer_t<Context, select_column_list_t<Database, Columns...>>
|
||||
struct serializer_t<Context, select_column_list_data_t<Database, Columns...>>
|
||||
{
|
||||
using T = select_column_list_t<Database, Columns...>;
|
||||
using T = select_column_list_data_t<Database, Columns...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -298,16 +401,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_select_column_list_t>
|
||||
{
|
||||
using T = no_select_column_list_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
127
include/sqlpp11/vendor/select_flag_list.h
vendored
127
include/sqlpp11/vendor/select_flag_list.h
vendored
@ -38,6 +38,24 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// SELECTED FLAGS DATA
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_data_t
|
||||
{
|
||||
select_flag_list_data_t(Flags... flags):
|
||||
_flags(flags...)
|
||||
{}
|
||||
|
||||
select_flag_list_data_t(const select_flag_list_data_t&) = default;
|
||||
select_flag_list_data_t(select_flag_list_data_t&&) = default;
|
||||
select_flag_list_data_t& operator=(const select_flag_list_data_t&) = default;
|
||||
select_flag_list_data_t& operator=(select_flag_list_data_t&&) = default;
|
||||
~select_flag_list_data_t() = default;
|
||||
|
||||
std::tuple<Flags...> _flags;
|
||||
vendor::interpretable_list_t<Database> _dynamic_flags;
|
||||
};
|
||||
|
||||
// SELECT FLAGS
|
||||
template<typename Database, typename... Flags>
|
||||
struct select_flag_list_t
|
||||
@ -51,53 +69,67 @@ namespace sqlpp
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_select_flag_t<Flags>::value...>::value, "at least one argument is not a select flag in select flag list");
|
||||
|
||||
select_flag_list_t& _select_flag_list() { return *this; }
|
||||
|
||||
select_flag_list_t(Flags... flags):
|
||||
_flags(flags...)
|
||||
{}
|
||||
|
||||
select_flag_list_t(const select_flag_list_t&) = default;
|
||||
select_flag_list_t(select_flag_list_t&&) = default;
|
||||
select_flag_list_t& operator=(const select_flag_list_t&) = default;
|
||||
select_flag_list_t& operator=(select_flag_list_t&&) = default;
|
||||
~select_flag_list_t() = default;
|
||||
// Data
|
||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Flag>
|
||||
void add_flag_ntc(Flag flag)
|
||||
void add_ntc(Flag flag)
|
||||
{
|
||||
add_flag<Flag, std::false_type>(flag);
|
||||
add<Flag, std::false_type>(flag);
|
||||
}
|
||||
|
||||
template<typename Flag, typename TableCheckRequired = std::true_type>
|
||||
void add_flag(Flag flag)
|
||||
void add(Flag flag)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_flag must not be called for static select flags");
|
||||
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in add_flag()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in add_flag()");
|
||||
static_assert(_is_dynamic::value, "select_flags::add() must not be called for static select flags");
|
||||
static_assert(is_select_flag_t<Flag>::value, "invalid select flag argument in select_flags::add()");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Flag>::value, "flag uses tables unknown to this statement in select_flags::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_select_flag_t<Flag>::value>;
|
||||
|
||||
_add_flag_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(flag, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Flag>
|
||||
void _add_flag_impl(Flag flag, const std::true_type&)
|
||||
void _add_impl(Flag flag, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_select_flag_list()._dynamic_flags.emplace_back(flag);
|
||||
return _data._dynamic_flags.emplace_back(flag);
|
||||
}
|
||||
|
||||
template<typename Flag>
|
||||
void _add_flag_impl(Flag flag, const std::false_type&);
|
||||
void _add_impl(Flag flag, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
_impl_t<Policies> select_flags;
|
||||
_impl_t<Policies>& operator()() { return select_flags; }
|
||||
const _impl_t<Policies>& operator()() const { return select_flags; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.select_flags)
|
||||
{
|
||||
return t.select_flags;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
const select_flag_list_t& _flag_list() const { return *this; }
|
||||
std::tuple<Flags...> _flags;
|
||||
vendor::interpretable_list_t<Database> _dynamic_flags;
|
||||
};
|
||||
|
||||
struct no_select_flag_list_t
|
||||
@ -105,6 +137,33 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_select_flags;
|
||||
_impl_t<Policies>& operator()() { return no_select_flags; }
|
||||
const _impl_t<Policies>& operator()() const { return no_select_flags; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_select_flags)
|
||||
{
|
||||
return t.no_select_flags;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -116,7 +175,7 @@ namespace sqlpp
|
||||
auto flags(Args... args)
|
||||
-> _new_statement_t<select_flag_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -124,7 +183,7 @@ namespace sqlpp
|
||||
-> _new_statement_t<select_flag_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_flags must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::select_flag_list_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), select_flag_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -132,9 +191,9 @@ namespace sqlpp
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Flags>
|
||||
struct serializer_t<Context, select_flag_list_t<Database, Flags...>>
|
||||
struct serializer_t<Context, select_flag_list_data_t<Database, Flags...>>
|
||||
{
|
||||
using T = select_flag_list_t<Database, Flags...>;
|
||||
using T = select_flag_list_data_t<Database, Flags...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -148,16 +207,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_select_flag_list_t>
|
||||
{
|
||||
using T = no_select_flag_list_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
4
include/sqlpp11/vendor/select_pseudo_table.h
vendored
4
include/sqlpp11/vendor/select_pseudo_table.h
vendored
@ -55,8 +55,8 @@ namespace sqlpp
|
||||
Select,
|
||||
NamedExpr...>, select_column_spec_t<NamedExpr>...>
|
||||
{
|
||||
using _value_type = no_value_t;
|
||||
using _is_pseudo_table = std::true_type;
|
||||
using _traits = make_traits<no_value_t, tag::table, tag::pseudo_table>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
select_pseudo_table_t(Select select):
|
||||
_select(select)
|
||||
|
145
include/sqlpp11/vendor/single_table.h
vendored
145
include/sqlpp11/vendor/single_table.h
vendored
@ -36,39 +36,151 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// A SINGLE TABLE DATA
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_data_t
|
||||
{
|
||||
single_table_data_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
|
||||
single_table_data_t(const single_table_data_t&) = default;
|
||||
single_table_data_t(single_table_data_t&&) = default;
|
||||
single_table_data_t& operator=(const single_table_data_t&) = default;
|
||||
single_table_data_t& operator=(single_table_data_t&&) = default;
|
||||
~single_table_data_t() = default;
|
||||
|
||||
Table _table;
|
||||
};
|
||||
|
||||
// A SINGLE TABLE
|
||||
template<typename Database, typename Table>
|
||||
struct single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table>;
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::single_table, tag::return_value>;
|
||||
using _recursive_traits = make_recursive_traits<Table>;
|
||||
|
||||
static_assert(is_table_t<Table>::value, "argument has to be a table");
|
||||
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
|
||||
|
||||
single_table_t(Table table):
|
||||
_table(table)
|
||||
{}
|
||||
using _data_t = single_table_data_t<Database, Table>;
|
||||
|
||||
single_table_t(const single_table_t&) = default;
|
||||
single_table_t(single_table_t&&) = default;
|
||||
single_table_t& operator=(const single_table_t&) = default;
|
||||
single_table_t& operator=(single_table_t&&) = default;
|
||||
~single_table_t() = default;
|
||||
struct _name_t {};
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = single_table_data_t<Database, Table>;
|
||||
|
||||
_impl_t<Policies> from;
|
||||
_impl_t<Policies>& operator()() { return from; }
|
||||
const _impl_t<Policies>& operator()() const { return from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.from)
|
||||
{
|
||||
return t.from;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
Table _table;
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{
|
||||
using _statement_t = typename Policies::_statement_t;
|
||||
|
||||
const _statement_t& _get_statement() const
|
||||
{
|
||||
return static_cast<const _statement_t&>(*this);
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
size_t _get_no_of_parameters() const
|
||||
{
|
||||
#warning need to fix this
|
||||
return 0;
|
||||
//return _parameter_list_t::size::value;
|
||||
}
|
||||
|
||||
void _check_consistency() const
|
||||
{
|
||||
// FIXME: Read up on what is allowed/prohibited in INSERT
|
||||
}
|
||||
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const -> decltype(db.insert(_get_statement()))
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run insert directly with parameters, use prepare instead");
|
||||
return db.insert(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename Db>
|
||||
auto _prepare(Db& db) const
|
||||
-> prepared_insert_t<Db, insert_t>
|
||||
{
|
||||
_check_consistency();
|
||||
|
||||
return {{}, db.prepare_insert(*this)};
|
||||
}
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
// NO INTO YET
|
||||
struct no_single_table_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_from)
|
||||
{
|
||||
return t.no_from;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -76,28 +188,21 @@ namespace sqlpp
|
||||
template<typename T>
|
||||
using _new_statement_t = typename Policies::template _new_statement_t<no_single_table_t, T>;
|
||||
|
||||
template<typename... Args>
|
||||
auto into(Args... args)
|
||||
-> _new_statement_t<single_table_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), single_table_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
#warning: remove can operate on several tables at once, so it should not use single_table anyway
|
||||
template<typename... Args>
|
||||
auto from(Args... args)
|
||||
-> _new_statement_t<single_table_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), single_table_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), single_table_data_t<void, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename Table>
|
||||
struct serializer_t<Context, single_table_t<Database, Table>>
|
||||
struct serializer_t<Context, single_table_data_t<Database, Table>>
|
||||
{
|
||||
using T = single_table_t<Database, Table>;
|
||||
using T = single_table_data_t<Database, Table>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
128
include/sqlpp11/vendor/update_list.h
vendored
128
include/sqlpp11/vendor/update_list.h
vendored
@ -36,6 +36,24 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// UPDATE ASSIGNMENTS DATA
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_data_t
|
||||
{
|
||||
update_list_data_t(Assignments... assignments):
|
||||
_assignments(assignments...)
|
||||
{}
|
||||
|
||||
update_list_data_t(const update_list_data_t&) = default;
|
||||
update_list_data_t(update_list_data_t&&) = default;
|
||||
update_list_data_t& operator=(const update_list_data_t&) = default;
|
||||
update_list_data_t& operator=(update_list_data_t&&) = default;
|
||||
~update_list_data_t() = default;
|
||||
|
||||
std::tuple<Assignments...> _assignments;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
|
||||
};
|
||||
|
||||
// UPDATE ASSIGNMENTS
|
||||
template<typename Database, typename... Assignments>
|
||||
struct update_list_t
|
||||
@ -61,57 +79,70 @@ namespace sqlpp
|
||||
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
|
||||
*/
|
||||
|
||||
update_list_t& _update_list() { return *this; }
|
||||
|
||||
update_list_t(Assignments... assignments):
|
||||
_assignments(assignments...)
|
||||
{}
|
||||
|
||||
update_list_t(const update_list_t&) = default;
|
||||
update_list_t(update_list_t&&) = default;
|
||||
update_list_t& operator=(const update_list_t&) = default;
|
||||
update_list_t& operator=(update_list_t&&) = default;
|
||||
~update_list_t() = default;
|
||||
// Data
|
||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Assignment>
|
||||
void add_set_ntc(Assignment assignment)
|
||||
void add_ntc(Assignment assignment)
|
||||
{
|
||||
add_set<Assignment, std::false_type>(assignment);
|
||||
add<Assignment, std::false_type>(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment, typename TableCheckRequired = std::true_type>
|
||||
void add_set(Assignment assignment)
|
||||
void add(Assignment assignment)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_set must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add_set()");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add_set() argument must not be updated");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add_set()");
|
||||
static_assert(_is_dynamic::value, "add must not be called for static from()");
|
||||
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
|
||||
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add() argument must not be updated");
|
||||
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<
|
||||
_is_dynamic::value,
|
||||
is_assignment_t<Assignment>::value,
|
||||
not must_not_update_t<typename Assignment::_column_t>::value>;
|
||||
|
||||
_add_set_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Assignment>
|
||||
void _add_set_impl(Assignment assignment, const std::true_type&)
|
||||
void _add_impl(Assignment assignment, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_update_list()._dynamic_assignments.emplace_back(assignment);
|
||||
return _data._dynamic_assignments.emplace_back(assignment);
|
||||
}
|
||||
|
||||
template<typename Assignment>
|
||||
void _add_set_impl(Assignment assignment, const std::false_type&);
|
||||
void _add_impl(Assignment assignment, const std::false_type&);
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
std::tuple<Assignments...> _assignments;
|
||||
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
|
||||
_impl_t<Policies> assignments;
|
||||
_impl_t<Policies>& operator()() { return assignments; }
|
||||
const _impl_t<Policies>& operator()() const { return assignments; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.assignments)
|
||||
{
|
||||
return t.assignments;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_update_list_t
|
||||
@ -119,6 +150,33 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_assignments;
|
||||
_impl_t<Policies>& operator()() { return no_assignments; }
|
||||
const _impl_t<Policies>& operator()() const { return no_assignments; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_assignments)
|
||||
{
|
||||
return t.no_assignments;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -130,7 +188,7 @@ namespace sqlpp
|
||||
auto set(Args... args)
|
||||
-> _new_statement_t<update_list_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -138,16 +196,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<update_list_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::update_list_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::update_list_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Assignments>
|
||||
struct serializer_t<Context, update_list_t<Database, Assignments...>>
|
||||
struct serializer_t<Context, update_list_data_t<Database, Assignments...>>
|
||||
{
|
||||
using T = update_list_t<Database, Assignments...>;
|
||||
using T = update_list_data_t<Database, Assignments...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -159,18 +217,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_update_list_t>
|
||||
{
|
||||
using T = no_update_list_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
121
include/sqlpp11/vendor/using.h
vendored
121
include/sqlpp11/vendor/using.h
vendored
@ -37,6 +37,24 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// USING DATA
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_data_t
|
||||
{
|
||||
using_data_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
{}
|
||||
|
||||
using_data_t(const using_data_t&) = default;
|
||||
using_data_t(using_data_t&&) = default;
|
||||
using_data_t& operator=(const using_data_t&) = default;
|
||||
using_data_t& operator=(using_data_t&&) = default;
|
||||
~using_data_t() = default;
|
||||
|
||||
std::tuple<Tables...> _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
};
|
||||
|
||||
// USING
|
||||
template<typename Database, typename... Tables>
|
||||
struct using_t
|
||||
@ -52,53 +70,95 @@ namespace sqlpp
|
||||
|
||||
static_assert(::sqlpp::detail::all_t<is_table_t<Tables>::value...>::value, "at least one argument is not an table in using()");
|
||||
|
||||
using_t& _using() { return *this; }
|
||||
|
||||
using_t(Tables... tables):
|
||||
_tables(tables...)
|
||||
{}
|
||||
|
||||
using_t(const using_t&) = default;
|
||||
using_t(using_t&&) = default;
|
||||
using_t& operator=(const using_t&) = default;
|
||||
using_t& operator=(using_t&&) = default;
|
||||
~using_t() = default;
|
||||
// Data
|
||||
using _data_t = using_data_t<Database, Tables...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Table>
|
||||
void add_using(Table table)
|
||||
void add(Table table)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_using must not be called for static using()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in add_using()");
|
||||
static_assert(_is_dynamic::value, "add must not be called for static using()");
|
||||
static_assert(is_table_t<Table>::value, "invalid table argument in add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_table_t<Table>::value>;
|
||||
|
||||
_add_using_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(table, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Table>
|
||||
void _add_using_impl(Table table, const std::true_type&)
|
||||
void _add_impl(Table table, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_using()._dynamic_tables.emplace_back(table);
|
||||
return _data._dynamic_tables.emplace_back(table);
|
||||
}
|
||||
|
||||
template<typename Table>
|
||||
void _add_using_impl(Table table, const std::false_type&);
|
||||
void _add_impl(Table table, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = using_data_t<Database, Tables...>;
|
||||
|
||||
std::tuple<Tables...> _tables;
|
||||
vendor::interpretable_list_t<Database> _dynamic_tables;
|
||||
_impl_t<Policies> using_;
|
||||
_impl_t<Policies>& operator()() { return using_; }
|
||||
const _impl_t<Policies>& operator()() const { return using_; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.using_)
|
||||
{
|
||||
return t.using_;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
// NO USING YET
|
||||
struct no_using_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_using;
|
||||
_impl_t<Policies>& operator()() { return no_using; }
|
||||
const _impl_t<Policies>& operator()() const { return no_using; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_using)
|
||||
{
|
||||
return t.no_using;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -110,7 +170,7 @@ namespace sqlpp
|
||||
auto using_(Args... args)
|
||||
-> _new_statement_t<using_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -118,16 +178,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<using_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_using must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::using_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), using_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Tables>
|
||||
struct serializer_t<Context, using_t<Database, Tables...>>
|
||||
struct serializer_t<Context, using_data_t<Database, Tables...>>
|
||||
{
|
||||
using T = using_t<Database, Tables...>;
|
||||
using T = using_data_t<Database, Tables...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -141,17 +201,6 @@ namespace sqlpp
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_using_t>
|
||||
{
|
||||
using T = no_using_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
178
include/sqlpp11/vendor/where.h
vendored
178
include/sqlpp11/vendor/where.h
vendored
@ -38,96 +38,183 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// WHERE
|
||||
// WHERE DATA
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_data_t
|
||||
{
|
||||
where_data_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
where_data_t(const where_data_t&) = default;
|
||||
where_data_t(where_data_t&&) = default;
|
||||
where_data_t& operator=(const where_data_t&) = default;
|
||||
where_data_t& operator=(where_data_t&&) = default;
|
||||
~where_data_t() = default;
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
};
|
||||
|
||||
// WHERE(EXPR)
|
||||
template<typename Database, typename... Expressions>
|
||||
struct where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<Expressions...>;
|
||||
|
||||
#warning: is_dynamic should be using a template alias (making it easier to replace the logic)
|
||||
using _is_dynamic = typename std::conditional<std::is_same<Database, void>::value, std::false_type, std::true_type>::type;
|
||||
|
||||
static_assert(_is_dynamic::value or sizeof...(Expressions), "at least one expression argument required in where()");
|
||||
static_assert(sqlpp::detail::none_t<is_assignment_t<Expressions>::value...>::value, "at least one argument is an assignment in where()");
|
||||
static_assert(sqlpp::detail::all_t<is_expression_t<Expressions>::value...>::value, "at least one argument is not valid expression in where()");
|
||||
|
||||
where_t& _where() { return *this; }
|
||||
|
||||
where_t(Expressions... expressions):
|
||||
_expressions(expressions...)
|
||||
{}
|
||||
|
||||
where_t(const where_t&) = default;
|
||||
where_t(where_t&&) = default;
|
||||
where_t& operator=(const where_t&) = default;
|
||||
where_t& operator=(where_t&&) = default;
|
||||
~where_t() = default;
|
||||
// Data
|
||||
using _data_t = where_data_t<Database, Expressions...>;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template <typename Policies>
|
||||
struct _methods_t
|
||||
struct _impl_t
|
||||
{
|
||||
template<typename Expression>
|
||||
void add_where_ntc(Expression expression)
|
||||
void add_ntc(Expression expression)
|
||||
{
|
||||
add_where<Expression, std::false_type>(expression);
|
||||
add<Expression, std::false_type>(expression);
|
||||
}
|
||||
|
||||
template<typename Expression, typename TableCheckRequired = std::true_type>
|
||||
void add_where(Expression expression)
|
||||
void add(Expression expression)
|
||||
{
|
||||
static_assert(_is_dynamic::value, "add_where can only be called for dynamic_where");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in add_where()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in add_where()");
|
||||
static_assert(_is_dynamic::value, "where::add() can only be called for dynamic_where");
|
||||
static_assert(is_expression_t<Expression>::value, "invalid expression argument in where::add()");
|
||||
static_assert(not TableCheckRequired::value or Policies::template _no_unknown_tables<Expression>::value, "expression uses tables unknown to this statement in where::add()");
|
||||
|
||||
using ok = ::sqlpp::detail::all_t<_is_dynamic::value, is_expression_t<Expression>::value>;
|
||||
|
||||
_add_where_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
_add_impl(expression, ok()); // dispatch to prevent compile messages after the static_assert
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Expression>
|
||||
void _add_where_impl(Expression expression, const std::true_type&)
|
||||
void _add_impl(Expression expression, const std::true_type&)
|
||||
{
|
||||
return static_cast<typename Policies::_statement_t*>(this)->_where()._dynamic_expressions.emplace_back(expression);
|
||||
return _data._dynamic_expressions.emplace_back(expression);
|
||||
}
|
||||
|
||||
template<typename Expression>
|
||||
void _add_where_impl(Expression expression, const std::false_type&);
|
||||
void _add_impl(Expression expression, const std::false_type&);
|
||||
|
||||
public:
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
std::tuple<Expressions...> _expressions;
|
||||
vendor::interpretable_list_t<Database> _dynamic_expressions;
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = where_data_t<Database, Expressions...>;
|
||||
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.where)
|
||||
{
|
||||
return t.where;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct where_data_t<void, bool>
|
||||
{
|
||||
bool _condition;
|
||||
};
|
||||
|
||||
// WHERE(BOOL)
|
||||
template<>
|
||||
struct where_t<void, bool>
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
where_t(bool condition):
|
||||
_condition(condition)
|
||||
{}
|
||||
// Data
|
||||
using _data_t = where_data_t<void, bool>;
|
||||
|
||||
where_t(const where_t&) = default;
|
||||
where_t(where_t&&) = default;
|
||||
where_t& operator=(const where_t&) = default;
|
||||
where_t& operator=(where_t&&) = default;
|
||||
~where_t() = default;
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = where_data_t<void, bool>;
|
||||
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.where)
|
||||
{
|
||||
return t.where;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
|
||||
bool _condition;
|
||||
};
|
||||
|
||||
// NO WHERE YET
|
||||
struct no_where_t
|
||||
{
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
using _data_t = no_data_t;
|
||||
|
||||
// Member implementation with data and methods
|
||||
template<typename Policies>
|
||||
struct _impl_t
|
||||
{
|
||||
_data_t _data;
|
||||
};
|
||||
|
||||
// Member template for adding the named member to a statement
|
||||
template<typename Policies>
|
||||
struct _member_t
|
||||
{
|
||||
using _data_t = no_data_t;
|
||||
|
||||
_impl_t<Policies> no_where;
|
||||
_impl_t<Policies>& operator()() { return no_where; }
|
||||
const _impl_t<Policies>& operator()() const { return no_where; }
|
||||
|
||||
template<typename T>
|
||||
static auto _get_member(T t) -> decltype(t.no_where)
|
||||
{
|
||||
return t.no_where;
|
||||
}
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -139,7 +226,7 @@ namespace sqlpp
|
||||
auto where(Args... args)
|
||||
-> _new_statement_t<where_t<void, Args...>>
|
||||
{
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_t<void, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<void, Args...>{args...} };
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
@ -147,16 +234,16 @@ namespace sqlpp
|
||||
-> _new_statement_t<where_t<_database_t, Args...>>
|
||||
{
|
||||
static_assert(not std::is_same<_database_t, void>::value, "dynamic_where must not be called in a static statement");
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), vendor::where_t<_database_t, Args...>{args...} };
|
||||
return { *static_cast<typename Policies::_statement_t*>(this), where_data_t<_database_t, Args...>{args...} };
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Interpreters
|
||||
template<typename Context, typename Database, typename... Expressions>
|
||||
struct serializer_t<Context, where_t<Database, Expressions...>>
|
||||
struct serializer_t<Context, where_data_t<Database, Expressions...>>
|
||||
{
|
||||
using T = where_t<Database, Expressions...>;
|
||||
using T = where_data_t<Database, Expressions...>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -172,9 +259,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, where_t<void, bool>>
|
||||
struct serializer_t<Context, where_data_t<void, bool>>
|
||||
{
|
||||
using T = where_t<void, bool>;
|
||||
using T = where_data_t<void, bool>;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
@ -184,17 +271,6 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_where_t>
|
||||
{
|
||||
using T = no_where_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
8
include/sqlpp11/vendor/wrap_operand.h
vendored
8
include/sqlpp11/vendor/wrap_operand.h
vendored
@ -45,7 +45,7 @@ namespace sqlpp
|
||||
{
|
||||
struct boolean_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::boolean, ::sqlpp::tag::expression>;
|
||||
using _traits = make_traits<::sqlpp::detail::boolean, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = bool;
|
||||
@ -83,7 +83,7 @@ namespace sqlpp
|
||||
|
||||
struct integral_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression>;
|
||||
using _traits = make_traits<::sqlpp::detail::integral, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = int64_t;
|
||||
@ -122,7 +122,7 @@ namespace sqlpp
|
||||
|
||||
struct floating_point_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point, ::sqlpp::tag::expression>;
|
||||
using _traits = make_traits<::sqlpp::detail::floating_point, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = double;
|
||||
@ -160,7 +160,7 @@ namespace sqlpp
|
||||
|
||||
struct text_operand
|
||||
{
|
||||
using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression>;
|
||||
using _traits = make_traits<::sqlpp::detail::text, ::sqlpp::tag::expression, ::sqlpp::tag::wrapped_value>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
using _value_t = std::string;
|
||||
|
@ -7,9 +7,9 @@ macro (build_and_run arg)
|
||||
endmacro ()
|
||||
|
||||
#build_and_run(InterpretTest)
|
||||
#build_and_run(InsertTest)
|
||||
build_and_run(InsertTest)
|
||||
#build_and_run(RemoveTest)
|
||||
build_and_run(UpdateTest)
|
||||
#build_and_run(UpdateTest)
|
||||
#build_and_run(SelectTest)
|
||||
#build_and_run(SelectTypeTest)
|
||||
#build_and_run(FunctionTest)
|
||||
|
@ -67,11 +67,12 @@ int main()
|
||||
serialize(insert_into(t).set(t.beta = "kirschauflauf"), printer).str();
|
||||
serialize(insert_into(t).columns(t.beta), printer).str();
|
||||
auto multi_insert = insert_into(t).columns(t.beta, t.delta);
|
||||
multi_insert.add_values(t.beta = "cheesecake", t.delta = 1);
|
||||
multi_insert.add_values(t.beta = sqlpp::default_value, t.delta = sqlpp::default_value);
|
||||
multi_insert.values.add(t.beta = "cheesecake", t.delta = 1);
|
||||
multi_insert.values.add(t.beta = sqlpp::default_value, t.delta = sqlpp::default_value);
|
||||
auto i = dynamic_insert_into(db, t).dynamic_set();
|
||||
i.add_set(t.beta = "kirschauflauf");
|
||||
serialize(i, printer).str();
|
||||
i.insert_list.add(t.beta = "kirschauflauf");
|
||||
printer.reset();
|
||||
std::cerr << serialize(i, printer).str() << std::endl;
|
||||
|
||||
db(multi_insert);
|
||||
|
||||
|
@ -46,12 +46,12 @@ int main()
|
||||
serialize(insert_into(t).columns(t.beta, t.gamma), printer).str();
|
||||
{
|
||||
auto i = insert_into(t).columns(t.gamma, t.beta);
|
||||
i.add_values(t.gamma = true, t.beta = "cheesecake");
|
||||
i.values.add(t.gamma = true, t.beta = "cheesecake");
|
||||
serialize(i, printer).str();
|
||||
i.add_values(t.gamma = false, t.beta = sqlpp::tvin("coffee"));
|
||||
i.add_values(t.gamma = false, t.beta = sqlpp::tvin(std::string()));
|
||||
i.values.add(t.gamma = false, t.beta = sqlpp::tvin("coffee"));
|
||||
i.values.add(t.gamma = false, t.beta = sqlpp::tvin(std::string()));
|
||||
serialize(i, printer).str();
|
||||
i.add_values(t.gamma = sqlpp::default_value, t.beta = sqlpp::null);
|
||||
i.values.add(t.gamma = sqlpp::default_value, t.beta = sqlpp::null);
|
||||
serialize(i, printer).str();
|
||||
}
|
||||
|
||||
@ -134,22 +134,22 @@ int main()
|
||||
// dynamic select
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_flags().dynamic_columns().from(t);
|
||||
s.add_column(t.beta);
|
||||
s.add_column(t.gamma);
|
||||
s.selected_columns.add(t.beta);
|
||||
s.selected_columns.add(t.gamma);
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_flags().dynamic_columns().from(t);
|
||||
s.add_flag(sqlpp::distinct);
|
||||
s.add_column(t.beta);
|
||||
s.add_column(t.gamma);
|
||||
s.select_flags.add(sqlpp::distinct);
|
||||
s.selected_columns.add(t.beta);
|
||||
s.selected_columns.add(t.gamma);
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_flags(sqlpp::distinct).dynamic_columns(t.alpha).extra_tables(t); // Would fail to run()
|
||||
s.add_flag(sqlpp::all);
|
||||
s.add_column(t.beta);
|
||||
s.add_column(t.gamma);
|
||||
s.select_flags.add(sqlpp::all);
|
||||
s.selected_columns.add(t.beta);
|
||||
s.selected_columns.add(t.gamma);
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ struct MockDb: public sqlpp::connection
|
||||
|
||||
void reset()
|
||||
{
|
||||
_os.clear();
|
||||
_os.str("");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -60,9 +60,12 @@ int main()
|
||||
serialize(remove_from(t).where(t.beta != "transparent"), printer).str();
|
||||
serialize(remove_from(t).using_(t), printer).str();
|
||||
auto r = dynamic_remove_from(db, t).dynamic_using().dynamic_where();
|
||||
r.add_using(t);
|
||||
r.add_where(t.beta != "transparent");
|
||||
serialize(r, printer).str();
|
||||
r.using_.add(t);
|
||||
r.where.add(t.beta != "transparent");
|
||||
printer.reset();
|
||||
std::cerr << serialize(r, printer).str() << std::endl;
|
||||
printer.reset();
|
||||
std::cerr << serialize(remove_from(t).where(true), printer).str() << std::endl;
|
||||
|
||||
db(r);
|
||||
|
||||
|
@ -49,6 +49,7 @@ int main()
|
||||
test::TabFoo f;
|
||||
test::TabBar t;
|
||||
|
||||
sqlpp::select(t.alpha).flags(sqlpp::all).from(t);
|
||||
for (const auto& row : db(select(all_of(t)).from(t).where(true)))
|
||||
{
|
||||
int64_t a = row.alpha;
|
||||
@ -68,20 +69,26 @@ int main()
|
||||
const bool g = row.gamma;
|
||||
}
|
||||
|
||||
auto stat = sqlpp::select().columns(all_of(t)).flags(sqlpp::all).from(t).extra_tables(f,t).where(t.alpha > 0).group_by(t.alpha).order_by(t.gamma.asc()).having(t.gamma).limit(7).offset(19);
|
||||
auto s = dynamic_select(db).dynamic_columns(all_of(t)).dynamic_flags().dynamic_from(t).extra_tables(f,t).dynamic_where().dynamic_group_by(t.alpha).dynamic_order_by().dynamic_having(t.gamma).dynamic_limit().dynamic_offset();
|
||||
s.add_flag(sqlpp::distinct);
|
||||
s.add_column(f.omega);
|
||||
s.add_from(f);
|
||||
s.add_where(t.alpha > 7);
|
||||
s.add_having(t.alpha > 7);
|
||||
s.set_limit(3);
|
||||
s.set_offset(3);
|
||||
s.add_group_by(t.beta);
|
||||
s.add_order_by(t.beta.asc());
|
||||
s.select_flags.add(sqlpp::distinct);
|
||||
s.selected_columns.add(f.omega);
|
||||
s.from.add(f);
|
||||
s.where.add(t.alpha > 7);
|
||||
s.having.add(t.alpha > 7);
|
||||
s.limit.set(3);
|
||||
s.offset.set(3);
|
||||
s.group_by.add(t.beta);
|
||||
s.order_by.add(t.beta.asc());
|
||||
for (const auto& row : db(s))
|
||||
{
|
||||
int64_t a = row.alpha;
|
||||
}
|
||||
|
||||
printer.reset();
|
||||
std::cerr << serialize(s, printer).str() << std::endl;
|
||||
|
||||
auto X = select(all_of(t)).from(t).as(t.alpha);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -311,10 +311,10 @@ int main()
|
||||
|
||||
{
|
||||
auto s = dynamic_select(db, all_of(t)).dynamic_from().dynamic_where().dynamic_limit().dynamic_offset();
|
||||
s.add_from(t);
|
||||
s.add_where(t.alpha > 7 and t.alpha == any(select(t.alpha).from(t).where(t.alpha < 3)));
|
||||
s.set_limit(30);
|
||||
s.set_limit(3);
|
||||
s.from.add(t);
|
||||
s.where.add_ntc(t.alpha > 7 and t.alpha == any(select(t.alpha).from(t).where(t.alpha < 3)));
|
||||
s.limit.set(30);
|
||||
s.limit.set(3);
|
||||
std::cerr << "------------------------\n";
|
||||
serialize(s, printer).str();
|
||||
std::cerr << "------------------------\n";
|
||||
@ -325,7 +325,7 @@ int main()
|
||||
// Test that select can be called with zero columns if it is used with dynamic columns.
|
||||
{
|
||||
auto s = dynamic_select(db).dynamic_columns().extra_tables(t);
|
||||
s.add_column(t.alpha);
|
||||
s.selected_columns.add(t.alpha);
|
||||
serialize(s, printer).str();
|
||||
}
|
||||
|
||||
@ -387,6 +387,5 @@ int main()
|
||||
.as(alias::a)
|
||||
;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -61,9 +61,11 @@ int main()
|
||||
serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).str();
|
||||
serialize(update(t).set(t.beta = "opaque").where(t.beta != t.beta), printer).str();
|
||||
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
|
||||
u.add_set(t.gamma = false);
|
||||
u.add_where(t.gamma != false);
|
||||
serialize(u, printer).str();
|
||||
#warning: This should fail since gamma is set already
|
||||
u.assignments.add(t.gamma = false);
|
||||
u.where.add(t.gamma != false);
|
||||
printer.reset();
|
||||
std::cerr << serialize(u, printer).str() << std::endl;
|
||||
|
||||
db(u);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user