server/repository.py
changeset 9469 032825bbacab
parent 9468 39b7a91a3f4c
child 9488 12dfce15c8ea
equal deleted inserted replaced
9468:39b7a91a3f4c 9469:032825bbacab
   186         self.system_source = self.get_source('native', 'system',
   186         self.system_source = self.get_source('native', 'system',
   187                                              config.system_source_config.copy())
   187                                              config.system_source_config.copy())
   188         self.sources_by_uri = {'system': self.system_source}
   188         self.sources_by_uri = {'system': self.system_source}
   189         # querier helper, need to be created after sources initialization
   189         # querier helper, need to be created after sources initialization
   190         self.querier = querier.QuerierHelper(self, self.schema)
   190         self.querier = querier.QuerierHelper(self, self.schema)
   191         # cache eid -> (type, physical source, extid, actual source)
   191         # cache eid -> (type, extid, actual source)
   192         self._type_source_cache = {}
   192         self._type_source_cache = {}
   193         # cache (extid, source uri) -> eid
   193         # cache extid -> eid
   194         self._extid_cache = {}
   194         self._extid_cache = {}
   195         # open some connection sets
   195         # open some connection sets
   196         if config.init_cnxset_pool:
   196         if config.init_cnxset_pool:
   197             self.init_cnxset_pool()
   197             self.init_cnxset_pool()
   198         # the hooks manager
   198         # the hooks manager
   726                 self.exception('unexpected error while executing %s with %s', rqlstring, args)
   726                 self.exception('unexpected error while executing %s with %s', rqlstring, args)
   727                 raise
   727                 raise
   728         finally:
   728         finally:
   729             session.free_cnxset()
   729             session.free_cnxset()
   730 
   730 
       
   731     @deprecated('[3.19] use .entity_metas(sessionid, eid, txid) instead')
   731     def describe(self, sessionid, eid, txid=None):
   732     def describe(self, sessionid, eid, txid=None):
   732         """return a tuple `(type, physical source uri, extid, actual source
   733         """return a tuple `(type, physical source uri, extid, actual source
   733         uri)` for the entity of the given `eid`
   734         uri)` for the entity of the given `eid`
       
   735 
       
   736         As of 3.19, physical source uri is always the system source.
   734         """
   737         """
   735         session = self._get_session(sessionid, setcnxset=True, txid=txid)
   738         session = self._get_session(sessionid, setcnxset=True, txid=txid)
   736         try:
   739         try:
   737             return self.type_and_source_from_eid(eid, session)
   740             etype, extid, source = self.type_and_source_from_eid(eid, session)
       
   741             return etype, source, extid, source
       
   742         finally:
       
   743             session.free_cnxset()
       
   744 
       
   745     def entity_metas(self, sessionid, eid, txid=None):
       
   746         """return a dictionary containing meta-datas for the entity of the given
       
   747         `eid`. Available keys are:
       
   748 
       
   749         * 'type', the entity's type name,
       
   750 
       
   751         * 'source', the name of the source from which this entity's coming from,
       
   752 
       
   753         * 'extid', the identifierfor this entity in its originating source, as
       
   754           an encoded string or `None` for entities from the 'system' source.
       
   755         """
       
   756         session = self._get_session(sessionid, setcnxset=True, txid=txid)
       
   757         try:
       
   758             etype, extid, source = self.type_and_source_from_eid(eid, session)
       
   759             return {'type': etype, 'source': source, 'extid': extid}
   738         finally:
   760         finally:
   739             session.free_cnxset()
   761             session.free_cnxset()
   740 
   762 
   741     def check_session(self, sessionid):
   763     def check_session(self, sessionid):
   742         """raise `BadConnectionId` if the connection is no more valid, else
   764         """raise `BadConnectionId` if the connection is no more valid, else
   932     # data sources handling ###################################################
   954     # data sources handling ###################################################
   933     # * correspondance between eid and (type, source)
   955     # * correspondance between eid and (type, source)
   934     # * correspondance between eid and local id (i.e. specific to a given source)
   956     # * correspondance between eid and local id (i.e. specific to a given source)
   935 
   957 
   936     def type_and_source_from_eid(self, eid, session=None):
   958     def type_and_source_from_eid(self, eid, session=None):
   937         """return a tuple `(type, physical source uri, extid, actual source
   959         """return a tuple `(type, extid, actual source uri)` for the entity of
   938         uri)` for the entity of the given `eid`
   960         the given `eid`
   939         """
   961         """
   940         try:
   962         try:
   941             eid = int(eid)
   963             eid = int(eid)
   942         except ValueError:
   964         except ValueError:
   943             raise UnknownEid(eid)
   965             raise UnknownEid(eid)
   948                 session = self.internal_session()
   970                 session = self.internal_session()
   949                 free_cnxset = True
   971                 free_cnxset = True
   950             else:
   972             else:
   951                 free_cnxset = False
   973                 free_cnxset = False
   952             try:
   974             try:
   953                 etype, uri, extid, auri = self.system_source.eid_type_source(
   975                 etype, extid, auri = self.system_source.eid_type_source(
   954                     session, eid)
   976                     session, eid)
   955             finally:
   977             finally:
   956                 if free_cnxset:
   978                 if free_cnxset:
   957                     session.free_cnxset()
   979                     session.free_cnxset()
   958             self._type_source_cache[eid] = (etype, uri, extid, auri)
   980             self._type_source_cache[eid] = (etype, extid, auri)
   959             if uri != 'system':
   981             return etype, extid, auri
   960                 self._extid_cache[(extid, uri)] = eid
       
   961             return etype, uri, extid, auri
       
   962 
   982 
   963     def clear_caches(self, eids):
   983     def clear_caches(self, eids):
   964         etcache = self._type_source_cache
   984         etcache = self._type_source_cache
   965         extidcache = self._extid_cache
   985         extidcache = self._extid_cache
   966         rqlcache = self.querier._rql_cache
   986         rqlcache = self.querier._rql_cache
   967         for eid in eids:
   987         for eid in eids:
   968             try:
   988             try:
   969                 etype, uri, extid, auri = etcache.pop(int(eid)) # may be a string in some cases
   989                 etype, extid, auri = etcache.pop(int(eid)) # may be a string in some cases
   970                 rqlcache.pop( ('%s X WHERE X eid %s' % (etype, eid),), None)
   990                 rqlcache.pop( ('%s X WHERE X eid %s' % (etype, eid),), None)
   971                 extidcache.pop((extid, uri), None)
   991                 extidcache.pop(extid, None)
   972             except KeyError:
   992             except KeyError:
   973                 etype = None
   993                 etype = None
   974             rqlcache.pop( ('Any X WHERE X eid %s' % eid,), None)
   994             rqlcache.pop( ('Any X WHERE X eid %s' % eid,), None)
   975             self.system_source.clear_eid_cache(eid, etype)
   995             self.system_source.clear_eid_cache(eid, etype)
   976 
   996 
   977     def type_from_eid(self, eid, session=None):
   997     def type_from_eid(self, eid, session=None):
   978         """return the type of the entity with id <eid>"""
   998         """return the type of the entity with id <eid>"""
   979         return self.type_and_source_from_eid(eid, session)[0]
   999         return self.type_and_source_from_eid(eid, session)[0]
   980 
       
   981     def source_from_eid(self, eid, session=None):
       
   982         """return the source for the given entity's eid"""
       
   983         return self.sources_by_uri[self.type_and_source_from_eid(eid, session)[1]]
       
   984 
  1000 
   985     def querier_cache_key(self, session, rql, args, eidkeys):
  1001     def querier_cache_key(self, session, rql, args, eidkeys):
   986         cachekey = [rql]
  1002         cachekey = [rql]
   987         for key in sorted(eidkeys):
  1003         for key in sorted(eidkeys):
   988             try:
  1004             try:
   995             cachekey.append(etype)
  1011             cachekey.append(etype)
   996             # ensure eid is correctly typed in args
  1012             # ensure eid is correctly typed in args
   997             args[key] = int(args[key])
  1013             args[key] = int(args[key])
   998         return tuple(cachekey)
  1014         return tuple(cachekey)
   999 
  1015 
  1000     def eid2extid(self, source, eid, session=None):
       
  1001         """get local id from an eid"""
       
  1002         etype, uri, extid, _ = self.type_and_source_from_eid(eid, session)
       
  1003         if source.uri != uri:
       
  1004             # eid not from the given source
       
  1005             raise UnknownEid(eid)
       
  1006         return extid
       
  1007 
       
  1008     def extid2eid(self, source, extid, etype, session=None, insert=True,
  1016     def extid2eid(self, source, extid, etype, session=None, insert=True,
  1009                   complete=True, commit=True, sourceparams=None):
  1017                   complete=True, commit=True, sourceparams=None):
  1010         """Return eid from a local id. If the eid is a negative integer, that
  1018         """Return eid from a local id. If the eid is a negative integer, that
  1011         means the entity is known but has been copied back to the system source
  1019         means the entity is known but has been copied back to the system source
  1012         hence should be ignored.
  1020         hence should be ignored.
  1027            complete building of the entity instance
  1035            complete building of the entity instance
  1028 
  1036 
  1029         6. unless source's :attr:`should_call_hooks` tell otherwise,
  1037         6. unless source's :attr:`should_call_hooks` tell otherwise,
  1030           'before_add_entity' hooks are called
  1038           'before_add_entity' hooks are called
  1031         """
  1039         """
  1032         uri = 'system'
  1040         try:
  1033         cachekey = (extid, uri)
  1041             return self._extid_cache[extid]
  1034         try:
       
  1035             return self._extid_cache[cachekey]
       
  1036         except KeyError:
  1042         except KeyError:
  1037             pass
  1043             pass
  1038         free_cnxset = False
  1044         free_cnxset = False
  1039         if session is None:
  1045         if session is None:
  1040             session = self.internal_session()
  1046             session = self.internal_session()
  1041             free_cnxset = True
  1047             free_cnxset = True
  1042         eid = self.system_source.extid2eid(session, uri, extid)
  1048         eid = self.system_source.extid2eid(session, extid)
  1043         if eid is not None:
  1049         if eid is not None:
  1044             self._extid_cache[cachekey] = eid
  1050             self._extid_cache[extid] = eid
  1045             self._type_source_cache[eid] = (etype, uri, extid, source.uri)
  1051             self._type_source_cache[eid] = (etype, extid, source.uri)
  1046             if free_cnxset:
  1052             if free_cnxset:
  1047                 session.free_cnxset()
  1053                 session.free_cnxset()
  1048             return eid
  1054             return eid
  1049         if not insert:
  1055         if not insert:
  1050             return
  1056             return
  1057         if not session.is_internal_session:
  1063         if not session.is_internal_session:
  1058             session = self.internal_session()
  1064             session = self.internal_session()
  1059             free_cnxset = True
  1065             free_cnxset = True
  1060         try:
  1066         try:
  1061             eid = self.system_source.create_eid(session)
  1067             eid = self.system_source.create_eid(session)
  1062             self._extid_cache[cachekey] = eid
  1068             self._extid_cache[extid] = eid
  1063             self._type_source_cache[eid] = (etype, uri, extid, source.uri)
  1069             self._type_source_cache[eid] = (etype, extid, source.uri)
  1064             entity = source.before_entity_insertion(
  1070             entity = source.before_entity_insertion(
  1065                 session, extid, etype, eid, sourceparams)
  1071                 session, extid, etype, eid, sourceparams)
  1066             if source.should_call_hooks:
  1072             if source.should_call_hooks:
  1067                 # get back a copy of operation for later restore if necessary,
  1073                 # get back a copy of operation for later restore if necessary,
  1068                 # see below
  1074                 # see below
  1079             if commit or free_cnxset:
  1085             if commit or free_cnxset:
  1080                 session.rollback(free_cnxset)
  1086                 session.rollback(free_cnxset)
  1081             else:
  1087             else:
  1082                 # XXX do some cleanup manually so that the transaction has a
  1088                 # XXX do some cleanup manually so that the transaction has a
  1083                 # chance to be commited, with simply this entity discarded
  1089                 # chance to be commited, with simply this entity discarded
  1084                 self._extid_cache.pop(cachekey, None)
  1090                 self._extid_cache.pop(extid, None)
  1085                 self._type_source_cache.pop(eid, None)
  1091                 self._type_source_cache.pop(eid, None)
  1086                 if 'entity' in locals():
  1092                 if 'entity' in locals():
  1087                     hook.CleanupDeletedEidsCacheOp.get_instance(session).add_data(entity.eid)
  1093                     hook.CleanupDeletedEidsCacheOp.get_instance(session).add_data(entity.eid)
  1088                     self.system_source.delete_info_multi(session, [entity])
  1094                     self.system_source.delete_info_multi(session, [entity])
  1089                     if source.should_call_hooks:
  1095                     if source.should_call_hooks:
  1175     def init_entity_caches(self, session, entity, source):
  1181     def init_entity_caches(self, session, entity, source):
  1176         """add entity to session entities cache and repo's extid cache.
  1182         """add entity to session entities cache and repo's extid cache.
  1177         Return entity's ext id if the source isn't the system source.
  1183         Return entity's ext id if the source isn't the system source.
  1178         """
  1184         """
  1179         session.set_entity_cache(entity)
  1185         session.set_entity_cache(entity)
  1180         suri = source.uri
  1186         if source.uri == 'system':
  1181         if suri == 'system':
       
  1182             extid = None
  1187             extid = None
  1183         else:
  1188         else:
  1184             suri = 'system'
       
  1185             extid = source.get_extid(entity)
  1189             extid = source.get_extid(entity)
  1186             self._extid_cache[(str(extid), suri)] = entity.eid
  1190             self._extid_cache[str(extid)] = entity.eid
  1187         self._type_source_cache[entity.eid] = (entity.cw_etype, suri, extid,
  1191         self._type_source_cache[entity.eid] = (entity.cw_etype, extid, source.uri)
  1188                                                source.uri)
       
  1189         return extid
  1192         return extid
  1190 
  1193 
  1191     def glob_add_entity(self, session, edited):
  1194     def glob_add_entity(self, session, edited):
  1192         """add an entity to the repository
  1195         """add an entity to the repository
  1193 
  1196