0
0
mirror of https://github.com/rbock/sqlpp11.git synced 2024-11-15 20:31:16 +08:00

Migrated update to generic statement

This commit is contained in:
rbock 2014-06-04 09:26:10 +02:00
parent c866f31ea5
commit d36037472f
4 changed files with 97 additions and 51 deletions

View File

@ -27,6 +27,8 @@
#ifndef SQLPP_UPDATE_H #ifndef SQLPP_UPDATE_H
#define SQLPP_UPDATE_H #define SQLPP_UPDATE_H
#include <sqlpp11/statement.h>
#include <sqlpp11/type_traits.h> #include <sqlpp11/type_traits.h>
#include <sqlpp11/parameter_list.h> #include <sqlpp11/parameter_list.h>
#include <sqlpp11/prepared_update.h> #include <sqlpp11/prepared_update.h>
@ -34,13 +36,10 @@
#include <sqlpp11/vendor/update_list.h> #include <sqlpp11/vendor/update_list.h>
#include <sqlpp11/vendor/noop.h> #include <sqlpp11/vendor/noop.h>
#include <sqlpp11/vendor/where.h> #include <sqlpp11/vendor/where.h>
#include <sqlpp11/vendor/policy_update.h>
#include <sqlpp11/detail/get_last.h>
#include <sqlpp11/detail/pick_arg.h>
namespace sqlpp namespace sqlpp
{ {
#if 0
template<typename Db, typename... Policies> template<typename Db, typename... Policies>
struct update_t; struct update_t;
@ -178,9 +177,10 @@ namespace sqlpp
} }
}; };
} }
#endif
template<typename Database> template<typename Database>
using blank_update_t = update_t<Database, using blank_update_t = statement_t<Database,
vendor::no_single_table_t, vendor::no_single_table_t,
vendor::no_update_list_t, vendor::no_update_list_t,
vendor::no_where_t>; vendor::no_where_t>;

View File

@ -36,6 +36,24 @@ namespace sqlpp
{ {
namespace vendor namespace vendor
{ {
// UPDATE ASSIGNMENTS DATA
template<typename Database, typename... Assignments>
struct update_list_data_t
{
update_list_data_t(Assignments... assignments):
_assignments(assignments...)
{}
update_list_data_t(const update_list_data_t&) = default;
update_list_data_t(update_list_data_t&&) = default;
update_list_data_t& operator=(const update_list_data_t&) = default;
update_list_data_t& operator=(update_list_data_t&&) = default;
~update_list_data_t() = default;
std::tuple<Assignments...> _assignments;
typename vendor::interpretable_list_t<Database> _dynamic_assignments;
};
// UPDATE ASSIGNMENTS // UPDATE ASSIGNMENTS
template<typename Database, typename... Assignments> template<typename Database, typename... Assignments>
struct update_list_t struct update_list_t
@ -61,57 +79,70 @@ namespace sqlpp
static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables"); static_assert(::sqlpp::detail::is_subset_of<_value_table_set, _column_table_set>::value, "set() contains values from foreign tables");
*/ */
update_list_t& _update_list() { return *this; } // Data
using _data_t = update_list_data_t<Database, Assignments...>;
update_list_t(Assignments... assignments): // Member implementation with data and methods
_assignments(assignments...) template <typename Policies>
{} struct _impl_t
update_list_t(const update_list_t&) = default;
update_list_t(update_list_t&&) = default;
update_list_t& operator=(const update_list_t&) = default;
update_list_t& operator=(update_list_t&&) = default;
~update_list_t() = default;
template<typename Policies>
struct _methods_t
{ {
template<typename Assignment> template<typename Assignment>
void add_set_ntc(Assignment assignment) void add_ntc(Assignment assignment)
{ {
add_set<Assignment, std::false_type>(assignment); add<Assignment, std::false_type>(assignment);
} }
template<typename Assignment, typename TableCheckRequired = std::true_type> template<typename Assignment, typename TableCheckRequired = std::true_type>
void add_set(Assignment assignment) void add(Assignment assignment)
{ {
static_assert(_is_dynamic::value, "add_set must not be called for static from()"); static_assert(_is_dynamic::value, "add must not be called for static from()");
static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add_set()"); static_assert(is_assignment_t<Assignment>::value, "invalid assignment argument in add()");
static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add_set() argument must not be updated"); static_assert(sqlpp::detail::not_t<must_not_update_t, typename Assignment::_column_t>::value, "add() argument must not be updated");
static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add_set()"); static_assert(TableCheckRequired::value or Policies::template _no_unknown_tables<Assignment>::value, "assignment uses tables unknown to this statement in add()");
using ok = ::sqlpp::detail::all_t< using ok = ::sqlpp::detail::all_t<
_is_dynamic::value, _is_dynamic::value,
is_assignment_t<Assignment>::value, is_assignment_t<Assignment>::value,
not must_not_update_t<typename Assignment::_column_t>::value>; not must_not_update_t<typename Assignment::_column_t>::value>;
_add_set_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert _add_impl(assignment, ok()); // dispatch to prevent compile messages after the static_assert
} }
private: private:
template<typename Assignment> template<typename Assignment>
void _add_set_impl(Assignment assignment, const std::true_type&) void _add_impl(Assignment assignment, const std::true_type&)
{ {
return static_cast<typename Policies::_statement_t*>(this)->_update_list()._dynamic_assignments.emplace_back(assignment); return _data._dynamic_assignments.emplace_back(assignment);
} }
template<typename Assignment> template<typename Assignment>
void _add_set_impl(Assignment assignment, const std::false_type&); void _add_impl(Assignment assignment, const std::false_type&);
public:
_data_t _data;
}; };
// Member template for adding the named member to a statement
template<typename Policies>
struct _member_t
{
using _data_t = update_list_data_t<Database, Assignments...>;
std::tuple<Assignments...> _assignments; _impl_t<Policies> assignments;
typename vendor::interpretable_list_t<Database> _dynamic_assignments; _impl_t<Policies>& operator()() { return assignments; }
const _impl_t<Policies>& operator()() const { return assignments; }
template<typename T>
static auto _get_member(T t) -> decltype(t.assignments)
{
return t.assignments;
}
};
// Additional methods for the statement
template<typename Policies>
struct _methods_t
{
};
}; };
struct no_update_list_t struct no_update_list_t
@ -119,6 +150,33 @@ namespace sqlpp
using _traits = make_traits<no_value_t, ::sqlpp::tag::where>; using _traits = make_traits<no_value_t, ::sqlpp::tag::where>;
using _recursive_traits = make_recursive_traits<>; using _recursive_traits = make_recursive_traits<>;
// Data
using _data_t = no_data_t;
// Member implementation with data and methods
template<typename Policies>
struct _impl_t
{
_data_t _data;
};
// Member template for adding the named member to a statement
template<typename Policies>
struct _member_t
{
using _data_t = no_data_t;
_impl_t<Policies> no_assignments;
_impl_t<Policies>& operator()() { return no_assignments; }
const _impl_t<Policies>& operator()() const { return no_assignments; }
template<typename T>
static auto _get_member(T t) -> decltype(t.no_assignments)
{
return t.no_assignments;
}
};
template<typename Policies> template<typename Policies>
struct _methods_t struct _methods_t
{ {
@ -130,7 +188,7 @@ namespace sqlpp
auto set(Args... args) auto set(Args... args)
-> _new_statement_t<update_list_t<void, Args...>> -> _new_statement_t<update_list_t<void, Args...>>
{ {
return { *static_cast<typename Policies::_statement_t*>(this), update_list_t<void, Args...>{args...} }; return { *static_cast<typename Policies::_statement_t*>(this), update_list_data_t<void, Args...>{args...} };
} }
template<typename... Args> template<typename... Args>
@ -138,16 +196,16 @@ namespace sqlpp
-> _new_statement_t<update_list_t<_database_t, Args...>> -> _new_statement_t<update_list_t<_database_t, Args...>>
{ {
static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement"); static_assert(not std::is_same<_database_t, void>::value, "dynamic_set must not be called in a static statement");
return { *static_cast<typename Policies::_statement_t*>(this), vendor::update_list_t<_database_t, Args...>{args...} }; return { *static_cast<typename Policies::_statement_t*>(this), vendor::update_list_data_t<_database_t, Args...>{args...} };
} }
}; };
}; };
// Interpreters // Interpreters
template<typename Context, typename Database, typename... Assignments> template<typename Context, typename Database, typename... Assignments>
struct serializer_t<Context, update_list_t<Database, Assignments...>> struct serializer_t<Context, update_list_data_t<Database, Assignments...>>
{ {
using T = update_list_t<Database, Assignments...>; using T = update_list_data_t<Database, Assignments...>;
static Context& _(const T& t, Context& context) static Context& _(const T& t, Context& context)
{ {
@ -159,18 +217,6 @@ namespace sqlpp
return context; return context;
} }
}; };
template<typename Context>
struct serializer_t<Context, no_update_list_t>
{
using T = no_update_list_t;
static Context& _(const T& t, Context& context)
{
return context;
}
};
} }
} }

View File

@ -8,8 +8,8 @@ endmacro ()
#build_and_run(InterpretTest) #build_and_run(InterpretTest)
#build_and_run(InsertTest) #build_and_run(InsertTest)
build_and_run(RemoveTest) #build_and_run(RemoveTest)
#build_and_run(UpdateTest) build_and_run(UpdateTest)
#build_and_run(SelectTest) #build_and_run(SelectTest)
#build_and_run(SelectTypeTest) #build_and_run(SelectTypeTest)
#build_and_run(FunctionTest) #build_and_run(FunctionTest)

View File

@ -61,8 +61,8 @@ int main()
serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).str(); serialize(update(t).set(t.gamma = false).where(t.beta != "transparent"), printer).str();
serialize(update(t).set(t.beta = "opaque").where(t.beta != t.beta), printer).str(); serialize(update(t).set(t.beta = "opaque").where(t.beta != t.beta), printer).str();
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where(); auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
u.add_set(t.gamma = false); u.assignments.add(t.gamma = false);
u.add_where(t.gamma != false); u.where.add(t.gamma != false);
serialize(u, printer).str(); serialize(u, printer).str();
db(u); db(u);