aboutsummaryrefslogtreecommitdiff
path: root/odb/oracle/statement.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'odb/oracle/statement.cxx')
-rw-r--r--odb/oracle/statement.cxx142
1 files changed, 69 insertions, 73 deletions
diff --git a/odb/oracle/statement.cxx b/odb/oracle/statement.cxx
index e932dab..5ca1a98 100644
--- a/odb/oracle/statement.cxx
+++ b/odb/oracle/statement.cxx
@@ -1244,12 +1244,12 @@ namespace odb
0,
n == 1 ? OCI_DEFAULT : OCI_BATCH_ERRORS));
- // If the statement failed as a whole, assume only the first row
- // was attempted (and failed). Otherwise, in the batch errors mode,
- // all the rows are always attempted (let's hope this is true).
+ // If the statement failed as a whole, assume no parameter sets
+ // were attempted. Otherwise, in the batch errors mode, all the
+ // sets are always attempted (let's hope this is actually true).
//
i_ = 0;
- n_ = (r == OCI_ERROR || r == OCI_INVALID_HANDLE ? 1 : n);
+ n_ = (r == OCI_ERROR || r == OCI_INVALID_HANDLE ? 0 : n);
if (mex_ != 0)
{
@@ -1913,6 +1913,9 @@ namespace odb
{
sword r (bulk_statement::execute (n, mex));
+ // Statement failed as a whole, assume no parameter sets were
+ // attempted.
+ //
if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
{
fetch (r, conn_.error_handle ());
@@ -1926,7 +1929,7 @@ namespace odb
{
size_t n (n_);
- // Find the index of the last sucessefully processed row.
+ // Find the index of the last sucessefully processed parameter set.
//
if (n != 1)
for (; n != 0 && status_[n - 1] != 0; --n) ;
@@ -1981,11 +1984,11 @@ namespace odb
{
assert ((i_ == i || i_ + 1 == i) && i < n_);
- // Get to the next row if necessary.
+ // Get to the next parameter set if necessary.
//
if (i != i_)
{
- mex_->current (++i_); // It cannot be NULL since this is a batch.
+ mex_->current (++i_); // mex cannot be NULL since this is a batch.
fetch (status_[i_] == 0 ? OCI_SUCCESS : OCI_ERROR, status_[i_]);
}
@@ -2082,11 +2085,13 @@ namespace odb
delete_statement::
delete_statement (connection_type& conn,
const string& text,
- binding& param)
+ binding& param,
+ bool unique)
: bulk_statement (conn,
text, statement_delete,
0, false,
- param.batch, param.status)
+ param.batch, param.status),
+ unique_ (unique)
{
bind_param (param.bind, param.count, param.batch, param.skip);
}
@@ -2094,11 +2099,13 @@ namespace odb
delete_statement::
delete_statement (connection_type& conn,
const char* text,
- binding& param)
+ binding& param,
+ bool unique)
: bulk_statement (conn,
text, statement_delete,
0, false,
- param.batch, param.status)
+ param.batch, param.status),
+ unique_ (unique)
{
bind_param (param.bind, param.count, param.batch, param.skip);
}
@@ -2107,30 +2114,21 @@ namespace odb
execute (size_t n, multiple_exceptions* mex)
{
sword r (bulk_statement::execute (n, mex));
+ OCIError* err (conn_.error_handle ());
+ // Statement failed as a whole, assume no parameter sets were
+ // attempted.
+ //
if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
{
- fetch (r, conn_.error_handle ());
+ fetch (r, err);
return n_;
}
- if (n == 1) // n and n_ are really the same here.
- fetch (OCI_SUCCESS, 0);
- else
- fetch (status_[i_] == 0 ? OCI_SUCCESS : OCI_ERROR, status_[i_]);
-
- return n_;
- }
-
- void delete_statement::
- fetch (sword r, OCIError* err1)
- {
- if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
- translate_error (err1, r, &conn_, i_, mex_); // Can return.
- else
+ // Figure out the affected row count.
+ //
{
ub4 rows (0);
- OCIError* err (conn_.error_handle ());
r = OCIAttrGet (stmt_,
OCI_HTYPE_STMT,
&rows,
@@ -2141,67 +2139,65 @@ namespace odb
if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
translate_error (err, r);
- cerr << "fetch: " << rows << endl;
-
result_ = static_cast<unsigned long long> (rows);
}
- }
- unsigned long long delete_statement::
- result (std::size_t i)
- {
- assert ((i_ == i || i_ + 1 == i) && i < n_);
+ cerr << "total: " << result_ << endl;
- // Get to the next row if necessary.
- //
- if (i != i_)
+ if (n_ > 1) // Batch.
{
- mex_->current (++i_); // It cannot be NULL since this is a batch.
- fetch (status_[i_] == 0 ? OCI_SUCCESS : OCI_ERROR, status_[i_]);
- }
+ if (result_ != 0) // Some rows did get affected.
+ {
+ size_t p (n_);
- return result_;
- }
+ // Subtract the parameter sets that failed since they haven't
+ // affected any rows.
+ //
+ for (size_t i (0); i != n_; ++i)
+ if (status_[i_] != 0)
+ p--;
- /*
- unsigned long long delete_statement::
- execute ()
- {
- {
- odb::tracer* t;
- if ((t = conn_.transaction_tracer ()) ||
- (t = conn_.tracer ()) ||
- (t = conn_.database ().tracer ()))
- t->execute (conn_, *this);
+ if (p > 1) // True batch.
+ {
+ if (unique_) // Each can affect 0 or 1 row.
+ {
+ result_ = (p == static_cast<size_t> (result_)
+ ? 1
+ : result_unknown);
+ }
+ else
+ result_ = result_unknown;
+ }
+ }
}
- OCIError* err (conn_.error_handle ());
+ if (n == 1) // n and n_ are really the same here.
+ fetch (OCI_SUCCESS, 0);
+ else
+ fetch (status_[i_] == 0 ? OCI_SUCCESS : OCI_ERROR, status_[i_]);
- sword r (OCIStmtExecute (conn_.handle (),
- stmt_,
- err,
- 1,
- 0,
- 0,
- 0,
- OCI_DEFAULT));
+ return n_;
+ }
+ void delete_statement::
+ fetch (sword r, OCIError* err)
+ {
if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
- translate_error (conn_, r);
+ translate_error (err, r, &conn_, i_, mex_); // Can return.
+ }
- ub4 row_count (0);
- r = OCIAttrGet (stmt_,
- OCI_HTYPE_STMT,
- &row_count,
- 0,
- OCI_ATTR_ROW_COUNT,
- err);
+ unsigned long long delete_statement::
+ result (std::size_t i)
+ {
+ assert ((i_ == i || i_ + 1 == i) && i < n_);
- if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
- translate_error (err, r);
+ if (i != i_)
+ {
+ mex_->current (++i_); // mex cannot be NULL since this is a batch.
+ fetch (status_[i_] == 0 ? OCI_SUCCESS : OCI_ERROR, status_[i_]);
+ }
- return static_cast<unsigned long long> (row_count);
+ return result_;
}
- */
}
}