From 5694c0a4529334756f2b914ad67408df199551dc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 21 Aug 2011 16:27:34 +0200 Subject: Add odb::connection class This abstract class represents a connection to the database. One can use it to start a transaction or to execute a native statement out of a transaction. Before we had concrete connection classes in the database runtime libraries (e.g., odb::mysql::connection). Now these classes derive from odb::connection. --- odb/sqlite/connection-factory.cxx | 10 ++++----- odb/sqlite/connection-factory.hxx | 8 ++++---- odb/sqlite/connection.cxx | 43 ++++++++++++++++++++++++++++++++++++++- odb/sqlite/connection.hxx | 23 ++++++++++++++++++++- odb/sqlite/database.cxx | 41 ++++--------------------------------- odb/sqlite/database.hxx | 21 +++++++++---------- odb/sqlite/database.ixx | 26 +++++++++++++++++++++-- odb/sqlite/forward.hxx | 7 +++++++ odb/sqlite/transaction-impl.cxx | 12 +++++------ odb/sqlite/transaction-impl.hxx | 6 +++--- 10 files changed, 127 insertions(+), 70 deletions(-) diff --git a/odb/sqlite/connection-factory.cxx b/odb/sqlite/connection-factory.cxx index fc9fefc..71f8b3e 100644 --- a/odb/sqlite/connection-factory.cxx +++ b/odb/sqlite/connection-factory.cxx @@ -38,12 +38,12 @@ namespace odb lock l (mutex_); } - shared_ptr single_connection_factory:: + connection_ptr single_connection_factory:: connect () { mutex_.lock (); connection_->factory_ = this; - shared_ptr r (connection_); + connection_ptr r (connection_); connection_.reset (); return r; } @@ -90,10 +90,10 @@ namespace odb // new_connection_factory // - shared_ptr new_connection_factory:: + connection_ptr new_connection_factory:: connect () { - return shared_ptr ( + return connection_ptr ( new (shared) connection (*db_, extra_flags_)); } @@ -126,7 +126,7 @@ namespace odb } } - shared_ptr connection_pool_factory:: + connection_ptr connection_pool_factory:: connect () { lock l (mutex_); diff --git a/odb/sqlite/connection-factory.hxx b/odb/sqlite/connection-factory.hxx index e687e27..8166fc4 100644 --- a/odb/sqlite/connection-factory.hxx +++ b/odb/sqlite/connection-factory.hxx @@ -27,7 +27,7 @@ namespace odb class LIBODB_SQLITE_EXPORT connection_factory { public: - virtual details::shared_ptr + virtual connection_ptr connect () = 0; public: @@ -48,7 +48,7 @@ namespace odb public: single_connection_factory (): db_ (0) {} - virtual details::shared_ptr + virtual connection_ptr connect (); virtual void @@ -104,7 +104,7 @@ namespace odb public: new_connection_factory (): db_ (0), extra_flags_ (0) {} - virtual details::shared_ptr + virtual connection_ptr connect (); virtual void @@ -154,7 +154,7 @@ namespace odb // @@ check min_ <= max_ } - virtual details::shared_ptr + virtual connection_ptr connect (); virtual void diff --git a/odb/sqlite/connection.cxx b/odb/sqlite/connection.cxx index 91b430a..d90c301 100644 --- a/odb/sqlite/connection.cxx +++ b/odb/sqlite/connection.cxx @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -38,7 +39,10 @@ namespace odb connection:: connection (database_type& db, int extra_flags) - : db_ (db), unlock_cond_ (unlock_mutex_), statements_ (0) + : odb::connection (db), + db_ (db), + unlock_cond_ (unlock_mutex_), + statements_ (0) { int f (db.flags () | extra_flags); const string& n (db.name ()); @@ -65,6 +69,43 @@ namespace odb statement_cache_.reset (new statement_cache_type (*this)); } + transaction_impl* connection:: + begin () + { + if (transaction::has_current ()) + throw already_in_transaction (); + + return new transaction_impl ( + connection_ptr (inc_ref (this)), transaction_impl::deferred); + } + + transaction_impl* connection:: + begin_immediate () + { + if (transaction::has_current ()) + throw already_in_transaction (); + + return new transaction_impl ( + connection_ptr (inc_ref (this)), transaction_impl::immediate); + } + + transaction_impl* connection:: + begin_exclusive () + { + if (transaction::has_current ()) + throw already_in_transaction (); + + return new transaction_impl ( + connection_ptr (inc_ref (this)), transaction_impl::exclusive); + } + + unsigned long long connection:: + execute (const char* s, std::size_t n) + { + simple_statement st (*this, s, n); + return st.execute (); + } + inline void connection_unlock_callback (void** args, int n) { diff --git a/odb/sqlite/connection.hxx b/odb/sqlite/connection.hxx index 3ae82e3..e069ce9 100644 --- a/odb/sqlite/connection.hxx +++ b/odb/sqlite/connection.hxx @@ -13,12 +13,14 @@ #include // std::auto_ptr #include +#include #include #include #include #include #include +#include #include namespace odb @@ -28,7 +30,10 @@ namespace odb class statement; class statement_cache; - class LIBODB_SQLITE_EXPORT connection: public details::shared_base + class connection; + typedef details::shared_ptr connection_ptr; + + class LIBODB_SQLITE_EXPORT connection: public odb::connection { public: typedef sqlite::statement_cache statement_cache_type; @@ -46,6 +51,22 @@ namespace odb } public: + virtual transaction_impl* + begin (); + + transaction_impl* + begin_immediate (); + + transaction_impl* + begin_exclusive (); + + public: + using odb::connection::execute; + + virtual unsigned long long + execute (const char* statement, std::size_t length); + + public: sqlite3* handle () { diff --git a/odb/sqlite/database.cxx b/odb/sqlite/database.cxx index 912ec97..e756608 100644 --- a/odb/sqlite/database.cxx +++ b/odb/sqlite/database.cxx @@ -6,10 +6,8 @@ #include #include -#include #include #include -#include #include #include @@ -80,42 +78,11 @@ namespace odb details::options::print_usage (os); } - unsigned long long database:: - execute (const char* s, std::size_t n) + odb::connection* database:: + connection_ () { - if (!transaction::has_current ()) - throw not_in_transaction (); - - connection_type& c (transaction::current ().connection ()); - simple_statement st (c, s, n); - return st.execute (); - } - - transaction_impl* database:: - begin () - { - if (transaction::has_current ()) - throw already_in_transaction (); - - return new transaction_impl (*this, transaction_impl::deferred); - } - - transaction_impl* database:: - begin_immediate () - { - if (transaction::has_current ()) - throw already_in_transaction (); - - return new transaction_impl (*this, transaction_impl::immediate); - } - - transaction_impl* database:: - begin_exclusive () - { - if (transaction::has_current ()) - throw already_in_transaction (); - - return new transaction_impl (*this, transaction_impl::exclusive); + connection_ptr c (factory_->connect ()); + return c.release (); } } } diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx index cfff30f..0eadbbf 100644 --- a/odb/sqlite/database.hxx +++ b/odb/sqlite/database.hxx @@ -28,12 +28,11 @@ namespace odb { namespace sqlite { + class transaction_impl; + class LIBODB_SQLITE_EXPORT database: public odb::database { public: - typedef sqlite::connection connection_type; - - public: database (const std::string& name, int flags = SQLITE_OPEN_READWRITE, std::auto_ptr = @@ -77,14 +76,10 @@ namespace odb return flags_; } + // Transactions. + // public: - using odb::database::execute; - - virtual unsigned long long - execute (const char* statement, std::size_t length); - - public: - virtual transaction_impl* + transaction_impl* begin (); transaction_impl* @@ -94,13 +89,17 @@ namespace odb begin_exclusive (); public: - details::shared_ptr + connection_ptr connection (); public: virtual ~database (); + protected: + virtual odb::connection* + connection_ (); + private: std::string name_; int flags_; diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx index 7e34e01..f78d659 100644 --- a/odb/sqlite/database.ixx +++ b/odb/sqlite/database.ixx @@ -7,10 +7,32 @@ namespace odb { namespace sqlite { - inline details::shared_ptr database:: + inline connection_ptr database:: connection () { - return factory_->connect (); + // Go through the virtual connection_() function instead of + // directly to allow overriding. + // + return connection_ptr ( + static_cast (connection_ ())); + } + + inline transaction_impl* database:: + begin () + { + return connection ()->begin (); + } + + inline transaction_impl* database:: + begin_immediate () + { + return connection ()->begin_immediate (); + } + + inline transaction_impl* database:: + begin_exclusive () + { + return connection ()->begin_exclusive (); } } } diff --git a/odb/sqlite/forward.hxx b/odb/sqlite/forward.hxx index 63c3be4..a4e3376 100644 --- a/odb/sqlite/forward.hxx +++ b/odb/sqlite/forward.hxx @@ -16,6 +16,7 @@ namespace odb { class database; class connection; + typedef details::shared_ptr connection_ptr; class connection_factory; class transaction; class query; @@ -37,6 +38,12 @@ namespace odb namespace details { template <> + struct counter_type + { + typedef shared_base counter; + }; + + template <> struct counter_type { typedef shared_base counter; diff --git a/odb/sqlite/transaction-impl.cxx b/odb/sqlite/transaction-impl.cxx index 609a9c5..772b274 100644 --- a/odb/sqlite/transaction-impl.cxx +++ b/odb/sqlite/transaction-impl.cxx @@ -14,26 +14,26 @@ namespace odb namespace sqlite { transaction_impl:: - transaction_impl (database_type& db, lock l) - : odb::transaction_impl (db), connection_ (db.connection ()) + transaction_impl (connection_ptr c, lock l) + : odb::transaction_impl (c->database (), *c), connection_ (c) { - statement_cache& c (connection_->statement_cache ()); + statement_cache& sc (connection_->statement_cache ()); switch (l) { case deferred: { - c.begin_statement ().execute (); + sc.begin_statement ().execute (); break; } case immediate: { - c.begin_immediate_statement ().execute (); + sc.begin_immediate_statement ().execute (); break; } case exclusive: { - c.begin_exclusive_statement ().execute (); + sc.begin_exclusive_statement ().execute (); break; } } diff --git a/odb/sqlite/transaction-impl.hxx b/odb/sqlite/transaction-impl.hxx index 3b09bcf..8b5687b 100644 --- a/odb/sqlite/transaction-impl.hxx +++ b/odb/sqlite/transaction-impl.hxx @@ -22,7 +22,7 @@ namespace odb class LIBODB_SQLITE_EXPORT transaction_impl: public odb::transaction_impl { protected: - friend class database; + friend class connection; friend class transaction; typedef sqlite::database database_type; @@ -35,7 +35,7 @@ namespace odb exclusive }; - transaction_impl (database_type&, lock); + transaction_impl (connection_ptr, lock); virtual ~transaction_impl (); @@ -50,7 +50,7 @@ namespace odb connection (); private: - details::shared_ptr connection_; + connection_ptr connection_; }; } } -- cgit v1.1