Skip to content

Commit 0a70580

Browse files
author
James William Pye
committed
Add an autocommit property to db-api connections.
1 parent a334bdb commit 0a70580

2 files changed

Lines changed: 76 additions & 2 deletions

File tree

postgresql/driver/dbapi20.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def close(self):
197197
for p in ps: p.close()
198198

199199
# Describe the "real" cursor as a "portal".
200-
# This should keep ambiguous terminology out of the picture.
200+
# This should keep ambiguous terminology out of adaptor.
201201
def _portal():
202202
def fget(self):
203203
if self.__portals is None:
@@ -229,25 +229,76 @@ class Connection(object):
229229
DatabaseError = DatabaseError
230230
NotSupportedError = NotSupportedError
231231

232+
def autocommit_set(self, val):
233+
if val:
234+
# already in autocommit mode.
235+
if self._xact is None:
236+
return
237+
self._xact.rollback()
238+
self._xact = None
239+
else:
240+
if self._xact is not None:
241+
return
242+
self._xact = self.database.xact()
243+
self._xact.start()
244+
245+
def autocommit_get(self):
246+
return self._xact is None
247+
248+
def autocommit_del(self):
249+
self.autocommit = False
250+
251+
autocommit = property(
252+
fget = autocommit_get,
253+
fset = autocommit_set,
254+
fdel = autocommit_del,
255+
)
256+
del autocommit_set, autocommit_get, autocommit_del
257+
232258
def __init__(self, connection):
233259
self.database = connection
234260
self._xact = self.database.xact()
235261
self._xact.start()
236262

237263
def close(self):
238264
if self.database.closed:
239-
raise Error("connection already closed")
265+
err = Error(
266+
"connection already closed",
267+
source = 'DRIVER',
268+
)
269+
self.database.ife_descend(err)
270+
err.raise_exception()
240271
self.database.close()
241272

242273
def cursor(self):
243274
return Cursor(self)
244275

245276
def commit(self):
277+
if self._xact is None:
278+
err = InterfaceError(
279+
"commit on connection in autocommit mode",
280+
source = 'DRIVER',
281+
details = {
282+
'hint': 'The "autocommit" property on the connection was set to True.'
283+
}
284+
)
285+
self.database.ife_descend(err)
286+
err.raise_exception()
246287
self._xact.commit()
247288
self._xact = self.database.xact()
248289
self._xact.start()
249290

250291
def rollback(self):
292+
if self._xact is None:
293+
err = InterfaceError(
294+
"rollback on connection in autocommit mode",
295+
source = 'DRIVER',
296+
details = {
297+
'hint': 'The "autocommit" property on the connection was set to True.'
298+
}
299+
)
300+
self.database.ife_descend(err)
301+
err.raise_exception()
251302
self._xact.rollback()
252303
self._xact = self.database.xact()
253304
self._xact.start()

postgresql/test/test_dbapi20.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,29 @@ def test_setoutputsize(self):
728728
# Real test for setoutputsize is driver dependant
729729
pass
730730

731+
def test_autocommit(self):
732+
con = self._connect()
733+
con2 = self._connect()
734+
try:
735+
con.autocommit = True
736+
# autocommit mode on, commit/abort on inappropriate.
737+
self.failUnlessRaises(
738+
con.InterfaceError,
739+
con.commit
740+
)
741+
self.failUnlessRaises(
742+
con.InterfaceError,
743+
con.rollback
744+
)
745+
c = con.cursor()
746+
c.execute("create table some_committed_table(i int)")
747+
# if this fails, autocommit had no effect on `con`
748+
con2.cursor().execute("drop table some_committed_table")
749+
con2.commit()
750+
finally:
751+
con.close()
752+
con2.close()
753+
731754
def test_None(self):
732755
con = self._connect()
733756
try:

0 commit comments

Comments
 (0)