mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-10-30 23:37:29 +03:00 
			
		
		
		
	Merge branch 'close-idempotent' into devel
This commit is contained in:
		
						commit
						37aa62ca52
					
				
							
								
								
									
										2
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								NEWS
									
									
									
									
									
								
							|  | @ -1,6 +1,8 @@ | ||||||
| What's new in psycopg 2.4.5 | What's new in psycopg 2.4.5 | ||||||
| --------------------------- | --------------------------- | ||||||
| 
 | 
 | ||||||
|  |   - The close() methods on connections and cursors don't raise exceptions | ||||||
|  |     if called on already closed objects. | ||||||
|   - Fixed fetchmany() with no argument in cursor subclasses |   - Fixed fetchmany() with no argument in cursor subclasses | ||||||
|     (ticket #84). |     (ticket #84). | ||||||
|   - Use lo_creat() instead of lo_create() when possible for better |   - Use lo_creat() instead of lo_create() when possible for better | ||||||
|  |  | ||||||
|  | @ -906,6 +906,10 @@ conn_poll(connectionObject *self) | ||||||
| void | void | ||||||
| conn_close(connectionObject *self) | conn_close(connectionObject *self) | ||||||
| { | { | ||||||
|  |     if (self->closed) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* sets this connection as closed even for other threads; also note that
 |     /* sets this connection as closed even for other threads; also note that
 | ||||||
|        we need to check the value of pgconn, because we get called even when |        we need to check the value of pgconn, because we get called even when | ||||||
|        the connection fails! */ |        the connection fails! */ | ||||||
|  | @ -922,14 +926,13 @@ conn_close(connectionObject *self) | ||||||
|      * closed only in status CONN_STATUS_READY. |      * closed only in status CONN_STATUS_READY. | ||||||
|      */ |      */ | ||||||
| 
 | 
 | ||||||
|     if (self->closed == 0) |  | ||||||
|     self->closed = 1; |     self->closed = 1; | ||||||
| 
 | 
 | ||||||
|     if (self->pgconn) { |     if (self->pgconn) { | ||||||
|         PQfinish(self->pgconn); |         PQfinish(self->pgconn); | ||||||
|         PQfreeCancel(self->cancel); |  | ||||||
|         Dprintf("conn_close: PQfinish called"); |  | ||||||
|         self->pgconn = NULL; |         self->pgconn = NULL; | ||||||
|  |         Dprintf("conn_close: PQfinish called"); | ||||||
|  |         PQfreeCancel(self->cancel); | ||||||
|         self->cancel = NULL; |         self->cancel = NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -122,8 +122,6 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds) | ||||||
| static PyObject * | static PyObject * | ||||||
| psyco_conn_close(connectionObject *self, PyObject *args) | psyco_conn_close(connectionObject *self, PyObject *args) | ||||||
| { | { | ||||||
|     EXC_IF_CONN_CLOSED(self); |  | ||||||
| 
 |  | ||||||
|     Dprintf("psyco_conn_close: closing connection at %p", self); |     Dprintf("psyco_conn_close: closing connection at %p", self); | ||||||
|     conn_close(self); |     conn_close(self); | ||||||
|     Dprintf("psyco_conn_close: connection at %p closed", self); |     Dprintf("psyco_conn_close: connection at %p closed", self); | ||||||
|  |  | ||||||
|  | @ -52,9 +52,12 @@ extern PyObject *pyPsycopgTzFixedOffsetTimezone; | ||||||
| static PyObject * | static PyObject * | ||||||
| psyco_curs_close(cursorObject *self, PyObject *args) | psyco_curs_close(cursorObject *self, PyObject *args) | ||||||
| { | { | ||||||
|     EXC_IF_CURS_CLOSED(self); |  | ||||||
|     EXC_IF_ASYNC_IN_PROGRESS(self, close); |     EXC_IF_ASYNC_IN_PROGRESS(self, close); | ||||||
| 
 | 
 | ||||||
|  |     if (self->closed) { | ||||||
|  |         goto exit; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (self->name != NULL) { |     if (self->name != NULL) { | ||||||
|         char buffer[128]; |         char buffer[128]; | ||||||
| 
 | 
 | ||||||
|  | @ -66,6 +69,7 @@ psyco_curs_close(cursorObject *self, PyObject *args) | ||||||
|     self->closed = 1; |     self->closed = 1; | ||||||
|     Dprintf("psyco_curs_close: cursor at %p closed", self); |     Dprintf("psyco_curs_close: cursor at %p closed", self); | ||||||
| 
 | 
 | ||||||
|  | exit: | ||||||
|     Py_INCREF(Py_None); |     Py_INCREF(Py_None); | ||||||
|     return Py_None; |     return Py_None; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -380,7 +380,9 @@ class DatabaseAPI20Test(unittest.TestCase): | ||||||
|         self.assertRaises(self.driver.Error,con.commit) |         self.assertRaises(self.driver.Error,con.commit) | ||||||
| 
 | 
 | ||||||
|         # connection.close should raise an Error if called more than once |         # connection.close should raise an Error if called more than once | ||||||
|         self.assertRaises(self.driver.Error,con.close) |         # Issue discussed on DB-SIG: consensus seem that close() should not | ||||||
|  |         # raised if called on closed objects. Issue reported back to Stuart. | ||||||
|  |         # self.assertRaises(self.driver.Error,con.close) | ||||||
| 
 | 
 | ||||||
|     def test_execute(self): |     def test_execute(self): | ||||||
|         con = self._connect() |         con = self._connect() | ||||||
|  |  | ||||||
|  | @ -48,6 +48,12 @@ class ConnectionTests(unittest.TestCase): | ||||||
|         conn.close() |         conn.close() | ||||||
|         self.assertEqual(conn.closed, True) |         self.assertEqual(conn.closed, True) | ||||||
| 
 | 
 | ||||||
|  |     def test_close_idempotent(self): | ||||||
|  |         conn = self.conn | ||||||
|  |         conn.close() | ||||||
|  |         conn.close() | ||||||
|  |         self.assert_(conn.closed) | ||||||
|  | 
 | ||||||
|     def test_cursor_closed_attribute(self): |     def test_cursor_closed_attribute(self): | ||||||
|         conn = self.conn |         conn = self.conn | ||||||
|         curs = conn.cursor() |         curs = conn.cursor() | ||||||
|  |  | ||||||
|  | @ -37,6 +37,12 @@ class CursorTests(unittest.TestCase): | ||||||
|     def tearDown(self): |     def tearDown(self): | ||||||
|         self.conn.close() |         self.conn.close() | ||||||
| 
 | 
 | ||||||
|  |     def test_close_idempotent(self): | ||||||
|  |         cur = self.conn.cursor() | ||||||
|  |         cur.close() | ||||||
|  |         cur.close() | ||||||
|  |         self.assert_(cur.closed) | ||||||
|  | 
 | ||||||
|     def test_empty_query(self): |     def test_empty_query(self): | ||||||
|         cur = self.conn.cursor() |         cur = self.conn.cursor() | ||||||
|         self.assertRaises(psycopg2.ProgrammingError, cur.execute, "") |         self.assertRaises(psycopg2.ProgrammingError, cur.execute, "") | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user