Re: Savepoint or subtransaction support

Markus Schiltknecht <[email protected]> Fri, 06 Oct 2006 11:56:05 +0200
Newsgroups gmane.comp.python.db.pypgsql.user
Message-ID <[email protected]>
This is a MIME-formatted message.  If you see this text it means that your
E-mail software does not support MIME-formatted messages.

--=_molabola.bugaboo.mu-22722-1160128565-0001-2
Content-Type: text/plain; charset=iso-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

as I really urgently need savepoints, I have written a small patch to 
add support for one savepoint. Only to find out that I should have 
looked in the SF 'patches' page where someone else did exactly the same...

I'm comparing our patches just now.

Regards

Markus

Markus Schiltknecht wrote:
> Hi,
> 
> I'd like to use savepoints or subtransactions. Now PyPgSQL does not seem 
> to support them.
> 
> Searching through the archives brought up a bug [1] and a feature 
> request at [2] for savepoint support. Another guy run into the same 
> problem as I did, but his solution seems dubious, see [3].
> 
> What's PyPgSQL's state concerning subtransactions or savepoints? What 
> does the Python DB-API say about them? What do other (i.e. MySQL 
> interfaces) do?
> 
> Regards
> 
> Markus
> 
> 
> [1]: Bug:
> https://sourceforge.net/tracker/index.php?func=detail&aid=1409818&group_id=16528&atid=116528
> 
> [2]: Feature Request:
> https://sourceforge.net/tracker/index.php?func=detail&aid=1503756&group_id=16528&atid=366528
> 
> [3]: Don't use transactions
> https://sourceforge.net/tracker/index.php?func=detail&aid=1524586&group_id=16528&atid=116528
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys -- and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Pypgsql-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/pypgsql-users


--=_molabola.bugaboo.mu-22722-1160128565-0001-2
Content-Type: text/plain; name=diff; charset=iso-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="diff"

Index: pyPgSQL/PgSQL.py
===================================================================
RCS file: /cvsroot/pypgsql/pypgsql/pyPgSQL/PgSQL.py,v
retrieving revision 1.50
diff -c -r1.50 PgSQL.py
*** pyPgSQL/PgSQL.py	1 Jun 2006 14:42:51 -0000	1.50
--- pyPgSQL/PgSQL.py	6 Oct 2006 09:50:42 -0000
***************
*** 2368,2373 ****
--- 2368,2374 ----
  	self.__dict__["TransactionLevel"] = ""
  	self.__dict__["notices"] = self.conn.notices
  	self.__dict__["inTransaction"] = 0
+ 	self.__dict__["current_savepoint"] = 0
  	self.__dict__["version"] = self.conn.version
  	self.__dict__["_isOpen"] = 1
  	self.__dict__["_cache"] = TypeCache(self)
***************
*** 2542,2547 ****
--- 2543,2549 ----
  	self.__dict__["conn"] = None
  	self.__dict__["cursors"] = None
  	self.__dict__["inTransaction"] = 0
+ 	self.__dict__["current_savepoint"] = 0
  	self.__dict__["TransactionLevel"] = None
  	self.__dict__["version"] = None
  	self.__dict__["notices"] = None
***************
*** 2587,2592 ****
--- 2589,2671 ----
  		raise InternalError, \
  		      	"Rollback failed - %s" % res.resultErrorMessage
  
+     def savepoint(self, name):
+ 	"""
+     savepoint()
+ 	Set a savepoint in the current connection, to which the connection
+ 	gets rolled back to on error or on request.\n"""
+ 
+ 	if not self._isOpen:
+ 	    raise InterfaceError, "Savepoint failed - Connection is not open."
+ 
+ 	if self.autocommit:
+ 	    raise InterfaceError, "Savepoint failed - autocommit is on."
+ 
+ 	if not self.inTransaction:
+ 	    raise InterfaceError, "Savepoint failed - not in a transaction."
+ 
+ 	_nl = len(self.conn.notices)
+ 	res = self.conn.query("SAVEPOINT %s" % name)
+ 	if len(self.notices) != _nl:
+ 	    raise Warning, self.notices.pop()
+ 	if res.resultStatus != COMMAND_OK:
+ 	    raise InternalError, \
+ 		    "Savepoint failed - %s" % res.resultErrorMessage
+ 
+ 	self.__dict__["current_savepoint"] = name
+ 
+     def rollback_savepoint(self, name=None):
+ 	if not self._isOpen:
+ 	    raise InterfaceError, "Rollback savepoint failed - Connection is not open."
+ 
+ 	if self.autocommit:
+ 	    raise InterfaceError, "Rollback savepoint failed - autocommit is on."
+ 
+ 	if not self.inTransaction:
+ 	    raise InterfaceError, "Rollback savepoint failed - not in a transaction."
+ 
+ 	if not self.current_savepoint:
+ 	    raise InterfaceError, "Rollback savepoint failed - no savepoint active."
+ 
+ 	if not name:
+ 	    name = self.current_savepoint
+ 
+ 	_nl = len(self.conn.notices)
+ 	res = self.conn.query("ROLLBACK TO SAVEPOINT %s" % name)
+ 	if len(self.notices) != _nl:
+ 	    raise Warning, self.notices.pop()
+ 	if res.resultStatus != COMMAND_OK:
+ 	    raise InternalError, \
+ 		    "Release savepoint failed - %s" % res.resultErrorMessage
+ 
+ 	self.__dict__["current_savepoint"] = 0
+ 
+     def release_savepoint(self, name=None):
+ 	if not self._isOpen:
+ 	    raise InterfaceError, "Release savepoint failed - Connection is not open."
+ 
+ 	if self.autocommit:
+ 	    raise InterfaceError, "Release savepoint failed - autocommit is on."
+ 
+ 	if not self.inTransaction:
+ 	    raise InterfaceError, "Release savepoint failed - not in a transaction."
+ 
+ 	if not self.current_savepoint:
+ 	    raise InterfaceError, "Release savepoint failed - no savepoint active."
+ 
+ 	if not name:
+ 	    name = self.current_savepoint
+ 
+ 	_nl = len(self.conn.notices)
+ 	res = self.conn.query("RELEASE SAVEPOINT %s" % name)
+ 	if len(self.notices) != _nl:
+ 	    raise Warning, self.notices.pop()
+ 	if res.resultStatus != COMMAND_OK:
+ 	    raise InternalError, \
+ 		    "Release savepoint failed - %s" % res.resultErrorMessage
+ 
+ 	self.__dict__["current_savepoint"] = 0
+ 
      def cursor(self, name=None, isRefCursor=PG_False):
  	"""
      cursor([name])
***************
*** 3101,3107 ****
  	except OperationalError, msg:
  	    # Uh-oh.  A fatal error occurred.  This means the current trans-
  	    # action has been aborted.  Try to recover to a sane state.
! 	    if self.conn.inTransaction:
  		_n = len(self.conn.notices)
  		self.conn.conn.query('ROLLBACK WORK')
  		if len(self.conn.notices) != _n:
--- 3180,3188 ----
  	except OperationalError, msg:
  	    # Uh-oh.  A fatal error occurred.  This means the current trans-
  	    # action has been aborted.  Try to recover to a sane state.
! 	    if self.conn.current_savepoint:
! 		self.conn.rollback_savepoint()
! 	    elif self.conn.inTransaction:
  		_n = len(self.conn.notices)
  		self.conn.conn.query('ROLLBACK WORK')
  		if len(self.conn.notices) != _n:

--=_molabola.bugaboo.mu-22722-1160128565-0001-2
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
--=_molabola.bugaboo.mu-22722-1160128565-0001-2
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Pypgsql-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pypgsql-users

--=_molabola.bugaboo.mu-22722-1160128565-0001-2--