From fa18ce5476b14e4d1684eebdd4a0822aab568397 Mon Sep 17 00:00:00 2001 From: rbock Date: Mon, 13 Jan 2014 23:05:48 +0100 Subject: [PATCH] interpret works for insert now Also added explicit .default_values() method --- include/sqlpp11/column.h | 9 ++- include/sqlpp11/insert.h | 64 ++++++++++----------- include/sqlpp11/insert_list.h | 105 ++++++++++++++++++++-------------- tests/InterpretTest.cpp | 5 ++ 4 files changed, 100 insertions(+), 83 deletions(-) diff --git a/include/sqlpp11/column.h b/include/sqlpp11/column.h index b1b98791..033108bb 100644 --- a/include/sqlpp11/column.h +++ b/include/sqlpp11/column.h @@ -59,11 +59,10 @@ namespace sqlpp column_t& operator=(column_t&&) = default; ~column_t() = default; - template - void serialize_name(std::ostream& os, Db& db) const - { - os << _name_t::_get_name(); - } + static constexpr const char* _get_name() + { + return _name_t::_get_name(); + } template expression_alias_t::type> as(alias_provider&&) const diff --git a/include/sqlpp11/insert.h b/include/sqlpp11/insert.h index a616fd0a..45dca769 100644 --- a/include/sqlpp11/insert.h +++ b/include/sqlpp11/insert.h @@ -39,6 +39,7 @@ namespace sqlpp { + template< typename Database = void, typename Table = noop, @@ -58,15 +59,27 @@ namespace sqlpp template using set_insert_list_t = insert_t; + using use_default_values_t = insert_t; using _parameter_tuple_t = std::tuple; using _parameter_list_t = typename make_parameter_list_t::type; + auto default_values() + -> use_default_values_t + { + static_assert(std::is_same::value, "cannot call default_values() after set() or default_values()"); + // FIXME: Need to check if all required columns are set + return { + _table, + {}, + }; + } + template auto set(Assignment&&... assignment) -> set_insert_list_t::type...>> { - static_assert(std::is_same::value, "cannot call set() twice"); + static_assert(std::is_same::value, "cannot call set() after set() or default_values()"); // FIXME: Need to check if all required columns are set return { _table, @@ -78,7 +91,7 @@ namespace sqlpp auto dynamic_set(Assignment&&... assignment) -> set_insert_list_t::type...>> { - static_assert(std::is_same::value, "cannot call set() twice"); + static_assert(std::is_same::value, "cannot call set() after set() or default_values()"); return { _table, insert_list_t::type...>{std::forward(assignment)...}, @@ -95,29 +108,6 @@ namespace sqlpp return *this; } - template - const insert_t& serialize(std::ostream& os, Db& db) const - { - os << "INSERT INTO "; - _table.serialize(os, db); - if (is_noop::value) - { - detail::serialize_empty_insert_list(os, db); - } - else - { - _insert_list.serialize(os, db); - } - return *this; - } - - template - insert_t& serialize(std::ostream& os, Db& db) - { - static_cast(this)->serialize(os, db); - return *this; - } - static constexpr size_t _get_static_no_of_parameters() { return _parameter_list_t::size::value; @@ -131,6 +121,7 @@ namespace sqlpp template std::size_t run(Db& db) const { + // FIXME: check if set or default_values() has ben called constexpr bool calledSet = not is_noop::value; constexpr bool requireSet = Table::_required_insert_columns::size::value > 0; static_assert(calledSet or not requireSet, "calling set() required for given table"); @@ -146,22 +137,27 @@ namespace sqlpp constexpr bool requireSet = Table::_required_insert_columns::size::value > 0; static_assert(calledSet or not requireSet, "calling set() required for given table"); - _set_parameter_index(0); return {{}, db.prepare_insert(*this)}; } - size_t _set_parameter_index(size_t index) - { - index = set_parameter_index(_table, index); - index = set_parameter_index(_insert_list, index); - return index; - } - - Table _table; InsertList _insert_list; }; + template + struct interpreter_t> + { + using T = insert_t; + + static Context& _(const T& t, Context& context) + { + context << "INSERT INTO "; + interpret(t._table, context); + interpret(t._insert_list, context); + return context; + } + }; + template insert_t::type> insert_into(Table&& table) { diff --git a/include/sqlpp11/insert_list.h b/include/sqlpp11/insert_list.h index d19bc892..2078ec6b 100644 --- a/include/sqlpp11/insert_list.h +++ b/include/sqlpp11/insert_list.h @@ -34,30 +34,43 @@ namespace sqlpp { - namespace detail + struct insert_default_values_t { - template - void serialize_empty_insert_list(std::ostream& os, const Db& db) - { + using _is_insert_list = std::true_type; + using _is_dynamic = std::false_type; + }; - if (connector_has_empty_list_insert_t::type>::value) - os << " () VALUES()"; - else - os << " DEFAULT VALUES"; + template + struct interpreter_t + { + using T = insert_default_values_t; + + static Context& _(const T& t, Context& context) + { + context << " DEFAULT VALUES"; + return context; } + }; template - struct insert_column + struct insert_column_t { - template - void serialize(std::ostream& os, Db& db) const - { - _column.serialize_name(os, db); - } - Column _column; }; - } + + template + struct interpreter_t> + { + using T = insert_column_t; + + static Context& _(const T& t, Context& context) + { + context << t._column._get_name(); + return context; + } + }; + + template class ProhibitPredicate, typename... Assignments> struct insert_list_t { @@ -95,43 +108,47 @@ namespace sqlpp { static_assert(is_assignment_t::type>::value, "set() arguments require to be assigments"); static_assert(not ProhibitPredicate::type>::value, "set() argument must not be used in insert"); - _dynamic_columns.emplace_back(detail::insert_column{std::forward(assignment._lhs)}); + _dynamic_columns.emplace_back(insert_column_t{std::forward(assignment._lhs)}); _dynamic_values.emplace_back(std::forward(assignment._rhs)); } - template - void serialize(std::ostream& os, Db& db) const - { - if (sizeof...(Assignments) + _dynamic_columns.size() == 0) - { - detail::serialize_empty_insert_list(os, db); - } - else - { - constexpr bool first = sizeof...(Assignments) == 0; - os << " ("; - detail::serialize_tuple(os, db, _columns, ','); - _dynamic_columns.serialize(os, db, first); - os << ") VALUES ("; - detail::serialize_tuple(os, db, _values, ','); - _dynamic_values.serialize(os, db, first); - os << ")"; - } - } - - size_t _set_parameter_index(size_t index) - { - index = set_parameter_index(_values, index); - return index; - } - - std::tuple...> _columns; + std::tuple...> _columns; _parameter_tuple_t _values; typename detail::serializable_list _dynamic_columns; typename detail::serializable_list _dynamic_values; }; + template class ProhibitPredicate, typename... Assignments> + struct interpreter_t> + { + using T = insert_list_t; + + static Context& _(const T& t, Context& context) + { + if (sizeof...(Assignments) + t._dynamic_columns.size() == 0) + { + interpret(insert_default_values_t(), context); + } + else + { + context << " ("; + interpret_tuple(t._columns, ",", context); + if (sizeof...(Assignments) and not t._dynamic_columns.empty()) + context << ','; + interpret_serializable_list(t._dynamic_columns, ',', context); + context << ") VALUES("; + interpret_tuple(t._values, ",", context); + if (sizeof...(Assignments) and not t._dynamic_values.empty()) + context << ','; + interpret_serializable_list(t._dynamic_values, ',', context); + context << ")"; + } + return context; + } + }; + + } #endif diff --git a/tests/InterpretTest.cpp b/tests/InterpretTest.cpp index 75a25122..25035371 100644 --- a/tests/InterpretTest.cpp +++ b/tests/InterpretTest.cpp @@ -26,6 +26,7 @@ #include "TabSample.h" #include "MockDb.h" #include +#include #include #include @@ -54,5 +55,9 @@ int main() interpret(parameter(t.alpha), printer).flush(); interpret(t.alpha == parameter(t.alpha), printer).flush(); + interpret(insert_into(t), printer).flush(); + interpret(insert_into(t).default_values(), printer).flush(); + interpret(insert_into(t).set(t.gamma = true), printer).flush(); + return 0; }