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:
parent
c866f31ea5
commit
d36037472f
@ -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>;
|
||||
|
128
include/sqlpp11/vendor/update_list.h
vendored
128
include/sqlpp11/vendor/update_list.h
vendored
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user