aboutsummaryrefslogtreecommitdiff
path: root/odb/mssql/simple-object-statements.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/mssql/simple-object-statements.hxx')
-rw-r--r--odb/mssql/simple-object-statements.hxx77
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_;