0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-16 04:47:18 +08:00

Clean up superfluous classes and functions

And remove some remaining dynamic parts which were overlooked before.
This commit is contained in:
Roland Bock 2024-06-08 18:33:40 +02:00
parent c347b5d11c
commit 8d0f3b3739
53 changed files with 513 additions and 2184 deletions

View File

@ -36,6 +36,7 @@
#include <optional>
namespace sqlpp
{
#warning move into compat?
template <class T>
using optional = std::optional<T>;

View File

@ -34,7 +34,7 @@
namespace sqlpp
{
template <typename Database, typename... Parts>
template <typename... Parts>
struct custom_query_t;
namespace detail
@ -50,20 +50,20 @@ namespace sqlpp
using type = Clause;
};
template <typename Db, typename... Parts>
template <typename... Parts>
struct custom_parts_t
{
using _custom_query_t = custom_query_t<Db, Parts...>;
using _custom_query_t = custom_query_t<Parts...>;
using _maybe_hidden_result_type_provider = detail::get_first_if<is_return_value_t, noop, Parts...>;
using _result_type_provider = typename unhide<_maybe_hidden_result_type_provider>::type;
using _result_methods_t = typename _result_type_provider::template _result_methods_t<_result_type_provider>;
};
} // namespace detail
template <typename Database, typename... Parts>
struct custom_query_t : private detail::custom_parts_t<Database, Parts...>::_result_methods_t
template <typename... Parts>
struct custom_query_t : private detail::custom_parts_t<Parts...>::_result_methods_t
{
using _methods_t = typename detail::custom_parts_t<Database, Parts...>::_result_methods_t;
using _methods_t = typename detail::custom_parts_t<Parts...>::_result_methods_t;
using _traits = make_traits<no_value_t, tag::is_statement>;
using _nodes = detail::type_vector<Parts...>;
@ -113,7 +113,7 @@ namespace sqlpp
}
template <typename Part>
auto with_result_type_of(Part part) -> custom_query_t<Database, hidden_t<Part>, Parts...>
auto with_result_type_of(Part part) -> custom_query_t<hidden_t<Part>, Parts...>
{
return {tuple_cat(std::make_tuple(hidden(part)), _parts)};
}
@ -121,18 +121,18 @@ namespace sqlpp
std::tuple<Parts...> _parts;
};
template <typename Context, typename Database, typename... Parts>
Context& serialize(const custom_query_t<Database, Parts...>& t, Context& context)
template <typename Context, typename... Parts>
Context& serialize(const custom_query_t<Parts...>& t, Context& context)
{
interpret_tuple_without_braces(t._parts, " ", context);
return context;
}
template <typename... Parts>
auto custom_query(Parts... parts) -> custom_query_t<void, wrap_operand_t<Parts>...>
auto custom_query(Parts... parts) -> custom_query_t<wrap_operand_t<Parts>...>
{
static_assert(sizeof...(Parts) > 0, "custom query requires at least one argument");
return custom_query_t<void, wrap_operand_t<Parts>...>(parts...);
return custom_query_t<wrap_operand_t<Parts>...>(parts...);
}
} // namespace sqlpp

View File

@ -32,23 +32,25 @@ namespace sqlpp
{
namespace detail
{
template <typename Target, typename Statement, typename Term>
typename Target::_data_t pick_arg_impl(Statement /* statement */, Term term, const std::true_type& /*unused*/)
template <typename Clause, typename OldStatement, typename NewClauseData>
const typename Clause::_data_t& pick_arg_impl(const OldStatement& /* old_statement */, const NewClauseData& new_data, const std::true_type& /*unused*/)
{
return term;
return new_data;
}
template <typename Target, typename Statement, typename Term>
typename Target::_data_t pick_arg_impl(Statement statement, Term /* term */, const std::false_type& /*unused*/)
template <typename Clause, typename OldStatement, typename NewClauseData>
const typename Clause::_data_t& pick_arg_impl(const OldStatement& old_statement, const NewClauseData& /* new_data */, const std::false_type& /*unused*/)
{
return Target::_get_member(statement)._data;
using old_policies_t = typename OldStatement::_policies_t;
using old_base_t = typename Clause::_base_t<old_policies_t>;
return static_cast<const old_base_t&>(old_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>
typename Target::_data_t pick_arg(Statement statement, Term term)
// Returns a old_statement's new_data either by picking the new_data from the old_statement or using the new new_data
template <typename Clause, typename OldStatement, typename NewClauseData>
const typename Clause::_data_t& pick_arg(const OldStatement& old_statement, const NewClauseData& new_data)
{
return pick_arg_impl<Target>(statement, term, std::is_same<typename Target::_data_t, Term>());
return pick_arg_impl<Clause>(old_statement, new_data, std::is_same<typename Clause::_data_t, typename std::decay<NewClauseData>::type>());
}
} // namespace detail
} // namespace sqlpp

View File

@ -43,49 +43,17 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_for_update>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = for_update_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = for_update_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : for_update{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> for_update;
_impl_t<Policies>& operator()()
{
return for_update;
}
const _impl_t<Policies>& operator()() const
{
return for_update;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.for_update)
{
return t.for_update;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -99,48 +67,16 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_for_update{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> no_for_update;
_impl_t<Policies>& operator()()
{
return no_for_update;
}
const _impl_t<Policies>& operator()() const
{
return no_for_update;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_for_update)
{
return t.no_for_update;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_for_update_t, T>;
@ -163,8 +99,8 @@ namespace sqlpp
}
template <typename T>
auto for_update(T&& t) -> decltype(statement_t<void, no_for_update_t>().for_update(std::forward<T>(t)))
auto for_update(T&& t) -> decltype(statement_t<no_for_update_t>().for_update(std::forward<T>(t)))
{
return statement_t<void, no_for_update_t>().for_update(std::forward<T>(t));
return statement_t<no_for_update_t>().for_update(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -36,76 +36,30 @@
namespace sqlpp
{
// FROM DATA
template <typename Database, typename Table>
template <typename Table>
struct from_data_t
{
from_data_t(Table table) : _table(table)
{
}
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;
Table _table;
};
// FROM
template <typename Database, typename Table>
template <typename Table>
struct from_t
{
using _traits = make_traits<no_value_t, tag::is_from>;
using _nodes = detail::type_vector<Table>;
// Data
using _data_t = from_data_t<Database, Table>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
using _database_t = Database;
using _table_t = Table;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = from_data_t<Table>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = from_data_t<Database, Table>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : from{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
// FIXME: We might want to check if we have too many tables define in the FROM
using _consistency_check = consistent_t;
@ -142,51 +96,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_from{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_from_t, T>;
@ -194,29 +115,29 @@ namespace sqlpp
using _consistency_check = consistent_t;
template <typename Table>
auto from(Table table) const -> _new_statement_t<check_from_static_t<Table>, from_t<void, from_table_t<Table>>>
auto from(Table table) const -> _new_statement_t<check_from_static_t<Table>, from_t<from_table_t<Table>>>
{
using Check = check_from_static_t<Table>;
return _from_impl<void>(Check{}, table);
return _from_impl(Check{}, table);
}
private:
template <typename Database, typename Check, typename Table>
template <typename Check, typename Table>
auto _from_impl(Check, Table table) const -> inconsistent<Check>;
template <typename Database, typename Table>
template <typename Table>
auto _from_impl(consistent_t /*unused*/, Table table) const
-> _new_statement_t<consistent_t, from_t<Database, from_table_t<Table>>>
-> _new_statement_t<consistent_t, from_t<from_table_t<Table>>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
from_data_t<Database, from_table_t<Table>>{from_table(table)}};
from_data_t<from_table_t<Table>>{from_table(table)}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename Table>
Context& serialize(const from_data_t<Database, Table>& t, Context& context)
template <typename Context, typename Table>
Context& serialize(const from_data_t<Table>& t, Context& context)
{
context << " FROM ";
serialize(t._table, context);
@ -224,9 +145,9 @@ namespace sqlpp
}
template <typename T>
auto from(T&& t) -> decltype(statement_t<void, no_from_t>().from(std::forward<T>(t)))
auto from(T&& t) -> decltype(statement_t<no_from_t>().from(std::forward<T>(t)))
{
return statement_t<void, no_from_t>().from(std::forward<T>(t));
return statement_t<no_from_t>().from(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -36,7 +36,7 @@
namespace sqlpp
{
// GROUP BY DATA
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct group_by_data_t
{
group_by_data_t(Expressions... expressions) : _expressions(expressions...)
@ -57,7 +57,7 @@ namespace sqlpp
"at least one group-by expression requires a table which is otherwise not known in the statement");
// GROUP BY
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct group_by_t
{
using _traits = make_traits<no_value_t, tag::is_group_by>;
@ -65,50 +65,17 @@ namespace sqlpp
using _provided_aggregates = detail::make_type_set_t<Expressions...>;
// Data
using _data_t = group_by_data_t<Database, Expressions...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = group_by_data_t<Expressions...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = group_by_data_t<Database, Expressions...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : group_by{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<group_by_t>::value,
consistent_t,
@ -136,48 +103,16 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_group_by{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_group_by_t, T>;
@ -186,33 +121,33 @@ namespace sqlpp
template <typename... Expressions>
auto group_by(Expressions... expressions) const
-> _new_statement_t<check_group_by_t<Expressions...>, group_by_t<void, Expressions...>>
-> _new_statement_t<check_group_by_t<Expressions...>, group_by_t<Expressions...>>
{
static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in group_by()");
return _group_by_impl<void>(check_group_by_t<Expressions...>{}, expressions...);
return _group_by_impl(check_group_by_t<Expressions...>{}, expressions...);
}
private:
template <typename Database, typename Check, typename... Expressions>
template <typename Check, typename... Expressions>
auto _group_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
template <typename Database, typename... Expressions>
template <typename... Expressions>
auto _group_by_impl(consistent_t /*unused*/, Expressions... expressions) const
-> _new_statement_t<consistent_t, group_by_t<Database, Expressions...>>
-> _new_statement_t<consistent_t, group_by_t<Expressions...>>
{
static_assert(not detail::has_duplicates<Expressions...>::value,
"at least one duplicate argument detected in group_by()");
return {static_cast<const derived_statement_t<Policies>&>(*this),
group_by_data_t<Database, Expressions...>{expressions...}};
group_by_data_t<Expressions...>{expressions...}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename... Expressions>
Context& serialize(const group_by_data_t<Database, Expressions...>& t, Context& context)
template <typename Context, typename... Expressions>
Context& serialize(const group_by_data_t<Expressions...>& t, Context& context)
{
context << " GROUP BY ";
interpret_tuple(t._expressions, ',', context);
@ -220,9 +155,9 @@ namespace sqlpp
}
template <typename... T>
auto group_by(T&&... t) -> decltype(statement_t<void, no_group_by_t>().group_by(std::forward<T>(t)...))
auto group_by(T&&... t) -> decltype(statement_t<no_group_by_t>().group_by(std::forward<T>(t)...))
{
return statement_t<void, no_group_by_t>().group_by(std::forward<T>(t)...);
return statement_t<no_group_by_t>().group_by(std::forward<T>(t)...);
}
} // namespace sqlpp

View File

@ -36,7 +36,7 @@
namespace sqlpp
{
// HAVING DATA
template <typename Database, typename Expression>
template <typename Expression>
struct having_data_t
{
having_data_t(Expression expression) : _expression(expression)
@ -60,56 +60,24 @@ namespace sqlpp
"having expression not built out of aggregate expressions");
// HAVING
template <typename Database, typename Expression>
template <typename Expression>
struct having_t
{
using _traits = make_traits<no_value_t, tag::is_having>;
using _nodes = detail::type_vector<Expression>;
// Data
using _data_t = having_data_t<Database, Expression>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = having_data_t<Expression>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = having_data_t<Database, Expression>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : having{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _table_check = typename std::conditional<Policies::template _no_unknown_tables<having_t>::value,
consistent_t,
@ -159,48 +127,17 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_having{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> no_having;
_impl_t<Policies>& operator()()
{
return no_having;
}
const _impl_t<Policies>& operator()() const
{
return no_having;
}
_data_t _data;
template <typename T>
static auto _get_member(T t) -> decltype(t.no_having)
{
return t.no_having;
}
using _database_t = typename Policies::_database_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename... T>
@ -217,30 +154,30 @@ namespace sqlpp
template <typename Expression>
auto having(Expression expression) const
-> _new_statement_t<check_having_static_t<Expression>, having_t<void, Expression>>
-> _new_statement_t<check_having_static_t<Expression>, having_t<Expression>>
{
using Check = check_having_static_t<Expression>;
return _having_impl<void>(Check{}, expression);
return _having_impl(Check{}, expression);
}
private:
template <typename Database, typename Check, typename Expression>
template <typename Check, typename Expression>
auto _having_impl(Check, Expression expression) const -> inconsistent<Check>;
template <typename Database, typename Expression>
template <typename Expression>
auto _having_impl(consistent_t /*unused*/, Expression expression) const
-> _new_statement_t<consistent_t, having_t<Database, Expression>>
-> _new_statement_t<consistent_t, having_t<Expression>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
having_data_t<Database, Expression>{expression}};
having_data_t<Expression>{expression}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename Expression>
Context& serialize(const having_data_t<Database, Expression>& t, Context& context)
template <typename Context, typename Expression>
Context& serialize(const having_data_t<Expression>& t, Context& context)
{
context << " HAVING ";
serialize(t._expression, context);
@ -248,9 +185,9 @@ namespace sqlpp
}
template <typename T>
auto having(T&& t) -> decltype(statement_t<void, no_having_t>().having(std::forward<T>(t)))
auto having(T&& t) -> decltype(statement_t<no_having_t>().having(std::forward<T>(t)))
{
return statement_t<void, no_having_t>().having(std::forward<T>(t));
return statement_t<no_having_t>().having(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -95,18 +95,17 @@ namespace sqlpp
return context;
}
template <typename Database>
using blank_insert_t = statement_t<Database, insert_t, no_into_t, no_insert_value_list_t>;
using blank_insert_t = statement_t<insert_t, no_into_t, no_insert_value_list_t>;
inline auto insert() -> blank_insert_t<void>
inline auto insert() -> blank_insert_t
{
return {};
}
template <typename Table>
constexpr auto insert_into(Table table) -> decltype(blank_insert_t<void>().into(table))
constexpr auto insert_into(Table table) -> decltype(blank_insert_t().into(table))
{
return {blank_insert_t<void>().into(table)};
return {blank_insert_t().into(table)};
}
} // namespace sqlpp

View File

@ -73,52 +73,21 @@ namespace sqlpp
// Data
using _data_t = insert_default_values_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = insert_default_values_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : default_values{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
};
template <typename Database, typename... Assignments>
template <typename... Assignments>
struct insert_list_data_t
{
insert_list_data_t(std::tuple<Assignments...> assignments)
@ -229,110 +198,33 @@ namespace sqlpp
template <typename... Assignments>
using check_insert_static_set_t = typename check_insert_static_set<Assignments...>::type;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
// template <typename Database, typename... Assignments>
// using check_insert_dynamic_set_t = static_combined_check_t<
// static_check_t<not std::is_same<Database, void>::value, assert_insert_dynamic_set_statement_dynamic_t>,
// check_insert_set_t<Assignments...>>;
template <typename Database, typename... Assignments>
struct check_insert_dynamic_set
{
using type = static_combined_check_t<
static_check_t<not std::is_same<Database, void>::value, assert_insert_dynamic_set_statement_dynamic_t>,
check_insert_set_t<Assignments...>>;
};
template <typename Database, typename... Assignments>
using check_insert_dynamic_set_t = typename check_insert_dynamic_set<Database, Assignments...>::type;
SQLPP_PORTABLE_STATIC_ASSERT(
assert_no_unknown_tables_in_insert_assignments_t,
"at least one insert assignment requires a table which is otherwise not known in the statement");
template <typename Database, typename... Assignments>
template <typename... Assignments>
struct insert_list_t
{
using _traits = make_traits<no_value_t, tag::is_insert_list>;
using _nodes = detail::type_vector<lhs_t<Assignments>..., rhs_t<Assignments>...>;
using _is_dynamic = is_database<Database>;
template <template <typename...> class Target>
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
template <template <typename...> class Target, template <typename> class Wrap>
using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>;
// Data
using _data_t = insert_list_data_t<Database, Assignments...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
template <typename Assignment>
void add(Assignment assignment)
{
static_assert(_is_dynamic::value, "add must not be called for static from()");
static_assert(is_assignment_t<Assignment>::value, "add() arguments require to be assigments");
using _assigned_columns = detail::make_type_set_t<lhs_t<Assignments>...>;
static_assert(not _assigned_columns::template count<lhs_t<Assignment>>(),
"Must not assign value to column twice");
static_assert(not must_not_insert_t<lhs_t<Assignment>>::value, "add() argument must not be used in insert");
static_assert(Policies::template _no_unknown_tables<Assignment>::value,
"add() contains a column from a foreign table");
using ok = logic::all_t<_is_dynamic::value, is_assignment_t<Assignment>::value>;
_add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
}
private:
template <typename Assignment>
void _add_impl(Assignment assignment, const std::true_type& /*unused*/)
{
_data._dynamic_columns.emplace_back(simple_column_t<lhs_t<Assignment>>{assignment._lhs});
_data._dynamic_values.emplace_back(assignment._rhs);
}
template <typename Assignment>
void _add_impl(Assignment assignment, const std::false_type&);
public:
_data_t _data;
};
using _data_t = insert_list_data_t<Assignments...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = insert_list_data_t<Database, Assignments...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : insert_list{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<insert_list_t>::value,
consistent_t,
@ -373,18 +265,18 @@ namespace sqlpp
// Data
using _data_t = column_list_data_t<Columns...>;
// Member implementation with data and methods
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
template <typename... Assignments>
void add(Assignments... assignments)
void add_values(Assignments... assignments)
{
static_assert(logic::all_t<is_assignment_t<Assignments>::value...>::value,
"add_values() arguments have to be assignments");
@ -405,40 +297,9 @@ namespace sqlpp
}
template <typename... Assignments>
void _add_impl(const std::false_type&, Assignments... assignments);
void _add_impl(const std::false_type& /*unused*/, Assignments... /*unused*/);
public:
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = column_list_data_t<Columns...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : values{std::forward<Args>(args)...}
{
}
_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;
}
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<column_list_t>::value,
consistent_t,
assert_no_unknown_tables_in_column_list_t>::type;
@ -463,51 +324,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_insert_values{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_insert_value_list_t, T>;
@ -530,35 +358,18 @@ namespace sqlpp
template <typename... Assignments>
auto set(Assignments... assignments) const
-> _new_statement_t<check_insert_static_set_t<Assignments...>, insert_list_t<void, Assignments...>>
-> _new_statement_t<check_insert_static_set_t<Assignments...>, insert_list_t<Assignments...>>
{
using Check = check_insert_static_set_t<Assignments...>;
return _set_impl<void>(Check{}, std::make_tuple(assignments...));
return _set_impl(Check{}, std::make_tuple(assignments...));
}
template <typename... Assignments>
auto set(std::tuple<Assignments...> assignments) const
-> _new_statement_t<check_insert_static_set_t<Assignments...>, insert_list_t<void, Assignments...>>
-> _new_statement_t<check_insert_static_set_t<Assignments...>, insert_list_t<Assignments...>>
{
using Check = check_insert_static_set_t<Assignments...>;
return _set_impl<void>(Check{}, assignments);
}
template <typename... Assignments>
auto dynamic_set(Assignments... assignments) const
-> _new_statement_t<check_insert_dynamic_set_t<_database_t, Assignments...>,
insert_list_t<_database_t, Assignments...>>
{
using Check = check_insert_dynamic_set_t<_database_t, Assignments...>;
return _set_impl<_database_t>(Check{}, std::make_tuple(assignments...));
}
template <typename... Assignments>
auto dynamic_set(std::tuple<Assignments...> assignments) const
-> _new_statement_t<check_insert_dynamic_set_t<_database_t, Assignments...>,
insert_list_t<_database_t, Assignments...>>
{
using Check = check_insert_dynamic_set_t<_database_t, Assignments...>;
return _set_impl<_database_t>(Check{}, assignments);
return _set_impl(Check{}, assignments);
}
private:
@ -582,15 +393,15 @@ namespace sqlpp
return {static_cast<const derived_statement_t<Policies>&>(*this), column_list_data_t<Columns...>{cols...}};
}
template <typename Database, typename Check, typename... Assignments>
template <typename Check, typename... Assignments>
auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
template <typename Database, typename... Assignments>
template <typename... Assignments>
auto _set_impl(consistent_t /*unused*/, std::tuple<Assignments...> assignments) const
-> _new_statement_t<consistent_t, insert_list_t<Database, Assignments...>>
-> _new_statement_t<consistent_t, insert_list_t<Assignments...>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
insert_list_data_t<Database, Assignments...>{assignments}};
insert_list_data_t<Assignments...>{assignments}};
}
};
};
@ -630,8 +441,8 @@ namespace sqlpp
return context;
}
template <typename Context, typename Database, typename... Assignments>
Context& serialize(const insert_list_data_t<Database, Assignments...>& t, Context& context)
template <typename Context, typename... Assignments>
Context& serialize(const insert_list_data_t<Assignments...>& t, Context& context)
{
context << " (";
interpret_tuple(t._columns, ",", context);
@ -644,15 +455,15 @@ namespace sqlpp
template <typename... Assignments>
auto insert_set(Assignments... assignments)
-> decltype(statement_t<void, no_insert_value_list_t>().set(assignments...))
-> decltype(statement_t<no_insert_value_list_t>().set(assignments...))
{
return statement_t<void, no_insert_value_list_t>().set(assignments...);
return statement_t<no_insert_value_list_t>().set(assignments...);
}
template <typename... Columns>
auto insert_columns(Columns... cols)
-> decltype(statement_t<void, no_insert_value_list_t>().columns(cols...))
-> decltype(statement_t<no_insert_value_list_t>().columns(cols...))
{
return statement_t<void, no_insert_value_list_t>().columns(cols...);
return statement_t<no_insert_value_list_t>().columns(cols...);
}
} // namespace sqlpp

View File

@ -36,7 +36,7 @@
namespace sqlpp
{
// A SINGLE TABLE DATA
template <typename Database, typename Table>
template <typename Table>
struct into_data_t
{
into_data_t(Table table) : _table(table)
@ -53,58 +53,27 @@ namespace sqlpp
};
// A SINGLE TABLE
template <typename Database, typename Table>
template <typename Table>
struct into_t
{
using _traits = make_traits<no_value_t, tag::is_into>;
using _nodes = detail::type_vector<Table>;
using _data_t = into_data_t<Database, Table>;
using _data_t = into_data_t<Table>;
struct _alias_t
{
};
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = into_data_t<Database, Table>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : into{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -127,39 +96,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
_impl_t<Policies> no_into;
_impl_t<Policies>& operator()()
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_into_t, T>;
@ -167,30 +115,30 @@ namespace sqlpp
using _consistency_check = assert_into_t;
template <typename Table>
auto into(Table table) const -> _new_statement_t<check_into_t<Table>, into_t<void, Table>>
auto into(Table table) const -> _new_statement_t<check_into_t<Table>, into_t<Table>>
{
return _into_impl<void>(check_into_t<Table>{}, table);
return _into_impl(check_into_t<Table>{}, table);
}
private:
template <typename Database, typename Check, typename Table>
template <typename Check, typename Table>
auto _into_impl(Check, Table table) const -> inconsistent<Check>;
template <typename Database, typename Table>
template <typename Table>
auto _into_impl(consistent_t /*unused*/, Table table) const
-> _new_statement_t<consistent_t, into_t<Database, Table>>
-> _new_statement_t<consistent_t, into_t<Table>>
{
static_assert(required_tables_of<into_t<Database, Table>>::size::value == 0,
static_assert(required_tables_of<into_t<Table>>::size::value == 0,
"argument depends on another table in into()");
return {static_cast<const derived_statement_t<Policies>&>(*this), into_data_t<Database, Table>{table}};
return {static_cast<const derived_statement_t<Policies>&>(*this), into_data_t<Table>{table}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename Table>
Context& serialize(const into_data_t<Database, Table>& t, Context& context)
template <typename Context, typename Table>
Context& serialize(const into_data_t<Table>& t, Context& context)
{
context << " INTO ";
serialize(t._table, context);
@ -198,8 +146,8 @@ namespace sqlpp
}
template <typename T>
auto into(T&& t) -> decltype(statement_t<void, no_into_t>().into(std::forward<T>(t)))
auto into(T&& t) -> decltype(statement_t<no_into_t>().into(std::forward<T>(t)))
{
return statement_t<void, no_into_t>().into(std::forward<T>(t));
return statement_t<no_into_t>().into(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -59,46 +59,15 @@ namespace sqlpp
// Data
using _data_t = limit_data_t<Limit>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = limit_data_t<Limit>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : limit{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -120,51 +89,19 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_limit{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> no_limit;
_impl_t<Policies>& operator()()
{
return no_limit;
}
const _impl_t<Policies>& operator()() const
{
return no_limit;
}
_data_t _data;
template <typename T>
static auto _get_member(T t) -> decltype(t.no_limit)
{
return t.no_limit;
}
using _database_t = typename Policies::_database_t;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_limit_t, T>;
@ -199,9 +136,9 @@ namespace sqlpp
}
template <typename T>
auto limit(T&& t) -> decltype(statement_t<void, no_limit_t>().limit(std::forward<T>(t)))
auto limit(T&& t) -> decltype(statement_t<no_limit_t>().limit(std::forward<T>(t)))
{
return statement_t<void, no_limit_t>().limit(std::forward<T>(t));
return statement_t<no_limit_t>().limit(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -34,35 +34,20 @@ namespace sqlpp
{
namespace mysql
{
template <typename Database>
using blank_remove_t =
statement_t<Database, remove_t, no_from_t, no_using_t, no_where_t<true>, no_order_by_t, no_limit_t>;
statement_t<remove_t, no_from_t, no_using_t, no_where_t<true>, no_order_by_t, no_limit_t>;
inline auto remove() -> blank_remove_t<void>
inline auto remove() -> blank_remove_t
{
return {};
}
template <typename Table>
auto remove_from(Table table) -> decltype(blank_remove_t<void>().from(table))
auto remove_from(Table table) -> decltype(blank_remove_t().from(table))
{
return {blank_remove_t<void>().from(table)};
return {blank_remove_t().from(table)};
}
template <typename Database>
auto dynamic_remove(const Database& /*unused*/) -> decltype(blank_remove_t<Database>())
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_remove_t<Database>()};
}
template <typename Database, typename Table>
auto dynamic_remove_from(const Database& /*unused*/, Table table)
-> decltype(blank_remove_t<Database>().from(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_remove_t<Database>().from(table)};
}
} // namespace mysql
} // namespace sqlpp

View File

@ -34,27 +34,14 @@ namespace sqlpp
{
namespace mysql
{
template <typename Database>
using blank_update_t = statement_t<Database,
update_t,
no_single_table_t,
no_update_list_t,
no_where_t<true>,
no_order_by_t,
no_limit_t>;
using blank_update_t =
statement_t<update_t, no_single_table_t, no_update_list_t, no_where_t<true>, no_order_by_t, no_limit_t>;
template <typename Table>
constexpr auto update(Table table) -> decltype(blank_update_t<void>().single_table(table))
constexpr auto update(Table table) -> decltype(blank_update_t().single_table(table))
{
return {blank_update_t<void>().single_table(table)};
return {blank_update_t().single_table(table)};
}
template <typename Database, typename Table>
constexpr auto dynamic_update(const Database& /*unused*/, Table table)
-> decltype(blank_update_t<Database>().single_table(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_update_t<Database>().single_table(table)};
}
} // namespace mysql
} // namespace sqlpp

View File

@ -56,49 +56,17 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_offset>;
using _nodes = detail::type_vector<Offset>;
// Data
using _data_t = offset_data_t<Offset>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = offset_data_t<Offset>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : offset{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -140,31 +108,12 @@ namespace sqlpp
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_offset{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_offset_t, T>;
@ -199,9 +148,9 @@ namespace sqlpp
}
template <typename T>
auto offset(T&& t) -> decltype(statement_t<void, no_offset_t>().offset(std::forward<T>(t)))
auto offset(T&& t) -> decltype(statement_t<no_offset_t>().offset(std::forward<T>(t)))
{
return statement_t<void, no_offset_t>().offset(std::forward<T>(t));
return statement_t<no_offset_t>().offset(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -36,7 +36,7 @@
namespace sqlpp
{
// ORDER BY DATA
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct order_by_data_t
{
order_by_data_t(Expressions... expressions) : _expressions(expressions...)
@ -57,56 +57,23 @@ namespace sqlpp
"at least one order-by expression requires a table which is otherwise not known in the statement");
// ORDER BY
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct order_by_t
{
using _traits = make_traits<no_value_t, tag::is_order_by>;
using _nodes = detail::type_vector<Expressions...>;
// Data
using _data_t = order_by_data_t<Database, Expressions...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = order_by_data_t<Expressions...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = order_by_data_t<Database, Expressions...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : order_by{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<order_by_t>::value,
consistent_t,
@ -134,48 +101,17 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : no_order_by{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> no_order_by;
_impl_t<Policies>& operator()()
{
return no_order_by;
}
const _impl_t<Policies>& operator()() const
{
return no_order_by;
}
_data_t _data;
template <typename T>
static auto _get_member(T t) -> decltype(t.no_order_by)
{
return t.no_order_by;
}
using _database_t = typename Policies::_database_t;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_order_by_t, T>;
@ -184,33 +120,33 @@ namespace sqlpp
template <typename... Expressions>
auto order_by(Expressions... expressions) const
-> _new_statement_t<check_order_by_t<Expressions...>, order_by_t<void, Expressions...>>
-> _new_statement_t<check_order_by_t<Expressions...>, order_by_t<Expressions...>>
{
static_assert(sizeof...(Expressions), "at least one expression (e.g. a column) required in order_by()");
return _order_by_impl<void>(check_order_by_t<Expressions...>{}, expressions...);
return _order_by_impl(check_order_by_t<Expressions...>{}, expressions...);
}
private:
template <typename Database, typename Check, typename... Expressions>
template <typename Check, typename... Expressions>
auto _order_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>;
template <typename Database, typename... Expressions>
template <typename... Expressions>
auto _order_by_impl(consistent_t /*unused*/, Expressions... expressions) const
-> _new_statement_t<consistent_t, order_by_t<Database, Expressions...>>
-> _new_statement_t<consistent_t, order_by_t<Expressions...>>
{
static_assert(not detail::has_duplicates<Expressions...>::value,
"at least one duplicate argument detected in order_by()");
return {static_cast<const derived_statement_t<Policies>&>(*this),
order_by_data_t<Database, Expressions...>{expressions...}};
order_by_data_t<Expressions...>{expressions...}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename... Expressions>
Context& serialize(const order_by_data_t<Database, Expressions...>& t, Context& context)
template <typename Context, typename... Expressions>
Context& serialize(const order_by_data_t<Expressions...>& t, Context& context)
{
context << " ORDER BY ";
interpret_tuple(t._expressions, ',', context);
@ -218,9 +154,9 @@ namespace sqlpp
}
template <typename... T>
auto order_by(T&&... t) -> decltype(statement_t<void, no_order_by_t>().order_by(std::forward<T>(t)...))
auto order_by(T&&... t) -> decltype(statement_t<no_order_by_t>().order_by(std::forward<T>(t)...))
{
return statement_t<void, no_order_by_t>().order_by(std::forward<T>(t)...);
return statement_t<no_order_by_t>().order_by(std::forward<T>(t)...);
}
} // namespace sqlpp

View File

@ -34,33 +34,19 @@ namespace sqlpp
{
namespace postgresql
{
template <typename Database>
using blank_insert_t =
statement_t<Database, insert_t, no_into_t, no_insert_value_list_t, no_on_conflict_t, no_returning_t>;
statement_t<insert_t, no_into_t, no_insert_value_list_t, no_on_conflict_t, no_returning_t>;
inline auto insert() -> blank_insert_t<void>
inline auto insert() -> blank_insert_t
{
return {blank_insert_t<void>()};
return {blank_insert_t()};
}
template <typename Table>
constexpr auto insert_into(Table table) -> decltype(blank_insert_t<void>().into(table))
constexpr auto insert_into(Table table) -> decltype(blank_insert_t().into(table))
{
return {blank_insert_t<void>().into(table)};
return {blank_insert_t().into(table)};
}
template <typename Database>
constexpr auto dynamic_insert(const Database&) -> decltype(blank_insert_t<Database>())
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_insert_t<Database>()};
}
template <typename Database, typename Table>
constexpr auto dynamic_insert_into(const Database&, Table table) -> decltype(blank_insert_t<Database>().into(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_insert_t<Database>().into(table)};
}
} // namespace postgresql
} // namespace sqlpp

View File

@ -108,44 +108,15 @@ namespace sqlpp
using _data_t = on_conflict_data_t<ConflictTarget>;
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
template <typename Policies>
struct _base_t
{
using _data_t = on_conflict_data_t<ConflictTarget>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069
template <typename... Args>
_base_t(Args&&... args) : on_conflict{std::forward<Args>(args)...}
{
}
_impl_t<Policies> on_conflict;
_impl_t<Policies>& operator()()
{
return on_conflict;
}
const _impl_t<Policies>& operator()() const
{
return on_conflict;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.on_conflict)
{
return t.on_conflict;
}
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, on_conflict_t, T>;
@ -156,20 +127,19 @@ namespace sqlpp
auto do_nothing() const -> _new_statement_t<consistent_t, on_conflict_do_nothing_t<ConflictTarget>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
on_conflict_do_nothing_data_t<ConflictTarget>{on_conflict._data}};
on_conflict_do_nothing_data_t<ConflictTarget>{_data}};
}
// DO UPDATE
template <typename... Assignments>
auto do_update(Assignments... assignments) const
-> _new_statement_t<check_on_conflict_do_update_static_set_t<Assignments...>,
on_conflict_do_update_t<void, ConflictTarget, Assignments...>>
on_conflict_do_update_t<ConflictTarget, Assignments...>>
{
static_assert(is_column_t<ConflictTarget>::value,
"conflict_target specification is required with do_update(...)");
return {static_cast<const derived_statement_t<Policies>&>(*this),
on_conflict_do_update_data_t<void, ConflictTarget, Assignments...>(on_conflict._data,
std::make_tuple(assignments...))};
on_conflict_do_update_data_t<ConflictTarget, Assignments...>(_data, std::make_tuple(assignments...))};
}
};
};
@ -181,38 +151,16 @@ namespace sqlpp
using _data_t = no_data_t;
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_on_conflict{std::forward<Args>(args)...}
{
}
_impl_t<Policies> no_on_conflict;
_impl_t<Policies>& operator()()
{
return no_on_conflict;
}
const _impl_t<Policies>& operator()() const
{
return no_on_conflict;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_on_conflict)
@ -220,8 +168,6 @@ namespace sqlpp
return t.no_on_conflict;
}
using _database_t = typename Policies::_database_t;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_on_conflict_t, T>;

View File

@ -66,46 +66,15 @@ namespace sqlpp
// Data
using _data_t = on_conflict_do_nothing_data_t<ConflictTarget>;
// Member implementation and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = on_conflict_do_nothing_data_t<ConflictTarget>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : column{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> column;
_impl_t<Policies>& operator()()
{
return column;
}
const _impl_t<Policies>& operator()() const
{
return column;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.column)
{
return t.column;
}
_data_t _data;
// No consistency check needed, do nothing is just do nothing.
using _consistency_check = consistent_t;

View File

@ -39,7 +39,7 @@ namespace sqlpp
namespace postgresql
{
// Assignments data
template <typename Database, typename ConflictTarget, typename... Assignments>
template <typename ConflictTarget, typename... Assignments>
struct on_conflict_do_update_data_t
{
on_conflict_do_update_data_t(on_conflict_data_t<ConflictTarget> conflict_target,
@ -59,11 +59,11 @@ namespace sqlpp
};
// Where data
template <typename Database, typename ConflictTarget, typename Expression, typename... Assignments>
template <typename ConflictTarget, typename Expression, typename... Assignments>
struct on_conflict_do_update_where_data_t
{
on_conflict_do_update_where_data_t(
Expression expression, on_conflict_do_update_data_t<Database, ConflictTarget, Assignments...> assignments)
Expression expression, on_conflict_do_update_data_t<ConflictTarget, Assignments...> assignments)
: _expression(expression), _assignments(assignments)
{
}
@ -74,115 +74,51 @@ namespace sqlpp
on_conflict_do_update_where_data_t& operator=(on_conflict_do_update_where_data_t&&) = default;
Expression _expression;
on_conflict_do_update_data_t<Database, ConflictTarget, Assignments...> _assignments;
// interpretable_list_t<Database> _dynamic_expressions;
on_conflict_do_update_data_t<ConflictTarget, Assignments...> _assignments;
};
// extra where statement
template <typename Database, typename ConflictTarget, typename Expression, typename... Assignments>
template <typename ConflictTarget, typename Expression, typename... Assignments>
struct on_conflict_do_update_where_t
{
using _traits = make_traits<no_value_t, tag::is_on_conflict_do_update>;
using _nodes = sqlpp::detail::type_vector<ConflictTarget, Expression, Assignments...>;
using _is_dynamic = is_database<Database>;
using _data_t = on_conflict_do_update_where_data_t<Database, ConflictTarget, Expression, Assignments...>;
using _data_t = on_conflict_do_update_where_data_t<ConflictTarget, Expression, Assignments...>;
// Member implementation and methods
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
template <typename Policies>
struct _base_t
{
using _data_t = on_conflict_do_update_where_data_t<Database, ConflictTarget, Expression, Assignments...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : where{std::forward<Args>(args)...}
{
}
_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;
}
using _consistency_check = consistent_t;
};
};
// Use the update_list
template <typename Database, typename ConflictTarget, typename... Assignments>
template <typename ConflictTarget, typename... Assignments>
struct on_conflict_do_update_t
{
using _traits = make_traits<no_value_t, tag::is_on_conflict_do_update>;
using _nodes = sqlpp::detail::type_vector<ConflictTarget, Assignments...>;
using _is_dynamic = is_database<Database>;
// Data
using _data_t = on_conflict_do_update_data_t<Database, ConflictTarget, Assignments...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
using _data_t = on_conflict_do_update_data_t<ConflictTarget, Assignments...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = on_conflict_do_update_data_t<Database, ConflictTarget, Assignments...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : assignments{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
@ -193,18 +129,18 @@ namespace sqlpp
template <typename Expression>
auto where(Expression expression) const
-> _new_statement_t<check_where_static_t<Expression>,
on_conflict_do_update_where_t<void, ConflictTarget, Expression, Assignments...>>
on_conflict_do_update_where_t<ConflictTarget, Expression, Assignments...>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
on_conflict_do_update_where_data_t<void, ConflictTarget, Expression, Assignments...>(
expression, assignments._data)};
on_conflict_do_update_where_data_t<ConflictTarget, Expression, Assignments...>(
expression, _data)};
}
};
};
template <typename Database, typename ConflictTarget, typename... Assignments>
template <typename ConflictTarget, typename... Assignments>
postgresql::context_t& serialize(
const postgresql::on_conflict_do_update_data_t<Database, ConflictTarget, Assignments...>& o,
const postgresql::on_conflict_do_update_data_t<ConflictTarget, Assignments...>& o,
postgresql::context_t& context)
{
serialize(o._conflict_target, context);
@ -213,9 +149,9 @@ namespace sqlpp
return context;
}
template <typename Database, typename ConflictTarget, typename Expression, typename... Assignments>
template <typename ConflictTarget, typename Expression, typename... Assignments>
postgresql::context_t& serialize(
const postgresql::on_conflict_do_update_where_data_t<Database, ConflictTarget, Expression, Assignments...>& o,
const postgresql::on_conflict_do_update_where_data_t<ConflictTarget, Expression, Assignments...>& o,
postgresql::context_t& context)
{
serialize(o._assignments, context);

View File

@ -33,33 +33,18 @@ namespace sqlpp
{
namespace postgresql
{
template <typename Database>
using blank_remove_t = statement_t<Database, remove_t, no_from_t, no_using_t, no_where_t<true>, no_returning_t>;
using blank_remove_t = statement_t<remove_t, no_from_t, no_using_t, no_where_t<true>, no_returning_t>;
inline auto remove() -> blank_remove_t<void>
inline auto remove() -> blank_remove_t
{
return {};
}
template <typename Table>
auto remove_from(Table table) -> decltype(blank_remove_t<void>().from(table))
auto remove_from(Table table) -> decltype(blank_remove_t().from(table))
{
return {blank_remove_t<void>().from(table)};
return {blank_remove_t().from(table)};
}
template <typename Database>
auto dynamic_remove(const Database& /*unused*/) -> decltype(blank_remove_t<Database>())
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_remove_t<Database>()};
}
template <typename Database, typename Table>
auto dynamic_remove_from(const Database& /*unused*/, Table table)
-> decltype(blank_remove_t<Database>().from(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_remove_t<Database>().from(table)};
}
} // namespace postgresql
} // namespace sqlpp

View File

@ -45,10 +45,9 @@ namespace sqlpp
{
};
template <typename Database>
using blank_returning_t = statement_t<Database, returning_t, no_returning_column_list_t>;
using blank_returning_t = statement_t<returning_t, no_returning_column_list_t>;
inline blank_returning_t<void> returning()
inline blank_returning_t returning()
{
return {};
}
@ -60,38 +59,16 @@ namespace sqlpp
using _data_t = no_data_t;
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_returning{std::forward<Args>(args)...}
{
}
_impl_t<Policies> no_returning;
_impl_t<Policies>& operator()()
{
return no_returning;
}
const _impl_t<Policies>& operator()() const
{
return no_returning;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_returning)
@ -99,8 +76,6 @@ namespace sqlpp
return t.no_returning;
}
using _database_t = typename Policies::_database_t;
template <typename... T>
static constexpr auto _check_tuple(std::tuple<T...>) -> check_selected_columns_t<T...>
{
@ -121,51 +96,26 @@ namespace sqlpp
template <typename... Columns>
auto returning(Columns... columns) const
-> _new_statement_t<decltype(_check_args(columns...)), returning_column_list_t<_database_t, Columns...>>
-> _new_statement_t<decltype(_check_args(columns...)), returning_column_list_t<Columns...>>
{
static_assert(sizeof...(Columns),
"at least one returnable expression (e.g. a column) is required in returning");
static_assert(decltype(_check_args(columns...))::value,
"at least one argument is not a returnable expression in returning()");
return {static_cast<const derived_statement_t<Policies>&>(*this),
typename returning_column_list_t<_database_t, Columns...>::_data_t{columns...}};
typename returning_column_list_t<Columns...>::_data_t{columns...}};
}
template <typename... Columns>
auto returning(std::tuple<Columns...> columns) const
-> _new_statement_t<decltype(_check_args(columns)), returning_column_list_t<_database_t, Columns...>>
-> _new_statement_t<decltype(_check_args(columns)), returning_column_list_t<Columns...>>
{
static_assert(sizeof...(Columns),
"at least one returnable expression (e.g. a column) is required in returning");
static_assert(decltype(_check_args(columns))::value,
"at least one argument is not a returnable expression in returning()");
return {static_cast<const derived_statement_t<Policies>&>(*this),
typename returning_column_list_t<_database_t, Columns...>::_data_t{columns}};
}
template <typename... Columns>
auto dynamic_returning(Columns... columns) const
-> _new_statement_t<void, returning_column_list_t<_database_t, Columns...>>
{
static_assert(sizeof...(Columns),
"at least one returnable expression (e.g. a column) is required in returning");
static_assert(decltype(_check_args(columns...))::value,
"at least one argument is not a returnable expression in returning()");
return {static_cast<const derived_statement_t<Policies>&>(*this),
typename returning_column_list_t<_database_t, Columns...>::_data_t{columns...}};
}
template <typename Database, typename... Columns>
auto dynamic_returning(const Database&, Columns... columns)
-> decltype(blank_returning_t<Database>().columns(columns...))
{
static_assert(sizeof...(Columns),
"at least one returnable expression (e.g. a column) is required in returning");
static_assert(decltype(_check_args(columns...))::value,
"at least one argument is not a returnable expression in returning()");
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {static_cast<const derived_statement_t<Policies>&>(*this),
typename dynamic_returning_column_list<_database_t>::_data_t{columns...}};
typename returning_column_list_t<Columns...>::_data_t{columns}};
}
};
};

View File

@ -69,7 +69,7 @@ namespace sqlpp
};
} // namespace detail
template <typename Database, typename... Columns>
template <typename... Columns>
struct returning_column_list_data_t
{
returning_column_list_data_t(Columns... columns) : _columns(columns...)
@ -92,7 +92,7 @@ namespace sqlpp
"at least one returning column requires a table which is otherwise not known in the statement");
// Columns in returning list
template <typename Database, typename... Columns>
template <typename... Columns>
struct returning_column_list_t
{
using _traits = typename detail::returning_traits<Columns...>::_traits;
@ -104,57 +104,17 @@ namespace sqlpp
};
// Data
using _data_t = returning_column_list_data_t<Database, Columns...>;
using _data_t = returning_column_list_data_t<Columns...>;
// Implementation
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
// Base template to be inherited by statement
template <typename Policies>
struct _base_t
{
using _data_t = returning_column_list_data_t<Database, Columns...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : returning_columns{std::forward<Args>(args)...}
{
}
_impl_t<Policies> returning_columns;
_impl_t<Policies>& operator()()
{
return returning_columns;
}
const _impl_t<Policies>& operator()() const
{
return returning_columns;
}
_impl_t<Policies>& get_selected_columns()
{
return returning_columns;
}
const _impl_t<Policies>& get_selected_columns() const
{
return returning_columns;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.returning_columms)
{
return t.returning_columns;
}
// Checks
using _table_check =
@ -185,7 +145,8 @@ namespace sqlpp
template <typename Db, typename Column>
using _field_t = typename _deferred_field_t<Db, Column>::type;
using _result_row_t = result_row_t < Db, _field_t<Db, Columns>... >;
template <typename Db>
using _result_row_t = result_row_t<Db, _field_t<Db, Columns>...>;
template <typename AliasProvider>
struct _deferred_table_t
@ -245,8 +206,8 @@ namespace sqlpp
namespace detail
{
template <typename Database, typename... Columns>
returning_column_list_t<Database, Columns...> make_returning_column_list(std::tuple<Columns...> columns);
template <typename... Columns>
returning_column_list_t<Columns...> make_returning_column_list(std::tuple<Columns...> columns);
}
struct no_returning_column_list_t
@ -261,48 +222,16 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
// Base template to be inherited by the statement
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
// Base template to be inherited
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&... args) : no_returned_columns{std::forward<Args>(args)...}
{
}
_impl_t<Policies> no_returned_columns;
_impl_t<Policies>& operator()()
{
return no_returned_columns;
}
const _impl_t<Policies>& operator()() const
{
return no_returned_columns;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_returned_columns)
{
return t.no_returned_columns;
}
using _database_t = typename Policies::_database_t;
template <typename... T>
struct _check : logic::all_t<is_selectable_t<T>::value...>
@ -330,36 +259,36 @@ namespace sqlpp
template <typename... Args>
auto returning(Args... args) const -> _new_statement_t<
decltype(_check_args(args...)),
decltype(detail::make_returning_column_list<void>(::sqlpp::detail::column_tuple_merge(args...)))>
decltype(detail::make_returning_column_list(::sqlpp::detail::column_tuple_merge(args...)))>
{
static_assert(sizeof...(Args), "at least one selectable expression (e.g. a column) required in returning()");
static_assert(decltype(_check_args(args...))::value,
"at least one argument is not a selectable expression in returning()");
return _returning_impl<void>(decltype(_check_args(args...)){}, ::sqlpp::detail::column_tuple_merge(args...));
return _returning_impl(decltype(_check_args(args...)){}, ::sqlpp::detail::column_tuple_merge(args...));
}
private:
template <typename Database, typename Check, typename... Args>
template <typename Check, typename... Args>
auto _returning_impl(const std::false_type&, std::tuple<Args...> args) const -> inconsistent<Check>;
template <typename Database, typename... Args>
template <typename... Args>
auto _returning_impl(consistent_t, std::tuple<Args...> args) const
-> _new_statement_t<consistent_t, returning_column_list_t<Database, Args...>>
-> _new_statement_t<consistent_t, returning_column_list_t<Args...>>
{
static_assert(not::sqlpp::detail::has_duplicates<Args...>::value, "at least one duplicate argument detected");
static_assert(not::sqlpp::detail::has_duplicates<typename Args::_alias_t...>::value,
"at least one duplicate name detected");
return {static_cast<const derived_statement_t<Policies>&>(*this),
typename returning_column_list_t<Database, Args...>::_data_t{args}};
typename returning_column_list_t<Args...>::_data_t{args}};
}
};
};
// Serialization
template <typename Database, typename... Columns>
postgresql::context_t& serialize(const postgresql::returning_column_list_data_t<Database, Columns...>& t,
template <typename... Columns>
postgresql::context_t& serialize(const postgresql::returning_column_list_data_t<Columns...>& t,
postgresql::context_t& context)
{
context << " RETURNING ";

View File

@ -33,22 +33,14 @@ namespace sqlpp
{
namespace postgresql
{
template <typename Database>
using blank_update_t =
statement_t<Database, update_t, no_single_table_t, no_update_list_t, no_where_t<true>, no_returning_t>;
statement_t<update_t, no_single_table_t, no_update_list_t, no_where_t<true>, no_returning_t>;
template <typename Table>
constexpr auto update(Table table) -> decltype(blank_update_t<void>().single_table(table))
constexpr auto update(Table table) -> decltype(blank_update_t().single_table(table))
{
return {blank_update_t<void>().single_table(table)};
return {blank_update_t().single_table(table)};
}
template <typename Database, typename Table>
constexpr auto dynamic_update(const Database&, Table table)
-> decltype(blank_update_t<Database>().single_table(table))
{
static_assert(std::is_base_of<connection, Database>::value, "Invalid database parameter");
return {blank_update_t<Database>().single_table(table)};
}
}
}

View File

@ -94,18 +94,17 @@ namespace sqlpp
return context;
}
template <typename Database>
using blank_remove_t = statement_t<Database, remove_t, no_from_t, no_using_t, no_where_t<true>>;
using blank_remove_t = statement_t<remove_t, no_from_t, no_using_t, no_where_t<true>>;
inline auto remove() -> blank_remove_t<void>
inline auto remove() -> blank_remove_t
{
return {};
}
template <typename Table>
auto remove_from(Table table) -> decltype(blank_remove_t<void>().from(table))
auto remove_from(Table table) -> decltype(blank_remove_t().from(table))
{
return {blank_remove_t<void>().from(table)};
return {blank_remove_t().from(table)};
}
} // namespace sqlpp

View File

@ -63,9 +63,7 @@ namespace sqlpp
return context;
}
template <typename Database>
using blank_select_t = statement_t<Database,
no_with_t,
using blank_select_t = statement_t<no_with_t,
select_t,
no_select_flag_list_t,
no_select_column_list_t,
@ -77,17 +75,18 @@ namespace sqlpp
no_limit_t,
no_offset_t,
no_union_t,
no_for_update_t>;
no_for_update_t
>;
inline blank_select_t<void> select() // FIXME: These should be constexpr
inline blank_select_t select() // FIXME: These should be constexpr
{
return {};
}
template <typename... Columns>
auto select(Columns... columns) -> decltype(blank_select_t<void>().columns(columns...))
auto select(Columns... columns) -> decltype(blank_select_t().columns(columns...))
{
return blank_select_t<void>().columns(columns...);
return blank_select_t().columns(columns...);
}
} // namespace sqlpp

View File

@ -65,7 +65,7 @@ namespace sqlpp
} // namespace detail
// SELECTED COLUMNS DATA
template <typename Database, typename... Columns>
template <typename... Columns>
struct select_column_list_data_t
{
select_column_list_data_t(Columns... columns) : _columns(columns...)
@ -95,7 +95,7 @@ namespace sqlpp
"not all selected columns are made of aggregates, despite group_by or similar");
// SELECTED COLUMNS
template <typename Database, typename... Columns>
template <typename... Columns>
struct select_column_list_t
{
using _traits = typename detail::select_traits<Columns...>::_traits;
@ -103,62 +103,25 @@ namespace sqlpp
using _alias_t = typename detail::select_traits<Columns...>::_alias_t;
using _data_t = select_column_list_data_t<Columns...>;
struct _column_type
{
};
// Data
using _data_t = select_column_list_data_t<Database, Columns...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = select_column_list_data_t<Database, Columns...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : selected_columns{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> selected_columns;
_impl_t<Policies>& operator()()
{
return selected_columns;
}
const _impl_t<Policies>& operator()() const
{
return selected_columns;
}
_data_t _data;
_impl_t<Policies>& get_selected_columns()
const _base_t& get_selected_columns() const
{
return selected_columns;
}
const _impl_t<Policies>& get_selected_columns() const
{
return selected_columns;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.selected_columns)
{
return t.selected_columns;
return *this;
}
using _table_check = typename std::conditional<Policies::template _no_unknown_tables<select_column_list_t>::value,
@ -260,8 +223,8 @@ namespace sqlpp
namespace detail
{
template <typename Database, typename... Columns>
select_column_list_t<Database, Columns...> make_column_list(std::tuple<Columns...> columns);
template <typename... Columns>
select_column_list_t<Columns...> make_column_list(std::tuple<Columns...> columns);
} // namespace detail
SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable");
@ -283,51 +246,18 @@ namespace sqlpp
{
};
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_selected_columns{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename... T>
static constexpr auto _check_args(std::tuple<T...> /*args*/) -> check_selected_columns_t<T...>
@ -343,42 +273,42 @@ namespace sqlpp
template <typename... Args>
auto columns(Args... args) const
-> _new_statement_t<decltype(_check_args(detail::column_tuple_merge(args...))),
decltype(detail::make_column_list<void>(detail::column_tuple_merge(args...)))>
decltype(detail::make_column_list(detail::column_tuple_merge(args...)))>
{
static_assert(sizeof...(Args), "at least one selectable expression (e.g. a column) required in columns()");
using check = decltype(_check_args(detail::column_tuple_merge(args...)));
static_assert(check::value,
"at least one argument is not a selectable expression in columns()");
return _columns_impl<void>(check{}, detail::column_tuple_merge(args...));
return _columns_impl(check{}, detail::column_tuple_merge(args...));
}
private:
template <typename Database, typename Check, typename... Args>
template <typename Check, typename... Args>
auto _columns_impl(Check, std::tuple<Args...> args) const -> inconsistent<Check>;
template <typename Database, typename... Args>
template <typename... Args>
auto _columns_impl(consistent_t /*unused*/, std::tuple<Args...> args) const
-> _new_statement_t<consistent_t, select_column_list_t<Database, Args...>>
-> _new_statement_t<consistent_t, select_column_list_t<Args...>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
typename select_column_list_t<Database, Args...>::_data_t{args}};
typename select_column_list_t<Args...>::_data_t{args}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename... Columns>
Context& serialize(const select_column_list_data_t<Database, Columns...>& t, Context& context)
template <typename Context, typename... Columns>
Context& serialize(const select_column_list_data_t<Columns...>& t, Context& context)
{
interpret_tuple(t._columns, ',', context);
return context;
}
template <typename... T>
auto select_columns(T&&... t) -> decltype(statement_t<void, no_select_column_list_t>().columns(std::forward<T>(t)...))
auto select_columns(T&&... t) -> decltype(statement_t<no_select_column_list_t>().columns(std::forward<T>(t)...))
{
return statement_t<void, no_select_column_list_t>().columns(std::forward<T>(t)...);
return statement_t<no_select_column_list_t>().columns(std::forward<T>(t)...);
}
} // namespace sqlpp

View File

@ -37,7 +37,7 @@
namespace sqlpp
{
// SELECTED FLAGS DATA
template <typename Database, typename... Flags>
template <typename... Flags>
struct select_flag_list_data_t
{
select_flag_list_data_t(Flags... flgs) : _flags(flgs...)
@ -54,56 +54,23 @@ namespace sqlpp
};
// SELECT FLAGS
template <typename Database, typename... Flags>
template <typename... Flags>
struct select_flag_list_t
{
using _traits = make_traits<no_value_t, tag::is_select_flag_list>;
using _nodes = detail::type_vector<Flags...>;
// Data
using _data_t = select_flag_list_data_t<Database, Flags...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = select_flag_list_data_t<Flags...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = select_flag_list_data_t<Database, Flags...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : select_flags{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -124,51 +91,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_select_flags{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_select_flag_list_t, T>;
@ -177,31 +111,31 @@ namespace sqlpp
template <typename... Flags>
auto flags(Flags... flgs) const
-> _new_statement_t<check_select_flags_t<Flags...>, select_flag_list_t<void, Flags...>>
-> _new_statement_t<check_select_flags_t<Flags...>, select_flag_list_t<Flags...>>
{
return _flags_impl<void>(check_select_flags_t<Flags...>{}, flgs...);
return _flags_impl(check_select_flags_t<Flags...>{}, flgs...);
}
private:
template <typename Database, typename Check, typename... Flags>
template <typename Check, typename... Flags>
auto _flags_impl(Check, Flags... flgs) const -> inconsistent<Check>;
template <typename Database, typename... Flags>
template <typename... Flags>
auto _flags_impl(consistent_t /*unused*/, Flags... flgs) const
-> _new_statement_t<consistent_t, select_flag_list_t<Database, Flags...>>
-> _new_statement_t<consistent_t, select_flag_list_t<Flags...>>
{
static_assert(not detail::has_duplicates<Flags...>::value,
"at least one duplicate argument detected in select flag list");
return {static_cast<const derived_statement_t<Policies>&>(*this),
select_flag_list_data_t<Database, Flags...>{flgs...}};
select_flag_list_data_t<Flags...>{flgs...}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename... Flags>
Context& serialize(const select_flag_list_data_t<Database, Flags...>& t, Context& context)
template <typename Context, typename... Flags>
Context& serialize(const select_flag_list_data_t<Flags...>& t, Context& context)
{
interpret_tuple(t._flags, ' ', context);
if (sizeof...(Flags) != 0u)
@ -212,9 +146,9 @@ namespace sqlpp
}
template <typename T>
auto select_flags(T&& t) -> decltype(statement_t<void, no_select_flag_list_t>().flags(std::forward<T>(t)))
auto select_flags(T&& t) -> decltype(statement_t<no_select_flag_list_t>().flags(std::forward<T>(t)))
{
return statement_t<void, no_select_flag_list_t>().flags(std::forward<T>(t));
return statement_t<no_select_flag_list_t>().flags(std::forward<T>(t));
}
} // namespace sqlpp

View File

@ -35,7 +35,7 @@
namespace sqlpp
{
// A SINGLE TABLE DATA
template <typename Database, typename Table>
template <typename Table>
struct single_table_data_t
{
single_table_data_t(Table table) : _table(table)
@ -52,7 +52,7 @@ namespace sqlpp
};
// A SINGLE TABLE
template <typename Database, typename Table>
template <typename Table>
struct single_table_t
{
using _traits = make_traits<no_value_t, tag::is_single_table>;
@ -61,52 +61,21 @@ namespace sqlpp
static_assert(is_table_t<Table>::value, "argument has to be a table");
static_assert(required_tables_of<Table>::size::value == 0, "table depends on another table");
using _data_t = single_table_data_t<Database, Table>;
using _data_t = single_table_data_t<Table>;
struct _alias_t
{
};
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = single_table_data_t<Database, Table>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : from{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -130,36 +99,16 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
_impl_t<Policies> no_from;
_impl_t<Policies>& operator()()
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_single_table_t, T>;
@ -167,30 +116,30 @@ namespace sqlpp
using _consistency_check = consistent_t;
template <typename Table>
auto single_table(Table table) const -> _new_statement_t<check_update_table_t<Table>, single_table_t<void, Table>>
auto single_table(Table table) const -> _new_statement_t<check_update_table_t<Table>, single_table_t<Table>>
{
return _single_table_impl<void>(check_update_table_t<Table>{}, table);
return _single_table_impl(check_update_table_t<Table>{}, table);
}
private:
template <typename Database, typename Check, typename Table>
template <typename Check, typename Table>
auto _single_table_impl(Check, Table table) const -> inconsistent<Check>;
template <typename Database, typename Table>
template <typename Table>
auto _single_table_impl(consistent_t /*unused*/, Table table) const
-> _new_statement_t<consistent_t, single_table_t<Database, Table>>
-> _new_statement_t<consistent_t, single_table_t<Table>>
{
static_assert(required_tables_of<single_table_t<Database, Table>>::size::value == 0,
static_assert(required_tables_of<single_table_t<Table>>::size::value == 0,
"argument depends on another table in single_table()");
return {static_cast<const derived_statement_t<Policies>&>(*this), single_table_data_t<Database, Table>{table}};
return {static_cast<const derived_statement_t<Policies>&>(*this), single_table_data_t<Table>{table}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename Table>
Context& serialize(const single_table_data_t<Database, Table>& t, Context& context)
template <typename Context, typename Table>
Context& serialize(const single_table_data_t<Table>& t, Context& context)
{
serialize(t._table, context);
return context;

View File

@ -78,62 +78,34 @@ namespace sqlpp
};
};
template <typename Database, typename InsertOrAlternative>
template <typename InsertOrAlternative>
using blank_insert_or_t =
statement_t<Database, insert_or_t<InsertOrAlternative>, no_into_t, no_insert_value_list_t>;
statement_t<insert_or_t<InsertOrAlternative>, no_into_t, no_insert_value_list_t>;
template <typename Database>
using blank_insert_or_replace_t = blank_insert_or_t<Database, insert_or_replace_name_t>;
using blank_insert_or_replace_t = blank_insert_or_t<insert_or_replace_name_t>;
template <typename Database>
using blank_insert_or_ignore_t = blank_insert_or_t<Database, insert_or_ignore_name_t>;
using blank_insert_or_ignore_t = blank_insert_or_t<insert_or_ignore_name_t>;
inline auto insert_or_replace() -> blank_insert_or_replace_t<void>
inline auto insert_or_replace() -> blank_insert_or_replace_t
{
return {blank_insert_or_replace_t<void>()};
return {blank_insert_or_replace_t()};
}
template <typename Table>
constexpr auto insert_or_replace_into(Table table) -> decltype(blank_insert_or_replace_t<void>().into(table))
constexpr auto insert_or_replace_into(Table table) -> decltype(blank_insert_or_replace_t().into(table))
{
return {blank_insert_or_replace_t<void>().into(table)};
return {blank_insert_or_replace_t().into(table)};
}
template <typename Database>
constexpr auto dynamic_insert_or_replace(const Database&) -> decltype(blank_insert_or_replace_t<Database>())
inline auto insert_or_ignore() -> blank_insert_or_ignore_t
{
return {blank_insert_or_replace_t<Database>()};
}
template <typename Database, typename Table>
constexpr auto dynamic_insert_or_replace_into(const Database&, Table table)
-> decltype(blank_insert_or_replace_t<Database>().into(table))
{
return {blank_insert_or_replace_t<Database>().into(table)};
}
inline auto insert_or_ignore() -> blank_insert_or_ignore_t<void>
{
return {blank_insert_or_ignore_t<void>()};
return {blank_insert_or_ignore_t()};
}
template <typename Table>
constexpr auto insert_or_ignore_into(Table table) -> decltype(blank_insert_or_ignore_t<void>().into(table))
constexpr auto insert_or_ignore_into(Table table) -> decltype(blank_insert_or_ignore_t().into(table))
{
return {blank_insert_or_ignore_t<void>().into(table)};
}
template <typename Database>
constexpr auto dynamic_insert_or_ignore(const Database&) -> decltype(blank_insert_or_ignore_t<Database>())
{
return {blank_insert_or_ignore_t<Database>()};
}
template <typename Database, typename Table>
constexpr auto dynamic_insert_or_ignore_into(const Database&, Table table)
-> decltype(blank_insert_or_ignore_t<Database>().into(table))
{
return {blank_insert_or_ignore_t<Database>().into(table)};
return {blank_insert_or_ignore_t().into(table)};
}
inline sqlite3::context_t& serialize(const sqlite3::insert_or_replace_name_t&, sqlite3::context_t& context)

View File

@ -57,8 +57,8 @@ namespace sqlpp
// disable some stuff that won't work with sqlite3
#if SQLITE_VERSION_NUMBER < 3008003
template <typename Database, typename... Expressions>
sqlite3::context_t& serialize(const with_data_t<Database, Expressions...>&, sqlite3::context_t& context)
template <typename... Expressions>
sqlite3::context_t& serialize(const with_data_t<Expressions...>&, sqlite3::context_t& context)
{
static_assert(wrong_t<Expressions...>::value, "Sqlite3: No support for with before version 3.8.3");
return context;

View File

@ -39,7 +39,7 @@
namespace sqlpp
{
template <typename Db, typename... Policies>
template <typename... Policies>
struct statement_t;
SQLPP_PORTABLE_STATIC_ASSERT(
@ -58,18 +58,17 @@ namespace sqlpp
return logic::any_t<is_missing_t<Policies>::value...>::value;
}
template <typename Db = void, typename... Policies>
template <typename... Policies>
struct statement_policies_t
{
using _database_t = Db;
using _statement_t = statement_t<Db, Policies...>;
using _statement_t = statement_t<Policies...>;
template <typename Needle, typename Replacement>
struct _policies_update_t
{
static_assert(make_type_set_t<Policies...>::template count<Needle>(),
"policies update for non-policy class detected");
using type = statement_t<Db, policy_update_t<Policies, Needle, Replacement>...>;
using type = statement_t<policy_update_t<Policies, Needle, Replacement>...>;
};
template <typename Needle, typename Replacement>
@ -154,13 +153,13 @@ namespace sqlpp
};
} // namespace detail
template <typename Db, typename... Policies>
struct statement_t : public Policies::template _base_t<detail::statement_policies_t<Db, Policies...>>...,
public expression_operators<statement_t<Db, Policies...>,
value_type_of<detail::statement_policies_t<Db, Policies...>>>,
public detail::statement_policies_t<Db, Policies...>::_result_methods_t
template <typename... Policies>
struct statement_t : public Policies::template _base_t<detail::statement_policies_t<Policies...>>...,
public expression_operators<statement_t<Policies...>,
value_type_of<detail::statement_policies_t<Policies...>>>,
public detail::statement_policies_t<Policies...>::_result_methods_t
{
using _policies_t = typename detail::statement_policies_t<Db, Policies...>;
using _policies_t = typename detail::statement_policies_t<Policies...>;
using _consistency_check =
detail::get_first_if<is_inconsistent_t,
@ -210,8 +209,8 @@ namespace sqlpp
// }
template <typename Statement, typename Term>
statement_t(Statement statement, Term term)
: Policies::template _base_t<_policies_t>(typename Policies::template _impl_t<_policies_t>(
detail::pick_arg<typename Policies::template _base_t<_policies_t>>(statement, term)))...
: Policies::template _base_t<_policies_t>(
detail::pick_arg<Policies>(statement, term))...
{
}
@ -251,13 +250,13 @@ namespace sqlpp
}
};
template <typename Context, typename Database, typename... Policies>
Context& serialize(const statement_t<Database, Policies...>& t, Context& context)
template <typename Context, typename... Policies>
Context& serialize(const statement_t<Policies...>& t, Context& context)
{
using P = detail::statement_policies_t<Database, Policies...>;
using P = detail::statement_policies_t<Policies...>;
using swallow = int[];
(void)swallow{0, (serialize(static_cast<const typename Policies::template _base_t<P>&>(t)()._data, context), 0)...};
(void)swallow{0, (serialize(static_cast<const typename Policies::template _base_t<P>&>(t)._data, context), 0)...};
return context;
}
@ -268,49 +267,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, Tag>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = NameData;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = NameData;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : statement_name{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};

View File

@ -28,6 +28,6 @@
namespace sqlpp
{
template <typename Db, typename... Policies>
template <typename... Policies>
struct statement_t;
} // namespace sqlpp

View File

@ -40,7 +40,7 @@ namespace sqlpp
{
struct no_union_t;
using blank_union_t = statement_t<void, no_union_t>;
using blank_union_t = statement_t<no_union_t>;
// There is no order by or limit or offset in union, use it as a pseudo table to do that.
template <typename Check, typename Union>
@ -52,14 +52,14 @@ namespace sqlpp
template <typename Union>
struct union_statement_impl<consistent_t, Union>
{
using type = statement_t<void, Union, no_union_t>;
using type = statement_t<Union, no_union_t>;
};
template <typename Check, typename Union>
using union_statement_t = typename union_statement_impl<Check, Union>::type;
// UNION(EXPR)
template <typename Database, typename Flag, typename Lhs, typename Rhs>
template <typename Flag, typename Lhs, typename Rhs>
struct union_t
{
using _traits = make_traits<no_value_t, tag::is_union, tag::is_return_value>;
@ -69,58 +69,26 @@ namespace sqlpp
{
};
// Data
using _data_t = union_data_t<Database, Flag, Lhs, Rhs>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
using _data_t = union_data_t<Flag, Lhs, Rhs>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = union_data_t<Database, Flag, Lhs, Rhs>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : union_{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> union_;
_impl_t<Policies>& operator()()
{
return union_;
}
const _impl_t<Policies>& operator()() const
{
return union_;
}
_data_t _data;
using _selected_columns_t = typename std::decay<decltype(union_._data._lhs.get_selected_columns())>::type;
using _selected_columns_t = typename std::decay<decltype(_data._lhs.get_selected_columns())>::type;
_selected_columns_t& get_selected_columns()
{
return union_._data._lhs.get_selected_columns();
return _data._lhs.get_selected_columns();
}
const _selected_columns_t& get_selected_columns() const
{
return union_._data._lhs.get_selected_columns();
}
template <typename T>
static auto _get_member(T t) -> decltype(t.union_)
{
return t.union_;
return _data._lhs.get_selected_columns();
}
using _consistency_check = detail::get_first_if<is_inconsistent_t,
@ -152,48 +120,15 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_union{std::forward<Args>(args)...}
{
}
_impl_t<Policies> no_union;
_impl_t<Policies>& operator()()
{
return no_union;
}
const _impl_t<Policies>& operator()() const
{
return no_union;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_union)
{
return t.no_union;
}
using _database_t = typename Policies::_database_t;
template <typename Check, typename T>
using _new_statement_t = union_statement_t<Check, T>;
@ -203,7 +138,7 @@ namespace sqlpp
template <typename Rhs>
auto union_distinct(Rhs rhs) const
-> _new_statement_t<check_union_t<derived_statement_t<Policies>, Rhs>,
union_t<void, union_distinct_t, derived_statement_t<Policies>, Rhs>>
union_t<union_distinct_t, derived_statement_t<Policies>, Rhs>>
{
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
@ -216,12 +151,12 @@ namespace sqlpp
static_assert(is_result_compatible<lhs_result_row_t, rhs_result_row_t>::value,
"both arguments in a union have to have the same result columns (type and name)");
return _union_impl<void, union_distinct_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
return _union_impl<union_distinct_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
}
template <typename Rhs>
auto union_all(Rhs rhs) const -> _new_statement_t<check_union_t<derived_statement_t<Policies>, Rhs>,
union_t<void, union_all_t, derived_statement_t<Policies>, Rhs>>
union_t<union_all_t, derived_statement_t<Policies>, Rhs>>
{
static_assert(is_statement_t<Rhs>::value, "argument of union call has to be a statement");
static_assert(has_policy_t<Rhs, is_select_t>::value, "argument of union call has to be a select");
@ -234,18 +169,18 @@ namespace sqlpp
static_assert(is_result_compatible<lhs_result_row_t, rhs_result_row_t>::value,
"both arguments in a union have to have the same result columns (type and name)");
return _union_impl<void, union_all_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
return _union_impl<union_all_t>(check_union_t<derived_statement_t<Policies>, Rhs>{}, rhs);
}
private:
template <typename Database, typename Flag, typename Check, typename Rhs>
template <typename Flag, typename Check, typename Rhs>
auto _union_impl(Check, Rhs rhs) const -> inconsistent<Check>;
template <typename Database, typename Flag, typename Rhs>
template <typename Flag, typename Rhs>
auto _union_impl(consistent_t /*unused*/, Rhs rhs) const
-> _new_statement_t<consistent_t, union_t<Database, Flag, derived_statement_t<Policies>, Rhs>>
-> _new_statement_t<consistent_t, union_t<Flag, derived_statement_t<Policies>, Rhs>>
{
return {blank_union_t{}, union_data_t<Database, Flag, derived_statement_t<Policies>, Rhs>{
return {blank_union_t{}, union_data_t<Flag, derived_statement_t<Policies>, Rhs>{
static_cast<const derived_statement_t<Policies>&>(*this), rhs}};
}
};
@ -253,15 +188,15 @@ namespace sqlpp
/*
template <typename T>
auto union_all(T&& t) -> decltype(statement_t<void, no_union_t>().union_all(std::forward<T>(t)))
auto union_all(T&& t) -> decltype(statement_t<no_union_t>().union_all(std::forward<T>(t)))
{
return statement_t<void, no_union_t>().union_all(std::forward<T>(t));
return statement_t<no_union_t>().union_all(std::forward<T>(t));
}
template <typename T>
auto union_distinct(T&& t) -> decltype(statement_t<void, no_union_t>().union_distinct(std::forward<T>(t)))
auto union_distinct(T&& t) -> decltype(statement_t<no_union_t>().union_distinct(std::forward<T>(t)))
{
return statement_t<void, no_union_t>().union_distinct(std::forward<T>(t));
return statement_t<no_union_t>().union_distinct(std::forward<T>(t));
}
*/
} // namespace sqlpp

View File

@ -28,7 +28,7 @@
namespace sqlpp
{
template <typename Database, typename Flag, typename Lhs, typename Rhs>
template <typename Flag, typename Lhs, typename Rhs>
struct union_data_t
{
union_data_t(Lhs lhs, Rhs rhs) : _lhs(lhs), _rhs(rhs)
@ -46,8 +46,8 @@ namespace sqlpp
};
// Interpreters
template <typename Context, typename Database, typename Flag, typename Lhs, typename Rhs>
Context& serialize(const union_data_t<Database, Flag, Lhs, Rhs>& t, Context& context)
template <typename Context, typename Flag, typename Lhs, typename Rhs>
Context& serialize(const union_data_t<Flag, Lhs, Rhs>& t, Context& context)
{
serialize(t._lhs, context);
context << " UNION ";

View File

@ -94,13 +94,12 @@ namespace sqlpp
return context;
}
template <typename Database>
using blank_update_t = statement_t<Database, update_t, no_single_table_t, no_update_list_t, no_where_t<true>>;
using blank_update_t = statement_t<update_t, no_single_table_t, no_update_list_t, no_where_t<true>>;
template <typename Table>
constexpr auto update(Table table) -> decltype(blank_update_t<void>().single_table(table))
constexpr auto update(Table table) -> decltype(blank_update_t().single_table(table))
{
return {blank_update_t<void>().single_table(table)};
return {blank_update_t().single_table(table)};
}
} // namespace sqlpp

View File

@ -33,7 +33,7 @@
namespace sqlpp
{
// UPDATE ASSIGNMENTS DATA
template <typename Database, typename... Assignments>
template <typename... Assignments>
struct update_list_data_t
{
update_list_data_t(std::tuple<Assignments...> assignments) : _assignments(assignments)
@ -54,56 +54,24 @@ namespace sqlpp
"at least one update assignment requires a table which is otherwise not known in the statement");
// UPDATE ASSIGNMENTS
template <typename Database, typename... Assignments>
template <typename... Assignments>
struct update_list_t
{
using _traits = make_traits<no_value_t, tag::is_update_list>;
using _nodes = detail::type_vector<Assignments...>;
// Data
using _data_t = update_list_data_t<Database, Assignments...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = update_list_data_t<Assignments...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = update_list_data_t<Database, Assignments...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : assignments{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<update_list_t>::value,
consistent_t,
@ -160,48 +128,16 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_assignments{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_update_list_t, T>;
@ -210,37 +146,37 @@ namespace sqlpp
template <typename... Assignments>
auto set(Assignments... assignments) const
-> _new_statement_t<check_update_static_set_t<Assignments...>, update_list_t<void, Assignments...>>
-> _new_statement_t<check_update_static_set_t<Assignments...>, update_list_t<Assignments...>>
{
using Check = check_update_static_set_t<Assignments...>;
return _set_impl<void>(Check{}, std::make_tuple(assignments...));
return _set_impl(Check{}, std::make_tuple(assignments...));
}
template <typename... Assignments>
auto set(std::tuple<Assignments...> assignments) const
-> _new_statement_t<check_update_static_set_t<Assignments...>, update_list_t<void, Assignments...>>
-> _new_statement_t<check_update_static_set_t<Assignments...>, update_list_t<Assignments...>>
{
using Check = check_update_static_set_t<Assignments...>;
return _set_impl<void>(Check{}, assignments);
return _set_impl(Check{}, assignments);
}
private:
template <typename Database, typename Check, typename... Assignments>
template <typename Check, typename... Assignments>
auto _set_impl(Check, Assignments... assignments) const -> inconsistent<Check>;
template <typename Database, typename... Assignments>
template <typename... Assignments>
auto _set_impl(consistent_t /*unused*/, std::tuple<Assignments...> assignments) const
-> _new_statement_t<consistent_t, update_list_t<Database, Assignments...>>
-> _new_statement_t<consistent_t, update_list_t<Assignments...>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
update_list_data_t<Database, Assignments...>{assignments}};
update_list_data_t<Assignments...>{assignments}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename... Assignments>
Context& serialize(const update_list_data_t<Database, Assignments...>& t, Context& context)
template <typename Context, typename... Assignments>
Context& serialize(const update_list_data_t<Assignments...>& t, Context& context)
{
context << " SET ";
interpret_tuple(t._assignments, ",", context);

View File

@ -34,7 +34,7 @@
namespace sqlpp
{
// USING DATA
template <typename Database, typename... Tables>
template <typename... Tables>
struct using_data_t
{
using_data_t(Tables... tables) : _tables(tables...)
@ -51,56 +51,23 @@ namespace sqlpp
};
// USING
template <typename Database, typename... Tables>
template <typename... Tables>
struct using_t
{
using _traits = make_traits<no_value_t, tag::is_using_>;
using _nodes = detail::type_vector<Tables...>;
// Data
using _data_t = using_data_t<Database, Tables...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = using_data_t<Tables...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = using_data_t<Database, Tables...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : using_{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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_;
}
_data_t _data;
// FIXME: Maybe check for unused tables, similar to from
using _consistency_check = consistent_t;
@ -123,51 +90,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_using{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_using_t, T>;
@ -175,34 +109,34 @@ namespace sqlpp
using _consistency_check = consistent_t;
template <typename... Tables>
auto using_(Tables... tables) const -> _new_statement_t<check_using_t<Tables...>, using_t<void, Tables...>>
auto using_(Tables... tables) const -> _new_statement_t<check_using_t<Tables...>, using_t<Tables...>>
{
static_assert(not detail::has_duplicates<Tables...>::value,
"at least one duplicate argument detected in using()");
static_assert(sizeof...(Tables), "at least one table required in using()");
return {_using_impl<void>(check_using_t<Tables...>{}, tables...)};
return {_using_impl(check_using_t<Tables...>{}, tables...)};
}
private:
template <typename Database, typename Check, typename... Tables>
template <typename Check, typename... Tables>
auto _using_impl(Check, Tables... tables) const -> inconsistent<Check>;
template <typename Database, typename... Tables>
template <typename... Tables>
auto _using_impl(consistent_t /*unused*/, Tables... tables) const
-> _new_statement_t<consistent_t, using_t<_database_t, Tables...>>
-> _new_statement_t<consistent_t, using_t<Tables...>>
{
static_assert(not detail::has_duplicates<Tables...>::value,
"at least one duplicate argument detected in using()");
return {static_cast<const derived_statement_t<Policies>&>(*this), using_data_t<Database, Tables...>{tables...}};
return {static_cast<const derived_statement_t<Policies>&>(*this), using_data_t<Tables...>{tables...}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename... Tables>
Context& serialize(const using_data_t<Database, Tables...>& t, Context& context)
template <typename Context, typename... Tables>
Context& serialize(const using_data_t<Tables...>& t, Context& context)
{
context << " USING ";
interpret_tuple(t._tables, ',', context);

View File

@ -38,19 +38,9 @@
namespace sqlpp
{
// WHERE DATA
template <typename Database, typename Expression>
template <typename Expression>
struct where_data_t
{
where_data_t(Expression expression) : _expression(expression)
{
}
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;
Expression _expression;
};
@ -59,56 +49,24 @@ namespace sqlpp
"at least one expression in where() requires a table which is otherwise not known in the statement");
// WHERE(EXPR)
template <typename Database, typename Expression>
template <typename Expression>
struct where_t
{
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<Expression>;
// Data
using _data_t = where_data_t<Database, Expression>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
public:
_data_t _data;
};
using _data_t = where_data_t<Expression>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = where_data_t<Database, Expression>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : where{std::forward<Args>(args)...}
_base_t(const _base_t&) = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<where_t>::value,
consistent_t,
@ -117,60 +75,29 @@ namespace sqlpp
};
template <>
struct where_data_t<void, unconditional_t>
struct where_data_t<unconditional_t>
{
};
// WHERE() UNCONDITIONALLY
template <>
struct where_t<void, unconditional_t>
struct where_t<unconditional_t>
{
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = where_data_t<void, unconditional_t>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
using _data_t = where_data_t<unconditional_t>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = where_data_t<void, unconditional_t>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : where{std::forward<Args>(args)...}
_base_t(const _base_t&) = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
_data_t _data;
using _consistency_check = consistent_t;
};
@ -223,51 +150,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_where{std::forward<Args>(args)...}
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_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;
}
using _database_t = typename Policies::_database_t;
_data_t _data;
template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_where_t, T>;
@ -277,62 +171,56 @@ namespace sqlpp
assert_where_or_unconditionally_called_t,
consistent_t>::type;
auto unconditionally() const -> _new_statement_t<consistent_t, where_t<void, unconditional_t>>
auto unconditionally() const -> _new_statement_t<consistent_t, where_t<unconditional_t>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<void, unconditional_t>{}};
return {static_cast<const derived_statement_t<Policies>&>(*this), where_data_t<unconditional_t>{}};
}
template <typename Expression>
auto where(Expression expression) const
-> _new_statement_t<check_where_static_t<Expression>, where_t<void, Expression>>
-> _new_statement_t<check_where_static_t<Expression>, where_t<Expression>>
{
using Check = check_where_static_t<Expression>;
return _where_impl<void>(Check{}, expression);
return _where_impl(Check{}, expression);
}
private:
template <typename Database, typename Check, typename Expression>
template <typename Check, typename Expression>
auto _where_impl(Check, Expression expression) const -> inconsistent<Check>;
template <typename Database, typename Expression>
template <typename Expression>
auto _where_impl(consistent_t /*unused*/, Expression expression) const
-> _new_statement_t<consistent_t, where_t<Database, Expression>>
-> _new_statement_t<consistent_t, where_t<Expression>>
{
return {static_cast<const derived_statement_t<Policies>&>(*this),
where_data_t<Database, Expression>{expression}};
where_data_t<Expression>{expression}};
}
};
};
// Interpreters
template <typename Context, typename Database, typename Expression>
Context& serialize(const where_data_t<Database, Expression>& t, Context& context)
template <typename Context, typename Expression>
Context& serialize(const where_data_t<Expression>& t, Context& context)
{
context << " WHERE ";
serialize(t._expression, context);
return context;
}
template <typename Context, typename Database>
Context& serialize(const where_data_t<Database, unconditional_t>& t, Context& context)
{
return context;
}
template <typename Context>
Context& serialize(const where_data_t<void, unconditional_t>&, Context& context)
Context& serialize(const where_data_t<unconditional_t>&, Context& context)
{
return context;
}
template <typename T>
auto where(T&& t) -> decltype(statement_t<void, no_where_t<false>>().where(std::forward<T>(t)))
auto where(T&& t) -> decltype(statement_t<no_where_t<false>>().where(std::forward<T>(t)))
{
return statement_t<void, no_where_t<false>>().where(std::forward<T>(t));
return statement_t<no_where_t<false>>().where(std::forward<T>(t));
}
inline auto unconditionally() -> decltype(statement_t<void, no_where_t<false>>().unconditionally())
inline auto unconditionally() -> decltype(statement_t<no_where_t<false>>().unconditionally())
{
return statement_t<void, no_where_t<false>>().unconditionally();
return statement_t<no_where_t<false>>().unconditionally();
}
} // namespace sqlpp

View File

@ -41,7 +41,7 @@
namespace sqlpp
{
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct with_data_t
{
using _is_recursive = logic::any_t<Expressions::_is_recursive...>;
@ -59,7 +59,7 @@ namespace sqlpp
std::tuple<Expressions...> _expressions;
};
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct with_t
{
using _traits = make_traits<no_value_t, tag::is_with>;
@ -68,49 +68,17 @@ namespace sqlpp
detail::make_joined_set_t<required_ctes_of<Expressions>...>; // WITH provides common table expressions
using _parameters = detail::type_vector_cat_t<parameters_of<Expressions>...>;
// Data
using _data_t = with_data_t<Database, Expressions...>;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{
}
_data_t _data;
};
using _data_t = with_data_t<Expressions...>;
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = with_data_t<Database, Expressions...>;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : with{std::forward<Args>(args)...}
_base_t(_data_t data) : _data{std::move(data)}
{
}
_impl_t<Policies> with;
_impl_t<Policies>& operator()()
{
return with;
}
const _impl_t<Policies>& operator()() const
{
return with;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.with)
{
return t.with;
}
_data_t _data;
// FIXME: Need real checks here
using _consistency_check = consistent_t;
@ -125,59 +93,29 @@ namespace sqlpp
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies>
struct _impl_t
struct _base_t
{
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
_base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
{
}
_data_t _data;
};
// Base template to be inherited by the statement
template <typename Policies>
struct _base_t
{
using _data_t = no_data_t;
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : no_with{std::forward<Args>(args)...}
{
}
_impl_t<Policies> no_with;
_impl_t<Policies>& operator()()
{
return no_with;
}
const _impl_t<Policies>& operator()() const
{
return no_with;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_with)
{
return t.no_with;
}
using _consistency_check = consistent_t;
};
};
template <typename Database, typename... Expressions>
template <typename... Expressions>
struct blank_with_t
{
with_data_t<Database, Expressions...> _data;
with_data_t<Expressions...> _data;
template <typename Statement>
auto operator()(Statement statement)
-> new_statement_t<consistent_t, typename Statement::_policies_t, no_with_t, with_t<Database, Expressions...>>
-> new_statement_t<consistent_t, typename Statement::_policies_t, no_with_t, with_t<Expressions...>>
{
// FIXME need checks here
// check that no cte refers to any of the ctes to the right
@ -186,10 +124,10 @@ namespace sqlpp
};
// Interpreters
template <typename Context, typename Database, typename... Expressions>
Context& serialize(const with_data_t<Database, Expressions...>& t, Context& context)
template <typename Context, typename... Expressions>
Context& serialize(const with_data_t<Expressions...>& t, Context& context)
{
using T = with_data_t<Database, Expressions...>;
using T = with_data_t<Expressions...>;
// FIXME: If there is a recursive CTE, add a "RECURSIVE" here
context << " WITH ";
if (T::_is_recursive::value)
@ -202,7 +140,7 @@ namespace sqlpp
}
template <typename... Expressions>
auto with(Expressions... cte) -> blank_with_t<void, Expressions...>
auto with(Expressions... cte) -> blank_with_t<Expressions...>
{
static_assert(logic::all_t<is_cte_t<Expressions>::value...>::value,
"at least one expression in with is not a common table expression");

View File

@ -61,7 +61,7 @@ int CustomQuery(int, char*[])
sqlpp::limit(7u), sqlpp::offset(3u)),
"SELECT DISTINCT tab_foo.omega FROM tab_foo INNER JOIN tab_bar ON (tab_foo.omega=tab_bar.alpha) WHERE "
"(tab_bar.alpha>17) GROUP BY tab_foo.omega HAVING (AVG(tab_bar.alpha)>19) ORDER BY tab_foo.omega "
"ASC,tab_foo.psi DESC ");
"ASC,tab_foo.psi DESC LIMIT 7 OFFSET 3");
// A pragma query for sqlite
compare(__LINE__,
@ -81,8 +81,8 @@ int CustomQuery(int, char*[])
// A multi-row "insert or ignore"
auto batch = insert_columns(bar.beta, bar.gamma);
batch.values.add(bar.beta = "sample", bar.gamma = true);
batch.values.add(bar.beta = "ample", bar.gamma = false);
batch.add_values(bar.beta = "sample", bar.gamma = true);
batch.add_values(bar.beta = "ample", bar.gamma = false);
compare(__LINE__, custom_query(sqlpp::insert(), sqlpp::verbatim(" OR IGNORE"), into(bar), batch),
"INSERT OR IGNORE INTO tab_bar (beta,gamma) VALUES ('sample',1),('ample',0)");

View File

@ -32,6 +32,8 @@
namespace
{
#warning restore this file!
#if 0
struct on_duplicate_key_update
{
std::string _serialized;
@ -56,6 +58,7 @@ namespace
return ::sqlpp::verbatim(_serialized);
}
};
#endif
} // namespace
int CustomQuery(int, char*[])
@ -68,8 +71,11 @@ int CustomQuery(int, char*[])
// A void custom query
printer.reset();
auto x = custom_query(sqlpp::verbatim("PRAGMA writeable_schema = "), true);
auto x =
//select(t.alpha).from(t).where(t.alpha > 7).group_by(t.alpha).having(max(t.alpha) > 13).order_by(t.beta.desc());
update(t).set(t.beta = "eight", t.gamma = true);
std::cerr << serialize(x, printer).str() << std::endl;
#if 0
db(x);
// Syntactically, it is possible to use this void query as a prepared statement, too, not sure, whether this makes
@ -92,8 +98,8 @@ int CustomQuery(int, char*[])
// Create a custom mulit-row "insert or ignore"
auto batch = insert_columns(t.beta, t.gamma);
batch.values.add(t.beta = "sample", t.gamma = true);
batch.values.add(t.beta = "ample", t.gamma = false);
batch.add_values(t.beta = "sample", t.gamma = true);
batch.add_values(t.beta = "ample", t.gamma = false);
db(custom_query(sqlpp::insert(), sqlpp::verbatim(" OR IGNORE"), into(t), batch));
// Create a MYSQL style custom "insert on duplicate update"
@ -117,6 +123,7 @@ int CustomQuery(int, char*[])
{
(void)row.alpha;
}
#endif
return 0;
}

View File

@ -61,10 +61,10 @@ int Insert(int, char*[])
serialize(insert_into(t).set(t.gamma = true, t.beta = "kirschauflauf"), printer).str();
serialize(insert_into(t).columns(t.gamma, t.beta), printer).str();
auto multi_insert = insert_into(t).columns(t.gamma, t.beta, t.delta);
multi_insert.values.add(t.gamma = true, t.beta = "cheesecake", t.delta = 1);
multi_insert.values.add(t.gamma = sqlpp::default_value, t.beta = sqlpp::default_value,
multi_insert.add_values(t.gamma = true, t.beta = "cheesecake", t.delta = 1);
multi_insert.add_values(t.gamma = sqlpp::default_value, t.beta = sqlpp::default_value,
t.delta = sqlpp::default_value);
multi_insert.values.add(t.gamma = sqlpp::value_or_null(true), t.beta = sqlpp::value_or_null("pie"),
multi_insert.add_values(t.gamma = sqlpp::value_or_null(true), t.beta = sqlpp::value_or_null("pie"),
t.delta = sqlpp::value_or_null<sqlpp::integer>(sqlpp::null));
printer.reset();
std::cerr << serialize(multi_insert, printer).str() << std::endl;
@ -74,7 +74,7 @@ int Insert(int, char*[])
.set(tabDateTime.colTimePoint = std::chrono::system_clock::now());
auto multi_time_insert = insert_into(tabDateTime).columns(tabDateTime.colTimePoint);
multi_time_insert.values.add(tabDateTime.colTimePoint = std::chrono::time_point_cast<std::chrono::microseconds>(
multi_time_insert.add_values(tabDateTime.colTimePoint = std::chrono::time_point_cast<std::chrono::microseconds>(
std::chrono::system_clock::now()));
#warning add tests with optional

View File

@ -41,9 +41,9 @@ int Interpret(int, char* [])
serialize(insert_into(t).columns(t.beta, t.gamma), printer).str();
{
auto i = insert_into(t).columns(t.gamma, t.beta);
i.values.add(t.gamma = true, t.beta = "cheesecake");
i.add_values(t.gamma = true, t.beta = "cheesecake");
serialize(i, printer).str();
i.values.add(t.gamma = sqlpp::default_value, t.beta = sqlpp::null);
i.add_values(t.gamma = sqlpp::default_value, t.beta = sqlpp::null);
serialize(i, printer).str();
}

View File

@ -79,8 +79,8 @@ int Ppgen(int, char*[])
db(insert_into(f).default_values());
auto i = insert_into(p).columns(p.name, p.feature, p.age, p.level);
i.values.add(p.name = "Roland", p.feature = 1, p.age = static_cast<unsigned int>(32), p.level = 3.14);
i.values.add(p.name = "Zaphod", p.feature = sqlpp::default_value, p.age = static_cast<unsigned int>(16),
i.add_values(p.name = "Roland", p.feature = 1, p.age = static_cast<unsigned int>(32), p.level = 3.14);
i.add_values(p.name = "Zaphod", p.feature = sqlpp::default_value, p.age = static_cast<unsigned int>(16),
p.level = 3.14 * 2);
db(i);

View File

@ -44,6 +44,9 @@ int Remove(int, char* [])
{
using T = decltype(remove_from(t).where(t.beta != "transparent"));
auto x = remove_from(t).where(t.beta != "transparent");
T y(x);
T z(std::move(x));
static_assert(sqlpp::is_regular<T>::value, "type requirement");
}

View File

@ -33,27 +33,8 @@ namespace sqlpp
template <typename T>
struct is_regular
{
#if defined __clang__
#if __has_feature(cxx_thread_local)
#define SQLPP_TEST_NO_THROW_MOVE_CONSTRUCTIBLE // clang 3.2 has a problem with nothrow_constructibility (it also does
// not have thread_local support)
#endif
#else
#define SQLPP_TEST_NO_THROW_MOVE_CONSTRUCTIBLE
#endif
static constexpr bool value =
true
#if !defined _MSC_VER
#if defined SQLPP_TEST_NO_THROW_MOVE_CONSTRUCTIBLE
and std::is_nothrow_move_constructible<T>::value
#endif
and std::is_move_assignable<T>::value // containers and strings are not noexcept_assignable
and std::is_copy_constructible<T>::value and std::is_copy_assignable<T>::value
// default constructor makes no sense
// (not) equals would be possible
// not sure about less
#endif
;
std::is_move_assignable<T>::value // containers and strings are not noexcept_assignable
and std::is_copy_constructible<T>::value and std::is_copy_assignable<T>::value;
};
}

View File

@ -56,11 +56,13 @@ int DynamicSelect(int, char*[])
const auto tab = TabSample{};
db(insert_into(tab).set(tab.gamma = true));
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
i.values.add(tab.beta = "cheesecake", tab.gamma = false);
i.values.add(tab.beta = "kaesekuchen", tab.gamma = true);
i.add_values(tab.beta = "rhabarbertorte", tab.gamma = false);
i.add_values(tab.beta = "cheesecake", tab.gamma = false);
i.add_values(tab.beta = "kaesekuchen", tab.gamma = true);
db(i);
#warning add tests with optional columns
/*
auto s = dynamic_select(db).dynamic_columns(tab.alpha).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
@ -68,6 +70,7 @@ int DynamicSelect(int, char*[])
{
std::cerr << "row.alpha: " << row.alpha << ", row.beta: " << row.at("beta") << std::endl;
};
*/
}
catch (const std::exception& e)
{

View File

@ -62,18 +62,11 @@ int MoveConstructor(int, char*[])
const auto tab = TabSample{};
db(insert_into(tab).set(tab.gamma = true));
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
i.values.add(tab.beta = "cheesecake", tab.gamma = false);
i.values.add(tab.beta = "kaesekuchen", tab.gamma = true);
i.add_values(tab.beta = "rhabarbertorte", tab.gamma = false);
i.add_values(tab.beta = "cheesecake", tab.gamma = false);
i.add_values(tab.beta = "kaesekuchen", tab.gamma = true);
db(i);
auto s = dynamic_select(db).dynamic_columns(tab.alpha).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
for (const auto& row : db(s))
{
std::cerr << "row.alpha: " << row.alpha << ", row.beta: " << row.at("beta") << std::endl;
};
db.commit_transaction();
assert(db.is_transaction_active() == false);
}

View File

@ -95,10 +95,7 @@ int Sample(int, char*[])
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(sqlpp::value_list(std::vector<int>{1, 2, 3, 4}))));
db(update(tab).set(tab.gamma = true).where(tab.alpha.in(1)));
// dynamic insert
auto dynin = dynamic_insert_into(db, tab).dynamic_set(tab.gamma = true);
dynin.insert_list.add(tab.beta = "cheesecake");
db(dynin);
#warning: Add test with optional insert
// remove
{

View File

@ -36,10 +36,7 @@ int Returning(int, char*[])
<< db(sqlpp::postgresql::insert_into(foo).set(foo.gamma = "asd").returning(std::make_tuple(foo.c_timepoint))).front().c_timepoint
<< std::endl;
auto i = sqlpp::postgresql::dynamic_insert_into(db, foo).dynamic_set().returning(foo.c_timepoint);
i.insert_list.add(foo.gamma = "blah");
std::cout << db(i).front().c_timepoint << std::endl;
#warning need to add optinal insert tests
auto updated =
db(sqlpp::postgresql::update(foo).set(foo.beta = 0).unconditionally().returning(foo.gamma, foo.beta));
@ -52,8 +49,8 @@ int Returning(int, char*[])
std::cout << "Gamma: " << row.gamma << " Beta: " << row.beta << std::endl;
auto multi_insert = sqlpp::postgresql::insert_into(foo).columns(foo.beta).returning(foo.alpha, foo.beta);
multi_insert.values.add(foo.beta = 1);
multi_insert.values.add(foo.beta = 2);
multi_insert.add_values(foo.beta = 1);
multi_insert.add_values(foo.beta = 2);
auto inserted = db(multi_insert);
for (const auto& row : inserted)

View File

@ -63,9 +63,9 @@ int main()
const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true)
i.add_values(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.add_values(tab.beta = "cheesecake", tab.gamma = false)
// i.add_values(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl;

View File

@ -68,9 +68,9 @@ int DynamicSelect(int, char*[])
const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true)
i.add_values(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.add_values(tab.beta = "cheesecake", tab.gamma = false)
// i.add_values(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl;
@ -80,14 +80,6 @@ int DynamicSelect(int, char*[])
<< db(select(sqlpp::verbatim<sqlpp::integer>("last_insert_rowid()").as(tab.alpha))).front().alpha
<< std::endl;
// select a static (alpha) and a dynamic column (beta)
auto s = dynamic_select(db).dynamic_columns(tab.alpha.as(left)).from(tab).unconditionally();
s.selected_columns.add(tab.beta);
s.selected_columns.add(tab.gamma);
for (const auto& row : db(s))
{
std::cerr << "row.alpha: " << row.left << ", row.beta: " << row.at("beta") << ", row.gamma: " << row.at("gamma")
<< std::endl;
};
#warning: add tests with optional columns
return 0;
}

View File

@ -87,9 +87,7 @@ int Sample(int, char*[])
std::cout << "Last Insert ID: " << db.last_insert_id() << "\n";
db(insert_into(tab).set(tab.gamma = true));
std::cout << "Last Insert ID: " << db.last_insert_id() << "\n";
auto di = dynamic_insert_into(db, tab).dynamic_set(tab.gamma = true);
di.insert_list.add(tab.beta = "");
db(di);
#warning: add tests for optional insert and insert_or
// update
db(update(tab).set(tab.gamma = false).where(tab.alpha.in(1)));