Quoting Nick Kew <[EMAIL PROTECTED]>:
Erm, no. It it doesn't exist, that reduces to resetting trans->errnum.
Ah, yes. Sorry. I meant we return APR_ENOTIMPL if the database cannot
possibly support resetting of trans->errnum correctly (such as PGSQL).
Otherwise, we just reset (i.e. SQLite, Oracle, MySQL).
This would obviously need to be called every time an error code is
returned by query/select, right?
If the application wants to handle the error (other than in the default
manner) then yes.
Right.
Well, it's something we can initialise and reset to. It'll just give current
behaviour. Could be relevant in cases like oracle, where (according to
your earlier post) it will commit even when there's an error, so that
gives us three behaviours that are clearly distinct.
Hmm, let's assume that apr_dbd_transaction_end in the underlying
driver takes into account all three modes - it would still work only
for the last query/select before the call to transaction end. All
queries before that, for which reset was not executed, would not even
touch the database (due to the trans->errnum check at the beginning of
each function). So, reset needs to be called explicitly if something
is to happen in query/select after a bad status code.
Given that, it would be more uniform to ask callers to reset the error
code explicitly, even for the last query/select before end, if they
are convinced that this transaction should in fact be committed. And
once they do that, one commit mode is quite sufficient. Something like
this:
Two explicit modes:
#define APR_DBD_TRANSACTION_COMMIT 0
#define APR_DBD_TRANSACTION_ROLLBACK 1
For:
apr_dbd_transaction_mode_get()
apr_dbd_transaction_mode_set()
And another functions call:
apr_dbd_transaction_recover()
The latter would attempt to recover the transaction from the error (if
underlying database permits and it all works out). It would be used by
caller if any of the query/select functions return bad status code and
the caller is confident the transaction should proceed as normal.
This function would look something like this in the driver:
static int dbd_foo_transaction_recover(apr_dbd_transaction_t *trans) {
int ret = -1;
if (trans) {
ret = foo_recover(...);
if (ret == foo_success ) {
trans->errnum = 0;
}
}
return ret;
}
Databases that don't support such functionality (e.g. PostgreSQL)
would simply return APR_ENOTIMPL.
--
Bojan