diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-11-09 18:14:37 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-11-09 18:14:37 +0200 |
commit | 0bf77eaad1fb2ad23f9aec64ea0fe3ab7cf06a28 (patch) | |
tree | 49d0ff8ee2f193c9eabfc67b06f1a2134d21a8b3 | |
parent | ea61e19c6c0a52be4740448d0d21605e090b460d (diff) |
Make database class move-constructible
This means it can be returned by value from a function in C++11.
-rw-r--r-- | odb/mssql/auto-handle.hxx | 12 | ||||
-rw-r--r-- | odb/mssql/connection-factory.cxx | 56 | ||||
-rw-r--r-- | odb/mssql/connection-factory.hxx | 39 | ||||
-rw-r--r-- | odb/mssql/connection.cxx | 34 | ||||
-rw-r--r-- | odb/mssql/connection.hxx | 38 | ||||
-rw-r--r-- | odb/mssql/connection.ixx | 6 | ||||
-rw-r--r-- | odb/mssql/database.hxx | 9 | ||||
-rw-r--r-- | odb/mssql/database.ixx | 26 |
8 files changed, 132 insertions, 88 deletions
diff --git a/odb/mssql/auto-handle.hxx b/odb/mssql/auto-handle.hxx index 81f9246..e54e543 100644 --- a/odb/mssql/auto-handle.hxx +++ b/odb/mssql/auto-handle.hxx @@ -7,6 +7,8 @@ #include <odb/pre.hxx> +#include <odb/details/config.hxx> // ODB_CXX11 + #include <odb/mssql/mssql-fwd.hxx> #include <odb/mssql/version.hxx> @@ -62,6 +64,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&); diff --git a/odb/mssql/connection-factory.cxx b/odb/mssql/connection-factory.cxx index 24add41..b0815cf 100644 --- a/odb/mssql/connection-factory.cxx +++ b/odb/mssql/connection-factory.cxx @@ -15,39 +15,20 @@ namespace odb namespace mssql { - // - // 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, SQLHDBC handle) - : connection (db, handle), pool_ (0) + pooled_connection (connection_pool_factory& f, SQLHDBC 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/mssql/connection-factory.hxx b/odb/mssql/connection-factory.hxx index 6713705..6fa4de4 100644 --- a/odb/mssql/connection-factory.hxx +++ b/odb/mssql/connection-factory.hxx @@ -25,42 +25,17 @@ namespace odb { namespace mssql { - class LIBODB_MSSQL_EXPORT connection_factory - { - public: - virtual connection_ptr - connect () = 0; - - public: - typedef mssql::database database_type; - - virtual void - database (database_type&) = 0; - - virtual - ~connection_factory (); - }; - class LIBODB_MSSQL_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_MSSQL_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_MSSQL_EXPORT pooled_connection: public connection { public: - pooled_connection (database_type&); - pooled_connection (database_type&, SQLHDBC); + pooled_connection (connection_pool_factory&); + pooled_connection (connection_pool_factory&, SQLHDBC); 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/mssql/connection.cxx b/odb/mssql/connection.cxx index 3128a2e..d83f6c9 100644 --- a/odb/mssql/connection.cxx +++ b/odb/mssql/connection.cxx @@ -28,23 +28,24 @@ namespace odb }; connection:: - connection (database_type& db) - : odb::connection (db), - db_ (db), + connection (connection_factory& cf) + : odb::connection (cf), state_ (state_disconnected), statement_cache_ (new statement_cache_type (*this)), long_data_buffer_ (0) { SQLRETURN r; + database_type& db (database ()); + // Allocate the connection handle. // { SQLHANDLE h; - r = SQLAllocHandle (SQL_HANDLE_DBC, db_.environment (), &h); + r = SQLAllocHandle (SQL_HANDLE_DBC, db.environment (), &h); if (!SQL_SUCCEEDED (r)) - translate_error (r, db_.environment (), SQL_HANDLE_ENV); + translate_error (r, db.environment (), SQL_HANDLE_ENV); handle_.reset (h); } @@ -74,7 +75,7 @@ namespace odb // Set transaction isolation level. // - transaction_isolation ti (db_.transaction_isolation ()); + transaction_isolation ti (db.transaction_isolation ()); switch (ti) { case isolation_read_committed: @@ -112,7 +113,7 @@ namespace odb SQLSMALLINT out_conn_str_size; r = SQLDriverConnectA (handle_, 0, // Parent window handle. - (SQLCHAR*) db_.connect_string ().c_str (), + (SQLCHAR*) db.connect_string ().c_str (), SQL_NTS, 0, // Output connection string buffer. 0, // Size of output connection string buffer. @@ -131,9 +132,8 @@ namespace odb } connection:: - connection (database_type& db, SQLHDBC handle) - : odb::connection (db), - db_ (db), + connection (connection_factory& cf, SQLHDBC handle) + : odb::connection (cf), handle_ (handle), state_ (state_connected), statement_cache_ (new statement_cache_type (*this)), @@ -268,5 +268,19 @@ namespace odb return static_cast<unsigned long long> (rows); } + + // connection_factory + // + connection_factory:: + ~connection_factory () + { + } + + void connection_factory:: + database (database_type& db) + { + odb::connection_factory::db_ = &db; + db_ = &db; + } } } diff --git a/odb/mssql/connection.hxx b/odb/mssql/connection.hxx index ae185e5..3401f31 100644 --- a/odb/mssql/connection.hxx +++ b/odb/mssql/connection.hxx @@ -28,6 +28,7 @@ namespace odb namespace mssql { 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&, SQLHDBC handle); + connection (connection_factory&); + connection (connection_factory&, SQLHDBC handle); database_type& - database () - { - return db_; - } + database (); public: virtual transaction_impl* @@ -138,7 +136,6 @@ namespace odb friend class transaction_impl; // invalidate_results() private: - database_type& db_; auto_handle<SQL_HANDLE_DBC> handle_; enum @@ -154,6 +151,33 @@ namespace odb details::unique_ptr<statement_cache_type> statement_cache_; details::buffer long_data_buffer_; }; + + class LIBODB_MSSQL_EXPORT connection_factory: + public odb::connection_factory + { + public: + typedef mssql::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/mssql/connection.ixx b/odb/mssql/connection.ixx index fe7f40e..824912a 100644 --- a/odb/mssql/connection.ixx +++ b/odb/mssql/connection.ixx @@ -6,6 +6,12 @@ namespace odb { namespace mssql { + 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/mssql/database.hxx b/odb/mssql/database.hxx index d01ba30..de179bd 100644 --- a/odb/mssql/database.hxx +++ b/odb/mssql/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> @@ -138,6 +139,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&); @@ -591,6 +598,8 @@ namespace odb init (); private: + // Note: remember to update move ctor if adding any new members. + // std::string user_; std::string password_; std::string db_; diff --git a/odb/mssql/database.ixx b/odb/mssql/database.ixx index 6558339..e90da54 100644 --- a/odb/mssql/database.ixx +++ b/odb/mssql/database.ixx @@ -2,12 +2,38 @@ // copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC // license : ODB NCUEL; see accompanying LICENSE file +#include <utility> // move() + #include <odb/mssql/transaction.hxx> namespace odb { namespace mssql { +#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_)), + protocol_ (db.protocol_), + host_ (std::move (db.host_)), + instance_ (std::move (db.instance_)), + port_ (db.port_), + server_ (std::move (db.server_)), + driver_ (std::move (db.driver_)), + extra_connect_string_ (std::move (db.extra_connect_string_)), + transaction_isolation_ (db.transaction_isolation_), + connect_string_ (std::move (db.connect_string_)), + 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 () { |