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> #include <optional>
namespace sqlpp namespace sqlpp
{ {
#warning move into compat?
template <class T> template <class T>
using optional = std::optional<T>; using optional = std::optional<T>;

View File

@ -34,7 +34,7 @@
namespace sqlpp namespace sqlpp
{ {
template <typename Database, typename... Parts> template <typename... Parts>
struct custom_query_t; struct custom_query_t;
namespace detail namespace detail
@ -50,20 +50,20 @@ namespace sqlpp
using type = Clause; using type = Clause;
}; };
template <typename Db, typename... Parts> template <typename... Parts>
struct custom_parts_t 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 _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_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>; using _result_methods_t = typename _result_type_provider::template _result_methods_t<_result_type_provider>;
}; };
} // namespace detail } // namespace detail
template <typename Database, typename... Parts> template <typename... Parts>
struct custom_query_t : private detail::custom_parts_t<Database, Parts...>::_result_methods_t 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 _traits = make_traits<no_value_t, tag::is_statement>;
using _nodes = detail::type_vector<Parts...>; using _nodes = detail::type_vector<Parts...>;
@ -113,7 +113,7 @@ namespace sqlpp
} }
template <typename Part> 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)}; return {tuple_cat(std::make_tuple(hidden(part)), _parts)};
} }
@ -121,18 +121,18 @@ namespace sqlpp
std::tuple<Parts...> _parts; std::tuple<Parts...> _parts;
}; };
template <typename Context, typename Database, typename... Parts> template <typename Context, typename... Parts>
Context& serialize(const custom_query_t<Database, Parts...>& t, Context& context) Context& serialize(const custom_query_t<Parts...>& t, Context& context)
{ {
interpret_tuple_without_braces(t._parts, " ", context); interpret_tuple_without_braces(t._parts, " ", context);
return context; return context;
} }
template <typename... Parts> 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"); 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 } // namespace sqlpp

View File

@ -32,23 +32,25 @@ namespace sqlpp
{ {
namespace detail namespace detail
{ {
template <typename Target, typename Statement, typename Term> template <typename Clause, typename OldStatement, typename NewClauseData>
typename Target::_data_t pick_arg_impl(Statement /* statement */, Term term, const std::true_type& /*unused*/) 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> template <typename Clause, typename OldStatement, typename NewClauseData>
typename Target::_data_t pick_arg_impl(Statement statement, Term /* term */, const std::false_type& /*unused*/) 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 // 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 Target, typename Statement, typename Term> template <typename Clause, typename OldStatement, typename NewClauseData>
typename Target::_data_t pick_arg(Statement statement, Term term) 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 detail
} // namespace sqlpp } // namespace sqlpp

View File

@ -43,49 +43,17 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_for_update>; using _traits = make_traits<no_value_t, tag::is_for_update>;
using _nodes = detail::type_vector<>; using _nodes = detail::type_vector<>;
// Data
using _data_t = for_update_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = for_update_data_t; _base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> for_update; _data_t _data;
_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;
}
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
}; };
@ -99,48 +67,16 @@ namespace sqlpp
// Data // Data
using _data_t = no_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> no_for_update; _data_t _data;
_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;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_for_update_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_for_update_t, T>;
@ -163,8 +99,8 @@ namespace sqlpp
} }
template <typename T> 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 } // namespace sqlpp

View File

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

View File

@ -36,7 +36,7 @@
namespace sqlpp namespace sqlpp
{ {
// GROUP BY DATA // GROUP BY DATA
template <typename Database, typename... Expressions> template <typename... Expressions>
struct group_by_data_t struct group_by_data_t
{ {
group_by_data_t(Expressions... expressions) : _expressions(expressions...) 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"); "at least one group-by expression requires a table which is otherwise not known in the statement");
// GROUP BY // GROUP BY
template <typename Database, typename... Expressions> template <typename... Expressions>
struct group_by_t struct group_by_t
{ {
using _traits = make_traits<no_value_t, tag::is_group_by>; 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...>; using _provided_aggregates = detail::make_type_set_t<Expressions...>;
// Data using _data_t = group_by_data_t<Expressions...>;
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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = group_by_data_t<Database, Expressions...>; _base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> group_by; _data_t _data;
_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;
}
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<group_by_t>::value, using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<group_by_t>::value,
consistent_t, consistent_t,
@ -136,48 +103,16 @@ namespace sqlpp
// Data // Data
using _data_t = no_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> no_group_by; _data_t _data;
_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;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_group_by_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_group_by_t, T>;
@ -186,33 +121,33 @@ namespace sqlpp
template <typename... Expressions> template <typename... Expressions>
auto group_by(Expressions... expressions) const 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()"); 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: private:
template <typename Database, typename Check, typename... Expressions> template <typename Check, typename... Expressions>
auto _group_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>; 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 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, static_assert(not detail::has_duplicates<Expressions...>::value,
"at least one duplicate argument detected in group_by()"); "at least one duplicate argument detected in group_by()");
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
group_by_data_t<Database, Expressions...>{expressions...}}; group_by_data_t<Expressions...>{expressions...}};
} }
}; };
}; };
// Interpreters // Interpreters
template <typename Context, typename Database, typename... Expressions> template <typename Context, typename... Expressions>
Context& serialize(const group_by_data_t<Database, Expressions...>& t, Context& context) Context& serialize(const group_by_data_t<Expressions...>& t, Context& context)
{ {
context << " GROUP BY "; context << " GROUP BY ";
interpret_tuple(t._expressions, ',', context); interpret_tuple(t._expressions, ',', context);
@ -220,9 +155,9 @@ namespace sqlpp
} }
template <typename... T> 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 } // namespace sqlpp

View File

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

View File

@ -95,18 +95,17 @@ namespace sqlpp
return context; return context;
} }
template <typename Database> using blank_insert_t = statement_t<insert_t, no_into_t, no_insert_value_list_t>;
using blank_insert_t = statement_t<Database, insert_t, no_into_t, no_insert_value_list_t>;
inline auto insert() -> blank_insert_t<void> inline auto insert() -> blank_insert_t
{ {
return {}; return {};
} }
template <typename Table> 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 } // namespace sqlpp

View File

@ -73,52 +73,21 @@ namespace sqlpp
// Data // Data
using _data_t = insert_default_values_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = insert_default_values_data_t; _base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> default_values; _data_t _data;
_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;
}
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
}; };
}; };
template <typename Database, typename... Assignments> template <typename... Assignments>
struct insert_list_data_t struct insert_list_data_t
{ {
insert_list_data_t(std::tuple<Assignments...> assignments) insert_list_data_t(std::tuple<Assignments...> assignments)
@ -229,110 +198,33 @@ namespace sqlpp
template <typename... Assignments> template <typename... Assignments>
using check_insert_static_set_t = typename check_insert_static_set<Assignments...>::type; 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( SQLPP_PORTABLE_STATIC_ASSERT(
assert_no_unknown_tables_in_insert_assignments_t, assert_no_unknown_tables_in_insert_assignments_t,
"at least one insert assignment requires a table which is otherwise not known in the statement"); "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 struct insert_list_t
{ {
using _traits = make_traits<no_value_t, tag::is_insert_list>; using _traits = make_traits<no_value_t, tag::is_insert_list>;
using _nodes = detail::type_vector<lhs_t<Assignments>..., rhs_t<Assignments>...>; using _nodes = detail::type_vector<lhs_t<Assignments>..., rhs_t<Assignments>...>;
using _is_dynamic = is_database<Database>;
template <template <typename...> class Target> template <template <typename...> class Target>
using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments? using copy_assignments_t = Target<Assignments...>; // FIXME: Nice idea to copy variadic template arguments?
template <template <typename...> class Target, template <typename> class Wrap> template <template <typename...> class Target, template <typename> class Wrap>
using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>; using copy_wrapped_assignments_t = Target<Wrap<Assignments>...>;
// Data // Data
using _data_t = insert_list_data_t<Database, Assignments...>; using _data_t = insert_list_data_t<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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = insert_list_data_t<Database, Assignments...>; _base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> insert_list; _data_t _data;
_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;
}
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<insert_list_t>::value, using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<insert_list_t>::value,
consistent_t, consistent_t,
@ -373,18 +265,18 @@ namespace sqlpp
// Data // Data
using _data_t = column_list_data_t<Columns...>; 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> template <typename Policies>
struct _impl_t struct _base_t
{ {
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2091069 _base_t(_data_t data) : _data{std::move(data)}
_impl_t() = default;
_impl_t(const _data_t& data) : _data(data)
{ {
} }
_data_t _data;
template <typename... Assignments> template <typename... Assignments>
void add(Assignments... assignments) void add_values(Assignments... assignments)
{ {
static_assert(logic::all_t<is_assignment_t<Assignments>::value...>::value, static_assert(logic::all_t<is_assignment_t<Assignments>::value...>::value,
"add_values() arguments have to be assignments"); "add_values() arguments have to be assignments");
@ -405,40 +297,9 @@ namespace sqlpp
} }
template <typename... Assignments> template <typename... Assignments>
void _add_impl(const std::false_type&, Assignments... assignments); void _add_impl(const std::false_type& /*unused*/, Assignments... /*unused*/);
public: 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, using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<column_list_t>::value,
consistent_t, consistent_t,
assert_no_unknown_tables_in_column_list_t>::type; 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 _traits = make_traits<no_value_t, tag::is_noop>;
using _nodes = detail::type_vector<>; using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> no_insert_values; _data_t _data;
_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;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_insert_value_list_t, 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> template <typename... Assignments>
auto set(Assignments... assignments) const 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...>; 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> template <typename... Assignments>
auto set(std::tuple<Assignments...> assignments) const 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...>; using Check = check_insert_static_set_t<Assignments...>;
return _set_impl<void>(Check{}, assignments); return _set_impl(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);
} }
private: private:
@ -582,15 +393,15 @@ namespace sqlpp
return {static_cast<const derived_statement_t<Policies>&>(*this), column_list_data_t<Columns...>{cols...}}; 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>; 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 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), 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; return context;
} }
template <typename Context, typename Database, typename... Assignments> template <typename Context, typename... Assignments>
Context& serialize(const insert_list_data_t<Database, Assignments...>& t, Context& context) Context& serialize(const insert_list_data_t<Assignments...>& t, Context& context)
{ {
context << " ("; context << " (";
interpret_tuple(t._columns, ",", context); interpret_tuple(t._columns, ",", context);
@ -644,15 +455,15 @@ namespace sqlpp
template <typename... Assignments> template <typename... Assignments>
auto insert_set(Assignments... 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> template <typename... Columns>
auto insert_columns(Columns... cols) 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 } // namespace sqlpp

View File

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

View File

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

View File

@ -34,35 +34,20 @@ namespace sqlpp
{ {
namespace mysql namespace mysql
{ {
template <typename Database>
using blank_remove_t = 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 {}; return {};
} }
template <typename Table> 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 mysql
} // namespace sqlpp } // namespace sqlpp

View File

@ -34,27 +34,14 @@ namespace sqlpp
{ {
namespace mysql namespace mysql
{ {
template <typename Database> using blank_update_t =
using blank_update_t = statement_t<Database, statement_t<update_t, no_single_table_t, no_update_list_t, no_where_t<true>, no_order_by_t, no_limit_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> 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 mysql
} // namespace sqlpp } // namespace sqlpp

View File

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

View File

@ -36,7 +36,7 @@
namespace sqlpp namespace sqlpp
{ {
// ORDER BY DATA // ORDER BY DATA
template <typename Database, typename... Expressions> template <typename... Expressions>
struct order_by_data_t struct order_by_data_t
{ {
order_by_data_t(Expressions... expressions) : _expressions(expressions...) 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"); "at least one order-by expression requires a table which is otherwise not known in the statement");
// ORDER BY // ORDER BY
template <typename Database, typename... Expressions> template <typename... Expressions>
struct order_by_t struct order_by_t
{ {
using _traits = make_traits<no_value_t, tag::is_order_by>; using _traits = make_traits<no_value_t, tag::is_order_by>;
using _nodes = detail::type_vector<Expressions...>; using _nodes = detail::type_vector<Expressions...>;
// Data using _data_t = order_by_data_t<Expressions...>;
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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = order_by_data_t<Database, Expressions...>; _base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> order_by; _data_t _data;
_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;
}
using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<order_by_t>::value, using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<order_by_t>::value,
consistent_t, consistent_t,
@ -134,48 +101,17 @@ namespace sqlpp
// Data // Data
using _data_t = no_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> no_order_by; _data_t _data;
_impl_t<Policies>& operator()()
{
return no_order_by;
}
const _impl_t<Policies>& operator()() const
{
return no_order_by;
}
template <typename T>
static auto _get_member(T t) -> decltype(t.no_order_by)
{
return t.no_order_by;
}
using _database_t = typename Policies::_database_t;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_order_by_t, T>; using _new_statement_t = new_statement_t<Check, Policies, no_order_by_t, T>;
@ -184,33 +120,33 @@ namespace sqlpp
template <typename... Expressions> template <typename... Expressions>
auto order_by(Expressions... expressions) const 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()"); 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: private:
template <typename Database, typename Check, typename... Expressions> template <typename Check, typename... Expressions>
auto _order_by_impl(Check, Expressions... expressions) const -> inconsistent<Check>; 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 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, static_assert(not detail::has_duplicates<Expressions...>::value,
"at least one duplicate argument detected in order_by()"); "at least one duplicate argument detected in order_by()");
return {static_cast<const derived_statement_t<Policies>&>(*this), return {static_cast<const derived_statement_t<Policies>&>(*this),
order_by_data_t<Database, Expressions...>{expressions...}}; order_by_data_t<Expressions...>{expressions...}};
} }
}; };
}; };
// Interpreters // Interpreters
template <typename Context, typename Database, typename... Expressions> template <typename Context, typename... Expressions>
Context& serialize(const order_by_data_t<Database, Expressions...>& t, Context& context) Context& serialize(const order_by_data_t<Expressions...>& t, Context& context)
{ {
context << " ORDER BY "; context << " ORDER BY ";
interpret_tuple(t._expressions, ',', context); interpret_tuple(t._expressions, ',', context);
@ -218,9 +154,9 @@ namespace sqlpp
} }
template <typename... T> 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 } // namespace sqlpp

View File

@ -34,33 +34,19 @@ namespace sqlpp
{ {
namespace postgresql namespace postgresql
{ {
template <typename Database>
using blank_insert_t = 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> 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 postgresql
} // namespace sqlpp } // namespace sqlpp

View File

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

View File

@ -66,46 +66,15 @@ namespace sqlpp
// Data // Data
using _data_t = on_conflict_do_nothing_data_t<ConflictTarget>; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = on_conflict_do_nothing_data_t<ConflictTarget>; _base_t(_data_t data) : _data{std::move(data)}
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : column{std::forward<Args>(args)...}
{ {
} }
_impl_t<Policies> column; _data_t _data;
_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;
}
// No consistency check needed, do nothing is just do nothing. // No consistency check needed, do nothing is just do nothing.
using _consistency_check = consistent_t; using _consistency_check = consistent_t;

View File

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

View File

@ -33,33 +33,18 @@ namespace sqlpp
{ {
namespace postgresql namespace postgresql
{ {
template <typename Database> using blank_remove_t = statement_t<remove_t, no_from_t, no_using_t, no_where_t<true>, no_returning_t>;
using blank_remove_t = statement_t<Database, 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 {}; return {};
} }
template <typename Table> 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 postgresql
} // namespace sqlpp } // namespace sqlpp

View File

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

View File

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

View File

@ -33,22 +33,14 @@ namespace sqlpp
{ {
namespace postgresql namespace postgresql
{ {
template <typename Database>
using blank_update_t = 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> 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; return context;
} }
template <typename Database> using blank_remove_t = statement_t<remove_t, no_from_t, no_using_t, no_where_t<true>>;
using blank_remove_t = statement_t<Database, 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 {}; return {};
} }
template <typename Table> 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 } // namespace sqlpp

View File

@ -63,9 +63,7 @@ namespace sqlpp
return context; return context;
} }
template <typename Database> using blank_select_t = statement_t<no_with_t,
using blank_select_t = statement_t<Database,
no_with_t,
select_t, select_t,
no_select_flag_list_t, no_select_flag_list_t,
no_select_column_list_t, no_select_column_list_t,
@ -77,17 +75,18 @@ namespace sqlpp
no_limit_t, no_limit_t,
no_offset_t, no_offset_t,
no_union_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 {}; return {};
} }
template <typename... Columns> 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 } // namespace sqlpp

View File

@ -65,7 +65,7 @@ namespace sqlpp
} // namespace detail } // namespace detail
// SELECTED COLUMNS DATA // SELECTED COLUMNS DATA
template <typename Database, typename... Columns> template <typename... Columns>
struct select_column_list_data_t struct select_column_list_data_t
{ {
select_column_list_data_t(Columns... columns) : _columns(columns...) 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"); "not all selected columns are made of aggregates, despite group_by or similar");
// SELECTED COLUMNS // SELECTED COLUMNS
template <typename Database, typename... Columns> template <typename... Columns>
struct select_column_list_t struct select_column_list_t
{ {
using _traits = typename detail::select_traits<Columns...>::_traits; 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 _alias_t = typename detail::select_traits<Columns...>::_alias_t;
using _data_t = select_column_list_data_t<Columns...>;
struct _column_type 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = select_column_list_data_t<Database, Columns...>; _base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> selected_columns; _data_t _data;
_impl_t<Policies>& operator()()
{
return selected_columns;
}
const _impl_t<Policies>& operator()() const
{
return selected_columns;
}
_impl_t<Policies>& get_selected_columns() const _base_t& get_selected_columns() const
{ {
return selected_columns; return *this;
}
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;
} }
using _table_check = typename std::conditional<Policies::template _no_unknown_tables<select_column_list_t>::value, using _table_check = typename std::conditional<Policies::template _no_unknown_tables<select_column_list_t>::value,
@ -260,8 +223,8 @@ namespace sqlpp
namespace detail namespace detail
{ {
template <typename Database, typename... Columns> template <typename... Columns>
select_column_list_t<Database, Columns...> make_column_list(std::tuple<Columns...> columns); select_column_list_t<Columns...> make_column_list(std::tuple<Columns...> columns);
} // namespace detail } // namespace detail
SQLPP_PORTABLE_STATIC_ASSERT(assert_selected_colums_are_selectable_t, "selected columns must be selectable"); 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; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> no_selected_columns; _data_t _data;
_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;
template <typename... T> template <typename... T>
static constexpr auto _check_args(std::tuple<T...> /*args*/) -> check_selected_columns_t<T...> static constexpr auto _check_args(std::tuple<T...> /*args*/) -> check_selected_columns_t<T...>
@ -343,42 +273,42 @@ namespace sqlpp
template <typename... Args> template <typename... Args>
auto columns(Args... args) const auto columns(Args... args) const
-> _new_statement_t<decltype(_check_args(detail::column_tuple_merge(args...))), -> _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()"); 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...))); using check = decltype(_check_args(detail::column_tuple_merge(args...)));
static_assert(check::value, static_assert(check::value,
"at least one argument is not a selectable expression in columns()"); "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: private:
template <typename Database, typename Check, typename... Args> template <typename Check, typename... Args>
auto _columns_impl(Check, std::tuple<Args...> args) const -> inconsistent<Check>; 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 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), 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 // Interpreters
template <typename Context, typename Database, typename... Columns> template <typename Context, typename... Columns>
Context& serialize(const select_column_list_data_t<Database, Columns...>& t, Context& context) Context& serialize(const select_column_list_data_t<Columns...>& t, Context& context)
{ {
interpret_tuple(t._columns, ',', context); interpret_tuple(t._columns, ',', context);
return context; return context;
} }
template <typename... T> 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 } // namespace sqlpp

View File

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

View File

@ -35,7 +35,7 @@
namespace sqlpp namespace sqlpp
{ {
// A SINGLE TABLE DATA // A SINGLE TABLE DATA
template <typename Database, typename Table> template <typename Table>
struct single_table_data_t struct single_table_data_t
{ {
single_table_data_t(Table table) : _table(table) single_table_data_t(Table table) : _table(table)
@ -52,7 +52,7 @@ namespace sqlpp
}; };
// A SINGLE TABLE // A SINGLE TABLE
template <typename Database, typename Table> template <typename Table>
struct single_table_t struct single_table_t
{ {
using _traits = make_traits<no_value_t, tag::is_single_table>; 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(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"); 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 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = single_table_data_t<Database, Table>; _base_t(_data_t data) : _data{std::move(data)}
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : from{std::forward<Args>(args)...}
{ {
} }
_impl_t<Policies> from; _data_t _data;
_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;
}
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
}; };
@ -130,36 +99,16 @@ namespace sqlpp
// Data // Data
using _data_t = no_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _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> _data_t _data;
static auto _get_member(T t) -> decltype(t.no_from)
{
return t.no_from;
}
using _database_t = typename Policies::_database_t;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_single_table_t, 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; using _consistency_check = consistent_t;
template <typename Table> 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: private:
template <typename Database, typename Check, typename Table> template <typename Check, typename Table>
auto _single_table_impl(Check, Table table) const -> inconsistent<Check>; 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 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()"); "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 // Interpreters
template <typename Context, typename Database, typename Table> template <typename Context, typename Table>
Context& serialize(const single_table_data_t<Database, Table>& t, Context& context) Context& serialize(const single_table_data_t<Table>& t, Context& context)
{ {
serialize(t._table, context); serialize(t._table, context);
return context; return context;

View File

@ -78,62 +78,34 @@ namespace sqlpp
}; };
}; };
template <typename Database, typename InsertOrAlternative> template <typename InsertOrAlternative>
using blank_insert_or_t = 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<insert_or_replace_name_t>;
using blank_insert_or_replace_t = blank_insert_or_t<Database, insert_or_replace_name_t>;
template <typename Database> using blank_insert_or_ignore_t = blank_insert_or_t<insert_or_ignore_name_t>;
using blank_insert_or_ignore_t = blank_insert_or_t<Database, 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> 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> inline auto insert_or_ignore() -> blank_insert_or_ignore_t
constexpr auto dynamic_insert_or_replace(const Database&) -> decltype(blank_insert_or_replace_t<Database>())
{ {
return {blank_insert_or_replace_t<Database>()}; return {blank_insert_or_ignore_t()};
}
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>()};
} }
template <typename Table> 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)}; return {blank_insert_or_ignore_t().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)};
} }
inline sqlite3::context_t& serialize(const sqlite3::insert_or_replace_name_t&, sqlite3::context_t& context) 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 // disable some stuff that won't work with sqlite3
#if SQLITE_VERSION_NUMBER < 3008003 #if SQLITE_VERSION_NUMBER < 3008003
template <typename Database, typename... Expressions> template <typename... Expressions>
sqlite3::context_t& serialize(const with_data_t<Database, Expressions...>&, sqlite3::context_t& context) 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"); static_assert(wrong_t<Expressions...>::value, "Sqlite3: No support for with before version 3.8.3");
return context; return context;

View File

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

View File

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

View File

@ -40,7 +40,7 @@ namespace sqlpp
{ {
struct no_union_t; 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. // 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> template <typename Check, typename Union>
@ -52,14 +52,14 @@ namespace sqlpp
template <typename Union> template <typename Union>
struct union_statement_impl<consistent_t, 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> template <typename Check, typename Union>
using union_statement_t = typename union_statement_impl<Check, Union>::type; using union_statement_t = typename union_statement_impl<Check, Union>::type;
// UNION(EXPR) // UNION(EXPR)
template <typename Database, typename Flag, typename Lhs, typename Rhs> template <typename Flag, typename Lhs, typename Rhs>
struct union_t struct union_t
{ {
using _traits = make_traits<no_value_t, tag::is_union, tag::is_return_value>; 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<Flag, Lhs, Rhs>;
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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = union_data_t<Database, Flag, Lhs, Rhs>; _base_t(_data_t data) : _data{std::move(data)}
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : union_{std::forward<Args>(args)...}
{ {
} }
_impl_t<Policies> union_; _data_t _data;
_impl_t<Policies>& operator()()
{
return union_;
}
const _impl_t<Policies>& operator()() const
{
return union_;
}
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() _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 const _selected_columns_t& get_selected_columns() const
{ {
return union_._data._lhs.get_selected_columns(); return _data._lhs.get_selected_columns();
}
template <typename T>
static auto _get_member(T t) -> decltype(t.union_)
{
return t.union_;
} }
using _consistency_check = detail::get_first_if<is_inconsistent_t, using _consistency_check = detail::get_first_if<is_inconsistent_t,
@ -152,48 +120,15 @@ namespace sqlpp
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies> template <typename Policies>
struct _impl_t struct _base_t
{ {
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 _base_t() = default;
_impl_t() = default; _base_t(_data_t data) : _data{std::move(data)}
_impl_t(const _data_t& data) : _data(data)
{ {
} }
_data_t _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> template <typename Check, typename T>
using _new_statement_t = union_statement_t<Check, T>; using _new_statement_t = union_statement_t<Check, T>;
@ -203,7 +138,7 @@ namespace sqlpp
template <typename Rhs> template <typename Rhs>
auto union_distinct(Rhs rhs) const auto union_distinct(Rhs rhs) const
-> _new_statement_t<check_union_t<derived_statement_t<Policies>, Rhs>, -> _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(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"); 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, 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)"); "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> template <typename Rhs>
auto union_all(Rhs rhs) const -> _new_statement_t<check_union_t<derived_statement_t<Policies>, 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(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"); 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, 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)"); "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: 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>; 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 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}}; static_cast<const derived_statement_t<Policies>&>(*this), rhs}};
} }
}; };
@ -253,15 +188,15 @@ namespace sqlpp
/* /*
template <typename T> 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> 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 } // namespace sqlpp

View File

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

View File

@ -94,13 +94,12 @@ namespace sqlpp
return context; return context;
} }
template <typename Database> using blank_update_t = statement_t<update_t, no_single_table_t, no_update_list_t, no_where_t<true>>;
using blank_update_t = statement_t<Database, update_t, no_single_table_t, no_update_list_t, no_where_t<true>>;
template <typename Table> 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 } // namespace sqlpp

View File

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

View File

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

View File

@ -38,19 +38,9 @@
namespace sqlpp namespace sqlpp
{ {
// WHERE DATA // WHERE DATA
template <typename Database, typename Expression> template <typename Expression>
struct where_data_t 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; 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"); "at least one expression in where() requires a table which is otherwise not known in the statement");
// WHERE(EXPR) // WHERE(EXPR)
template <typename Database, typename Expression> template <typename Expression>
struct where_t struct where_t
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<Expression>; using _nodes = detail::type_vector<Expression>;
// Data using _data_t = where_data_t<Expression>;
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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = where_data_t<Database, Expression>; _base_t(const _base_t&) = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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; _data_t _data;
_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 = typename std::conditional<Policies::template _no_unknown_tables<where_t>::value, using _consistency_check = typename std::conditional<Policies::template _no_unknown_tables<where_t>::value,
consistent_t, consistent_t,
@ -117,60 +75,29 @@ namespace sqlpp
}; };
template <> template <>
struct where_data_t<void, unconditional_t> struct where_data_t<unconditional_t>
{ {
}; };
// WHERE() UNCONDITIONALLY // WHERE() UNCONDITIONALLY
template <> template <>
struct where_t<void, unconditional_t> struct where_t<unconditional_t>
{ {
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>; using _nodes = detail::type_vector<>;
// Data using _data_t = where_data_t<unconditional_t>;
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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = where_data_t<void, unconditional_t>; _base_t(const _base_t&) = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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; _data_t _data;
_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; using _consistency_check = consistent_t;
}; };
@ -223,51 +150,18 @@ namespace sqlpp
using _traits = make_traits<no_value_t, tag::is_where>; using _traits = make_traits<no_value_t, tag::is_where>;
using _nodes = detail::type_vector<>; using _nodes = detail::type_vector<>;
// Data
using _data_t = no_data_t; 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 // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = no_data_t; _base_t() = default;
_base_t(_data_t data) : _data{std::move(data)}
// 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)...}
{ {
} }
_impl_t<Policies> no_where; _data_t _data;
_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;
template <typename Check, typename T> template <typename Check, typename T>
using _new_statement_t = new_statement_t<Check, Policies, no_where_t, 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, assert_where_or_unconditionally_called_t,
consistent_t>::type; 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> template <typename Expression>
auto where(Expression expression) const 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>; using Check = check_where_static_t<Expression>;
return _where_impl<void>(Check{}, expression); return _where_impl(Check{}, expression);
} }
private: private:
template <typename Database, typename Check, typename Expression> template <typename Check, typename Expression>
auto _where_impl(Check, Expression expression) const -> inconsistent<Check>; 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 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), return {static_cast<const derived_statement_t<Policies>&>(*this),
where_data_t<Database, Expression>{expression}}; where_data_t<Expression>{expression}};
} }
}; };
}; };
// Interpreters // Interpreters
template <typename Context, typename Database, typename Expression> template <typename Context, typename Expression>
Context& serialize(const where_data_t<Database, Expression>& t, Context& context) Context& serialize(const where_data_t<Expression>& t, Context& context)
{ {
context << " WHERE "; context << " WHERE ";
serialize(t._expression, context); serialize(t._expression, context);
return 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> 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; return context;
} }
template <typename T> 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 } // namespace sqlpp

View File

@ -41,7 +41,7 @@
namespace sqlpp namespace sqlpp
{ {
template <typename Database, typename... Expressions> template <typename... Expressions>
struct with_data_t struct with_data_t
{ {
using _is_recursive = logic::any_t<Expressions::_is_recursive...>; using _is_recursive = logic::any_t<Expressions::_is_recursive...>;
@ -59,7 +59,7 @@ namespace sqlpp
std::tuple<Expressions...> _expressions; std::tuple<Expressions...> _expressions;
}; };
template <typename Database, typename... Expressions> template <typename... Expressions>
struct with_t struct with_t
{ {
using _traits = make_traits<no_value_t, tag::is_with>; 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 detail::make_joined_set_t<required_ctes_of<Expressions>...>; // WITH provides common table expressions
using _parameters = detail::type_vector_cat_t<parameters_of<Expressions>...>; using _parameters = detail::type_vector_cat_t<parameters_of<Expressions>...>;
// Data using _data_t = with_data_t<Expressions...>;
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;
};
// Base template to be inherited by the statement // Base template to be inherited by the statement
template <typename Policies> template <typename Policies>
struct _base_t struct _base_t
{ {
using _data_t = with_data_t<Database, Expressions...>; _base_t(_data_t data) : _data{std::move(data)}
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269
template <typename... Args>
_base_t(Args&&... args) : with{std::forward<Args>(args)...}
{ {
} }
_impl_t<Policies> with; _data_t _data;
_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;
}
// FIXME: Need real checks here // FIXME: Need real checks here
using _consistency_check = consistent_t; using _consistency_check = consistent_t;
@ -125,59 +93,29 @@ namespace sqlpp
// Data // Data
using _data_t = no_data_t; using _data_t = no_data_t;
// Member implementation with data and methods
template <typename Policies> template <typename Policies>
struct _impl_t struct _base_t
{ {
// workaround for msvc bug https://connect.microsoft.com/VisualStudio/Feedback/Details/2173269 _base_t() = default;
_impl_t() = default; _base_t(_data_t data) : _data{std::move(data)}
_impl_t(const _data_t& data) : _data(data)
{ {
} }
_data_t _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; using _consistency_check = consistent_t;
}; };
}; };
template <typename Database, typename... Expressions> template <typename... Expressions>
struct blank_with_t struct blank_with_t
{ {
with_data_t<Database, Expressions...> _data; with_data_t<Expressions...> _data;
template <typename Statement> template <typename Statement>
auto operator()(Statement 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 // FIXME need checks here
// check that no cte refers to any of the ctes to the right // check that no cte refers to any of the ctes to the right
@ -186,10 +124,10 @@ namespace sqlpp
}; };
// Interpreters // Interpreters
template <typename Context, typename Database, typename... Expressions> template <typename Context, typename... Expressions>
Context& serialize(const with_data_t<Database, Expressions...>& t, Context& context) 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 // FIXME: If there is a recursive CTE, add a "RECURSIVE" here
context << " WITH "; context << " WITH ";
if (T::_is_recursive::value) if (T::_is_recursive::value)
@ -202,7 +140,7 @@ namespace sqlpp
} }
template <typename... Expressions> 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, static_assert(logic::all_t<is_cte_t<Expressions>::value...>::value,
"at least one expression in with is not a common table expression"); "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)), 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 " "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 " "(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 // A pragma query for sqlite
compare(__LINE__, compare(__LINE__,
@ -81,8 +81,8 @@ int CustomQuery(int, char*[])
// A multi-row "insert or ignore" // A multi-row "insert or ignore"
auto batch = insert_columns(bar.beta, bar.gamma); auto batch = insert_columns(bar.beta, bar.gamma);
batch.values.add(bar.beta = "sample", bar.gamma = true); batch.add_values(bar.beta = "sample", bar.gamma = true);
batch.values.add(bar.beta = "ample", bar.gamma = false); batch.add_values(bar.beta = "ample", bar.gamma = false);
compare(__LINE__, custom_query(sqlpp::insert(), sqlpp::verbatim(" OR IGNORE"), into(bar), batch), 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)"); "INSERT OR IGNORE INTO tab_bar (beta,gamma) VALUES ('sample',1),('ample',0)");

View File

@ -32,6 +32,8 @@
namespace namespace
{ {
#warning restore this file!
#if 0
struct on_duplicate_key_update struct on_duplicate_key_update
{ {
std::string _serialized; std::string _serialized;
@ -56,6 +58,7 @@ namespace
return ::sqlpp::verbatim(_serialized); return ::sqlpp::verbatim(_serialized);
} }
}; };
#endif
} // namespace } // namespace
int CustomQuery(int, char*[]) int CustomQuery(int, char*[])
@ -68,8 +71,11 @@ int CustomQuery(int, char*[])
// A void custom query // A void custom query
printer.reset(); 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; std::cerr << serialize(x, printer).str() << std::endl;
#if 0
db(x); db(x);
// Syntactically, it is possible to use this void query as a prepared statement, too, not sure, whether this makes // 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" // Create a custom mulit-row "insert or ignore"
auto batch = insert_columns(t.beta, t.gamma); auto batch = insert_columns(t.beta, t.gamma);
batch.values.add(t.beta = "sample", t.gamma = true); batch.add_values(t.beta = "sample", t.gamma = true);
batch.values.add(t.beta = "ample", t.gamma = false); batch.add_values(t.beta = "ample", t.gamma = false);
db(custom_query(sqlpp::insert(), sqlpp::verbatim(" OR IGNORE"), into(t), batch)); db(custom_query(sqlpp::insert(), sqlpp::verbatim(" OR IGNORE"), into(t), batch));
// Create a MYSQL style custom "insert on duplicate update" // Create a MYSQL style custom "insert on duplicate update"
@ -117,6 +123,7 @@ int CustomQuery(int, char*[])
{ {
(void)row.alpha; (void)row.alpha;
} }
#endif
return 0; 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).set(t.gamma = true, t.beta = "kirschauflauf"), printer).str();
serialize(insert_into(t).columns(t.gamma, t.beta), 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); 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.add_values(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 = sqlpp::default_value, t.beta = sqlpp::default_value,
t.delta = 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)); t.delta = sqlpp::value_or_null<sqlpp::integer>(sqlpp::null));
printer.reset(); printer.reset();
std::cerr << serialize(multi_insert, printer).str() << std::endl; 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()); .set(tabDateTime.colTimePoint = std::chrono::system_clock::now());
auto multi_time_insert = insert_into(tabDateTime).columns(tabDateTime.colTimePoint); 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())); std::chrono::system_clock::now()));
#warning add tests with optional #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(); serialize(insert_into(t).columns(t.beta, t.gamma), printer).str();
{ {
auto i = insert_into(t).columns(t.gamma, t.beta); 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(); 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(); serialize(i, printer).str();
} }

View File

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

View File

@ -44,6 +44,9 @@ int Remove(int, char* [])
{ {
using T = decltype(remove_from(t).where(t.beta != "transparent")); 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"); static_assert(sqlpp::is_regular<T>::value, "type requirement");
} }

View File

@ -33,27 +33,8 @@ namespace sqlpp
template <typename T> template <typename T>
struct is_regular 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 = static constexpr bool value =
true std::is_move_assignable<T>::value // containers and strings are not noexcept_assignable
#if !defined _MSC_VER and std::is_copy_constructible<T>::value and std::is_copy_assignable<T>::value;
#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
;
}; };
} }

View File

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

View File

@ -62,18 +62,11 @@ int MoveConstructor(int, char*[])
const auto tab = TabSample{}; const auto tab = TabSample{};
db(insert_into(tab).set(tab.gamma = true)); db(insert_into(tab).set(tab.gamma = true));
auto i = insert_into(tab).columns(tab.beta, tab.gamma); auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false); i.add_values(tab.beta = "rhabarbertorte", tab.gamma = false);
i.values.add(tab.beta = "cheesecake", tab.gamma = false); i.add_values(tab.beta = "cheesecake", tab.gamma = false);
i.values.add(tab.beta = "kaesekuchen", tab.gamma = true); i.add_values(tab.beta = "kaesekuchen", tab.gamma = true);
db(i); 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(); db.commit_transaction();
assert(db.is_transaction_active() == false); 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 = 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))); db(update(tab).set(tab.gamma = true).where(tab.alpha.in(1)));
// dynamic insert #warning: Add test with optional insert
auto dynin = dynamic_insert_into(db, tab).dynamic_set(tab.gamma = true);
dynin.insert_list.add(tab.beta = "cheesecake");
db(dynin);
// remove // 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 << db(sqlpp::postgresql::insert_into(foo).set(foo.gamma = "asd").returning(std::make_tuple(foo.c_timepoint))).front().c_timepoint
<< std::endl; << std::endl;
auto i = sqlpp::postgresql::dynamic_insert_into(db, foo).dynamic_set().returning(foo.c_timepoint); #warning need to add optinal insert tests
i.insert_list.add(foo.gamma = "blah");
std::cout << db(i).front().c_timepoint << std::endl;
auto updated = auto updated =
db(sqlpp::postgresql::update(foo).set(foo.beta = 0).unconditionally().returning(foo.gamma, foo.beta)); 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; 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); 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.add_values(foo.beta = 1);
multi_insert.values.add(foo.beta = 2); multi_insert.add_values(foo.beta = 2);
auto inserted = db(multi_insert); auto inserted = db(multi_insert);
for (const auto& row : inserted) for (const auto& row : inserted)

View File

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

View File

@ -68,9 +68,9 @@ int DynamicSelect(int, char*[])
const auto tab = TabSample{}; const auto tab = TabSample{};
auto i = insert_into(tab).columns(tab.beta, tab.gamma); auto i = insert_into(tab).columns(tab.beta, tab.gamma);
i.values.add(tab.beta = "rhabarbertorte", tab.gamma = false); i.add_values(tab.beta = "rhabarbertorte", tab.gamma = false);
// i.values.add(tab.beta = "cheesecake", tab.gamma = false) // i.add_values(tab.beta = "cheesecake", tab.gamma = false)
// i.values.add(tab.beta = "kaesekuchen", tab.gamma = true) // i.add_values(tab.beta = "kaesekuchen", tab.gamma = true)
auto last_insert_rowid = db(i); auto last_insert_rowid = db(i);
std::cerr << "last insert rowid: " << last_insert_rowid << std::endl; 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 << db(select(sqlpp::verbatim<sqlpp::integer>("last_insert_rowid()").as(tab.alpha))).front().alpha
<< std::endl; << std::endl;
// select a static (alpha) and a dynamic column (beta) #warning: add tests with optional columns
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;
};
return 0; return 0;
} }

View File

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