aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-11-14 16:24:50 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-11-14 16:24:50 +0200
commite1fa2e2e2ef912d08095c8f4f90eb6b810f3c107 (patch)
treec9935e99724d63871173267603a80fed3619f84a
parent6d29dfc7d766482cbe5578d662041431bd3d6dc9 (diff)
Old interface compatibility and testing fixes
Now all tests pass for both Oracle and SQL Server.
-rw-r--r--odb/oracle/container-statements.hxx2
-rw-r--r--odb/oracle/no-id-object-statements.hxx2
-rw-r--r--odb/oracle/polymorphic-object-statements.hxx8
-rw-r--r--odb/oracle/section-statements.hxx3
-rw-r--r--odb/oracle/section-statements.txx2
-rw-r--r--odb/oracle/simple-object-statements.hxx45
-rw-r--r--odb/oracle/statement.cxx115
-rw-r--r--odb/oracle/statement.hxx87
8 files changed, 172 insertions, 92 deletions
diff --git a/odb/oracle/container-statements.hxx b/odb/oracle/container-statements.hxx
index ef1733d..a0a1742 100644
--- a/odb/oracle/container-statements.hxx
+++ b/odb/oracle/container-statements.hxx
@@ -122,7 +122,7 @@ namespace odb
insert_text_,
versioned_, // Process if versioned.
insert_image_binding_,
- false));
+ 0));
return *insert_;
}
diff --git a/odb/oracle/no-id-object-statements.hxx b/odb/oracle/no-id-object-statements.hxx
index 0be8dac..fe4d8d0 100644
--- a/odb/oracle/no-id-object-statements.hxx
+++ b/odb/oracle/no-id-object-statements.hxx
@@ -88,7 +88,7 @@ namespace odb
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
insert_image_binding_,
- false));
+ 0));
return *persist_;
}
diff --git a/odb/oracle/polymorphic-object-statements.hxx b/odb/oracle/polymorphic-object-statements.hxx
index 81ea3c3..58ecdaa 100644
--- a/odb/oracle/polymorphic-object-statements.hxx
+++ b/odb/oracle/polymorphic-object-statements.hxx
@@ -306,7 +306,7 @@ namespace odb
object_traits::persist_statement,
object_traits::versioned, // Process if versioned.
insert_image_binding_,
- false));
+ 0));
return *persist_;
}
@@ -366,6 +366,7 @@ namespace odb
return extra_statement_cache_.get (
conn_,
image_,
+ id_image (),
id_image_binding (),
&id_image_binding ()); // Note, not id+version.
}
@@ -404,8 +405,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/oracle/section-statements.hxx b/odb/oracle/section-statements.hxx
index 3d32b65..eb61cc1 100644
--- a/odb/oracle/section-statements.hxx
+++ b/odb/oracle/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 oracle::select_statement select_statement_type;
typedef oracle::update_statement update_statement_type;
@@ -43,7 +44,7 @@ namespace odb
typedef oracle::connection connection_type;
section_statements (connection_type&,
- image_type&,
+ image_type&, id_image_type&,
binding& id, binding& idv);
connection_type&
diff --git a/odb/oracle/section-statements.txx b/odb/oracle/section-statements.txx
index 391550f..583b706 100644
--- a/odb/oracle/section-statements.txx
+++ b/odb/oracle/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/oracle/simple-object-statements.hxx b/odb/oracle/simple-object-statements.hxx
index 18e4270..0ee263a 100644
--- a/odb/oracle/simple-object-statements.hxx
+++ b/odb/oracle/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 oracle::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_;
@@ -395,8 +402,8 @@ namespace odb
new (details::shared) delete_statement_type (
conn_,
object_traits::erase_statement,
- id_image_binding_,
- true)); // Unique (0 or 1 affected rows).
+ true, // Unique (0 or 1 affected rows).
+ id_image_binding_));
return *erase_;
}
@@ -410,8 +417,7 @@ namespace odb
new (details::shared) delete_statement_type (
conn_,
object_traits::optimistic_erase_statement,
- od_.id_image_binding_,
- true)); // Unique (0 or 1 affected rows).
+ od_.id_image_binding_));
}
return *od_.erase_;
@@ -423,7 +429,9 @@ namespace odb
extra_statement_cache ()
{
return extra_statement_cache_.get (
- conn_, images_[0].obj, id_image_binding_, od_.id_image_binding ());
+ conn_,
+ images_[0].obj, images_[0].id,
+ id_image_binding_, od_.id_image_binding ());
}
public:
@@ -470,8 +478,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_;
// The UPDATE statement uses both the object and id image. Keep
// them next to each other so that the same skip distance can
diff --git a/odb/oracle/statement.cxx b/odb/oracle/statement.cxx
index 27fa867..f4d9eef 100644
--- a/odb/oracle/statement.cxx
+++ b/odb/oracle/statement.cxx
@@ -1284,7 +1284,7 @@ namespace odb
// Clear the status array.
//
- memset (status_, sizeof (status_), 0);
+ memset (status_, 0, n * sizeof (status_[0]));
// @@ TODO allocate per batch stmt (maybe lazily here if NULL).
//
@@ -1314,7 +1314,7 @@ namespace odb
if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
translate_error (err1, r);
- cerr << "NUM_DML_ERRORS: " << errors << endl;
+ //cerr << "NUM_DML_ERRORS: " << errors << endl;
errors_ = errors;
if (errors != 0)
@@ -1393,7 +1393,7 @@ namespace odb
rows = static_cast<unsigned long long> (n);
}
- cerr << "total: " << rows << endl;
+ //cerr << "total: " << rows << endl;
if (n_ > 1) // Batch.
{
@@ -1869,12 +1869,11 @@ namespace odb
// the last extracted size after OCIStmtExecute() below. Thanks,
// Oracle!
//
- if (it != 0)
- {
- *reinterpret_cast<ub2*> (
- reinterpret_cast<char*> (b.size) + (it - 1) * skip) =
- static_cast<ub2> (st.ret_size_);
- }
+ if (st.ret_prev_ != 0)
+ *st.ret_prev_ = static_cast<ub2> (st.ret_size_);
+
+ st.ret_prev_ = reinterpret_cast<ub2*> (
+ reinterpret_cast<char*> (b.size) + it * skip);
*size = &st.ret_size_;
}
@@ -1983,6 +1982,9 @@ namespace odb
{
OCIError* err (conn_.error_handle ());
+ if (ret_ != 0)
+ ret_prev_ = 0;
+
// Ignore ORA-00001 error code, see fetch() below for details.
//
sword r (bulk_statement::execute (n, mex, (ret_ == 0 ? 1 : 0)));
@@ -1995,34 +1997,25 @@ namespace odb
sb4 e;
OCIErrorGet (err, 1, 0, &e, 0, 0, OCI_HTYPE_ERROR);
fetch (r, e);
+
+ if (result_) // If fetch() hasn't translated the error.
+ translate_error (err, r, &conn_, 0, mex_); // Can return.
+
return n_;
}
// Store the last returned id size (see odb_oracle_returning_out()
// for details).
//
- if (ret_ != 0)
- {
- size_t n (n_);
-
- // Find the index of the last sucessefully processed parameter set.
- //
- if (n != 1)
- for (; n != 0 && status_[n - 1] != 0; --n) ;
-
- if (n != 0) // They all might have failed.
- {
- *reinterpret_cast<ub2*> (
- reinterpret_cast<char*> (
- ret_->bind[0].size) + (n - 1) * ret_->skip) =
- static_cast<ub2> (ret_size_);
- }
- }
+ if (ret_ != 0 && ret_prev_ != 0)
+ *ret_prev_ = static_cast<ub2> (ret_size_);
if (status_ == 0) // Non-batch mode.
fetch (OCI_SUCCESS, 0);
else
+ {
fetch (status_[i_] == 0 ? OCI_SUCCESS : OCI_ERROR, status_[i_]);
+ }
return n_;
}
@@ -2055,6 +2048,23 @@ namespace odb
update_statement::
update_statement (connection_type& conn,
const string& text,
+ bool process,
+ binding& param)
+ : bulk_statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false,
+ param.batch, param.status),
+ unique_ (false)
+ {
+ assert (param.batch == 1); // Specify unique_hint explicitly.
+
+ if (!empty ())
+ bind_param (param.bind, param.count, param.batch, param.skip);
+ }
+
+ update_statement::
+ update_statement (connection_type& conn,
+ const string& text,
bool unique,
bool process,
binding& param)
@@ -2071,6 +2081,23 @@ namespace odb
update_statement::
update_statement (connection_type& conn,
const char* text,
+ bool process,
+ binding& param)
+ : bulk_statement (conn,
+ text, statement_update,
+ (process ? &param : 0), false,
+ param.batch, param.status),
+ unique_ (false)
+ {
+ assert (param.batch == 1); // Specify unique_hint explicitly.
+
+ if (!empty ())
+ bind_param (param.bind, param.count, param.batch, param.skip);
+ }
+
+ update_statement::
+ update_statement (connection_type& conn,
+ const char* text,
bool unique,
bool process,
binding& param)
@@ -2130,8 +2157,22 @@ namespace odb
delete_statement::
delete_statement (connection_type& conn,
const string& text,
- binding& param,
- bool unique)
+ binding& param)
+ : bulk_statement (conn,
+ text, statement_delete,
+ 0, false,
+ param.batch, param.status),
+ unique_ (false)
+ {
+ assert (param.batch == 1); // Specify unique_hint explicitly.
+ bind_param (param.bind, param.count, param.batch, param.skip);
+ }
+
+ delete_statement::
+ delete_statement (connection_type& conn,
+ const string& text,
+ bool unique,
+ binding& param)
: bulk_statement (conn,
text, statement_delete,
0, false,
@@ -2144,8 +2185,22 @@ namespace odb
delete_statement::
delete_statement (connection_type& conn,
const char* text,
- binding& param,
- bool unique)
+ binding& param)
+ : bulk_statement (conn,
+ text, statement_delete,
+ 0, false,
+ param.batch, param.status),
+ unique_ (false)
+ {
+ assert (param.batch == 1); // Specify unique_hint explicitly.
+ bind_param (param.bind, param.count, param.batch, param.skip);
+ }
+
+ delete_statement::
+ delete_statement (connection_type& conn,
+ const char* text,
+ bool unique,
+ binding& param)
: bulk_statement (conn,
text, statement_delete,
0, false,
diff --git a/odb/oracle/statement.hxx b/odb/oracle/statement.hxx
index db032fa..f90efa3 100644
--- a/odb/oracle/statement.hxx
+++ b/odb/oracle/statement.hxx
@@ -317,45 +317,25 @@ namespace odb
// Return the number of parameter sets (out of n) that were attempted.
//
std::size_t
- execute (std::size_t n = 1, multiple_exceptions* = 0);
+ execute (std::size_t n, multiple_exceptions*);
// Return true if successful and false if this row is a duplicate.
// All other errors are reported via exceptions.
//
bool
- result (std::size_t i = 0);
+ result (std::size_t i);
+
+ bool
+ execute ()
+ {
+ execute (1, 0);
+ return result (0);
+ }
private:
insert_statement (const insert_statement&);
insert_statement& operator= (const insert_statement&);
- /*
- @@ RM
-
- // Only OCI versions 11.2 and greater support conversion of the internal
- // Oracle type NUMBER to an external 64-bit integer type. If we detect
- // version 11.2 or greater we provide an unsigned long long image.
- // Otherwise, we revert to using a NUMBER image and manipulate it using
- // the custom conversion algorithms found in details/number.hxx.
- //
- public:
- struct id_bind_type
- {
- union
- {
- struct
- {
- char buffer[21];
- ub4 size;
- } number;
-
- unsigned long long integer;
- } id;
-
- sb2 indicator;
- };
- */
-
private:
void
init (binding& param);
@@ -366,6 +346,7 @@ namespace odb
public: // For odb_oracle_returning_*().
binding* ret_;
ub4 ret_size_; // You don't want to know (see statement.cxx).
+ ub2* ret_prev_;
private:
bool result_;
@@ -394,12 +375,22 @@ namespace odb
//
update_statement (connection_type& conn,
const std::string& text,
+ bool process_text,
+ binding& param);
+
+ update_statement (connection_type& conn,
+ const std::string& text,
bool unique_hint,
bool process_text,
binding& param);
update_statement (connection_type& conn,
const char* text,
+ bool process_text,
+ binding& param);
+
+ update_statement (connection_type& conn,
+ const char* text,
bool unique_hint,
bool process_text,
binding& param);
@@ -407,7 +398,7 @@ namespace odb
// Return the number of parameter sets (out of n) that were attempted.
//
std::size_t
- execute (std::size_t n = 1, multiple_exceptions* = 0);
+ execute (std::size_t n, multiple_exceptions*);
// Return the number of rows affected (deleted) by the parameter
// set. If this is a batch (n > 1 in execute() call above) and it
@@ -418,7 +409,14 @@ namespace odb
using bulk_statement::result_unknown;
unsigned long long
- result (std::size_t i = 0);
+ result (std::size_t i);
+
+ unsigned long long
+ execute ()
+ {
+ execute (1, 0);
+ return result (0);
+ }
private:
update_statement (const update_statement&);
@@ -452,18 +450,26 @@ namespace odb
//
delete_statement (connection_type& conn,
const std::string& text,
- binding& param,
- bool unique_hint = false);
+ binding& param);
+
+ delete_statement (connection_type& conn,
+ const std::string& text,
+ bool unique_hint,
+ binding& param);
delete_statement (connection_type& conn,
const char* text,
- binding& param,
- bool unique_hint = false);
+ binding& param);
+
+ delete_statement (connection_type& conn,
+ const char* text,
+ bool unique_hint,
+ binding& param);
// Return the number of parameter sets (out of n) that were attempted.
//
std::size_t
- execute (std::size_t n = 1, multiple_exceptions* = 0);
+ execute (std::size_t n, multiple_exceptions*);
// Return the number of rows affected (deleted) by the parameter
// set. If this is a batch (n > 1 in execute() call above) and it
@@ -474,7 +480,14 @@ namespace odb
using bulk_statement::result_unknown;
unsigned long long
- result (std::size_t i = 0);
+ result (std::size_t i);
+
+ unsigned long long
+ execute ()
+ {
+ execute (1, 0);
+ return result (0);
+ }
private:
delete_statement (const delete_statement&);