diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-17 13:34:17 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-25 06:43:50 +0200 |
commit | 6ba692aabf2afae6dab83139ca5e219bfc614890 (patch) | |
tree | 75eec5e22602a5ddae9bc82c5d8253f922853c0c | |
parent | 3bb29e43f60229bcac00777c839174703f848c16 (diff) |
Implement bulk database operation support for Oracle and SQL Server
-rw-r--r-- | odb/sqlite/container-statements.hxx | 3 | ||||
-rw-r--r-- | odb/sqlite/database.hxx | 4 | ||||
-rw-r--r-- | odb/sqlite/database.ixx | 7 | ||||
-rw-r--r-- | odb/sqlite/exceptions.cxx | 18 | ||||
-rw-r--r-- | odb/sqlite/exceptions.hxx | 9 | ||||
-rw-r--r-- | odb/sqlite/no-id-object-statements.hxx | 3 | ||||
-rw-r--r-- | odb/sqlite/polymorphic-object-statements.hxx | 9 | ||||
-rw-r--r-- | odb/sqlite/section-statements.hxx | 3 | ||||
-rw-r--r-- | odb/sqlite/section-statements.txx | 2 | ||||
-rw-r--r-- | odb/sqlite/simple-object-statements.hxx | 41 | ||||
-rw-r--r-- | odb/sqlite/statement.cxx | 29 | ||||
-rw-r--r-- | odb/sqlite/statement.hxx | 10 |
12 files changed, 100 insertions, 38 deletions
diff --git a/odb/sqlite/container-statements.hxx b/odb/sqlite/container-statements.hxx index 058a255..4871fe8 100644 --- a/odb/sqlite/container-statements.hxx +++ b/odb/sqlite/container-statements.hxx @@ -126,7 +126,8 @@ namespace odb conn_, insert_text_, versioned_, // Process if versioned. - insert_image_binding_)); + insert_image_binding_, + 0)); return *insert_; } diff --git a/odb/sqlite/database.hxx b/odb/sqlite/database.hxx index 0eef6d5..f3d8248 100644 --- a/odb/sqlite/database.hxx +++ b/odb/sqlite/database.hxx @@ -124,6 +124,10 @@ namespace odb template <typename T> typename object_traits<T>::id_type + persist (const T& object); + + template <typename T> + typename object_traits<T>::id_type persist (T* obj_ptr); template <typename T, template <typename> class P> diff --git a/odb/sqlite/database.ixx b/odb/sqlite/database.ixx index d5918f0..5b21e36 100644 --- a/odb/sqlite/database.ixx +++ b/odb/sqlite/database.ixx @@ -27,6 +27,13 @@ namespace odb template <typename T> inline typename object_traits<T>::id_type database:: + persist (const T& obj) + { + return persist_<const T, id_sqlite> (obj); + } + + template <typename T> + inline typename object_traits<T>::id_type database:: persist (T* p) { typedef typename object_traits<T>::pointer_type object_pointer; diff --git a/odb/sqlite/exceptions.cxx b/odb/sqlite/exceptions.cxx index 08cdf90..ece5def 100644 --- a/odb/sqlite/exceptions.cxx +++ b/odb/sqlite/exceptions.cxx @@ -22,6 +22,12 @@ namespace odb return "transaction is forced to rollback"; } + forced_rollback* forced_rollback:: + clone () const + { + return new forced_rollback (*this); + } + // // database_exception // @@ -51,6 +57,12 @@ namespace odb return what_.c_str (); } + database_exception* database_exception:: + clone () const + { + return new database_exception (*this); + } + // // cli_exception // @@ -71,5 +83,11 @@ namespace odb { return what_.c_str (); } + + cli_exception* cli_exception:: + clone () const + { + return new cli_exception (*this); + } } } diff --git a/odb/sqlite/exceptions.hxx b/odb/sqlite/exceptions.hxx index 8a21d5e..6bae164 100644 --- a/odb/sqlite/exceptions.hxx +++ b/odb/sqlite/exceptions.hxx @@ -29,6 +29,9 @@ namespace odb { virtual const char* what () const throw (); + + virtual forced_rollback* + clone () const; }; struct LIBODB_SQLITE_EXPORT database_exception: odb::database_exception @@ -60,6 +63,9 @@ namespace odb virtual const char* what () const throw (); + virtual database_exception* + clone () const; + private: int error_; int extended_error_; @@ -75,6 +81,9 @@ namespace odb virtual const char* what () const throw (); + virtual cli_exception* + clone () const; + private: std::string what_; }; diff --git a/odb/sqlite/no-id-object-statements.hxx b/odb/sqlite/no-id-object-statements.hxx index 2e0cb05..a42616d 100644 --- a/odb/sqlite/no-id-object-statements.hxx +++ b/odb/sqlite/no-id-object-statements.hxx @@ -88,7 +88,8 @@ namespace odb conn_, object_traits::persist_statement, object_traits::versioned, // Process if versioned. - insert_image_binding_)); + insert_image_binding_, + 0)); } return *persist_; diff --git a/odb/sqlite/polymorphic-object-statements.hxx b/odb/sqlite/polymorphic-object-statements.hxx index 2586cb0..4464fa3 100644 --- a/odb/sqlite/polymorphic-object-statements.hxx +++ b/odb/sqlite/polymorphic-object-statements.hxx @@ -315,7 +315,8 @@ namespace odb conn_, object_traits::persist_statement, object_traits::versioned, // Process if versioned. - insert_image_binding_)); + insert_image_binding_, + 0)); } return *persist_; @@ -381,6 +382,7 @@ namespace odb return extra_statement_cache_.get ( conn_, image_, + id_image (), id_image_binding (), &id_image_binding ()); // Note, not id+version. } @@ -419,8 +421,9 @@ namespace odb root_statements_type& root_statements_; base_statements_type& base_statements_; - extra_statement_cache_ptr<extra_statement_cache_type, image_type> - extra_statement_cache_; + extra_statement_cache_ptr<extra_statement_cache_type, + image_type, + id_image_type> extra_statement_cache_; image_type image_; diff --git a/odb/sqlite/section-statements.hxx b/odb/sqlite/section-statements.hxx index dff5ec5..f52d531 100644 --- a/odb/sqlite/section-statements.hxx +++ b/odb/sqlite/section-statements.hxx @@ -36,6 +36,7 @@ namespace odb typedef ST traits; typedef typename traits::image_type image_type; + typedef typename traits::id_image_type id_image_type; typedef sqlite::select_statement select_statement_type; typedef sqlite::update_statement update_statement_type; @@ -43,7 +44,7 @@ namespace odb typedef sqlite::connection connection_type; section_statements (connection_type&, - image_type&, + image_type&, id_image_type&, binding& id, binding& idv); connection_type& diff --git a/odb/sqlite/section-statements.txx b/odb/sqlite/section-statements.txx index f005f74..19f6968 100644 --- a/odb/sqlite/section-statements.txx +++ b/odb/sqlite/section-statements.txx @@ -11,7 +11,7 @@ namespace odb template <typename T, typename ST> section_statements<T, ST>:: section_statements (connection_type& conn, - image_type& im, + image_type& im, id_image_type&, binding& id, binding& idv) : conn_ (conn), svm_ (0), diff --git a/odb/sqlite/simple-object-statements.hxx b/odb/sqlite/simple-object-statements.hxx index f438d90..801f791 100644 --- a/odb/sqlite/simple-object-statements.hxx +++ b/odb/sqlite/simple-object-statements.hxx @@ -39,49 +39,56 @@ namespace odb // deleter function which will be initialized during allocation // (at that point we know that the cache class is defined). // - template <typename T, typename I> + template <typename T, typename I, typename ID> struct extra_statement_cache_ptr { typedef I image_type; + typedef ID id_image_type; typedef sqlite::connection connection_type; extra_statement_cache_ptr (): p_ (0) {} ~extra_statement_cache_ptr () { if (p_ != 0) - (this->*deleter_) (0, 0, 0, 0); + (this->*deleter_) (0, 0, 0, 0, 0); } T& - get (connection_type& c, image_type& im, binding& id, binding* idv) + get (connection_type& c, + image_type& im, id_image_type& idim, + binding& id, binding* idv) { if (p_ == 0) - allocate (&c, &im, &id, (idv != 0 ? idv : &id)); + allocate (&c, &im, &idim, &id, (idv != 0 ? idv : &id)); return *p_; } private: void - allocate (connection_type*, image_type*, binding*, binding*); + allocate (connection_type*, + image_type*, id_image_type*, + binding*, binding*); private: T* p_; void (extra_statement_cache_ptr::*deleter_) ( - connection_type*, image_type*, binding*, binding*); + connection_type*, image_type*, id_image_type*, binding*, binding*); }; - template <typename T, typename I> - void extra_statement_cache_ptr<T, I>:: - allocate (connection_type* c, image_type* im, binding* id, binding* idv) + template <typename T, typename I, typename ID> + void extra_statement_cache_ptr<T, I, ID>:: + allocate (connection_type* c, + image_type* im, id_image_type* idim, + binding* id, binding* idv) { // To reduce object code size, this function acts as both allocator // and deleter. // if (p_ == 0) { - p_ = new T (*c, *im, *id, *idv); - deleter_ = &extra_statement_cache_ptr<T, I>::allocate; + p_ = new T (*c, *im, *idim, *id, *idv); + deleter_ = &extra_statement_cache_ptr<T, I, ID>::allocate; } else delete p_; @@ -354,7 +361,8 @@ namespace odb conn_, object_traits::persist_statement, object_traits::versioned, // Process if versioned. - insert_image_binding_)); + insert_image_binding_, + (object_traits::auto_id ? &id_image_binding_ : 0))); } return *persist_; @@ -430,7 +438,9 @@ namespace odb extra_statement_cache () { return extra_statement_cache_.get ( - conn_, image_, id_image_binding_, od_.id_image_binding ()); + conn_, + image_, id_image_, + id_image_binding_, od_.id_image_binding ()); } public: @@ -476,8 +486,9 @@ namespace odb template <typename T1> friend class polymorphic_derived_object_statements; - extra_statement_cache_ptr<extra_statement_cache_type, image_type> - extra_statement_cache_; + extra_statement_cache_ptr<extra_statement_cache_type, + image_type, + id_image_type> extra_statement_cache_; image_type image_; diff --git a/odb/sqlite/statement.cxx b/odb/sqlite/statement.cxx index d56f45f..09188cb 100644 --- a/odb/sqlite/statement.cxx +++ b/odb/sqlite/statement.cxx @@ -605,11 +605,13 @@ namespace odb insert_statement (connection_type& conn, const string& text, bool process, - binding& param) + binding& param, + binding* returning) : statement (conn, text, statement_insert, (process ? ¶m : 0), false), - param_ (param) + param_ (param), + returning_ (returning) { } @@ -617,11 +619,13 @@ namespace odb insert_statement (connection_type& conn, const char* text, bool process, - binding& param) + binding& param, + binding* returning) : statement (conn, text, statement_insert, (process ? ¶m : 0), false), - param_ (param) + param_ (param), + returning_ (returning) { } @@ -679,14 +683,17 @@ namespace odb translate_error (e, conn_); } - return true; - } + if (returning_ != 0) + { + bind& b (returning_->bind[0]); - unsigned long long insert_statement:: - id () - { - return static_cast<unsigned long long> ( - sqlite3_last_insert_rowid (conn_.handle ())); + *b.is_null = false; + *static_cast<long long*> (b.buffer) = + static_cast<long long> ( + sqlite3_last_insert_rowid (conn_.handle ())); + } + + return true; } // update_statement diff --git a/odb/sqlite/statement.hxx b/odb/sqlite/statement.hxx index 7d7f021..84d90d7 100644 --- a/odb/sqlite/statement.hxx +++ b/odb/sqlite/statement.hxx @@ -328,12 +328,14 @@ namespace odb insert_statement (connection_type& conn, const std::string& text, bool process_text, - binding& param); + binding& param, + binding* returning); insert_statement (connection_type& conn, const char* text, bool process_text, - binding& param); + binding& param, + binding* returning); // Return true if successful and false if the row is a duplicate. // All other errors are reported by throwing exceptions. @@ -341,15 +343,13 @@ namespace odb bool execute (); - unsigned long long - id (); - private: insert_statement (const insert_statement&); insert_statement& operator= (const insert_statement&); private: binding& param_; + binding* returning_; }; class LIBODB_SQLITE_EXPORT update_statement: public statement |