mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-16 04:47:18 +08:00
Using _member_t to have variadic named members in statements
This commit is contained in:
parent
76fc2fb397
commit
408e96af4a
@ -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 static_cast<typename Target::template _member_t<Target>>(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>());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace sqlpp
|
||||
_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...>;
|
||||
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<select_policies_t>
|
||||
{};
|
||||
@ -143,7 +143,7 @@ namespace sqlpp
|
||||
typename... Policies
|
||||
>
|
||||
struct select_t:
|
||||
public Policies...,
|
||||
public Policies::template _member_t<Policies>...,
|
||||
public detail::select_policies_t<Db, Policies...>::_value_type::template expression_operators<select_t<Db, Policies...>>,
|
||||
public detail::select_policies_t<Db, Policies...>::_result_methods_t,
|
||||
public detail::select_policies_t<Db, Policies...>::_methods_t
|
||||
@ -165,7 +165,7 @@ namespace sqlpp
|
||||
|
||||
template<typename Statement, typename Term>
|
||||
select_t(Statement statement, Term term):
|
||||
Policies(detail::pick_arg<Policies>(statement, term))...
|
||||
Policies::template _member_t<Policies>{{detail::pick_arg<Policies>(statement, term)}}...
|
||||
{}
|
||||
|
||||
select_t(const select_t& r) = default;
|
||||
@ -173,7 +173,6 @@ namespace sqlpp
|
||||
select_t& operator=(const select_t& r) = default;
|
||||
select_t& operator=(select_t&& r) = default;
|
||||
~select_t() = default;
|
||||
|
||||
};
|
||||
|
||||
namespace vendor
|
||||
@ -188,7 +187,7 @@ namespace sqlpp
|
||||
context << "SELECT ";
|
||||
|
||||
using swallow = int[];
|
||||
(void) swallow{(serialize(static_cast<const Policies&>(t), context), 0)...};
|
||||
(void) swallow{(serialize(static_cast<const Policies&>(t)._data, context), 0)...};
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -197,16 +196,16 @@ namespace sqlpp
|
||||
|
||||
template<typename Database>
|
||||
using blank_select_t = select_t<Database,
|
||||
vendor::no_select_flag_list_t,
|
||||
//vendor::no_select_flag_list_t,
|
||||
vendor::no_select_column_list_t,
|
||||
vendor::no_from_t,
|
||||
vendor::no_extra_tables_t,
|
||||
vendor::no_where_t,
|
||||
vendor::no_from_t/*,
|
||||
vendor::no_extra_tables_t*/,
|
||||
vendor::no_where_t/*,
|
||||
vendor::no_group_by_t,
|
||||
vendor::no_having_t,
|
||||
vendor::no_order_by_t,
|
||||
vendor::no_limit_t,
|
||||
vendor::no_offset_t>;
|
||||
vendor::no_offset_t*/>;
|
||||
|
||||
|
||||
blank_select_t<void> select() // FIXME: These should be constexpr
|
||||
|
99
include/sqlpp11/vendor/from.h
vendored
99
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,52 @@ 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_t(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()");
|
||||
|
||||
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
|
||||
{
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
struct no_from_t
|
||||
@ -101,6 +126,28 @@ namespace sqlpp
|
||||
using _traits = make_traits<no_value_t, ::sqlpp::tag::noop>;
|
||||
using _recursive_traits = make_recursive_traits<>;
|
||||
|
||||
// Data
|
||||
struct _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
|
||||
{
|
||||
_impl_t<Policies> no_from;
|
||||
_impl_t<Policies>& operator()() { return no_from; }
|
||||
const _impl_t<Policies>& operator()() const { return no_from; }
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -112,7 +159,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,14 +167,14 @@ 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...>;
|
||||
|
||||
@ -145,9 +192,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_from_t>
|
||||
struct serializer_t<Context, no_from_t::_data_t>
|
||||
{
|
||||
using T = no_from_t;
|
||||
using T = no_from_t::_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
6
include/sqlpp11/vendor/noop.h
vendored
6
include/sqlpp11/vendor/noop.h
vendored
@ -39,6 +39,12 @@ namespace sqlpp
|
||||
{
|
||||
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>
|
||||
|
180
include/sqlpp11/vendor/select_column_list.h
vendored
180
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,67 +127,54 @@ namespace sqlpp
|
||||
}
|
||||
};
|
||||
|
||||
// SELECTED COLUMNS DATA
|
||||
template<typename Database, typename... Columns>
|
||||
struct select_column_list_data_t
|
||||
{
|
||||
select_column_list_data_t(Columns... columns):
|
||||
_columns(columns...)
|
||||
{}
|
||||
|
||||
// SELECT 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; }
|
||||
const select_column_list_t& _select_column_list() const { 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)
|
||||
@ -212,27 +199,58 @@ namespace sqlpp
|
||||
_add_column_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&)
|
||||
{
|
||||
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
|
||||
{
|
||||
_impl_t<Policies> selected_columns;
|
||||
_impl_t<Policies>& operator()() { return selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return 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 = _pseudo_table_t<_statement_t>;
|
||||
using alias = typename _pseudo_table_t<_statement_t>::template _alias_t<AliasProvider>;
|
||||
using table = select_pseudo_table_t<_statement_t, Columns...>;
|
||||
using alias = typename table::template _alias_t<AliasProvider>;
|
||||
};
|
||||
|
||||
template<typename AliasProvider>
|
||||
@ -245,11 +263,12 @@ namespace sqlpp
|
||||
_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>(static_cast<const _statement_t&>(*this)).as(aliasProvider);
|
||||
return _table_t<AliasProvider>(_get_statement()).as(aliasProvider);
|
||||
}
|
||||
|
||||
const _dynamic_names_t& get_dynamic_names() const
|
||||
{
|
||||
return static_cast<const typename Policies::_statement_t*>(this)->_select_column_list()._dynamic_columns._dynamic_expression_names;
|
||||
return _get_statement().selected_columns._data._dynamic_columns._dynamic_expression_names;
|
||||
}
|
||||
|
||||
static constexpr size_t _get_static_no_of_parameters()
|
||||
@ -266,18 +285,18 @@ namespace sqlpp
|
||||
|
||||
size_t get_no_of_result_columns() const
|
||||
{
|
||||
return static_size() + get_dynamic_names().size();
|
||||
return sizeof...(Columns) + get_dynamic_names().size();
|
||||
}
|
||||
|
||||
// Execute
|
||||
template<typename Db>
|
||||
auto _run(Db& db) const
|
||||
-> result_t<decltype(db.select(std::declval<const _statement_t>())), _result_row_t<Db>>
|
||||
-> result_t<decltype(db.select(_get_statement())), _result_row_t<Db>>
|
||||
{
|
||||
Policies::_check_consistency();
|
||||
static_assert(_get_static_no_of_parameters() == 0, "cannot run select directly with parameters, use prepare instead");
|
||||
|
||||
return {db.select(static_cast<const _statement_t&>(*this)), get_dynamic_names()};
|
||||
return {db.select(_get_statement()), get_dynamic_names()};
|
||||
}
|
||||
#if 0
|
||||
|
||||
@ -293,10 +312,6 @@ namespace sqlpp
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
const select_column_list_t& _column_list() const { return *this; }
|
||||
std::tuple<Columns...> _columns;
|
||||
dynamic_select_column_list<Database> _dynamic_columns;
|
||||
};
|
||||
}
|
||||
|
||||
@ -315,17 +330,30 @@ 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
|
||||
struct _data_t
|
||||
{
|
||||
static_assert(wrong_t<T>::value, "Cannot use a select as a table when no columns have been selected yet");
|
||||
};
|
||||
|
||||
// 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
|
||||
{
|
||||
_impl_t<Policies> no_selected_columns;
|
||||
_impl_t<Policies>& operator()() { return no_selected_columns; }
|
||||
const _impl_t<Policies>& operator()() const { return no_selected_columns; }
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -337,7 +365,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>
|
||||
@ -345,20 +373,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)...)} };
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Policies>
|
||||
struct _result_methods_t
|
||||
{};
|
||||
};
|
||||
|
||||
// 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)
|
||||
{
|
||||
@ -374,9 +398,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_select_column_list_t>
|
||||
struct serializer_t<Context, typename no_select_column_list_t::_data_t>
|
||||
{
|
||||
using T = no_select_column_list_t;
|
||||
using T = typename no_select_column_list_t::_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
148
include/sqlpp11/vendor/where.h
vendored
148
include/sqlpp11/vendor/where.h
vendored
@ -38,96 +38,160 @@ namespace sqlpp
|
||||
{
|
||||
namespace vendor
|
||||
{
|
||||
// WHERE
|
||||
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
|
||||
{
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return 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
|
||||
{
|
||||
_impl_t<Policies> where;
|
||||
_impl_t<Policies>& operator()() { return where; }
|
||||
const _impl_t<Policies>& operator()() const { return 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
|
||||
struct _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
|
||||
{
|
||||
_impl_t<Policies> no_where;
|
||||
_impl_t<Policies>& operator()() { return no_where; }
|
||||
const _impl_t<Policies>& operator()() const { return no_where; }
|
||||
};
|
||||
|
||||
// Additional methods for the statement
|
||||
template<typename Policies>
|
||||
struct _methods_t
|
||||
{
|
||||
@ -139,7 +203,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 +211,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 +236,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)
|
||||
{
|
||||
@ -185,9 +249,9 @@ namespace sqlpp
|
||||
};
|
||||
|
||||
template<typename Context>
|
||||
struct serializer_t<Context, no_where_t>
|
||||
struct serializer_t<Context, typename no_where_t::_data_t>
|
||||
{
|
||||
using T = no_where_t;
|
||||
using T = typename no_where_t::_data_t;
|
||||
|
||||
static Context& _(const T& t, Context& context)
|
||||
{
|
||||
|
@ -55,6 +55,7 @@ int main()
|
||||
const std::string b = row.beta;
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (const auto& row : db(select(all_of(t).as(t)).from(t).where(true)))
|
||||
{
|
||||
int64_t a = row.tabBar.alpha;
|
||||
@ -85,6 +86,7 @@ int main()
|
||||
|
||||
|
||||
auto X = select(all_of(t)).from(t).as(t.alpha);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user