diff options
Diffstat (limited to 'odb/mssql/simple-object-statements.hxx')
-rw-r--r-- | odb/mssql/simple-object-statements.hxx | 77 |
1 files changed, 51 insertions, 26 deletions
diff --git a/odb/mssql/simple-object-statements.hxx b/odb/mssql/simple-object-statements.hxx index ab43439..77b1c34 100644 --- a/odb/mssql/simple-object-statements.hxx +++ b/odb/mssql/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 mssql::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_; @@ -155,7 +162,7 @@ namespace odb typedef T object_type; typedef object_traits_impl<object_type, id_mssql> object_traits; - optimistic_data (bind*); + optimistic_data (bind*, std::size_t skip, SQLUSMALLINT* status); binding* id_image_binding () {return &id_image_binding_;} @@ -170,7 +177,7 @@ namespace odb template <typename T> struct optimistic_data<T, false> { - optimistic_data (bind*) {} + optimistic_data (bind*, std::size_t, SQLUSMALLINT*) {} binding* id_image_binding () {return 0;} @@ -276,9 +283,9 @@ namespace odb // Object image. // image_type& - image () + image (std::size_t i = 0) { - return image_; + return images_[i].obj; } // Insert binding. @@ -323,7 +330,7 @@ namespace odb // Object id image and binding. // id_image_type& - id_image () {return id_image_;} + id_image (std::size_t i = 0) {return images_[i].id;} std::size_t id_image_version () const {return id_image_version_;} @@ -339,7 +346,7 @@ namespace odb // at the same time. // binding& - optimistic_id_image_binding () {return od_.id_image_binding_;} + optimistic_id_image_binding () {return *od_.id_image_binding ();} // Statements. // @@ -355,6 +362,9 @@ namespace odb insert_image_binding_, object_traits::auto_id, object_traits::rowversion, + (object_traits::rowversion + ? &optimistic_id_image_binding () + : (object_traits::auto_id ? &id_image_binding () : 0)), false)); return *persist_; @@ -385,9 +395,10 @@ namespace odb new (details::shared) update_statement_type ( conn_, object_traits::update_statement, - object_traits::versioned, // Process if versioned. + true, // Unique (0 or 1). + object_traits::versioned, // Process if versioned. update_image_binding_, - object_traits::rowversion, + object_traits::rowversion ? &optimistic_id_image_binding () : 0, false)); return *update_; @@ -401,6 +412,7 @@ namespace odb new (details::shared) delete_statement_type ( conn_, object_traits::erase_statement, + true, // Unique (0 or 1 affected rows). id_image_binding_, false)); @@ -429,7 +441,9 @@ namespace odb extra_statement_cache () { return extra_statement_cache_.get ( - conn_, image_, id_image_binding_, od_.id_image_binding ()); + conn_, + images_[0].obj, images_[0].id, + id_image_binding_, od_.id_image_binding ()); } public: @@ -476,10 +490,22 @@ 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_; + + // The UPDATE statement uses both the object and id image. Keep + // them next to each other so that the same skip distance can + // be used in batch binding. + // + struct images + { + image_type obj; + id_image_type id; + }; - image_type image_; + images images_[object_traits::batch]; + SQLUSMALLINT status_[object_traits::batch]; // Select binding. // @@ -508,10 +534,9 @@ namespace odb bind update_image_bind_[update_column_count + id_column_count + managed_optimistic_column_count]; - // Id image binding (only used as a parameter). Uses the suffix in - // the update bind. + // Id image binding (only used as a parameter or in OUTPUT for + // auto id and version). Uses the suffix in the update bind. // - id_image_type id_image_; std::size_t id_image_version_; binding id_image_binding_; |