diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-03-29 17:53:00 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-03-29 17:53:00 +0200 |
commit | 163bb9d59de08b02074395fbb2a9fde5f8cc14d9 (patch) | |
tree | 891972c2612ff6b4c4ddd787f5952591f6c9fbd9 | |
parent | 0db95154f2f063f6747d29c5c048bae933dcb7a1 (diff) |
Add single_connection_factory
-rw-r--r-- | odb/sqlite/connection-factory.cxx | 61 | ||||
-rw-r--r-- | odb/sqlite/connection-factory.hxx | 60 |
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 { |