diff options
Diffstat (limited to 'odb/sqlite/connection-factory.cxx')
-rw-r--r-- | odb/sqlite/connection-factory.cxx | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/odb/sqlite/connection-factory.cxx b/odb/sqlite/connection-factory.cxx deleted file mode 100644 index 794c6dd..0000000 --- a/odb/sqlite/connection-factory.cxx +++ /dev/null @@ -1,417 +0,0 @@ -// file : odb/sqlite/connection-factory.cxx -// license : GNU GPL v2; see accompanying LICENSE file - -#include <cassert> - -#include <odb/details/lock.hxx> - -#include <odb/sqlite/database.hxx> -#include <odb/sqlite/connection-factory.hxx> - -#include <odb/sqlite/details/config.hxx> // LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY - -using namespace std; - -namespace odb -{ - using namespace details; - - namespace sqlite - { - // - // serial_connection_factory - // - - serial_connection_factory:: - ~serial_connection_factory () - { - // We should hold the last reference to the connection. - // - if (connection_ != 0) - assert (connection_.count () == 1); - } - - connection_ptr serial_connection_factory:: - create () - { - return connection_ptr (new (shared) connection (*this)); - } - - connection_ptr serial_connection_factory:: - connect () - { - return connection_; - } - - void serial_connection_factory:: - database (database_type& db) - { - connection_factory::database (db); - - if (!connection_) - connection_ = create (); - } - - // - // 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_); - } - - single_connection_factory::single_connection_ptr - single_connection_factory:: - create () - { - return single_connection_ptr (new (shared) single_connection (*this)); - } - - connection_ptr single_connection_factory:: - connect () - { - mutex_.lock (); - connection_->callback_ = &connection_->cb_; - connection_ptr r (connection_); - connection_.reset (); - return r; - } - - void single_connection_factory:: - database (database_type& db) - { - connection_factory::database (db); - - if (!connection_) - connection_ = create (); - } - - bool single_connection_factory:: - release (single_connection* c) - { - c->callback_ = 0; - connection_.reset (inc_ref (c)); - connection_->recycle (); - mutex_.unlock (); - return false; - } - - // - // single_connection_factory::single_connection - // - - single_connection_factory::single_connection:: - single_connection (single_connection_factory& f, int extra_flags) - : connection (f, extra_flags) - { - cb_.arg = this; - cb_.zero_counter = &zero_counter; - } - - single_connection_factory::single_connection:: - single_connection (single_connection_factory& f, sqlite3* handle) - : connection (f, handle) - { - 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 static_cast<single_connection_factory&> (c->factory_).release (c); - } - - // - // new_connection_factory - // - - connection_ptr new_connection_factory:: - connect () - { - return connection_ptr (new (shared) connection (*this, extra_flags_)); - } - - void new_connection_factory:: - database (database_type& db) - { - bool first (db_ == 0); - - connection_factory::database (db); - - if (!first) - return; - - // Unless explicitly disabled, enable shared cache. - // -#if SQLITE_VERSION_NUMBER >= 3006018 && defined(LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY) - if ((db_->flags () & SQLITE_OPEN_PRIVATECACHE) == 0) - extra_flags_ |= SQLITE_OPEN_SHAREDCACHE; -#endif - } - - // - // connection_pool_factory - // - - connection_pool_factory::pooled_connection_ptr connection_pool_factory:: - create () - { - return pooled_connection_ptr ( - new (shared) pooled_connection (*this, extra_flags_)); - } - - connection_pool_factory:: - ~connection_pool_factory () - { - // Wait for all the connections currently in use to return to the pool. - // - lock l (mutex_); - while (in_use_ != 0) - { - waiters_++; - cond_.wait (l); - waiters_--; - } - } - - connection_ptr connection_pool_factory:: - connect () - { - lock l (mutex_); - - while (true) - { - // See if we have a spare connection. - // - if (connections_.size () != 0) - { - shared_ptr<pooled_connection> c (connections_.back ()); - connections_.pop_back (); - - c->callback_ = &c->cb_; - in_use_++; - return c; - } - - // See if we can create a new one. - // - if(max_ == 0 || in_use_ < max_) - { - shared_ptr<pooled_connection> c (create ()); - c->callback_ = &c->cb_; - in_use_++; - return c; - } - - // Wait until someone releases a connection. - // - waiters_++; - cond_.wait (l); - waiters_--; - } - } - - void connection_pool_factory:: - database (database_type& db) - { - bool first (db_ == 0); - - connection_factory::database (db); - - if (!first) - return; - - // Unless explicitly disabled, enable shared cache. - // -#if SQLITE_VERSION_NUMBER >= 3006018 && defined(LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY) - if ((db_->flags () & SQLITE_OPEN_PRIVATECACHE) == 0) - extra_flags_ |= SQLITE_OPEN_SHAREDCACHE; -#endif - - if (min_ > 0) - { - connections_.reserve (min_); - - for(size_t i (0); i < min_; ++i) - connections_.push_back (create ()); - } - } - - bool connection_pool_factory:: - release (pooled_connection* c) - { - c->callback_ = 0; - - lock l (mutex_); - - // Determine if we need to keep or free this connection. - // - bool keep (waiters_ != 0 || - min_ == 0 || - (connections_.size () + in_use_ <= min_)); - - in_use_--; - - if (keep) - { - connections_.push_back (pooled_connection_ptr (inc_ref (c))); - connections_.back ()->recycle (); - } - - if (waiters_ != 0) - cond_.signal (); - - return !keep; - } - - // - // connection_pool_factory::pooled_connection - // - - connection_pool_factory::pooled_connection:: - pooled_connection (connection_pool_factory& f, int extra_flags) - : connection (f, extra_flags) - { - cb_.arg = this; - cb_.zero_counter = &zero_counter; - } - - connection_pool_factory::pooled_connection:: - pooled_connection (connection_pool_factory& f, sqlite3* handle) - : connection (f, handle) - { - 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 static_cast<connection_pool_factory&> (c->factory_).release (c); - } - - // - // default_attached_connection_factory - // - - void default_attached_connection_factory:: - detach () - { - // Note that this function may be called several times, for example, in - // case of detach_database() failure. - // - if (attached_connection_ != 0) - { - // We should hold the last reference to the attached connection. - // - assert (attached_connection_.count () == 1); - - // While it may seem like a good idea to also invalidate query results - // and reset active statements, if any such result/statement is still - // alive, then there would be bigger problems since it would have a - // dangling reference to the connection. In a way, that's the same - // reason we don't do it in the connection destructor. - - // Remove ourselves from the active object list of the main - // connection. - // - if (next_ != this) // Might have already been done. - list_remove (); - - const string& s (database ().schema ()); - - if (s != "main" && s != "temp") - main_factory ().detach_database (main_connection_, s); - - // Explicitly free the attached connection so that we don't try to - // redo this. - // - attached_connection_.reset (); - } - } - - default_attached_connection_factory:: - ~default_attached_connection_factory () - { - if (attached_connection_ != 0) - { - // This can throw. Ignoring the failure to detach seems like the most - // sensible thing to do here. - // - try{ detach (); } catch (...) {} - } - } - - connection_ptr default_attached_connection_factory:: - connect () - { - return attached_connection_; - } - - void default_attached_connection_factory:: - database (database_type& db) - { - attached_connection_factory::database (db); - - if (!attached_connection_) - { - const string& s (db.schema ()); - - if (s != "main" && s != "temp") - main_factory ().attach_database (main_connection_, db.name (), s); - - attached_connection_.reset ( - new (shared) connection (*this, - s != "main" ? &translate_statement : 0)); - - // Add ourselves to the active object list of the main connection. - // - list_add (); - } - } - - void default_attached_connection_factory:: - clear () - { - attached_connection_->clear (); - } - - void default_attached_connection_factory:: - translate_statement (string& r, - const char* text, - size_t text_size, - connection& conn) - { - r.assign (text, text_size); - - // Things will fall apart if any of the statements we translate use - // "main" as a table alias. So we have this crude check even though it - // means we cannot use "main" for other aliases (e.g., column). - // - assert (r.find ("AS \"main\"") == string::npos); - - const string& s (conn.database ().schema ()); - for (size_t p (0); (p = r.find ("\"main\".", p, 7)) != string::npos; ) - { - // Verify the preceding character. - // - if (p != 0 && r[p - 1] == '.') - { - p += 7; - continue; - } - - r.replace (p + 1, 4, s); - p += s.size () + 3; - } - } - } -} |