aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/sqlite/connection-factory.cxx61
-rw-r--r--odb/sqlite/connection-factory.hxx60
2 files changed, 121 insertions, 0 deletions
diff --git a/odb/sqlite/connection-factory.cxx b/odb/sqlite/connection-factory.cxx
index 11184bc..fc9fefc 100644
--- a/odb/sqlite/connection-factory.cxx
+++ b/odb/sqlite/connection-factory.cxx
@@ -26,6 +26,67 @@ namespace odb
}
//
+ // single_connection_factory
+ //
+
+ single_connection_factory::
+ ~single_connection_factory ()
+ {
+ // If the connection is currently in use, wait for it to return to
+ // the factory.
+ //
+ lock l (mutex_);
+ }
+
+ shared_ptr<connection> single_connection_factory::
+ connect ()
+ {
+ mutex_.lock ();
+ connection_->factory_ = this;
+ shared_ptr<connection> r (connection_);
+ connection_.reset ();
+ return r;
+ }
+
+ void single_connection_factory::
+ database (database_type& db)
+ {
+ db_ = &db;
+ connection_.reset (new (shared) single_connection (*db_, 0, 0));
+ }
+
+ bool single_connection_factory::
+ release (single_connection* c)
+ {
+ c->factory_ = 0;
+ connection_.reset (inc_ref (c));
+ mutex_.unlock ();
+ return false;
+ }
+
+ //
+ // single_connection_factory::single_connection
+ //
+
+ single_connection_factory::single_connection::
+ single_connection (database_type& db,
+ int extra_flags,
+ single_connection_factory* factory)
+ : connection (db, extra_flags), factory_ (factory)
+ {
+ callback_.arg = this;
+ callback_.zero_counter = &zero_counter;
+ shared_base::callback_ = &callback_;
+ }
+
+ 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;
+ }
+
+ //
// new_connection_factory
//
diff --git a/odb/sqlite/connection-factory.hxx b/odb/sqlite/connection-factory.hxx
index 76bdc11..e687e27 100644
--- a/odb/sqlite/connection-factory.hxx
+++ b/odb/sqlite/connection-factory.hxx
@@ -40,6 +40,64 @@ namespace odb
~connection_factory ();
};
+ // Share a single connection.
+ //
+ class LIBODB_SQLITE_EXPORT single_connection_factory:
+ public connection_factory
+ {
+ public:
+ single_connection_factory (): db_ (0) {}
+
+ virtual details::shared_ptr<connection>
+ connect ();
+
+ virtual void
+ database (database_type&);
+
+ virtual
+ ~single_connection_factory ();
+
+ private:
+ single_connection_factory (const single_connection_factory&);
+ single_connection_factory& operator= (const single_connection_factory&);
+
+ private:
+ class single_connection: public connection
+ {
+ public:
+ // NULL factory value indicates that the connection is not in use.
+ //
+ single_connection (database_type&,
+ int extra_flags,
+ single_connection_factory*);
+
+ private:
+ static bool
+ zero_counter (void*);
+
+ private:
+ friend class single_connection_factory;
+
+ shared_base::refcount_callback callback_;
+ single_connection_factory* factory_;
+ };
+
+ friend class single_connection;
+
+ private:
+ // Return true if the connection should be deleted, false otherwise.
+ //
+ bool
+ release (single_connection*);
+
+ private:
+ database_type* db_;
+ details::mutex mutex_;
+ details::shared_ptr<single_connection> connection_;
+ };
+
+ // Create a new connection every time one is requested.
+ //
class LIBODB_SQLITE_EXPORT new_connection_factory:
public connection_factory
{
@@ -61,6 +119,8 @@ namespace odb
int extra_flags_;
};
+ // Pool a number of connections.
+ //
class LIBODB_SQLITE_EXPORT connection_pool_factory:
public connection_factory
{