Mercurial > libervia-pubsub
annotate sat_pubsub/pgsql_storage.py @ 405:c56a728412f1
file organisation + setup refactoring:
- `/src` has been renamed to `/sat_pubsub`, this is the recommended naming convention
- revamped `setup.py` on the basis of SàT's `setup.py`
- added a `VERSION` which is the unique place where version number will now be set
- use same trick as in SàT to specify dev version (`D` at the end)
- use setuptools_scm to retrieve Mercurial hash when in dev version
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 16 Aug 2019 12:00:02 +0200 |
parents | src/pgsql_storage.py@1dc606612405 |
children | a58610ab2983 |
rev | line source |
---|---|
233 | 1 #!/usr/bin/python |
2 #-*- coding: utf-8 -*- | |
3 | |
384 | 4 # Copyright (c) 2012-2019 Jérôme Poisson |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
5 # Copyright (c) 2013-2016 Adrien Cossa |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
6 # Copyright (c) 2003-2011 Ralph Meijer |
233 | 7 |
8 | |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
9 # This program is free software: you can redistribute it and/or modify |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
10 # it under the terms of the GNU Affero General Public License as published by |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
11 # the Free Software Foundation, either version 3 of the License, or |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
12 # (at your option) any later version. |
233 | 13 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
14 # This program is distributed in the hope that it will be useful, |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
17 # GNU Affero General Public License for more details. |
233 | 18 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
19 # You should have received a copy of the GNU Affero General Public License |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
20 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
21 # -- |
233 | 22 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
23 # This program is based on Idavoll (http://idavoll.ik.nu/), |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
24 # originaly written by Ralph Meijer (http://ralphm.net/blog/) |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
25 # It is sublicensed under AGPL v3 (or any later version) as allowed by the original |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
26 # license. |
233 | 27 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
28 # -- |
233 | 29 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
30 # Here is a copy of the original license: |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
31 |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
32 # Copyright (c) 2003-2011 Ralph Meijer |
233 | 33 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
34 # Permission is hereby granted, free of charge, to any person obtaining |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
35 # a copy of this software and associated documentation files (the |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
36 # "Software"), to deal in the Software without restriction, including |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
37 # without limitation the rights to use, copy, modify, merge, publish, |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
38 # distribute, sublicense, and/or sell copies of the Software, and to |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
39 # permit persons to whom the Software is furnished to do so, subject to |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
40 # the following conditions: |
233 | 41 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
42 # The above copyright notice and this permission notice shall be |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
43 # included in all copies or substantial portions of the Software. |
233 | 44 |
312
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
45 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
46 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
47 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
48 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
49 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
50 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
5d7c3787672e
fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
51 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
233 | 52 |
155
5191ba7c4df8
Work towards first release 0.5.0.
Ralph Meijer <ralphm@ik.nu>
parents:
148
diff
changeset
|
53 |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
54 import copy, logging |
202
77c61e2b8c75
Use `domish.Element`s to represent items, instead of serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents:
198
diff
changeset
|
55 |
77c61e2b8c75
Use `domish.Element`s to represent items, instead of serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents:
198
diff
changeset
|
56 from zope.interface import implements |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
57 |
344
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
58 from twisted.internet import reactor |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
59 from twisted.internet import defer |
107 | 60 from twisted.words.protocols.jabber import jid |
323 | 61 from twisted.python import log |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
62 |
271
232002e132db
pgsql_backend unicode fix: parseXml was expecting str and getting unicode
Goffi <goffi@goffi.org>
parents:
270
diff
changeset
|
63 from wokkel import generic |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
64 from wokkel.pubsub import Subscription |
107 | 65 |
317
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
66 from sat_pubsub import error |
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
67 from sat_pubsub import iidavoll |
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
68 from sat_pubsub import const |
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
69 from sat_pubsub import container |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
70 from sat_pubsub import exceptions |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
71 import uuid |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
72 import psycopg2 |
270
f17034e4cf4a
fixed unicode handling with psycopg2
Goffi <goffi@goffi.org>
parents:
265
diff
changeset
|
73 import psycopg2.extensions |
271
232002e132db
pgsql_backend unicode fix: parseXml was expecting str and getting unicode
Goffi <goffi@goffi.org>
parents:
270
diff
changeset
|
74 # we wants psycopg2 to return us unicode, not str |
270
f17034e4cf4a
fixed unicode handling with psycopg2
Goffi <goffi@goffi.org>
parents:
265
diff
changeset
|
75 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) |
f17034e4cf4a
fixed unicode handling with psycopg2
Goffi <goffi@goffi.org>
parents:
265
diff
changeset
|
76 psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY) |
244 | 77 |
271
232002e132db
pgsql_backend unicode fix: parseXml was expecting str and getting unicode
Goffi <goffi@goffi.org>
parents:
270
diff
changeset
|
78 # parseXml manage str, but we get unicode |
232002e132db
pgsql_backend unicode fix: parseXml was expecting str and getting unicode
Goffi <goffi@goffi.org>
parents:
270
diff
changeset
|
79 parseXml = lambda unicode_data: generic.parseXml(unicode_data.encode('utf-8')) |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
80 ITEMS_SEQ_NAME = u'node_{node_id}_seq' |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
81 PEP_COL_NAME = 'pep' |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
82 CURRENT_VERSION = '5' |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
83 # retrieve the maximum integer item id + 1 |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
84 NEXT_ITEM_ID_QUERY = r"SELECT COALESCE(max(item::integer)+1,1) as val from items where node_id={node_id} and item ~ E'^\\d+$'" |
271
232002e132db
pgsql_backend unicode fix: parseXml was expecting str and getting unicode
Goffi <goffi@goffi.org>
parents:
270
diff
changeset
|
85 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
86 |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
87 def withPEP(query, values, pep, recipient): |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
88 """Helper method to facilitate PEP management |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
89 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
90 @param query: SQL query basis |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
91 @param values: current values to replace in query |
364
8bd8be6815ab
completed docstrings + use short notation for sets
Arnaud Joset <info@agayon.be>
parents:
357
diff
changeset
|
92 @param pep(bool): True if we are in PEP mode |
8bd8be6815ab
completed docstrings + use short notation for sets
Arnaud Joset <info@agayon.be>
parents:
357
diff
changeset
|
93 @param recipient(jid.JID): jid of the recipient |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
94 @return: query + PEP AND check, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
95 recipient's bare jid is added to value if needed |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
96 """ |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
97 if pep: |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
98 pep_check="AND {}=%s".format(PEP_COL_NAME) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
99 values=list(values) + [recipient.userhost()] |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
100 else: |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
101 pep_check="AND {} IS NULL".format(PEP_COL_NAME) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
102 return "{} {}".format(query, pep_check), values |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
103 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
104 |
107 | 105 class Storage: |
106 | |
167
ef22e4150caa
Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents:
163
diff
changeset
|
107 implements(iidavoll.IStorage) |
107 | 108 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
109 defaultConfig = { |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
110 'leaf': { |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
111 const.OPT_PERSIST_ITEMS: True, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
112 const.OPT_DELIVER_PAYLOADS: True, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
113 const.OPT_SEND_LAST_PUBLISHED_ITEM: 'on_sub', |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
114 const.OPT_ACCESS_MODEL: const.VAL_AMODEL_DEFAULT, |
260 | 115 const.OPT_PUBLISH_MODEL: const.VAL_PMODEL_DEFAULT, |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
116 const.OPT_SERIAL_IDS: False, |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
117 const.OPT_CONSISTENT_PUBLISHER: False, |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
118 }, |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
119 'collection': { |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
120 const.OPT_DELIVER_PAYLOADS: True, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
121 const.OPT_SEND_LAST_PUBLISHED_ITEM: 'on_sub', |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
122 const.OPT_ACCESS_MODEL: const.VAL_AMODEL_DEFAULT, |
260 | 123 const.OPT_PUBLISH_MODEL: const.VAL_PMODEL_DEFAULT, |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
124 } |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
125 } |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
126 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
127 def __init__(self, dbpool): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
128 self.dbpool = dbpool |
344
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
129 d = self.dbpool.runQuery("SELECT value FROM metadata WHERE key='version'") |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
130 d.addCallbacks(self._checkVersion, self._versionEb) |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
131 |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
132 def _checkVersion(self, row): |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
133 version = row[0].value |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
134 if version != CURRENT_VERSION: |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
135 logging.error("Bad database schema version ({current}), please upgrade to {needed}".format( |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
136 current=version, needed=CURRENT_VERSION)) |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
137 reactor.stop() |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
138 |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
139 def _versionEb(self, failure): |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
140 logging.error("Can't check schema version: {reason}".format(reason=failure)) |
8cf1be9572f8
pgsql: check schema version and exit with a message asking to upgrade if it's not the current one
Goffi <goffi@goffi.org>
parents:
341
diff
changeset
|
141 reactor.stop() |
107 | 142 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
143 def _buildNode(self, row): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
144 """Build a note class from database result row""" |
107 | 145 configuration = {} |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
146 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
147 if not row: |
167
ef22e4150caa
Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents:
163
diff
changeset
|
148 raise error.NodeNotFound() |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
149 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
150 if row[2] == 'leaf': |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
151 configuration = { |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
152 'pubsub#persist_items': row[3], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
153 'pubsub#deliver_payloads': row[4], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
154 'pubsub#send_last_published_item': row[5], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
155 const.OPT_ACCESS_MODEL:row[6], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
156 const.OPT_PUBLISH_MODEL:row[7], |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
157 const.OPT_SERIAL_IDS:row[8], |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
158 const.OPT_CONSISTENT_PUBLISHER:row[9], |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
159 } |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
160 schema = row[10] |
352 | 161 if schema is not None: |
162 schema = parseXml(schema) | |
163 node = LeafNode(row[0], row[1], configuration, schema) | |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
164 node.dbpool = self.dbpool |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
165 return node |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
166 elif row[2] == 'collection': |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
167 configuration = { |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
168 'pubsub#deliver_payloads': row[4], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
169 'pubsub#send_last_published_item': row[5], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
170 const.OPT_ACCESS_MODEL: row[6], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
171 const.OPT_PUBLISH_MODEL:row[7], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
172 } |
352 | 173 node = CollectionNode(row[0], row[1], configuration, None) |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
174 node.dbpool = self.dbpool |
107 | 175 return node |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
176 else: |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
177 raise ValueError("Unknown node type !") |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
178 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
179 def getNodeById(self, nodeDbId): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
180 """Get node using database ID insted of pubsub identifier |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
181 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
182 @param nodeDbId(unicode): database ID |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
183 """ |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
184 return self.dbpool.runInteraction(self._getNodeById, nodeDbId) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
185 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
186 def _getNodeById(self, cursor, nodeDbId): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
187 cursor.execute("""SELECT node_id, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
188 node, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
189 node_type, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
190 persist_items, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
191 deliver_payloads, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
192 send_last_published_item, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
193 access_model, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
194 publish_model, |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
195 serial_ids, |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
196 consistent_publisher, |
352 | 197 schema::text, |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
198 pep |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
199 FROM nodes |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
200 WHERE node_id=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
201 (nodeDbId,)) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
202 row = cursor.fetchone() |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
203 return self._buildNode(row) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
204 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
205 def getNode(self, nodeIdentifier, pep, recipient=None): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
206 return self.dbpool.runInteraction(self._getNode, nodeIdentifier, pep, recipient) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
207 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
208 def _getNode(self, cursor, nodeIdentifier, pep, recipient): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
209 cursor.execute(*withPEP("""SELECT node_id, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
210 node, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
211 node_type, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
212 persist_items, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
213 deliver_payloads, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
214 send_last_published_item, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
215 access_model, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
216 publish_model, |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
217 serial_ids, |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
218 consistent_publisher, |
352 | 219 schema::text, |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
220 pep |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
221 FROM nodes |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
222 WHERE node=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
223 (nodeIdentifier,), pep, recipient)) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
224 row = cursor.fetchone() |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
225 return self._buildNode(row) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
226 |
349
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
227 def getNodeIds(self, pep, recipient, allowed_accesses=None): |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
228 """retrieve ids of existing nodes |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
229 |
364
8bd8be6815ab
completed docstrings + use short notation for sets
Arnaud Joset <info@agayon.be>
parents:
357
diff
changeset
|
230 @param pep(bool): True if it's a PEP request |
8bd8be6815ab
completed docstrings + use short notation for sets
Arnaud Joset <info@agayon.be>
parents:
357
diff
changeset
|
231 @param recipient(jid.JID, None): recipient of the PEP request |
349
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
232 @param allowed_accesses(None, set): only nodes with access |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
233 in this set will be returned |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
234 None to return all nodes |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
235 @return (list[unicode]): ids of nodes |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
236 """ |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
237 if not pep: |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
238 query = "SELECT node from nodes WHERE pep is NULL" |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
239 values = [] |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
240 else: |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
241 query = "SELECT node from nodes WHERE pep=%s" |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
242 values = [recipient.userhost()] |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
243 |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
244 if allowed_accesses is not None: |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
245 query += "AND access_model IN %s" |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
246 values.append(tuple(allowed_accesses)) |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
247 |
20b82fb8de02
backend: check nodes/items permission on disco#items:
Goffi <goffi@goffi.org>
parents:
347
diff
changeset
|
248 d = self.dbpool.runQuery(query, values) |
107 | 249 d.addCallback(lambda results: [r[0] for r in results]) |
250 return d | |
251 | |
352 | 252 def createNode(self, nodeIdentifier, owner, config, schema, pep, recipient=None): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
253 return self.dbpool.runInteraction(self._createNode, nodeIdentifier, |
352 | 254 owner, config, schema, pep, recipient) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
255 |
352 | 256 def _createNode(self, cursor, nodeIdentifier, owner, config, schema, pep, recipient): |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
257 if config['pubsub#node_type'] != 'leaf': |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
258 raise error.NoCollections() |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
259 |
136
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
260 owner = owner.userhost() |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
261 |
107 | 262 try: |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
263 cursor.execute("""INSERT INTO nodes |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
264 (node, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
265 node_type, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
266 persist_items, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
267 deliver_payloads, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
268 send_last_published_item, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
269 access_model, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
270 publish_model, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
271 serial_ids, |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
272 consistent_publisher, |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
273 schema, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
274 pep) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
275 VALUES |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
276 (%s, 'leaf', %s, %s, %s, %s, %s, %s, %s, %s, %s)""", |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
277 (nodeIdentifier, |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
278 config['pubsub#persist_items'], |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
279 config['pubsub#deliver_payloads'], |
240
70c8bb90d75f
added access_model to config, default to 'open'
Goffi <goffi@goffi.org>
parents:
235
diff
changeset
|
280 config['pubsub#send_last_published_item'], |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
281 config[const.OPT_ACCESS_MODEL], |
260 | 282 config[const.OPT_PUBLISH_MODEL], |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
283 config[const.OPT_SERIAL_IDS], |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
284 config[const.OPT_CONSISTENT_PUBLISHER], |
352 | 285 schema, |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
286 recipient.userhost() if pep else None |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
287 ) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
288 ) |
332
31cbd8b9fa7f
pgsql: node creation now return error.NodeExists in case of unique violation, and InvalidConfigurationOption else
Goffi <goffi@goffi.org>
parents:
331
diff
changeset
|
289 except cursor._pool.dbapi.IntegrityError as e: |
31cbd8b9fa7f
pgsql: node creation now return error.NodeExists in case of unique violation, and InvalidConfigurationOption else
Goffi <goffi@goffi.org>
parents:
331
diff
changeset
|
290 if e.pgcode == "23505": |
31cbd8b9fa7f
pgsql: node creation now return error.NodeExists in case of unique violation, and InvalidConfigurationOption else
Goffi <goffi@goffi.org>
parents:
331
diff
changeset
|
291 # unique_violation |
31cbd8b9fa7f
pgsql: node creation now return error.NodeExists in case of unique violation, and InvalidConfigurationOption else
Goffi <goffi@goffi.org>
parents:
331
diff
changeset
|
292 raise error.NodeExists() |
31cbd8b9fa7f
pgsql: node creation now return error.NodeExists in case of unique violation, and InvalidConfigurationOption else
Goffi <goffi@goffi.org>
parents:
331
diff
changeset
|
293 else: |
31cbd8b9fa7f
pgsql: node creation now return error.NodeExists in case of unique violation, and InvalidConfigurationOption else
Goffi <goffi@goffi.org>
parents:
331
diff
changeset
|
294 raise error.InvalidConfigurationOption() |
167
ef22e4150caa
Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents:
163
diff
changeset
|
295 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
296 cursor.execute(*withPEP("""SELECT node_id FROM nodes WHERE node=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
297 (nodeIdentifier,), pep, recipient)); |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
298 node_id = cursor.fetchone()[0] |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
299 |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
300 cursor.execute("""SELECT 1 as bool from entities where jid=%s""", |
227
8540825f85e0
Replaced unmaintained pyPgSQL by Psycopg 2
Goffi <goffi@goffi.org>
parents:
206
diff
changeset
|
301 (owner,)) |
107 | 302 |
303 if not cursor.fetchone(): | |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
304 # XXX: we can NOT rely on the previous query! Commit is needed now because |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
305 # if the entry exists the next query will leave the database in a corrupted |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
306 # state: the solution is to rollback. I tried with other methods like |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
307 # "WHERE NOT EXISTS" but none of them worked, so the following solution |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
308 # looks like the sole - unless you have auto-commit on. More info |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
309 # about this issue: http://cssmay.com/question/tag/tag-psycopg2 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
310 cursor.connection.commit() |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
311 try: |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
312 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
313 (owner,)) |
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
314 except psycopg2.IntegrityError as e: |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
315 cursor.connection.rollback() |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
316 logging.warning("during node creation: %s" % e.message) |
107 | 317 |
318 cursor.execute("""INSERT INTO affiliations | |
319 (node_id, entity_id, affiliation) | |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
320 SELECT %s, entity_id, 'owner' FROM |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
321 (SELECT entity_id FROM entities |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
322 WHERE jid=%s) as e""", |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
323 (node_id, owner)) |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
324 |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
325 if config[const.OPT_ACCESS_MODEL] == const.VAL_AMODEL_PUBLISHER_ROSTER: |
259
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
326 if const.OPT_ROSTER_GROUPS_ALLOWED in config: |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
327 allowed_groups = config[const.OPT_ROSTER_GROUPS_ALLOWED] |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
328 else: |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
329 allowed_groups = [] |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
330 for group in allowed_groups: |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
331 #TODO: check that group are actually in roster |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
332 cursor.execute("""INSERT INTO node_groups_authorized (node_id, groupname) |
6fe7da6b4b32
node "roster" access model management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
333 VALUES (%s,%s)""" , (node_id, group)) |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
334 # XXX: affiliations can't be set on during node creation (at least not with XEP-0060 alone) |
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
335 # so whitelist affiliations need to be done afterward |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
336 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
337 # no we may have to do extra things according to config options |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
338 default_conf = self.defaultConfig['leaf'] |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
339 # XXX: trigger works on node creation because OPT_SERIAL_IDS is False in defaultConfig |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
340 # if this value is changed, the _configurationTriggers method should be adapted. |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
341 Node._configurationTriggers(cursor, node_id, default_conf, config) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
342 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
343 def deleteNodeByDbId(self, db_id): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
344 """Delete a node using directly its database id""" |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
345 return self.dbpool.runInteraction(self._deleteNodeByDbId, db_id) |
107 | 346 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
347 def _deleteNodeByDbId(self, cursor, db_id): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
348 cursor.execute("""DELETE FROM nodes WHERE node_id=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
349 (db_id,)) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
350 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
351 if cursor.rowcount != 1: |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
352 raise error.NodeNotFound() |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
353 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
354 def deleteNode(self, nodeIdentifier, pep, recipient=None): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
355 return self.dbpool.runInteraction(self._deleteNode, nodeIdentifier, pep, recipient) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
356 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
357 def _deleteNode(self, cursor, nodeIdentifier, pep, recipient): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
358 cursor.execute(*withPEP("""DELETE FROM nodes WHERE node=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
359 (nodeIdentifier,), pep, recipient)) |
107 | 360 |
361 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
|
362 raise error.NodeNotFound() |
107 | 363 |
331 | 364 def getAffiliations(self, entity, nodeIdentifier, pep, recipient=None): |
365 return self.dbpool.runInteraction(self._getAffiliations, entity, nodeIdentifier, pep, recipient) | |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
366 |
331 | 367 def _getAffiliations(self, cursor, entity, nodeIdentifier, pep, recipient=None): |
368 query = ["""SELECT node, affiliation FROM entities | |
369 NATURAL JOIN affiliations | |
370 NATURAL JOIN nodes | |
371 WHERE jid=%s"""] | |
372 args = [entity.userhost()] | |
373 | |
374 if nodeIdentifier is not None: | |
375 query.append("AND node=%s") | |
376 args.append(nodeIdentifier) | |
377 | |
378 cursor.execute(*withPEP(' '.join(query), args, pep, recipient)) | |
379 rows = cursor.fetchall() | |
380 return [tuple(r) for r in rows] | |
107 | 381 |
357
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
382 def getSubscriptions(self, entity, nodeIdentifier=None, pep=False, recipient=None): |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
383 """retrieve subscriptions of an entity |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
384 |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
385 @param entity(jid.JID): entity to check |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
386 @param nodeIdentifier(unicode, None): node identifier |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
387 None to retrieve all subscriptions |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
388 @param pep: True if we are in PEP mode |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
389 @param recipient: jid of the recipient |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
390 """ |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
391 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
392 def toSubscriptions(rows): |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
393 subscriptions = [] |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
394 for row in rows: |
357
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
395 subscriber = jid.internJID('%s/%s' % (row.jid, |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
396 row.resource)) |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
397 subscription = Subscription(row.node, subscriber, row.state) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
398 subscriptions.append(subscription) |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
399 return subscriptions |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
400 |
357
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
401 query = ["""SELECT node, |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
402 jid, |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
403 resource, |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
404 state |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
405 FROM entities |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
406 NATURAL JOIN subscriptions |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
407 NATURAL JOIN nodes |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
408 WHERE jid=%s"""] |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
409 |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
410 args = [entity.userhost()] |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
411 |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
412 if nodeIdentifier is not None: |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
413 query.append("AND node=%s") |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
414 args.append(nodeIdentifier) |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
415 |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
416 d = self.dbpool.runQuery(*withPEP(' '.join(query), args, pep, recipient)) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
417 d.addCallback(toSubscriptions) |
107 | 418 return d |
419 | |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
420 def getDefaultConfiguration(self, nodeType): |
366
81e6d4a516c3
storage (pgsql): getDefaultConfiguration now returns a shallow copy of default conf dict, to avoid modification.
Goffi <goffi@goffi.org>
parents:
365
diff
changeset
|
421 return self.defaultConfig[nodeType].copy() |
107 | 422 |
337
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
423 def formatLastItems(self, result): |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
424 last_items = [] |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
425 for pep_jid_s, node, data, item_access_model in result: |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
426 pep_jid = jid.JID(pep_jid_s) |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
427 item = generic.stripNamespace(parseXml(data)) |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
428 last_items.append((pep_jid, node, item, item_access_model)) |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
429 return last_items |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
430 |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
431 def getLastItems(self, entities, nodes, node_accesses, item_accesses, pep): |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
432 """get last item for several nodes and entities in a single request""" |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
433 if not entities or not nodes or not node_accesses or not item_accesses: |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
434 raise ValueError("entities, nodes and accesses must not be empty") |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
435 if node_accesses != ('open',) or item_accesses != ('open',): |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
436 raise NotImplementedError('only "open" access model is handled for now') |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
437 if not pep: |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
438 raise NotImplementedError(u"getLastItems is only implemented for PEP at the moment") |
351
2098295747fd
pgsql: cast items.data to text when needed + db schema version bump.
Goffi <goffi@goffi.org>
parents:
349
diff
changeset
|
439 d = self.dbpool.runQuery("""SELECT DISTINCT ON (node_id) pep, node, data::text, items.access_model |
337
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
440 FROM items |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
441 NATURAL JOIN nodes |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
442 WHERE nodes.pep IN %s |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
443 AND node IN %s |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
444 AND nodes.access_model in %s |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
445 AND items.access_model in %s |
374 | 446 ORDER BY node_id DESC, items.updated DESC""", |
337
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
447 (tuple([e.userhost() for e in entities]), |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
448 nodes, |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
449 node_accesses, |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
450 item_accesses)) |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
451 d.addCallback(self.formatLastItems) |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
452 return d |
57a3051ee435
storage (pgsql): added getLastItems method, to get last items from a series of nodes and entities (needed for PEP compliance).
Goffi <goffi@goffi.org>
parents:
332
diff
changeset
|
453 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
454 |
107 | 455 class Node: |
456 | |
167
ef22e4150caa
Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents:
163
diff
changeset
|
457 implements(iidavoll.INode) |
107 | 458 |
352 | 459 def __init__(self, nodeDbId, nodeIdentifier, config, schema): |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
460 self.nodeDbId = nodeDbId |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
461 self.nodeIdentifier = nodeIdentifier |
107 | 462 self._config = config |
352 | 463 self._schema = schema |
107 | 464 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
465 def _checkNodeExists(self, cursor): |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
466 cursor.execute("""SELECT 1 as exist FROM nodes WHERE node_id=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
467 (self.nodeDbId,)) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
468 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
|
469 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
|
470 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
471 def getType(self): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
472 return self.nodeType |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
473 |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
474 def getOwners(self): |
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
475 d = self.dbpool.runQuery("""SELECT jid FROM nodes NATURAL JOIN affiliations NATURAL JOIN entities WHERE node_id=%s and affiliation='owner'""", (self.nodeDbId,)) |
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
476 d.addCallback(lambda rows: [jid.JID(r[0]) for r in rows]) |
243
42048e37699e
added experimental roster access_model (use remote_roster)
Goffi <goffi@goffi.org>
parents:
240
diff
changeset
|
477 return d |
42048e37699e
added experimental roster access_model (use remote_roster)
Goffi <goffi@goffi.org>
parents:
240
diff
changeset
|
478 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
479 def getConfiguration(self): |
107 | 480 return self._config |
481 | |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
482 def getNextId(self): |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
483 """return XMPP item id usable for next item to publish |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
484 |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
485 the return value will be next int if serila_ids is set, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
486 else an UUID will be returned |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
487 """ |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
488 if self._config[const.OPT_SERIAL_IDS]: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
489 d = self.dbpool.runQuery("SELECT nextval('{seq_name}')".format( |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
490 seq_name = ITEMS_SEQ_NAME.format(node_id=self.nodeDbId))) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
491 d.addCallback(lambda rows: unicode(rows[0][0])) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
492 return d |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
493 else: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
494 return defer.succeed(unicode(uuid.uuid4())) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
495 |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
496 @staticmethod |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
497 def _configurationTriggers(cursor, node_id, old_config, new_config): |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
498 """trigger database relative actions needed when a config is changed |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
499 |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
500 @param cursor(): current db cursor |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
501 @param node_id(unicode): database ID of the node |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
502 @param old_config(dict): config of the node before the change |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
503 @param new_config(dict): new options that will be changed |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
504 """ |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
505 serial_ids = new_config[const.OPT_SERIAL_IDS] |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
506 if serial_ids != old_config[const.OPT_SERIAL_IDS]: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
507 # serial_ids option has been modified, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
508 # we need to handle corresponding sequence |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
509 |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
510 # XXX: we use .format in following queries because values |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
511 # are generated by ourself |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
512 seq_name = ITEMS_SEQ_NAME.format(node_id=node_id) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
513 if serial_ids: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
514 # the next query get the max value +1 of all XMPP items ids |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
515 # which are integers, and default to 1 |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
516 cursor.execute(NEXT_ITEM_ID_QUERY.format(node_id=node_id)) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
517 next_val = cursor.fetchone()[0] |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
518 cursor.execute("DROP SEQUENCE IF EXISTS {seq_name}".format(seq_name = seq_name)) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
519 cursor.execute("CREATE SEQUENCE {seq_name} START {next_val} OWNED BY nodes.node_id".format( |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
520 seq_name = seq_name, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
521 next_val = next_val)) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
522 else: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
523 cursor.execute("DROP SEQUENCE IF EXISTS {seq_name}".format(seq_name = seq_name)) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
524 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
525 def setConfiguration(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
|
526 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
|
527 |
107 | 528 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
|
529 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
|
530 config[option] = options[option] |
180
fc687620599b
Properly add send_last_published_item configuration item.
Ralph Meijer <ralphm@ik.nu>
parents:
173
diff
changeset
|
531 |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
532 d = self.dbpool.runInteraction(self._setConfiguration, config) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
533 d.addCallback(self._setCachedConfiguration, config) |
124
c4ee16bc48e5
Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents:
121
diff
changeset
|
534 return d |
c4ee16bc48e5
Change Node.set_configuration() to set cached configuration in a callback.
Ralph Meijer <ralphm@ik.nu>
parents:
121
diff
changeset
|
535 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
536 def _setConfiguration(self, cursor, config): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
537 self._checkNodeExists(cursor) |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
538 self._configurationTriggers(cursor, self.nodeDbId, self._config, config) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
539 cursor.execute("""UPDATE nodes SET persist_items=%s, |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
540 deliver_payloads=%s, |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
541 send_last_published_item=%s, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
542 access_model=%s, |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
543 publish_model=%s, |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
544 serial_ids=%s, |
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
545 consistent_publisher=%s |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
546 WHERE node_id=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
547 (config[const.OPT_PERSIST_ITEMS], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
548 config[const.OPT_DELIVER_PAYLOADS], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
549 config[const.OPT_SEND_LAST_PUBLISHED_ITEM], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
550 config[const.OPT_ACCESS_MODEL], |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
551 config[const.OPT_PUBLISH_MODEL], |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
552 config[const.OPT_SERIAL_IDS], |
403
1dc606612405
implemented experimental "consistent_publisher" option:
Goffi <goffi@goffi.org>
parents:
402
diff
changeset
|
553 config[const.OPT_CONSISTENT_PUBLISHER], |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
554 self.nodeDbId)) |
107 | 555 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
556 def _setCachedConfiguration(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
|
557 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
|
558 |
352 | 559 def getSchema(self): |
560 return self._schema | |
561 | |
562 def setSchema(self, schema): | |
563 d = self.dbpool.runInteraction(self._setSchema, schema) | |
564 d.addCallback(self._setCachedSchema, schema) | |
565 return d | |
566 | |
567 def _setSchema(self, cursor, schema): | |
568 self._checkNodeExists(cursor) | |
569 cursor.execute("""UPDATE nodes SET schema=%s | |
570 WHERE node_id=%s""", | |
571 (schema.toXml() if schema else None, | |
572 self.nodeDbId)) | |
573 | |
574 def _setCachedSchema(self, void, schema): | |
575 self._schema = schema | |
576 | |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
577 def getMetaData(self): |
107 | 578 config = copy.copy(self._config) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
579 config["pubsub#node_type"] = self.nodeType |
107 | 580 return config |
581 | |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
582 def getAffiliation(self, entity): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
583 return self.dbpool.runInteraction(self._getAffiliation, entity) |
107 | 584 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
585 def _getAffiliation(self, cursor, entity): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
586 self._checkNodeExists(cursor) |
107 | 587 cursor.execute("""SELECT affiliation FROM affiliations |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
588 NATURAL JOIN nodes |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
589 NATURAL JOIN entities |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
590 WHERE node_id=%s AND jid=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
591 (self.nodeDbId, |
136
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
592 entity.userhost())) |
107 | 593 |
594 try: | |
595 return cursor.fetchone()[0] | |
596 except TypeError: | |
597 return None | |
598 | |
240
70c8bb90d75f
added access_model to config, default to 'open'
Goffi <goffi@goffi.org>
parents:
235
diff
changeset
|
599 def getAccessModel(self): |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
600 return self._config[const.OPT_ACCESS_MODEL] |
240
70c8bb90d75f
added access_model to config, default to 'open'
Goffi <goffi@goffi.org>
parents:
235
diff
changeset
|
601 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
602 def getSubscription(self, subscriber): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
603 return self.dbpool.runInteraction(self._getSubscription, subscriber) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
604 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
605 def _getSubscription(self, cursor, subscriber): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
606 self._checkNodeExists(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
|
607 |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
608 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
|
609 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
|
610 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
611 cursor.execute("""SELECT state FROM subscriptions |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
612 NATURAL JOIN nodes |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
613 NATURAL JOIN entities |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
614 WHERE node_id=%s AND jid=%s AND resource=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
615 (self.nodeDbId, |
136
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
616 userhost, |
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
617 resource)) |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
618 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
619 row = cursor.fetchone() |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
620 if not row: |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
621 return None |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
622 else: |
227
8540825f85e0
Replaced unmaintained pyPgSQL by Psycopg 2
Goffi <goffi@goffi.org>
parents:
206
diff
changeset
|
623 return Subscription(self.nodeIdentifier, subscriber, row[0]) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
624 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
625 def getSubscriptions(self, state=None): |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
626 return self.dbpool.runInteraction(self._getSubscriptions, 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
|
627 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
628 def _getSubscriptions(self, cursor, state): |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
629 self._checkNodeExists(cursor) |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
630 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
631 query = """SELECT node, jid, resource, state, |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
632 subscription_type, subscription_depth |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
633 FROM subscriptions |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
634 NATURAL JOIN nodes |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
635 NATURAL JOIN entities |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
636 WHERE node_id=%s""" |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
637 values = [self.nodeDbId] |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
638 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
639 if state: |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
640 query += " AND state=%s" |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
641 values.append(state) |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
642 |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
643 cursor.execute(query, values) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
644 rows = cursor.fetchall() |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
645 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
646 subscriptions = [] |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
647 for row in rows: |
357
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
648 subscriber = jid.JID(u'%s/%s' % (row.jid, row.resource)) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
649 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
650 options = {} |
357
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
651 if row.subscription_type: |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
652 options['pubsub#subscription_type'] = row.subscription_type; |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
653 if row.subscription_depth: |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
654 options['pubsub#subscription_depth'] = row.subscription_depth; |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
655 |
357
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
656 subscriptions.append(Subscription(row.node, subscriber, |
1167e48e5f52
handle single node on subscriptions request
Goffi <goffi@goffi.org>
parents:
356
diff
changeset
|
657 row.state, options)) |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
658 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
659 return subscriptions |
107 | 660 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
661 def addSubscription(self, subscriber, state, config): |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
662 return self.dbpool.runInteraction(self._addSubscription, subscriber, |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
663 state, config) |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
664 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
665 def _addSubscription(self, cursor, subscriber, state, config): |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
666 self._checkNodeExists(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
|
667 |
107 | 668 userhost = subscriber.userhost() |
669 resource = subscriber.resource or '' | |
670 | |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
671 subscription_type = config.get('pubsub#subscription_type') |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
672 subscription_depth = config.get('pubsub#subscription_depth') |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
673 |
107 | 674 try: |
675 cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""", | |
227
8540825f85e0
Replaced unmaintained pyPgSQL by Psycopg 2
Goffi <goffi@goffi.org>
parents:
206
diff
changeset
|
676 (userhost,)) |
8540825f85e0
Replaced unmaintained pyPgSQL by Psycopg 2
Goffi <goffi@goffi.org>
parents:
206
diff
changeset
|
677 except cursor._pool.dbapi.IntegrityError: |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
678 cursor.connection.rollback() |
107 | 679 |
680 try: | |
681 cursor.execute("""INSERT INTO subscriptions | |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
682 (node_id, entity_id, resource, state, |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
683 subscription_type, subscription_depth) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
684 SELECT %s, entity_id, %s, %s, %s, %s FROM |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
685 (SELECT entity_id FROM entities |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
686 WHERE jid=%s) AS ent_id""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
687 (self.nodeDbId, |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
688 resource, |
136
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
689 state, |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
690 subscription_type, |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
691 subscription_depth, |
136
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
692 userhost)) |
227
8540825f85e0
Replaced unmaintained pyPgSQL by Psycopg 2
Goffi <goffi@goffi.org>
parents:
206
diff
changeset
|
693 except cursor._pool.dbapi.IntegrityError: |
167
ef22e4150caa
Move protocol implementations (pubsub, disco, forms) to and depend on wokkel.
Ralph Meijer <ralphm@ik.nu>
parents:
163
diff
changeset
|
694 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
|
695 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
696 def removeSubscription(self, subscriber): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
697 return self.dbpool.runInteraction(self._removeSubscription, |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
698 subscriber) |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
699 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
700 def _removeSubscription(self, cursor, subscriber): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
701 self._checkNodeExists(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
|
702 |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
703 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
|
704 resource = subscriber.resource or '' |
107 | 705 |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
706 cursor.execute("""DELETE FROM subscriptions WHERE |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
707 node_id=%s AND |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
708 entity_id=(SELECT entity_id FROM entities |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
709 WHERE jid=%s) AND |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
710 resource=%s""", |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
711 (self.nodeDbId, |
136
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
712 userhost, |
327de183f48d
Discover client_encoding parameter to pyPgSQL, removing all encode() calls.
Ralph Meijer <ralphm@ik.nu>
parents:
127
diff
changeset
|
713 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
|
714 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
|
715 raise error.NotSubscribed() |
107 | 716 |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
717 return None |
107 | 718 |
341
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
719 def setSubscriptions(self, subscriptions): |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
720 return self.dbpool.runInteraction(self._setSubscriptions, subscriptions) |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
721 |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
722 def _setSubscriptions(self, cursor, subscriptions): |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
723 self._checkNodeExists(cursor) |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
724 |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
725 entities = self.getOrCreateEntities(cursor, [s.subscriber for s in subscriptions]) |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
726 entities_map = {jid.JID(e.jid): e for e in entities} |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
727 |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
728 # then we construct values for subscriptions update according to entity_id we just got |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
729 placeholders = ','.join(len(subscriptions) * ["%s"]) |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
730 values = [] |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
731 for subscription in subscriptions: |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
732 entity_id = entities_map[subscription.subscriber].entity_id |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
733 resource = subscription.subscriber.resource or u'' |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
734 values.append((self.nodeDbId, entity_id, resource, subscription.state, None, None)) |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
735 # we use upsert so new values are inserted and existing one updated. This feature is only available for PostgreSQL >= 9.5 |
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
736 cursor.execute("INSERT INTO subscriptions(node_id, entity_id, resource, state, subscription_type, subscription_depth) VALUES " + placeholders + " ON CONFLICT (entity_id, resource, node_id) DO UPDATE SET state=EXCLUDED.state", [v for v in values]) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
737 |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
738 def isSubscribed(self, entity): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
739 return self.dbpool.runInteraction(self._isSubscribed, 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
|
740 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
741 def _isSubscribed(self, cursor, entity): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
742 self._checkNodeExists(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
|
743 |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
744 cursor.execute("""SELECT 1 as bool FROM entities |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
745 NATURAL JOIN subscriptions |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
746 NATURAL JOIN nodes |
146
b4490bdc77e5
Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents:
145
diff
changeset
|
747 WHERE entities.jid=%s |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
748 AND node_id=%s AND state='subscribed'""", |
146
b4490bdc77e5
Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents:
145
diff
changeset
|
749 (entity.userhost(), |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
750 self.nodeDbId)) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
751 |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
752 return cursor.fetchone() is not None |
107 | 753 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
754 def getAffiliations(self): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
755 return self.dbpool.runInteraction(self._getAffiliations) |
145
f393bccec4bc
Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents:
142
diff
changeset
|
756 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
757 def _getAffiliations(self, cursor): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
758 self._checkNodeExists(cursor) |
145
f393bccec4bc
Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents:
142
diff
changeset
|
759 |
f393bccec4bc
Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents:
142
diff
changeset
|
760 cursor.execute("""SELECT jid, affiliation FROM nodes |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
761 NATURAL JOIN affiliations |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
762 NATURAL JOIN entities |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
763 WHERE node_id=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
764 (self.nodeDbId,)) |
145
f393bccec4bc
Add get_affiliations to Node class in storage facilities in preparation of
Ralph Meijer <ralphm@ik.nu>
parents:
142
diff
changeset
|
765 result = cursor.fetchall() |
180
fc687620599b
Properly add send_last_published_item configuration item.
Ralph Meijer <ralphm@ik.nu>
parents:
173
diff
changeset
|
766 |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
767 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
|
768 |
331 | 769 def getOrCreateEntities(self, cursor, entities_jids): |
770 """Get entity_id from entities in entities table | |
771 | |
772 Entities will be inserted it they don't exist | |
773 @param entities_jid(list[jid.JID]): entities to get or create | |
341
b49f75a26156
backend, pgsql: implemented subscriptionsGet and subscriptionsSet
Goffi <goffi@goffi.org>
parents:
337
diff
changeset
|
774 @return list[record(entity_id,jid)]]: list of entity_id and jid (as plain string) |
331 | 775 both existing and inserted entities are returned |
776 """ | |
777 # cf. http://stackoverflow.com/a/35265559 | |
778 placeholders = ','.join(len(entities_jids) * ["(%s)"]) | |
779 query = ( | |
780 """ | |
781 WITH | |
782 jid_values (jid) AS ( | |
783 VALUES {placeholders} | |
784 ), | |
785 inserted (entity_id, jid) AS ( | |
786 INSERT INTO entities (jid) | |
787 SELECT jid | |
788 FROM jid_values | |
789 ON CONFLICT DO NOTHING | |
790 RETURNING entity_id, jid | |
791 ) | |
792 SELECT e.entity_id, e.jid | |
793 FROM entities e JOIN jid_values jv ON jv.jid = e.jid | |
794 UNION ALL | |
795 SELECT entity_id, jid | |
796 FROM inserted""".format(placeholders=placeholders)) | |
797 cursor.execute(query, [j.userhost() for j in entities_jids]) | |
798 return cursor.fetchall() | |
799 | |
800 def setAffiliations(self, affiliations): | |
801 return self.dbpool.runInteraction(self._setAffiliations, affiliations) | |
802 | |
803 def _setAffiliations(self, cursor, affiliations): | |
804 self._checkNodeExists(cursor) | |
805 | |
806 entities = self.getOrCreateEntities(cursor, affiliations) | |
807 | |
808 # then we construct values for affiliations update according to entity_id we just got | |
809 placeholders = ','.join(len(affiliations) * ["(%s,%s,%s)"]) | |
810 values = [] | |
811 map(values.extend, ((e.entity_id, affiliations[jid.JID(e.jid)], self.nodeDbId) for e in entities)) | |
812 | |
813 # we use upsert so new values are inserted and existing one updated. This feature is only available for PostgreSQL >= 9.5 | |
814 cursor.execute("INSERT INTO affiliations(entity_id,affiliation,node_id) VALUES " + placeholders + " ON CONFLICT (entity_id,node_id) DO UPDATE SET affiliation=EXCLUDED.affiliation", values) | |
815 | |
816 def deleteAffiliations(self, entities): | |
817 return self.dbpool.runInteraction(self._deleteAffiliations, entities) | |
818 | |
819 def _deleteAffiliations(self, cursor, entities): | |
820 """delete affiliations and subscriptions for this entity""" | |
821 self._checkNodeExists(cursor) | |
822 placeholders = ','.join(len(entities) * ["%s"]) | |
823 cursor.execute("DELETE FROM affiliations WHERE node_id=%s AND entity_id in (SELECT entity_id FROM entities WHERE jid IN (" + placeholders + ")) RETURNING entity_id", [self.nodeDbId] + [e.userhost() for e in entities]) | |
824 | |
825 rows = cursor.fetchall() | |
826 placeholders = ','.join(len(rows) * ["%s"]) | |
827 cursor.execute("DELETE FROM subscriptions WHERE node_id=%s AND entity_id in (" + placeholders + ")", [self.nodeDbId] + [r[0] for r in rows]) | |
828 | |
829 def getAuthorizedGroups(self): | |
830 return self.dbpool.runInteraction(self._getNodeGroups) | |
831 | |
832 def _getAuthorizedGroups(self, cursor): | |
833 cursor.execute("SELECT groupname FROM node_groups_authorized NATURAL JOIN nodes WHERE node=%s", | |
834 (self.nodeDbId,)) | |
835 rows = cursor.fetchall() | |
836 return [row[0] for row in rows] | |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
837 |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
838 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
839 class LeafNode(Node): |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
840 |
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
841 implements(iidavoll.ILeafNode) |
107 | 842 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
843 nodeType = 'leaf' |
107 | 844 |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
845 def getOrderBy(self, ext_data, direction='DESC'): |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
846 """Return ORDER BY clause corresponding to Order By key in ext_data |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
847 |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
848 @param ext_data (dict): extra data as used in getItems |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
849 @param direction (unicode): ORDER BY direction (ASC or DESC) |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
850 @return (unicode): ORDER BY clause to use |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
851 """ |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
852 keys = ext_data.get('order_by') |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
853 if not keys: |
378
22832c1d2827
storage (pgsql): don't specify table name in ORDER BY clause as it can cause troubles in some requests.
Goffi <goffi@goffi.org>
parents:
375
diff
changeset
|
854 return u'ORDER BY updated ' + direction |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
855 cols_statmnt = [] |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
856 for key in keys: |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
857 if key == 'creation': |
378
22832c1d2827
storage (pgsql): don't specify table name in ORDER BY clause as it can cause troubles in some requests.
Goffi <goffi@goffi.org>
parents:
375
diff
changeset
|
858 column = 'item_id' # could work with items.created too |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
859 elif key == 'modification': |
378
22832c1d2827
storage (pgsql): don't specify table name in ORDER BY clause as it can cause troubles in some requests.
Goffi <goffi@goffi.org>
parents:
375
diff
changeset
|
860 column = 'updated' |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
861 else: |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
862 log.msg(u"WARNING: Unknown order by key: {key}".format(key=key)) |
378
22832c1d2827
storage (pgsql): don't specify table name in ORDER BY clause as it can cause troubles in some requests.
Goffi <goffi@goffi.org>
parents:
375
diff
changeset
|
863 column = 'updated' |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
864 cols_statmnt.append(column + u' ' + direction) |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
865 |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
866 return u"ORDER BY " + u",".join([col for col in cols_statmnt]) |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
867 |
393
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
868 @defer.inlineCallbacks |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
869 def storeItems(self, items_data, publisher): |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
870 # XXX: runInteraction doesn't seem to work when there are several "insert" |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
871 # or "update". |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
872 # Before the unpacking was done in _storeItems, but this was causing trouble |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
873 # in case of multiple items_data. So this has now be moved here. |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
874 # FIXME: investigate the issue with runInteraction |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
875 for item_data in items_data: |
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
876 yield self.dbpool.runInteraction(self._storeItems, item_data, 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
|
877 |
393
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
878 def _storeItems(self, cursor, item_data, publisher): |
250 | 879 self._checkNodeExists(cursor) |
393
728b08c0d000
storage (pgsql): fixed storage of multiple items
Goffi <goffi@goffi.org>
parents:
390
diff
changeset
|
880 self._storeItem(cursor, item_data, publisher) |
244 | 881 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
882 def _storeItem(self, cursor, item_data, publisher): |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
883 # first try to insert the item |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
884 # - if it fails (conflict), and the item is new and we have serial_ids options, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
885 # current id will be recomputed using next item id query (note that is not perfect, as |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
886 # table is not locked and this can fail if two items are added at the same time |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
887 # but this can only happen with serial_ids and if future ids have been set by a client, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
888 # this case should be rare enough to consider this situation acceptable) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
889 # - if item insertion fail and the item is not new, we do an update |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
890 # - in other cases, exception is raised |
301
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
891 item, access_model, item_config = item_data.item, item_data.access_model, item_data.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
|
892 data = item.toXml() |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
893 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
894 insert_query = """INSERT INTO items (node_id, item, publisher, data, access_model) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
895 SELECT %s, %s, %s, %s, %s FROM nodes |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
896 WHERE node_id=%s |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
897 RETURNING item_id""" |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
898 insert_data = [self.nodeDbId, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
899 item["id"], |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
900 publisher.full(), |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
901 data, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
902 access_model, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
903 self.nodeDbId] |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
904 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
905 try: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
906 cursor.execute(insert_query, insert_data) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
907 except cursor._pool.dbapi.IntegrityError as e: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
908 if e.pgcode != "23505": |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
909 # we only handle unique_violation, every other exception must be raised |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
910 raise e |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
911 cursor.connection.rollback() |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
912 # the item already exist |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
913 if item_data.new: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
914 # the item is new |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
915 if self._config[const.OPT_SERIAL_IDS]: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
916 # this can happen with serial_ids, if a item has been stored |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
917 # with a future id (generated by XMPP client) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
918 cursor.execute(NEXT_ITEM_ID_QUERY.format(node_id=self.nodeDbId)) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
919 next_id = cursor.fetchone()[0] |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
920 # we update the sequence, so we can skip conflicting ids |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
921 cursor.execute(u"SELECT setval('{seq_name}', %s)".format( |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
922 seq_name = ITEMS_SEQ_NAME.format(node_id=self.nodeDbId)), [next_id]) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
923 # and now we can retry the query with the new id |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
924 item['id'] = insert_data[1] = unicode(next_id) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
925 # item saved in DB must also be updated with the new id |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
926 insert_data[3] = item.toXml() |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
927 cursor.execute(insert_query, insert_data) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
928 else: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
929 # but if we have not serial_ids, we have a real problem |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
930 raise e |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
931 else: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
932 # this is an update |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
933 cursor.execute("""UPDATE items SET updated=now(), publisher=%s, data=%s |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
934 FROM nodes |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
935 WHERE nodes.node_id = items.node_id AND |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
936 nodes.node_id = %s and items.item=%s |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
937 RETURNING item_id""", |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
938 (publisher.full(), |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
939 data, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
940 self.nodeDbId, |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
941 item["id"])) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
942 if cursor.rowcount != 1: |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
943 raise exceptions.InternalError("item has not been updated correctly") |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
944 item_id = cursor.fetchone()[0]; |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
945 self._storeCategories(cursor, item_id, item_data.categories, update=True) |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
946 return |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
947 |
301
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
948 item_id = cursor.fetchone()[0]; |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
949 self._storeCategories(cursor, item_id, item_data.categories) |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
950 |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
951 if access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: |
250 | 952 if const.OPT_ROSTER_GROUPS_ALLOWED in item_config: |
953 item_config.fields[const.OPT_ROSTER_GROUPS_ALLOWED].fieldType='list-multi' #XXX: needed to force list if there is only one value | |
954 allowed_groups = item_config[const.OPT_ROSTER_GROUPS_ALLOWED] | |
245
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
955 else: |
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
956 allowed_groups = [] |
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
957 for group in allowed_groups: |
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
958 #TODO: check that group are actually in roster |
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
959 cursor.execute("""INSERT INTO item_groups_authorized (item_id, groupname) |
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
960 VALUES (%s,%s)""" , (item_id, group)) |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
961 # TODO: whitelist access model |
245
e11e99246be5
allowed groups from item_config are now stored
Goffi <goffi@goffi.org>
parents:
244
diff
changeset
|
962 |
301
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
963 def _storeCategories(self, cursor, item_id, categories, update=False): |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
964 # TODO: handle canonical form |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
965 if update: |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
966 cursor.execute("""DELETE FROM item_categories |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
967 WHERE item_id=%s""", (item_id,)) |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
968 |
402
724e39d596a9
psql: use a set for categories, to avoid duplicates (and constraint failure)
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
969 # we use a set to avoid duplicates |
724e39d596a9
psql: use a set for categories, to avoid duplicates (and constraint failure)
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
970 for category in set(categories): |
301
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
971 cursor.execute("""INSERT INTO item_categories (item_id, category) |
05c875a13a62
categories are now stored in a dedicated table if item contain an atom entry:
Goffi <goffi@goffi.org>
parents:
297
diff
changeset
|
972 VALUES (%s, %s)""", (item_id, category)) |
107 | 973 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
974 def removeItems(self, itemIdentifiers): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
975 return self.dbpool.runInteraction(self._removeItems, itemIdentifiers) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
976 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
977 def _removeItems(self, cursor, itemIdentifiers): |
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
978 self._checkNodeExists(cursor) |
180
fc687620599b
Properly add send_last_published_item configuration item.
Ralph Meijer <ralphm@ik.nu>
parents:
173
diff
changeset
|
979 |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
980 deleted = [] |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
981 |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
982 for itemIdentifier in itemIdentifiers: |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
983 cursor.execute("""DELETE FROM items WHERE |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
984 node_id=%s AND |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
985 item=%s""", |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
986 (self.nodeDbId, |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
987 itemIdentifier)) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
988 |
142
812300cdbc22
Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents:
136
diff
changeset
|
989 if cursor.rowcount: |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
990 deleted.append(itemIdentifier) |
142
812300cdbc22
Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents:
136
diff
changeset
|
991 |
812300cdbc22
Changed behaviour of retraction of items so that only the actually deleted
Ralph Meijer <ralphm@ik.nu>
parents:
136
diff
changeset
|
992 return deleted |
107 | 993 |
278 | 994 def getItems(self, authorized_groups, unrestricted, maxItems=None, ext_data=None): |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
995 """ Get all authorised items |
346 | 996 |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
997 @param authorized_groups: we want to get items that these groups can access |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
998 @param unrestricted: if true, don't check permissions (i.e.: get all items) |
318 | 999 @param maxItems: nb of items we want to get |
1000 @param ext_data: options for extra features like RSM and MAM | |
278 | 1001 |
317
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1002 @return: list of container.ItemData |
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1003 if unrestricted is False, access_model and config will be None |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1004 """ |
278 | 1005 if ext_data is None: |
1006 ext_data = {} | |
347 | 1007 return self.dbpool.runInteraction(self._getItems, authorized_groups, unrestricted, maxItems, ext_data, ids_only=False) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
1008 |
346 | 1009 def getItemsIds(self, authorized_groups, unrestricted, maxItems=None, ext_data=None): |
1010 """ Get all authorised items ids | |
1011 | |
1012 @param authorized_groups: we want to get items that these groups can access | |
1013 @param unrestricted: if true, don't check permissions (i.e.: get all items) | |
1014 @param maxItems: nb of items we want to get | |
1015 @param ext_data: options for extra features like RSM and MAM | |
1016 | |
1017 @return list(unicode): list of ids | |
1018 """ | |
1019 if ext_data is None: | |
1020 ext_data = {} | |
1021 return self.dbpool.runInteraction(self._getItems, authorized_groups, unrestricted, maxItems, ext_data, ids_only=True) | |
1022 | |
318 | 1023 def _appendSourcesAndFilters(self, query, args, authorized_groups, unrestricted, ext_data): |
1024 """append sources and filters to sql query requesting items and return ORDER BY | |
278 | 1025 |
318 | 1026 arguments query, args, authorized_groups, unrestricted and ext_data are the same as for |
1027 _getItems | |
1028 """ | |
1029 # SOURCES | |
323 | 1030 query.append("FROM nodes INNER JOIN items USING (node_id)") |
1031 | |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1032 if unrestricted: |
323 | 1033 query_filters = ["WHERE node_id=%s"] |
318 | 1034 args.append(self.nodeDbId) |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1035 else: |
323 | 1036 query.append("LEFT JOIN item_groups_authorized USING (item_id)") |
318 | 1037 args.append(self.nodeDbId) |
1038 if authorized_groups: | |
1039 get_groups = " or (items.access_model='roster' and groupname in %s)" | |
1040 args.append(authorized_groups) | |
1041 else: | |
1042 get_groups = "" | |
278 | 1043 |
323 | 1044 query_filters = ["WHERE node_id=%s AND (items.access_model='open'" + get_groups + ")"] |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1045 |
318 | 1046 # FILTERS |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
278
diff
changeset
|
1047 if 'filters' in ext_data: # MAM filters |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
278
diff
changeset
|
1048 for filter_ in ext_data['filters']: |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
278
diff
changeset
|
1049 if filter_.var == 'start': |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1050 query_filters.append("AND created>=%s") |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1051 args.append(filter_.value) |
323 | 1052 elif filter_.var == 'end': |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1053 query_filters.append("AND created<=%s") |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1054 args.append(filter_.value) |
323 | 1055 elif filter_.var == 'with': |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
278
diff
changeset
|
1056 jid_s = filter_.value |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
278
diff
changeset
|
1057 if '/' in jid_s: |
323 | 1058 query_filters.append("AND publisher=%s") |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1059 args.append(filter_.value) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1060 else: |
323 | 1061 query_filters.append("AND publisher LIKE %s") |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1062 args.append(u"{}%".format(filter_.value)) |
323 | 1063 elif filter_.var == const.MAM_FILTER_CATEGORY: |
1064 query.append("LEFT JOIN item_categories USING (item_id)") | |
1065 query_filters.append("AND category=%s") | |
1066 args.append(filter_.value) | |
1067 else: | |
1068 log.msg("WARNING: unknown filter: {}".format(filter_.encode('utf-8'))) | |
1069 | |
1070 query.extend(query_filters) | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
278
diff
changeset
|
1071 |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
1072 return self.getOrderBy(ext_data) |
318 | 1073 |
346 | 1074 def _getItems(self, cursor, authorized_groups, unrestricted, maxItems, ext_data, ids_only): |
318 | 1075 self._checkNodeExists(cursor) |
1076 | |
1077 if maxItems == 0: | |
1078 return [] | |
1079 | |
1080 args = [] | |
1081 | |
1082 # SELECT | |
346 | 1083 if ids_only: |
1084 query = ["SELECT item"] | |
1085 else: | |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1086 query = ["SELECT data::text,items.access_model,item_id,created,updated"] |
318 | 1087 |
1088 query_order = self._appendSourcesAndFilters(query, args, authorized_groups, unrestricted, ext_data) | |
278 | 1089 |
1090 if 'rsm' in ext_data: | |
1091 rsm = ext_data['rsm'] | |
1092 maxItems = rsm.max | |
1093 if rsm.index is not None: | |
319
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1094 # We need to know the item_id of corresponding to the index (offset) of the current query |
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1095 # so we execute the query to look for the item_id |
318 | 1096 tmp_query = query[:] |
1097 tmp_args = args[:] | |
319
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1098 tmp_query[0] = "SELECT item_id" |
318 | 1099 tmp_query.append("{} LIMIT 1 OFFSET %s".format(query_order)) |
1100 tmp_args.append(rsm.index) | |
1101 cursor.execute(' '.join(query), args) | |
1102 # FIXME: bad index is not managed yet | |
319
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1103 item_id = cursor.fetchall()[0][0] |
318 | 1104 |
319
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1105 # now that we have the id, we can use it |
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1106 query.append("AND item_id<=%s") |
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1107 args.append(item_id) |
278 | 1108 elif rsm.before is not None: |
1109 if rsm.before != '': | |
319
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1110 query.append("AND item_id>(SELECT item_id FROM items WHERE item=%s LIMIT 1)") |
278 | 1111 args.append(rsm.before) |
318 | 1112 if maxItems is not None: |
1113 # if we have maxItems (i.e. a limit), we need to reverse order | |
1114 # in a first query to get the right items | |
1115 query.insert(0,"SELECT * from (") | |
375
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
1116 query.append(self.getOrderBy(ext_data, direction='ASC')) |
9a787881b824
implemented Order-By ProtoXEP (MAM + PubSub)
Goffi <goffi@goffi.org>
parents:
374
diff
changeset
|
1117 query.append("LIMIT %s) as x") |
318 | 1118 args.append(maxItems) |
278 | 1119 elif rsm.after: |
319
a51947371625
pgsql storage: use item_id instead of date to order and select items
Goffi <goffi@goffi.org>
parents:
318
diff
changeset
|
1120 query.append("AND item_id<(SELECT item_id FROM items WHERE item=%s LIMIT 1)") |
278 | 1121 args.append(rsm.after) |
1122 | |
318 | 1123 query.append(query_order) |
278 | 1124 |
297
4115999d85e9
fixes behavior when maxItems is 0
souliane <souliane@mailoo.org>
parents:
294
diff
changeset
|
1125 if maxItems is not None: |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1126 query.append("LIMIT %s") |
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1127 args.append(maxItems) |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
1128 |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1129 cursor.execute(' '.join(query), args) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
1130 |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
1131 result = cursor.fetchall() |
346 | 1132 if unrestricted and not ids_only: |
318 | 1133 # with unrestricted query, we need to fill the access_list for a roster access items |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1134 ret = [] |
356
95c83899b5e9
pgsql: fixed bad data filling in getItemsData:
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
1135 for item_data in result: |
95c83899b5e9
pgsql: fixed bad data filling in getItemsData:
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
1136 item = generic.stripNamespace(parseXml(item_data.data)) |
95c83899b5e9
pgsql: fixed bad data filling in getItemsData:
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
1137 access_model = item_data.access_model |
95c83899b5e9
pgsql: fixed bad data filling in getItemsData:
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
1138 item_id = item_data.item_id |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1139 created = item_data.created |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1140 updated = item_data.updated |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1141 access_list = {} |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
1142 if access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1143 cursor.execute('SELECT groupname FROM item_groups_authorized WHERE item_id=%s', (item_id,)) |
356
95c83899b5e9
pgsql: fixed bad data filling in getItemsData:
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
1144 access_list[const.OPT_ROSTER_GROUPS_ALLOWED] = [r.groupname for r in cursor.fetchall()] |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1145 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1146 ret.append(container.ItemData(item, access_model, access_list, created=created, updated=updated)) |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
1147 # TODO: whitelist item access model |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1148 return ret |
318 | 1149 |
346 | 1150 if ids_only: |
356
95c83899b5e9
pgsql: fixed bad data filling in getItemsData:
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
1151 return [r.item for r in result] |
346 | 1152 else: |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1153 items_data = [container.ItemData(generic.stripNamespace(parseXml(r.data)), r.access_model, created=r.created, updated=r.updated) for r in result] |
317
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1154 return items_data |
107 | 1155 |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1156 def getItemsById(self, authorized_groups, unrestricted, itemIdentifiers): |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
1157 """Get items which are in the given list |
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
1158 |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1159 @param authorized_groups: we want to get items that these groups can access |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1160 @param unrestricted: if true, don't check permissions |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1161 @param itemIdentifiers: list of ids of the items we want to get |
317
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1162 @return: list of container.ItemData |
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1163 ItemData.config will contains access_list (managed as a dictionnary with same key as for item_config) |
34adc4a8aa64
new container module, with an ItemData container:
Goffi <goffi@goffi.org>
parents:
312
diff
changeset
|
1164 if unrestricted is False, access_model and config will be None |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1165 """ |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1166 return self.dbpool.runInteraction(self._getItemsById, authorized_groups, unrestricted, itemIdentifiers) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
1167 |
248
50f6ee966da8
item are gotten according to item's access model in getItems
Goffi <goffi@goffi.org>
parents:
247
diff
changeset
|
1168 def _getItemsById(self, cursor, authorized_groups, unrestricted, itemIdentifiers): |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
1169 self._checkNodeExists(cursor) |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1170 ret = [] |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1171 if unrestricted: #we get everything without checking permissions |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1172 for itemIdentifier in itemIdentifiers: |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1173 cursor.execute("""SELECT data::text,items.access_model,item_id,created,updated FROM nodes |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1174 INNER JOIN items USING (node_id) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1175 WHERE node_id=%s AND item=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1176 (self.nodeDbId, |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1177 itemIdentifier)) |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1178 result = cursor.fetchone() |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1179 if not result: |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1180 raise error.ItemNotFound() |
107 | 1181 |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1182 item = generic.stripNamespace(parseXml(result[0])) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1183 access_model = result[1] |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1184 item_id = result[2] |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1185 created= result[3] |
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1186 updated= result[4] |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1187 access_list = {} |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
1188 if access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1189 cursor.execute('SELECT groupname FROM item_groups_authorized WHERE item_id=%s', (item_id,)) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1190 access_list[const.OPT_ROSTER_GROUPS_ALLOWED] = [r[0] for r in cursor.fetchall()] |
330
82d1259b3e36
backend, pgsql storage: better items/notification handling, various fixes:
Goffi <goffi@goffi.org>
parents:
324
diff
changeset
|
1191 #TODO: WHITELIST access_model |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1192 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1193 ret.append(container.ItemData(item, access_model, access_list, created=created, updated=updated)) |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1194 else: #we check permission before returning items |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1195 for itemIdentifier in itemIdentifiers: |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1196 args = [self.nodeDbId, itemIdentifier] |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1197 if authorized_groups: |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1198 args.append(authorized_groups) |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1199 cursor.execute("""SELECT data::text, created, updated FROM nodes |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1200 INNER JOIN items USING (node_id) |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1201 LEFT JOIN item_groups_authorized USING (item_id) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1202 WHERE node_id=%s AND item=%s AND |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
1203 (items.access_model='open' """ + |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1204 ("or (items.access_model='roster' and groupname in %s)" if authorized_groups else '') + ")", |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1205 args) |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1206 |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1207 result = cursor.fetchone() |
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1208 if result: |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
366
diff
changeset
|
1209 ret.append(container.ItemData(generic.stripNamespace(parseXml(result[0])), created=result[1], updated=result[2])) |
262
7b821432d012
fixed node auto-create feature
souliane <souliane@mailoo.org>
parents:
260
diff
changeset
|
1210 |
252
25a1dc7181cc
full items, with item-configuration, are returned if items are asked by the owner
Goffi <goffi@goffi.org>
parents:
250
diff
changeset
|
1211 return ret |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
1212 |
318 | 1213 def getItemsCount(self, authorized_groups, unrestricted, ext_data=None): |
1214 """Count expected number of items in a getItems query | |
1215 | |
1216 @param authorized_groups: we want to get items that these groups can access | |
1217 @param unrestricted: if true, don't check permissions (i.e.: get all items) | |
1218 @param ext_data: options for extra features like RSM and MAM | |
1219 """ | |
1220 if ext_data is None: | |
1221 ext_data = {} | |
1222 return self.dbpool.runInteraction(self._getItemsCount, authorized_groups, unrestricted, ext_data) | |
1223 | |
1224 def _getItemsCount(self, cursor, authorized_groups, unrestricted, ext_data): | |
1225 self._checkNodeExists(cursor) | |
1226 args = [] | |
1227 | |
1228 # SELECT | |
1229 query = ["SELECT count(1)"] | |
1230 | |
1231 self._appendSourcesAndFilters(query, args, authorized_groups, unrestricted, ext_data) | |
1232 | |
1233 cursor.execute(' '.join(query), args) | |
1234 return cursor.fetchall()[0][0] | |
1235 | |
1236 def getItemsIndex(self, item_id, authorized_groups, unrestricted, ext_data=None): | |
1237 """Get expected index of first item in the window of a getItems query | |
1238 | |
1239 @param item_id: id of the item | |
1240 @param authorized_groups: we want to get items that these groups can access | |
1241 @param unrestricted: if true, don't check permissions (i.e.: get all items) | |
1242 @param ext_data: options for extra features like RSM and MAM | |
1243 """ | |
1244 if ext_data is None: | |
1245 ext_data = {} | |
1246 return self.dbpool.runInteraction(self._getItemsIndex, item_id, authorized_groups, unrestricted, ext_data) | |
1247 | |
1248 def _getItemsIndex(self, cursor, item_id, authorized_groups, unrestricted, ext_data): | |
1249 self._checkNodeExists(cursor) | |
1250 args = [] | |
1251 | |
1252 # SELECT | |
1253 query = [] | |
1254 | |
1255 query_order = self._appendSourcesAndFilters(query, args, authorized_groups, unrestricted, ext_data) | |
1256 | |
1257 query_select = "SELECT row_number from (SELECT row_number() OVER ({}), item".format(query_order) | |
1258 query.insert(0, query_select) | |
1259 query.append(") as x WHERE item=%s") | |
1260 args.append(item_id) | |
1261 | |
1262 cursor.execute(' '.join(query), args) | |
1263 # XXX: row_number start at 1, but we want that index start at 0 | |
324
e73e42b4f6ff
pgsql storage: getItemsIndex raise NodeNotFound in this make sense
Goffi <goffi@goffi.org>
parents:
323
diff
changeset
|
1264 try: |
e73e42b4f6ff
pgsql storage: getItemsIndex raise NodeNotFound in this make sense
Goffi <goffi@goffi.org>
parents:
323
diff
changeset
|
1265 return cursor.fetchall()[0][0] - 1 |
e73e42b4f6ff
pgsql storage: getItemsIndex raise NodeNotFound in this make sense
Goffi <goffi@goffi.org>
parents:
323
diff
changeset
|
1266 except IndexError: |
e73e42b4f6ff
pgsql storage: getItemsIndex raise NodeNotFound in this make sense
Goffi <goffi@goffi.org>
parents:
323
diff
changeset
|
1267 raise error.NodeNotFound() |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1268 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1269 def getItemsPublishers(self, itemIdentifiers): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1270 """Get the publishers for all given identifiers |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1271 |
308
087b705493a6
fixed publisher check on item publishing
Goffi <goffi@goffi.org>
parents:
301
diff
changeset
|
1272 @return (dict[unicode, jid.JID]): map of itemIdentifiers to publisher |
087b705493a6
fixed publisher check on item publishing
Goffi <goffi@goffi.org>
parents:
301
diff
changeset
|
1273 if item is not found, key is skipped in resulting dict |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1274 """ |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1275 return self.dbpool.runInteraction(self._getItemsPublishers, itemIdentifiers) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1276 |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1277 def _getItemsPublishers(self, cursor, itemIdentifiers): |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1278 self._checkNodeExists(cursor) |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1279 ret = {} |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1280 for itemIdentifier in itemIdentifiers: |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1281 cursor.execute("""SELECT publisher FROM items |
390
fba96e95e329
storage (pgsql): fixed filtering in getItemsPublishers
Goffi <goffi@goffi.org>
parents:
384
diff
changeset
|
1282 WHERE node_id=%s AND item=%s""", |
fba96e95e329
storage (pgsql): fixed filtering in getItemsPublishers
Goffi <goffi@goffi.org>
parents:
384
diff
changeset
|
1283 (self.nodeDbId, itemIdentifier,)) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1284 result = cursor.fetchone() |
308
087b705493a6
fixed publisher check on item publishing
Goffi <goffi@goffi.org>
parents:
301
diff
changeset
|
1285 if result: |
087b705493a6
fixed publisher check on item publishing
Goffi <goffi@goffi.org>
parents:
301
diff
changeset
|
1286 ret[itemIdentifier] = jid.JID(result[0]) |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1287 return ret |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1288 |
107 | 1289 def purge(self): |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1290 return self.dbpool.runInteraction(self._purge) |
121
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
1291 |
127
d3689da18ed2
Don't use encode('utf-8') on serialized XML.
Ralph Meijer <ralphm@ik.nu>
parents:
124
diff
changeset
|
1292 def _purge(self, cursor): |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
1293 self._checkNodeExists(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
|
1294 |
4f0113adb7ed
Add Node._check_node_exists() calls to all Node methods, because nodes could
Ralph Meijer <ralphm@ik.nu>
parents:
113
diff
changeset
|
1295 cursor.execute("""DELETE FROM items WHERE |
294
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1296 node_id=%s""", |
df1edebb0466
PEP implementation, draft (huge patch sorry):
Goffi <goffi@goffi.org>
parents:
283
diff
changeset
|
1297 (self.nodeDbId,)) |
198
e404775b12df
Change naming and spacing conventions to match Twisted's.
Ralph Meijer <ralphm@ik.nu>
parents:
181
diff
changeset
|
1298 |
263
9dfd3890e646
added the constant FLAG_RETRACT_ALLOW_PUBLISHER to allow a publisher to retract an item he has published in a node of "open" publish model.
souliane <souliane@mailoo.org>
parents:
262
diff
changeset
|
1299 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
1300 class CollectionNode(Node): |
146
b4490bdc77e5
Change semantics of Node.is_subscribed() to match all subscriptions for an
Ralph Meijer <ralphm@ik.nu>
parents:
145
diff
changeset
|
1301 |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
1302 nodeType = 'collection' |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1303 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1304 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1305 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1306 class GatewayStorage(object): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1307 """ |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1308 Memory based storage facility for the XMPP-HTTP gateway. |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1309 """ |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1310 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1311 def __init__(self, dbpool): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1312 self.dbpool = dbpool |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1313 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1314 def _countCallbacks(self, cursor, service, nodeIdentifier): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1315 """ |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1316 Count number of callbacks registered for a node. |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1317 """ |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1318 cursor.execute("""SELECT count(*) FROM callbacks |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1319 WHERE service=%s and node=%s""", |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1320 (service.full(), |
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1321 nodeIdentifier)) |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1322 results = cursor.fetchall() |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1323 return results[0][0] |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1324 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1325 def addCallback(self, service, nodeIdentifier, callback): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1326 def interaction(cursor): |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1327 cursor.execute("""SELECT 1 as bool FROM callbacks |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1328 WHERE service=%s and node=%s and uri=%s""", |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1329 (service.full(), |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1330 nodeIdentifier, |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1331 callback)) |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1332 if cursor.fetchall(): |
206
274a45d2a5ab
Implement root collection that includes all leaf nodes.
Ralph Meijer <ralphm@ik.nu>
parents:
204
diff
changeset
|
1333 return |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1334 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1335 cursor.execute("""INSERT INTO callbacks |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1336 (service, node, uri) VALUES |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1337 (%s, %s, %s)""", |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1338 (service.full(), |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1339 nodeIdentifier, |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1340 callback)) |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1341 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1342 return self.dbpool.runInteraction(interaction) |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1343 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1344 def removeCallback(self, service, nodeIdentifier, callback): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1345 def interaction(cursor): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1346 cursor.execute("""DELETE FROM callbacks |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1347 WHERE service=%s and node=%s and uri=%s""", |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1348 (service.full(), |
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1349 nodeIdentifier, |
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1350 callback)) |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1351 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1352 if cursor.rowcount != 1: |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1353 raise error.NotSubscribed() |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1354 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1355 last = not self._countCallbacks(cursor, service, nodeIdentifier) |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1356 return last |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1357 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1358 return self.dbpool.runInteraction(interaction) |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1359 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1360 def getCallbacks(self, service, nodeIdentifier): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1361 def interaction(cursor): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1362 cursor.execute("""SELECT uri FROM callbacks |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1363 WHERE service=%s and node=%s""", |
276
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1364 (service.full(), |
b757c29b20d7
import changes from idavoll changeset 233 (24be3a11ddbc), by Ralph Meijer and based on a patch by Nuno Santos
souliane <souliane@mailoo.org>
parents:
271
diff
changeset
|
1365 nodeIdentifier)) |
204
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1366 results = cursor.fetchall() |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1367 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1368 if not results: |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1369 raise error.NoCallbacks() |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1370 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1371 return [result[0] for result in results] |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1372 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1373 return self.dbpool.runInteraction(interaction) |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1374 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1375 def hasCallbacks(self, service, nodeIdentifier): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1376 def interaction(cursor): |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1377 return bool(self._countCallbacks(cursor, service, nodeIdentifier)) |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1378 |
b4bf0a5ce50d
Implement storage facilities for the HTTP gateway.
Ralph Meijer <ralphm@ik.nu>
parents:
202
diff
changeset
|
1379 return self.dbpool.runInteraction(interaction) |