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
commit2bf2944a844d002267d3508ce81a2128ccbb8af7 (patch)
tree32732629cdd48b789242e6a8dc1673c593f6fb8f
parent857fabab0c537a286e8a39503bf987029669d854 (diff)
Make database class move-constructible
This means it can be returned by value from a function in C++11.
-rw-r--r--odb/sqlite/connection-factory.cxx86
-rw-r--r--odb/sqlite/connection-factory.hxx46
-rw-r--r--odb/sqlite/connection.cxx32
-rw-r--r--odb/sqlite/connection.hxx42
-rw-r--r--odb/sqlite/connection.ixx6
-rw-r--r--odb/sqlite/database.hxx9
-rw-r--r--odb/sqlite/database.ixx16
7 files changed, 136 insertions, 101 deletions
diff --git a/odb/sqlite/connection-factory.cxx b/odb/sqlite/connection-factory.cxx
index c40190a..317d048 100644
--- a/odb/sqlite/connection-factory.cxx
+++ b/odb/sqlite/connection-factory.cxx
@@ -18,15 +18,6 @@ namespace odb
namespace sqlite
{
//
- // connection_factory
- //
-
- connection_factory::
- ~connection_factory ()
- {
- }
-
- //
// single_connection_factory
//
@@ -43,14 +34,14 @@ namespace odb
single_connection_factory::
create ()
{
- return single_connection_ptr (new (shared) single_connection (*db_));
+ return single_connection_ptr (new (shared) single_connection (*this));
}
connection_ptr single_connection_factory::
connect ()
{
mutex_.lock ();
- connection_->factory_ = this;
+ connection_->callback_ = &connection_->cb_;
connection_ptr r (connection_);
connection_.reset ();
return r;
@@ -59,14 +50,16 @@ namespace odb
void single_connection_factory::
database (database_type& db)
{
- db_ = &db;
- connection_ = create ();
+ connection_factory::database (db);
+
+ if (!connection_)
+ connection_ = create ();
}
bool single_connection_factory::
release (single_connection* c)
{
- c->factory_ = 0;
+ c->callback_ = 0;
connection_.reset (inc_ref (c));
connection_->recycle ();
mutex_.unlock ();
@@ -78,28 +71,26 @@ namespace odb
//
single_connection_factory::single_connection::
- single_connection (database_type& db, int extra_flags)
- : connection (db, extra_flags), factory_ (0)
+ single_connection (single_connection_factory& f, int extra_flags)
+ : connection (f, extra_flags)
{
- callback_.arg = this;
- callback_.zero_counter = &zero_counter;
- shared_base::callback_ = &callback_;
+ cb_.arg = this;
+ cb_.zero_counter = &zero_counter;
}
single_connection_factory::single_connection::
- single_connection (database_type& db, sqlite3* handle)
- : connection (db, handle), factory_ (0)
+ single_connection (single_connection_factory& f, sqlite3* 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 single_connection_factory::single_connection::
zero_counter (void* arg)
{
single_connection* c (static_cast<single_connection*> (arg));
- return c->factory_ ? c->factory_->release (c) : true;
+ return static_cast<single_connection_factory&> (c->factory_).release (c);
}
//
@@ -109,14 +100,18 @@ namespace odb
connection_ptr new_connection_factory::
connect ()
{
- return connection_ptr (
- new (shared) connection (*db_, extra_flags_));
+ return connection_ptr (new (shared) connection (*this, extra_flags_));
}
void new_connection_factory::
database (database_type& db)
{
- db_ = &db;
+ bool first (db_ == 0);
+
+ connection_factory::database (db);
+
+ if (!first)
+ return;
// Unless explicitly disabled, enable shared cache.
//
@@ -134,7 +129,7 @@ namespace odb
create ()
{
return pooled_connection_ptr (
- new (shared) pooled_connection (*db_, extra_flags_));
+ new (shared) pooled_connection (*this, extra_flags_));
}
connection_pool_factory::
@@ -165,7 +160,7 @@ namespace odb
shared_ptr<pooled_connection> c (connections_.back ());
connections_.pop_back ();
- c->pool_ = this;
+ c->callback_ = &c->cb_;
in_use_++;
return c;
}
@@ -175,7 +170,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;
}
@@ -191,7 +186,12 @@ namespace odb
void connection_pool_factory::
database (database_type& db)
{
- db_ = &db;
+ bool first (db_ == 0);
+
+ connection_factory::database (db);
+
+ if (!first)
+ return;
// Unless explicitly disabled, enable shared cache.
//
@@ -212,7 +212,7 @@ namespace odb
bool connection_pool_factory::
release (pooled_connection* c)
{
- c->pool_ = 0;
+ c->callback_ = 0;
lock l (mutex_);
@@ -241,28 +241,26 @@ namespace odb
//
connection_pool_factory::pooled_connection::
- pooled_connection (database_type& db, int extra_flags)
- : connection (db, extra_flags), pool_ (0)
+ pooled_connection (connection_pool_factory& f, int extra_flags)
+ : connection (f, extra_flags)
{
- 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, sqlite3* handle)
- : connection (db, handle), pool_ (0)
+ pooled_connection (connection_pool_factory& f, sqlite3* 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/sqlite/connection-factory.hxx b/odb/sqlite/connection-factory.hxx
index c0d15ff..d3d6aea 100644
--- a/odb/sqlite/connection-factory.hxx
+++ b/odb/sqlite/connection-factory.hxx
@@ -24,29 +24,13 @@ namespace odb
{
namespace sqlite
{
- class LIBODB_SQLITE_EXPORT connection_factory
- {
- public:
- virtual connection_ptr
- connect () = 0;
-
- public:
- typedef sqlite::database database_type;
-
- virtual void
- database (database_type&) = 0;
-
- virtual
- ~connection_factory ();
- };
-
// Share a single connection.
//
class LIBODB_SQLITE_EXPORT single_connection_factory:
public connection_factory
{
public:
- single_connection_factory (): db_ (0) {}
+ single_connection_factory () {}
virtual connection_ptr
connect ();
@@ -65,8 +49,8 @@ namespace odb
class LIBODB_SQLITE_EXPORT single_connection: public connection
{
public:
- single_connection (database_type&, int extra_flags = 0);
- single_connection (database_type&, sqlite3*);
+ single_connection (single_connection_factory&, int extra_flags = 0);
+ single_connection (single_connection_factory&, sqlite3*);
private:
static bool
@@ -74,12 +58,7 @@ namespace odb
private:
friend class single_connection_factory;
-
- shared_base::refcount_callback callback_;
-
- // NULL factory value indicates that the connection is not in use.
- //
- single_connection_factory* factory_;
+ shared_base::refcount_callback cb_;
};
friend class single_connection;
@@ -99,7 +78,6 @@ namespace odb
release (single_connection*);
protected:
- database_type* db_;
details::mutex mutex_;
single_connection_ptr connection_;
};
@@ -110,7 +88,7 @@ namespace odb
public connection_factory
{
public:
- new_connection_factory (): db_ (0), extra_flags_ (0) {}
+ new_connection_factory (): extra_flags_ (0) {}
virtual connection_ptr
connect ();
@@ -123,7 +101,6 @@ namespace odb
new_connection_factory& operator= (const new_connection_factory&);
private:
- database_type* db_;
int extra_flags_;
};
@@ -156,7 +133,6 @@ namespace odb
extra_flags_ (0),
in_use_ (0),
waiters_ (0),
- db_ (0),
cond_ (mutex_)
{
// max_connections == 0 means unlimited.
@@ -181,8 +157,8 @@ namespace odb
class LIBODB_SQLITE_EXPORT pooled_connection: public connection
{
public:
- pooled_connection (database_type&, int extra_flags = 0);
- pooled_connection (database_type&, sqlite3*);
+ pooled_connection (connection_pool_factory&, int extra_flags = 0);
+ pooled_connection (connection_pool_factory&, sqlite3*);
private:
static bool
@@ -190,12 +166,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;
@@ -223,7 +194,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/sqlite/connection.cxx b/odb/sqlite/connection.cxx
index c44d648..b150470 100644
--- a/odb/sqlite/connection.cxx
+++ b/odb/sqlite/connection.cxx
@@ -29,12 +29,13 @@ namespace odb
namespace sqlite
{
connection::
- connection (database_type& db, int extra_flags)
- : odb::connection (db),
- db_ (db),
+ connection (connection_factory& cf, int extra_flags)
+ : odb::connection (cf),
unlock_cond_ (unlock_mutex_),
active_objects_ (0)
{
+ database_type& db (database ());
+
int f (db.flags () | extra_flags);
const string& n (db.name ());
@@ -81,9 +82,8 @@ namespace odb
}
connection::
- connection (database_type& db, sqlite3* handle)
- : odb::connection (db),
- db_ (db),
+ connection (connection_factory& cf, sqlite3* handle)
+ : odb::connection (cf),
handle_ (handle),
unlock_cond_ (unlock_mutex_),
active_objects_ (0)
@@ -94,14 +94,16 @@ namespace odb
void connection::
init ()
{
+ database_type& db (database ());
+
// Enable/disable foreign key constraints.
//
generic_statement st (
*this,
- db_.foreign_keys ()
+ db.foreign_keys ()
? "PRAGMA foreign_keys=ON"
: "PRAGMA foreign_keys=OFF",
- db_.foreign_keys () ? 22 : 23);
+ db.foreign_keys () ? 22 : 23);
st.execute ();
// Create statement cache.
@@ -190,6 +192,20 @@ namespace odb
while (active_objects_ != 0)
active_objects_->clear ();
}
+
+ // connection_factory
+ //
+ connection_factory::
+ ~connection_factory ()
+ {
+ }
+
+ void connection_factory::
+ database (database_type& db)
+ {
+ odb::connection_factory::db_ = &db;
+ db_ = &db;
+ }
}
}
diff --git a/odb/sqlite/connection.hxx b/odb/sqlite/connection.hxx
index 7499eb9..5110163 100644
--- a/odb/sqlite/connection.hxx
+++ b/odb/sqlite/connection.hxx
@@ -30,6 +30,7 @@ namespace odb
namespace sqlite
{
class statement_cache;
+ class connection_factory;
class connection;
typedef details::shared_ptr<connection> connection_ptr;
@@ -76,14 +77,11 @@ namespace odb
virtual
~connection ();
- connection (database_type&, int extra_flags = 0);
- connection (database_type&, sqlite3* handle);
+ connection (connection_factory&, int extra_flags = 0);
+ connection (connection_factory&, sqlite3* handle);
database_type&
- database ()
- {
- return db_;
- }
+ database ();
public:
virtual transaction_impl*
@@ -173,11 +171,6 @@ namespace odb
init ();
private:
- // Needed to break the circular connection-database dependency
- // (odb::connection has the odb::database member).
- //
- database_type& db_;
-
auto_handle<sqlite3> handle_;
// Keep statement_cache_ after handle_ so that it is destroyed before
@@ -205,6 +198,33 @@ namespace odb
friend class active_object;
active_object* active_objects_;
};
+
+ class LIBODB_SQLITE_EXPORT connection_factory:
+ public odb::connection_factory
+ {
+ public:
+ typedef sqlite::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/sqlite/connection.ixx b/odb/sqlite/connection.ixx
index 23df27c..ab6d72e 100644
--- a/odb/sqlite/connection.ixx
+++ b/odb/sqlite/connection.ixx
@@ -32,6 +32,12 @@ namespace odb
// connection
//
+ 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/sqlite/database.hxx b/odb/sqlite/database.hxx
index f7f3994..f846f9e 100644
--- a/odb/sqlite/database.hxx
+++ b/odb/sqlite/database.hxx
@@ -14,6 +14,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>
@@ -84,6 +85,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&);
@@ -458,6 +465,8 @@ namespace odb
connection_ ();
private:
+ // Note: remember to update move ctor if adding any new members.
+ //
std::string name_;
int flags_;
bool foreign_keys_;
diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx
index c1e8f07..aec4ba5 100644
--- a/odb/sqlite/database.ixx
+++ b/odb/sqlite/database.ixx
@@ -2,12 +2,28 @@
// copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC
// license : GNU GPL v2; see accompanying LICENSE file
+#include <utility> // move()
+
#include <odb/sqlite/transaction.hxx>
namespace odb
{
namespace sqlite
{
+#ifdef ODB_CXX11
+ inline database::
+ database (database&& db) // Has to be inline.
+ : odb::database (std::move (db)),
+ name_ (std::move (db.name_)),
+ flags_ (db.flags_),
+ foreign_keys_ (db.foreign_keys_),
+ vfs_ (std::move (db.vfs_)),
+ factory_ (std::move (db.factory_))
+ {
+ factory_->database (*this); // New database instance.
+ }
+#endif
+
inline connection_ptr database::
connection ()
{