Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Chris Darroch
Bojan Smojver wrote:

 Here is the patch along the lines of setting the modes of the  
 transaction. It doesn't have force commit, but if the list decides  
 that it's the right thing to do, I'll rework. I didn't test this -  
 it's just a prototype. A patch for folks using MySQL is included as  
 well.

   Looks pretty good to me.  I think you're right that we only
need commit and rollback as options for the end of a transaction,
but for possibly surprising reason (see below)

Nick Kew wrote:

 There's rather more than that: after any failed operation within
 a transaction, apr_dbd assumes transaction failure and declines
 to attempt any further ops, without reference to the backend.

   I think perhaps we should remove this logic from all the drivers
entirely.  Here's why, and it connects back to my initial notion
of a forceable commit option, which I realize now was really
based on an instinct that I'd sometimes want to override the
built-in decision by apr_dbd to cancel my transaction.

   A simple example from (my) real life would be that I sometimes
want to insert a row and, if a constraint violation occurs, do
something else.  If I do that work outside an apr_dbd transaction,
no problem.  If I do it inside, though, apr_dbd will prevent
me from proceeding once I get the constraint violation.

   Applications using apr_dbd without transactions already have
to handle all the possible errors that they care about from
the databases they're using.  We don't, for example, have the
apr_dbd drivers attempt to map all possible DB errors to a
standard set of APR errors -- that would just be an impossible task,
I think.  So I'm inclined to say that when using transactions,
things should be no different; apr_dbd should get out of the
way and let the application decide which errors it can recover from.

   Here's another real-life example; this one is database-specific.
I sometimes register application-defined error codes with Oracle
and then set up triggers to throw those errors based on some PL/SQL
logic.  These are errors that are meaningful to my higher-level
application and in some cases signal it to do something else;
I don't really want apr_dbd deciding that one of these errors means
the whole transaction is bad.

   Thoughts, flames?

Chris.

-- 
GPG Key ID: 366A375B
GPG Key Fingerprint: 485E 5041 17E1 E2BB C263  E4DE C8E3 FA36 366A 375B


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Nick Kew
On Monday 01 May 2006 16:47, Chris Darroch wrote:

 Nick Kew wrote:
  There's rather more than that: after any failed operation within
  a transaction, apr_dbd assumes transaction failure and declines
  to attempt any further ops, without reference to the backend.

I think perhaps we should remove this logic from all the drivers
 entirely.  Here's why, and it connects back to my initial notion
 of a forceable commit option, which I realize now was really
 based on an instinct that I'd sometimes want to override the
 built-in decision by apr_dbd to cancel my transaction.

Well, postgresql will give us essentially the same logic within its
transactions, and I had an idea other databases did similar things.
Cheaper for apr_dbd to do it without troubling the backend, and
I'd be reluctant to change that, at least as default behaviour.

A simple example from (my) real life would be that I sometimes
 want to insert a row and, if a constraint violation occurs, do
 something else.  If I do that work outside an apr_dbd transaction,
 no problem.  If I do it inside, though, apr_dbd will prevent
 me from proceeding once I get the constraint violation.

OK, fairy nuff.

Bojan's proposed patch (or some variant on it) will set transaction mode.
How about if we add a further APR_DBD_TRANSACTION_CLEARERR flag
(to be ORed with the mode) that'll let the application clear an error.
Drivers could reset the application state and make any corresponding
calls to the backend.  Would you be happy with that?

-- 
Nick Kew


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Chris Darroch
Nick:

 Bojan's proposed patch (or some variant on it) will set transaction mode.
 How about if we add a further APR_DBD_TRANSACTION_CLEARERR flag
 (to be ORed with the mode) that'll let the application clear an error.
 Drivers could reset the application state and make any corresponding
 calls to the backend.  Would you be happy with that?

   Sounds good -- if you see an error you can handle, you clear
the transaction's error state back to ok, and apr_dbd lets you
proceed.  Seems very reasonable to me; thanks!

Chris.

-- 
GPG Key ID: 366A375B
GPG Key Fingerprint: 485E 5041 17E1 E2BB C263  E4DE C8E3 FA36 366A 375B



Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver
On Mon, 2006-05-01 at 14:11 -0400, Chris Darroch wrote:

Sounds good -- if you see an error you can handle, you clear
 the transaction's error state back to ok, and apr_dbd lets you
 proceed.  Seems very reasonable to me; thanks!

Perhaps. However, it would seem that not all databases behave the same
on error mid-transaction. Compare SQLite3 with PostgreSQL:

--
sqlite create table test (a text primary key);
sqlite begin;
sqlite insert into test values ('a');
sqlite insert into test values ('a');
SQL error: column a is not unique
sqlite end;
sqlite select * from test;
a-- ONE ROW INSERTED!
--

--
postgres=# create table test (a text primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index
test_pkey for table test
CREATE TABLE
postgres=# begin;
BEGIN
postgres=# insert into test values ('a');
INSERT 0 1
postgres=# insert into test values ('a');
ERROR:  duplicate key violates unique constraint test_pkey
postgres=# end;
ROLLBACK
postgres=#  select * from test;
 a
---
(0 rows)-- NOTHING INSERTED!
--

In other words, once PostgreSQL encounters an error mid-transaction, it
would seem that one needs a savepoint to fix things before anything
gets committed. Clearing APR DBD error, doesn't help with PostgreSQL -
the transaction will still be rolled back by the database. MySQL 5
behaves like SQLite3. Not sure what Oracle does - I can check when I get
to work later on (but I'm guessing it would be similar to PostgreSQL).

Maybe there is a way to tell PostgreSQL not to fail - not sure...

-- 
Bojan



Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver
On Mon, 2006-05-01 at 12:41 -0700, Tyler MacDonald wrote:

 Maybe if MySQL is detected APR should refuse to support
 transactions and tell the end user to find a non-broken database engine. :-)

He, he... Something like this:

#define APR_EGOFINDOTHERDB 9

-- 
Bojan



Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Nick Kew
On Monday 01 May 2006 20:50, Bojan Smojver wrote:
 On Mon, 2006-05-01 at 12:41 -0700, Tyler MacDonald wrote:

huh?  Not in my mailbox, nor at marc.theaimsgroup.com ...

  Maybe if MySQL is detected APR should refuse to support
  transactions and tell the end user to find a non-broken database engine.
  :-)

AIUI, MySQL transaction support depends on the mysql backend
selected (bdb vs innodb vs ...).  What sucks is that it just ignores
you silently when you have a backend that doesn't support them.

-- 
Nick Kew


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Tyler MacDonald
Nick Kew [EMAIL PROTECTED] wrote:
 On Monday 01 May 2006 20:50, Bojan Smojver wrote:
  On Mon, 2006-05-01 at 12:41 -0700, Tyler MacDonald wrote:
 huh?  Not in my mailbox, nor at marc.theaimsgroup.com ...

I'll forward it. I accidentally sent it from my work email
[EMAIL PROTECTED] so it's being held for moderation...

 AIUI, MySQL transaction support depends on the mysql backend
 selected (bdb vs innodb vs ...).  What sucks is that it just ignores
 you silently when you have a backend that doesn't support them.

Yep. That's evil as well. :-)

- Tyler



Fwd: Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Tyler MacDonald
Here's the message that wsa sent from the wrong address:

- Forwarded message from Tyler MacDonald [EMAIL PROTECTED] -

From: Tyler MacDonald [EMAIL PROTECTED]
To: Bojan Smojver [EMAIL PROTECTED]
Cc: dev@apr.apache.org
Subject: Re: [PATCH]: Introduce APR DBD transaction mode

Bojan Smojver [EMAIL PROTECTED] wrote:
 Perhaps. However, it would seem that not all databases behave the same
 on error mid-transaction. Compare SQLite3 with PostgreSQL:

SQLite3's transactions leave a bit to be desired.. and on that note,
be very, very wary of MySQL as well. It allows a transaction to be committed
even if there were errors during the transaction (pasted below), and it also
will AUTOMATICALLY COMMIT A TRANSACTION IF YOU DO A CREATE TABLE. That part
is EVIL, EVIL, EVIL!!

(sorry, venting...)

But yeah. Because of implicit commits in MySQL (see
http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html), any sort of
tracking of a transaction is pretty much moot under MySQL. This drove me mad
when I was working on DBIx::Transaction
(http://search.cpan.org/~CRAKRJACK/DBIx-Transaction-0.008) and
DBIx::Migration::Directories
(http://search.cpan.org/~CRAKRJACK/DBIx-Migration-Directories-0.05).

Maybe if MySQL is detected APR should refuse to support
transactions and tell the end user to find a non-broken database engine. :-)

Cheers,
Tyler

mysql begin work;
Query OK, 0 rows affected (0.00 sec)

mysql insert into foo values (1);
Query OK, 1 row affected (0.00 sec)

mysql insert into foo values (1);
Query OK, 1 row affected (0.00 sec)

mysql invert into foo values (1);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to use
near 'invert into foo values (1)' at line 1
mysql commit;
Query OK, 0 rows affected (0.01 sec)

mysql select * from foo;
+--+
| bar  |
+--+
| 1|
| 1|
+--+
2 rows in set (0.00 sec)



- End forwarded message -



Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Tyler MacDonald
Bojan Smojver [EMAIL PROTECTED] wrote:
 Perhaps. However, it would seem that not all databases behave the same
 on error mid-transaction. Compare SQLite3 with PostgreSQL:

SQLite3's transactions leave a bit to be desired.. and on that note,
be very, very wary of MySQL as well. It allows a transaction to be committed
even if there were errors during the transaction (pasted below), and it also
will AUTOMATICALLY COMMIT A TRANSACTION IF YOU DO A CREATE TABLE. That part
is EVIL, EVIL, EVIL!!

(sorry, venting...)

But yeah. Because of implicit commits in MySQL (see
http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html), any sort of
tracking of a transaction is pretty much moot under MySQL. This drove me mad
when I was working on DBIx::Transaction
(http://search.cpan.org/~CRAKRJACK/DBIx-Transaction-0.008) and
DBIx::Migration::Directories
(http://search.cpan.org/~CRAKRJACK/DBIx-Migration-Directories-0.05).

Maybe if MySQL is detected APR should refuse to support
transactions and tell the end user to find a non-broken database engine. :-)

Cheers,
Tyler

mysql begin work;
Query OK, 0 rows affected (0.00 sec)

mysql insert into foo values (1);
Query OK, 1 row affected (0.00 sec)

mysql insert into foo values (1);
Query OK, 1 row affected (0.00 sec)

mysql invert into foo values (1);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to use
near 'invert into foo values (1)' at line 1
mysql commit;
Query OK, 0 rows affected (0.01 sec)

mysql select * from foo;
+--+
| bar  |
+--+
| 1|
| 1|
+--+
2 rows in set (0.00 sec)




Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Nick Kew
On Monday 01 May 2006 02:28, Bojan Smojver wrote:
 Here is the patch along the lines of setting the modes of the
 transaction. It doesn't have force commit, but if the list decides
 that it's the right thing to do, I'll rework. I didn't test this -
 it's just a prototype. A patch for folks using MySQL is included as
 well.

OK, here's a sketch for the shape of an update based on this thread
but without reference to TFM.  Any advances on this for the underlying
model?  Or simplifications?

(1) in apr_dbd.h

#define APR_DBD_TRANSACTION_COMMIT  0x01 /* force */
#define APR_DBD_TRANSACTION_ROLLBACK   0x02 /* force */
#define APR_DBD_TRANSACTION_DEFAULT0x03 /* commit-unless-error */
#define APR_DBD_TRANSACTION_MODEBITS  0x03
#define APR_DBD_TRANSACTION_CLEARERR  0x04

(2) in a driver

static int dbd_foo_transaction_mode(apr_dbd_transaction_t *trans,
int flags)
{
  int ret = 0
   int mode = flags  APR_DBD_TRANSACTION_MODEBITS;
   switch (flags) {
   case APR_DBD_TRANSACTION_COMMIT:
   case APR_DBD_TRANSACTION_ROLLBACK:
  trans-mode = mode;
  break;
   default:
  trans-mode = APR_DBD_TRANSACTION_DEFAULT ;
  break;
   }
   if ((trans-errnum != 0)  (flags  APR_DBD_TRANSACTION_CLEARERR)) {
  ret = foo_clearerror(...);
  if (ret == foo_success) {
  trans-errnum = 0;
  }
   }
   return ret; /* or juggle if foo_success != 0 */
}

-- 
Nick Kew


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver

Quoting Bojan Smojver [EMAIL PROTECTED]:


Not sure what Oracle does - I can check when I get
to work later on (but I'm guessing it would be similar to PostgreSQL).


Actually, Oracle will commit even if there were errors. So, the  
situation is that for PostgreSQL, resetting the transaction error code  
is meaningless - the whole transaction will be rolled back eventually,  
unless explicit savepoints are used. Other databases will happily  
ignore the errors and commit whatever remains.


--
Bojan


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver

Quoting Nick Kew [EMAIL PROTECTED]:


static int dbd_foo_transaction_mode(apr_dbd_transaction_t *trans,
int flags)
{
  int ret = 0
   int mode = flags  APR_DBD_TRANSACTION_MODEBITS;
   switch (flags) {

 ^
   |--- should be mode?


   case APR_DBD_TRANSACTION_COMMIT:
   case APR_DBD_TRANSACTION_ROLLBACK:
  trans-mode = mode;
  break;
   default:
  trans-mode = APR_DBD_TRANSACTION_DEFAULT ;
  break;
   }
   if ((trans-errnum != 0)  (flags  APR_DBD_TRANSACTION_CLEARERR)) {
  ret = foo_clearerror(...);


I'm guessing foo_clearerror() is a database specific function for  
clearing errors, if such a beast exists. If not, user gets back  
APR_ENOTIMPL status and the whole transaction must be rolled back.  
This would obviously need to be called every time an error code is  
returned by query/select, right?


Still a little bit unclear on the function of  
APR_DBD_TRANSACTION_DEFAULT here. Given that the errors need to be  
cleared explicitly anyway (or at least that's how I read it), having  
one commit mode should be sufficient (i.e. if the errors weren't  
cleared by using APR_DBD_TRANSACTION_CLEARERR, commit won't work  
anyway).


--
Bojan


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Nick Kew
On Tuesday 02 May 2006 00:53, Bojan Smojver wrote:

 I'm guessing foo_clearerror() is a database specific function for
 clearing errors, if such a beast exists.

Yep.

 If not, user gets back 
 APR_ENOTIMPL status and the whole transaction must be rolled back.

Erm, no.  It it doesn't exist, that reduces to resetting trans-errnum.

 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.

 Still a little bit unclear on the function of
 APR_DBD_TRANSACTION_DEFAULT here. Given that the errors need to be
 cleared explicitly anyway (or at least that's how I read it), having
 one commit mode should be sufficient (i.e. if the errors weren't
 cleared by using APR_DBD_TRANSACTION_CLEARERR, commit won't work
 anyway).

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.

-- 
Nick Kew


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver

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


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver

Quoting Bojan Smojver [EMAIL PROTECTED]:


Databases that don't support such functionality (e.g. PostgreSQL)
would simply return APR_ENOTIMPL.


Actually, I take this bit back. We *always* reset trans-errnum, just  
like Nick said (even when there is no foo_clearerr()). And this to be  
able to execute ROLLBACK TO SAVEPOINT suchandsuch for a database  
like PGSQL, in order to actually fix the underlying database nastiness.


--
Bojan


Re: [PATCH]: Introduce APR DBD transaction mode

2006-05-01 Thread Bojan Smojver

Quoting Bojan Smojver [EMAIL PROTECTED]:


Something like this:


Attached example patches.

--
Bojan
Index: include/apr_dbd.h
===
--- include/apr_dbd.h	(revision 398759)
+++ include/apr_dbd.h	(working copy)
@@ -153,6 +153,38 @@
  apr_pool_t *pool,
  apr_dbd_transaction_t *trans);
 
+#define APR_DBD_TRANSACTION_COMMIT   0  /** commit the transaction */
+#define APR_DBD_TRANSACTION_ROLLBACK 1  /** rollback the transaction */
+
+/** apr_dbd_transaction_mode_get: get the mode of transaction
+ *
+ *  @param driver - the driver
+ *  @param trans  - the transaction
+ *  @return mode of transaction
+ */
+APU_DECLARE(int) apr_dbd_transaction_mode_get(const apr_dbd_driver_t *driver,
+  apr_dbd_transaction_t *trans);
+
+/** apr_dbd_transaction_mode_set: set the mode of transaction
+ *
+ *  @param driver - the driver
+ *  @param trans  - the transaction
+ *  @param mode   - new mode of the transaction
+ *  @return new mode of transaction
+ */
+APU_DECLARE(int) apr_dbd_transaction_mode_set(const apr_dbd_driver_t *driver,
+  apr_dbd_transaction_t *trans,
+  int mode);
+
+/** apr_dbd_transaction_recover: recover transaction from an error condition
+ *
+ *  @param driver - the driver
+ *  @param trans  - the transaction
+ *  @return 0 for success or error code
+ */
+APU_DECLARE(int) apr_dbd_transaction_recover(const apr_dbd_driver_t *driver,
+ apr_dbd_transaction_t *trans);
+
 /** apr_dbd_query: execute an SQL query that doesn't return a result set
  *
  *  @param driver - the driver
Index: include/private/apr_dbd_internal.h
===
--- include/private/apr_dbd_internal.h	(revision 398759)
+++ include/private/apr_dbd_internal.h	(working copy)
@@ -82,9 +82,9 @@
 
 /** transaction: start a transaction.  May be a no-op.
  *
- *  @param pool - a pool to use for error messages (if any).
+ *  @param pool   - a pool to use for error messages (if any).
  *  @param handle - the connection
- *  @param transaction - ptr to a transaction.  May be null on entry
+ *  @param trans  - ptr to a transaction.  May be null on entry
  *  @return 0 for success or error code
  */
 int (*start_transaction)(apr_pool_t *pool, apr_dbd_t *handle,
@@ -94,7 +94,7 @@
  *  (commit on success, rollback on error).
  *  May be a no-op.
  *
- *  @param transaction - the transaction.
+ *  @param trans - the transaction.
  *  @return 0 for success or error code
  */
 int (*end_transaction)(apr_dbd_transaction_t *trans);
@@ -254,6 +254,28 @@
  *  @return param name, or NULL if col is out of bounds.
  */
 const char* (*get_name)(const apr_dbd_results_t *res, int col);
+
+/** transaction_mode_get: get the mode of transaction
+ *
+ *  @param trans - the transaction.
+ *  @return mode of transaction
+ */
+int (*transaction_mode_get)(apr_dbd_transaction_t *trans);
+
+/** transaction_mode_set: get the mode of transaction
+ *
+ *  @param trans - the transaction.
+ *  @param mode  - new mode of the transaction
+ *  @return new mode of transaction
+ */
+int (*transaction_mode_set)(apr_dbd_transaction_t *trans, int mode);
+
+/** transaction_recover: recover transaction from an error condition
+ *
+ *  @param trans - the transaction.
+ *  @return 0 for success or error code
+ */
+int (*transaction_recover)(apr_dbd_transaction_t *trans);
 };
 
 /* Export mutex lock/unlock for drivers that need it */
Index: dbd/apr_dbd_sqlite2.c
===
--- dbd/apr_dbd_sqlite2.c	(revision 398759)
+++ dbd/apr_dbd_sqlite2.c	(working copy)
@@ -29,6 +29,7 @@
 #include apr_dbd_internal.h
 
 struct apr_dbd_transaction_t {
+int mode;
 int errnum;
 apr_dbd_t *handle;
 };
@@ -292,7 +293,8 @@
 int ret = -1;   /* no transaction is an error cond */
 
 if (trans) {
-if (trans-errnum) {
+/* rollback on error or explicit rollback request */
+if (trans-errnum || trans-mode) {
 trans-errnum = 0;
 ret =
 dbd_sqlite_query(trans-handle, rows,
@@ -308,6 +310,36 @@
 return ret;
 }
 
+static int dbd_sqlite_transaction_mode_get(apr_dbd_transaction_t *trans)
+{
+if (!trans)
+return APR_DBD_TRANSACTION_COMMIT;
+
+return trans-mode;
+}
+
+static int dbd_sqlite_transaction_mode_set(apr_dbd_transaction_t *trans,
+   int mode)
+{
+if (!trans)
+return APR_DBD_TRANSACTION_COMMIT;
+
+return trans-mode = (mode ? APR_DBD_TRANSACTION_ROLLBACK
+   

[PATCH]: Introduce APR DBD transaction mode

2006-04-30 Thread Bojan Smojver
Here is the patch along the lines of setting the modes of the  
transaction. It doesn't have force commit, but if the list decides  
that it's the right thing to do, I'll rework. I didn't test this -  
it's just a prototype. A patch for folks using MySQL is included as  
well.


--
Bojan
Index: include/apr_dbd.h
===
--- include/apr_dbd.h	(revision 398484)
+++ include/apr_dbd.h	(working copy)
@@ -153,6 +153,29 @@
  apr_pool_t *pool,
  apr_dbd_transaction_t *trans);
 
+#define APR_DBD_TRANSACTION_COMMIT   0  /** commit the transaction */
+#define APR_DBD_TRANSACTION_ROLLBACK 1  /** rollback the transaction */
+
+/** apr_dbd_transaction_mode_get: get the mode of transaction
+ *
+ *  @param driver - the driver
+ *  @param trans  - the transaction
+ *  @return mode of transaction
+ */
+APU_DECLARE(int) apr_dbd_transaction_mode_get(const apr_dbd_driver_t *driver,
+  apr_dbd_transaction_t *trans);
+
+/** apr_dbd_transaction_mode_set: set the mode of transaction
+ *
+ *  @param driver - the driver
+ *  @param trans  - the transaction
+ *  @param mode   - new mode of the transaction
+ *  @return new mode of transaction
+ */
+APU_DECLARE(int) apr_dbd_transaction_mode_set(const apr_dbd_driver_t *driver,
+  apr_dbd_transaction_t *trans,
+  int mode);
+
 /** apr_dbd_query: execute an SQL query that doesn't return a result set
  *
  *  @param driver - the driver
Index: include/private/apr_dbd_internal.h
===
--- include/private/apr_dbd_internal.h	(revision 398484)
+++ include/private/apr_dbd_internal.h	(working copy)
@@ -82,9 +82,9 @@
 
 /** transaction: start a transaction.  May be a no-op.
  *
- *  @param pool - a pool to use for error messages (if any).
+ *  @param pool   - a pool to use for error messages (if any).
  *  @param handle - the connection
- *  @param transaction - ptr to a transaction.  May be null on entry
+ *  @param trans  - ptr to a transaction.  May be null on entry
  *  @return 0 for success or error code
  */
 int (*start_transaction)(apr_pool_t *pool, apr_dbd_t *handle,
@@ -94,7 +94,7 @@
  *  (commit on success, rollback on error).
  *  May be a no-op.
  *
- *  @param transaction - the transaction.
+ *  @param trans - the transaction.
  *  @return 0 for success or error code
  */
 int (*end_transaction)(apr_dbd_transaction_t *trans);
@@ -254,6 +254,21 @@
  *  @return param name, or NULL if col is out of bounds.
  */
 const char* (*get_name)(const apr_dbd_results_t *res, int col);
+
+/** transaction_mode_get: get the mode of transaction
+ *
+ *  @param trans - the transaction.
+ *  @return mode of transaction
+ */
+int (*transaction_mode_get)(apr_dbd_transaction_t *trans);
+
+/** transaction_mode_set: get the mode of transaction
+ *
+ *  @param trans - the transaction.
+ *  @param mode  - new mode of the transaction
+ *  @return new mode of transaction
+ */
+int (*transaction_mode_set)(apr_dbd_transaction_t *trans, int mode);
 };
 
 /* Export mutex lock/unlock for drivers that need it */
Index: dbd/apr_dbd_sqlite2.c
===
--- dbd/apr_dbd_sqlite2.c	(revision 398484)
+++ dbd/apr_dbd_sqlite2.c	(working copy)
@@ -29,6 +29,7 @@
 #include apr_dbd_internal.h
 
 struct apr_dbd_transaction_t {
+int mode;
 int errnum;
 apr_dbd_t *handle;
 };
@@ -292,7 +293,8 @@
 int ret = -1;   /* no transaction is an error cond */
 
 if (trans) {
-if (trans-errnum) {
+/* rollback on error or explicit rollback request */
+if (trans-errnum || trans-mode) {
 trans-errnum = 0;
 ret =
 dbd_sqlite_query(trans-handle, rows,
@@ -308,6 +310,18 @@
 return ret;
 }
 
+static int dbd_sqlite_transaction_mode_get(apr_dbd_transaction_t *trans)
+{
+return trans-mode;
+}
+
+static int dbd_sqlite_transaction_mode_set(apr_dbd_transaction_t *trans,
+   int mode)
+{
+return trans-mode = (mode ? APR_DBD_TRANSACTION_ROLLBACK
+   : APR_DBD_TRANSACTION_COMMIT);
+}
+
 static apr_dbd_t *dbd_sqlite_open(apr_pool_t * pool, const char *params_)
 {
 apr_dbd_t *sql;
@@ -396,6 +410,8 @@
 dbd_sqlite_pvselect,
 dbd_sqlite_pquery,
 dbd_sqlite_pselect,
-dbd_sqlite_get_name
+dbd_sqlite_get_name,
+dbd_sqlite_transaction_mode_get,
+dbd_sqlite_transaction_mode_set
 };
 #endif
Index: dbd/apr_dbd_sqlite3.c
===
--- dbd/apr_dbd_sqlite3.c	(revision 398484)
+++ 

Re: [PATCH]: Introduce APR DBD transaction mode

2006-04-30 Thread Bojan Smojver

Quoting Bojan Smojver [EMAIL PROTECTED]:


A patch for folks using MySQL is included as well.


Sorry about the traling comma after dbd_mysql_transaction_mode_set -  
lazy cut/paste :-(


--
Bojan