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

View File

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

View File

@ -8,8 +8,8 @@ endmacro ()
#build_and_run(InterpretTest)
#build_and_run(InsertTest)
build_and_run(RemoveTest)
#build_and_run(UpdateTest)
#build_and_run(RemoveTest)
build_and_run(UpdateTest)
#build_and_run(SelectTest)
#build_and_run(SelectTypeTest)
#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.beta = "opaque").where(t.beta != t.beta), printer).str();
auto u = dynamic_update(db, t).dynamic_set(t.gamma = false).dynamic_where();
u.add_set(t.gamma = false);
u.add_where(t.gamma != false);
u.assignments.add(t.gamma = false);
u.where.add(t.gamma != false);
serialize(u, printer).str();
db(u);