diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-17 13:35:21 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2014-11-25 06:43:14 +0200 |
commit | d44d7c96d38453d5a971b813be4c6635bf0b38fb (patch) | |
tree | 3d3d0803f4ae707cf8926ce134ace4a35c08a8f5 | |
parent | f5826c7da4cc11d46a34e4a5e435cff2730c7263 (diff) |
Implement bulk database operation support for Oracle and SQL Server
-rw-r--r-- | odb/mysql/container-statements.hxx | 1 | ||||
-rw-r--r-- | odb/mysql/database.hxx | 4 | ||||
-rw-r--r-- | odb/mysql/database.ixx | 7 | ||||
-rw-r--r-- | odb/mysql/exceptions.cxx | 12 | ||||
-rw-r--r-- | odb/mysql/exceptions.hxx | 6 | ||||
-rw-r--r-- | odb/mysql/no-id-object-statements.hxx | 1 | ||||
-rw-r--r-- | odb/mysql/polymorphic-object-statements.hxx | 7 | ||||
-rw-r--r-- | odb/mysql/section-statements.hxx | 3 | ||||
-rw-r--r-- | odb/mysql/section-statements.txx | 2 | ||||
-rw-r--r-- | odb/mysql/simple-object-statements.hxx | 39 | ||||
-rw-r--r-- | odb/mysql/statement.cxx | 44 | ||||
-rw-r--r-- | odb/mysql/statement.hxx | 9 |
12 files changed, 104 insertions, 31 deletions
diff --git a/odb/mysql/container-statements.hxx b/odb/mysql/container-statements.hxx index be86cda..191d9f6 100644 --- a/odb/mysql/container-statements.hxx +++ b/odb/mysql/container-statements.hxx @@ -128,6 +128,7 @@ namespace odb insert_text_, versioned_, // Process if versioned. insert_image_binding_, + 0, false)); return *insert_; diff --git a/odb/mysql/database.hxx b/odb/mysql/database.hxx index 8d11e72..9192138 100644 --- a/odb/mysql/database.hxx +++ b/odb/mysql/database.hxx @@ -180,6 +180,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/mysql/database.ixx b/odb/mysql/database.ixx index 09fc641..68aecec 100644 --- a/odb/mysql/database.ixx +++ b/odb/mysql/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_mysql> (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/mysql/exceptions.cxx b/odb/mysql/exceptions.cxx index ddf5ce8..8e2375a 100644 --- a/odb/mysql/exceptions.cxx +++ b/odb/mysql/exceptions.cxx @@ -36,6 +36,12 @@ namespace odb return what_.c_str (); } + database_exception* database_exception:: + clone () const + { + return new database_exception (*this); + } + // // cli_exception // @@ -56,5 +62,11 @@ namespace odb { return what_.c_str (); } + + cli_exception* cli_exception:: + clone () const + { + return new cli_exception (*this); + } } } diff --git a/odb/mysql/exceptions.hxx b/odb/mysql/exceptions.hxx index 824f678..ea4e493 100644 --- a/odb/mysql/exceptions.hxx +++ b/odb/mysql/exceptions.hxx @@ -49,6 +49,9 @@ namespace odb virtual const char* what () const throw (); + virtual database_exception* + clone () const; + private: unsigned int error_; std::string sqlstate_; @@ -64,6 +67,9 @@ namespace odb virtual const char* what () const throw (); + virtual cli_exception* + clone () const; + private: std::string what_; }; diff --git a/odb/mysql/no-id-object-statements.hxx b/odb/mysql/no-id-object-statements.hxx index 0da7368..b2c5ce2 100644 --- a/odb/mysql/no-id-object-statements.hxx +++ b/odb/mysql/no-id-object-statements.hxx @@ -88,6 +88,7 @@ namespace odb object_traits::persist_statement, object_traits::versioned, // Process if versioned. insert_image_binding_, + 0, false)); return *persist_; diff --git a/odb/mysql/polymorphic-object-statements.hxx b/odb/mysql/polymorphic-object-statements.hxx index 63662df..1607926 100644 --- a/odb/mysql/polymorphic-object-statements.hxx +++ b/odb/mysql/polymorphic-object-statements.hxx @@ -314,6 +314,7 @@ namespace odb object_traits::persist_statement, object_traits::versioned, // Process if versioned. insert_image_binding_, + 0, false)); return *persist_; @@ -376,6 +377,7 @@ namespace odb return extra_statement_cache_.get ( conn_, image_, + id_image (), id_image_binding (), &id_image_binding ()); // Note, not id+version. } @@ -414,8 +416,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/mysql/section-statements.hxx b/odb/mysql/section-statements.hxx index bc83942..c4e83ac 100644 --- a/odb/mysql/section-statements.hxx +++ b/odb/mysql/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 mysql::select_statement select_statement_type; typedef mysql::update_statement update_statement_type; @@ -43,7 +44,7 @@ namespace odb typedef mysql::connection connection_type; section_statements (connection_type&, - image_type&, + image_type&, id_image_type&, binding& id, binding& idv); connection_type& diff --git a/odb/mysql/section-statements.txx b/odb/mysql/section-statements.txx index 61bfafe..78fb183 100644 --- a/odb/mysql/section-statements.txx +++ b/odb/mysql/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/mysql/simple-object-statements.hxx b/odb/mysql/simple-object-statements.hxx index 1ce8472..f5d52c0 100644 --- a/odb/mysql/simple-object-statements.hxx +++ b/odb/mysql/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 mysql::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_; @@ -353,6 +360,7 @@ namespace odb object_traits::persist_statement, object_traits::versioned, // Process if versioned. insert_image_binding_, + (object_traits::auto_id ? &id_image_binding_ : 0), false)); return *persist_; @@ -426,7 +434,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: @@ -472,8 +482,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/mysql/statement.cxx b/odb/mysql/statement.cxx index 4b80913..85732de 100644 --- a/odb/mysql/statement.cxx +++ b/odb/mysql/statement.cxx @@ -564,12 +564,14 @@ 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_version_ (0) + param_version_ (0), + returning_ (returning) { } @@ -578,13 +580,15 @@ namespace odb const char* text, bool process, binding& param, + binding* returning, bool copy_text) : statement (conn, text, statement_insert, (process ? ¶m : 0), false, copy_text), param_ (param), - param_version_ (0) + param_version_ (0), + returning_ (returning) { } @@ -625,13 +629,35 @@ namespace odb translate_error (conn_, stmt_); } - return true; - } + if (returning_ != 0) + { + unsigned long long i (mysql_stmt_insert_id (stmt_)); - unsigned long long insert_statement:: - id () - { - return static_cast<unsigned long long> (mysql_stmt_insert_id (stmt_)); + MYSQL_BIND& b (returning_->bind[0]); + void* v (b.buffer); + + switch (b.buffer_type) + { + case MYSQL_TYPE_TINY: + *static_cast<unsigned char*> (v) = static_cast<unsigned char> (i); + break; + case MYSQL_TYPE_SHORT: + *static_cast<unsigned short*> (v) = static_cast<unsigned short> (i); + break; + case MYSQL_TYPE_LONG: + *static_cast<unsigned int*> (v) = static_cast<unsigned int> (i); + break; + case MYSQL_TYPE_LONGLONG: + *static_cast<unsigned long long*> (v) = i; + break; + default: + assert (false); // Auto id column type is not an integer. + } + + *b.is_null = false; + } + + return true; } // update_statement diff --git a/odb/mysql/statement.hxx b/odb/mysql/statement.hxx index 3e7afad..faf8e01 100644 --- a/odb/mysql/statement.hxx +++ b/odb/mysql/statement.hxx @@ -238,12 +238,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* returning, bool copy_text = true); // Return true if successful and false if the row is a duplicate. @@ -252,9 +254,6 @@ namespace odb bool execute (); - unsigned long long - id (); - private: insert_statement (const insert_statement&); insert_statement& operator= (const insert_statement&); @@ -262,6 +261,8 @@ namespace odb private: binding& param_; std::size_t param_version_; + + binding* returning_; }; class LIBODB_MYSQL_EXPORT update_statement: public statement |