comparison sat/memory/sqla.py @ 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
parents 1a10b8b4f169
children 045af0eeda3f
comparison
equal deleted inserted replaced
3861:37a1193d90db 3862:100dd30244c6
45 from sat.core.i18n import _ 45 from sat.core.i18n import _
46 from sat.core import exceptions 46 from sat.core import exceptions
47 from sat.core.log import getLogger 47 from sat.core.log import getLogger
48 from sat.core.constants import Const as C 48 from sat.core.constants import Const as C
49 from sat.core.core_types import SatXMPPEntity 49 from sat.core.core_types import SatXMPPEntity
50 from sat.tools.utils import aio 50 from sat.tools.utils import aio, as_future
51 from sat.tools.common import uri 51 from sat.tools.common import uri
52 from sat.memory import migration 52 from sat.memory import migration
53 from sat.memory import sqla_config 53 from sat.memory import sqla_config
54 from sat.memory.sqla_mapping import ( 54 from sat.memory.sqla_mapping import (
55 NOT_IN_EXTRA, 55 NOT_IN_EXTRA,
1057 client: SatXMPPEntity, 1057 client: SatXMPPEntity,
1058 service: jid.JID, 1058 service: jid.JID,
1059 name: str, 1059 name: str,
1060 with_items: bool = False, 1060 with_items: bool = False,
1061 with_subscriptions: bool = False, 1061 with_subscriptions: bool = False,
1062 create: bool = False,
1063 create_kwargs: Optional[dict] = None
1062 ) -> Optional[PubsubNode]: 1064 ) -> Optional[PubsubNode]:
1063 """ 1065 """Retrieve a PubsubNode from DB
1066
1067 @param service: service hosting the node
1068 @param name: node's name
1069 @param with_items: retrieve items in the same query
1070 @param with_subscriptions: retrieve subscriptions in the same query
1071 @param create: if the node doesn't exist in DB, create it
1072 @param create_kwargs: keyword arguments to use with ``setPubsubNode`` if the node
1073 needs to be created.
1064 """ 1074 """
1065 async with self.session() as session: 1075 async with self.session() as session:
1066 stmt = ( 1076 stmt = (
1067 select(PubsubNode) 1077 select(PubsubNode)
1068 .filter_by( 1078 .filter_by(
1078 if with_subscriptions: 1088 if with_subscriptions:
1079 stmt = stmt.options( 1089 stmt = stmt.options(
1080 joinedload(PubsubNode.subscriptions) 1090 joinedload(PubsubNode.subscriptions)
1081 ) 1091 )
1082 result = await session.execute(stmt) 1092 result = await session.execute(stmt)
1083 return result.unique().scalar_one_or_none() 1093 ret = result.unique().scalar_one_or_none()
1094 if ret is None and create:
1095 # we auto-create the node
1096 if create_kwargs is None:
1097 create_kwargs = {}
1098 try:
1099 return await as_future(self.setPubsubNode(
1100 client, service, name, **create_kwargs
1101 ))
1102 except IntegrityError as e:
1103 if "unique" in str(e.orig).lower():
1104 # the node may already exist, if it has been created just after
1105 # getPubsubNode above
1106 log.debug("ignoring UNIQUE constraint error")
1107 cached_node = await as_future(self.getPubsubNode(
1108 client,
1109 service,
1110 name,
1111 with_items=with_items,
1112 with_subscriptions=with_subscriptions
1113 ))
1114 else:
1115 raise e
1116 else:
1117 return ret
1084 1118
1085 @aio 1119 @aio
1086 async def setPubsubNode( 1120 async def setPubsubNode(
1087 self, 1121 self,
1088 client: SatXMPPEntity, 1122 client: SatXMPPEntity,