Mercurial > libervia-pubsub
annotate idavoll/pgsql_backend.py @ 41:ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
class for the actual storage.
author | Ralph Meijer <ralphm@ik.nu> |
---|---|
date | Sun, 31 Oct 2004 21:11:03 +0000 |
parents | 39d0c6fa027f |
children | 9685b7e291ef |
rev | line source |
---|---|
28 | 1 from twisted.application import service |
2 from twisted.internet import defer | |
3 from twisted.protocols.jabber import jid | |
4 from twisted.enterprise import adbapi | |
5 import backend | |
6 | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
7 class Storage: |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
8 def __init__(self, user, database): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
9 self.dbpool = adbapi.ConnectionPool('pyPgSQL.PgSQL', user=user, |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
10 database=database) |
28 | 11 |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
12 def _get_node_configuration(self, cursor, node_id): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
13 configuration = {} |
28 | 14 cursor.execute("""SELECT persistent, deliver_payload FROM nodes |
15 WHERE node=%s""", | |
16 (node_id,)) | |
17 try: | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
18 (configuration["persist_items"], |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
19 configuration["deliver_payloads"]) = cursor.fetchone() |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
20 return configuration |
28 | 21 except TypeError: |
22 raise backend.NodeNotFound | |
23 | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
24 def get_node_configuration(self, node_id): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
25 return self.dbpool.runInteraction(self._get_node_configuration, node_id) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
26 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
27 def _get_affiliation(self, cursor, node_id, entity): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
28 cursor.execute("""SELECT affiliation FROM affiliations |
28 | 29 JOIN nodes ON (node_id=nodes.id) |
30 JOIN entities ON (entity_id=entities.id) | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
31 WHERE node=%s AND jid=%s""", |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
32 (node_id.encode('utf8'), entity.encode('utf8'))) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
33 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
34 try: |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
35 return cursor.fetchone()[0] |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
36 except TypeError: |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
37 return None |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
38 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
39 def get_affiliation(self, node_id, entity): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
40 return self.dbpool.runInteraction(self._get_affiliation, node_id, |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
41 entity) |
28 | 42 |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
43 def get_subscribers(self, node_id): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
44 d = self.dbpool.runQuery("""SELECT jid, resource FROM subscriptions |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
45 JOIN nodes ON (node_id=nodes.id) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
46 JOIN entities ON (entity_id=entities.id) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
47 WHERE node=%s AND |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
48 subscription='subscribed'""", |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
49 (node_id.encode('utf8'),)) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
50 d.addCallback(self._convert_to_jids) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
51 return d |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
52 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
53 def _convert_to_jids(self, list): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
54 return [jid.JID("%s/%s" % (l[0], l[1])).full() for l in list] |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
55 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
56 class BackendService(backend.BackendService): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
57 """ PostgreSQL backend Service for a JEP-0060 pubsub service """ |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
58 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
59 def __init__(self, storage): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
60 backend.BackendService.__init__(self) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
61 self.storage = storage |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
62 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
63 def do_publish(self, result, node_id, items, requestor): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
64 print result |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
65 configuration = result[0][1] |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
66 persist_items = configuration["persist_items"] |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
67 deliver_payloads = configuration["deliver_payloads"] |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
68 affiliation = result[1][1] |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
69 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
70 if affiliation not in ['owner', 'publisher']: |
28 | 71 raise backend.NotAuthorized |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
72 |
28 | 73 if items and not persist_items and not deliver_payloads: |
74 raise backend.NoPayloadAllowed | |
75 elif not items and (persist_items or deliver_payloads): | |
76 raise backend.PayloadExpected | |
77 | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
78 print "publish by %s to %s" % (requestor.full(), node_id) |
28 | 79 |
80 if persist_items or deliver_payloads: | |
81 for item in items: | |
82 if item["id"] is None: | |
83 item["id"] = 'random' # FIXME | |
84 | |
85 if persist_items: | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
86 d = self.store_items(node_id, items, requestor.full()) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
87 else: |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
88 d = defer.succeed(None) |
28 | 89 |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
90 d.addCallback(self.do_notify, node_id, items, deliver_payloads) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
91 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
92 def do_notify(self, result, node_id, items, deliver_payloads): |
28 | 93 if items and not deliver_payloads: |
94 for item in items: | |
95 item.children = [] | |
96 | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
97 self.dispatch({ 'items': items, 'node_id': node_id }, |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
98 '//event/pubsub/notify') |
28 | 99 |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
100 def publish(self, node_id, items, requestor): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
101 d1 = self.storage.get_node_configuration(node_id) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
102 d2 = self.storage.get_affiliation(node_id, requestor.full()) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
103 d = defer.DeferredList([d1, d2], fireOnOneErrback=1) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
104 d.addErrback(lambda x: x.value[0]) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
105 d.addCallback(self.do_publish, node_id, items, requestor) |
28 | 106 return d |
107 | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
108 def get_notification_list(self, node_id, items): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
109 d = self.storage.get_subscribers(node_id) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
110 d.addCallback(self._magic_filter, node_id, items) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
111 return d |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
112 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
113 def _magic_filter(self, subscribers, node_id, items): |
28 | 114 list = {} |
115 for subscriber in subscribers: | |
116 list[subscriber] = items | |
117 | |
118 return list | |
119 | |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
120 def store_items(self, node_id, items, publisher): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
121 return defer.succeed(None) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
122 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
123 class PublishService(service.Service): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
124 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
125 __implements__ = backend.IPublishService, |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
126 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
127 def publish(self, node_id, items, requestor): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
128 return self.parent.publish(node_id, items, requestor) |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
129 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
130 class NotificationService(backend.NotificationService): |
28 | 131 |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
132 __implements__ = backend.INotificationService, |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
133 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
134 def get_notification_list(self, node_id, items): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
135 return self.parent.get_notification_list(node_id, items) |
28 | 136 |
41
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
137 class PersistenceService(service.Service): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
138 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
139 __implements__ = backend.IPersistenceService, |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
140 |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
141 def store_items(self, node_id, items, publisher): |
ea3d3544a52e
Rewrite using separated backend interfaces. The backend also uses a separate
Ralph Meijer <ralphm@ik.nu>
parents:
28
diff
changeset
|
142 return self.parent.store_items(node_id, items, publisher) |