annotate idavoll/pgsql_storage.py @ 173:246911bcb699

Make node type part of node configuration.
author Ralph Meijer <ralphm@ik.nu>
date Wed, 09 Apr 2008 11:43:16 +0000
parents bc269696ef42
children fc687620599b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
171
bc269696ef42 Reply with the correct error condition on subscription when not subscribed.
Ralph Meijer <ralphm@ik.nu>
parents: 170
diff changeset
1 # Copyright (c) 2003-2008 Ralph Meijer
155
5191ba7c4df8 Work towards first release 0.5.0.
Ralph Meijer <ralphm@ik.nu>
parents: 148
diff changeset
2 # See LICENSE for details.
5191ba7c4df8 Work towards first release 0.5.0.
Ralph Meijer <ralphm@ik.nu>
parents: 148
diff changeset
3
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
4 import copy
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
5 from twisted.enterprise import adbapi
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
6 from twisted.words.protocols.jabber import jid
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
7 from zope.interface import implements
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
8
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
9 from idavoll import error, iidavoll
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
10
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
11 class Storage:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
12
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
13 implements(iidavoll.IStorage)
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
14
170
958e69630e52 Provide twistd parameters for connecting to a remote PostgreSQL database.
Ralph Meijer <ralphm@ik.nu>
parents: 167
diff changeset
15 def __init__(self, user, database, password=None, host=None, port=None):
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
16 self._dbpool = adbapi.ConnectionPool('pyPgSQL.PgSQL',
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
17 user=user,
163
1701c0e2c707 Add --dbpass option for passing a password to the PostgreSQL backend.
Ralph Meijer <ralphm@ik.nu>
parents: 155
diff changeset
18 password=password,
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
19 database=database,
170
958e69630e52 Provide twistd parameters for connecting to a remote PostgreSQL database.
Ralph Meijer <ralphm@ik.nu>
parents: 167
diff changeset
20 host=host,
958e69630e52 Provide twistd parameters for connecting to a remote PostgreSQL database.
Ralph Meijer <ralphm@ik.nu>
parents: 167
diff changeset
21 port=port,
958e69630e52 Provide twistd parameters for connecting to a remote PostgreSQL database.
Ralph Meijer <ralphm@ik.nu>
parents: 167
diff changeset
22 cp_reconnect=True,
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
23 client_encoding='utf-8'
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
24 )
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
25
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
26 def get_node(self, node_id):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
27 return self._dbpool.runInteraction(self._get_node, node_id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
28
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
29 def _get_node(self, cursor, node_id):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
30 configuration = {}
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
31 cursor.execute("""SELECT persistent, deliver_payload FROM nodes
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
32 WHERE node=%s""",
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
33 (node_id,))
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
34 try:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
35 (configuration["pubsub#persist_items"],
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
36 configuration["pubsub#deliver_payloads"]) = cursor.fetchone()
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
37 except TypeError:
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
38 raise error.NodeNotFound()
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
39 else:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
40 node = LeafNode(node_id, configuration)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
41 node._dbpool = self._dbpool
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
42 return node
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
43
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
44 def get_node_ids(self):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
45 d = self._dbpool.runQuery("""SELECT node from nodes""")
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
46 d.addCallback(lambda results: [r[0] for r in results])
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
47 return d
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
48
173
246911bcb699 Make node type part of node configuration.
Ralph Meijer <ralphm@ik.nu>
parents: 171
diff changeset
49 def create_node(self, node_id, owner, config=None):
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
50 return self._dbpool.runInteraction(self._create_node, node_id, owner)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
51
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
52 def _create_node(self, cursor, node_id, owner):
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
53 node_id = node_id
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
54 owner = owner.userhost()
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
55 try:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
56 cursor.execute("""INSERT INTO nodes (node) VALUES (%s)""",
113
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
57 (node_id))
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
58 except cursor._pool.dbapi.OperationalError:
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
59 raise error.NodeExists()
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
60
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
61 cursor.execute("""SELECT 1 from entities where jid=%s""",
113
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
62 (owner))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
63
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
64 if not cursor.fetchone():
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
65 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
113
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
66 (owner))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
67
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
68 cursor.execute("""INSERT INTO affiliations
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
69 (node_id, entity_id, affiliation)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
70 SELECT n.id, e.id, 'owner' FROM
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
71 (SELECT id FROM nodes WHERE node=%s) AS n
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
72 CROSS JOIN
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
73 (SELECT id FROM entities WHERE jid=%s) AS e""",
113
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
74 (node_id, owner))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
75
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
76 def delete_node(self, node_id):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
77 return self._dbpool.runInteraction(self._delete_node, node_id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
78
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
79 def _delete_node(self, cursor, node_id):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
80 cursor.execute("""DELETE FROM nodes WHERE node=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
81 (node_id,))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
82
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
83 if cursor.rowcount != 1:
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
84 raise error.NodeNotFound()
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
85
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
86 def get_affiliations(self, entity):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
87 d = self._dbpool.runQuery("""SELECT node, affiliation FROM entities
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
88 JOIN affiliations ON
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
89 (affiliations.entity_id=entities.id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
90 JOIN nodes ON
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
91 (nodes.id=affiliations.node_id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
92 WHERE jid=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
93 (entity.userhost(),))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
94 d.addCallback(lambda results: [tuple(r) for r in results])
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
95 return d
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
96
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
97 def get_subscriptions(self, entity):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
98 d = self._dbpool.runQuery("""SELECT node, jid, resource, subscription
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
99 FROM entities JOIN subscriptions ON
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
100 (subscriptions.entity_id=entities.id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
101 JOIN nodes ON
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
102 (nodes.id=subscriptions.node_id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
103 WHERE jid=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
104 (entity.userhost(),))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
105 d.addCallback(self._convert_subscription_jids)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
106 return d
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
108 def _convert_subscription_jids(self, subscriptions):
148
b03e5ad81173 Change all calls to jid.JID to jid.internJID to avoid redoing stringprep.
Ralph Meijer <ralphm@ik.nu>
parents: 146
diff changeset
109 return [(node,
b03e5ad81173 Change all calls to jid.JID to jid.internJID to avoid redoing stringprep.
Ralph Meijer <ralphm@ik.nu>
parents: 146
diff changeset
110 jid.internJID('%s/%s' % (subscriber, resource)),
b03e5ad81173 Change all calls to jid.JID to jid.internJID to avoid redoing stringprep.
Ralph Meijer <ralphm@ik.nu>
parents: 146
diff changeset
111 subscription)
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
112 for node, subscriber, resource, subscription in subscriptions]
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
113
171
bc269696ef42 Reply with the correct error condition on subscription when not subscribed.
Ralph Meijer <ralphm@ik.nu>
parents: 170
diff changeset
114
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
115 class Node:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
116
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
117 implements(iidavoll.INode)
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
118
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
119 def __init__(self, node_id, config):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
120 self.id = node_id
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
121 self._config = config
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
122
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
123 def _check_node_exists(self, cursor):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
124 cursor.execute("""SELECT id FROM nodes WHERE node=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
125 (self.id))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
126 if not cursor.fetchone():
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
127 raise error.NodeNotFound()
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
128
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
129 def get_type(self):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
130 return self.type
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
131
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
132 def get_configuration(self):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
133 return self._config
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
134
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
135 def set_configuration(self, options):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
136 config = copy.copy(self._config)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
137
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
138 for option in options:
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
139 if option in config:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
140 config[option] = options[option]
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
141
124
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
142 d = self._dbpool.runInteraction(self._set_configuration, config)
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
143 d.addCallback(self._set_cached_configuration, config)
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
144 return d
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
145
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
146 def _set_configuration(self, cursor, config):
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
147 self._check_node_exists(cursor)
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
148 cursor.execute("""UPDATE nodes SET persistent=%s, deliver_payload=%s
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
149 WHERE node=%s""",
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
150 (config["pubsub#persist_items"],
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
151 config["pubsub#deliver_payloads"],
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
152 self.id))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
153
124
c4ee16bc48e5 Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents: 121
diff changeset
154 def _set_cached_configuration(self, void, config):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
155 self._config = config
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
156
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
157 def get_meta_data(self):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
158 config = copy.copy(self._config)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
159 config["pubsub#node_type"] = self.type
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
160 return config
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
161
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
162 def get_affiliation(self, entity):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
163 return self._dbpool.runInteraction(self._get_affiliation, entity)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
164
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
165 def _get_affiliation(self, cursor, entity):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
166 self._check_node_exists(cursor)
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
167 cursor.execute("""SELECT affiliation FROM affiliations
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
168 JOIN nodes ON (node_id=nodes.id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
169 JOIN entities ON (entity_id=entities.id)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
170 WHERE node=%s AND jid=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
171 (self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
172 entity.userhost()))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
173
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
174 try:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
175 return cursor.fetchone()[0]
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
176 except TypeError:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
177 return None
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
178
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
179 def get_subscription(self, subscriber):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
180 return self._dbpool.runInteraction(self._get_subscription, subscriber)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
181
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
182 def _get_subscription(self, cursor, subscriber):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
183 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
184
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
185 userhost = subscriber.userhost()
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
186 resource = subscriber.resource or ''
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
187
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
188 cursor.execute("""SELECT subscription FROM subscriptions
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
189 JOIN nodes ON (nodes.id=subscriptions.node_id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
190 JOIN entities ON
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
191 (entities.id=subscriptions.entity_id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
192 WHERE node=%s AND jid=%s AND resource=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
193 (self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
194 userhost,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
195 resource))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
196 try:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
197 return cursor.fetchone()[0]
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
198 except TypeError:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
199 return None
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
200
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
201 def add_subscription(self, subscriber, state):
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
202 return self._dbpool.runInteraction(self._add_subscription, subscriber,
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
203 state)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
204
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
205 def _add_subscription(self, cursor, subscriber, state):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
206 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
207
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
208 userhost = subscriber.userhost()
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
209 resource = subscriber.resource or ''
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
210
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
211 try:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
212 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
213 (userhost))
113
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
214 except cursor._pool.dbapi.OperationalError:
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
215 pass
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
216
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
217 try:
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
218 cursor.execute("""INSERT INTO subscriptions
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
219 (node_id, entity_id, resource, subscription)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
220 SELECT n.id, e.id, %s, %s FROM
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
221 (SELECT id FROM nodes WHERE node=%s) AS n
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
222 CROSS JOIN
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
223 (SELECT id FROM entities WHERE jid=%s) AS e""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
224 (resource,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
225 state,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
226 self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
227 userhost))
113
dfef919aaf1b Fix interpretations of JIDs.
Ralph Meijer <ralphm@ik.nu>
parents: 107
diff changeset
228 except cursor._pool.dbapi.OperationalError:
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
229 raise error.SubscriptionExists()
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
230
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
231 def remove_subscription(self, subscriber):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
232 return self._dbpool.runInteraction(self._remove_subscription,
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
233 subscriber)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
234
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
235 def _remove_subscription(self, cursor, subscriber):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
236 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
237
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
238 userhost = subscriber.userhost()
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
239 resource = subscriber.resource or ''
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
240
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
241 cursor.execute("""DELETE FROM subscriptions WHERE
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
242 node_id=(SELECT id FROM nodes WHERE node=%s) AND
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
243 entity_id=(SELECT id FROM entities WHERE jid=%s)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
244 AND resource=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
245 (self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
246 userhost,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
247 resource))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
248 if cursor.rowcount != 1:
171
bc269696ef42 Reply with the correct error condition on subscription when not subscribed.
Ralph Meijer <ralphm@ik.nu>
parents: 170
diff changeset
249 raise error.NotSubscribed()
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
250
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
251 return None
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
252
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
253 def get_subscribers(self):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
254 d = self._dbpool.runInteraction(self._get_subscribers)
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
255 d.addCallback(self._convert_to_jids)
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
256 return d
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
257
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
258 def _get_subscribers(self, cursor):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
259 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
260 cursor.execute("""SELECT jid, resource FROM subscriptions
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
261 JOIN nodes ON (node_id=nodes.id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
262 JOIN entities ON (entity_id=entities.id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
263 WHERE node=%s AND
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
264 subscription='subscribed'""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
265 (self.id,))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
266 return cursor.fetchall()
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
267
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
268 def _convert_to_jids(self, list):
148
b03e5ad81173 Change all calls to jid.JID to jid.internJID to avoid redoing stringprep.
Ralph Meijer <ralphm@ik.nu>
parents: 146
diff changeset
269 return [jid.internJID("%s/%s" % (l[0], l[1])) for l in list]
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
270
146
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
271 def is_subscribed(self, entity):
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
272 return self._dbpool.runInteraction(self._is_subscribed, entity)
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
273
146
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
274 def _is_subscribed(self, cursor, entity):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
275 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
276
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
277 cursor.execute("""SELECT 1 FROM entities
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
278 JOIN subscriptions ON
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
279 (entities.id=subscriptions.entity_id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
280 JOIN nodes ON
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
281 (nodes.id=subscriptions.node_id)
146
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
282 WHERE entities.jid=%s
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
283 AND node=%s AND subscription='subscribed'""",
146
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
284 (entity.userhost(),
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
285 self.id))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
286
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
287 return cursor.fetchone() is not None
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
288
145
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
289 def get_affiliations(self):
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
290 return self._dbpool.runInteraction(self._get_affiliations)
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
291
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
292 def _get_affiliations(self, cursor):
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
293 self._check_node_exists(cursor)
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
294
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
295 cursor.execute("""SELECT jid, affiliation FROM nodes
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
296 JOIN affiliations ON
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
297 (nodes.id = affiliations.node_id)
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
298 JOIN entities ON
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
299 (affiliations.entity_id = entities.id)
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
300 WHERE node=%s""",
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
301 self.id)
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
302 result = cursor.fetchall()
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
303
148
b03e5ad81173 Change all calls to jid.JID to jid.internJID to avoid redoing stringprep.
Ralph Meijer <ralphm@ik.nu>
parents: 146
diff changeset
304 return [(jid.internJID(r[0]), r[1]) for r in result]
145
f393bccec4bc Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents: 142
diff changeset
305
146
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
306 class LeafNodeMixin:
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
307
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
308 type = 'leaf'
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
309
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
310 def store_items(self, items, publisher):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
311 return self._dbpool.runInteraction(self._store_items, items, publisher)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
312
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
313 def _store_items(self, cursor, items, publisher):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
314 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
315 for item in items:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
316 self._store_item(cursor, item, publisher)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
317
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
318 def _store_item(self, cursor, item, publisher):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
319 data = item.toXml()
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
320 cursor.execute("""UPDATE items SET date=now(), publisher=%s, data=%s
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
321 FROM nodes
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
322 WHERE nodes.id = items.node_id AND
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
323 nodes.node = %s and items.item=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
324 (publisher.full(),
127
d3689da18ed2 Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents: 124
diff changeset
325 data,
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
326 self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
327 item["id"]))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
328 if cursor.rowcount == 1:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
329 return
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
330
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
331 cursor.execute("""INSERT INTO items (node_id, item, publisher, data)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
332 SELECT id, %s, %s, %s FROM nodes WHERE node=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
333 (item["id"],
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
334 publisher.full(),
127
d3689da18ed2 Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents: 124
diff changeset
335 data,
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
336 self.id))
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
337
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
338 def remove_items(self, item_ids):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
339 return self._dbpool.runInteraction(self._remove_items, item_ids)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
340
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
341 def _remove_items(self, cursor, item_ids):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
342 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
343
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
344 deleted = []
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
345
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
346 for item_id in item_ids:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
347 cursor.execute("""DELETE FROM items WHERE
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
348 node_id=(SELECT id FROM nodes WHERE node=%s) AND
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
349 item=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
350 (self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
351 item_id))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
352
142
812300cdbc22 Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents: 136
diff changeset
353 if cursor.rowcount:
812300cdbc22 Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents: 136
diff changeset
354 deleted.append(item_id)
812300cdbc22 Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents: 136
diff changeset
355
812300cdbc22 Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents: 136
diff changeset
356 return deleted
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
357
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
358 def get_items(self, max_items=None):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
359 return self._dbpool.runInteraction(self._get_items, max_items)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
360
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
361 def _get_items(self, cursor, max_items):
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
362 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
363 query = """SELECT data FROM nodes JOIN items ON
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
364 (nodes.id=items.node_id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
365 WHERE node=%s ORDER BY date DESC"""
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
366 if max_items:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
367 cursor.execute(query + " LIMIT %s",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
368 (self.id,
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
369 max_items))
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
370 else:
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
371 cursor.execute(query, (self.id))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
372
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
373 result = cursor.fetchall()
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
374 return [unicode(r[0], 'utf-8') for r in result]
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
375
127
d3689da18ed2 Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents: 124
diff changeset
376 def get_items_by_id(self, item_ids):
d3689da18ed2 Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents: 124
diff changeset
377 return self._dbpool.runInteraction(self._get_items_by_id, item_ids)
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
378
127
d3689da18ed2 Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents: 124
diff changeset
379 def _get_items_by_id(self, cursor, item_ids):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
380 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
381 items = []
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
382 for item_id in item_ids:
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
383 cursor.execute("""SELECT data FROM nodes JOIN items ON
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
384 (nodes.id=items.node_id)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
385 WHERE node=%s AND item=%s""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
386 (self.id,
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
387 item_id))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
388 result = cursor.fetchone()
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
389 if result:
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
390 items.append(unicode(result[0], 'utf-8'))
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
391 return items
107
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
392
d252d793f0ed Initial revision.
Ralph Meijer <ralphm@ik.nu>
parents:
diff changeset
393 def purge(self):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
394 return self._dbpool.runInteraction(self._purge)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
395
127
d3689da18ed2 Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents: 124
diff changeset
396 def _purge(self, cursor):
121
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
397 self._check_node_exists(cursor)
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
398
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
399 cursor.execute("""DELETE FROM items WHERE
4f0113adb7ed Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents: 113
diff changeset
400 node_id=(SELECT id FROM nodes WHERE node=%s)""",
136
327de183f48d Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents: 127
diff changeset
401 (self.id,))
146
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
402
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
403 class LeafNode(Node, LeafNodeMixin):
b4490bdc77e5 Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents: 145
diff changeset
404
167
ef22e4150caa Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents: 163
diff changeset
405 implements(iidavoll.ILeafNode)