From 2db43d4c2f2bed0348d781367090e633ad02779f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 17 Nov 2014 09:08:25 +0200 Subject: Implement bulk database operation support for Oracle and SQL Server --- odb/pgsql/container-statements.hxx | 2 +- odb/pgsql/database.hxx | 4 +++ odb/pgsql/database.ixx | 7 +++++ odb/pgsql/exceptions.cxx | 12 +++++++++ odb/pgsql/exceptions.hxx | 6 +++++ odb/pgsql/no-id-object-statements.hxx | 2 +- odb/pgsql/polymorphic-object-statements.hxx | 8 +++--- odb/pgsql/section-statements.hxx | 2 ++ odb/pgsql/section-statements.txx | 1 + odb/pgsql/simple-object-statements.hxx | 30 ++++++++++++--------- odb/pgsql/statement.cxx | 42 +++-------------------------- odb/pgsql/statement.hxx | 14 +++------- 12 files changed, 63 insertions(+), 67 deletions(-) diff --git a/odb/pgsql/container-statements.hxx b/odb/pgsql/container-statements.hxx index 0bd222d..80aa30c 100644 --- a/odb/pgsql/container-statements.hxx +++ b/odb/pgsql/container-statements.hxx @@ -135,7 +135,7 @@ namespace odb insert_count_, insert_image_binding_, insert_image_native_binding_, - false, + 0, false)); return *insert_; diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx index dda8d31..c6bc05a 100644 --- a/odb/pgsql/database.hxx +++ b/odb/pgsql/database.hxx @@ -93,6 +93,10 @@ namespace odb template typename object_traits::id_type + persist (const T& object); + + template + typename object_traits::id_type persist (T* obj_ptr); template class P> diff --git a/odb/pgsql/database.ixx b/odb/pgsql/database.ixx index 21b5729..5324fc8 100644 --- a/odb/pgsql/database.ixx +++ b/odb/pgsql/database.ixx @@ -27,6 +27,13 @@ namespace odb template inline typename object_traits::id_type database:: + persist (const T& obj) + { + return persist_ (obj); + } + + template + inline typename object_traits::id_type database:: persist (T* p) { typedef typename object_traits::pointer_type object_pointer; diff --git a/odb/pgsql/exceptions.cxx b/odb/pgsql/exceptions.cxx index 23a47cb..f4ac22a 100644 --- a/odb/pgsql/exceptions.cxx +++ b/odb/pgsql/exceptions.cxx @@ -41,6 +41,12 @@ namespace odb return what_.c_str (); } + database_exception* database_exception:: + clone () const + { + return new database_exception (*this); + } + // // cli_exception // @@ -61,5 +67,11 @@ namespace odb { return what_.c_str (); } + + cli_exception* cli_exception:: + clone () const + { + return new cli_exception (*this); + } } } diff --git a/odb/pgsql/exceptions.hxx b/odb/pgsql/exceptions.hxx index d15cec0..6296b75 100644 --- a/odb/pgsql/exceptions.hxx +++ b/odb/pgsql/exceptions.hxx @@ -43,6 +43,9 @@ namespace odb virtual const char* what () const throw (); + virtual database_exception* + clone () const; + private: std::string sqlstate_; std::string message_; @@ -57,6 +60,9 @@ namespace odb virtual const char* what () const throw (); + virtual cli_exception* + clone () const; + private: std::string what_; }; diff --git a/odb/pgsql/no-id-object-statements.hxx b/odb/pgsql/no-id-object-statements.hxx index a95b6c5..2616eab 100644 --- a/odb/pgsql/no-id-object-statements.hxx +++ b/odb/pgsql/no-id-object-statements.hxx @@ -92,7 +92,7 @@ namespace odb insert_column_count, insert_image_binding_, insert_image_native_binding_, - false, + 0, false)); return *persist_; diff --git a/odb/pgsql/polymorphic-object-statements.hxx b/odb/pgsql/polymorphic-object-statements.hxx index f5ddcea..0e42cbf 100644 --- a/odb/pgsql/polymorphic-object-statements.hxx +++ b/odb/pgsql/polymorphic-object-statements.hxx @@ -330,7 +330,7 @@ namespace odb insert_column_count, insert_image_binding_, insert_image_native_binding_, - object_traits::auto_id, + 0, false)); return *persist_; @@ -405,6 +405,7 @@ namespace odb return extra_statement_cache_.get ( conn_, image_, + id_image (), id_image_binding (), &id_image_binding (), // Note, not id+version. root_statements_.id_image_native_binding (), @@ -446,8 +447,9 @@ namespace odb root_statements_type& root_statements_; base_statements_type& base_statements_; - extra_statement_cache_ptr - extra_statement_cache_; + extra_statement_cache_ptr extra_statement_cache_; image_type image_; diff --git a/odb/pgsql/section-statements.hxx b/odb/pgsql/section-statements.hxx index e7dcd9e..fd4910e 100644 --- a/odb/pgsql/section-statements.hxx +++ b/odb/pgsql/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 pgsql::select_statement select_statement_type; typedef pgsql::update_statement update_statement_type; @@ -44,6 +45,7 @@ namespace odb section_statements (connection_type&, image_type&, + id_image_type&, binding& id, binding& idv, native_binding& idn, diff --git a/odb/pgsql/section-statements.txx b/odb/pgsql/section-statements.txx index 4781833..2e46e4d 100644 --- a/odb/pgsql/section-statements.txx +++ b/odb/pgsql/section-statements.txx @@ -12,6 +12,7 @@ namespace odb section_statements:: section_statements (connection_type& conn, image_type& im, + id_image_type&, binding& id, binding& idv, native_binding& idn, diff --git a/odb/pgsql/simple-object-statements.hxx b/odb/pgsql/simple-object-statements.hxx index afa869a..f9d7e46 100644 --- a/odb/pgsql/simple-object-statements.hxx +++ b/odb/pgsql/simple-object-statements.hxx @@ -39,29 +39,31 @@ namespace odb // deleter function which will be initialized during allocation // (at that point we know that the cache class is defined). // - template + template struct extra_statement_cache_ptr { typedef I image_type; + typedef ID id_image_type; typedef pgsql::connection connection_type; extra_statement_cache_ptr (): p_ (0) {} ~extra_statement_cache_ptr () { if (p_ != 0) - (this->*deleter_) (0, 0, 0, 0, 0, 0); + (this->*deleter_) (0, 0, 0, 0, 0, 0, 0); } T& get (connection_type& c, image_type& im, + id_image_type& idim, binding& id, binding* idv, native_binding& idn, const Oid* idt) { if (p_ == 0) - allocate (&c, &im, &id, (idv != 0 ? idv : &id), &idn, idt); + allocate (&c, &im, &idim, &id, (idv != 0 ? idv : &id), &idn, idt); return *p_; } @@ -69,21 +71,21 @@ namespace odb private: void allocate (connection_type*, - image_type*, + image_type*, id_image_type*, binding*, binding*, native_binding*, const Oid*); private: T* p_; void (extra_statement_cache_ptr::*deleter_) ( connection_type*, - image_type*, + image_type*, id_image_type*, binding*, binding*, native_binding*, const Oid*); }; - template - void extra_statement_cache_ptr:: + template + void extra_statement_cache_ptr:: allocate (connection_type* c, - image_type* im, + image_type* im, id_image_type* idim, binding* id, binding* idv, native_binding* idn, const Oid* idt) { // To reduce object code size, this function acts as both allocator @@ -91,8 +93,8 @@ namespace odb // if (p_ == 0) { - p_ = new T (*c, *im, *id, *idv, *idn, idt); - deleter_ = &extra_statement_cache_ptr::allocate; + p_ = new T (*c, *im, *idim, *id, *idv, *idn, idt); + deleter_ = &extra_statement_cache_ptr::allocate; } else delete p_; @@ -381,7 +383,7 @@ namespace odb insert_column_count, insert_image_binding_, insert_image_native_binding_, - object_traits::auto_id, + (object_traits::auto_id ? &id_image_binding_ : 0), false)); return *persist_; @@ -471,6 +473,7 @@ namespace odb return extra_statement_cache_.get ( conn_, image_, + id_image_, id_image_binding_, od_.id_image_binding (), id_image_native_binding_, @@ -521,8 +524,9 @@ namespace odb template friend class polymorphic_derived_object_statements; - extra_statement_cache_ptr - extra_statement_cache_; + extra_statement_cache_ptr extra_statement_cache_; image_type image_; diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx index 895cff5..bd27243 100644 --- a/odb/pgsql/statement.cxx +++ b/odb/pgsql/statement.cxx @@ -698,7 +698,7 @@ namespace odb size_t types_count, binding& param, native_binding& native_param, - bool returning) + binding* returning) : statement (conn, name, text, statement_insert, (process ? ¶m : 0), false, @@ -718,7 +718,7 @@ namespace odb size_t types_count, binding& param, native_binding& native_param, - bool returning, + binding* returning, bool copy) : statement (conn, name, text, statement_insert, @@ -767,42 +767,8 @@ namespace odb translate_error (conn_, h); } - if (returning_) - { - // Get the id value that was returned using the RETURNING clause. - // - const char* v (PQgetvalue (h, 0, 0)); - - // While the ODB auto id type can only be INT or BIGINT, handle the - // SMALLINT integer in case we are dealing with a custom schema. - // - switch (PQftype (h, 0)) - { - case int2_oid: - { - id_ = endian_traits::ntoh ( - *reinterpret_cast (v)); - break; - } - case int4_oid: - { - id_ = endian_traits::ntoh ( - *reinterpret_cast (v)); - break; - } - case int8_oid: - { - id_ = endian_traits::ntoh ( - *reinterpret_cast (v)); - break; - } - default: - { - assert (false); - break; - } - } - } + if (returning_ != 0) + bind_result (returning_->bind, 1, h, 0, false); return true; } diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx index 6c6095c..8ecaa19 100644 --- a/odb/pgsql/statement.hxx +++ b/odb/pgsql/statement.hxx @@ -278,7 +278,7 @@ namespace odb std::size_t types_count, binding& param, native_binding& native_param, - bool returning); + binding* returning); insert_statement (connection_type& conn, const char* name, @@ -288,7 +288,7 @@ namespace odb std::size_t types_count, binding& param, native_binding& native_param, - bool returning, + binding* returning, bool copy_name_text = true); // Return true if successful and false if the row is a duplicate. @@ -297,12 +297,6 @@ namespace odb bool execute (); - unsigned long long - id () - { - return id_; - } - private: insert_statement (const insert_statement&); insert_statement& operator= (const insert_statement&); @@ -310,9 +304,7 @@ namespace odb private: binding& param_; native_binding& native_param_; - - bool returning_; - unsigned long long id_; + binding* returning_; }; class LIBODB_PGSQL_EXPORT update_statement: public statement -- cgit v1.1