From 9bcc5f8a9181886f4c73ea5b4671b35d8722cb3a Mon Sep 17 00:00:00 2001 From: Carsten Stiborg Date: Wed, 11 Oct 2023 13:50:41 +0000 Subject: [PATCH] Add rowset default ctor and clear() This allows creating empty rowset objects or resetting them to the empty state later, which seems to make sense. Closes #198. Closes #1057. Closes #1086. --- include/soci/rowset.h | 19 +++++++++++++++++-- tests/common-tests.h | 15 +++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/soci/rowset.h b/include/soci/rowset.h index afd5cf3f9..63abe8f4d 100644 --- a/include/soci/rowset.h +++ b/include/soci/rowset.h @@ -113,6 +113,11 @@ class rowset_impl typedef rowset_iterator iterator; + rowset_impl() + : refs_(1), st_(nullptr), define_(nullptr) + { + } + rowset_impl(details::prepare_temp_type const & prep) : refs_(1), st_(new statement(prep)), define_(new T()) { @@ -135,8 +140,8 @@ class rowset_impl iterator begin() const { - // No ownership transfer occurs here - return iterator(*st_, *define_); + // No ownership transfer occurs here. Empty rowset doesn't have any valid begin iterator. + return st_ ? iterator(*st_, *define_) : iterator(); } iterator end() const @@ -182,6 +187,11 @@ class rowset pimpl_->incRef(); } + rowset() + : pimpl_(new details::rowset_impl()) + { + } + // Due to the existence of conversion from session to prepare_temp_type, it // would have been possible to construct a rowset from session if we didn't // delete this ctor -- so do delete it because it doesn't make sense to @@ -204,6 +214,11 @@ class rowset return *this; } + void clear() + { + *this = rowset(); + } + const_iterator begin() const { return pimpl_->begin(); diff --git a/tests/common-tests.h b/tests/common-tests.h index 9f13f40b7..9bd0773de 100644 --- a/tests/common-tests.h +++ b/tests/common-tests.h @@ -2888,7 +2888,12 @@ TEST_CASE_METHOD(common_tests, "Rowset creation and copying", "[core][rowset]") // create and populate the test table auto_table_creator tableCreator(tc_.table_creator_1(sql)); { - // Open empty rowset + // Create empty rowset + rowset rs1; + CHECK(rs1.begin() == rs1.end()); + } + { + // Load empty rowset rowset rs1 = (sql.prepare << "select * from soci_test"); CHECK(rs1.begin() == rs1.end()); } @@ -2909,7 +2914,7 @@ TEST_CASE_METHOD(common_tests, "Rowset creation and copying", "[core][rowset]") if (!tc_.has_multiple_select_bug()) { // Assignment - rowset rs1 = (sql.prepare << "select * from soci_test"); + rowset rs1; rowset rs2 = (sql.prepare << "select * from soci_test"); rowset rs3 = (sql.prepare << "select * from soci_test"); rs1 = rs2; @@ -2940,6 +2945,12 @@ TEST_CASE_METHOD(common_tests, "Rowset iteration", "[core][rowset]") CHECK(5 == std::distance(rs.begin(), rs.end())); } + { + rowset rs = (sql.prepare << "select * from soci_test"); + + rs.clear(); + CHECK(rs.begin() == rs.end()); + } } }