mirror of
https://github.com/rbock/sqlpp11.git
synced 2024-11-15 20:31:16 +08:00
interpreter added for update()
This commit is contained in:
parent
9335a62087
commit
602f33726f
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
template<typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
|
template<typename Database, typename... Assignments>
|
||||||
struct assignment_list_t
|
struct assignment_list_t
|
||||||
{
|
{
|
||||||
using _is_assignment_list = std::true_type;
|
using _is_assignment_list = std::true_type;
|
||||||
@ -52,14 +52,14 @@ namespace sqlpp
|
|||||||
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
||||||
|
|
||||||
// check for prohibited assignments
|
// check for prohibited assignments
|
||||||
using _prohibited_assignment_set = typename detail::make_set_if<ProhibitPredicate, typename Assignments::column_type...>::type;
|
using _prohibited_assignment_set = typename detail::make_set_if<must_not_update_t, typename Assignments::column_type...>::type;
|
||||||
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
||||||
|
|
||||||
template<typename Assignment>
|
template<typename Assignment>
|
||||||
void add(Assignment&& assignment)
|
void add(Assignment&& assignment)
|
||||||
{
|
{
|
||||||
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
||||||
static_assert(not ProhibitPredicate<typename std::decay<Assignment>::type::column_type>::value, "set() argument must not be updated");
|
static_assert(not must_not_update_t<typename std::decay<Assignment>::type::column_type>::value, "set() argument must not be updated");
|
||||||
_dynamic_assignments.emplace_back(std::forward<Assignment>(assignment));
|
_dynamic_assignments.emplace_back(std::forward<Assignment>(assignment));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +81,22 @@ namespace sqlpp
|
|||||||
typename detail::serializable_list<Database> _dynamic_assignments;
|
typename detail::serializable_list<Database> _dynamic_assignments;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context, typename Database, typename... Assignments>
|
||||||
|
struct interpreter_t<Context, assignment_list_t<Database, Assignments...>>
|
||||||
|
{
|
||||||
|
using T = assignment_list_t<Database, Assignments...>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << " SET ";
|
||||||
|
interpret_tuple(t._assignments, ",", context);
|
||||||
|
if (sizeof...(Assignments) and not t._dynamic_assignments.empty())
|
||||||
|
context << ',';
|
||||||
|
interpret_serializable_list(t._dynamic_assignments, ',', context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
#include <sqlpp11/parameter_list.h>
|
#include <sqlpp11/parameter_list.h>
|
||||||
#include <sqlpp11/prepared_insert.h>
|
#include <sqlpp11/prepared_insert.h>
|
||||||
|
|
||||||
#include <sqlpp11/detail/serialize_tuple.h>
|
|
||||||
|
|
||||||
namespace sqlpp
|
namespace sqlpp
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -77,24 +75,24 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto set(Assignment&&... assignment)
|
auto set(Assignment&&... assignment)
|
||||||
-> set_insert_list_t<insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>>
|
-> set_insert_list_t<insert_list_t<void, typename std::decay<Assignment>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()");
|
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()");
|
||||||
// FIXME: Need to check if all required columns are set
|
// FIXME: Need to check if all required columns are set
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
insert_list_t<void, must_not_insert_t, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
insert_list_t<void, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto dynamic_set(Assignment&&... assignment)
|
auto dynamic_set(Assignment&&... assignment)
|
||||||
-> set_insert_list_t<insert_list_t<Database, must_not_insert_t, typename std::decay<Assignment>::type...>>
|
-> set_insert_list_t<insert_list_t<Database, typename std::decay<Assignment>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()");
|
static_assert(std::is_same<InsertList, noop>::value, "cannot call set() after set() or default_values()");
|
||||||
return {
|
return {
|
||||||
_table,
|
_table,
|
||||||
insert_list_t<Database, must_not_insert_t, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
insert_list_t<Database, typename std::decay<Assignment>::type...>{std::forward<Assignment>(assignment)...},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +128,7 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db) const
|
||||||
-> prepared_insert_t<typename std::decay<Db>::type, insert_t>
|
-> prepared_insert_t<typename std::decay<Db>::type, insert_t>
|
||||||
{
|
{
|
||||||
constexpr bool calledSet = not is_noop<InsertList>::value;
|
constexpr bool calledSet = not is_noop<InsertList>::value;
|
||||||
|
@ -71,7 +71,7 @@ namespace sqlpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
|
template<typename Database, typename... Assignments>
|
||||||
struct insert_list_t
|
struct insert_list_t
|
||||||
{
|
{
|
||||||
using _is_insert_list = std::true_type;
|
using _is_insert_list = std::true_type;
|
||||||
@ -89,7 +89,7 @@ namespace sqlpp
|
|||||||
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
static_assert(_assignment_set::size::value == sizeof...(Assignments), "at least one argument is not an assignment in set()");
|
||||||
|
|
||||||
// check for prohibited assignments
|
// check for prohibited assignments
|
||||||
using _prohibited_assignment_set = typename detail::make_set_if<ProhibitPredicate, typename Assignments::column_type...>::type;
|
using _prohibited_assignment_set = typename detail::make_set_if<must_not_insert_t, typename Assignments::column_type...>::type;
|
||||||
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
static_assert(_prohibited_assignment_set::size::value == 0, "at least one assignment is prohibited by its column definition in set()");
|
||||||
|
|
||||||
insert_list_t(Assignments... assignment):
|
insert_list_t(Assignments... assignment):
|
||||||
@ -107,7 +107,7 @@ namespace sqlpp
|
|||||||
void add(Assignment&& assignment)
|
void add(Assignment&& assignment)
|
||||||
{
|
{
|
||||||
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
static_assert(is_assignment_t<typename std::decay<Assignment>::type>::value, "set() arguments require to be assigments");
|
||||||
static_assert(not ProhibitPredicate<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
|
static_assert(not must_not_insert_t<typename std::decay<Assignment>::type>::value, "set() argument must not be used in insert");
|
||||||
_dynamic_columns.emplace_back(insert_column_t<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
|
_dynamic_columns.emplace_back(insert_column_t<typename Assignment::column_type>{std::forward<typename Assignment::column_type>(assignment._lhs)});
|
||||||
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
|
_dynamic_values.emplace_back(std::forward<typename Assignment::value_type>(assignment._rhs));
|
||||||
}
|
}
|
||||||
@ -119,10 +119,10 @@ namespace sqlpp
|
|||||||
typename detail::serializable_list<Database> _dynamic_values;
|
typename detail::serializable_list<Database> _dynamic_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename Database, template<typename> class ProhibitPredicate, typename... Assignments>
|
template<typename Context, typename Database, typename... Assignments>
|
||||||
struct interpreter_t<Context, insert_list_t<Database, ProhibitPredicate, Assignments...>>
|
struct interpreter_t<Context, insert_list_t<Database, Assignments...>>
|
||||||
{
|
{
|
||||||
using T = insert_list_t<Database, ProhibitPredicate, Assignments...>;
|
using T = insert_list_t<Database, Assignments...>;
|
||||||
|
|
||||||
static Context& _(const T& t, Context& context)
|
static Context& _(const T& t, Context& context)
|
||||||
{
|
{
|
||||||
|
@ -145,13 +145,6 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
remove_t& serialize(std::ostream& os, Db& db)
|
|
||||||
{
|
|
||||||
static_cast<const remove_t*>(this)->serialize(os, db);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr size_t _get_static_no_of_parameters()
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
{
|
{
|
||||||
return _parameter_list_t::size::value;
|
return _parameter_list_t::size::value;
|
||||||
@ -170,22 +163,12 @@ namespace sqlpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db) const
|
||||||
-> prepared_remove_t<typename std::decay<Db>::type, remove_t>
|
-> prepared_remove_t<typename std::decay<Db>::type, remove_t>
|
||||||
{
|
{
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, db.prepare_remove(*this)};
|
return {{}, db.prepare_remove(*this)};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _set_parameter_index(size_t index)
|
|
||||||
{
|
|
||||||
index = set_parameter_index(_table, index);
|
|
||||||
index = set_parameter_index(_using, index);
|
|
||||||
index = set_parameter_index(_where, index);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Table _table;
|
Table _table;
|
||||||
Using _using;
|
Using _using;
|
||||||
Where _where;
|
Where _where;
|
||||||
|
@ -584,29 +584,16 @@ namespace sqlpp
|
|||||||
// Prepare
|
// Prepare
|
||||||
template<typename Db>
|
template<typename Db>
|
||||||
auto prepare(Db& db)
|
auto prepare(Db& db)
|
||||||
-> prepared_select_t<typename std::decay<Db>::type, select_t>
|
-> prepared_select_t<typename std::decay<Db>::type, select_t> const
|
||||||
{
|
{
|
||||||
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
static_assert(not is_noop<ExpressionList>::value, "cannot run select without having selected anything");
|
||||||
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
static_assert(is_from_t<From>::value, "cannot run select without a from()");
|
||||||
// FIXME: Check for missing aliases (if references are used)
|
// FIXME: Check for missing aliases (if references are used)
|
||||||
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
// FIXME: Check for missing tables, well, actually, check for missing tables at the where(), order_by(), etc.
|
||||||
|
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
return {{}, get_dynamic_names(), db.prepare_select(*this)};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _set_parameter_index(size_t index)
|
|
||||||
{
|
|
||||||
index = set_parameter_index(_expression_list, index);
|
|
||||||
index = set_parameter_index(_where, index);
|
|
||||||
index = set_parameter_index(_group_by, index);
|
|
||||||
index = set_parameter_index(_having, index);
|
|
||||||
index = set_parameter_index(_order_by, index);
|
|
||||||
index = set_parameter_index(_limit, index);
|
|
||||||
index = set_parameter_index(_offset, index);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flags _flags;
|
Flags _flags;
|
||||||
ExpressionList _expression_list;
|
ExpressionList _expression_list;
|
||||||
From _from;
|
From _from;
|
||||||
|
@ -67,7 +67,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto set(Assignment&&... assignment)
|
auto set(Assignment&&... assignment)
|
||||||
-> set_assignments_t<assignment_list_t<void, must_not_update_t, typename std::decay<Assignment>::type...>>
|
-> set_assignments_t<assignment_list_t<void, typename std::decay<Assignment>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
|
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
|
||||||
return {
|
return {
|
||||||
@ -79,7 +79,7 @@ namespace sqlpp
|
|||||||
|
|
||||||
template<typename... Assignment>
|
template<typename... Assignment>
|
||||||
auto dynamic_set(Assignment&&... assignment)
|
auto dynamic_set(Assignment&&... assignment)
|
||||||
-> set_assignments_t<assignment_list_t<Database, must_not_update_t, typename std::decay<Assignment>::type...>>
|
-> set_assignments_t<assignment_list_t<Database, typename std::decay<Assignment>::type...>>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
|
static_assert(std::is_same<Assignments, noop>::value, "cannot call set() twice");
|
||||||
return {
|
return {
|
||||||
@ -135,23 +135,6 @@ namespace sqlpp
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
const update_t& serialize(std::ostream& os, Db& db) const
|
|
||||||
{
|
|
||||||
os << "UPDATE ";
|
|
||||||
_table.serialize(os, db);
|
|
||||||
_assignments.serialize(os, db);
|
|
||||||
_where.serialize(os, db);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Db>
|
|
||||||
update_t& serialize(std::ostream& os, Db& db)
|
|
||||||
{
|
|
||||||
static_cast<const update_t*>(this)->serialize(os, db);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr size_t _get_static_no_of_parameters()
|
static constexpr size_t _get_static_no_of_parameters()
|
||||||
{
|
{
|
||||||
return _parameter_list_t::size::value;
|
return _parameter_list_t::size::value;
|
||||||
@ -176,22 +159,34 @@ namespace sqlpp
|
|||||||
{
|
{
|
||||||
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
static_assert(not is_noop<Assignments>::value, "calling set() required before running update");
|
||||||
|
|
||||||
_set_parameter_index(0);
|
|
||||||
return {{}, db.prepare_update(*this)};
|
return {{}, db.prepare_update(*this)};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t _set_parameter_index(size_t index)
|
|
||||||
{
|
|
||||||
index = set_parameter_index(_table, index);
|
|
||||||
index = set_parameter_index(_assignments, index);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
Table _table;
|
Table _table;
|
||||||
Assignments _assignments;
|
Assignments _assignments;
|
||||||
Where _where;
|
Where _where;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Context,
|
||||||
|
typename Database,
|
||||||
|
typename Table,
|
||||||
|
typename Assignments,
|
||||||
|
typename Where
|
||||||
|
>
|
||||||
|
struct interpreter_t<Context, update_t<Database, Table, Assignments, Where>>
|
||||||
|
{
|
||||||
|
using T = update_t<Database, Table, Assignments, Where>;
|
||||||
|
|
||||||
|
static Context& _(const T& t, Context& context)
|
||||||
|
{
|
||||||
|
context << "UPDATE ";
|
||||||
|
interpret(t._table, context);
|
||||||
|
interpret(t._assignments, context);
|
||||||
|
interpret(t._where, context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Table>
|
template<typename Table>
|
||||||
constexpr update_t<void, typename std::decay<Table>::type> update(Table&& table)
|
constexpr update_t<void, typename std::decay<Table>::type> update(Table&& table)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "MockDb.h"
|
#include "MockDb.h"
|
||||||
#include <sqlpp11/select.h>
|
#include <sqlpp11/select.h>
|
||||||
#include <sqlpp11/insert.h>
|
#include <sqlpp11/insert.h>
|
||||||
|
#include <sqlpp11/update.h>
|
||||||
#include <sqlpp11/functions.h>
|
#include <sqlpp11/functions.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -65,5 +66,8 @@ int main()
|
|||||||
interpret(insert_into(t).set(t.gamma = true), printer).flush();
|
interpret(insert_into(t).set(t.gamma = true), printer).flush();
|
||||||
interpret(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).flush();
|
interpret(insert_into(t).set(t.gamma = sqlpp::tvin(false)), printer).flush();
|
||||||
|
|
||||||
|
interpret(update(t), printer).flush();
|
||||||
|
interpret(update(t).set(t.gamma = true), printer).flush();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user