diff options
Diffstat (limited to 'odb/sqlite/connection.cxx')
-rw-r--r-- | odb/sqlite/connection.cxx | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx deleted file mode 100644 index 0445163..0000000 --- a/odb/sqlite/connection.cxx +++ /dev/null @@ -1,310 +0,0 @@ -// file : odb/sqlite/connection.cxx -// license : GNU GPL v2; see accompanying LICENSE file - -#include <new> // std::bad_alloc -#include <string> -#include <cassert> - -#include <odb/details/lock.hxx> - -#include <odb/sqlite/database.hxx> -#include <odb/sqlite/connection.hxx> -#include <odb/sqlite/transaction.hxx> -#include <odb/sqlite/statement.hxx> -#include <odb/sqlite/statement-cache.hxx> -#include <odb/sqlite/prepared-query.hxx> -#include <odb/sqlite/error.hxx> -#include <odb/sqlite/exceptions.hxx> // deadlock - -#include <odb/sqlite/details/config.hxx> // LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY - -using namespace std; - -extern "C" void -odb_sqlite_connection_unlock_callback (void**, int); - -namespace odb -{ - using namespace details; - - namespace sqlite - { - connection:: - connection (connection_factory& cf, - int extra_flags, - statement_translator* st) - : odb::connection (cf), - statement_translator_ (st), - unlock_cond_ (unlock_mutex_), - active_objects_ (0) - { - database_type& db (database ()); - - int f (db.flags () | extra_flags); - const string& n (db.name ()); - - // If we are opening a temporary database, then add the create flag. - // - if (n.empty () || n == ":memory:") - f |= SQLITE_OPEN_CREATE; - - // A connection can only be used by a single thread at a time. So - // disable locking in SQLite unless explicitly requested. - // -#if defined(SQLITE_OPEN_NOMUTEX) - if ((f & SQLITE_OPEN_FULLMUTEX) == 0) - f |= SQLITE_OPEN_NOMUTEX; -#endif - - sqlite3* h (0); - - // sqlite3_open_v2() was only addedin SQLite 3.5.0. - // -#if SQLITE_VERSION_NUMBER >= 3005000 - const string& vfs (db.vfs ()); - int e ( - sqlite3_open_v2 ( - n.c_str (), &h, f, (vfs.empty () ? 0 : vfs.c_str ()))); -#else - // Readonly opening not supported in SQLite earlier than 3.5.0. - // - assert ((f & SQLITE_OPEN_READONLY) == 0); - int e (sqlite3_open (n.c_str (), &h)); -#endif - - handle_.reset (h); - - if (e != SQLITE_OK) - { - if (handle_ == 0) - throw bad_alloc (); - - translate_error (e, *this); - } - - init (); - } - - connection:: - connection (connection_factory& cf, - sqlite3* handle, - statement_translator* st) - : odb::connection (cf), - handle_ (handle), - statement_translator_ (st), - unlock_cond_ (unlock_mutex_), - active_objects_ (0) - { - init (); - } - - void connection:: - init () - { - database_type& db (database ()); - - // Enable/disable foreign key constraints. - // - generic_statement st ( - *this, - db.foreign_keys () - ? "PRAGMA foreign_keys=ON" - : "PRAGMA foreign_keys=OFF", - db.foreign_keys () ? 22 : 23); - st.execute (); - - // String lengths include '\0', as per the SQLite manual suggestion. - // - begin_.reset (new (shared) generic_statement (*this, "BEGIN", 6)); - commit_.reset (new (shared) generic_statement (*this, "COMMIT", 7)); - rollback_.reset (new (shared) generic_statement (*this, "ROLLBACK", 9)); - - // Create statement cache. - // - statement_cache_.reset (new statement_cache_type (*this)); - } - - connection:: - connection (attached_connection_factory& cf, statement_translator* st) - : odb::connection (cf), - handle_ (0), - statement_translator_ (st), - unlock_cond_ (unlock_mutex_), - active_objects_ (0) - { - // Copy some things over from the main connection. - // - connection& main (*cf.main_connection_); - - tracer_ = main.tracer_; - - // Create statement cache. - // - statement_cache_.reset (new statement_cache_type (*this)); - } - - connection:: - ~connection () - { - // Destroy prepared query statements before freeing the connections. - // - recycle (); - clear_prepared_map (); - } - - generic_statement& connection:: - begin_statement () - { - return static_cast<generic_statement&> (*begin_); - } - - generic_statement& connection:: - begin_immediate_statement () - { - if (!begin_immediate_) - begin_immediate_.reset ( - new (shared) generic_statement (*this, "BEGIN IMMEDIATE", 16)); - - return static_cast<generic_statement&> (*begin_immediate_); - } - - generic_statement& connection:: - begin_exclusive_statement () - { - if (!begin_exclusive_) - begin_exclusive_.reset ( - new (shared) generic_statement (*this, "BEGIN EXCLUSIVE", 16)); - - return static_cast<generic_statement&> (*begin_exclusive_); - } - - generic_statement& connection:: - commit_statement () - { - return static_cast<generic_statement&> (*commit_); - } - - generic_statement& connection:: - rollback_statement () - { - return static_cast<generic_statement&> (*rollback_); - } - - transaction_impl* connection:: - begin () - { - return new transaction_impl ( - connection_ptr (inc_ref (this)), transaction_impl::deferred); - } - - transaction_impl* connection:: - begin_immediate () - { - return new transaction_impl ( - connection_ptr (inc_ref (this)), transaction_impl::immediate); - } - - transaction_impl* connection:: - begin_exclusive () - { - return new transaction_impl ( - connection_ptr (inc_ref (this)), transaction_impl::exclusive); - } - - unsigned long long connection:: - execute (const char* s, std::size_t n) - { - generic_statement st (*this, s, n); - return st.execute (); - } - - inline void - connection_unlock_callback (void** args, int n) - { - for (int i (0); i < n; ++i) - { - connection* c (static_cast<connection*> (args[i])); - details::lock l (c->unlock_mutex_); - c->unlocked_ = true; - c->unlock_cond_.signal (); - } - } - - void connection:: - wait () - { -#ifdef LIBODB_SQLITE_HAVE_UNLOCK_NOTIFY - unlocked_ = false; - - // unlock_notify() returns SQLITE_OK or SQLITE_LOCKED (deadlock). - // - int e (sqlite3_unlock_notify (handle (), - &odb_sqlite_connection_unlock_callback, - this)); - if (e == SQLITE_LOCKED) - throw deadlock (); - - details::lock l (unlock_mutex_); - - while (!unlocked_) - unlock_cond_.wait (l); -#else - translate_error (SQLITE_LOCKED, *this); -#endif - } - - void connection:: - clear () - { - invalidate_results (); - - // The current first active_object may remove itself from the list and - // make the second object (if any) the new first. - // - for (active_object** pp (&active_objects_); *pp != 0; ) - { - active_object* p (*pp); - p->clear (); - - // Move to the next object if this one decided to stay on the list. - // - if (*pp == p) - pp = &p->next_; - } - } - - // connection_factory - // - connection_factory:: - ~connection_factory () - { - } - - void connection_factory:: - database (database_type& db) - { - odb::connection_factory::db_ = &db; - db_ = &db; - } - - void connection_factory:: - attach_database (const connection_ptr& conn, - const std::string& name, - const std::string& schema) - { - conn->execute ("ATTACH DATABASE '" + name + "' AS \"" + schema + '"'); - } - - void connection_factory:: - detach_database (const connection_ptr& conn, const std::string& schema) - { - conn->execute ("DETACH DATABASE \"" + schema + '"'); - } - } -} - -extern "C" void -odb_sqlite_connection_unlock_callback (void** args, int n) -{ - odb::sqlite::connection_unlock_callback (args, n); -} |