aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-11-09 18:14:37 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-11-09 18:14:37 +0200
commit476f21938f75553d6bff5e8780b537f7182c5675 (patch)
tree27bc4afb2c6a8a673dee0eebeedcf4d7090b5437
parent56a8e716a30df1c894e6ccfa16c4a0bfb43baa9c (diff)
Make database class move-constructible
This means it can be returned by value from a function in C++11.
-rw-r--r--odb/oracle/auto-handle.hxx20
-rw-r--r--odb/oracle/connection-factory.cxx56
-rw-r--r--odb/oracle/connection-factory.hxx39
-rw-r--r--odb/oracle/connection.cxx48
-rw-r--r--odb/oracle/connection.hxx39
-rw-r--r--odb/oracle/connection.ixx6
-rw-r--r--odb/oracle/database.hxx9
-rw-r--r--odb/oracle/database.ixx22
8 files changed, 144 insertions, 95 deletions
diff --git a/odb/oracle/auto-handle.hxx b/odb/oracle/auto-handle.hxx
index cdbda4f..f764fe2 100644
--- a/odb/oracle/auto-handle.hxx
+++ b/odb/oracle/auto-handle.hxx
@@ -7,6 +7,8 @@
#include <odb/pre.hxx>
+#include <odb/details/config.hxx> // ODB_CXX11
+
#include <odb/oracle/version.hxx>
#include <odb/oracle/oracle-fwd.hxx>
@@ -125,6 +127,16 @@ namespace odb
h_ = h;
}
+#ifdef ODB_CXX11
+ auto_handle (auto_handle&& ah): h_ (ah.release ()) {}
+ auto_handle& operator= (auto_handle&& ah)
+ {
+ if (this != &ah)
+ reset (ah.release ());
+ return *this;
+ }
+#endif
+
private:
auto_handle (const auto_handle&);
auto_handle& operator= (const auto_handle&);
@@ -198,6 +210,10 @@ namespace odb
}
private:
+ auto_handle (const auto_handle&);
+ auto_handle& operator= (const auto_handle&);
+
+ private:
OCISvcCtx* h_;
OCIError* e_;
};
@@ -259,6 +275,10 @@ namespace odb
}
private:
+ auto_handle (const auto_handle&);
+ auto_handle& operator= (const auto_handle&);
+
+ private:
OCIStmt* h_;
ub4 release_mode_;
OCIError* e_;
diff --git a/odb/oracle/connection-factory.cxx b/odb/oracle/connection-factory.cxx
index 4658a22..17bb68f 100644
--- a/odb/oracle/connection-factory.cxx
+++ b/odb/oracle/connection-factory.cxx
@@ -15,39 +15,20 @@ namespace odb
namespace oracle
{
- //
- // connection_factory
- //
-
- connection_factory::
- ~connection_factory ()
- {
- }
-
- //
// new_connection_factory
//
-
connection_ptr new_connection_factory::
connect ()
{
- return connection_ptr (new (shared) connection (*db_));
+ return connection_ptr (new (shared) connection (*this));
}
- void new_connection_factory::
- database (database_type& db)
- {
- db_ = &db;
- }
-
- //
// connection_pool_factory
//
-
connection_pool_factory::pooled_connection_ptr connection_pool_factory::
create ()
{
- return pooled_connection_ptr (new (shared) pooled_connection (*db_));
+ return pooled_connection_ptr (new (shared) pooled_connection (*this));
}
connection_pool_factory::
@@ -79,7 +60,7 @@ namespace odb
shared_ptr<pooled_connection> c (connections_.back ());
connections_.pop_back ();
- c->pool_ = this;
+ c->callback_ = &c->cb_;
in_use_++;
return c;
}
@@ -89,7 +70,7 @@ namespace odb
if (max_ == 0 || in_use_ < max_)
{
shared_ptr<pooled_connection> c (create ());
- c->pool_ = this;
+ c->callback_ = &c->cb_;
in_use_++;
return c;
}
@@ -105,7 +86,12 @@ namespace odb
void connection_pool_factory::
database (database_type& db)
{
- db_ = &db;
+ bool first (db_ == 0);
+
+ connection_factory::database (db);
+
+ if (!first)
+ return;
if (min_ > 0)
{
@@ -119,7 +105,7 @@ namespace odb
bool connection_pool_factory::
release (pooled_connection* c)
{
- c->pool_ = 0;
+ c->callback_ = 0;
lock l (mutex_);
@@ -149,28 +135,26 @@ namespace odb
//
connection_pool_factory::pooled_connection::
- pooled_connection (database_type& db)
- : connection (db), pool_ (0)
+ pooled_connection (connection_pool_factory& f)
+ : connection (f)
{
- callback_.arg = this;
- callback_.zero_counter = &zero_counter;
- shared_base::callback_ = &callback_;
+ cb_.arg = this;
+ cb_.zero_counter = &zero_counter;
}
connection_pool_factory::pooled_connection::
- pooled_connection (database_type& db, OCISvcCtx* handle)
- : connection (db, handle), pool_ (0)
+ pooled_connection (connection_pool_factory& f, OCISvcCtx* handle)
+ : connection (f, handle)
{
- callback_.arg = this;
- callback_.zero_counter = &zero_counter;
- shared_base::callback_ = &callback_;
+ cb_.arg = this;
+ cb_.zero_counter = &zero_counter;
}
bool connection_pool_factory::pooled_connection::
zero_counter (void* arg)
{
pooled_connection* c (static_cast<pooled_connection*> (arg));
- return c->pool_ ? c->pool_->release (c) : true;
+ return static_cast<connection_pool_factory&> (c->factory_).release (c);
}
}
}
diff --git a/odb/oracle/connection-factory.hxx b/odb/oracle/connection-factory.hxx
index aa8ed5b..67d18b1 100644
--- a/odb/oracle/connection-factory.hxx
+++ b/odb/oracle/connection-factory.hxx
@@ -25,42 +25,17 @@ namespace odb
{
namespace oracle
{
- class LIBODB_ORACLE_EXPORT connection_factory
- {
- public:
- virtual connection_ptr
- connect () = 0;
-
- public:
- typedef oracle::database database_type;
-
- virtual void
- database (database_type&) = 0;
-
- virtual
- ~connection_factory ();
- };
-
class LIBODB_ORACLE_EXPORT new_connection_factory: public connection_factory
{
public:
- new_connection_factory ()
- : db_ (0)
- {
- }
+ new_connection_factory () {}
virtual connection_ptr
connect ();
- virtual void
- database (database_type&);
-
private:
new_connection_factory (const new_connection_factory&);
new_connection_factory& operator= (const new_connection_factory&);
-
- private:
- database_type* db_;
};
class LIBODB_ORACLE_EXPORT connection_pool_factory:
@@ -86,7 +61,6 @@ namespace odb
min_ (min_connections),
in_use_ (0),
waiters_ (0),
- db_ (0),
cond_ (mutex_)
{
// max_connections == 0 means unlimited.
@@ -111,8 +85,8 @@ namespace odb
class LIBODB_ORACLE_EXPORT pooled_connection: public connection
{
public:
- pooled_connection (database_type&);
- pooled_connection (database_type&, OCISvcCtx*);
+ pooled_connection (connection_pool_factory&);
+ pooled_connection (connection_pool_factory&, OCISvcCtx*);
private:
static bool
@@ -121,11 +95,7 @@ namespace odb
private:
friend class connection_pool_factory;
- shared_base::refcount_callback callback_;
-
- // NULL pool value indicates that the connection is not in use.
- //
- connection_pool_factory* pool_;
+ shared_base::refcount_callback cb_;
};
friend class pooled_connection;
@@ -152,7 +122,6 @@ namespace odb
std::size_t in_use_; // Number of connections currently in use.
std::size_t waiters_; // Number of threads waiting for a connection.
- database_type* db_;
connections connections_;
details::mutex mutex_;
diff --git a/odb/oracle/connection.cxx b/odb/oracle/connection.cxx
index bb06121..79f35c0 100644
--- a/odb/oracle/connection.cxx
+++ b/odb/oracle/connection.cxx
@@ -22,18 +22,19 @@ namespace odb
namespace oracle
{
connection::
- connection (database_type& db)
- : odb::connection (db),
- db_ (db),
+ connection (connection_factory& cf)
+ : odb::connection (cf),
failed_ (false),
statement_cache_ (new statement_cache_type (*this)),
lob_buffer_ (0)
{
sword r (0);
+ database_type& db (database ());
+
{
OCIError* e (0);
- r = OCIHandleAlloc (db_.environment (),
+ r = OCIHandleAlloc (db.environment (),
reinterpret_cast<void**> (&e),
OCI_HTYPE_ERROR,
0,
@@ -48,7 +49,7 @@ namespace odb
auto_handle<OCIAuthInfo> auth_info;
{
OCIAuthInfo* a (0);
- r = OCIHandleAlloc (db_.environment (),
+ r = OCIHandleAlloc (db.environment (),
reinterpret_cast<void**> (&a),
OCI_HTYPE_AUTHINFO,
0,
@@ -63,8 +64,8 @@ namespace odb
r = OCIAttrSet (
auth_info,
OCI_HTYPE_AUTHINFO,
- reinterpret_cast<OraText*> (const_cast<char*> (db_.user ().c_str ())),
- static_cast <ub4> (db_.user ().size ()),
+ reinterpret_cast<OraText*> (const_cast<char*> (db.user ().c_str ())),
+ static_cast <ub4> (db.user ().size ()),
OCI_ATTR_USERNAME,
error_);
@@ -75,8 +76,8 @@ namespace odb
auth_info,
OCI_HTYPE_AUTHINFO,
reinterpret_cast<OraText*> (
- const_cast<char*> (db_.password ().c_str ())),
- static_cast<ub4> (db_.password ().size ()),
+ const_cast<char*> (db.password ().c_str ())),
+ static_cast<ub4> (db.password ().size ()),
OCI_ATTR_PASSWORD,
error_);
@@ -87,12 +88,12 @@ namespace odb
OCISvcCtx* s (0);
r = OCISessionGet (
- db_.environment (),
+ db.environment (),
error_,
&s,
auth_info,
- reinterpret_cast<OraText*> (const_cast<char*> (db_.db ().c_str ())),
- static_cast<ub4> (db_.db ().size ()),
+ reinterpret_cast<OraText*> (const_cast<char*> (db.db ().c_str ())),
+ static_cast<ub4> (db.db ().size ()),
0,
0,
0,
@@ -108,18 +109,19 @@ namespace odb
}
connection::
- connection (database_type& db, OCISvcCtx* handle)
- : odb::connection (db),
- db_ (db),
+ connection (connection_factory& cf, OCISvcCtx* handle)
+ : odb::connection (cf),
failed_ (false),
statement_cache_ (new statement_cache_type (*this)),
lob_buffer_ (0)
{
sword r (0);
+ database_type& db (database ());
+
{
OCIError* e (0);
- r = OCIHandleAlloc (db_.environment (),
+ r = OCIHandleAlloc (db.environment (),
reinterpret_cast<void**> (&e),
OCI_HTYPE_ERROR,
0,
@@ -156,5 +158,19 @@ namespace odb
generic_statement st (*this, string (s, n));
return st.execute ();
}
+
+ // connection_factory
+ //
+ connection_factory::
+ ~connection_factory ()
+ {
+ }
+
+ void connection_factory::
+ database (database_type& db)
+ {
+ odb::connection_factory::db_ = &db;
+ db_ = &db;
+ }
}
}
diff --git a/odb/oracle/connection.hxx b/odb/oracle/connection.hxx
index 40a8ddd..e8bcdae 100644
--- a/odb/oracle/connection.hxx
+++ b/odb/oracle/connection.hxx
@@ -28,6 +28,7 @@ namespace odb
namespace oracle
{
class statement_cache;
+ class connection_factory;
class connection;
typedef details::shared_ptr<connection> connection_ptr;
@@ -41,14 +42,11 @@ namespace odb
virtual
~connection ();
- connection (database_type&);
- connection (database_type&, OCISvcCtx* handle);
+ connection (connection_factory&);
+ connection (connection_factory&, OCISvcCtx* handle);
database_type&
- database ()
- {
- return db_;
- }
+ database ();
public:
virtual transaction_impl*
@@ -144,8 +142,6 @@ namespace odb
friend class transaction_impl; // invalidate_results()
private:
- database_type& db_;
-
// It is important that the error_ member is declared before the
// handle_ member as handle_ depends on error_ during destruction.
//
@@ -157,6 +153,33 @@ namespace odb
details::unique_ptr<statement_cache_type> statement_cache_;
details::buffer lob_buffer_;
};
+
+ class LIBODB_ORACLE_EXPORT connection_factory:
+ public odb::connection_factory
+ {
+ public:
+ typedef oracle::database database_type;
+
+ virtual void
+ database (database_type&);
+
+ database_type&
+ database () {return *db_;}
+
+ virtual connection_ptr
+ connect () = 0;
+
+ virtual
+ ~connection_factory ();
+
+ connection_factory (): db_ (0) {}
+
+ // Needed to break the circular connection_factory-database dependency
+ // (odb::connection_factory has the odb::database member).
+ //
+ protected:
+ database_type* db_;
+ };
}
}
diff --git a/odb/oracle/connection.ixx b/odb/oracle/connection.ixx
index 40a9eda..165c2df 100644
--- a/odb/oracle/connection.ixx
+++ b/odb/oracle/connection.ixx
@@ -6,6 +6,12 @@ namespace odb
{
namespace oracle
{
+ inline database& connection::
+ database ()
+ {
+ return static_cast<connection_factory&> (factory_).database ();
+ }
+
template <typename T>
inline prepared_query<T> connection::
prepare_query (const char* n, const char* q)
diff --git a/odb/oracle/database.hxx b/odb/oracle/database.hxx
index 5534800..d4a0410 100644
--- a/odb/oracle/database.hxx
+++ b/odb/oracle/database.hxx
@@ -12,6 +12,7 @@
#include <iosfwd> // std::ostream
#include <odb/database.hxx>
+#include <odb/details/config.hxx> // ODB_CXX11
#include <odb/details/unique-ptr.hxx>
#include <odb/details/transfer-ptr.hxx>
@@ -80,6 +81,12 @@ namespace odb
details::transfer_ptr<connection_factory> =
details::transfer_ptr<connection_factory> ());
+ // Move-constructible but not move-assignable.
+ //
+#ifdef ODB_CXX11
+ database (database&&);
+#endif
+
static void
print_usage (std::ostream&);
@@ -505,6 +512,8 @@ namespace odb
connection_ ();
private:
+ // Note: remember to update move ctor if adding any new members.
+ //
std::string user_;
std::string password_;
diff --git a/odb/oracle/database.ixx b/odb/oracle/database.ixx
index 24f435a..167375d 100644
--- a/odb/oracle/database.ixx
+++ b/odb/oracle/database.ixx
@@ -2,12 +2,34 @@
// copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC
// license : ODB NCUEL; see accompanying LICENSE file
+#include <utility> // move()
+
#include <odb/oracle/transaction.hxx>
namespace odb
{
namespace oracle
{
+#ifdef ODB_CXX11
+ inline database::
+ database (database&& db) // Has to be inline.
+ : odb::database (std::move (db)),
+ user_ (std::move (db.user_)),
+ password_ (std::move (db.password_)),
+ db_ (std::move (db.db_)),
+ service_ (std::move (db.service_)),
+ host_ (std::move (db.host_)),
+ port_ (db.port_),
+ charset_ (db.charset_),
+ ncharset_ (db.ncharset_),
+ auto_environment_ (std::move (db.auto_environment_)),
+ environment_ (db.environment_),
+ factory_ (std::move (db.factory_))
+ {
+ factory_->database (*this); // New database instance.
+ }
+#endif
+
inline connection_ptr database::
connection ()
{