self.described = True
def _close_gen(self, cur: BaseCursor[ConnectionType]) -> PQGen[None]:
+ # if we didn't declare the cursor ourselves we still have to close it
+ # but we must make sure it exists.
+ if not self.described:
+ query = sql.SQL(
+ "select 1 from pg_catalog.pg_cursors where name = {}"
+ ).format(sql.Literal(self.name))
+ res = yield from cur._conn._exec_command(query)
+ if res.ntuples == 0:
+ return
+
query = sql.SQL("close {}").format(sql.Identifier(self.name))
yield from cur._conn._exec_command(query)
assert not recwarn
+def test_close_noop(conn, recwarn):
+ cur = conn.cursor("foo")
+ cur.close()
+ assert not recwarn
+
+
def test_context(conn, recwarn):
with conn.cursor("foo") as cur:
cur.execute("select generate_series(1, 10) as bar")
def test_steal_cursor(conn):
cur1 = conn.cursor()
- cur1.execute(
- "declare test cursor without hold for select generate_series(1, 6)"
- )
+ cur1.execute("declare test cursor for select generate_series(1, 6)")
cur2 = conn.cursor("test")
# can call fetch without execute
assert cur2.fetchone() == (1,)
assert cur2.fetchmany(3) == [(2,), (3,), (4,)]
assert cur2.fetchall() == [(5,), (6,)]
+
+
+def test_stolen_cursor_close(conn):
+ cur1 = conn.cursor()
+ cur1.execute("declare test cursor for select generate_series(1, 6)")
+ cur2 = conn.cursor("test")
+ cur2.close()
+
+ cur1.execute("declare test cursor for select generate_series(1, 6)")
+ cur2 = conn.cursor("test")
+ cur2.close()
assert not recwarn
+async def test_close_noop(aconn, recwarn):
+ cur = await aconn.cursor("foo")
+ await cur.close()
+ assert not recwarn
+
+
async def test_context(aconn, recwarn):
async with await aconn.cursor("foo") as cur:
await cur.execute("select generate_series(1, 10) as bar")