mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	#8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute.
Patch by R. David Murray, unit tests by Shashwat Anand.
This commit is contained in:
		
							parent
							
								
									bcb8d3a0a5
								
							
						
					
					
						commit
						d35251dc19
					
				
					 6 changed files with 50 additions and 1 deletions
				
			
		|  | @ -227,6 +227,13 @@ Connection Objects | |||
|    one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section | ||||
|    :ref:`sqlite3-controlling-transactions` for a more detailed explanation. | ||||
| 
 | ||||
| .. attribute:: Connection.in_transaction | ||||
| 
 | ||||
|    .. versionadded:: 3.2 | ||||
| 
 | ||||
|    :cont:`True` if a transaction is active (there are uncommitted changes), | ||||
|    :const:`False` otherwise.  Read-only attribute. | ||||
| 
 | ||||
| 
 | ||||
| .. method:: Connection.cursor([cursorClass]) | ||||
| 
 | ||||
|  | @ -806,7 +813,8 @@ So if you are within a transaction and issue a command like ``CREATE TABLE | |||
| before executing that command. There are two reasons for doing that. The first | ||||
| is that some of these commands don't work within transactions. The other reason | ||||
| is that sqlite3 needs to keep track of the transaction state (if a transaction | ||||
| is active or not). | ||||
| is active or not).  The current transaction state is exposed through the | ||||
| :attr:`Connection.in_transaction` attribute of the connection object. | ||||
| 
 | ||||
| You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes | ||||
| (or none at all) via the *isolation_level* parameter to the :func:`connect` | ||||
|  |  | |||
|  | @ -100,6 +100,18 @@ New, Improved, and Deprecated Modules | |||
| 
 | ||||
|   (Contributed by Tarek Ziade.) | ||||
| 
 | ||||
| * The *sqlite3* module has some new features: | ||||
| 
 | ||||
|   * XXX *enable_load_extension* | ||||
| 
 | ||||
|   * XXX *load_extension* | ||||
| 
 | ||||
|   * New :class:`~sqlite3.Connection` attribute | ||||
|     :attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there | ||||
|     are uncommitted changes, and :const:`False` otherwise.  (Contributed | ||||
|     by R. David Murray and Shashwat Anand, :issue:`8845`.) | ||||
| 
 | ||||
| 
 | ||||
| Multi-threading | ||||
| =============== | ||||
| 
 | ||||
|  |  | |||
|  | @ -84,6 +84,7 @@ def CheckNotSupportedError(self): | |||
|                         "NotSupportedError is not a subclass of DatabaseError") | ||||
| 
 | ||||
| class ConnectionTests(unittest.TestCase): | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         self.cx = sqlite.connect(":memory:") | ||||
|         cu = self.cx.cursor() | ||||
|  | @ -140,6 +141,28 @@ def CheckExceptions(self): | |||
|         self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError) | ||||
|         self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError) | ||||
| 
 | ||||
|     def CheckInTransaction(self): | ||||
|         # Can't use db from setUp because we want to test initial state. | ||||
|         cx = sqlite.connect(":memory:") | ||||
|         cu = cx.cursor() | ||||
|         self.assertEqual(cx.in_transaction, False) | ||||
|         cu.execute("create table transactiontest(id integer primary key, name text)") | ||||
|         self.assertEqual(cx.in_transaction, False) | ||||
|         cu.execute("insert into transactiontest(name) values (?)", ("foo",)) | ||||
|         self.assertEqual(cx.in_transaction, True) | ||||
|         cu.execute("select name from transactiontest where name=?", ["foo"]) | ||||
|         row = cu.fetchone() | ||||
|         self.assertEqual(cx.in_transaction, True) | ||||
|         cx.commit() | ||||
|         self.assertEqual(cx.in_transaction, False) | ||||
|         cu.execute("select name from transactiontest where name=?", ["foo"]) | ||||
|         row = cu.fetchone() | ||||
|         self.assertEqual(cx.in_transaction, False) | ||||
| 
 | ||||
|     def CheckInTransactionRO(self): | ||||
|         with self.assertRaises(AttributeError): | ||||
|             self.cx.in_transaction = True | ||||
| 
 | ||||
| class CursorTests(unittest.TestCase): | ||||
|     def setUp(self): | ||||
|         self.cx = sqlite.connect(":memory:") | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ Billy G. Allie | |||
| Kevin Altis | ||||
| Joe Amenta | ||||
| Mark Anacker | ||||
| Shashwat Anand | ||||
| Anders Andersen | ||||
| John Anderson | ||||
| Erik Andersén | ||||
|  |  | |||
|  | @ -398,6 +398,9 @@ C-API | |||
| Library | ||||
| ------- | ||||
| 
 | ||||
| - Issue #8845: sqlite3 Connection objects now have a read-only in_transaction | ||||
|   attribute that is True iff there are uncommitted changes. | ||||
| 
 | ||||
| - Issue #1289118: datetime.timedelta objects can now be multiplied by float | ||||
|   and divided by float and int objects.  Results are rounded to the nearest | ||||
|   multiple of timedelta.resolution with ties resolved using round-half-to-even | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ | |||
| 
 | ||||
| #include "cache.h" | ||||
| #include "module.h" | ||||
| #include "structmember.h" | ||||
| #include "connection.h" | ||||
| #include "statement.h" | ||||
| #include "cursor.h" | ||||
|  | @ -1551,6 +1552,7 @@ static struct PyMemberDef connection_members[] = | |||
|     {"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY}, | ||||
|     {"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)}, | ||||
|     {"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)}, | ||||
|     {"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY}, | ||||
|     {NULL} | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 R. David Murray
						R. David Murray