Skip to content

Commit c787630

Browse files
olegendovadz
authored andcommitted
Make session and connection_parameters movable
Implement move constructors for these classes and add unit tests for them. See SOCI#1098.
1 parent c8c323f commit c787630

File tree

5 files changed

+143
-0
lines changed

5 files changed

+143
-0
lines changed

include/soci/connection-parameters.h

+4
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class SOCI_DECL connection_parameters
3939
explicit connection_parameters(std::string const & fullConnectString);
4040

4141
connection_parameters(connection_parameters const& other);
42+
connection_parameters(connection_parameters && other);
4243
connection_parameters& operator=(connection_parameters const& other);
44+
connection_parameters& operator=(connection_parameters && other);
4345

4446
~connection_parameters();
4547

@@ -77,6 +79,8 @@ class SOCI_DECL connection_parameters
7779
}
7880

7981
private:
82+
void reset_after_move();
83+
8084
// The backend and connection string specified in our ctor.
8185
backend_factory const * factory_;
8286
std::string connectString_;

include/soci/session.h

+5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class SOCI_DECL session
5555
explicit session(std::string const & connectString);
5656
explicit session(connection_pool & pool);
5757

58+
session(session &&other);
59+
session &operator=(session &&other);
60+
5861
~session();
5962

6063
void open(connection_parameters const & parameters);
@@ -191,6 +194,8 @@ class SOCI_DECL session
191194
private:
192195
SOCI_NOT_COPYABLE(session)
193196

197+
void reset_after_move();
198+
194199
std::ostringstream query_stream_;
195200
std::unique_ptr<details::query_transformation_function> query_transformation_;
196201

src/core/connection-parameters.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ connection_parameters::connection_parameters(connection_parameters const& other)
119119
backendRef_->inc_ref();
120120
}
121121

122+
connection_parameters::connection_parameters(connection_parameters && other)
123+
: factory_(std::move(other.factory_)),
124+
connectString_(std::move(other.connectString_)),
125+
backendRef_(std::move(other.backendRef_)),
126+
options_(std::move(other.options_))
127+
{
128+
other.reset_after_move();
129+
}
130+
122131
connection_parameters& connection_parameters::operator=(connection_parameters const& other)
123132
{
124133
// Order is important in case of self-assignment.
@@ -135,10 +144,31 @@ connection_parameters& connection_parameters::operator=(connection_parameters co
135144
return *this;
136145
}
137146

147+
connection_parameters& connection_parameters::operator=(connection_parameters && other)
148+
{
149+
if (backendRef_ && backendRef_ != other.backendRef_)
150+
backendRef_->dec_ref();
151+
152+
factory_ = std::move (other.factory_);
153+
connectString_ = std::move(other.connectString_);
154+
backendRef_ = std::move(other.backendRef_);
155+
options_ = std::move(other.options_);
156+
157+
other.reset_after_move();
158+
159+
return *this;
160+
}
161+
138162
connection_parameters::~connection_parameters()
139163
{
140164
if (backendRef_)
141165
backendRef_->dec_ref();
142166
}
143167

168+
void connection_parameters::reset_after_move()
169+
{
170+
factory_ = nullptr;
171+
backendRef_ = nullptr;
172+
}
173+
144174
} // namespace soci

src/core/session.cpp

+73
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,79 @@ session::session(connection_pool & pool)
134134
backEnd_ = pooledSession.get_backend();
135135
}
136136

137+
session::session(session && other)
138+
: once(std::move(other.once)),
139+
prepare(std::move(other.prepare)),
140+
query_stream_(std::move(other.query_stream_)),
141+
query_transformation_(std::move(other.query_transformation_)),
142+
logger_(std::move(other.logger_)),
143+
lastConnectParameters_(std::move(other.lastConnectParameters_)),
144+
uppercaseColumnNames_(std::move(other.uppercaseColumnNames_)),
145+
backEnd_(std::move(other.backEnd_)),
146+
gotData_(std::move(other.gotData_)),
147+
isFromPool_(std::move(other.isFromPool_)),
148+
poolPosition_(std::move(other.poolPosition_)),
149+
pool_(std::move(other.pool_))
150+
{
151+
if (!isFromPool_)
152+
{
153+
// If 'other' session was from a pool, 'once' and 'prepare'
154+
// will have been already setup to point at the pooled session above.
155+
// Otherwise reset them to reference 'this'.
156+
once.set_session(this);
157+
prepare.set_session(this);
158+
}
159+
160+
other.reset_after_move ();
161+
}
162+
163+
session& session::operator=(session && other)
164+
{
165+
if (this != &other)
166+
{
167+
if (isFromPool_)
168+
{
169+
pool_->give_back(poolPosition_);
170+
}
171+
else if (backEnd_ != other.backEnd_)
172+
{
173+
delete backEnd_;
174+
}
175+
176+
if (other.isFromPool_)
177+
{
178+
// If 'other' session was from a pool, 'once' and 'prepare'
179+
// will have been already setup reference the pooled session above.
180+
// Otherwise leave them alone and let them continue referencing 'this'.
181+
once = std::move(other.once);
182+
prepare = std::move(other.prepare);
183+
}
184+
185+
query_stream_ = std::move(other.query_stream_);
186+
query_transformation_ = std::move(other.query_transformation_);
187+
logger_ = std::move(other.logger_);
188+
lastConnectParameters_ = std::move(other.lastConnectParameters_);
189+
uppercaseColumnNames_ = std::move(other.uppercaseColumnNames_);
190+
backEnd_ = std::move(other.backEnd_);
191+
gotData_ = std::move(other.gotData_);
192+
isFromPool_ = std::move(other.isFromPool_);
193+
poolPosition_ = std::move(other.poolPosition_);
194+
pool_ = std::move(other.pool_);
195+
196+
other.reset_after_move();
197+
}
198+
199+
return *this;
200+
}
201+
202+
void session::reset_after_move()
203+
{
204+
isFromPool_ = false;
205+
pool_ = nullptr;
206+
backEnd_ = nullptr;
207+
pool_ = nullptr;
208+
}
209+
137210
session::~session()
138211
{
139212
if (isFromPool_)

tests/common-tests.h

+31
Original file line numberDiff line numberDiff line change
@@ -4319,6 +4319,37 @@ TEST_CASE_METHOD(common_tests, "Connection and reconnection", "[core][connect]")
43194319
}
43204320
}
43214321

4322+
{
4323+
// check move semantics of session
4324+
4325+
#if __GNUC__ >= 13 || defined (__clang__)
4326+
SOCI_GCC_WARNING_SUPPRESS(self-move)
4327+
#endif
4328+
4329+
soci::session sql_0;
4330+
soci::session sql_1 = std::move(sql_0);
4331+
4332+
CHECK(!sql_0.is_connected());
4333+
CHECK(!sql_1.is_connected());
4334+
4335+
sql_0.open(backEndFactory_, connectString_);
4336+
CHECK(sql_0.is_connected());
4337+
CHECK(sql_0.get_backend());
4338+
4339+
sql_1 = std::move(sql_0);
4340+
CHECK(!sql_0.is_connected());
4341+
CHECK(!sql_0.get_backend());
4342+
CHECK(sql_1.is_connected());
4343+
CHECK(sql_1.get_backend());
4344+
4345+
sql_1 = std::move(sql_1);
4346+
CHECK(sql_1.is_connected());
4347+
CHECK(sql_1.get_backend());
4348+
4349+
#if __GNUC__ >= 13 || defined (__clang__)
4350+
SOCI_GCC_WARNING_RESTORE(self-move)
4351+
#endif
4352+
}
43224353
}
43234354

43244355
#ifdef SOCI_HAVE_BOOST

0 commit comments

Comments
 (0)