diff --git a/include/sqlpp11/detail/column_index_sequence.h b/include/sqlpp11/detail/column_index_sequence.h deleted file mode 100644 index 0db26d01..00000000 --- a/include/sqlpp11/detail/column_index_sequence.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2013-2014, Roland Bock - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SQLPP_DETAIL_COLUMN_INDEX_SEQUENCE_H -#define SQLPP_DETAIL_COLUMN_INDEX_SEQUENCE_H - -#include - -namespace sqlpp -{ - namespace detail - { - template - struct column_index_sequence - { - static constexpr std::size_t last_index = LastIndex; - }; - - template - struct make_column_index_sequence_impl; - - template - struct make_column_index_sequence_impl, Column, Rest...> - { - using type = typename make_column_index_sequence_impl, Rest...>::type; - }; - - template - struct make_column_index_sequence_impl, multi_field_spec_t, Rest...> - { - using type = typename make_column_index_sequence_impl, Rest...>::type; - }; - - template - struct make_column_index_sequence_impl> - { - using type = column_index_sequence; - }; - - template - using make_column_index_sequence = typename make_column_index_sequence_impl, Fields...>::type; - - } -} - - -#endif diff --git a/include/sqlpp11/detail/field_index_sequence.h b/include/sqlpp11/detail/field_index_sequence.h new file mode 100644 index 00000000..22e82318 --- /dev/null +++ b/include/sqlpp11/detail/field_index_sequence.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013-2014, Roland Bock + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLPP_DETAIL_FIELD_INDEX_SEQUENCE_H +#define SQLPP_DETAIL_FIELD_INDEX_SEQUENCE_H + +#include +#include + +namespace sqlpp +{ + namespace detail + { + template + struct field_index_sequence + { + static constexpr std::size_t _next_index = NextIndex; + }; + + template + struct make_field_index_sequence_impl + { + static_assert(wrong_t::value, "invalid field index sequence arguments"); + }; + + template + struct make_field_index_sequence_impl, field_spec_t, Rest...> + { + using type = typename make_field_index_sequence_impl, Rest...>::type; + }; + + template + struct make_field_index_sequence_impl, multi_field_spec_t, Rest...> + { + using type = typename make_field_index_sequence_impl::value, Ints..., NextIndex>, Rest...>::type; + }; + + template + struct make_field_index_sequence_impl> + { + using type = field_index_sequence; + }; + + template + using make_field_index_sequence = typename make_field_index_sequence_impl, Fields...>::type; + + } +} + + +#endif diff --git a/include/sqlpp11/result_row.h b/include/sqlpp11/result_row.h index 676a8eef..2132390e 100644 --- a/include/sqlpp11/result_row.h +++ b/include/sqlpp11/result_row.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include namespace sqlpp { @@ -66,9 +66,9 @@ namespace sqlpp template struct result_field>>: - public AliasProvider::_name_t::template _member_t, FieldSpecs...>> + public AliasProvider::_name_t::template _member_t, FieldSpecs...>> { - using _multi_field = typename AliasProvider::_name_t::template _member_t, FieldSpecs...>>; + using _multi_field = typename AliasProvider::_name_t::template _member_t, FieldSpecs...>>; result_field() = default; @@ -89,12 +89,10 @@ namespace sqlpp } }; - template - struct result_row_impl, FieldSpecs...>: + template + struct result_row_impl, FieldSpecs...>: public result_field... { - static constexpr std::size_t _last_index = LastIndex; - result_row_impl() = default; void _validate() @@ -120,11 +118,11 @@ namespace sqlpp } template - struct result_row_t: public detail::result_row_impl, FieldSpecs...> + struct result_row_t: public detail::result_row_impl, FieldSpecs...> { - using _impl = detail::result_row_impl, FieldSpecs...>; + using _field_index_sequence = detail::make_field_index_sequence<0, FieldSpecs...>; + using _impl = detail::result_row_impl; bool _is_valid; - static constexpr size_t _last_static_index = _impl::_last_index; result_row_t(): _impl(), @@ -168,7 +166,7 @@ namespace sqlpp static constexpr size_t static_size() { - return _last_static_index; + return _field_index_sequence::_next_index; } template @@ -179,9 +177,10 @@ namespace sqlpp }; template - struct dynamic_result_row_t: public detail::result_row_impl, FieldSpecs...> + struct dynamic_result_row_t: public detail::result_row_impl, FieldSpecs...> { - using _impl = detail::result_row_impl, FieldSpecs...>; + using _field_index_sequence = detail::make_field_index_sequence<0, FieldSpecs...>; + using _impl = detail::result_row_impl; struct _field_spec_t { using _traits = make_traits; @@ -190,10 +189,9 @@ namespace sqlpp struct _name_t {}; }; using _field_type = result_field_t; - static constexpr size_t _last_static_index = _impl::_last_index; bool _is_valid; - std::vector _dynamic_columns; + std::vector _dynamic_field_names; std::map _dynamic_fields; dynamic_result_row_t(): @@ -202,12 +200,12 @@ namespace sqlpp { } - dynamic_result_row_t(const std::vector& dynamic_columns): + dynamic_result_row_t(const std::vector& dynamic_field_names): _impl(), _is_valid(false), - _dynamic_columns(dynamic_columns) + _dynamic_field_names(dynamic_field_names) { - for (auto name : _dynamic_columns) + for (auto name : _dynamic_field_names) { _dynamic_fields.insert({name, _field_type{}}); } @@ -259,10 +257,11 @@ namespace sqlpp { _impl::_bind(target); - std::size_t index = _last_static_index; - for (const auto& name : _dynamic_columns) + std::size_t index = _field_index_sequence::_next_index; + for (const auto& name : _dynamic_field_names) { - _dynamic_fields.at(name)._bind(target, ++index); + _dynamic_fields.at(name)._bind(target, index); + ++index; } } }; diff --git a/tests/SelectTypeTest.cpp b/tests/SelectTypeTest.cpp index f709947a..6a8f931e 100644 --- a/tests/SelectTypeTest.cpp +++ b/tests/SelectTypeTest.cpp @@ -270,7 +270,7 @@ int main() static_assert(sqlpp::is_regular::value, "type requirement"); } - // Test that select(all_of(tab)) is expanded in select + // Test that all_of(tab) is expanded in select { auto a = select(all_of(t)); auto b = select(t.alpha, t.beta, t.gamma, t.delta); @@ -279,7 +279,7 @@ int main() //static_assert(std::is_same::value, "t has to be expanded by select()"); } - // Test that select(all_of(tab)) is expanded in multi_column + // Test that all_of(tab) is expanded in multi_column { auto a = multi_column(all_of(t)).as(alias::a); auto b = multi_column(t.alpha, t.beta, t.gamma, t.delta).as(alias::a); @@ -292,6 +292,19 @@ int main() static_assert(not sqlpp::is_expression_t::value, "a multi_column is not a value"); } + // Test result field indices + { + using Select = decltype(select( + all_of(t), // index 0, 1, 2, 3 (alpha, beta, gamma, delta) + multi_column(all_of(t)).as(alias::left), // index 4 (including 4, 5, 6, 7) + multi_column(all_of(t)).as(alias::right), // index 8 (including 8, 9, 10, 11) + t.alpha.as(alias::a) // index 12 + ).from(t).where(true)); // next index is 13 + using ResultRow = typename Select::_result_methods_t::template _result_row_t; + using IndexSequence = ResultRow::_field_index_sequence; + static_assert(std::is_same>::value, "invalid field sequence"); + } + // Test that result sets with identical name/value combinations have identical types { auto a = select(t.alpha);