Skip to content

Commit 94b8850

Browse files
author
James William Pye
committed
Add listening_channels method.
1 parent 8c31e7c commit 94b8850

4 files changed

Lines changed: 38 additions & 5 deletions

File tree

postgresql/api.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,12 @@ def unlisten(self, *channels) -> None:
10351035
Equivalent to issuing "UNLISTEN <x>" for x in channels.
10361036
"""
10371037

1038+
@abstractmethod
1039+
def listening_channels(self) -> ["channel name", ...]:
1040+
"""
1041+
Return an *iterator* to all the channels currently being listened to.
1042+
"""
1043+
10381044
class SocketFactory(object):
10391045
@propertydoc
10401046
@abstractproperty

postgresql/driver/pq3.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,12 +2247,28 @@ def notify(self, channel, payload = None,
22472247
channel.replace('"', '""'),
22482248
))
22492249

2250-
def listen(self, *channels):
2251-
qstr = ';'.join(('LISTEN ' + x.replace('"', '""') for x in channels))
2250+
def listening_channels(self):
2251+
if self.version_info[:2] > (8,4):
2252+
return self.sys.listening_channels()
2253+
else:
2254+
return self.sys.listening_relations()
2255+
2256+
def listen(self, *channels, len = len):
2257+
qstr = ''
2258+
for x in channels:
2259+
# XXX: hardcoded identifier length?
2260+
if len(x) > 63:
2261+
raise ValueError("channel name too long: " + x)
2262+
qstr += '; LISTEN ' + x.replace('"', '""')
22522263
return self.execute(qstr)
22532264

2254-
def unlisten(self, *channels):
2255-
qstr = ';'.join(('UNLISTEN ' + x.replace('"', '""') for x in channels))
2265+
def unlisten(self, *channels, len = len):
2266+
qstr = ''
2267+
for x in channels:
2268+
# XXX: hardcoded identifier length?
2269+
if len(x) > 63:
2270+
raise ValueError("channel name too long: " + x)
2271+
qstr += '; UNLISTEN ' + x.replace('"', '""')
22562272
return self.execute(qstr)
22572273

22582274
def __init__(self, connector, *args, **kw):

postgresql/lib/libsys.sql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
##
2-
# libsys.sql
2+
# libsys.sql - SQL to support driver features
33
##
44
-- Queries for dealing with the PostgreSQL catalogs for supporting the driver.
55

@@ -161,3 +161,11 @@ SELECT pg_reload_conf()
161161

162162
[languages:transient:column]
163163
SELECT lanname FROM pg_catalog.pg_language
164+
165+
[listening_channels:transient:column]
166+
SELECT channel FROM pg_catalog.pg_listening_channels() AS x(channel)
167+
168+
[listening_relations:transient:column]
169+
-- listening_relations: old version of listening_channels.
170+
SELECT relname as channel FROM pg_catalog.pg_listener
171+
WHERE listenerpid = pg_catalog.pg_backend_pid();

postgresql/test/test_driver.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,9 @@ def testNotify(self):
14791479
self.db.notify('foo')
14801480
self.db.execute('')
14811481
self.failUnlessEqual(self.db._notifies, [])
1482+
# Invoke an error to show that listen() is all or none.
1483+
self.failUnlessRaises(Exception, self.db.listen, 'doesntexist', 'x'*64)
1484+
self.failUnless('doesntexist' not in self.db.listening_channels())
14821485

14831486
if __name__ == '__main__':
14841487
unittest.main()

0 commit comments

Comments
 (0)