From 121f56549bea33c9884182a0b3f4f58f233ba98f Mon Sep 17 00:00:00 2001 From: rbock Date: Wed, 8 Jan 2014 22:14:16 +0100 Subject: [PATCH] Added prepared statement support to insert, update and remove (untested yet) --- include/sqlpp11/assignment_list.h | 9 ++++++++- include/sqlpp11/insert.h | 10 +++++----- include/sqlpp11/prepared_remove.h | 2 +- include/sqlpp11/prepared_update.h | 2 +- include/sqlpp11/remove.h | 32 +++++++++++++++++++++++++++--- include/sqlpp11/update.h | 33 ++++++++++++++++++++++++++++--- include/sqlpp11/using.h | 9 ++++++++- 7 files changed, 82 insertions(+), 15 deletions(-) diff --git a/include/sqlpp11/assignment_list.h b/include/sqlpp11/assignment_list.h index 3cf598fd..e55e8ab5 100644 --- a/include/sqlpp11/assignment_list.h +++ b/include/sqlpp11/assignment_list.h @@ -39,6 +39,7 @@ namespace sqlpp { using _is_assignment_list = std::true_type; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; // check for at least one order expression static_assert(_is_dynamic::value or sizeof...(Assignments), "at least one assignment expression required in set()"); @@ -70,7 +71,13 @@ namespace sqlpp _dynamic_assignments.serialize(os, db, sizeof...(Assignments) == 0); } - std::tuple::type...> _assignments; + size_t _set_parameter_index(size_t index) + { + index = set_parameter_index(_assignments, index); + return index; + } + + _parameter_tuple_t _assignments; typename detail::serializable_list _dynamic_assignments; }; diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index 6dd0fc8e..a2b33d4b 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -111,11 +111,6 @@ namespace sqlpp return *this; } - static constexpr size_t _get_static_no_of_parameters() - { - return _parameter_list_t::size::value; - } - template insert_t& serialize(std::ostream& os, Db& db) { @@ -123,6 +118,11 @@ namespace sqlpp return *this; } + static constexpr size_t _get_static_no_of_parameters() + { + return _parameter_list_t::size::value; + } + template std::size_t run(Db& db) const { diff --git a/include/sqlpp11/prepared_remove.h b/include/sqlpp11/prepared_remove.h index 0dcd2b30..b8adcfbe 100644 --- a/include/sqlpp11/prepared_remove.h +++ b/include/sqlpp11/prepared_remove.h @@ -33,7 +33,7 @@ namespace sqlpp { template - struct prepared_select_t + struct prepared_remove_t { using _parameter_list_t = typename Remove::_parameter_list_t; using _prepared_query_t = typename Db::_prepared_query_t; diff --git a/include/sqlpp11/prepared_update.h b/include/sqlpp11/prepared_update.h index aadb94ae..35d13d95 100644 --- a/include/sqlpp11/prepared_update.h +++ b/include/sqlpp11/prepared_update.h @@ -33,7 +33,7 @@ namespace sqlpp { template - struct prepared_select_t + struct prepared_update_t { using _parameter_list_t = typename Update::_parameter_list_t; using _prepared_query_t = typename Db::_prepared_query_t; diff --git a/include/sqlpp11/remove.h b/include/sqlpp11/remove.h index e657f87a..856145c8 100644 --- a/include/sqlpp11/remove.h +++ b/include/sqlpp11/remove.h @@ -32,6 +32,8 @@ #include #include #include +#include +#include namespace sqlpp { @@ -60,6 +62,9 @@ namespace sqlpp template using set_where_t = remove_t; + using _parameter_tuple_t = std::tuple; + using _parameter_list_t = typename make_parameter_list_t::type; + template auto using_(Tab&&... tab) -> set_using_t::type...>> @@ -147,14 +152,35 @@ namespace sqlpp return *this; } + static constexpr size_t _get_static_no_of_parameters() + { + return _parameter_list_t::size::value; + } + template std::size_t run(Db& db) const { - std::ostringstream oss; - serialize(oss, db); - return db.remove(oss.str()); + static_assert(_get_static_no_of_parameters() == 0, "cannot run remove directly with parameters, use prepare instead"); + return db.remove(*this); } + template + auto prepare(Db& db) + -> prepared_remove_t::type, remove_t> + { + _set_parameter_index(0); + 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; Using _using; Where _where; diff --git a/include/sqlpp11/update.h b/include/sqlpp11/update.h index 60cc9fec..3f245c11 100644 --- a/include/sqlpp11/update.h +++ b/include/sqlpp11/update.h @@ -32,6 +32,8 @@ #include #include #include +#include +#include namespace sqlpp { @@ -60,6 +62,9 @@ namespace sqlpp template using set_where_t = update_t; + using _parameter_tuple_t = std::tuple; + using _parameter_list_t = typename make_parameter_list_t::type; + template auto set(Assignment&&... assignment) -> set_assignments_t::type...>> @@ -147,14 +152,36 @@ namespace sqlpp return *this; } + static constexpr size_t _get_static_no_of_parameters() + { + return _parameter_list_t::size::value; + } + template std::size_t run(Db& db) const { - std::ostringstream oss; - serialize(oss, db); - return db.update(oss.str()); + static_assert(not is_noop::value, "calling set() required before running update"); + static_assert(_get_static_no_of_parameters() == 0, "cannot run update directly with parameters, use prepare instead"); + return db.update(*this); } + template + auto prepare(Db& db) + -> prepared_update_t::type, update_t> + { + static_assert(not is_noop::value, "calling set() required before running update"); + + _set_parameter_index(0); + 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; Assignments _assignments; Where _where; diff --git a/include/sqlpp11/using.h b/include/sqlpp11/using.h index 9af96bd2..8bc7f3d1 100644 --- a/include/sqlpp11/using.h +++ b/include/sqlpp11/using.h @@ -40,6 +40,7 @@ namespace sqlpp { using _is_using = std::true_type; using _is_dynamic = typename std::conditional::value, std::false_type, std::true_type>::type; + using _parameter_tuple_t = std::tuple; static_assert(_is_dynamic::value or sizeof...(Table), "at least one table argument required in using()"); @@ -68,7 +69,13 @@ namespace sqlpp _dynamic_tables.serialize(os, db, sizeof...(Table) == 0); } - std::tuple _tables; + size_t _set_parameter_index(size_t index) + { + index = set_parameter_index(_tables, index); + return index; + } + + _parameter_tuple_t _tables; detail::serializable_list _dynamic_tables; };