Mercurial > libervia-backend
changeset 3862:100dd30244c6
core (memory/sqla): add argument to `getPubsubNode` to auto-create a node:
if the node is not in cache, the new `create` and `create_kwargs` arguments can be used to
automatically call `setPubsubNode`
rel 370
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 20 Jul 2022 17:41:44 +0200 (2022-07-20) |
parents | 37a1193d90db |
children | c04f5e8a3568 |
files | sat/memory/sqla.py |
diffstat | 1 files changed, 37 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/sat/memory/sqla.py Wed Jul 20 17:19:53 2022 +0200 +++ b/sat/memory/sqla.py Wed Jul 20 17:41:44 2022 +0200 @@ -47,7 +47,7 @@ from sat.core.log import getLogger from sat.core.constants import Const as C from sat.core.core_types import SatXMPPEntity -from sat.tools.utils import aio +from sat.tools.utils import aio, as_future from sat.tools.common import uri from sat.memory import migration from sat.memory import sqla_config @@ -1059,8 +1059,18 @@ name: str, with_items: bool = False, with_subscriptions: bool = False, + create: bool = False, + create_kwargs: Optional[dict] = None ) -> Optional[PubsubNode]: - """ + """Retrieve a PubsubNode from DB + + @param service: service hosting the node + @param name: node's name + @param with_items: retrieve items in the same query + @param with_subscriptions: retrieve subscriptions in the same query + @param create: if the node doesn't exist in DB, create it + @param create_kwargs: keyword arguments to use with ``setPubsubNode`` if the node + needs to be created. """ async with self.session() as session: stmt = ( @@ -1080,7 +1090,31 @@ joinedload(PubsubNode.subscriptions) ) result = await session.execute(stmt) - return result.unique().scalar_one_or_none() + ret = result.unique().scalar_one_or_none() + if ret is None and create: + # we auto-create the node + if create_kwargs is None: + create_kwargs = {} + try: + return await as_future(self.setPubsubNode( + client, service, name, **create_kwargs + )) + except IntegrityError as e: + if "unique" in str(e.orig).lower(): + # the node may already exist, if it has been created just after + # getPubsubNode above + log.debug("ignoring UNIQUE constraint error") + cached_node = await as_future(self.getPubsubNode( + client, + service, + name, + with_items=with_items, + with_subscriptions=with_subscriptions + )) + else: + raise e + else: + return ret @aio async def setPubsubNode(