Mercurial > libervia-pubsub
comparison sat_pubsub/backend.py @ 367:a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
/!\ this patch updates pgqsl schema /!\
Had to set 2 features in the same patch, to avoid updating 2 times the schema.
1) creation/last modification date:
column keeping the date of creation of items is renamed from "date" to "created"
the date of last modification of items is saved in the new "updated" column
2) serial ids:
this experimental feature allows to have ids in series (i.e. 1, 2, 3, etc.) instead of UUID.
This is a convenience feature and there are some drawbacks:
- PostgreSQL sequences are used, so gaps can happen (see PostgreSQL documentation for more details)
- if somebody create an item with a future id in the series, the series will adapt, which can have undesired effect, and may lead to item fail if several items are created at the same time. For instance if next id in series is "8", and somebody hads already created item "8" and "256", the item will be created with biggest value in items +1 (i.e. 257). if 2 people want to create item in this situation, the second will fail with a conflict error.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 04 Nov 2017 21:31:32 +0100 |
parents | 9fbb31ce495b |
children | 618a92080812 |
comparison
equal
deleted
inserted
replaced
366:81e6d4a516c3 | 367:a772f7dac930 |
---|---|
140 const.VAL_PMODEL_OPEN: "Everybody can publish", | 140 const.VAL_PMODEL_OPEN: "Everybody can publish", |
141 const.VAL_PMODEL_PUBLISHERS: "Only owner and publishers can publish", | 141 const.VAL_PMODEL_PUBLISHERS: "Only owner and publishers can publish", |
142 const.VAL_PMODEL_SUBSCRIBERS: "Everybody which subscribed to the node", | 142 const.VAL_PMODEL_SUBSCRIBERS: "Everybody which subscribed to the node", |
143 } | 143 } |
144 }, | 144 }, |
145 const.OPT_SERIAL_IDS: | |
146 {"type": "boolean", | |
147 "label": "Use serial ids"}, | |
145 } | 148 } |
146 | 149 |
147 subscriptionOptions = { | 150 subscriptionOptions = { |
148 "pubsub#subscription_type": | 151 "pubsub#subscription_type": |
149 {"type": "list-single", | 152 {"type": "list-single", |
356 #FIXME: owner and publisher are not necessarly the same. So far we use only owner to get roster. | 359 #FIXME: owner and publisher are not necessarly the same. So far we use only owner to get roster. |
357 #FIXME: in addition, there can be several owners: that is not managed yet | 360 #FIXME: in addition, there can be several owners: that is not managed yet |
358 d.addCallback(self._doPublish, items, requestor, pep, recipient) | 361 d.addCallback(self._doPublish, items, requestor, pep, recipient) |
359 return d | 362 return d |
360 | 363 |
364 @defer.inlineCallbacks | |
361 def _doPublish(self, result, items, requestor, pep, recipient): | 365 def _doPublish(self, result, items, requestor, pep, recipient): |
362 affiliation, node = result | 366 affiliation, node = result |
363 if node.nodeType == 'collection': | 367 if node.nodeType == 'collection': |
364 raise error.NoPublishing() | 368 raise error.NoPublishing() |
365 | 369 |
379 item['publisher'] = requestor.full() | 383 item['publisher'] = requestor.full() |
380 if persistItems or deliverPayloads: | 384 if persistItems or deliverPayloads: |
381 item.uri = None | 385 item.uri = None |
382 item.defaultUri = None | 386 item.defaultUri = None |
383 if not item.getAttribute("id"): | 387 if not item.getAttribute("id"): |
384 item["id"] = str(uuid.uuid4()) | 388 item["id"] = yield node.getNextId() |
389 new_item = True | |
385 else: | 390 else: |
386 check_overwrite = True | 391 check_overwrite = True |
392 new_item = False | |
387 access_model, item_config = self.parseItemConfig(item) | 393 access_model, item_config = self.parseItemConfig(item) |
388 categories = self.parseCategories(item) | 394 categories = self.parseCategories(item) |
389 schema = node.getSchema() | 395 schema = node.getSchema() |
390 if schema is not None: | 396 if schema is not None: |
391 self.enforceSchema(item, schema, affiliation) | 397 self.enforceSchema(item, schema, affiliation) |
392 items_data.append(container.ItemData(item, access_model, item_config, categories)) | 398 items_data.append(container.ItemData(item, access_model, item_config, categories, new=new_item)) |
393 | 399 |
394 if persistItems: | 400 if persistItems: |
401 | |
395 if check_overwrite and affiliation != 'owner': | 402 if check_overwrite and affiliation != 'owner': |
396 # we don't want a publisher to overwrite the item | 403 # we don't want a publisher to overwrite the item |
397 # of an other publisher | 404 # of an other publisher |
398 d = self._checkOverwrite(node, [item['id'] for item in items if item.getAttribute('id')], requestor) | 405 yield self._checkOverwrite(node, [item['id'] for item in items if item.getAttribute('id')], requestor) |
399 d.addCallback(lambda _: node.storeItems(items_data, requestor)) | 406 |
400 else: | 407 # TODO: check conflict and recalculate max id if serial_ids is set |
401 d = node.storeItems(items_data, requestor) | 408 yield node.storeItems(items_data, requestor) |
402 else: | 409 |
403 d = defer.succeed(None) | 410 yield self._doNotify(node, items_data, deliverPayloads, pep, recipient) |
404 | 411 |
405 d.addCallback(self._doNotify, node, items_data, | 412 def _doNotify(self, node, items_data, deliverPayloads, pep, recipient): |
406 deliverPayloads, pep, recipient) | |
407 return d | |
408 | |
409 def _doNotify(self, result, node, items_data, deliverPayloads, pep, recipient): | |
410 if items_data and not deliverPayloads: | 413 if items_data and not deliverPayloads: |
411 for item_data in items_data: | 414 for item_data in items_data: |
412 item_data.item.children = [] | 415 item_data.item.children = [] |
413 self.dispatch({'items_data': items_data, 'node': node, 'pep': pep, 'recipient': recipient}, | 416 self.dispatch({'items_data': items_data, 'node': node, 'pep': pep, 'recipient': recipient}, |
414 '//event/pubsub/notify') | 417 '//event/pubsub/notify') |
619 | 622 |
620 d = self.storage.getNode(nodeIdentifier, pep, recipient) | 623 d = self.storage.getNode(nodeIdentifier, pep, recipient) |
621 d.addCallback(lambda node: node.getSchema()) | 624 d.addCallback(lambda node: node.getSchema()) |
622 | 625 |
623 return d | 626 return d |
624 | |
625 | 627 |
626 def setNodeSchema(self, nodeIdentifier, schema, requestor, pep, recipient): | 628 def setNodeSchema(self, nodeIdentifier, schema, requestor, pep, recipient): |
627 """set or remove Schema of a node | 629 """set or remove Schema of a node |
628 | 630 |
629 @param nodeIdentifier(unicode): identifier of the pubusb node | 631 @param nodeIdentifier(unicode): identifier of the pubusb node |