From 9597c3712c00bd373a69d89512e9d34f2f8b8e88 Mon Sep 17 00:00:00 2001 From: Roland Bock Date: Sun, 15 Dec 2013 13:02:41 +0100 Subject: [PATCH] Moved result construction more towards connector. This will make it easier to handle different formats --- include/sqlpp11/parameter_list.h | 31 ++++++++++--------- include/sqlpp11/prepared_select.h | 14 +++++++-- include/sqlpp11/result.h | 51 ++++++++++++++----------------- include/sqlpp11/result_row.h | 21 +++++++++++-- include/sqlpp11/select.h | 23 ++++++++++++-- tests/PreparedTest.cpp | 11 +++++-- 6 files changed, 98 insertions(+), 53 deletions(-) diff --git a/include/sqlpp11/parameter_list.h b/include/sqlpp11/parameter_list.h index 249c0391..664a4274 100644 --- a/include/sqlpp11/parameter_list.h +++ b/include/sqlpp11/parameter_list.h @@ -33,48 +33,50 @@ namespace sqlpp { template - struct named_parameter_list_t + struct parameter_list_t { - static_assert(detail::wrong::value, "Template parameter for named_parameter_list_t has to be a tuple"); + static_assert(detail::wrong::value, "Template parameter for parameter_list_t has to be a tuple"); }; template - struct named_parameter_list_t>: public Parameter::_member_t... + struct parameter_list_t>: public Parameter::_member_t... { - named_parameter_list_t(): + parameter_list_t(): Parameter::_member_t()..., _parameter_tuple(static_cast(*this)()...) {} - named_parameter_list_t(const named_parameter_list_t& rhs) + parameter_list_t(const parameter_list_t& rhs) noexcept(std::is_nothrow_copy_constructible>::value): Parameter::_member_t(static_cast(rhs))..., _parameter_tuple(static_cast(*this)()...) {} - named_parameter_list_t(named_parameter_list_t&& rhs) + parameter_list_t(parameter_list_t&& rhs) noexcept(std::is_nothrow_move_constructible>::value): Parameter::_member_t(std::move(static_cast(rhs)))..., _parameter_tuple(static_cast(*this)()...) {} - named_parameter_list_t& operator=(const named_parameter_list_t& rhs) + parameter_list_t& operator=(const parameter_list_t& rhs) noexcept(std::is_nothrow_copy_assignable>::value) { _parameter_tuple = rhs._parameter_tuple; return *this; } - named_parameter_list_t& operator=(named_parameter_list_t&& rhs) + parameter_list_t& operator=(parameter_list_t&& rhs) noexcept(std::is_nothrow_move_assignable>::value) { _parameter_tuple = std::move(rhs._parameter_tuple); return *this; } - ~named_parameter_list_t() = default; + ~parameter_list_t() = default; - std::tuple _parameter_tuple; + using parameter_tuple_t = std::tuple; + using size = std::tuple_size; + parameter_tuple_t _parameter_tuple; }; namespace detail @@ -107,11 +109,10 @@ namespace sqlpp } template - auto named_parameter_list(const Exp& exp) - -> named_parameter_list_t::type>::type> - { - return {}; - } + struct make_parameter_list_t + { + using type = parameter_list_t::type>::type>; + }; } diff --git a/include/sqlpp11/prepared_select.h b/include/sqlpp11/prepared_select.h index a93c229b..867c16fd 100644 --- a/include/sqlpp11/prepared_select.h +++ b/include/sqlpp11/prepared_select.h @@ -28,7 +28,7 @@ #define SQLPP_PREPARED_SELECT_H #include -#include +#include namespace sqlpp { @@ -37,8 +37,18 @@ namespace sqlpp { using _result_row_t = typename Select::_result_row_t; using _parameter_list_t = typename Select::_parameter_list_t; + using _dynamic_names_t = typename Select::_dynamic_names_t; + using _handle_t = typename Db::_prepared_handle_t; - typename Db::prepared_query_handle _name; + auto run(Db& db) const + -> result_t + { + return {db.run_prepared_select(_handle, params), _dynamic_names}; + } + + _parameter_list_t params; + _dynamic_names_t _dynamic_names; + _handle_t _handle; }; } diff --git a/include/sqlpp11/result.h b/include/sqlpp11/result.h index 3acf6de4..8c346f4e 100644 --- a/include/sqlpp11/result.h +++ b/include/sqlpp11/result.h @@ -33,31 +33,27 @@ namespace sqlpp { - template + template class result_t { - using db_result_t = typename Db::_result_t; + using db_result_t = DbResult; + using result_row_t = typename db_result_t::result_row_t; - db_result_t _result; - raw_result_row_t _raw_result_row; - raw_result_row_t _end; - DynamicNames _dynamic_columns; // only needed in case of dynamic columns in the select - ResultRow _result_row; + db_result_t _db_result; + result_row_t _result_row; + result_row_t _end; public: result_t(): - _raw_result_row({}), - _end({}), - _dynamic_columns(), - _result_row(_raw_result_row, _dynamic_columns) + _db_result(), + _result_row(), + _end() {} - result_t(db_result_t&& result, DynamicNames dynamic_columns): - _result(std::move(result)), - _raw_result_row(_result.next()), - _end({}), - _dynamic_columns(dynamic_columns), - _result_row(_raw_result_row, _dynamic_columns) + result_t(db_result_t&& result): + _db_result(std::move(result)), + _result_row(_db_result.next()), + _end({}) {} result_t(const result_t&) = delete; @@ -69,26 +65,26 @@ namespace sqlpp class iterator { public: - iterator(result_t& result, raw_result_row_t& raw_result_row): + iterator(result_t& result, result_row_t& result_row): _result(result), - _raw_result_row(raw_result_row) + _result_row(result_row) { //std::cerr << "result::iterator::constructor" << std::endl; } - const ResultRow& operator*() const + const result_row_t& operator*() const { return _result.front(); } - const ResultRow* operator->() const + const result_row_t* operator->() const { return &_result.front(); } bool operator==(const iterator& rhs) const { - return _raw_result_row == rhs._raw_result_row; + return _result_row == rhs._result_row; } bool operator!=(const iterator& rhs) const @@ -102,12 +98,12 @@ namespace sqlpp } result_t& _result; - raw_result_row_t& _raw_result_row; + result_row_t& _result_row; }; iterator begin() { - return iterator(*this, _raw_result_row); + return iterator(*this, _result_row); } iterator end() @@ -115,20 +111,19 @@ namespace sqlpp return iterator(*this, _end); } - const ResultRow& front() const + const result_row_t& front() const { return _result_row; } bool empty() const { - return _raw_result_row == _end; + return _result_row == _end; } void pop_front() { - _raw_result_row = _result.next(); - _result_row = _raw_result_row; + _result_row = _db_result.next(); } }; diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 827dad68..59f95d4b 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -103,21 +103,36 @@ namespace sqlpp { using _impl = detail::result_row_impl<0, 0, NamedExpr...>; bool _is_row; + raw_result_row_t _raw_result_row; + + result_row_t(): + _raw_result_row(), + _impl(_raw_result_row), + _is_row(false) + { + } template result_row_t(const raw_result_row_t& raw_result_row, const T&): - _impl(raw_result_row), - _is_row(raw_result_row.data != nullptr) + _raw_result_row(raw_result_row), + _impl(_raw_result_row), + _is_row(_raw_result_row.data != nullptr) { } result_row_t& operator=(const raw_result_row_t& raw_result_row) { _impl::operator=(raw_result_row); - _is_row = raw_result_row.data != nullptr; + _raw_result_row = raw_result_row; + _is_row = _raw_result_row.data != nullptr; return *this; } + bool operator==(const result_row_t& rhs) + { + return _raw_result_row == rhs._raw_result_row; + } + explicit operator bool() const { return _is_row; diff --git a/include/sqlpp11/select.h b/include/sqlpp11/select.h index 4f62e01e..88dfb636 100644 --- a/include/sqlpp11/select.h +++ b/include/sqlpp11/select.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -569,7 +570,21 @@ namespace sqlpp // Execute template - result_t run(Db& db) const + auto run(Db& db) const + -> result_t + { + static_assert(not is_noop::value, "cannot run select without having selected anything"); + static_assert(is_from_t::value, "cannot run select without a from()"); + static_assert(_parameter_list_t::size::value == 0, "cannot run select directly with parameters, use prepare instead"); + // 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. + + return {db.select(*this)}; + } + + /* + template + prepared_select_t run(Db& db) const { static_assert(not is_noop::value, "cannot run select without having selected anything"); static_assert(is_from_t::value, "cannot run select without a from()"); @@ -578,8 +593,9 @@ namespace sqlpp std::ostringstream oss; serialize(oss, db); - return {db.select(oss.str()), _expression_list._dynamic_expressions._dynamic_expression_names}; + return {db.prepare_select(oss.str()), _expression_list._dynamic_expressions._dynamic_expression_names}; } + */ Flags _flags; ExpressionList _expression_list; @@ -590,7 +606,8 @@ namespace sqlpp OrderBy _order_by; Limit _limit; Offset _offset; - decltype(named_parameter_list(std::declval>())) _parameter_list; + using _parameter_t = std::tuple; + using _parameter_list_t = typename make_parameter_list_t::type; }; // construct select flag list diff --git a/tests/PreparedTest.cpp b/tests/PreparedTest.cpp index ae6fc935..c83db03b 100644 --- a/tests/PreparedTest.cpp +++ b/tests/PreparedTest.cpp @@ -77,7 +77,9 @@ int main() // OK, fine, now create a named parameter list from an expression { - auto npl = named_parameter_list(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma)); + using Exp = decltype(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma)); + using T = sqlpp::make_parameter_list_t::type; + T npl; static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); @@ -89,7 +91,10 @@ int main() // Wonderful, now take a look at the parameter list of a select { - auto npl = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma))._parameter_list; + auto s = select(all_of(t)).from(t).where(t.beta.like(parameter(t.beta)) and t.alpha == parameter(t.alpha) or t.gamma != parameter(t.gamma)); + using S = decltype(s); + using T = sqlpp::make_parameter_list_t::type; + T npl; static_assert(std::is_same::value, "type requirement"); static_assert(std::is_same::value, "type requirement"); @@ -102,6 +107,8 @@ int main() auto x = npl; x = npl; std::cerr << x.alpha << std::endl; + x = decltype(npl)(); + std::cerr << x.alpha << std::endl; }